Merge pull request #5024 from greenhouse-org/fix-windows-path

Fix TryCreateParentDirectory on Windows
diff --git a/BUILD b/BUILD
index 884e32f..25c41a4 100644
--- a/BUILD
+++ b/BUILD
@@ -111,7 +111,7 @@
         "src/google/protobuf/stubs/time.cc",
         "src/google/protobuf/wire_format_lite.cc",
     ],
-    hdrs = glob(["src/google/protobuf/**/*.h"]),
+    hdrs = glob(["src/google/protobuf/**/*.h", "src/google/protobuf/**/*.inc"]),
     copts = COPTS,
     includes = ["src/"],
     linkopts = LINK_OPTS,
@@ -178,7 +178,7 @@
         "src/google/protobuf/wire_format.cc",
         "src/google/protobuf/wrappers.pb.cc",
     ],
-    hdrs = glob(["src/**/*.h"]),
+    hdrs = glob(["src/**/*.h", "src/**/*.inc"]),
     copts = COPTS,
     includes = ["src/"],
     linkopts = LINK_OPTS,
@@ -356,6 +356,7 @@
         "src/google/protobuf/compiler/plugin.pb.cc",
         "src/google/protobuf/compiler/python/python_generator.cc",
         "src/google/protobuf/compiler/ruby/ruby_generator.cc",
+        "src/google/protobuf/compiler/scc.cc",
         "src/google/protobuf/compiler/subprocess.cc",
         "src/google/protobuf/compiler/zip_writer.cc",
     ],
@@ -436,6 +437,7 @@
     "google/protobuf/unittest_optimize_for.proto",
     "google/protobuf/unittest_preserve_unknown_enum.proto",
     "google/protobuf/unittest_preserve_unknown_enum2.proto",
+    "google/protobuf/unittest_proto3.proto",
     "google/protobuf/unittest_proto3_arena.proto",
     "google/protobuf/unittest_proto3_arena_lite.proto",
     "google/protobuf/unittest_proto3_lite.proto",
@@ -451,6 +453,7 @@
     "google/protobuf/util/internal/testdata/struct.proto",
     "google/protobuf/util/internal/testdata/timestamp_duration.proto",
     "google/protobuf/util/internal/testdata/wrappers.proto",
+    "google/protobuf/util/json_format.proto",
     "google/protobuf/util/json_format_proto3.proto",
     "google/protobuf/util/message_differencer_unittest.proto",
 ]
@@ -545,6 +548,7 @@
         "src/google/protobuf/proto3_arena_lite_unittest.cc",
         "src/google/protobuf/proto3_arena_unittest.cc",
         "src/google/protobuf/proto3_lite_unittest.cc",
+        "src/google/protobuf/proto3_lite_unittest.inc",
         "src/google/protobuf/reflection_ops_unittest.cc",
         "src/google/protobuf/repeated_field_reflection_unittest.cc",
         "src/google/protobuf/repeated_field_unittest.cc",
diff --git a/Makefile.am b/Makefile.am
index 24f520c..6694dff 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -689,6 +689,18 @@
   php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php        \
   php/src/Google/Protobuf/Internal/UninterpretedOption.php            \
   php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php   \
+  php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php \
+  php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php  \
+  php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php \
+  php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php     \
+  php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php      \
+  php/src/Google/Protobuf/Internal/FieldOptions_CType.php             \
+  php/src/Google/Protobuf/Internal/FieldOptions_JSType.php            \
+  php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php       \
+  php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php   \
+  php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php \
+  php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php        \
+  php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php   \
   php/src/Google/Protobuf/ListValue.php                               \
   php/src/Google/Protobuf/Method.php                                  \
   php/src/Google/Protobuf/Mixin.php                                   \
@@ -824,6 +836,10 @@
   python/google/protobuf/pyext/map_container.h                               \
   python/google/protobuf/pyext/message.cc                                    \
   python/google/protobuf/pyext/message.h                                     \
+  python/google/protobuf/pyext/field.cc                                      \
+  python/google/protobuf/pyext/field.h                                       \
+  python/google/protobuf/pyext/unknown_fields.cc                             \
+  python/google/protobuf/pyext/unknown_fields.h                              \
   python/google/protobuf/pyext/message_factory.cc                            \
   python/google/protobuf/pyext/message_factory.h                             \
   python/google/protobuf/pyext/message_module.cc                             \
diff --git a/README.md b/README.md
index f0f2e32..618c6d7 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,7 @@
 
 | Language                             | Source                                                      | Ubuntu | MacOS | Windows |
 |--------------------------------------|-------------------------------------------------------------|--------|-------|---------|
-| C++ (include C++ runtime and protoc) | [src](src)                                                  | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-cpp_distcheck.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fcpp_distcheck%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fcpp%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-cpp_distcheck.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fcpp_distcheck%2Fcontinuous) | [![Build status](https://ci.appveyor.com/api/projects/status/73ctee6ua4w2ruin?svg=true)](https://ci.appveyor.com/project/protobuf/protobuf) |
+| C++ (include C++ runtime and protoc) | [src](src)                                                  | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-cpp_distcheck.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fcpp_distcheck%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-bazel.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fbazel%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fcpp%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-cpp_distcheck.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fcpp_distcheck%2Fcontinuous) | [![Build status](https://ci.appveyor.com/api/projects/status/73ctee6ua4w2ruin?svg=true)](https://ci.appveyor.com/project/protobuf/protobuf) |
 | Java                                 | [java](java)                                                | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-java_compatibility.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fjava_compatibility%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-java_jdk7.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fjava_jdk7%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-java_oracle7.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fjava_oracle7%2Fcontinuous) | | |
 | Python                               | [python](python)                                            | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python_compatibility.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython_compatibility%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython_cpp%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython_cpp%2Fcontinuous) | |
 | Objective-C                          | [objectivec](objectivec)                                    | | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_cocoapods_integration.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_cocoapods_integration%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_ios_debug.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_ios_debug%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_ios_release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_ios_release%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_osx.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_osx%2Fcontinuous) | |
diff --git a/benchmarks/Makefile.am b/benchmarks/Makefile.am
index 4f7df64..c758ee6 100644
--- a/benchmarks/Makefile.am
+++ b/benchmarks/Makefile.am
@@ -546,6 +546,58 @@
 
 ############ PHP RULES END #################
 
+############ protobuf.js RULE BEGIN #############
+
+pbjs_preparation:
+	mkdir -p tmp/protobuf.js
+	cd tmp/protobuf.js && git clone https://github.com/dcodeIO/protobuf.js.git && \
+			cd protobuf.js && npm install && npm run build
+	cd tmp/protobuf.js && npm install benchmark
+	cp protobuf.js/* tmp/protobuf.js
+	cp js/benchmark_suite.js tmp/protobuf.js
+	touch pbjs_preparation
+
+pbjs_middleman: pbjs_preparation
+	export OLDDIR=$$(pwd) && cd tmp/protobuf.js && node generate_pbjs_files.js --target static-module --include_path=$$OLDDIR -o generated_bundle_code.js $(benchmarks_protoc_inputs) $(benchmarks_protoc_inputs_benchmark_wrapper) $(benchmarks_protoc_inputs_proto2)
+	touch pbjs_middleman
+
+pbjs-benchmark: pbjs_middleman
+	@echo '#! /bin/bash' > pbjs-benchmark
+	@echo 'cd tmp/protobuf.js' >> pbjs-benchmark
+	@echo 'sed -i "s/protobufjs/.\/protobuf.js/g" generated_bundle_code.js' >> pbjs-benchmark
+	@echo 'env NODE_PATH=".:./node_modules:$$NODE_PATH" node protobufjs_benchmark.js $$@' >> pbjs-benchmark
+	@chmod +x pbjs-benchmark
+
+pbjs: pbjs-benchmark
+	./pbjs-benchmark $(all_data)
+
+############ protobuf.js RULE END #############
+
+############ JS RULE BEGIN #############
+
+js_preparation:
+	mkdir -p tmp/js
+	oldpwd=$$(pwd) && cd $(top_srcdir)/js && npm install && npm test
+	cd tmp/js && npm install benchmark
+	cp js/* tmp/js
+	touch js_preparation
+
+js_middleman: js_preparation
+	oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --js_out=import_style=commonjs,binary:$$oldpwd/tmp/js $(benchmarks_protoc_inputs) $(benchmarks_protoc_inputs_benchmark_wrapper) $(benchmarks_protoc_inputs_proto2))
+	touch js_middleman
+
+js-benchmark: js_middleman
+	@echo '#! /bin/bash' > js-benchmark
+	@echo 'export TOP_JS_SRCDIR=$$(cd $(top_srcdir)/js && pwd)' >> js-benchmark
+	@echo 'cd tmp/js' >> js-benchmark
+	@echo 'env NODE_PATH="$$TOP_JS_SRCDIR:.:./node_modules:$$NODE_PATH" node --max-old-space-size=4096 js_benchmark.js $$@' >> js-benchmark
+	@chmod +x js-benchmark
+
+js: js-benchmark
+	./js-benchmark $(all_data)
+
+############ JS RULE END #############
+
 MAINTAINERCLEANFILES =                                                     \
 	Makefile.in
 
@@ -593,8 +645,13 @@
 	generate_proto3_data                                                     \
 	php-benchmark                                                            \
 	php-c-benchmark                                                          \
-	proto3_middleman_php
-	
+	proto3_middleman_php                                                     \
+	pbjs_preparation                                                         \
+	pbjs_middleman                                                           \
+	pbjs-benchmark                                                           \
+	js_preparation                                                           \
+	js_middleman                                                             \
+	js-benchmark
 
 clean-local:
 	-rm -rf tmp/*
diff --git a/benchmarks/README.md b/benchmarks/README.md
index 91b80a9..534e0bd 100644
--- a/benchmarks/README.md
+++ b/benchmarks/README.md
@@ -62,6 +62,9 @@
 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
+Node.js benchmark need [node](https://nodejs.org/en/)(higher than V6) and [npm](https://www.npmjs.com/) package manager installed. This benchmark is using the [benchmark](https://www.npmjs.com/package/benchmark) framework to test, which needn't to manually install. And another prerequisite is [protobuf js](https://github.com/google/protobuf/tree/master/js), which needn't to manually install either
+
 ### Big data
 
 There's some optional big testing data which is not included in the directory
@@ -136,6 +139,11 @@
 $ make php_c
 ```
 
+### Node.js
+```
+$ make js
+```
+
 To run a specific dataset or run with specific options:
 
 ### Java:
@@ -195,6 +203,11 @@
 $ ./php-c-benchmark $(specific generated dataset file name)
 ```
 
+### Node.js
+```
+$ make js-benchmark
+$ ./js-benchmark $(specific generated dataset file name)
+```
 
 ## Benchmark datasets
 
diff --git a/benchmarks/cpp/cpp_benchmark.cc b/benchmarks/cpp/cpp_benchmark.cc
index f8b5529..036d234 100644
--- a/benchmarks/cpp/cpp_benchmark.cc
+++ b/benchmarks/cpp/cpp_benchmark.cc
@@ -30,7 +30,7 @@
 
 #include <fstream>
 #include <iostream>
-#include "benchmark/benchmark_api.h"
+#include "benchmark/benchmark.h"
 #include "benchmarks.pb.h"
 #include "datasets/google_message1/proto2/benchmark_message1_proto2.pb.h"
 #include "datasets/google_message1/proto3/benchmark_message1_proto3.pb.h"
diff --git a/benchmarks/js/benchmark_suite.js b/benchmarks/js/benchmark_suite.js
new file mode 100644
index 0000000..c95024b
--- /dev/null
+++ b/benchmarks/js/benchmark_suite.js
@@ -0,0 +1,33 @@
+var benchmark = require("benchmark");
+
+function newBenchmark(messageName, filename, language) {
+  var benches = [];
+  return {
+    suite: new benchmark.Suite(messageName + filename + language )
+      .on("add", function(event) {
+          benches.push(event.target);
+      })
+      .on("start", function() {
+          process.stdout.write(
+            "benchmarking message " + messageName 
+            + " of dataset file " + filename 
+            + "'s performance ..." + "\n\n");
+      })
+      .on("cycle", function(event) {
+          process.stdout.write(String(event.target) + "\n");
+      })
+      .on("complete", function() {
+          var getHz = function(bench) {
+            return 1 / (bench.stats.mean + bench.stats.moe);
+          }
+          benches.forEach(function(val, index) {
+            benches[index] = getHz(val); 
+          });
+      }),
+     benches: benches
+  }
+}
+
+module.exports = {
+        newBenchmark: newBenchmark
+}
diff --git a/benchmarks/js/js_benchmark.js b/benchmarks/js/js_benchmark.js
new file mode 100644
index 0000000..14905e3
--- /dev/null
+++ b/benchmarks/js/js_benchmark.js
@@ -0,0 +1,70 @@
+require('./datasets/google_message1/proto2/benchmark_message1_proto2_pb.js');
+require('./datasets/google_message1/proto3/benchmark_message1_proto3_pb.js');
+require('./datasets/google_message2/benchmark_message2_pb.js');
+require('./datasets/google_message3/benchmark_message3_pb.js');
+require('./datasets/google_message4/benchmark_message4_pb.js');
+require('./benchmarks_pb.js');
+
+var fs = require('fs');
+var benchmarkSuite = require("./benchmark_suite.js");
+
+
+function getNewPrototype(name) {
+  var message = eval("proto." + name);
+  if (typeof(message) == "undefined") {
+    throw "type " + name + " is undefined";
+  }
+  return message;
+}
+
+var results = [];
+
+console.log("#####################################################");
+console.log("Js Benchmark: ");
+process.argv.forEach(function(filename, index) {
+  if (index < 2) {
+    return;
+  }
+  var benchmarkDataset =
+      proto.benchmarks.BenchmarkDataset.deserializeBinary(fs.readFileSync(filename));
+  var messageList = [];
+  var totalBytes = 0;
+  benchmarkDataset.getPayloadList().forEach(function(onePayload) {
+    var message = getNewPrototype(benchmarkDataset.getMessageName());
+    messageList.push(message.deserializeBinary(onePayload));
+    totalBytes += onePayload.length;
+  });
+  
+  var senarios = benchmarkSuite.newBenchmark(
+      benchmarkDataset.getMessageName(), filename, "js");
+  senarios.suite
+  .add("js deserialize", function() {
+    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({
+    filename: filename,
+    benchmarks: {
+      protobufjs_decoding: senarios.benches[0] * totalBytes,
+      protobufjs_encoding: senarios.benches[1] * totalBytes
+    }
+  })
+
+  console.log("Throughput for deserialize: " 
+    + senarios.benches[0] * totalBytes / 1024 / 1024 + "MB/s" );
+  console.log("Throughput for serialize: " 
+    + senarios.benches[1] * totalBytes / 1024 / 1024 + "MB/s" );
+  console.log("");
+});
+console.log("#####################################################");
+
diff --git a/benchmarks/protobuf.js/generate_pbjs_files.js b/benchmarks/protobuf.js/generate_pbjs_files.js
new file mode 100644
index 0000000..11945bf
--- /dev/null
+++ b/benchmarks/protobuf.js/generate_pbjs_files.js
@@ -0,0 +1,25 @@
+var pbjs = require("./protobuf.js/cli").pbjs
+
+var argv = [];
+var protoFiles = [];
+var prefix = "";
+process.argv.forEach(function(val, index) {
+  var arg = val;
+  if (arg.length > 6 && arg.substring(arg.length - 6) == ".proto") {
+    protoFiles.push(arg);
+  } else if (arg.length > 15 && arg.substring(0, 15) ==  "--include_path=") {
+    prefix = arg.substring(15);
+  } else if (index >= 2) {
+    argv.push(arg);
+  }
+});
+protoFiles.forEach(function(val) {
+  argv.push(prefix + "/" + val);
+});
+
+pbjs.main(argv, function(err, output){
+  if (err) {
+    console.log(err);
+  }
+});
+
diff --git a/benchmarks/protobuf.js/protobufjs_benchmark.js b/benchmarks/protobuf.js/protobufjs_benchmark.js
new file mode 100644
index 0000000..2629e9f
--- /dev/null
+++ b/benchmarks/protobuf.js/protobufjs_benchmark.js
@@ -0,0 +1,66 @@
+var root = require("./generated_bundle_code.js");
+var fs = require('fs');
+var benchmark = require("./node_modules/benchmark");
+var benchmarkSuite = require("./benchmark_suite.js");
+
+
+function getNewPrototype(name) {
+  var message = eval("root." + name);
+  if (typeof(message) == "undefined") {
+    throw "type " + name + " is undefined";
+  }
+  return message;
+}
+
+
+var results = [];
+
+console.log("#####################################################");
+console.log("ProtobufJs Benchmark: ");
+process.argv.forEach(function(filename, index) {
+  if (index < 2) {
+    return;
+  }
+  var benchmarkDataset =
+      root.benchmarks.BenchmarkDataset.decode(fs.readFileSync(filename));
+  var messageList = [];
+  var totalBytes = 0;
+  benchmarkDataset.payload.forEach(function(onePayload) {
+    var message = getNewPrototype(benchmarkDataset.messageName);
+    messageList.push(message.decode(onePayload));
+    totalBytes += onePayload.length;
+  });
+  
+  var senarios = benchmarkSuite.newBenchmark(
+    benchmarkDataset.messageName, filename, "protobufjs");
+  senarios.suite
+  .add("protobuf.js static decoding", function() {
+    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({
+    filename: filename,
+    benchmarks: {
+      protobufjs_decoding: senarios.benches[0] * totalBytes,
+      protobufjs_encoding: senarios.benches[1] * totalBytes
+    }
+  })
+
+  console.log("Throughput for decoding: " 
+    + senarios.benches[0] * totalBytes / 1024 / 1024 + "MB/s" );
+  console.log("Throughput for encoding: " 
+    + senarios.benches[1] * totalBytes / 1024 / 1024 + "MB/s" );
+  console.log("");
+});
+console.log("#####################################################");
+
diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in
index 9fd9de0..3818c4e 100644
--- a/cmake/extract_includes.bat.in
+++ b/cmake/extract_includes.bat.in
@@ -72,6 +72,9 @@
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\message_lite.h" include\google\protobuf\message_lite.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\metadata.h" include\google\protobuf\metadata.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\metadata_lite.h" include\google\protobuf\metadata_lite.h
+copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\port.h" include\google\protobuf\port.h
+copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\port_def.inc" include\google\protobuf\port_def.inc
+copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\port_undef.inc" include\google\protobuf\port_undef.inc
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection.h" include\google\protobuf\reflection.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection_ops.h" include\google\protobuf\reflection_ops.h
 copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_field.h" include\google\protobuf\repeated_field.h
diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake
index a9f5c36..850a85a 100644
--- a/cmake/libprotoc.cmake
+++ b/cmake/libprotoc.cmake
@@ -78,6 +78,7 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/scc.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/subprocess.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/zip_writer.cc
 )
@@ -153,6 +154,7 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_message_field.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_oneof.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h
+  ${protobuf_source_dir}/src/google/protobuf/compiler/scc.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/subprocess.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/zip_writer.h
 )
@@ -177,3 +179,4 @@
     OUTPUT_NAME ${LIB_PREFIX}protoc
     DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}")
 add_library(protobuf::libprotoc ALIAS libprotoc)
+
diff --git a/cmake/tests.cmake b/cmake/tests.cmake
index 603d7e9..f4679d1 100644
--- a/cmake/tests.cmake
+++ b/cmake/tests.cmake
@@ -63,6 +63,7 @@
   google/protobuf/unittest_optimize_for.proto
   google/protobuf/unittest_preserve_unknown_enum.proto
   google/protobuf/unittest_preserve_unknown_enum2.proto
+  google/protobuf/unittest_proto3.proto
   google/protobuf/unittest_proto3_arena.proto
   google/protobuf/unittest_proto3_arena_lite.proto
   google/protobuf/unittest_proto3_lite.proto
@@ -78,6 +79,7 @@
   google/protobuf/util/internal/testdata/struct.proto
   google/protobuf/util/internal/testdata/timestamp_duration.proto
   google/protobuf/util/internal/testdata/wrappers.proto
+  google/protobuf/util/json_format.proto
   google/protobuf/util/json_format_proto3.proto
   google/protobuf/util/message_differencer_unittest.proto
 )
@@ -166,6 +168,7 @@
   ${protobuf_source_dir}/src/google/protobuf/proto3_arena_lite_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/proto3_arena_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/proto3_lite_unittest.cc
+  ${protobuf_source_dir}/src/google/protobuf/proto3_lite_unittest.inc
   ${protobuf_source_dir}/src/google/protobuf/reflection_ops_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/repeated_field_reflection_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/repeated_field_unittest.cc
diff --git a/conformance/ConformanceJava.java b/conformance/ConformanceJava.java
index dcdc27e..d1ce405 100644
--- a/conformance/ConformanceJava.java
+++ b/conformance/ConformanceJava.java
@@ -233,7 +233,7 @@
       }
       case JSON_PAYLOAD: {
         try {
-          TestMessagesProto3.TestAllTypesProto3.Builder builder = 
+          TestMessagesProto3.TestAllTypesProto3.Builder builder =
               TestMessagesProto3.TestAllTypesProto3.newBuilder();
           JsonFormat.Parser parser = JsonFormat.parser().usingTypeRegistry(typeRegistry);
           if (request.getTestCategory()
diff --git a/conformance/conformance.proto b/conformance/conformance.proto
index d838e57..af89152 100644
--- a/conformance/conformance.proto
+++ b/conformance/conformance.proto
@@ -58,14 +58,15 @@
 }
 
 enum TestCategory {
-  BINARY_TEST = 0;  // Test binary wire format.
-  JSON_TEST = 1;  // Test json wire format.
+  UNSPECIFIED_TEST = 0;
+  BINARY_TEST = 1;  // Test binary wire format.
+  JSON_TEST = 2;  // Test json wire format.
   // Similar to JSON_TEST. However, during parsing json, testee should ignore
   // unknown fields. This feature is optional. Each implementation can descide
   // whether to support it.  See
   // https://developers.google.com/protocol-buffers/docs/proto3#json_options
   // for more detail.
-  JSON_IGNORE_UNKNOWN_PARSING_TEST = 2;  
+  JSON_IGNORE_UNKNOWN_PARSING_TEST = 3;
 }
 
 // Represents a single test case's input.  The testee should:
@@ -94,9 +95,9 @@
   // protobuf_test_messages.proto2.TestAllTypesProto2.
   string message_type = 4;
 
-  // Each test is given a specific test category. Some category may need spedific
-  // support in testee programs. Refer to the defintion of TestCategory for
-  // more information.
+  // Each test is given a specific test category. Some category may need
+  // spedific support in testee programs. Refer to the defintion of TestCategory
+  // for more information.
   TestCategory test_category = 5;
 }
 
diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc
index 74342b6..0a45f9b 100644
--- a/conformance/conformance_test.cc
+++ b/conformance/conformance_test.cc
@@ -28,200 +28,83 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+#include <set>
 #include <stdarg.h>
 #include <string>
 #include <fstream>
 
 #include "conformance.pb.h"
 #include "conformance_test.h"
-#include <google/protobuf/test_messages_proto3.pb.h>
-#include <google/protobuf/test_messages_proto2.pb.h>
 
-#include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/message.h>
 #include <google/protobuf/text_format.h>
 #include <google/protobuf/util/field_comparator.h>
 #include <google/protobuf/util/json_util.h>
 #include <google/protobuf/util/message_differencer.h>
-#include <google/protobuf/util/type_resolver_util.h>
-#include <google/protobuf/wire_format_lite.h>
-
-#include "third_party/jsoncpp/json.h"
 
 using conformance::ConformanceRequest;
 using conformance::ConformanceResponse;
 using conformance::WireFormat;
-using google::protobuf::Descriptor;
-using google::protobuf::FieldDescriptor;
-using google::protobuf::internal::WireFormatLite;
 using google::protobuf::TextFormat;
 using google::protobuf::util::DefaultFieldComparator;
 using google::protobuf::util::JsonToBinaryString;
 using google::protobuf::util::MessageDifferencer;
-using google::protobuf::util::NewTypeResolverForDescriptorPool;
 using google::protobuf::util::Status;
-using protobuf_test_messages::proto3::TestAllTypesProto3;
-using protobuf_test_messages::proto2::TestAllTypesProto2;
 using std::string;
 
-namespace {
-
-static const char kTypeUrlPrefix[] = "type.googleapis.com";
-
-static string GetTypeUrl(const Descriptor* message) {
-  return string(kTypeUrlPrefix) + "/" + message->full_name();
-}
-
-/* Routines for building arbitrary protos *************************************/
-
-// We would use CodedOutputStream except that we want more freedom to build
-// arbitrary protos (even invalid ones).
-
-const string empty;
-
-string cat(const string& a, const string& b,
-           const string& c = empty,
-           const string& d = empty,
-           const string& e = empty,
-           const string& f = empty,
-           const string& g = empty,
-           const string& h = empty,
-           const string& i = empty,
-           const string& j = empty,
-           const string& k = empty,
-           const string& l = empty) {
-  string ret;
-  ret.reserve(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() +
-              g.size() + h.size() + i.size() + j.size() + k.size() + l.size());
-  ret.append(a);
-  ret.append(b);
-  ret.append(c);
-  ret.append(d);
-  ret.append(e);
-  ret.append(f);
-  ret.append(g);
-  ret.append(h);
-  ret.append(i);
-  ret.append(j);
-  ret.append(k);
-  ret.append(l);
-  return ret;
-}
-
-// The maximum number of bytes that it takes to encode a 64-bit varint.
-#define VARINT_MAX_LEN 10
-
-size_t vencode64(uint64_t val, int over_encoded_bytes, char *buf) {
-  if (val == 0) { buf[0] = 0; return 1; }
-  size_t i = 0;
-  while (val) {
-    uint8_t byte = val & 0x7fU;
-    val >>= 7;
-    if (val || over_encoded_bytes) byte |= 0x80U;
-    buf[i++] = byte;
-  }
-  while (over_encoded_bytes--) {
-    assert(i < 10);
-    uint8_t byte = over_encoded_bytes ? 0x80 : 0;
-    buf[i++] = byte;
-  }
-  return i;
-}
-
-string varint(uint64_t x) {
-  char buf[VARINT_MAX_LEN];
-  size_t len = vencode64(x, 0, buf);
-  return string(buf, len);
-}
-
-// Encodes a varint that is |extra| bytes longer than it needs to be, but still
-// valid.
-string longvarint(uint64_t x, int extra) {
-  char buf[VARINT_MAX_LEN];
-  size_t len = vencode64(x, extra, buf);
-  return string(buf, len);
-}
-
-// TODO: proper byte-swapping for big-endian machines.
-string fixed32(void *data) { return string(static_cast<char*>(data), 4); }
-string fixed64(void *data) { return string(static_cast<char*>(data), 8); }
-
-string delim(const string& buf) { return cat(varint(buf.size()), buf); }
-string u32(uint32_t u32) { return fixed32(&u32); }
-string u64(uint64_t u64) { return fixed64(&u64); }
-string flt(float f) { return fixed32(&f); }
-string dbl(double d) { return fixed64(&d); }
-string zz32(int32_t x) { return varint(WireFormatLite::ZigZagEncode32(x)); }
-string zz64(int64_t x) { return varint(WireFormatLite::ZigZagEncode64(x)); }
-
-string tag(uint32_t fieldnum, char wire_type) {
-  return varint((fieldnum << 3) | wire_type);
-}
-
-string submsg(uint32_t fn, const string& buf) {
-  return cat( tag(fn, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim(buf) );
-}
-
-#define UNKNOWN_FIELD 666
-
-const FieldDescriptor* GetFieldForType(FieldDescriptor::Type type,
-                                       bool repeated, bool isProto3) {
-
-  const Descriptor* d = isProto3 ?
-      TestAllTypesProto3().GetDescriptor() : TestAllTypesProto2().GetDescriptor();
-  for (int i = 0; i < d->field_count(); i++) {
-    const FieldDescriptor* f = d->field(i);
-    if (f->type() == type && f->is_repeated() == repeated) {
-      return f;
-    }
-  }
-  GOOGLE_LOG(FATAL) << "Couldn't find field with type " << (int)type;
-  return nullptr;
-}
-
-string UpperCase(string str) {
-  for (int i = 0; i < str.size(); i++) {
-    str[i] = toupper(str[i]);
-  }
-  return str;
-}
-
-}  // anonymous namespace
-
 namespace google {
 namespace protobuf {
 
+std::set<ConformanceTestSuite*> *conformance_test_suite_set;
+GOOGLE_PROTOBUF_DECLARE_ONCE(conformance_test_suite_set_init_);
+
+void DeleteConformanceTestSuiteSet() {
+  delete conformance_test_suite_set;
+}
+
+static void InitConformanceTestSuiteSet() {
+  conformance_test_suite_set = new std::set<ConformanceTestSuite*>();
+  internal::OnShutdown(&DeleteConformanceTestSuiteSet);
+}
+
+static void InitConformanceTestSuiteSetOnce() {
+  ::google::protobuf::GoogleOnceInit(
+      &conformance_test_suite_set_init_,
+      &InitConformanceTestSuiteSet);
+}
+
+void AddTestSuite(ConformanceTestSuite* suite) {
+  InitConformanceTestSuiteSetOnce();
+  conformance_test_suite_set->insert(suite);
+}
+
+const std::set<ConformanceTestSuite*>& GetTestSuiteSet() {
+  InitConformanceTestSuiteSetOnce();
+  return *conformance_test_suite_set;
+}
+
 ConformanceTestSuite::ConformanceRequestSetting::ConformanceRequestSetting(
-    ConformanceLevel level, conformance::WireFormat input_format,
+    ConformanceLevel level,
+    conformance::WireFormat input_format,
     conformance::WireFormat output_format,
     conformance::TestCategory test_category,
-    bool is_proto3,
+    const Message& prototype_message,
     const string& test_name, const string& input)
-    : level_(level), is_proto3_(is_proto3) {
-  auto newTestMessage = [&is_proto3]() {
-    Message* newMessage;
-    if (is_proto3) {
-      newMessage = new TestAllTypesProto3;
-    } else {
-      newMessage = new TestAllTypesProto2;
-    }
-    return newMessage;
-  };
-
-  string input_format_string;
-  string output_format_string;
-  string rname = is_proto3 ? ".Proto3" : ".Proto2";
-
+    : level_(level),
+      input_format_(input_format),
+      output_format_(output_format),
+      prototype_message_(prototype_message),
+      test_name_(test_name) {
   switch (input_format) {
     case conformance::PROTOBUF: {
       request_.set_protobuf_payload(input);
-      input_format_string = ".ProtobufInput.";
       break;
     }
 
     case conformance::JSON: {
       request_.set_json_payload(input);
-      input_format_string = ".JsonInput.";
       break;
     }
 
@@ -229,41 +112,74 @@
       GOOGLE_LOG(FATAL) << "Unspecified input format";
   }
 
-  switch (output_format) {
-    case conformance::PROTOBUF: {
-      output_format_string = ".ProtobufOutput";
-      break;
-    }
-
-    case conformance::JSON: {
-      output_format_string = ".JsonOutput";
-      break;
-    }
-
-    default:
-      GOOGLE_LOG(FATAL) << "Unspecified output format";
-  }
-
   request_.set_test_category(test_category);
 
-  test_name_ = ConformanceLevelToString(level) + rname +
-               input_format_string + test_name +
-               output_format_string;
-
-  if (is_proto3) {
-    request_.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3");
-  } else {
-    request_.set_message_type("protobuf_test_messages.proto2.TestAllTypesProto2");
-  }
+  request_.set_message_type(prototype_message.GetDescriptor()->full_name());
   request_.set_requested_output_format(output_format);
 }
 
-Message* ConformanceTestSuite::ConformanceRequestSetting::GetTestMessage() const {
-  if (is_proto3_) {
-    return new TestAllTypesProto3();
-  } else {
-    return new TestAllTypesProto2();
+Message* ConformanceTestSuite::ConformanceRequestSetting::
+    GetTestMessage() const {
+  return prototype_message_.New();
+}
+
+string ConformanceTestSuite::ConformanceRequestSetting::
+    GetTestName() const {
+  string rname =
+      prototype_message_.GetDescriptor()->file()->syntax() ==
+        FileDescriptor::SYNTAX_PROTO3 ? "Proto3" : "Proto2";
+
+  return StrCat(ConformanceLevelToString(level_), ".",
+                rname, ".",
+                InputFormatString(input_format_),
+                ".", test_name_, ".",
+                OutputFormatString(output_format_));
+}
+
+string ConformanceTestSuite::ConformanceRequestSetting::
+    ConformanceLevelToString(
+        ConformanceLevel level) const {
+  switch (level) {
+    case REQUIRED: return "Required";
+    case RECOMMENDED: return "Recommended";
   }
+  GOOGLE_LOG(FATAL) << "Unknown value: " << level;
+  return "";
+}
+
+string ConformanceTestSuite::ConformanceRequestSetting::
+    InputFormatString(conformance::WireFormat format) const {
+  switch (format) {
+    case conformance::PROTOBUF:
+      return "ProtobufInput";
+    case conformance::JSON:
+      return "JsonInput";
+    default:
+      GOOGLE_LOG(FATAL) << "Unspecified output format";
+  }
+  return "";
+}
+
+string ConformanceTestSuite::ConformanceRequestSetting::
+    OutputFormatString(conformance::WireFormat format) const {
+  switch (format) {
+    case conformance::PROTOBUF:
+      return "ProtobufOutput";
+    case conformance::JSON:
+      return "JsonOutput";
+    default:
+      GOOGLE_LOG(FATAL) << "Unspecified output format";
+  }
+  return "";
+}
+
+void ConformanceTestSuite::SetFailureList(
+    const string& filename,
+    const std::vector<string>& failure_list) {
+  failure_list_filename_ = filename;
+  expected_to_fail_.clear();
+  std::copy(failure_list.begin(), failure_list.end(),
+            std::inserter(expected_to_fail_, expected_to_fail_.end()));
 }
 
 void ConformanceTestSuite::ReportSuccess(const string& test_name) {
@@ -312,41 +228,6 @@
   skipped_.insert(test_name);
 }
 
-string ConformanceTestSuite::ConformanceLevelToString(ConformanceLevel level) {
-  switch (level) {
-    case REQUIRED: return "Required";
-    case RECOMMENDED: return "Recommended";
-  }
-  GOOGLE_LOG(FATAL) << "Unknown value: " << level;
-  return "";
-}
-
-void ConformanceTestSuite::RunTest(const string& test_name,
-                                   const ConformanceRequest& request,
-                                   ConformanceResponse* response) {
-  if (test_names_.insert(test_name).second == false) {
-    GOOGLE_LOG(FATAL) << "Duplicated test name: " << test_name;
-  }
-
-  string serialized_request;
-  string serialized_response;
-  request.SerializeToString(&serialized_request);
-
-  runner_->RunTest(test_name, serialized_request, &serialized_response);
-
-  if (!response->ParseFromString(serialized_response)) {
-    response->Clear();
-    response->set_runtime_error("response proto could not be parsed.");
-  }
-
-  if (verbose_) {
-    StringAppendF(&output_, "conformance test: name=%s, request=%s, response=%s\n",
-                  test_name.c_str(),
-                  request.ShortDebugString().c_str(),
-                  response->ShortDebugString().c_str());
-  }
-}
-
 void ConformanceTestSuite::RunValidInputTest(
     const ConformanceRequestSetting& setting,
     const string& equivalent_text_format) {
@@ -462,355 +343,38 @@
                   differences.c_str());
   }
 }
-void ConformanceTestSuite::ExpectParseFailureForProtoWithProtoVersion (
-    const string& proto, const string& test_name, ConformanceLevel level,
-    bool isProto3) {
-  ConformanceRequest request;
-  ConformanceResponse response;
-  request.set_protobuf_payload(proto);
-  request.set_test_category(conformance::BINARY_TEST);
-  if (isProto3) {
-    request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3");
-  } else {
-    request.set_message_type("protobuf_test_messages.proto2.TestAllTypesProto2");
+
+void ConformanceTestSuite::RunTest(const string& test_name,
+                                   const ConformanceRequest& request,
+                                   ConformanceResponse* response) {
+  if (test_names_.insert(test_name).second == false) {
+    GOOGLE_LOG(FATAL) << "Duplicated test name: " << test_name;
   }
-  string effective_test_name = ConformanceLevelToString(level) +
-      (isProto3 ? ".Proto3" : ".Proto2") +
-      ".ProtobufInput." + test_name;
 
-  // We don't expect output, but if the program erroneously accepts the protobuf
-  // we let it send its response as this.  We must not leave it unspecified.
-  request.set_requested_output_format(conformance::PROTOBUF);
+  string serialized_request;
+  string serialized_response;
+  request.SerializeToString(&serialized_request);
 
-  RunTest(effective_test_name, request, &response);
-  if (response.result_case() == ConformanceResponse::kParseError) {
-    ReportSuccess(effective_test_name);
-  } else if (response.result_case() == ConformanceResponse::kSkipped) {
-    ReportSkip(effective_test_name, request, response);
-  } else {
-    ReportFailure(effective_test_name, level, request, response,
-                  "Should have failed to parse, but didn't.");
+  runner_->RunTest(test_name, serialized_request, &serialized_response);
+
+  if (!response->ParseFromString(serialized_response)) {
+    response->Clear();
+    response->set_runtime_error("response proto could not be parsed.");
+  }
+
+  if (verbose_) {
+    StringAppendF(&output_,
+                  "conformance test: name=%s, request=%s, response=%s\n",
+                  test_name.c_str(),
+                  request.ShortDebugString().c_str(),
+                  response->ShortDebugString().c_str());
   }
 }
 
-// Expect that this precise protobuf will cause a parse error.
-void ConformanceTestSuite::ExpectParseFailureForProto(
-    const string& proto, const string& test_name, ConformanceLevel level) {
-  ExpectParseFailureForProtoWithProtoVersion(proto, test_name, level, true);
-  ExpectParseFailureForProtoWithProtoVersion(proto, test_name, level, false);
-}
-
-// Expect that this protobuf will cause a parse error, even if it is followed
-// by valid protobuf data.  We can try running this twice: once with this
-// data verbatim and once with this data followed by some valid data.
-//
-// TODO(haberman): implement the second of these.
-void ConformanceTestSuite::ExpectHardParseFailureForProto(
-    const string& proto, const string& test_name, ConformanceLevel level) {
-  return ExpectParseFailureForProto(proto, test_name, level);
-}
-
-void ConformanceTestSuite::RunValidJsonTest(
-    const string& test_name, ConformanceLevel level, const string& input_json,
-    const string& equivalent_text_format) {
-  ConformanceRequestSetting setting1(
-      level, conformance::JSON, conformance::PROTOBUF,
-      conformance::JSON_TEST,
-      true, test_name, input_json);
-  RunValidInputTest(setting1, equivalent_text_format);
-
-  ConformanceRequestSetting setting2(
-      level, conformance::JSON, conformance::JSON,
-      conformance::JSON_TEST,
-      true, test_name, input_json);
-  RunValidInputTest(setting2, equivalent_text_format);
-}
-
-void ConformanceTestSuite::RunValidJsonTestWithProtobufInput(
-    const string& test_name, ConformanceLevel level, const TestAllTypesProto3& input,
-    const string& equivalent_text_format) {
-  ConformanceRequestSetting setting(
-      level, conformance::PROTOBUF, conformance::JSON,
-      conformance::JSON_TEST,
-      true, test_name, input.SerializeAsString());
-  RunValidInputTest(setting, equivalent_text_format);
-}
-
-void ConformanceTestSuite::RunValidJsonIgnoreUnknownTest(
-    const string& test_name, ConformanceLevel level, const string& input_json,
-    const string& equivalent_text_format) {
-  ConformanceRequestSetting setting(
-      level, conformance::JSON, conformance::PROTOBUF,
-      conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST,
-      true, test_name, input_json);
-  RunValidInputTest(setting, equivalent_text_format);
-}
-
-void ConformanceTestSuite::RunValidProtobufTest(
-    const string& test_name, ConformanceLevel level,
-    const string& input_protobuf, const string& equivalent_text_format,
-    bool isProto3) {
-  ConformanceRequestSetting setting1(
-      level, conformance::PROTOBUF, conformance::PROTOBUF,
-      conformance::BINARY_TEST,
-      isProto3, test_name, input_protobuf);
-  RunValidInputTest(setting1, equivalent_text_format);
-
-  if (isProto3) {
-    ConformanceRequestSetting setting2(
-        level, conformance::PROTOBUF, conformance::JSON,
-        conformance::BINARY_TEST,
-        true, test_name, input_protobuf);
-    RunValidInputTest(setting2, equivalent_text_format);
-  }
-}
-
-void ConformanceTestSuite::RunValidBinaryProtobufTest(
-    const string& test_name, ConformanceLevel level,
-    const string& input_protobuf, bool isProto3) {
-  ConformanceRequestSetting setting(
-      level, conformance::PROTOBUF, conformance::PROTOBUF,
-      conformance::BINARY_TEST,
-      isProto3, test_name, input_protobuf);
-  RunValidBinaryInputTest(setting, input_protobuf);
-}
-
-void ConformanceTestSuite::RunValidProtobufTestWithMessage(
-    const string& test_name, ConformanceLevel level, const Message *input,
-    const string& equivalent_text_format, bool isProto3) {
-  RunValidProtobufTest(test_name, level, input->SerializeAsString(), equivalent_text_format, isProto3);
-}
-
-// According to proto3 JSON specification, JSON serializers follow more strict
-// rules than parsers (e.g., a serializer must serialize int32 values as JSON
-// numbers while the parser is allowed to accept them as JSON strings). This
-// method allows strict checking on a proto3 JSON serializer by inspecting
-// the JSON output directly.
-void ConformanceTestSuite::RunValidJsonTestWithValidator(
-    const string& test_name, ConformanceLevel level, const string& input_json,
-    const Validator& validator) {
-  ConformanceRequest request;
-  ConformanceResponse response;
-  request.set_json_payload(input_json);
-  request.set_requested_output_format(conformance::JSON);
-  request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3");
-
-  string effective_test_name = ConformanceLevelToString(level) +
-      ".Proto3.JsonInput." + test_name + ".Validator";
-
-  RunTest(effective_test_name, request, &response);
-
-  if (response.result_case() == ConformanceResponse::kSkipped) {
-    ReportSkip(effective_test_name, request, response);
-    return;
-  }
-
-  if (response.result_case() != ConformanceResponse::kJsonPayload) {
-    ReportFailure(effective_test_name, level, request, response,
-                  "Expected JSON payload but got type %d.",
-                  response.result_case());
-    return;
-  }
-  Json::Reader reader;
-  Json::Value value;
-  if (!reader.parse(response.json_payload(), value)) {
-    ReportFailure(effective_test_name, level, request, response,
-                  "JSON payload cannot be parsed as valid JSON: %s",
-                  reader.getFormattedErrorMessages().c_str());
-    return;
-  }
-  if (!validator(value)) {
-    ReportFailure(effective_test_name, level, request, response,
-                  "JSON payload validation failed.");
-    return;
-  }
-  ReportSuccess(effective_test_name);
-}
-
-void ConformanceTestSuite::ExpectParseFailureForJson(
-    const string& test_name, ConformanceLevel level, const string& input_json) {
-  ConformanceRequest request;
-  ConformanceResponse response;
-  request.set_json_payload(input_json);
-  request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3");
-  string effective_test_name =
-      ConformanceLevelToString(level) + ".Proto3.JsonInput." + test_name;
-
-  // We don't expect output, but if the program erroneously accepts the protobuf
-  // we let it send its response as this.  We must not leave it unspecified.
-  request.set_requested_output_format(conformance::JSON);
-
-  RunTest(effective_test_name, request, &response);
-  if (response.result_case() == ConformanceResponse::kParseError) {
-    ReportSuccess(effective_test_name);
-  } else if (response.result_case() == ConformanceResponse::kSkipped) {
-    ReportSkip(effective_test_name, request, response);
-  } else {
-    ReportFailure(effective_test_name, level, request, response,
-                  "Should have failed to parse, but didn't.");
-  }
-}
-
-void ConformanceTestSuite::ExpectSerializeFailureForJson(
-    const string& test_name, ConformanceLevel level, const string& text_format) {
-  TestAllTypesProto3 payload_message;
-  GOOGLE_CHECK(
-      TextFormat::ParseFromString(text_format, &payload_message))
-          << "Failed to parse: " << text_format;
-
-  ConformanceRequest request;
-  ConformanceResponse response;
-  request.set_protobuf_payload(payload_message.SerializeAsString());
-  request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3");
-  string effective_test_name =
-      ConformanceLevelToString(level) + "." + test_name + ".JsonOutput";
-  request.set_requested_output_format(conformance::JSON);
-
-  RunTest(effective_test_name, request, &response);
-  if (response.result_case() == ConformanceResponse::kSerializeError) {
-    ReportSuccess(effective_test_name);
-  } else if (response.result_case() == ConformanceResponse::kSkipped) {
-    ReportSkip(effective_test_name, request, response);
-  } else {
-    ReportFailure(effective_test_name, level, request, response,
-                  "Should have failed to serialize, but didn't.");
-  }
-}
-
-//TODO: proto2?
-void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
-  // Incomplete values for each wire type.
-  static const string incompletes[6] = {
-    string("\x80"),     // VARINT
-    string("abcdefg"),  // 64BIT
-    string("\x80"),     // DELIMITED (partial length)
-    string(),           // START_GROUP (no value required)
-    string(),           // END_GROUP (no value required)
-    string("abc")       // 32BIT
-  };
-
-  const FieldDescriptor* field = GetFieldForType(type, false, true);
-  const FieldDescriptor* rep_field = GetFieldForType(type, true, true);
-  WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType(
-      static_cast<WireFormatLite::FieldType>(type));
-  const string& incomplete = incompletes[wire_type];
-  const string type_name =
-      UpperCase(string(".") + FieldDescriptor::TypeName(type));
-
-  ExpectParseFailureForProto(
-      tag(field->number(), wire_type),
-      "PrematureEofBeforeKnownNonRepeatedValue" + type_name, REQUIRED);
-
-  ExpectParseFailureForProto(
-      tag(rep_field->number(), wire_type),
-      "PrematureEofBeforeKnownRepeatedValue" + type_name, REQUIRED);
-
-  ExpectParseFailureForProto(
-      tag(UNKNOWN_FIELD, wire_type),
-      "PrematureEofBeforeUnknownValue" + type_name, REQUIRED);
-
-  ExpectParseFailureForProto(
-      cat( tag(field->number(), wire_type), incomplete ),
-      "PrematureEofInsideKnownNonRepeatedValue" + type_name, REQUIRED);
-
-  ExpectParseFailureForProto(
-      cat( tag(rep_field->number(), wire_type), incomplete ),
-      "PrematureEofInsideKnownRepeatedValue" + type_name, REQUIRED);
-
-  ExpectParseFailureForProto(
-      cat( tag(UNKNOWN_FIELD, wire_type), incomplete ),
-      "PrematureEofInsideUnknownValue" + type_name, REQUIRED);
-
-  if (wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
-    ExpectParseFailureForProto(
-        cat( tag(field->number(), wire_type), varint(1) ),
-        "PrematureEofInDelimitedDataForKnownNonRepeatedValue" + type_name,
-        REQUIRED);
-
-    ExpectParseFailureForProto(
-        cat( tag(rep_field->number(), wire_type), varint(1) ),
-        "PrematureEofInDelimitedDataForKnownRepeatedValue" + type_name,
-        REQUIRED);
-
-    // EOF in the middle of delimited data for unknown value.
-    ExpectParseFailureForProto(
-        cat( tag(UNKNOWN_FIELD, wire_type), varint(1) ),
-        "PrematureEofInDelimitedDataForUnknownValue" + type_name, REQUIRED);
-
-    if (type == FieldDescriptor::TYPE_MESSAGE) {
-      // Submessage ends in the middle of a value.
-      string incomplete_submsg =
-          cat( tag(WireFormatLite::TYPE_INT32, WireFormatLite::WIRETYPE_VARINT),
-                incompletes[WireFormatLite::WIRETYPE_VARINT] );
-      ExpectHardParseFailureForProto(
-          cat( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
-               varint(incomplete_submsg.size()),
-               incomplete_submsg ),
-          "PrematureEofInSubmessageValue" + type_name, REQUIRED);
-    }
-  } else if (type != FieldDescriptor::TYPE_GROUP) {
-    // Non-delimited, non-group: eligible for packing.
-
-    // Packed region ends in the middle of a value.
-    ExpectHardParseFailureForProto(
-        cat(tag(rep_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
-            varint(incomplete.size()), incomplete),
-        "PrematureEofInPackedFieldValue" + type_name, REQUIRED);
-
-    // EOF in the middle of packed region.
-    ExpectParseFailureForProto(
-        cat(tag(rep_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
-            varint(1)),
-        "PrematureEofInPackedField" + type_name, REQUIRED);
-  }
-}
-
-void ConformanceTestSuite::TestValidDataForType(
-    FieldDescriptor::Type type,
-    std::vector<std::pair<std::string, std::string>> values) {
-  for (int isProto3 = 0; isProto3 < 2; isProto3++) {
-    const string type_name =
-        UpperCase(string(".") + FieldDescriptor::TypeName(type));
-    WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType(
-        static_cast<WireFormatLite::FieldType>(type));
-    const FieldDescriptor* field = GetFieldForType(type, false, isProto3);
-    const FieldDescriptor* rep_field = GetFieldForType(type, true, isProto3);
-
-    RunValidProtobufTest("ValidDataScalar" + type_name, REQUIRED,
-                         cat(tag(field->number(), wire_type), values[0].first),
-                         field->name() + ": " + values[0].second, isProto3);
-
-    string proto;
-    string text = field->name() + ": " + values.back().second;
-    for (size_t i = 0; i < values.size(); i++) {
-      proto += cat(tag(field->number(), wire_type), values[i].first);
-    }
-    RunValidProtobufTest("RepeatedScalarSelectsLast" + type_name, REQUIRED,
-                         proto, text, isProto3);
-
-    proto.clear();
-    text.clear();
-
-    for (size_t i = 0; i < values.size(); i++) {
-      proto += cat(tag(rep_field->number(), wire_type), values[i].first);
-      text += rep_field->name() + ": " + values[i].second + " ";
-    }
-    RunValidProtobufTest("ValidDataRepeated" + type_name, REQUIRED,
-                         proto, text, isProto3);
-  }
-}
-
-void ConformanceTestSuite::SetFailureList(const string& filename,
-                                          const std::vector<string>& failure_list) {
-  failure_list_filename_ = filename;
-  expected_to_fail_.clear();
-  std::copy(failure_list.begin(), failure_list.end(),
-            std::inserter(expected_to_fail_, expected_to_fail_.end()));
-}
-
-bool ConformanceTestSuite::CheckSetEmpty(const std::set<string>& set_to_check,
-                                         const std::string& write_to_file,
-                                         const std::string& msg) {
+bool ConformanceTestSuite::CheckSetEmpty(
+    const std::set<string>& set_to_check,
+    const std::string& write_to_file,
+    const std::string& msg) {
   if (set_to_check.empty()) {
     return true;
   } else {
@@ -839,70 +403,8 @@
   }
 }
 
-// TODO: proto2?
-void ConformanceTestSuite::TestIllegalTags() {
-  // field num 0 is illegal
-  string nullfield[] = {
-    "\1DEADBEEF",
-    "\2\1\1",
-    "\3\4",
-    "\5DEAD"
-  };
-  for (int i = 0; i < 4; i++) {
-    string name = "IllegalZeroFieldNum_Case_0";
-    name.back() += i;
-    ExpectParseFailureForProto(nullfield[i], name, REQUIRED);
-  }
-}
-template <class MessageType>
-void ConformanceTestSuite::TestOneofMessage (MessageType &message,
-                                             bool isProto3) {
-  message.set_oneof_uint32(0);
-  RunValidProtobufTestWithMessage(
-      "OneofZeroUint32", RECOMMENDED, &message, "oneof_uint32: 0", isProto3);
-  message.mutable_oneof_nested_message()->set_a(0);
-  RunValidProtobufTestWithMessage(
-      "OneofZeroMessage", RECOMMENDED, &message,
-      isProto3 ? "oneof_nested_message: {}" : "oneof_nested_message: {a: 0}",
-      isProto3);
-  message.mutable_oneof_nested_message()->set_a(1);
-  RunValidProtobufTestWithMessage(
-      "OneofZeroMessageSetTwice", RECOMMENDED, &message,
-      "oneof_nested_message: {a: 1}",
-      isProto3);
-  message.set_oneof_string("");
-  RunValidProtobufTestWithMessage(
-      "OneofZeroString", RECOMMENDED, &message, "oneof_string: \"\"", isProto3);
-  message.set_oneof_bytes("");
-  RunValidProtobufTestWithMessage(
-      "OneofZeroBytes", RECOMMENDED, &message, "oneof_bytes: \"\"", isProto3);
-  message.set_oneof_bool(false);
-  RunValidProtobufTestWithMessage(
-      "OneofZeroBool", RECOMMENDED, &message, "oneof_bool: false", isProto3);
-  message.set_oneof_uint64(0);
-  RunValidProtobufTestWithMessage(
-      "OneofZeroUint64", RECOMMENDED, &message, "oneof_uint64: 0", isProto3);
-  message.set_oneof_float(0.0f);
-  RunValidProtobufTestWithMessage(
-      "OneofZeroFloat", RECOMMENDED, &message, "oneof_float: 0", isProto3);
-  message.set_oneof_double(0.0);
-  RunValidProtobufTestWithMessage(
-      "OneofZeroDouble", RECOMMENDED, &message, "oneof_double: 0", isProto3);
-  message.set_oneof_enum(MessageType::FOO);
-  RunValidProtobufTestWithMessage(
-      "OneofZeroEnum", RECOMMENDED, &message, "oneof_enum: FOO", isProto3);
-}
-
-template <class MessageType>
-void ConformanceTestSuite::TestUnknownMessage(MessageType& message,
-                                              bool isProto3) {
-  message.ParseFromString("\xA8\x1F\x01");
-  RunValidBinaryProtobufTest("UnknownVarint", REQUIRED,
-                             message.SerializeAsString(), isProto3);
-}
-
-bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
-                                    std::string* output) {
+bool ConformanceTestSuite::RunSuite(
+    ConformanceTestRunner* runner, std::string* output) {
   runner_ = runner;
   successes_ = 0;
   expected_failures_ = 0;
@@ -910,1714 +412,10 @@
   test_names_.clear();
   unexpected_failing_tests_.clear();
   unexpected_succeeding_tests_.clear();
-  type_resolver_.reset(NewTypeResolverForDescriptorPool(
-      kTypeUrlPrefix, DescriptorPool::generated_pool()));
-  type_url_ = GetTypeUrl(TestAllTypesProto3::descriptor());
 
   output_ = "\nCONFORMANCE TEST BEGIN ====================================\n\n";
 
-  for (int i = 1; i <= FieldDescriptor::MAX_TYPE; i++) {
-    if (i == FieldDescriptor::TYPE_GROUP) continue;
-    TestPrematureEOFForType(static_cast<FieldDescriptor::Type>(i));
-  }
-
-  TestIllegalTags();
-
-  int64 kInt64Min = -9223372036854775808ULL;
-  int64 kInt64Max = 9223372036854775807ULL;
-  uint64 kUint64Max = 18446744073709551615ULL;
-  int32 kInt32Max = 2147483647;
-  int32 kInt32Min = -2147483648;
-  uint32 kUint32Max = 4294967295UL;
-
-  TestValidDataForType(FieldDescriptor::TYPE_DOUBLE, {
-    {dbl(0.1), "0.1"},
-    {dbl(1.7976931348623157e+308), "1.7976931348623157e+308"},
-    {dbl(2.22507385850720138309e-308), "2.22507385850720138309e-308"}
-  });
-  TestValidDataForType(FieldDescriptor::TYPE_FLOAT, {
-    {flt(0.1), "0.1"},
-    {flt(1.00000075e-36), "1.00000075e-36"},
-    {flt(3.402823e+38), "3.402823e+38"},  // 3.40282347e+38
-    {flt(1.17549435e-38f), "1.17549435e-38"}
-  });
-  TestValidDataForType(FieldDescriptor::TYPE_INT64, {
-    {varint(12345), "12345"},
-    {varint(kInt64Max), std::to_string(kInt64Max)},
-    {varint(kInt64Min), std::to_string(kInt64Min)}
-  });
-  TestValidDataForType(FieldDescriptor::TYPE_UINT64, {
-    {varint(12345), "12345"},
-    {varint(kUint64Max), std::to_string(kUint64Max)},
-    {varint(0), "0"}
-  });
-  TestValidDataForType(FieldDescriptor::TYPE_INT32, {
-    {varint(12345), "12345"},
-    {longvarint(12345, 2), "12345"},
-    {longvarint(12345, 7), "12345"},
-    {varint(kInt32Max), std::to_string(kInt32Max)},
-    {varint(kInt32Min), std::to_string(kInt32Min)},
-    {varint(1LL << 33), std::to_string(static_cast<int32>(1LL << 33))},
-    {varint((1LL << 33) - 1),
-     std::to_string(static_cast<int32>((1LL << 33) - 1))},
-  });
-  TestValidDataForType(FieldDescriptor::TYPE_UINT32, {
-    {varint(12345), "12345"},
-    {longvarint(12345, 2), "12345"},
-    {longvarint(12345, 7), "12345"},
-    {varint(kUint32Max), std::to_string(kUint32Max)},  // UINT32_MAX
-    {varint(0), "0"},
-    {varint(1LL << 33), std::to_string(static_cast<uint32>(1LL << 33))},
-    {varint((1LL << 33) - 1),
-     std::to_string(static_cast<uint32>((1LL << 33) - 1))},
-  });
-  TestValidDataForType(FieldDescriptor::TYPE_FIXED64, {
-    {u64(12345), "12345"},
-    {u64(kUint64Max), std::to_string(kUint64Max)},
-    {u64(0), "0"}
-  });
-  TestValidDataForType(FieldDescriptor::TYPE_FIXED32, {
-    {u32(12345), "12345"},
-    {u32(kUint32Max), std::to_string(kUint32Max)},  // UINT32_MAX
-    {u32(0), "0"}
-  });
-  TestValidDataForType(FieldDescriptor::TYPE_SFIXED64, {
-    {u64(12345), "12345"},
-    {u64(kInt64Max), std::to_string(kInt64Max)},
-    {u64(kInt64Min), std::to_string(kInt64Min)}
-  });
-  TestValidDataForType(FieldDescriptor::TYPE_SFIXED32, {
-    {u32(12345), "12345"},
-    {u32(kInt32Max), std::to_string(kInt32Max)},
-    {u32(kInt32Min), std::to_string(kInt32Min)}
-  });
-  TestValidDataForType(FieldDescriptor::TYPE_BOOL, {
-    {varint(1), "true"},
-    {varint(0), "false"},
-    {varint(12345678), "true"}
-  });
-  TestValidDataForType(FieldDescriptor::TYPE_SINT32, {
-    {zz32(12345), "12345"},
-    {zz32(kInt32Max), std::to_string(kInt32Max)},
-    {zz32(kInt32Min), std::to_string(kInt32Min)}
-  });
-  TestValidDataForType(FieldDescriptor::TYPE_SINT64, {
-    {zz64(12345), "12345"},
-    {zz64(kInt64Max), std::to_string(kInt64Max)},
-    {zz64(kInt64Min), std::to_string(kInt64Min)}
-  });
-
-  // TODO(haberman):
-  // TestValidDataForType(FieldDescriptor::TYPE_STRING
-  // TestValidDataForType(FieldDescriptor::TYPE_GROUP
-  // TestValidDataForType(FieldDescriptor::TYPE_MESSAGE
-  // TestValidDataForType(FieldDescriptor::TYPE_BYTES
-  // TestValidDataForType(FieldDescriptor::TYPE_ENUM
-
-  RunValidJsonTest("HelloWorld", REQUIRED,
-                   "{\"optionalString\":\"Hello, World!\"}",
-                   "optional_string: 'Hello, World!'");
-
-  // NOTE: The spec for JSON support is still being sorted out, these may not
-  // all be correct.
-  // Test field name conventions.
-  RunValidJsonTest(
-      "FieldNameInSnakeCase", REQUIRED,
-      R"({
-        "fieldname1": 1,
-        "fieldName2": 2,
-        "FieldName3": 3,
-        "fieldName4": 4
-      })",
-      R"(
-        fieldname1: 1
-        field_name2: 2
-        _field_name3: 3
-        field__name4_: 4
-      )");
-  RunValidJsonTest(
-      "FieldNameWithNumbers", REQUIRED,
-      R"({
-        "field0name5": 5,
-        "field0Name6": 6
-      })",
-      R"(
-        field0name5: 5
-        field_0_name6: 6
-      )");
-  RunValidJsonTest(
-      "FieldNameWithMixedCases", REQUIRED,
-      R"({
-        "fieldName7": 7,
-        "FieldName8": 8,
-        "fieldName9": 9,
-        "FieldName10": 10,
-        "FIELDNAME11": 11,
-        "FIELDName12": 12
-      })",
-      R"(
-        fieldName7: 7
-        FieldName8: 8
-        field_Name9: 9
-        Field_Name10: 10
-        FIELD_NAME11: 11
-        FIELD_name12: 12
-      )");
-  RunValidJsonTest(
-      "FieldNameWithDoubleUnderscores", RECOMMENDED,
-      R"({
-        "FieldName13": 13,
-        "FieldName14": 14,
-        "fieldName15": 15,
-        "fieldName16": 16,
-        "fieldName17": 17,
-        "FieldName18": 18
-      })",
-      R"(
-        __field_name13: 13
-        __Field_name14: 14
-        field__name15: 15
-        field__Name16: 16
-        field_name17__: 17
-        Field_name18__: 18
-      )");
-  // Using the original proto field name in JSON is also allowed.
-  RunValidJsonTest(
-      "OriginalProtoFieldName", REQUIRED,
-      R"({
-        "fieldname1": 1,
-        "field_name2": 2,
-        "_field_name3": 3,
-        "field__name4_": 4,
-        "field0name5": 5,
-        "field_0_name6": 6,
-        "fieldName7": 7,
-        "FieldName8": 8,
-        "field_Name9": 9,
-        "Field_Name10": 10,
-        "FIELD_NAME11": 11,
-        "FIELD_name12": 12,
-        "__field_name13": 13,
-        "__Field_name14": 14,
-        "field__name15": 15,
-        "field__Name16": 16,
-        "field_name17__": 17,
-        "Field_name18__": 18
-      })",
-      R"(
-        fieldname1: 1
-        field_name2: 2
-        _field_name3: 3
-        field__name4_: 4
-        field0name5: 5
-        field_0_name6: 6
-        fieldName7: 7
-        FieldName8: 8
-        field_Name9: 9
-        Field_Name10: 10
-        FIELD_NAME11: 11
-        FIELD_name12: 12
-        __field_name13: 13
-        __Field_name14: 14
-        field__name15: 15
-        field__Name16: 16
-        field_name17__: 17
-        Field_name18__: 18
-      )");
-  // Field names can be escaped.
-  RunValidJsonTest(
-      "FieldNameEscaped", REQUIRED,
-      R"({"fieldn\u0061me1": 1})",
-      "fieldname1: 1");
-  // String ends with escape character.
-  ExpectParseFailureForJson(
-      "StringEndsWithEscapeChar", RECOMMENDED,
-      "{\"optionalString\": \"abc\\");
-  // Field names must be quoted (or it's not valid JSON).
-  ExpectParseFailureForJson(
-      "FieldNameNotQuoted", RECOMMENDED,
-      "{fieldname1: 1}");
-  // Trailing comma is not allowed (not valid JSON).
-  ExpectParseFailureForJson(
-      "TrailingCommaInAnObject", RECOMMENDED,
-      R"({"fieldname1":1,})");
-  ExpectParseFailureForJson(
-      "TrailingCommaInAnObjectWithSpace", RECOMMENDED,
-      R"({"fieldname1":1 ,})");
-  ExpectParseFailureForJson(
-      "TrailingCommaInAnObjectWithSpaceCommaSpace", RECOMMENDED,
-      R"({"fieldname1":1 , })");
-  ExpectParseFailureForJson(
-      "TrailingCommaInAnObjectWithNewlines", RECOMMENDED,
-      R"({
-        "fieldname1":1,
-      })");
-  // JSON doesn't support comments.
-  ExpectParseFailureForJson(
-      "JsonWithComments", RECOMMENDED,
-      R"({
-        // This is a comment.
-        "fieldname1": 1
-      })");
-  // JSON spec says whitespace doesn't matter, so try a few spacings to be sure.
-  RunValidJsonTest(
-      "OneLineNoSpaces", RECOMMENDED,
-      "{\"optionalInt32\":1,\"optionalInt64\":2}",
-      R"(
-        optional_int32: 1
-        optional_int64: 2
-      )");
-  RunValidJsonTest(
-      "OneLineWithSpaces", RECOMMENDED,
-      "{ \"optionalInt32\" : 1 , \"optionalInt64\" : 2 }",
-      R"(
-        optional_int32: 1
-        optional_int64: 2
-      )");
-  RunValidJsonTest(
-      "MultilineNoSpaces", RECOMMENDED,
-      "{\n\"optionalInt32\"\n:\n1\n,\n\"optionalInt64\"\n:\n2\n}",
-      R"(
-        optional_int32: 1
-        optional_int64: 2
-      )");
-  RunValidJsonTest(
-      "MultilineWithSpaces", RECOMMENDED,
-      "{\n  \"optionalInt32\"  :  1\n  ,\n  \"optionalInt64\"  :  2\n}\n",
-      R"(
-        optional_int32: 1
-        optional_int64: 2
-      )");
-  // Missing comma between key/value pairs.
-  ExpectParseFailureForJson(
-      "MissingCommaOneLine", RECOMMENDED,
-      "{ \"optionalInt32\": 1 \"optionalInt64\": 2 }");
-  ExpectParseFailureForJson(
-      "MissingCommaMultiline", RECOMMENDED,
-      "{\n  \"optionalInt32\": 1\n  \"optionalInt64\": 2\n}");
-  // Duplicated field names are not allowed.
-  ExpectParseFailureForJson(
-      "FieldNameDuplicate", RECOMMENDED,
-      R"({
-        "optionalNestedMessage": {a: 1},
-        "optionalNestedMessage": {}
-      })");
-  ExpectParseFailureForJson(
-      "FieldNameDuplicateDifferentCasing1", RECOMMENDED,
-      R"({
-        "optional_nested_message": {a: 1},
-        "optionalNestedMessage": {}
-      })");
-  ExpectParseFailureForJson(
-      "FieldNameDuplicateDifferentCasing2", RECOMMENDED,
-      R"({
-        "optionalNestedMessage": {a: 1},
-        "optional_nested_message": {}
-      })");
-  // Serializers should use lowerCamelCase by default.
-  RunValidJsonTestWithValidator(
-      "FieldNameInLowerCamelCase", REQUIRED,
-      R"({
-        "fieldname1": 1,
-        "fieldName2": 2,
-        "FieldName3": 3,
-        "fieldName4": 4
-      })",
-      [](const Json::Value& value) {
-        return value.isMember("fieldname1") &&
-            value.isMember("fieldName2") &&
-            value.isMember("FieldName3") &&
-            value.isMember("fieldName4");
-      });
-  RunValidJsonTestWithValidator(
-      "FieldNameWithNumbers", REQUIRED,
-      R"({
-        "field0name5": 5,
-        "field0Name6": 6
-      })",
-      [](const Json::Value& value) {
-        return value.isMember("field0name5") &&
-            value.isMember("field0Name6");
-      });
-  RunValidJsonTestWithValidator(
-      "FieldNameWithMixedCases", REQUIRED,
-      R"({
-        "fieldName7": 7,
-        "FieldName8": 8,
-        "fieldName9": 9,
-        "FieldName10": 10,
-        "FIELDNAME11": 11,
-        "FIELDName12": 12
-      })",
-      [](const Json::Value& value) {
-        return value.isMember("fieldName7") &&
-            value.isMember("FieldName8") &&
-            value.isMember("fieldName9") &&
-            value.isMember("FieldName10") &&
-            value.isMember("FIELDNAME11") &&
-            value.isMember("FIELDName12");
-      });
-  RunValidJsonTestWithValidator(
-      "FieldNameWithDoubleUnderscores", RECOMMENDED,
-      R"({
-        "FieldName13": 13,
-        "FieldName14": 14,
-        "fieldName15": 15,
-        "fieldName16": 16,
-        "fieldName17": 17,
-        "FieldName18": 18
-      })",
-      [](const Json::Value& value) {
-        return value.isMember("FieldName13") &&
-            value.isMember("FieldName14") &&
-            value.isMember("fieldName15") &&
-            value.isMember("fieldName16") &&
-            value.isMember("fieldName17") &&
-            value.isMember("FieldName18");
-      });
-
-  // Integer fields.
-  RunValidJsonTest(
-      "Int32FieldMaxValue", REQUIRED,
-      R"({"optionalInt32": 2147483647})",
-      "optional_int32: 2147483647");
-  RunValidJsonTest(
-      "Int32FieldMinValue", REQUIRED,
-      R"({"optionalInt32": -2147483648})",
-      "optional_int32: -2147483648");
-  RunValidJsonTest(
-      "Uint32FieldMaxValue", REQUIRED,
-      R"({"optionalUint32": 4294967295})",
-      "optional_uint32: 4294967295");
-  RunValidJsonTest(
-      "Int64FieldMaxValue", REQUIRED,
-      R"({"optionalInt64": "9223372036854775807"})",
-      "optional_int64: 9223372036854775807");
-  RunValidJsonTest(
-      "Int64FieldMinValue", REQUIRED,
-      R"({"optionalInt64": "-9223372036854775808"})",
-      "optional_int64: -9223372036854775808");
-  RunValidJsonTest(
-      "Uint64FieldMaxValue", REQUIRED,
-      R"({"optionalUint64": "18446744073709551615"})",
-      "optional_uint64: 18446744073709551615");
-  // While not the largest Int64, this is the largest
-  // Int64 which can be exactly represented within an
-  // IEEE-754 64-bit float, which is the expected level
-  // of interoperability guarantee. Larger values may
-  // work in some implementations, but should not be
-  // relied upon.
-  RunValidJsonTest(
-      "Int64FieldMaxValueNotQuoted", REQUIRED,
-      R"({"optionalInt64": 9223372036854774784})",
-      "optional_int64: 9223372036854774784");
-  RunValidJsonTest(
-      "Int64FieldMinValueNotQuoted", REQUIRED,
-      R"({"optionalInt64": -9223372036854775808})",
-      "optional_int64: -9223372036854775808");
-  // Largest interoperable Uint64; see comment above
-  // for Int64FieldMaxValueNotQuoted.
-  RunValidJsonTest(
-      "Uint64FieldMaxValueNotQuoted", REQUIRED,
-      R"({"optionalUint64": 18446744073709549568})",
-      "optional_uint64: 18446744073709549568");
-  // Values can be represented as JSON strings.
-  RunValidJsonTest(
-      "Int32FieldStringValue", REQUIRED,
-      R"({"optionalInt32": "2147483647"})",
-      "optional_int32: 2147483647");
-  RunValidJsonTest(
-      "Int32FieldStringValueEscaped", REQUIRED,
-      R"({"optionalInt32": "2\u003147483647"})",
-      "optional_int32: 2147483647");
-
-  // Parsers reject out-of-bound integer values.
-  ExpectParseFailureForJson(
-      "Int32FieldTooLarge", REQUIRED,
-      R"({"optionalInt32": 2147483648})");
-  ExpectParseFailureForJson(
-      "Int32FieldTooSmall", REQUIRED,
-      R"({"optionalInt32": -2147483649})");
-  ExpectParseFailureForJson(
-      "Uint32FieldTooLarge", REQUIRED,
-      R"({"optionalUint32": 4294967296})");
-  ExpectParseFailureForJson(
-      "Int64FieldTooLarge", REQUIRED,
-      R"({"optionalInt64": "9223372036854775808"})");
-  ExpectParseFailureForJson(
-      "Int64FieldTooSmall", REQUIRED,
-      R"({"optionalInt64": "-9223372036854775809"})");
-  ExpectParseFailureForJson(
-      "Uint64FieldTooLarge", REQUIRED,
-      R"({"optionalUint64": "18446744073709551616"})");
-  // Parser reject non-integer numeric values as well.
-  ExpectParseFailureForJson(
-      "Int32FieldNotInteger", REQUIRED,
-      R"({"optionalInt32": 0.5})");
-  ExpectParseFailureForJson(
-      "Uint32FieldNotInteger", REQUIRED,
-      R"({"optionalUint32": 0.5})");
-  ExpectParseFailureForJson(
-      "Int64FieldNotInteger", REQUIRED,
-      R"({"optionalInt64": "0.5"})");
-  ExpectParseFailureForJson(
-      "Uint64FieldNotInteger", REQUIRED,
-      R"({"optionalUint64": "0.5"})");
-
-  // Integers but represented as float values are accepted.
-  RunValidJsonTest(
-      "Int32FieldFloatTrailingZero", REQUIRED,
-      R"({"optionalInt32": 100000.000})",
-      "optional_int32: 100000");
-  RunValidJsonTest(
-      "Int32FieldExponentialFormat", REQUIRED,
-      R"({"optionalInt32": 1e5})",
-      "optional_int32: 100000");
-  RunValidJsonTest(
-      "Int32FieldMaxFloatValue", REQUIRED,
-      R"({"optionalInt32": 2.147483647e9})",
-      "optional_int32: 2147483647");
-  RunValidJsonTest(
-      "Int32FieldMinFloatValue", REQUIRED,
-      R"({"optionalInt32": -2.147483648e9})",
-      "optional_int32: -2147483648");
-  RunValidJsonTest(
-      "Uint32FieldMaxFloatValue", REQUIRED,
-      R"({"optionalUint32": 4.294967295e9})",
-      "optional_uint32: 4294967295");
-
-  // Parser reject non-numeric values.
-  ExpectParseFailureForJson(
-      "Int32FieldNotNumber", REQUIRED,
-      R"({"optionalInt32": "3x3"})");
-  ExpectParseFailureForJson(
-      "Uint32FieldNotNumber", REQUIRED,
-      R"({"optionalUint32": "3x3"})");
-  ExpectParseFailureForJson(
-      "Int64FieldNotNumber", REQUIRED,
-      R"({"optionalInt64": "3x3"})");
-  ExpectParseFailureForJson(
-      "Uint64FieldNotNumber", REQUIRED,
-      R"({"optionalUint64": "3x3"})");
-  // JSON does not allow "+" on numric values.
-  ExpectParseFailureForJson(
-      "Int32FieldPlusSign", REQUIRED,
-      R"({"optionalInt32": +1})");
-  // JSON doesn't allow leading 0s.
-  ExpectParseFailureForJson(
-      "Int32FieldLeadingZero", REQUIRED,
-      R"({"optionalInt32": 01})");
-  ExpectParseFailureForJson(
-      "Int32FieldNegativeWithLeadingZero", REQUIRED,
-      R"({"optionalInt32": -01})");
-  // String values must follow the same syntax rule. Specifically leading
-  // or trailing spaces are not allowed.
-  ExpectParseFailureForJson(
-      "Int32FieldLeadingSpace", REQUIRED,
-      R"({"optionalInt32": " 1"})");
-  ExpectParseFailureForJson(
-      "Int32FieldTrailingSpace", REQUIRED,
-      R"({"optionalInt32": "1 "})");
-
-  // 64-bit values are serialized as strings.
-  RunValidJsonTestWithValidator(
-      "Int64FieldBeString", RECOMMENDED,
-      R"({"optionalInt64": 1})",
-      [](const Json::Value& value) {
-        return value["optionalInt64"].type() == Json::stringValue &&
-            value["optionalInt64"].asString() == "1";
-      });
-  RunValidJsonTestWithValidator(
-      "Uint64FieldBeString", RECOMMENDED,
-      R"({"optionalUint64": 1})",
-      [](const Json::Value& value) {
-        return value["optionalUint64"].type() == Json::stringValue &&
-            value["optionalUint64"].asString() == "1";
-      });
-
-  // Bool fields.
-  RunValidJsonTest(
-      "BoolFieldTrue", REQUIRED,
-      R"({"optionalBool":true})",
-      "optional_bool: true");
-  RunValidJsonTest(
-      "BoolFieldFalse", REQUIRED,
-      R"({"optionalBool":false})",
-      "optional_bool: false");
-
-  // Other forms are not allowed.
-  ExpectParseFailureForJson(
-      "BoolFieldIntegerZero", RECOMMENDED,
-      R"({"optionalBool":0})");
-  ExpectParseFailureForJson(
-      "BoolFieldIntegerOne", RECOMMENDED,
-      R"({"optionalBool":1})");
-  ExpectParseFailureForJson(
-      "BoolFieldCamelCaseTrue", RECOMMENDED,
-      R"({"optionalBool":True})");
-  ExpectParseFailureForJson(
-      "BoolFieldCamelCaseFalse", RECOMMENDED,
-      R"({"optionalBool":False})");
-  ExpectParseFailureForJson(
-      "BoolFieldAllCapitalTrue", RECOMMENDED,
-      R"({"optionalBool":TRUE})");
-  ExpectParseFailureForJson(
-      "BoolFieldAllCapitalFalse", RECOMMENDED,
-      R"({"optionalBool":FALSE})");
-  ExpectParseFailureForJson(
-      "BoolFieldDoubleQuotedTrue", RECOMMENDED,
-      R"({"optionalBool":"true"})");
-  ExpectParseFailureForJson(
-      "BoolFieldDoubleQuotedFalse", RECOMMENDED,
-      R"({"optionalBool":"false"})");
-
-  // Float fields.
-  RunValidJsonTest(
-      "FloatFieldMinPositiveValue", REQUIRED,
-      R"({"optionalFloat": 1.175494e-38})",
-      "optional_float: 1.175494e-38");
-  RunValidJsonTest(
-      "FloatFieldMaxNegativeValue", REQUIRED,
-      R"({"optionalFloat": -1.175494e-38})",
-      "optional_float: -1.175494e-38");
-  RunValidJsonTest(
-      "FloatFieldMaxPositiveValue", REQUIRED,
-      R"({"optionalFloat": 3.402823e+38})",
-      "optional_float: 3.402823e+38");
-  RunValidJsonTest(
-      "FloatFieldMinNegativeValue", REQUIRED,
-      R"({"optionalFloat": 3.402823e+38})",
-      "optional_float: 3.402823e+38");
-  // Values can be quoted.
-  RunValidJsonTest(
-      "FloatFieldQuotedValue", REQUIRED,
-      R"({"optionalFloat": "1"})",
-      "optional_float: 1");
-  // Special values.
-  RunValidJsonTest(
-      "FloatFieldNan", REQUIRED,
-      R"({"optionalFloat": "NaN"})",
-      "optional_float: nan");
-  RunValidJsonTest(
-      "FloatFieldInfinity", REQUIRED,
-      R"({"optionalFloat": "Infinity"})",
-      "optional_float: inf");
-  RunValidJsonTest(
-      "FloatFieldNegativeInfinity", REQUIRED,
-      R"({"optionalFloat": "-Infinity"})",
-      "optional_float: -inf");
-  // Non-cannonical Nan will be correctly normalized.
-  {
-    TestAllTypesProto3 message;
-    // IEEE floating-point standard 32-bit quiet NaN:
-    //   0111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
-    message.set_optional_float(
-        WireFormatLite::DecodeFloat(0x7FA12345));
-    RunValidJsonTestWithProtobufInput(
-        "FloatFieldNormalizeQuietNan", REQUIRED, message,
-        "optional_float: nan");
-    // IEEE floating-point standard 64-bit signaling NaN:
-    //   1111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
-    message.set_optional_float(
-        WireFormatLite::DecodeFloat(0xFFB54321));
-    RunValidJsonTestWithProtobufInput(
-        "FloatFieldNormalizeSignalingNan", REQUIRED, message,
-        "optional_float: nan");
-  }
-
-  // Special values must be quoted.
-  ExpectParseFailureForJson(
-      "FloatFieldNanNotQuoted", RECOMMENDED,
-      R"({"optionalFloat": NaN})");
-  ExpectParseFailureForJson(
-      "FloatFieldInfinityNotQuoted", RECOMMENDED,
-      R"({"optionalFloat": Infinity})");
-  ExpectParseFailureForJson(
-      "FloatFieldNegativeInfinityNotQuoted", RECOMMENDED,
-      R"({"optionalFloat": -Infinity})");
-  // Parsers should reject out-of-bound values.
-  ExpectParseFailureForJson(
-      "FloatFieldTooSmall", REQUIRED,
-      R"({"optionalFloat": -3.502823e+38})");
-  ExpectParseFailureForJson(
-      "FloatFieldTooLarge", REQUIRED,
-      R"({"optionalFloat": 3.502823e+38})");
-
-  // Double fields.
-  RunValidJsonTest(
-      "DoubleFieldMinPositiveValue", REQUIRED,
-      R"({"optionalDouble": 2.22507e-308})",
-      "optional_double: 2.22507e-308");
-  RunValidJsonTest(
-      "DoubleFieldMaxNegativeValue", REQUIRED,
-      R"({"optionalDouble": -2.22507e-308})",
-      "optional_double: -2.22507e-308");
-  RunValidJsonTest(
-      "DoubleFieldMaxPositiveValue", REQUIRED,
-      R"({"optionalDouble": 1.79769e+308})",
-      "optional_double: 1.79769e+308");
-  RunValidJsonTest(
-      "DoubleFieldMinNegativeValue", REQUIRED,
-      R"({"optionalDouble": -1.79769e+308})",
-      "optional_double: -1.79769e+308");
-  // Values can be quoted.
-  RunValidJsonTest(
-      "DoubleFieldQuotedValue", REQUIRED,
-      R"({"optionalDouble": "1"})",
-      "optional_double: 1");
-  // Speical values.
-  RunValidJsonTest(
-      "DoubleFieldNan", REQUIRED,
-      R"({"optionalDouble": "NaN"})",
-      "optional_double: nan");
-  RunValidJsonTest(
-      "DoubleFieldInfinity", REQUIRED,
-      R"({"optionalDouble": "Infinity"})",
-      "optional_double: inf");
-  RunValidJsonTest(
-      "DoubleFieldNegativeInfinity", REQUIRED,
-      R"({"optionalDouble": "-Infinity"})",
-      "optional_double: -inf");
-  // Non-cannonical Nan will be correctly normalized.
-  {
-    TestAllTypesProto3 message;
-    message.set_optional_double(
-        WireFormatLite::DecodeDouble(0x7FFA123456789ABCLL));
-    RunValidJsonTestWithProtobufInput(
-        "DoubleFieldNormalizeQuietNan", REQUIRED, message,
-        "optional_double: nan");
-    message.set_optional_double(
-        WireFormatLite::DecodeDouble(0xFFFBCBA987654321LL));
-    RunValidJsonTestWithProtobufInput(
-        "DoubleFieldNormalizeSignalingNan", REQUIRED, message,
-        "optional_double: nan");
-  }
-
-  // Special values must be quoted.
-  ExpectParseFailureForJson(
-      "DoubleFieldNanNotQuoted", RECOMMENDED,
-      R"({"optionalDouble": NaN})");
-  ExpectParseFailureForJson(
-      "DoubleFieldInfinityNotQuoted", RECOMMENDED,
-      R"({"optionalDouble": Infinity})");
-  ExpectParseFailureForJson(
-      "DoubleFieldNegativeInfinityNotQuoted", RECOMMENDED,
-      R"({"optionalDouble": -Infinity})");
-
-  // Parsers should reject out-of-bound values.
-  ExpectParseFailureForJson(
-      "DoubleFieldTooSmall", REQUIRED,
-      R"({"optionalDouble": -1.89769e+308})");
-  ExpectParseFailureForJson(
-      "DoubleFieldTooLarge", REQUIRED,
-      R"({"optionalDouble": +1.89769e+308})");
-
-  // Enum fields.
-  RunValidJsonTest(
-      "EnumField", REQUIRED,
-      R"({"optionalNestedEnum": "FOO"})",
-      "optional_nested_enum: FOO");
-  // Enum values must be represented as strings.
-  ExpectParseFailureForJson(
-      "EnumFieldNotQuoted", REQUIRED,
-      R"({"optionalNestedEnum": FOO})");
-  // Numeric values are allowed.
-  RunValidJsonTest(
-      "EnumFieldNumericValueZero", REQUIRED,
-      R"({"optionalNestedEnum": 0})",
-      "optional_nested_enum: FOO");
-  RunValidJsonTest(
-      "EnumFieldNumericValueNonZero", REQUIRED,
-      R"({"optionalNestedEnum": 1})",
-      "optional_nested_enum: BAR");
-  // Unknown enum values are represented as numeric values.
-  RunValidJsonTestWithValidator(
-      "EnumFieldUnknownValue", REQUIRED,
-      R"({"optionalNestedEnum": 123})",
-      [](const Json::Value& value) {
-        return value["optionalNestedEnum"].type() == Json::intValue &&
-            value["optionalNestedEnum"].asInt() == 123;
-      });
-
-  // String fields.
-  RunValidJsonTest(
-      "StringField", REQUIRED,
-      R"({"optionalString": "Hello world!"})",
-      "optional_string: \"Hello world!\"");
-  RunValidJsonTest(
-      "StringFieldUnicode", REQUIRED,
-      // Google in Chinese.
-      R"({"optionalString": "谷歌"})",
-      R"(optional_string: "谷歌")");
-  RunValidJsonTest(
-      "StringFieldEscape", REQUIRED,
-      R"({"optionalString": "\"\\\/\b\f\n\r\t"})",
-      R"(optional_string: "\"\\/\b\f\n\r\t")");
-  RunValidJsonTest(
-      "StringFieldUnicodeEscape", REQUIRED,
-      R"({"optionalString": "\u8C37\u6B4C"})",
-      R"(optional_string: "谷歌")");
-  RunValidJsonTest(
-      "StringFieldUnicodeEscapeWithLowercaseHexLetters", REQUIRED,
-      R"({"optionalString": "\u8c37\u6b4c"})",
-      R"(optional_string: "谷歌")");
-  RunValidJsonTest(
-      "StringFieldSurrogatePair", REQUIRED,
-      // The character is an emoji: grinning face with smiling eyes. 😁
-      R"({"optionalString": "\uD83D\uDE01"})",
-      R"(optional_string: "\xF0\x9F\x98\x81")");
-
-  // Unicode escapes must start with "\u" (lowercase u).
-  ExpectParseFailureForJson(
-      "StringFieldUppercaseEscapeLetter", RECOMMENDED,
-      R"({"optionalString": "\U8C37\U6b4C"})");
-  ExpectParseFailureForJson(
-      "StringFieldInvalidEscape", RECOMMENDED,
-      R"({"optionalString": "\uXXXX\u6B4C"})");
-  ExpectParseFailureForJson(
-      "StringFieldUnterminatedEscape", RECOMMENDED,
-      R"({"optionalString": "\u8C3"})");
-  ExpectParseFailureForJson(
-      "StringFieldUnpairedHighSurrogate", RECOMMENDED,
-      R"({"optionalString": "\uD800"})");
-  ExpectParseFailureForJson(
-      "StringFieldUnpairedLowSurrogate", RECOMMENDED,
-      R"({"optionalString": "\uDC00"})");
-  ExpectParseFailureForJson(
-      "StringFieldSurrogateInWrongOrder", RECOMMENDED,
-      R"({"optionalString": "\uDE01\uD83D"})");
-  ExpectParseFailureForJson(
-      "StringFieldNotAString", REQUIRED,
-      R"({"optionalString": 12345})");
-
-  // Bytes fields.
-  RunValidJsonTest(
-      "BytesField", REQUIRED,
-      R"({"optionalBytes": "AQI="})",
-      R"(optional_bytes: "\x01\x02")");
-  RunValidJsonTest(
-      "BytesFieldBase64Url", RECOMMENDED,
-      R"({"optionalBytes": "-_"})",
-      R"(optional_bytes: "\xfb")");
-
-  // Message fields.
-  RunValidJsonTest(
-      "MessageField", REQUIRED,
-      R"({"optionalNestedMessage": {"a": 1234}})",
-      "optional_nested_message: {a: 1234}");
-
-  // Oneof fields.
-  ExpectParseFailureForJson(
-      "OneofFieldDuplicate", REQUIRED,
-      R"({"oneofUint32": 1, "oneofString": "test"})");
-  // Ensure zero values for oneof make it out/backs.
-  TestAllTypesProto3 messageProto3;
-  TestAllTypesProto2 messageProto2;
-  TestOneofMessage(messageProto3, true);
-  TestOneofMessage(messageProto2, false);
-  RunValidJsonTest(
-      "OneofZeroUint32", RECOMMENDED,
-      R"({"oneofUint32": 0})", "oneof_uint32: 0");
-  RunValidJsonTest(
-      "OneofZeroMessage", RECOMMENDED,
-      R"({"oneofNestedMessage": {}})", "oneof_nested_message: {}");
-  RunValidJsonTest(
-      "OneofZeroString", RECOMMENDED,
-      R"({"oneofString": ""})", "oneof_string: \"\"");
-  RunValidJsonTest(
-      "OneofZeroBytes", RECOMMENDED,
-      R"({"oneofBytes": ""})", "oneof_bytes: \"\"");
-  RunValidJsonTest(
-      "OneofZeroBool", RECOMMENDED,
-      R"({"oneofBool": false})", "oneof_bool: false");
-  RunValidJsonTest(
-      "OneofZeroUint64", RECOMMENDED,
-      R"({"oneofUint64": 0})", "oneof_uint64: 0");
-  RunValidJsonTest(
-      "OneofZeroFloat", RECOMMENDED,
-      R"({"oneofFloat": 0.0})", "oneof_float: 0");
-  RunValidJsonTest(
-      "OneofZeroDouble", RECOMMENDED,
-      R"({"oneofDouble": 0.0})", "oneof_double: 0");
-  RunValidJsonTest(
-      "OneofZeroEnum", RECOMMENDED,
-      R"({"oneofEnum":"FOO"})", "oneof_enum: FOO");
-
-  // Repeated fields.
-  RunValidJsonTest(
-      "PrimitiveRepeatedField", REQUIRED,
-      R"({"repeatedInt32": [1, 2, 3, 4]})",
-      "repeated_int32: [1, 2, 3, 4]");
-  RunValidJsonTest(
-      "EnumRepeatedField", REQUIRED,
-      R"({"repeatedNestedEnum": ["FOO", "BAR", "BAZ"]})",
-      "repeated_nested_enum: [FOO, BAR, BAZ]");
-  RunValidJsonTest(
-      "StringRepeatedField", REQUIRED,
-      R"({"repeatedString": ["Hello", "world"]})",
-      R"(repeated_string: ["Hello", "world"])");
-  RunValidJsonTest(
-      "BytesRepeatedField", REQUIRED,
-      R"({"repeatedBytes": ["AAEC", "AQI="]})",
-      R"(repeated_bytes: ["\x00\x01\x02", "\x01\x02"])");
-  RunValidJsonTest(
-      "MessageRepeatedField", REQUIRED,
-      R"({"repeatedNestedMessage": [{"a": 1234}, {"a": 5678}]})",
-      "repeated_nested_message: {a: 1234}"
-      "repeated_nested_message: {a: 5678}");
-
-  // Repeated field elements are of incorrect type.
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingIntegersGotBool", REQUIRED,
-      R"({"repeatedInt32": [1, false, 3, 4]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingIntegersGotString", REQUIRED,
-      R"({"repeatedInt32": [1, 2, "name", 4]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingIntegersGotMessage", REQUIRED,
-      R"({"repeatedInt32": [1, 2, 3, {"a": 4}]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingStringsGotInt", REQUIRED,
-      R"({"repeatedString": ["1", 2, "3", "4"]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingStringsGotBool", REQUIRED,
-      R"({"repeatedString": ["1", "2", false, "4"]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingStringsGotMessage", REQUIRED,
-      R"({"repeatedString": ["1", 2, "3", {"a": 4}]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingMessagesGotInt", REQUIRED,
-      R"({"repeatedNestedMessage": [{"a": 1}, 2]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingMessagesGotBool", REQUIRED,
-      R"({"repeatedNestedMessage": [{"a": 1}, false]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldWrongElementTypeExpectingMessagesGotString", REQUIRED,
-      R"({"repeatedNestedMessage": [{"a": 1}, "2"]})");
-  // Trailing comma in the repeated field is not allowed.
-  ExpectParseFailureForJson(
-      "RepeatedFieldTrailingComma", RECOMMENDED,
-      R"({"repeatedInt32": [1, 2, 3, 4,]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldTrailingCommaWithSpace", RECOMMENDED,
-      "{\"repeatedInt32\": [1, 2, 3, 4 ,]}");
-  ExpectParseFailureForJson(
-      "RepeatedFieldTrailingCommaWithSpaceCommaSpace", RECOMMENDED,
-      "{\"repeatedInt32\": [1, 2, 3, 4 , ]}");
-  ExpectParseFailureForJson(
-      "RepeatedFieldTrailingCommaWithNewlines", RECOMMENDED,
-      "{\"repeatedInt32\": [\n  1,\n  2,\n  3,\n  4,\n]}");
-
-  // Map fields.
-  RunValidJsonTest(
-      "Int32MapField", REQUIRED,
-      R"({"mapInt32Int32": {"1": 2, "3": 4}})",
-      "map_int32_int32: {key: 1 value: 2}"
-      "map_int32_int32: {key: 3 value: 4}");
-  ExpectParseFailureForJson(
-      "Int32MapFieldKeyNotQuoted", RECOMMENDED,
-      R"({"mapInt32Int32": {1: 2, 3: 4}})");
-  RunValidJsonTest(
-      "Uint32MapField", REQUIRED,
-      R"({"mapUint32Uint32": {"1": 2, "3": 4}})",
-      "map_uint32_uint32: {key: 1 value: 2}"
-      "map_uint32_uint32: {key: 3 value: 4}");
-  ExpectParseFailureForJson(
-      "Uint32MapFieldKeyNotQuoted", RECOMMENDED,
-      R"({"mapUint32Uint32": {1: 2, 3: 4}})");
-  RunValidJsonTest(
-      "Int64MapField", REQUIRED,
-      R"({"mapInt64Int64": {"1": 2, "3": 4}})",
-      "map_int64_int64: {key: 1 value: 2}"
-      "map_int64_int64: {key: 3 value: 4}");
-  ExpectParseFailureForJson(
-      "Int64MapFieldKeyNotQuoted", RECOMMENDED,
-      R"({"mapInt64Int64": {1: 2, 3: 4}})");
-  RunValidJsonTest(
-      "Uint64MapField", REQUIRED,
-      R"({"mapUint64Uint64": {"1": 2, "3": 4}})",
-      "map_uint64_uint64: {key: 1 value: 2}"
-      "map_uint64_uint64: {key: 3 value: 4}");
-  ExpectParseFailureForJson(
-      "Uint64MapFieldKeyNotQuoted", RECOMMENDED,
-      R"({"mapUint64Uint64": {1: 2, 3: 4}})");
-  RunValidJsonTest(
-      "BoolMapField", REQUIRED,
-      R"({"mapBoolBool": {"true": true, "false": false}})",
-      "map_bool_bool: {key: true value: true}"
-      "map_bool_bool: {key: false value: false}");
-  ExpectParseFailureForJson(
-      "BoolMapFieldKeyNotQuoted", RECOMMENDED,
-      R"({"mapBoolBool": {true: true, false: false}})");
-  RunValidJsonTest(
-      "MessageMapField", REQUIRED,
-      R"({
-        "mapStringNestedMessage": {
-          "hello": {"a": 1234},
-          "world": {"a": 5678}
-        }
-      })",
-      R"(
-        map_string_nested_message: {
-          key: "hello"
-          value: {a: 1234}
-        }
-        map_string_nested_message: {
-          key: "world"
-          value: {a: 5678}
-        }
-      )");
-  // Since Map keys are represented as JSON strings, escaping should be allowed.
-  RunValidJsonTest(
-      "Int32MapEscapedKey", REQUIRED,
-      R"({"mapInt32Int32": {"\u0031": 2}})",
-      "map_int32_int32: {key: 1 value: 2}");
-  RunValidJsonTest(
-      "Int64MapEscapedKey", REQUIRED,
-      R"({"mapInt64Int64": {"\u0031": 2}})",
-      "map_int64_int64: {key: 1 value: 2}");
-  RunValidJsonTest(
-      "BoolMapEscapedKey", REQUIRED,
-      R"({"mapBoolBool": {"tr\u0075e": true}})",
-      "map_bool_bool: {key: true value: true}");
-
-  // "null" is accepted for all fields types.
-  RunValidJsonTest(
-      "AllFieldAcceptNull", REQUIRED,
-      R"({
-        "optionalInt32": null,
-        "optionalInt64": null,
-        "optionalUint32": null,
-        "optionalUint64": null,
-        "optionalSint32": null,
-        "optionalSint64": null,
-        "optionalFixed32": null,
-        "optionalFixed64": null,
-        "optionalSfixed32": null,
-        "optionalSfixed64": null,
-        "optionalFloat": null,
-        "optionalDouble": null,
-        "optionalBool": null,
-        "optionalString": null,
-        "optionalBytes": null,
-        "optionalNestedEnum": null,
-        "optionalNestedMessage": null,
-        "repeatedInt32": null,
-        "repeatedInt64": null,
-        "repeatedUint32": null,
-        "repeatedUint64": null,
-        "repeatedSint32": null,
-        "repeatedSint64": null,
-        "repeatedFixed32": null,
-        "repeatedFixed64": null,
-        "repeatedSfixed32": null,
-        "repeatedSfixed64": null,
-        "repeatedFloat": null,
-        "repeatedDouble": null,
-        "repeatedBool": null,
-        "repeatedString": null,
-        "repeatedBytes": null,
-        "repeatedNestedEnum": null,
-        "repeatedNestedMessage": null,
-        "mapInt32Int32": null,
-        "mapBoolBool": null,
-        "mapStringNestedMessage": null
-      })",
-      "");
-
-  // Repeated field elements cannot be null.
-  ExpectParseFailureForJson(
-      "RepeatedFieldPrimitiveElementIsNull", RECOMMENDED,
-      R"({"repeatedInt32": [1, null, 2]})");
-  ExpectParseFailureForJson(
-      "RepeatedFieldMessageElementIsNull", RECOMMENDED,
-      R"({"repeatedNestedMessage": [{"a":1}, null, {"a":2}]})");
-  // Map field keys cannot be null.
-  ExpectParseFailureForJson(
-      "MapFieldKeyIsNull", RECOMMENDED,
-      R"({"mapInt32Int32": {null: 1}})");
-  // Map field values cannot be null.
-  ExpectParseFailureForJson(
-      "MapFieldValueIsNull", RECOMMENDED,
-      R"({"mapInt32Int32": {"0": null}})");
-
-  // http://www.rfc-editor.org/rfc/rfc7159.txt says strings have to use double
-  // quotes.
-  ExpectParseFailureForJson(
-      "StringFieldSingleQuoteKey", RECOMMENDED,
-      R"({'optionalString': "Hello world!"})");
-  ExpectParseFailureForJson(
-      "StringFieldSingleQuoteValue", RECOMMENDED,
-      R"({"optionalString": 'Hello world!'})");
-  ExpectParseFailureForJson(
-      "StringFieldSingleQuoteBoth", RECOMMENDED,
-      R"({'optionalString': 'Hello world!'})");
-
-  // Unknown fields.
-  {
-    TestAllTypesProto3 messageProto3;
-    TestAllTypesProto2 messageProto2;
-    //TODO(yilunchong): update this behavior when unknown field's behavior
-    // changed in open source. Also delete
-    // Required.Proto3.ProtobufInput.UnknownVarint.ProtobufOutput
-    // from failure list of python_cpp python java
-    TestUnknownMessage(messageProto3, true);
-    TestUnknownMessage(messageProto2, false);
-  }
-
-  // Wrapper types.
-  RunValidJsonTest(
-      "OptionalBoolWrapper", REQUIRED,
-      R"({"optionalBoolWrapper": false})",
-      "optional_bool_wrapper: {value: false}");
-  RunValidJsonTest(
-      "OptionalInt32Wrapper", REQUIRED,
-      R"({"optionalInt32Wrapper": 0})",
-      "optional_int32_wrapper: {value: 0}");
-  RunValidJsonTest(
-      "OptionalUint32Wrapper", REQUIRED,
-      R"({"optionalUint32Wrapper": 0})",
-      "optional_uint32_wrapper: {value: 0}");
-  RunValidJsonTest(
-      "OptionalInt64Wrapper", REQUIRED,
-      R"({"optionalInt64Wrapper": 0})",
-      "optional_int64_wrapper: {value: 0}");
-  RunValidJsonTest(
-      "OptionalUint64Wrapper", REQUIRED,
-      R"({"optionalUint64Wrapper": 0})",
-      "optional_uint64_wrapper: {value: 0}");
-  RunValidJsonTest(
-      "OptionalFloatWrapper", REQUIRED,
-      R"({"optionalFloatWrapper": 0})",
-      "optional_float_wrapper: {value: 0}");
-  RunValidJsonTest(
-      "OptionalDoubleWrapper", REQUIRED,
-      R"({"optionalDoubleWrapper": 0})",
-      "optional_double_wrapper: {value: 0}");
-  RunValidJsonTest(
-      "OptionalStringWrapper", REQUIRED,
-      R"({"optionalStringWrapper": ""})",
-      R"(optional_string_wrapper: {value: ""})");
-  RunValidJsonTest(
-      "OptionalBytesWrapper", REQUIRED,
-      R"({"optionalBytesWrapper": ""})",
-      R"(optional_bytes_wrapper: {value: ""})");
-  RunValidJsonTest(
-      "OptionalWrapperTypesWithNonDefaultValue", REQUIRED,
-      R"({
-        "optionalBoolWrapper": true,
-        "optionalInt32Wrapper": 1,
-        "optionalUint32Wrapper": 1,
-        "optionalInt64Wrapper": "1",
-        "optionalUint64Wrapper": "1",
-        "optionalFloatWrapper": 1,
-        "optionalDoubleWrapper": 1,
-        "optionalStringWrapper": "1",
-        "optionalBytesWrapper": "AQI="
-      })",
-      R"(
-        optional_bool_wrapper: {value: true}
-        optional_int32_wrapper: {value: 1}
-        optional_uint32_wrapper: {value: 1}
-        optional_int64_wrapper: {value: 1}
-        optional_uint64_wrapper: {value: 1}
-        optional_float_wrapper: {value: 1}
-        optional_double_wrapper: {value: 1}
-        optional_string_wrapper: {value: "1"}
-        optional_bytes_wrapper: {value: "\x01\x02"}
-      )");
-  RunValidJsonTest(
-      "RepeatedBoolWrapper", REQUIRED,
-      R"({"repeatedBoolWrapper": [true, false]})",
-      "repeated_bool_wrapper: {value: true}"
-      "repeated_bool_wrapper: {value: false}");
-  RunValidJsonTest(
-      "RepeatedInt32Wrapper", REQUIRED,
-      R"({"repeatedInt32Wrapper": [0, 1]})",
-      "repeated_int32_wrapper: {value: 0}"
-      "repeated_int32_wrapper: {value: 1}");
-  RunValidJsonTest(
-      "RepeatedUint32Wrapper", REQUIRED,
-      R"({"repeatedUint32Wrapper": [0, 1]})",
-      "repeated_uint32_wrapper: {value: 0}"
-      "repeated_uint32_wrapper: {value: 1}");
-  RunValidJsonTest(
-      "RepeatedInt64Wrapper", REQUIRED,
-      R"({"repeatedInt64Wrapper": [0, 1]})",
-      "repeated_int64_wrapper: {value: 0}"
-      "repeated_int64_wrapper: {value: 1}");
-  RunValidJsonTest(
-      "RepeatedUint64Wrapper", REQUIRED,
-      R"({"repeatedUint64Wrapper": [0, 1]})",
-      "repeated_uint64_wrapper: {value: 0}"
-      "repeated_uint64_wrapper: {value: 1}");
-  RunValidJsonTest(
-      "RepeatedFloatWrapper", REQUIRED,
-      R"({"repeatedFloatWrapper": [0, 1]})",
-      "repeated_float_wrapper: {value: 0}"
-      "repeated_float_wrapper: {value: 1}");
-  RunValidJsonTest(
-      "RepeatedDoubleWrapper", REQUIRED,
-      R"({"repeatedDoubleWrapper": [0, 1]})",
-      "repeated_double_wrapper: {value: 0}"
-      "repeated_double_wrapper: {value: 1}");
-  RunValidJsonTest(
-      "RepeatedStringWrapper", REQUIRED,
-      R"({"repeatedStringWrapper": ["", "AQI="]})",
-      R"(
-        repeated_string_wrapper: {value: ""}
-        repeated_string_wrapper: {value: "AQI="}
-      )");
-  RunValidJsonTest(
-      "RepeatedBytesWrapper", REQUIRED,
-      R"({"repeatedBytesWrapper": ["", "AQI="]})",
-      R"(
-        repeated_bytes_wrapper: {value: ""}
-        repeated_bytes_wrapper: {value: "\x01\x02"}
-      )");
-  RunValidJsonTest(
-      "WrapperTypesWithNullValue", REQUIRED,
-      R"({
-        "optionalBoolWrapper": null,
-        "optionalInt32Wrapper": null,
-        "optionalUint32Wrapper": null,
-        "optionalInt64Wrapper": null,
-        "optionalUint64Wrapper": null,
-        "optionalFloatWrapper": null,
-        "optionalDoubleWrapper": null,
-        "optionalStringWrapper": null,
-        "optionalBytesWrapper": null,
-        "repeatedBoolWrapper": null,
-        "repeatedInt32Wrapper": null,
-        "repeatedUint32Wrapper": null,
-        "repeatedInt64Wrapper": null,
-        "repeatedUint64Wrapper": null,
-        "repeatedFloatWrapper": null,
-        "repeatedDoubleWrapper": null,
-        "repeatedStringWrapper": null,
-        "repeatedBytesWrapper": null
-      })",
-      "");
-
-  // Duration
-  RunValidJsonTest(
-      "DurationMinValue", REQUIRED,
-      R"({"optionalDuration": "-315576000000.999999999s"})",
-      "optional_duration: {seconds: -315576000000 nanos: -999999999}");
-  RunValidJsonTest(
-      "DurationMaxValue", REQUIRED,
-      R"({"optionalDuration": "315576000000.999999999s"})",
-      "optional_duration: {seconds: 315576000000 nanos: 999999999}");
-  RunValidJsonTest(
-      "DurationRepeatedValue", REQUIRED,
-      R"({"repeatedDuration": ["1.5s", "-1.5s"]})",
-      "repeated_duration: {seconds: 1 nanos: 500000000}"
-      "repeated_duration: {seconds: -1 nanos: -500000000}");
-  RunValidJsonTest(
-      "DurationNull", REQUIRED,
-      R"({"optionalDuration": null})",
-      "");
-
-  ExpectParseFailureForJson(
-      "DurationMissingS", REQUIRED,
-      R"({"optionalDuration": "1"})");
-  ExpectParseFailureForJson(
-      "DurationJsonInputTooSmall", REQUIRED,
-      R"({"optionalDuration": "-315576000001.000000000s"})");
-  ExpectParseFailureForJson(
-      "DurationJsonInputTooLarge", REQUIRED,
-      R"({"optionalDuration": "315576000001.000000000s"})");
-  ExpectSerializeFailureForJson(
-      "DurationProtoInputTooSmall", REQUIRED,
-      "optional_duration: {seconds: -315576000001 nanos: 0}");
-  ExpectSerializeFailureForJson(
-      "DurationProtoInputTooLarge", REQUIRED,
-      "optional_duration: {seconds: 315576000001 nanos: 0}");
-
-  RunValidJsonTestWithValidator(
-      "DurationHasZeroFractionalDigit", RECOMMENDED,
-      R"({"optionalDuration": "1.000000000s"})",
-      [](const Json::Value& value) {
-        return value["optionalDuration"].asString() == "1s";
-      });
-  RunValidJsonTestWithValidator(
-      "DurationHas3FractionalDigits", RECOMMENDED,
-      R"({"optionalDuration": "1.010000000s"})",
-      [](const Json::Value& value) {
-        return value["optionalDuration"].asString() == "1.010s";
-      });
-  RunValidJsonTestWithValidator(
-      "DurationHas6FractionalDigits", RECOMMENDED,
-      R"({"optionalDuration": "1.000010000s"})",
-      [](const Json::Value& value) {
-        return value["optionalDuration"].asString() == "1.000010s";
-      });
-  RunValidJsonTestWithValidator(
-      "DurationHas9FractionalDigits", RECOMMENDED,
-      R"({"optionalDuration": "1.000000010s"})",
-      [](const Json::Value& value) {
-        return value["optionalDuration"].asString() == "1.000000010s";
-      });
-
-  // Timestamp
-  RunValidJsonTest(
-      "TimestampMinValue", REQUIRED,
-      R"({"optionalTimestamp": "0001-01-01T00:00:00Z"})",
-      "optional_timestamp: {seconds: -62135596800}");
-  RunValidJsonTest(
-      "TimestampMaxValue", REQUIRED,
-      R"({"optionalTimestamp": "9999-12-31T23:59:59.999999999Z"})",
-      "optional_timestamp: {seconds: 253402300799 nanos: 999999999}");
-  RunValidJsonTest(
-      "TimestampRepeatedValue", REQUIRED,
-      R"({
-        "repeatedTimestamp": [
-          "0001-01-01T00:00:00Z",
-          "9999-12-31T23:59:59.999999999Z"
-        ]
-      })",
-      "repeated_timestamp: {seconds: -62135596800}"
-      "repeated_timestamp: {seconds: 253402300799 nanos: 999999999}");
-  RunValidJsonTest(
-      "TimestampWithPositiveOffset", REQUIRED,
-      R"({"optionalTimestamp": "1970-01-01T08:00:00+08:00"})",
-      "optional_timestamp: {seconds: 0}");
-  RunValidJsonTest(
-      "TimestampWithNegativeOffset", REQUIRED,
-      R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})",
-      "optional_timestamp: {seconds: 0}");
-  RunValidJsonTest(
-      "TimestampNull", REQUIRED,
-      R"({"optionalTimestamp": null})",
-      "");
-
-  ExpectParseFailureForJson(
-      "TimestampJsonInputTooSmall", REQUIRED,
-      R"({"optionalTimestamp": "0000-01-01T00:00:00Z"})");
-  ExpectParseFailureForJson(
-      "TimestampJsonInputTooLarge", REQUIRED,
-      R"({"optionalTimestamp": "10000-01-01T00:00:00Z"})");
-  ExpectParseFailureForJson(
-      "TimestampJsonInputMissingZ", REQUIRED,
-      R"({"optionalTimestamp": "0001-01-01T00:00:00"})");
-  ExpectParseFailureForJson(
-      "TimestampJsonInputMissingT", REQUIRED,
-      R"({"optionalTimestamp": "0001-01-01 00:00:00Z"})");
-  ExpectParseFailureForJson(
-      "TimestampJsonInputLowercaseZ", REQUIRED,
-      R"({"optionalTimestamp": "0001-01-01T00:00:00z"})");
-  ExpectParseFailureForJson(
-      "TimestampJsonInputLowercaseT", REQUIRED,
-      R"({"optionalTimestamp": "0001-01-01t00:00:00Z"})");
-  ExpectSerializeFailureForJson(
-      "TimestampProtoInputTooSmall", REQUIRED,
-      "optional_timestamp: {seconds: -62135596801}");
-  ExpectSerializeFailureForJson(
-      "TimestampProtoInputTooLarge", REQUIRED,
-      "optional_timestamp: {seconds: 253402300800}");
-  RunValidJsonTestWithValidator(
-      "TimestampZeroNormalized", RECOMMENDED,
-      R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})",
-      [](const Json::Value& value) {
-        return value["optionalTimestamp"].asString() ==
-            "1970-01-01T00:00:00Z";
-      });
-  RunValidJsonTestWithValidator(
-      "TimestampHasZeroFractionalDigit", RECOMMENDED,
-      R"({"optionalTimestamp": "1970-01-01T00:00:00.000000000Z"})",
-      [](const Json::Value& value) {
-        return value["optionalTimestamp"].asString() ==
-            "1970-01-01T00:00:00Z";
-      });
-  RunValidJsonTestWithValidator(
-      "TimestampHas3FractionalDigits", RECOMMENDED,
-      R"({"optionalTimestamp": "1970-01-01T00:00:00.010000000Z"})",
-      [](const Json::Value& value) {
-        return value["optionalTimestamp"].asString() ==
-            "1970-01-01T00:00:00.010Z";
-      });
-  RunValidJsonTestWithValidator(
-      "TimestampHas6FractionalDigits", RECOMMENDED,
-      R"({"optionalTimestamp": "1970-01-01T00:00:00.000010000Z"})",
-      [](const Json::Value& value) {
-        return value["optionalTimestamp"].asString() ==
-            "1970-01-01T00:00:00.000010Z";
-      });
-  RunValidJsonTestWithValidator(
-      "TimestampHas9FractionalDigits", RECOMMENDED,
-      R"({"optionalTimestamp": "1970-01-01T00:00:00.000000010Z"})",
-      [](const Json::Value& value) {
-        return value["optionalTimestamp"].asString() ==
-            "1970-01-01T00:00:00.000000010Z";
-      });
-
-  // FieldMask
-  RunValidJsonTest(
-      "FieldMask", REQUIRED,
-      R"({"optionalFieldMask": "foo,barBaz"})",
-      R"(optional_field_mask: {paths: "foo" paths: "bar_baz"})");
-  ExpectParseFailureForJson(
-      "FieldMaskInvalidCharacter", RECOMMENDED,
-      R"({"optionalFieldMask": "foo,bar_bar"})");
-  ExpectSerializeFailureForJson(
-      "FieldMaskPathsDontRoundTrip", RECOMMENDED,
-      R"(optional_field_mask: {paths: "fooBar"})");
-  ExpectSerializeFailureForJson(
-      "FieldMaskNumbersDontRoundTrip", RECOMMENDED,
-      R"(optional_field_mask: {paths: "foo_3_bar"})");
-  ExpectSerializeFailureForJson(
-      "FieldMaskTooManyUnderscore", RECOMMENDED,
-      R"(optional_field_mask: {paths: "foo__bar"})");
-
-  // Struct
-  RunValidJsonTest(
-      "Struct", REQUIRED,
-      R"({
-        "optionalStruct": {
-          "nullValue": null,
-          "intValue": 1234,
-          "boolValue": true,
-          "doubleValue": 1234.5678,
-          "stringValue": "Hello world!",
-          "listValue": [1234, "5678"],
-          "objectValue": {
-            "value": 0
-          }
-        }
-      })",
-      R"(
-        optional_struct: {
-          fields: {
-            key: "nullValue"
-            value: {null_value: NULL_VALUE}
-          }
-          fields: {
-            key: "intValue"
-            value: {number_value: 1234}
-          }
-          fields: {
-            key: "boolValue"
-            value: {bool_value: true}
-          }
-          fields: {
-            key: "doubleValue"
-            value: {number_value: 1234.5678}
-          }
-          fields: {
-            key: "stringValue"
-            value: {string_value: "Hello world!"}
-          }
-          fields: {
-            key: "listValue"
-            value: {
-              list_value: {
-                values: {
-                  number_value: 1234
-                }
-                values: {
-                  string_value: "5678"
-                }
-              }
-            }
-          }
-          fields: {
-            key: "objectValue"
-            value: {
-              struct_value: {
-                fields: {
-                  key: "value"
-                  value: {
-                    number_value: 0
-                  }
-                }
-              }
-            }
-          }
-        }
-      )");
-  // Value
-  RunValidJsonTest(
-      "ValueAcceptInteger", REQUIRED,
-      R"({"optionalValue": 1})",
-      "optional_value: { number_value: 1}");
-  RunValidJsonTest(
-      "ValueAcceptFloat", REQUIRED,
-      R"({"optionalValue": 1.5})",
-      "optional_value: { number_value: 1.5}");
-  RunValidJsonTest(
-      "ValueAcceptBool", REQUIRED,
-      R"({"optionalValue": false})",
-      "optional_value: { bool_value: false}");
-  RunValidJsonTest(
-      "ValueAcceptNull", REQUIRED,
-      R"({"optionalValue": null})",
-      "optional_value: { null_value: NULL_VALUE}");
-  RunValidJsonTest(
-      "ValueAcceptString", REQUIRED,
-      R"({"optionalValue": "hello"})",
-      R"(optional_value: { string_value: "hello"})");
-  RunValidJsonTest(
-      "ValueAcceptList", REQUIRED,
-      R"({"optionalValue": [0, "hello"]})",
-      R"(
-        optional_value: {
-          list_value: {
-            values: {
-              number_value: 0
-            }
-            values: {
-              string_value: "hello"
-            }
-          }
-        }
-      )");
-  RunValidJsonTest(
-      "ValueAcceptListWithNull", REQUIRED,
-      R"({"optionalValue": ["x", null, "y"]})",
-      R"(
-        optional_value: {
-          list_value: {
-            values: {
-              string_value: "x"
-            }
-            values: {
-              null_value: NULL_VALUE
-            }
-            values: {
-              string_value: "y"
-            }
-          }
-        }
-      )");
-  RunValidJsonTest(
-      "ValueAcceptObject", REQUIRED,
-      R"({"optionalValue": {"value": 1}})",
-      R"(
-        optional_value: {
-          struct_value: {
-            fields: {
-              key: "value"
-              value: {
-                number_value: 1
-              }
-            }
-          }
-        }
-      )");
-
-  // Any
-  RunValidJsonTest(
-      "Any", REQUIRED,
-      R"({
-        "optionalAny": {
-          "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3",
-          "optionalInt32": 12345
-        }
-      })",
-      R"(
-        optional_any: {
-          [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
-            optional_int32: 12345
-          }
-        }
-      )");
-  RunValidJsonTest(
-      "AnyNested", REQUIRED,
-      R"({
-        "optionalAny": {
-          "@type": "type.googleapis.com/google.protobuf.Any",
-          "value": {
-            "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3",
-            "optionalInt32": 12345
-          }
-        }
-      })",
-      R"(
-        optional_any: {
-          [type.googleapis.com/google.protobuf.Any] {
-            [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
-              optional_int32: 12345
-            }
-          }
-        }
-      )");
-  // The special "@type" tag is not required to appear first.
-  RunValidJsonTest(
-      "AnyUnorderedTypeTag", REQUIRED,
-      R"({
-        "optionalAny": {
-          "optionalInt32": 12345,
-          "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3"
-        }
-      })",
-      R"(
-        optional_any: {
-          [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
-            optional_int32: 12345
-          }
-        }
-      )");
-  // Well-known types in Any.
-  RunValidJsonTest(
-      "AnyWithInt32ValueWrapper", REQUIRED,
-      R"({
-        "optionalAny": {
-          "@type": "type.googleapis.com/google.protobuf.Int32Value",
-          "value": 12345
-        }
-      })",
-      R"(
-        optional_any: {
-          [type.googleapis.com/google.protobuf.Int32Value] {
-            value: 12345
-          }
-        }
-      )");
-  RunValidJsonTest(
-      "AnyWithDuration", REQUIRED,
-      R"({
-        "optionalAny": {
-          "@type": "type.googleapis.com/google.protobuf.Duration",
-          "value": "1.5s"
-        }
-      })",
-      R"(
-        optional_any: {
-          [type.googleapis.com/google.protobuf.Duration] {
-            seconds: 1
-            nanos: 500000000
-          }
-        }
-      )");
-  RunValidJsonTest(
-      "AnyWithTimestamp", REQUIRED,
-      R"({
-        "optionalAny": {
-          "@type": "type.googleapis.com/google.protobuf.Timestamp",
-          "value": "1970-01-01T00:00:00Z"
-        }
-      })",
-      R"(
-        optional_any: {
-          [type.googleapis.com/google.protobuf.Timestamp] {
-            seconds: 0
-            nanos: 0
-          }
-        }
-      )");
-  RunValidJsonTest(
-      "AnyWithFieldMask", REQUIRED,
-      R"({
-        "optionalAny": {
-          "@type": "type.googleapis.com/google.protobuf.FieldMask",
-          "value": "foo,barBaz"
-        }
-      })",
-      R"(
-        optional_any: {
-          [type.googleapis.com/google.protobuf.FieldMask] {
-            paths: ["foo", "bar_baz"]
-          }
-        }
-      )");
-  RunValidJsonTest(
-      "AnyWithStruct", REQUIRED,
-      R"({
-        "optionalAny": {
-          "@type": "type.googleapis.com/google.protobuf.Struct",
-          "value": {
-            "foo": 1
-          }
-        }
-      })",
-      R"(
-        optional_any: {
-          [type.googleapis.com/google.protobuf.Struct] {
-            fields: {
-              key: "foo"
-              value: {
-                number_value: 1
-              }
-            }
-          }
-        }
-      )");
-  RunValidJsonTest(
-      "AnyWithValueForJsonObject", REQUIRED,
-      R"({
-        "optionalAny": {
-          "@type": "type.googleapis.com/google.protobuf.Value",
-          "value": {
-            "foo": 1
-          }
-        }
-      })",
-      R"(
-        optional_any: {
-          [type.googleapis.com/google.protobuf.Value] {
-            struct_value: {
-              fields: {
-                key: "foo"
-                value: {
-                  number_value: 1
-                }
-              }
-            }
-          }
-        }
-      )");
-  RunValidJsonTest(
-      "AnyWithValueForInteger", REQUIRED,
-      R"({
-        "optionalAny": {
-          "@type": "type.googleapis.com/google.protobuf.Value",
-          "value": 1
-        }
-      })",
-      R"(
-        optional_any: {
-          [type.googleapis.com/google.protobuf.Value] {
-            number_value: 1
-          }
-        }
-      )");
-
-  RunValidJsonIgnoreUnknownTest(
-      "IgnoreUnknownJsonNumber", REQUIRED,
-      R"({
-        "unknown": 1
-      })",
-      "");
-  RunValidJsonIgnoreUnknownTest(
-      "IgnoreUnknownJsonString", REQUIRED,
-      R"({
-        "unknown": "a"
-      })",
-      "");
-  RunValidJsonIgnoreUnknownTest(
-      "IgnoreUnknownJsonTrue", REQUIRED,
-      R"({
-        "unknown": true
-      })",
-      "");
-  RunValidJsonIgnoreUnknownTest(
-      "IgnoreUnknownJsonFalse", REQUIRED,
-      R"({
-        "unknown": false
-      })",
-      "");
-  RunValidJsonIgnoreUnknownTest(
-      "IgnoreUnknownJsonNull", REQUIRED,
-      R"({
-        "unknown": null
-      })",
-      "");
-  RunValidJsonIgnoreUnknownTest(
-      "IgnoreUnknownJsonObject", REQUIRED,
-      R"({
-        "unknown": {"a": 1}
-      })",
-      "");
+  RunSuiteImpl();
 
   bool ok = true;
   if (!CheckSetEmpty(expected_to_fail_, "nonexistent_tests.txt",
diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h
index 2044896..8738735 100644
--- a/conformance/conformance_test.h
+++ b/conformance/conformance_test.h
@@ -40,12 +40,13 @@
 
 #include <functional>
 #include <string>
+
+#include <google/protobuf/descriptor.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/util/type_resolver.h>
 #include <google/protobuf/wire_format_lite.h>
 
 #include "conformance.pb.h"
-#include "third_party/jsoncpp/json.h"
 
 namespace conformance {
 class ConformanceRequest;
@@ -78,7 +79,23 @@
 };
 
 // Class representing the test suite itself.  To run it, implement your own
-// class derived from ConformanceTestRunner and then write code like:
+// class derived from ConformanceTestRunner, class derived from
+// ConformanceTestSuite and then write code like:
+//
+//    class MyConformanceTestSuite : public ConformanceTestSuite {
+//     public:
+//      void RunSuiteImpl() {
+//        // INSERT ACTURAL TESTS.
+//      }
+//    };
+//
+//    // Force MyConformanceTestSuite to be added at dynamic initialization
+//    // time.
+//    struct StaticTestSuiteInitializer {
+//      StaticTestSuiteInitializer() {
+//        AddTestSuite(new MyConformanceTestSuite());
+//      }
+//    } static_test_suite_initializer;
 //
 //    class MyConformanceTestRunner : public ConformanceTestRunner {
 //     public:
@@ -89,15 +106,17 @@
 //
 //    int main() {
 //      MyConformanceTestRunner runner;
-//      google::protobuf::ConformanceTestSuite suite;
-//
-//      std::string output;
-//      suite.RunSuite(&runner, &output);
+//      const std::set<ConformanceTestSuite*>& test_suite_set =
+//          ::google::protobuf::GetTestSuiteSet();
+//      for (auto suite : test_suite_set) {
+//        suite->RunSuite(&runner, &output);
+//      }
 //    }
 //
 class ConformanceTestSuite {
  public:
   ConformanceTestSuite() : verbose_(false), enforce_recommended_(false) {}
+  virtual ~ConformanceTestSuite() {}
 
   void SetVerbose(bool verbose) { verbose_ = verbose; }
 
@@ -130,7 +149,7 @@
   // tests passed.
   bool RunSuite(ConformanceTestRunner* runner, std::string* output);
 
- private:
+ protected:
   // Test cases are classified into a few categories:
   //   REQUIRED: the test case must be passed for an implementation to be
   //             interoperable with other implementations. For example, a
@@ -151,34 +170,43 @@
   class ConformanceRequestSetting {
    public:
     ConformanceRequestSetting(
-        ConformanceLevel level, conformance::WireFormat input_format,
+        ConformanceLevel level,
+        conformance::WireFormat input_format,
         conformance::WireFormat output_format,
         conformance::TestCategory test_category,
-        bool is_proto3,
+        const Message& prototype_message,
         const string& test_name, const string& input);
+    virtual ~ConformanceRequestSetting() {}
 
-   Message* GetTestMessage() const;
+    Message* GetTestMessage() const;
 
-   const string& GetTestName() const {
-     return test_name_;
-   }
+    string GetTestName() const;
 
-   const conformance::ConformanceRequest& GetRequest() const {
-     return request_;
-   }
+    const conformance::ConformanceRequest& GetRequest() const {
+      return request_;
+    }
 
-   const ConformanceLevel GetLevel() const {
-     return level_;
-   }
+    const ConformanceLevel GetLevel() const {
+      return level_;
+    }
+
+    string ConformanceLevelToString(ConformanceLevel level) const;
+
+   protected:
+    virtual string InputFormatString(conformance::WireFormat format) const;
+    virtual string OutputFormatString(conformance::WireFormat format) const;
 
    private:
     ConformanceLevel level_;
-    bool is_proto3_;
+    ::conformance::WireFormat input_format_;
+    ::conformance::WireFormat output_format_;
+    const Message& prototype_message_;
     string test_name_;
     conformance::ConformanceRequest request_;
   };
 
-  static string ConformanceLevelToString(ConformanceLevel level);
+  bool CheckSetEmpty(const std::set<string>& set_to_check,
+                     const std::string& write_to_file, const std::string& msg);
 
   void ReportSuccess(const std::string& test_name);
   void ReportFailure(const string& test_name,
@@ -189,73 +217,18 @@
   void ReportSkip(const string& test_name,
                   const conformance::ConformanceRequest& request,
                   const conformance::ConformanceResponse& response);
-  void RunTest(const std::string& test_name,
-               const conformance::ConformanceRequest& request,
-               conformance::ConformanceResponse* response);
+
   void RunValidInputTest(const ConformanceRequestSetting& setting,
                          const string& equivalent_text_format);
   void RunValidBinaryInputTest(const ConformanceRequestSetting& setting,
                                const string& equivalent_wire_format);
-  void RunValidJsonTest(const string& test_name,
-                        ConformanceLevel level,
-                        const string& input_json,
-                        const string& equivalent_text_format);
-  void RunValidJsonIgnoreUnknownTest(
-      const string& test_name, ConformanceLevel level, const string& input_json,
-      const string& equivalent_text_format);
-  void RunValidJsonTestWithProtobufInput(
-      const string& test_name,
-      ConformanceLevel level,
-      const protobuf_test_messages::proto3::TestAllTypesProto3& input,
-      const string& equivalent_text_format);
-  void RunValidProtobufTest(const string& test_name, ConformanceLevel level,
-                            const string& input_protobuf,
-                            const string& equivalent_text_format,
-                            bool isProto3);
-  void RunValidBinaryProtobufTest(const string& test_name,
-                                  ConformanceLevel level,
-                                  const string& input_protobuf,
-                                  bool isProto3);
-  void RunValidProtobufTestWithMessage(
-      const string& test_name, ConformanceLevel level,
-      const Message *input,
-      const string& equivalent_text_format,
-      bool isProto3);
 
-  typedef std::function<bool(const Json::Value&)> Validator;
-  void RunValidJsonTestWithValidator(const string& test_name,
-                                     ConformanceLevel level,
-                                     const string& input_json,
-                                     const Validator& validator);
-  void ExpectParseFailureForJson(const string& test_name,
-                                 ConformanceLevel level,
-                                 const string& input_json);
-  void ExpectSerializeFailureForJson(const string& test_name,
-                                     ConformanceLevel level,
-                                     const string& text_format);
-  void ExpectParseFailureForProtoWithProtoVersion (const string& proto,
-                                                   const string& test_name,
-                                                   ConformanceLevel level,
-                                                   bool isProto3);
-  void ExpectParseFailureForProto(const std::string& proto,
-                                  const std::string& test_name,
-                                  ConformanceLevel level);
-  void ExpectHardParseFailureForProto(const std::string& proto,
-                                      const std::string& test_name,
-                                      ConformanceLevel level);
-  void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type);
-  void TestIllegalTags();
-  template <class MessageType>
-  void TestOneofMessage (MessageType &message,
-                         bool isProto3);
-  template <class MessageType>
-  void TestUnknownMessage (MessageType &message,
-                           bool isProto3);
-  void TestValidDataForType(
-      google::protobuf::FieldDescriptor::Type,
-      std::vector<std::pair<std::string, std::string>> values);
-  bool CheckSetEmpty(const std::set<string>& set_to_check,
-                     const std::string& write_to_file, const std::string& msg);
+  void RunTest(const std::string& test_name,
+               const conformance::ConformanceRequest& request,
+               conformance::ConformanceResponse* response);
+
+  virtual void RunSuiteImpl() = 0;
+
   ConformanceTestRunner* runner_;
   int successes_;
   int expected_failures_;
@@ -281,10 +254,14 @@
   // The set of tests that the testee opted out of;
   std::set<std::string> skipped_;
 
-  std::unique_ptr<google::protobuf::util::TypeResolver> type_resolver_;
+  std::unique_ptr<google::protobuf::util::TypeResolver>
+      type_resolver_;
   std::string type_url_;
 };
 
+void AddTestSuite(ConformanceTestSuite* suite);
+const std::set<ConformanceTestSuite*>& GetTestSuiteSet();
+
 }  // namespace protobuf
 }  // namespace google
 
diff --git a/conformance/conformance_test_impl.cc b/conformance/conformance_test_impl.cc
new file mode 100644
index 0000000..acd0f25
--- /dev/null
+++ b/conformance/conformance_test_impl.cc
@@ -0,0 +1,2368 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "conformance_test.h"
+#include "third_party/jsoncpp/json.h"
+
+#include <google/protobuf/test_messages_proto3.pb.h>
+#include <google/protobuf/test_messages_proto2.pb.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/util/type_resolver_util.h>
+#include <google/protobuf/wire_format_lite.h>
+
+using conformance::ConformanceRequest;
+using conformance::ConformanceResponse;
+using google::protobuf::Descriptor;
+using google::protobuf::FieldDescriptor;
+using google::protobuf::Message;
+using google::protobuf::internal::WireFormatLite;
+using google::protobuf::TextFormat;
+using google::protobuf::util::NewTypeResolverForDescriptorPool;
+using protobuf_test_messages::proto3::TestAllTypesProto3;
+using protobuf_test_messages::proto2::TestAllTypesProto2;
+using std::string;
+
+namespace {
+
+static const char kTypeUrlPrefix[] = "type.googleapis.com";
+
+static string GetTypeUrl(const Descriptor* message) {
+  return string(kTypeUrlPrefix) + "/" + message->full_name();
+}
+
+/* Routines for building arbitrary protos *************************************/
+
+// We would use CodedOutputStream except that we want more freedom to build
+// arbitrary protos (even invalid ones).
+
+const string empty;
+
+string cat(const string& a, const string& b,
+           const string& c = empty,
+           const string& d = empty,
+           const string& e = empty,
+           const string& f = empty,
+           const string& g = empty,
+           const string& h = empty,
+           const string& i = empty,
+           const string& j = empty,
+           const string& k = empty,
+           const string& l = empty) {
+  string ret;
+  ret.reserve(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() +
+              g.size() + h.size() + i.size() + j.size() + k.size() + l.size());
+  ret.append(a);
+  ret.append(b);
+  ret.append(c);
+  ret.append(d);
+  ret.append(e);
+  ret.append(f);
+  ret.append(g);
+  ret.append(h);
+  ret.append(i);
+  ret.append(j);
+  ret.append(k);
+  ret.append(l);
+  return ret;
+}
+
+// The maximum number of bytes that it takes to encode a 64-bit varint.
+#define VARINT_MAX_LEN 10
+
+size_t vencode64(uint64_t val, int over_encoded_bytes, char *buf) {
+  if (val == 0) { buf[0] = 0; return 1; }
+  size_t i = 0;
+  while (val) {
+    uint8_t byte = val & 0x7fU;
+    val >>= 7;
+    if (val || over_encoded_bytes) byte |= 0x80U;
+    buf[i++] = byte;
+  }
+  while (over_encoded_bytes--) {
+    assert(i < 10);
+    uint8_t byte = over_encoded_bytes ? 0x80 : 0;
+    buf[i++] = byte;
+  }
+  return i;
+}
+
+string varint(uint64_t x) {
+  char buf[VARINT_MAX_LEN];
+  size_t len = vencode64(x, 0, buf);
+  return string(buf, len);
+}
+
+// Encodes a varint that is |extra| bytes longer than it needs to be, but still
+// valid.
+string longvarint(uint64_t x, int extra) {
+  char buf[VARINT_MAX_LEN];
+  size_t len = vencode64(x, extra, buf);
+  return string(buf, len);
+}
+
+// TODO: proper byte-swapping for big-endian machines.
+string fixed32(void *data) { return string(static_cast<char*>(data), 4); }
+string fixed64(void *data) { return string(static_cast<char*>(data), 8); }
+
+string delim(const string& buf) { return cat(varint(buf.size()), buf); }
+string u32(uint32_t u32) { return fixed32(&u32); }
+string u64(uint64_t u64) { return fixed64(&u64); }
+string flt(float f) { return fixed32(&f); }
+string dbl(double d) { return fixed64(&d); }
+string zz32(int32_t x) { return varint(WireFormatLite::ZigZagEncode32(x)); }
+string zz64(int64_t x) { return varint(WireFormatLite::ZigZagEncode64(x)); }
+
+string tag(uint32_t fieldnum, char wire_type) {
+  return varint((fieldnum << 3) | wire_type);
+}
+
+string submsg(uint32_t fn, const string& buf) {
+  return cat( tag(fn, WireFormatLite::WIRETYPE_LENGTH_DELIMITED), delim(buf) );
+}
+
+#define UNKNOWN_FIELD 666
+
+const FieldDescriptor* GetFieldForType(FieldDescriptor::Type type,
+                                       bool repeated, bool is_proto3) {
+
+  const Descriptor* d = is_proto3 ?
+      TestAllTypesProto3().GetDescriptor() : TestAllTypesProto2().GetDescriptor();
+  for (int i = 0; i < d->field_count(); i++) {
+    const FieldDescriptor* f = d->field(i);
+    if (f->type() == type && f->is_repeated() == repeated) {
+      return f;
+    }
+  }
+  GOOGLE_LOG(FATAL) << "Couldn't find field with type " << (int)type;
+  return nullptr;
+}
+
+string UpperCase(string str) {
+  for (int i = 0; i < str.size(); i++) {
+    str[i] = toupper(str[i]);
+  }
+  return str;
+}
+
+std::unique_ptr<Message> NewTestMessage(bool is_proto3) {
+  std::unique_ptr<Message> prototype;
+  if (is_proto3) {
+    prototype.reset(new TestAllTypesProto3());
+  } else {
+    prototype.reset(new TestAllTypesProto2());
+  }
+  return prototype;
+}
+
+}  // anonymous namespace
+
+namespace google {
+namespace protobuf {
+
+class ConformanceTestSuiteImpl : public ConformanceTestSuite {
+ public:
+  ConformanceTestSuiteImpl() {}
+
+ private:
+  void RunSuiteImpl();
+  void RunValidJsonTest(const string& test_name,
+                        ConformanceLevel level,
+                        const string& input_json,
+                        const string& equivalent_text_format);
+  void RunValidJsonTestWithProtobufInput(
+      const string& test_name,
+      ConformanceLevel level,
+      const protobuf_test_messages::proto3::TestAllTypesProto3& input,
+      const string& equivalent_text_format);
+  void RunValidJsonIgnoreUnknownTest(
+      const string& test_name, ConformanceLevel level, const string& input_json,
+      const string& equivalent_text_format);
+  void RunValidProtobufTest(const string& test_name, ConformanceLevel level,
+                            const string& input_protobuf,
+                            const string& equivalent_text_format,
+                            bool is_proto3);
+  void RunValidBinaryProtobufTest(const string& test_name,
+                                  ConformanceLevel level,
+                                  const string& input_protobuf,
+                                  bool is_proto3);
+  void RunValidProtobufTestWithMessage(
+      const string& test_name, ConformanceLevel level,
+      const Message *input,
+      const string& equivalent_text_format,
+      bool is_proto3);
+
+  typedef std::function<bool(const Json::Value&)> Validator;
+  void RunValidJsonTestWithValidator(const string& test_name,
+                                     ConformanceLevel level,
+                                     const string& input_json,
+                                     const Validator& validator);
+  void ExpectParseFailureForJson(const string& test_name,
+                                 ConformanceLevel level,
+                                 const string& input_json);
+  void ExpectSerializeFailureForJson(const string& test_name,
+                                     ConformanceLevel level,
+                                     const string& text_format);
+  void ExpectParseFailureForProtoWithProtoVersion (const string& proto,
+                                                   const string& test_name,
+                                                   ConformanceLevel level,
+                                                   bool is_proto3);
+  void ExpectParseFailureForProto(const std::string& proto,
+                                  const std::string& test_name,
+                                  ConformanceLevel level);
+  void ExpectHardParseFailureForProto(const std::string& proto,
+                                      const std::string& test_name,
+                                      ConformanceLevel level);
+  void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type);
+  void TestIllegalTags();
+  template <class MessageType>
+  void TestOneofMessage (MessageType &message,
+                         bool is_proto3);
+  template <class MessageType>
+  void TestUnknownMessage (MessageType &message,
+                           bool is_proto3);
+  void TestValidDataForType(
+      google::protobuf::FieldDescriptor::Type,
+      std::vector<std::pair<std::string, std::string>> values);
+};
+
+void ConformanceTestSuiteImpl::ExpectParseFailureForProtoWithProtoVersion (
+    const string& proto, const string& test_name, ConformanceLevel level,
+    bool is_proto3) {
+  std::unique_ptr<Message> prototype = NewTestMessage(is_proto3);
+  // We don't expect output, but if the program erroneously accepts the protobuf
+  // we let it send its response as this.  We must not leave it unspecified.
+  ConformanceRequestSetting setting(
+      level, conformance::PROTOBUF, conformance::PROTOBUF,
+      conformance::BINARY_TEST,
+      *prototype, test_name, proto);
+
+  const ConformanceRequest& request = setting.GetRequest();
+  ConformanceResponse response;
+  string effective_test_name =
+      StrCat(setting.ConformanceLevelToString(level),
+             (is_proto3 ? ".Proto3" : ".Proto2"),
+             ".ProtobufInput.", test_name);
+
+  RunTest(effective_test_name, request, &response);
+  if (response.result_case() == ConformanceResponse::kParseError) {
+    ReportSuccess(effective_test_name);
+  } else if (response.result_case() == ConformanceResponse::kSkipped) {
+    ReportSkip(effective_test_name, request, response);
+  } else {
+    ReportFailure(effective_test_name, level, request, response,
+                  "Should have failed to parse, but didn't.");
+  }
+}
+
+// Expect that this precise protobuf will cause a parse error.
+void ConformanceTestSuiteImpl::ExpectParseFailureForProto(
+    const string& proto, const string& test_name, ConformanceLevel level) {
+  ExpectParseFailureForProtoWithProtoVersion(proto, test_name, level, true);
+  ExpectParseFailureForProtoWithProtoVersion(proto, test_name, level, false);
+}
+
+// Expect that this protobuf will cause a parse error, even if it is followed
+// by valid protobuf data.  We can try running this twice: once with this
+// data verbatim and once with this data followed by some valid data.
+//
+// TODO(haberman): implement the second of these.
+void ConformanceTestSuiteImpl::ExpectHardParseFailureForProto(
+    const string& proto, const string& test_name, ConformanceLevel level) {
+  return ExpectParseFailureForProto(proto, test_name, level);
+}
+
+void ConformanceTestSuiteImpl::RunValidJsonTest(
+    const string& test_name, ConformanceLevel level, const string& input_json,
+    const string& equivalent_text_format) {
+  TestAllTypesProto3 prototype;
+  ConformanceRequestSetting setting1(
+      level, conformance::JSON, conformance::PROTOBUF,
+      conformance::JSON_TEST,
+      prototype, test_name, input_json);
+  RunValidInputTest(setting1, equivalent_text_format);
+  ConformanceRequestSetting setting2(
+      level, conformance::JSON, conformance::JSON,
+      conformance::JSON_TEST,
+      prototype, test_name, input_json);
+  RunValidInputTest(setting2, equivalent_text_format);
+}
+
+void ConformanceTestSuiteImpl::RunValidJsonTestWithProtobufInput(
+    const string& test_name, ConformanceLevel level, const TestAllTypesProto3& input,
+    const string& equivalent_text_format) {
+  ConformanceRequestSetting setting(
+      level, conformance::PROTOBUF, conformance::JSON,
+      conformance::JSON_TEST,
+      input, test_name, input.SerializeAsString());
+  RunValidInputTest(setting, equivalent_text_format);
+}
+
+void ConformanceTestSuiteImpl::RunValidJsonIgnoreUnknownTest(
+    const string& test_name, ConformanceLevel level, const string& input_json,
+    const string& equivalent_text_format) {
+  TestAllTypesProto3 prototype;
+  ConformanceRequestSetting setting(
+      level, conformance::JSON, conformance::PROTOBUF,
+      conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST,
+      prototype, test_name, input_json);
+  RunValidInputTest(setting, equivalent_text_format);
+}
+
+void ConformanceTestSuiteImpl::RunValidProtobufTest(
+    const string& test_name, ConformanceLevel level,
+    const string& input_protobuf, const string& equivalent_text_format,
+    bool is_proto3) {
+  std::unique_ptr<Message> prototype = NewTestMessage(is_proto3);
+
+  ConformanceRequestSetting setting1(
+      level, conformance::PROTOBUF, conformance::PROTOBUF,
+      conformance::BINARY_TEST,
+      *prototype, test_name, input_protobuf);
+  RunValidInputTest(setting1, equivalent_text_format);
+
+  if (is_proto3) {
+    ConformanceRequestSetting setting2(
+        level, conformance::PROTOBUF, conformance::JSON,
+        conformance::BINARY_TEST,
+        *prototype, test_name, input_protobuf);
+    RunValidInputTest(setting2, equivalent_text_format);
+  }
+}
+
+void ConformanceTestSuiteImpl::RunValidBinaryProtobufTest(
+    const string& test_name, ConformanceLevel level,
+    const string& input_protobuf, bool is_proto3) {
+  std::unique_ptr<Message> prototype = NewTestMessage(is_proto3);
+  ConformanceRequestSetting setting(
+      level, conformance::PROTOBUF, conformance::PROTOBUF,
+      conformance::BINARY_TEST,
+      *prototype, test_name, input_protobuf);
+  RunValidBinaryInputTest(setting, input_protobuf);
+}
+
+void ConformanceTestSuiteImpl::RunValidProtobufTestWithMessage(
+    const string& test_name, ConformanceLevel level, const Message *input,
+    const string& equivalent_text_format, bool is_proto3) {
+  RunValidProtobufTest(test_name, level, input->SerializeAsString(),
+                       equivalent_text_format, is_proto3);
+}
+
+// According to proto3 JSON specification, JSON serializers follow more strict
+// rules than parsers (e.g., a serializer must serialize int32 values as JSON
+// numbers while the parser is allowed to accept them as JSON strings). This
+// method allows strict checking on a proto3 JSON serializer by inspecting
+// the JSON output directly.
+void ConformanceTestSuiteImpl::RunValidJsonTestWithValidator(
+    const string& test_name, ConformanceLevel level, const string& input_json,
+    const Validator& validator) {
+  TestAllTypesProto3 prototype;
+  ConformanceRequestSetting setting(
+      level, conformance::JSON, conformance::JSON,
+      conformance::JSON_TEST,
+      prototype, test_name, input_json);
+  const ConformanceRequest& request = setting.GetRequest();
+  ConformanceResponse response;
+  string effective_test_name =
+      StrCat(setting.ConformanceLevelToString(level),
+             ".Proto3.JsonInput.",
+             test_name, ".Validator");
+
+  RunTest(effective_test_name, request, &response);
+
+  if (response.result_case() == ConformanceResponse::kSkipped) {
+    ReportSkip(effective_test_name, request, response);
+    return;
+  }
+
+  if (response.result_case() != ConformanceResponse::kJsonPayload) {
+    ReportFailure(effective_test_name, level, request, response,
+                  "Expected JSON payload but got type %d.",
+                  response.result_case());
+    return;
+  }
+  Json::Reader reader;
+  Json::Value value;
+  if (!reader.parse(response.json_payload(), value)) {
+    ReportFailure(effective_test_name, level, request, response,
+                  "JSON payload cannot be parsed as valid JSON: %s",
+                  reader.getFormattedErrorMessages().c_str());
+    return;
+  }
+  if (!validator(value)) {
+    ReportFailure(effective_test_name, level, request, response,
+                  "JSON payload validation failed.");
+    return;
+  }
+  ReportSuccess(effective_test_name);
+}
+
+void ConformanceTestSuiteImpl::ExpectParseFailureForJson(
+    const string& test_name, ConformanceLevel level, const string& input_json) {
+  TestAllTypesProto3 prototype;
+  // We don't expect output, but if the program erroneously accepts the protobuf
+  // we let it send its response as this.  We must not leave it unspecified.
+  ConformanceRequestSetting setting(
+      level, conformance::JSON, conformance::JSON,
+      conformance::JSON_TEST,
+      prototype, test_name, input_json);
+  const ConformanceRequest& request = setting.GetRequest();
+  ConformanceResponse response;
+  string effective_test_name =
+      StrCat(setting.ConformanceLevelToString(level),
+             ".Proto3.JsonInput.", test_name);
+
+  RunTest(effective_test_name, request, &response);
+  if (response.result_case() == ConformanceResponse::kParseError) {
+    ReportSuccess(effective_test_name);
+  } else if (response.result_case() == ConformanceResponse::kSkipped) {
+    ReportSkip(effective_test_name, request, response);
+  } else {
+    ReportFailure(effective_test_name, level, request, response,
+                  "Should have failed to parse, but didn't.");
+  }
+}
+
+void ConformanceTestSuiteImpl::ExpectSerializeFailureForJson(
+    const string& test_name, ConformanceLevel level, const string& text_format) {
+  TestAllTypesProto3 payload_message;
+  GOOGLE_CHECK(
+      TextFormat::ParseFromString(text_format, &payload_message))
+          << "Failed to parse: " << text_format;
+
+  TestAllTypesProto3 prototype;
+  ConformanceRequestSetting setting(
+      level, conformance::PROTOBUF, conformance::JSON,
+      conformance::JSON_TEST,
+      prototype, test_name, payload_message.SerializeAsString());
+  const ConformanceRequest& request = setting.GetRequest();
+  ConformanceResponse response;
+  string effective_test_name =
+      StrCat(setting.ConformanceLevelToString(level),
+             ".", test_name, ".JsonOutput");
+
+  RunTest(effective_test_name, request, &response);
+  if (response.result_case() == ConformanceResponse::kSerializeError) {
+    ReportSuccess(effective_test_name);
+  } else if (response.result_case() == ConformanceResponse::kSkipped) {
+    ReportSkip(effective_test_name, request, response);
+  } else {
+    ReportFailure(effective_test_name, level, request, response,
+                  "Should have failed to serialize, but didn't.");
+  }
+}
+
+//TODO: proto2?
+void ConformanceTestSuiteImpl::TestPrematureEOFForType(
+    FieldDescriptor::Type type) {
+  // Incomplete values for each wire type.
+  static const string incompletes[6] = {
+    string("\x80"),     // VARINT
+    string("abcdefg"),  // 64BIT
+    string("\x80"),     // DELIMITED (partial length)
+    string(),           // START_GROUP (no value required)
+    string(),           // END_GROUP (no value required)
+    string("abc")       // 32BIT
+  };
+
+  const FieldDescriptor* field = GetFieldForType(type, false, true);
+  const FieldDescriptor* rep_field = GetFieldForType(type, true, true);
+  WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType(
+      static_cast<WireFormatLite::FieldType>(type));
+  const string& incomplete = incompletes[wire_type];
+  const string type_name =
+      UpperCase(string(".") + FieldDescriptor::TypeName(type));
+
+  ExpectParseFailureForProto(
+      tag(field->number(), wire_type),
+      "PrematureEofBeforeKnownNonRepeatedValue" + type_name, REQUIRED);
+
+  ExpectParseFailureForProto(
+      tag(rep_field->number(), wire_type),
+      "PrematureEofBeforeKnownRepeatedValue" + type_name, REQUIRED);
+
+  ExpectParseFailureForProto(
+      tag(UNKNOWN_FIELD, wire_type),
+      "PrematureEofBeforeUnknownValue" + type_name, REQUIRED);
+
+  ExpectParseFailureForProto(
+      cat( tag(field->number(), wire_type), incomplete ),
+      "PrematureEofInsideKnownNonRepeatedValue" + type_name, REQUIRED);
+
+  ExpectParseFailureForProto(
+      cat( tag(rep_field->number(), wire_type), incomplete ),
+      "PrematureEofInsideKnownRepeatedValue" + type_name, REQUIRED);
+
+  ExpectParseFailureForProto(
+      cat( tag(UNKNOWN_FIELD, wire_type), incomplete ),
+      "PrematureEofInsideUnknownValue" + type_name, REQUIRED);
+
+  if (wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+    ExpectParseFailureForProto(
+        cat( tag(field->number(), wire_type), varint(1) ),
+        "PrematureEofInDelimitedDataForKnownNonRepeatedValue" + type_name,
+        REQUIRED);
+
+    ExpectParseFailureForProto(
+        cat( tag(rep_field->number(), wire_type), varint(1) ),
+        "PrematureEofInDelimitedDataForKnownRepeatedValue" + type_name,
+        REQUIRED);
+
+    // EOF in the middle of delimited data for unknown value.
+    ExpectParseFailureForProto(
+        cat( tag(UNKNOWN_FIELD, wire_type), varint(1) ),
+        "PrematureEofInDelimitedDataForUnknownValue" + type_name, REQUIRED);
+
+    if (type == FieldDescriptor::TYPE_MESSAGE) {
+      // Submessage ends in the middle of a value.
+      string incomplete_submsg =
+          cat( tag(WireFormatLite::TYPE_INT32, WireFormatLite::WIRETYPE_VARINT),
+                incompletes[WireFormatLite::WIRETYPE_VARINT] );
+      ExpectHardParseFailureForProto(
+          cat( tag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
+               varint(incomplete_submsg.size()),
+               incomplete_submsg ),
+          "PrematureEofInSubmessageValue" + type_name, REQUIRED);
+    }
+  } else if (type != FieldDescriptor::TYPE_GROUP) {
+    // Non-delimited, non-group: eligible for packing.
+
+    // Packed region ends in the middle of a value.
+    ExpectHardParseFailureForProto(
+        cat(tag(rep_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
+            varint(incomplete.size()), incomplete),
+        "PrematureEofInPackedFieldValue" + type_name, REQUIRED);
+
+    // EOF in the middle of packed region.
+    ExpectParseFailureForProto(
+        cat(tag(rep_field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED),
+            varint(1)),
+        "PrematureEofInPackedField" + type_name, REQUIRED);
+  }
+}
+
+void ConformanceTestSuiteImpl::TestValidDataForType(
+    FieldDescriptor::Type type,
+    std::vector<std::pair<std::string, std::string>> values) {
+  for (int is_proto3 = 0; is_proto3 < 2; is_proto3++) {
+    const string type_name =
+        UpperCase(string(".") + FieldDescriptor::TypeName(type));
+    WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType(
+        static_cast<WireFormatLite::FieldType>(type));
+    const FieldDescriptor* field = GetFieldForType(type, false, is_proto3);
+    const FieldDescriptor* rep_field = GetFieldForType(type, true, is_proto3);
+
+    RunValidProtobufTest("ValidDataScalar" + type_name, REQUIRED,
+                         cat(tag(field->number(), wire_type), values[0].first),
+                         field->name() + ": " + values[0].second, is_proto3);
+
+    string proto;
+    string text = field->name() + ": " + values.back().second;
+    for (size_t i = 0; i < values.size(); i++) {
+      proto += cat(tag(field->number(), wire_type), values[i].first);
+    }
+    RunValidProtobufTest("RepeatedScalarSelectsLast" + type_name, REQUIRED,
+                         proto, text, is_proto3);
+
+    proto.clear();
+    text.clear();
+
+    for (size_t i = 0; i < values.size(); i++) {
+      proto += cat(tag(rep_field->number(), wire_type), values[i].first);
+      text += rep_field->name() + ": " + values[i].second + " ";
+    }
+    RunValidProtobufTest("ValidDataRepeated" + type_name, REQUIRED,
+                         proto, text, is_proto3);
+  }
+}
+
+// TODO: proto2?
+void ConformanceTestSuiteImpl::TestIllegalTags() {
+  // field num 0 is illegal
+  string nullfield[] = {
+    "\1DEADBEEF",
+    "\2\1\1",
+    "\3\4",
+    "\5DEAD"
+  };
+  for (int i = 0; i < 4; i++) {
+    string name = "IllegalZeroFieldNum_Case_0";
+    name.back() += i;
+    ExpectParseFailureForProto(nullfield[i], name, REQUIRED);
+  }
+}
+template <class MessageType>
+void ConformanceTestSuiteImpl::TestOneofMessage (
+    MessageType &message, bool is_proto3) {
+  message.set_oneof_uint32(0);
+  RunValidProtobufTestWithMessage(
+      "OneofZeroUint32", RECOMMENDED, &message, "oneof_uint32: 0", is_proto3);
+  message.mutable_oneof_nested_message()->set_a(0);
+  RunValidProtobufTestWithMessage(
+      "OneofZeroMessage", RECOMMENDED, &message,
+      is_proto3 ? "oneof_nested_message: {}" : "oneof_nested_message: {a: 0}",
+      is_proto3);
+  message.mutable_oneof_nested_message()->set_a(1);
+  RunValidProtobufTestWithMessage(
+      "OneofZeroMessageSetTwice", RECOMMENDED, &message,
+      "oneof_nested_message: {a: 1}",
+      is_proto3);
+  message.set_oneof_string("");
+  RunValidProtobufTestWithMessage(
+      "OneofZeroString", RECOMMENDED, &message, "oneof_string: \"\"", is_proto3);
+  message.set_oneof_bytes("");
+  RunValidProtobufTestWithMessage(
+      "OneofZeroBytes", RECOMMENDED, &message, "oneof_bytes: \"\"", is_proto3);
+  message.set_oneof_bool(false);
+  RunValidProtobufTestWithMessage(
+      "OneofZeroBool", RECOMMENDED, &message, "oneof_bool: false", is_proto3);
+  message.set_oneof_uint64(0);
+  RunValidProtobufTestWithMessage(
+      "OneofZeroUint64", RECOMMENDED, &message, "oneof_uint64: 0", is_proto3);
+  message.set_oneof_float(0.0f);
+  RunValidProtobufTestWithMessage(
+      "OneofZeroFloat", RECOMMENDED, &message, "oneof_float: 0", is_proto3);
+  message.set_oneof_double(0.0);
+  RunValidProtobufTestWithMessage(
+      "OneofZeroDouble", RECOMMENDED, &message, "oneof_double: 0", is_proto3);
+  message.set_oneof_enum(MessageType::FOO);
+  RunValidProtobufTestWithMessage(
+      "OneofZeroEnum", RECOMMENDED, &message, "oneof_enum: FOO", is_proto3);
+}
+
+template <class MessageType>
+void ConformanceTestSuiteImpl::TestUnknownMessage(
+    MessageType& message, bool is_proto3) {
+  message.ParseFromString("\xA8\x1F\x01");
+  RunValidBinaryProtobufTest("UnknownVarint", REQUIRED,
+                             message.SerializeAsString(), is_proto3);
+}
+
+void ConformanceTestSuiteImpl::RunSuiteImpl() {
+  type_resolver_.reset(NewTypeResolverForDescriptorPool(
+      kTypeUrlPrefix, DescriptorPool::generated_pool()));
+  type_url_ = GetTypeUrl(TestAllTypesProto3::descriptor());
+
+  for (int i = 1; i <= FieldDescriptor::MAX_TYPE; i++) {
+    if (i == FieldDescriptor::TYPE_GROUP) continue;
+    TestPrematureEOFForType(static_cast<FieldDescriptor::Type>(i));
+  }
+
+  TestIllegalTags();
+
+  int64 kInt64Min = -9223372036854775808ULL;
+  int64 kInt64Max = 9223372036854775807ULL;
+  uint64 kUint64Max = 18446744073709551615ULL;
+  int32 kInt32Max = 2147483647;
+  int32 kInt32Min = -2147483648;
+  uint32 kUint32Max = 4294967295UL;
+
+  TestValidDataForType(FieldDescriptor::TYPE_DOUBLE, {
+    {dbl(0.1), "0.1"},
+    {dbl(1.7976931348623157e+308), "1.7976931348623157e+308"},
+    {dbl(2.22507385850720138309e-308), "2.22507385850720138309e-308"}
+  });
+  TestValidDataForType(FieldDescriptor::TYPE_FLOAT, {
+    {flt(0.1), "0.1"},
+    {flt(1.00000075e-36), "1.00000075e-36"},
+    {flt(3.402823e+38), "3.402823e+38"},  // 3.40282347e+38
+    {flt(1.17549435e-38f), "1.17549435e-38"}
+  });
+  TestValidDataForType(FieldDescriptor::TYPE_INT64, {
+    {varint(12345), "12345"},
+    {varint(kInt64Max), std::to_string(kInt64Max)},
+    {varint(kInt64Min), std::to_string(kInt64Min)}
+  });
+  TestValidDataForType(FieldDescriptor::TYPE_UINT64, {
+    {varint(12345), "12345"},
+    {varint(kUint64Max), std::to_string(kUint64Max)},
+    {varint(0), "0"}
+  });
+  TestValidDataForType(FieldDescriptor::TYPE_INT32, {
+    {varint(12345), "12345"},
+    {longvarint(12345, 2), "12345"},
+    {longvarint(12345, 7), "12345"},
+    {varint(kInt32Max), std::to_string(kInt32Max)},
+    {varint(kInt32Min), std::to_string(kInt32Min)},
+    {varint(1LL << 33), std::to_string(static_cast<int32>(1LL << 33))},
+    {varint((1LL << 33) - 1),
+     std::to_string(static_cast<int32>((1LL << 33) - 1))},
+  });
+  TestValidDataForType(FieldDescriptor::TYPE_UINT32, {
+    {varint(12345), "12345"},
+    {longvarint(12345, 2), "12345"},
+    {longvarint(12345, 7), "12345"},
+    {varint(kUint32Max), std::to_string(kUint32Max)},  // UINT32_MAX
+    {varint(0), "0"},
+    {varint(1LL << 33), std::to_string(static_cast<uint32>(1LL << 33))},
+    {varint((1LL << 33) - 1),
+     std::to_string(static_cast<uint32>((1LL << 33) - 1))},
+  });
+  TestValidDataForType(FieldDescriptor::TYPE_FIXED64, {
+    {u64(12345), "12345"},
+    {u64(kUint64Max), std::to_string(kUint64Max)},
+    {u64(0), "0"}
+  });
+  TestValidDataForType(FieldDescriptor::TYPE_FIXED32, {
+    {u32(12345), "12345"},
+    {u32(kUint32Max), std::to_string(kUint32Max)},  // UINT32_MAX
+    {u32(0), "0"}
+  });
+  TestValidDataForType(FieldDescriptor::TYPE_SFIXED64, {
+    {u64(12345), "12345"},
+    {u64(kInt64Max), std::to_string(kInt64Max)},
+    {u64(kInt64Min), std::to_string(kInt64Min)}
+  });
+  TestValidDataForType(FieldDescriptor::TYPE_SFIXED32, {
+    {u32(12345), "12345"},
+    {u32(kInt32Max), std::to_string(kInt32Max)},
+    {u32(kInt32Min), std::to_string(kInt32Min)}
+  });
+  TestValidDataForType(FieldDescriptor::TYPE_BOOL, {
+    {varint(1), "true"},
+    {varint(0), "false"},
+    {varint(12345678), "true"}
+  });
+  TestValidDataForType(FieldDescriptor::TYPE_SINT32, {
+    {zz32(12345), "12345"},
+    {zz32(kInt32Max), std::to_string(kInt32Max)},
+    {zz32(kInt32Min), std::to_string(kInt32Min)}
+  });
+  TestValidDataForType(FieldDescriptor::TYPE_SINT64, {
+    {zz64(12345), "12345"},
+    {zz64(kInt64Max), std::to_string(kInt64Max)},
+    {zz64(kInt64Min), std::to_string(kInt64Min)}
+  });
+
+  // TODO(haberman):
+  // TestValidDataForType(FieldDescriptor::TYPE_STRING
+  // TestValidDataForType(FieldDescriptor::TYPE_GROUP
+  // TestValidDataForType(FieldDescriptor::TYPE_MESSAGE
+  // TestValidDataForType(FieldDescriptor::TYPE_BYTES
+  // TestValidDataForType(FieldDescriptor::TYPE_ENUM
+
+  RunValidJsonTest("HelloWorld", REQUIRED,
+                   "{\"optionalString\":\"Hello, World!\"}",
+                   "optional_string: 'Hello, World!'");
+
+  // NOTE: The spec for JSON support is still being sorted out, these may not
+  // all be correct.
+  // Test field name conventions.
+  RunValidJsonTest(
+      "FieldNameInSnakeCase", REQUIRED,
+      R"({
+        "fieldname1": 1,
+        "fieldName2": 2,
+        "FieldName3": 3,
+        "fieldName4": 4
+      })",
+      R"(
+        fieldname1: 1
+        field_name2: 2
+        _field_name3: 3
+        field__name4_: 4
+      )");
+  RunValidJsonTest(
+      "FieldNameWithNumbers", REQUIRED,
+      R"({
+        "field0name5": 5,
+        "field0Name6": 6
+      })",
+      R"(
+        field0name5: 5
+        field_0_name6: 6
+      )");
+  RunValidJsonTest(
+      "FieldNameWithMixedCases", REQUIRED,
+      R"({
+        "fieldName7": 7,
+        "FieldName8": 8,
+        "fieldName9": 9,
+        "FieldName10": 10,
+        "FIELDNAME11": 11,
+        "FIELDName12": 12
+      })",
+      R"(
+        fieldName7: 7
+        FieldName8: 8
+        field_Name9: 9
+        Field_Name10: 10
+        FIELD_NAME11: 11
+        FIELD_name12: 12
+      )");
+  RunValidJsonTest(
+      "FieldNameWithDoubleUnderscores", RECOMMENDED,
+      R"({
+        "FieldName13": 13,
+        "FieldName14": 14,
+        "fieldName15": 15,
+        "fieldName16": 16,
+        "fieldName17": 17,
+        "FieldName18": 18
+      })",
+      R"(
+        __field_name13: 13
+        __Field_name14: 14
+        field__name15: 15
+        field__Name16: 16
+        field_name17__: 17
+        Field_name18__: 18
+      )");
+  // Using the original proto field name in JSON is also allowed.
+  RunValidJsonTest(
+      "OriginalProtoFieldName", REQUIRED,
+      R"({
+        "fieldname1": 1,
+        "field_name2": 2,
+        "_field_name3": 3,
+        "field__name4_": 4,
+        "field0name5": 5,
+        "field_0_name6": 6,
+        "fieldName7": 7,
+        "FieldName8": 8,
+        "field_Name9": 9,
+        "Field_Name10": 10,
+        "FIELD_NAME11": 11,
+        "FIELD_name12": 12,
+        "__field_name13": 13,
+        "__Field_name14": 14,
+        "field__name15": 15,
+        "field__Name16": 16,
+        "field_name17__": 17,
+        "Field_name18__": 18
+      })",
+      R"(
+        fieldname1: 1
+        field_name2: 2
+        _field_name3: 3
+        field__name4_: 4
+        field0name5: 5
+        field_0_name6: 6
+        fieldName7: 7
+        FieldName8: 8
+        field_Name9: 9
+        Field_Name10: 10
+        FIELD_NAME11: 11
+        FIELD_name12: 12
+        __field_name13: 13
+        __Field_name14: 14
+        field__name15: 15
+        field__Name16: 16
+        field_name17__: 17
+        Field_name18__: 18
+      )");
+  // Field names can be escaped.
+  RunValidJsonTest(
+      "FieldNameEscaped", REQUIRED,
+      R"({"fieldn\u0061me1": 1})",
+      "fieldname1: 1");
+  // String ends with escape character.
+  ExpectParseFailureForJson(
+      "StringEndsWithEscapeChar", RECOMMENDED,
+      "{\"optionalString\": \"abc\\");
+  // Field names must be quoted (or it's not valid JSON).
+  ExpectParseFailureForJson(
+      "FieldNameNotQuoted", RECOMMENDED,
+      "{fieldname1: 1}");
+  // Trailing comma is not allowed (not valid JSON).
+  ExpectParseFailureForJson(
+      "TrailingCommaInAnObject", RECOMMENDED,
+      R"({"fieldname1":1,})");
+  ExpectParseFailureForJson(
+      "TrailingCommaInAnObjectWithSpace", RECOMMENDED,
+      R"({"fieldname1":1 ,})");
+  ExpectParseFailureForJson(
+      "TrailingCommaInAnObjectWithSpaceCommaSpace", RECOMMENDED,
+      R"({"fieldname1":1 , })");
+  ExpectParseFailureForJson(
+      "TrailingCommaInAnObjectWithNewlines", RECOMMENDED,
+      R"({
+        "fieldname1":1,
+      })");
+  // JSON doesn't support comments.
+  ExpectParseFailureForJson(
+      "JsonWithComments", RECOMMENDED,
+      R"({
+        // This is a comment.
+        "fieldname1": 1
+      })");
+  // JSON spec says whitespace doesn't matter, so try a few spacings to be sure.
+  RunValidJsonTest(
+      "OneLineNoSpaces", RECOMMENDED,
+      "{\"optionalInt32\":1,\"optionalInt64\":2}",
+      R"(
+        optional_int32: 1
+        optional_int64: 2
+      )");
+  RunValidJsonTest(
+      "OneLineWithSpaces", RECOMMENDED,
+      "{ \"optionalInt32\" : 1 , \"optionalInt64\" : 2 }",
+      R"(
+        optional_int32: 1
+        optional_int64: 2
+      )");
+  RunValidJsonTest(
+      "MultilineNoSpaces", RECOMMENDED,
+      "{\n\"optionalInt32\"\n:\n1\n,\n\"optionalInt64\"\n:\n2\n}",
+      R"(
+        optional_int32: 1
+        optional_int64: 2
+      )");
+  RunValidJsonTest(
+      "MultilineWithSpaces", RECOMMENDED,
+      "{\n  \"optionalInt32\"  :  1\n  ,\n  \"optionalInt64\"  :  2\n}\n",
+      R"(
+        optional_int32: 1
+        optional_int64: 2
+      )");
+  // Missing comma between key/value pairs.
+  ExpectParseFailureForJson(
+      "MissingCommaOneLine", RECOMMENDED,
+      "{ \"optionalInt32\": 1 \"optionalInt64\": 2 }");
+  ExpectParseFailureForJson(
+      "MissingCommaMultiline", RECOMMENDED,
+      "{\n  \"optionalInt32\": 1\n  \"optionalInt64\": 2\n}");
+  // Duplicated field names are not allowed.
+  ExpectParseFailureForJson(
+      "FieldNameDuplicate", RECOMMENDED,
+      R"({
+        "optionalNestedMessage": {a: 1},
+        "optionalNestedMessage": {}
+      })");
+  ExpectParseFailureForJson(
+      "FieldNameDuplicateDifferentCasing1", RECOMMENDED,
+      R"({
+        "optional_nested_message": {a: 1},
+        "optionalNestedMessage": {}
+      })");
+  ExpectParseFailureForJson(
+      "FieldNameDuplicateDifferentCasing2", RECOMMENDED,
+      R"({
+        "optionalNestedMessage": {a: 1},
+        "optional_nested_message": {}
+      })");
+  // Serializers should use lowerCamelCase by default.
+  RunValidJsonTestWithValidator(
+      "FieldNameInLowerCamelCase", REQUIRED,
+      R"({
+        "fieldname1": 1,
+        "fieldName2": 2,
+        "FieldName3": 3,
+        "fieldName4": 4
+      })",
+      [](const Json::Value& value) {
+        return value.isMember("fieldname1") &&
+            value.isMember("fieldName2") &&
+            value.isMember("FieldName3") &&
+            value.isMember("fieldName4");
+      });
+  RunValidJsonTestWithValidator(
+      "FieldNameWithNumbers", REQUIRED,
+      R"({
+        "field0name5": 5,
+        "field0Name6": 6
+      })",
+      [](const Json::Value& value) {
+        return value.isMember("field0name5") &&
+            value.isMember("field0Name6");
+      });
+  RunValidJsonTestWithValidator(
+      "FieldNameWithMixedCases", REQUIRED,
+      R"({
+        "fieldName7": 7,
+        "FieldName8": 8,
+        "fieldName9": 9,
+        "FieldName10": 10,
+        "FIELDNAME11": 11,
+        "FIELDName12": 12
+      })",
+      [](const Json::Value& value) {
+        return value.isMember("fieldName7") &&
+            value.isMember("FieldName8") &&
+            value.isMember("fieldName9") &&
+            value.isMember("FieldName10") &&
+            value.isMember("FIELDNAME11") &&
+            value.isMember("FIELDName12");
+      });
+  RunValidJsonTestWithValidator(
+      "FieldNameWithDoubleUnderscores", RECOMMENDED,
+      R"({
+        "FieldName13": 13,
+        "FieldName14": 14,
+        "fieldName15": 15,
+        "fieldName16": 16,
+        "fieldName17": 17,
+        "FieldName18": 18
+      })",
+      [](const Json::Value& value) {
+        return value.isMember("FieldName13") &&
+            value.isMember("FieldName14") &&
+            value.isMember("fieldName15") &&
+            value.isMember("fieldName16") &&
+            value.isMember("fieldName17") &&
+            value.isMember("FieldName18");
+      });
+
+  // Integer fields.
+  RunValidJsonTest(
+      "Int32FieldMaxValue", REQUIRED,
+      R"({"optionalInt32": 2147483647})",
+      "optional_int32: 2147483647");
+  RunValidJsonTest(
+      "Int32FieldMinValue", REQUIRED,
+      R"({"optionalInt32": -2147483648})",
+      "optional_int32: -2147483648");
+  RunValidJsonTest(
+      "Uint32FieldMaxValue", REQUIRED,
+      R"({"optionalUint32": 4294967295})",
+      "optional_uint32: 4294967295");
+  RunValidJsonTest(
+      "Int64FieldMaxValue", REQUIRED,
+      R"({"optionalInt64": "9223372036854775807"})",
+      "optional_int64: 9223372036854775807");
+  RunValidJsonTest(
+      "Int64FieldMinValue", REQUIRED,
+      R"({"optionalInt64": "-9223372036854775808"})",
+      "optional_int64: -9223372036854775808");
+  RunValidJsonTest(
+      "Uint64FieldMaxValue", REQUIRED,
+      R"({"optionalUint64": "18446744073709551615"})",
+      "optional_uint64: 18446744073709551615");
+  // While not the largest Int64, this is the largest
+  // Int64 which can be exactly represented within an
+  // IEEE-754 64-bit float, which is the expected level
+  // of interoperability guarantee. Larger values may
+  // work in some implementations, but should not be
+  // relied upon.
+  RunValidJsonTest(
+      "Int64FieldMaxValueNotQuoted", REQUIRED,
+      R"({"optionalInt64": 9223372036854774784})",
+      "optional_int64: 9223372036854774784");
+  RunValidJsonTest(
+      "Int64FieldMinValueNotQuoted", REQUIRED,
+      R"({"optionalInt64": -9223372036854775808})",
+      "optional_int64: -9223372036854775808");
+  // Largest interoperable Uint64; see comment above
+  // for Int64FieldMaxValueNotQuoted.
+  RunValidJsonTest(
+      "Uint64FieldMaxValueNotQuoted", REQUIRED,
+      R"({"optionalUint64": 18446744073709549568})",
+      "optional_uint64: 18446744073709549568");
+  // Values can be represented as JSON strings.
+  RunValidJsonTest(
+      "Int32FieldStringValue", REQUIRED,
+      R"({"optionalInt32": "2147483647"})",
+      "optional_int32: 2147483647");
+  RunValidJsonTest(
+      "Int32FieldStringValueEscaped", REQUIRED,
+      R"({"optionalInt32": "2\u003147483647"})",
+      "optional_int32: 2147483647");
+
+  // Parsers reject out-of-bound integer values.
+  ExpectParseFailureForJson(
+      "Int32FieldTooLarge", REQUIRED,
+      R"({"optionalInt32": 2147483648})");
+  ExpectParseFailureForJson(
+      "Int32FieldTooSmall", REQUIRED,
+      R"({"optionalInt32": -2147483649})");
+  ExpectParseFailureForJson(
+      "Uint32FieldTooLarge", REQUIRED,
+      R"({"optionalUint32": 4294967296})");
+  ExpectParseFailureForJson(
+      "Int64FieldTooLarge", REQUIRED,
+      R"({"optionalInt64": "9223372036854775808"})");
+  ExpectParseFailureForJson(
+      "Int64FieldTooSmall", REQUIRED,
+      R"({"optionalInt64": "-9223372036854775809"})");
+  ExpectParseFailureForJson(
+      "Uint64FieldTooLarge", REQUIRED,
+      R"({"optionalUint64": "18446744073709551616"})");
+  // Parser reject non-integer numeric values as well.
+  ExpectParseFailureForJson(
+      "Int32FieldNotInteger", REQUIRED,
+      R"({"optionalInt32": 0.5})");
+  ExpectParseFailureForJson(
+      "Uint32FieldNotInteger", REQUIRED,
+      R"({"optionalUint32": 0.5})");
+  ExpectParseFailureForJson(
+      "Int64FieldNotInteger", REQUIRED,
+      R"({"optionalInt64": "0.5"})");
+  ExpectParseFailureForJson(
+      "Uint64FieldNotInteger", REQUIRED,
+      R"({"optionalUint64": "0.5"})");
+
+  // Integers but represented as float values are accepted.
+  RunValidJsonTest(
+      "Int32FieldFloatTrailingZero", REQUIRED,
+      R"({"optionalInt32": 100000.000})",
+      "optional_int32: 100000");
+  RunValidJsonTest(
+      "Int32FieldExponentialFormat", REQUIRED,
+      R"({"optionalInt32": 1e5})",
+      "optional_int32: 100000");
+  RunValidJsonTest(
+      "Int32FieldMaxFloatValue", REQUIRED,
+      R"({"optionalInt32": 2.147483647e9})",
+      "optional_int32: 2147483647");
+  RunValidJsonTest(
+      "Int32FieldMinFloatValue", REQUIRED,
+      R"({"optionalInt32": -2.147483648e9})",
+      "optional_int32: -2147483648");
+  RunValidJsonTest(
+      "Uint32FieldMaxFloatValue", REQUIRED,
+      R"({"optionalUint32": 4.294967295e9})",
+      "optional_uint32: 4294967295");
+
+  // Parser reject non-numeric values.
+  ExpectParseFailureForJson(
+      "Int32FieldNotNumber", REQUIRED,
+      R"({"optionalInt32": "3x3"})");
+  ExpectParseFailureForJson(
+      "Uint32FieldNotNumber", REQUIRED,
+      R"({"optionalUint32": "3x3"})");
+  ExpectParseFailureForJson(
+      "Int64FieldNotNumber", REQUIRED,
+      R"({"optionalInt64": "3x3"})");
+  ExpectParseFailureForJson(
+      "Uint64FieldNotNumber", REQUIRED,
+      R"({"optionalUint64": "3x3"})");
+  // JSON does not allow "+" on numric values.
+  ExpectParseFailureForJson(
+      "Int32FieldPlusSign", REQUIRED,
+      R"({"optionalInt32": +1})");
+  // JSON doesn't allow leading 0s.
+  ExpectParseFailureForJson(
+      "Int32FieldLeadingZero", REQUIRED,
+      R"({"optionalInt32": 01})");
+  ExpectParseFailureForJson(
+      "Int32FieldNegativeWithLeadingZero", REQUIRED,
+      R"({"optionalInt32": -01})");
+  // String values must follow the same syntax rule. Specifically leading
+  // or trailing spaces are not allowed.
+  ExpectParseFailureForJson(
+      "Int32FieldLeadingSpace", REQUIRED,
+      R"({"optionalInt32": " 1"})");
+  ExpectParseFailureForJson(
+      "Int32FieldTrailingSpace", REQUIRED,
+      R"({"optionalInt32": "1 "})");
+
+  // 64-bit values are serialized as strings.
+  RunValidJsonTestWithValidator(
+      "Int64FieldBeString", RECOMMENDED,
+      R"({"optionalInt64": 1})",
+      [](const Json::Value& value) {
+        return value["optionalInt64"].type() == Json::stringValue &&
+            value["optionalInt64"].asString() == "1";
+      });
+  RunValidJsonTestWithValidator(
+      "Uint64FieldBeString", RECOMMENDED,
+      R"({"optionalUint64": 1})",
+      [](const Json::Value& value) {
+        return value["optionalUint64"].type() == Json::stringValue &&
+            value["optionalUint64"].asString() == "1";
+      });
+
+  // Bool fields.
+  RunValidJsonTest(
+      "BoolFieldTrue", REQUIRED,
+      R"({"optionalBool":true})",
+      "optional_bool: true");
+  RunValidJsonTest(
+      "BoolFieldFalse", REQUIRED,
+      R"({"optionalBool":false})",
+      "optional_bool: false");
+
+  // Other forms are not allowed.
+  ExpectParseFailureForJson(
+      "BoolFieldIntegerZero", RECOMMENDED,
+      R"({"optionalBool":0})");
+  ExpectParseFailureForJson(
+      "BoolFieldIntegerOne", RECOMMENDED,
+      R"({"optionalBool":1})");
+  ExpectParseFailureForJson(
+      "BoolFieldCamelCaseTrue", RECOMMENDED,
+      R"({"optionalBool":True})");
+  ExpectParseFailureForJson(
+      "BoolFieldCamelCaseFalse", RECOMMENDED,
+      R"({"optionalBool":False})");
+  ExpectParseFailureForJson(
+      "BoolFieldAllCapitalTrue", RECOMMENDED,
+      R"({"optionalBool":TRUE})");
+  ExpectParseFailureForJson(
+      "BoolFieldAllCapitalFalse", RECOMMENDED,
+      R"({"optionalBool":FALSE})");
+  ExpectParseFailureForJson(
+      "BoolFieldDoubleQuotedTrue", RECOMMENDED,
+      R"({"optionalBool":"true"})");
+  ExpectParseFailureForJson(
+      "BoolFieldDoubleQuotedFalse", RECOMMENDED,
+      R"({"optionalBool":"false"})");
+
+  // Float fields.
+  RunValidJsonTest(
+      "FloatFieldMinPositiveValue", REQUIRED,
+      R"({"optionalFloat": 1.175494e-38})",
+      "optional_float: 1.175494e-38");
+  RunValidJsonTest(
+      "FloatFieldMaxNegativeValue", REQUIRED,
+      R"({"optionalFloat": -1.175494e-38})",
+      "optional_float: -1.175494e-38");
+  RunValidJsonTest(
+      "FloatFieldMaxPositiveValue", REQUIRED,
+      R"({"optionalFloat": 3.402823e+38})",
+      "optional_float: 3.402823e+38");
+  RunValidJsonTest(
+      "FloatFieldMinNegativeValue", REQUIRED,
+      R"({"optionalFloat": 3.402823e+38})",
+      "optional_float: 3.402823e+38");
+  // Values can be quoted.
+  RunValidJsonTest(
+      "FloatFieldQuotedValue", REQUIRED,
+      R"({"optionalFloat": "1"})",
+      "optional_float: 1");
+  // Special values.
+  RunValidJsonTest(
+      "FloatFieldNan", REQUIRED,
+      R"({"optionalFloat": "NaN"})",
+      "optional_float: nan");
+  RunValidJsonTest(
+      "FloatFieldInfinity", REQUIRED,
+      R"({"optionalFloat": "Infinity"})",
+      "optional_float: inf");
+  RunValidJsonTest(
+      "FloatFieldNegativeInfinity", REQUIRED,
+      R"({"optionalFloat": "-Infinity"})",
+      "optional_float: -inf");
+  // Non-cannonical Nan will be correctly normalized.
+  {
+    TestAllTypesProto3 message;
+    // IEEE floating-point standard 32-bit quiet NaN:
+    //   0111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
+    message.set_optional_float(
+        WireFormatLite::DecodeFloat(0x7FA12345));
+    RunValidJsonTestWithProtobufInput(
+        "FloatFieldNormalizeQuietNan", REQUIRED, message,
+        "optional_float: nan");
+    // IEEE floating-point standard 64-bit signaling NaN:
+    //   1111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
+    message.set_optional_float(
+        WireFormatLite::DecodeFloat(0xFFB54321));
+    RunValidJsonTestWithProtobufInput(
+        "FloatFieldNormalizeSignalingNan", REQUIRED, message,
+        "optional_float: nan");
+  }
+
+  // Special values must be quoted.
+  ExpectParseFailureForJson(
+      "FloatFieldNanNotQuoted", RECOMMENDED,
+      R"({"optionalFloat": NaN})");
+  ExpectParseFailureForJson(
+      "FloatFieldInfinityNotQuoted", RECOMMENDED,
+      R"({"optionalFloat": Infinity})");
+  ExpectParseFailureForJson(
+      "FloatFieldNegativeInfinityNotQuoted", RECOMMENDED,
+      R"({"optionalFloat": -Infinity})");
+  // Parsers should reject out-of-bound values.
+  ExpectParseFailureForJson(
+      "FloatFieldTooSmall", REQUIRED,
+      R"({"optionalFloat": -3.502823e+38})");
+  ExpectParseFailureForJson(
+      "FloatFieldTooLarge", REQUIRED,
+      R"({"optionalFloat": 3.502823e+38})");
+
+  // Double fields.
+  RunValidJsonTest(
+      "DoubleFieldMinPositiveValue", REQUIRED,
+      R"({"optionalDouble": 2.22507e-308})",
+      "optional_double: 2.22507e-308");
+  RunValidJsonTest(
+      "DoubleFieldMaxNegativeValue", REQUIRED,
+      R"({"optionalDouble": -2.22507e-308})",
+      "optional_double: -2.22507e-308");
+  RunValidJsonTest(
+      "DoubleFieldMaxPositiveValue", REQUIRED,
+      R"({"optionalDouble": 1.79769e+308})",
+      "optional_double: 1.79769e+308");
+  RunValidJsonTest(
+      "DoubleFieldMinNegativeValue", REQUIRED,
+      R"({"optionalDouble": -1.79769e+308})",
+      "optional_double: -1.79769e+308");
+  // Values can be quoted.
+  RunValidJsonTest(
+      "DoubleFieldQuotedValue", REQUIRED,
+      R"({"optionalDouble": "1"})",
+      "optional_double: 1");
+  // Speical values.
+  RunValidJsonTest(
+      "DoubleFieldNan", REQUIRED,
+      R"({"optionalDouble": "NaN"})",
+      "optional_double: nan");
+  RunValidJsonTest(
+      "DoubleFieldInfinity", REQUIRED,
+      R"({"optionalDouble": "Infinity"})",
+      "optional_double: inf");
+  RunValidJsonTest(
+      "DoubleFieldNegativeInfinity", REQUIRED,
+      R"({"optionalDouble": "-Infinity"})",
+      "optional_double: -inf");
+  // Non-cannonical Nan will be correctly normalized.
+  {
+    TestAllTypesProto3 message;
+    message.set_optional_double(
+        WireFormatLite::DecodeDouble(0x7FFA123456789ABCLL));
+    RunValidJsonTestWithProtobufInput(
+        "DoubleFieldNormalizeQuietNan", REQUIRED, message,
+        "optional_double: nan");
+    message.set_optional_double(
+        WireFormatLite::DecodeDouble(0xFFFBCBA987654321LL));
+    RunValidJsonTestWithProtobufInput(
+        "DoubleFieldNormalizeSignalingNan", REQUIRED, message,
+        "optional_double: nan");
+  }
+
+  // Special values must be quoted.
+  ExpectParseFailureForJson(
+      "DoubleFieldNanNotQuoted", RECOMMENDED,
+      R"({"optionalDouble": NaN})");
+  ExpectParseFailureForJson(
+      "DoubleFieldInfinityNotQuoted", RECOMMENDED,
+      R"({"optionalDouble": Infinity})");
+  ExpectParseFailureForJson(
+      "DoubleFieldNegativeInfinityNotQuoted", RECOMMENDED,
+      R"({"optionalDouble": -Infinity})");
+
+  // Parsers should reject out-of-bound values.
+  ExpectParseFailureForJson(
+      "DoubleFieldTooSmall", REQUIRED,
+      R"({"optionalDouble": -1.89769e+308})");
+  ExpectParseFailureForJson(
+      "DoubleFieldTooLarge", REQUIRED,
+      R"({"optionalDouble": +1.89769e+308})");
+
+  // Enum fields.
+  RunValidJsonTest(
+      "EnumField", REQUIRED,
+      R"({"optionalNestedEnum": "FOO"})",
+      "optional_nested_enum: FOO");
+  // Enum values must be represented as strings.
+  ExpectParseFailureForJson(
+      "EnumFieldNotQuoted", REQUIRED,
+      R"({"optionalNestedEnum": FOO})");
+  // Numeric values are allowed.
+  RunValidJsonTest(
+      "EnumFieldNumericValueZero", REQUIRED,
+      R"({"optionalNestedEnum": 0})",
+      "optional_nested_enum: FOO");
+  RunValidJsonTest(
+      "EnumFieldNumericValueNonZero", REQUIRED,
+      R"({"optionalNestedEnum": 1})",
+      "optional_nested_enum: BAR");
+  // Unknown enum values are represented as numeric values.
+  RunValidJsonTestWithValidator(
+      "EnumFieldUnknownValue", REQUIRED,
+      R"({"optionalNestedEnum": 123})",
+      [](const Json::Value& value) {
+        return value["optionalNestedEnum"].type() == Json::intValue &&
+            value["optionalNestedEnum"].asInt() == 123;
+      });
+
+  // String fields.
+  RunValidJsonTest(
+      "StringField", REQUIRED,
+      R"({"optionalString": "Hello world!"})",
+      "optional_string: \"Hello world!\"");
+  RunValidJsonTest(
+      "StringFieldUnicode", REQUIRED,
+      // Google in Chinese.
+      R"({"optionalString": "谷歌"})",
+      R"(optional_string: "谷歌")");
+  RunValidJsonTest(
+      "StringFieldEscape", REQUIRED,
+      R"({"optionalString": "\"\\\/\b\f\n\r\t"})",
+      R"(optional_string: "\"\\/\b\f\n\r\t")");
+  RunValidJsonTest(
+      "StringFieldUnicodeEscape", REQUIRED,
+      R"({"optionalString": "\u8C37\u6B4C"})",
+      R"(optional_string: "谷歌")");
+  RunValidJsonTest(
+      "StringFieldUnicodeEscapeWithLowercaseHexLetters", REQUIRED,
+      R"({"optionalString": "\u8c37\u6b4c"})",
+      R"(optional_string: "谷歌")");
+  RunValidJsonTest(
+      "StringFieldSurrogatePair", REQUIRED,
+      // The character is an emoji: grinning face with smiling eyes. 😁
+      R"({"optionalString": "\uD83D\uDE01"})",
+      R"(optional_string: "\xF0\x9F\x98\x81")");
+
+  // Unicode escapes must start with "\u" (lowercase u).
+  ExpectParseFailureForJson(
+      "StringFieldUppercaseEscapeLetter", RECOMMENDED,
+      R"({"optionalString": "\U8C37\U6b4C"})");
+  ExpectParseFailureForJson(
+      "StringFieldInvalidEscape", RECOMMENDED,
+      R"({"optionalString": "\uXXXX\u6B4C"})");
+  ExpectParseFailureForJson(
+      "StringFieldUnterminatedEscape", RECOMMENDED,
+      R"({"optionalString": "\u8C3"})");
+  ExpectParseFailureForJson(
+      "StringFieldUnpairedHighSurrogate", RECOMMENDED,
+      R"({"optionalString": "\uD800"})");
+  ExpectParseFailureForJson(
+      "StringFieldUnpairedLowSurrogate", RECOMMENDED,
+      R"({"optionalString": "\uDC00"})");
+  ExpectParseFailureForJson(
+      "StringFieldSurrogateInWrongOrder", RECOMMENDED,
+      R"({"optionalString": "\uDE01\uD83D"})");
+  ExpectParseFailureForJson(
+      "StringFieldNotAString", REQUIRED,
+      R"({"optionalString": 12345})");
+
+  // Bytes fields.
+  RunValidJsonTest(
+      "BytesField", REQUIRED,
+      R"({"optionalBytes": "AQI="})",
+      R"(optional_bytes: "\x01\x02")");
+  RunValidJsonTest(
+      "BytesFieldBase64Url", RECOMMENDED,
+      R"({"optionalBytes": "-_"})",
+      R"(optional_bytes: "\xfb")");
+
+  // Message fields.
+  RunValidJsonTest(
+      "MessageField", REQUIRED,
+      R"({"optionalNestedMessage": {"a": 1234}})",
+      "optional_nested_message: {a: 1234}");
+
+  // Oneof fields.
+  ExpectParseFailureForJson(
+      "OneofFieldDuplicate", REQUIRED,
+      R"({"oneofUint32": 1, "oneofString": "test"})");
+  // Ensure zero values for oneof make it out/backs.
+  TestAllTypesProto3 messageProto3;
+  TestAllTypesProto2 messageProto2;
+  TestOneofMessage(messageProto3, true);
+  TestOneofMessage(messageProto2, false);
+  RunValidJsonTest(
+      "OneofZeroUint32", RECOMMENDED,
+      R"({"oneofUint32": 0})", "oneof_uint32: 0");
+  RunValidJsonTest(
+      "OneofZeroMessage", RECOMMENDED,
+      R"({"oneofNestedMessage": {}})", "oneof_nested_message: {}");
+  RunValidJsonTest(
+      "OneofZeroString", RECOMMENDED,
+      R"({"oneofString": ""})", "oneof_string: \"\"");
+  RunValidJsonTest(
+      "OneofZeroBytes", RECOMMENDED,
+      R"({"oneofBytes": ""})", "oneof_bytes: \"\"");
+  RunValidJsonTest(
+      "OneofZeroBool", RECOMMENDED,
+      R"({"oneofBool": false})", "oneof_bool: false");
+  RunValidJsonTest(
+      "OneofZeroUint64", RECOMMENDED,
+      R"({"oneofUint64": 0})", "oneof_uint64: 0");
+  RunValidJsonTest(
+      "OneofZeroFloat", RECOMMENDED,
+      R"({"oneofFloat": 0.0})", "oneof_float: 0");
+  RunValidJsonTest(
+      "OneofZeroDouble", RECOMMENDED,
+      R"({"oneofDouble": 0.0})", "oneof_double: 0");
+  RunValidJsonTest(
+      "OneofZeroEnum", RECOMMENDED,
+      R"({"oneofEnum":"FOO"})", "oneof_enum: FOO");
+
+  // Repeated fields.
+  RunValidJsonTest(
+      "PrimitiveRepeatedField", REQUIRED,
+      R"({"repeatedInt32": [1, 2, 3, 4]})",
+      "repeated_int32: [1, 2, 3, 4]");
+  RunValidJsonTest(
+      "EnumRepeatedField", REQUIRED,
+      R"({"repeatedNestedEnum": ["FOO", "BAR", "BAZ"]})",
+      "repeated_nested_enum: [FOO, BAR, BAZ]");
+  RunValidJsonTest(
+      "StringRepeatedField", REQUIRED,
+      R"({"repeatedString": ["Hello", "world"]})",
+      R"(repeated_string: ["Hello", "world"])");
+  RunValidJsonTest(
+      "BytesRepeatedField", REQUIRED,
+      R"({"repeatedBytes": ["AAEC", "AQI="]})",
+      R"(repeated_bytes: ["\x00\x01\x02", "\x01\x02"])");
+  RunValidJsonTest(
+      "MessageRepeatedField", REQUIRED,
+      R"({"repeatedNestedMessage": [{"a": 1234}, {"a": 5678}]})",
+      "repeated_nested_message: {a: 1234}"
+      "repeated_nested_message: {a: 5678}");
+
+  // Repeated field elements are of incorrect type.
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingIntegersGotBool", REQUIRED,
+      R"({"repeatedInt32": [1, false, 3, 4]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingIntegersGotString", REQUIRED,
+      R"({"repeatedInt32": [1, 2, "name", 4]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingIntegersGotMessage", REQUIRED,
+      R"({"repeatedInt32": [1, 2, 3, {"a": 4}]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingStringsGotInt", REQUIRED,
+      R"({"repeatedString": ["1", 2, "3", "4"]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingStringsGotBool", REQUIRED,
+      R"({"repeatedString": ["1", "2", false, "4"]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingStringsGotMessage", REQUIRED,
+      R"({"repeatedString": ["1", 2, "3", {"a": 4}]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingMessagesGotInt", REQUIRED,
+      R"({"repeatedNestedMessage": [{"a": 1}, 2]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingMessagesGotBool", REQUIRED,
+      R"({"repeatedNestedMessage": [{"a": 1}, false]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldWrongElementTypeExpectingMessagesGotString", REQUIRED,
+      R"({"repeatedNestedMessage": [{"a": 1}, "2"]})");
+  // Trailing comma in the repeated field is not allowed.
+  ExpectParseFailureForJson(
+      "RepeatedFieldTrailingComma", RECOMMENDED,
+      R"({"repeatedInt32": [1, 2, 3, 4,]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldTrailingCommaWithSpace", RECOMMENDED,
+      "{\"repeatedInt32\": [1, 2, 3, 4 ,]}");
+  ExpectParseFailureForJson(
+      "RepeatedFieldTrailingCommaWithSpaceCommaSpace", RECOMMENDED,
+      "{\"repeatedInt32\": [1, 2, 3, 4 , ]}");
+  ExpectParseFailureForJson(
+      "RepeatedFieldTrailingCommaWithNewlines", RECOMMENDED,
+      "{\"repeatedInt32\": [\n  1,\n  2,\n  3,\n  4,\n]}");
+
+  // Map fields.
+  RunValidJsonTest(
+      "Int32MapField", REQUIRED,
+      R"({"mapInt32Int32": {"1": 2, "3": 4}})",
+      "map_int32_int32: {key: 1 value: 2}"
+      "map_int32_int32: {key: 3 value: 4}");
+  ExpectParseFailureForJson(
+      "Int32MapFieldKeyNotQuoted", RECOMMENDED,
+      R"({"mapInt32Int32": {1: 2, 3: 4}})");
+  RunValidJsonTest(
+      "Uint32MapField", REQUIRED,
+      R"({"mapUint32Uint32": {"1": 2, "3": 4}})",
+      "map_uint32_uint32: {key: 1 value: 2}"
+      "map_uint32_uint32: {key: 3 value: 4}");
+  ExpectParseFailureForJson(
+      "Uint32MapFieldKeyNotQuoted", RECOMMENDED,
+      R"({"mapUint32Uint32": {1: 2, 3: 4}})");
+  RunValidJsonTest(
+      "Int64MapField", REQUIRED,
+      R"({"mapInt64Int64": {"1": 2, "3": 4}})",
+      "map_int64_int64: {key: 1 value: 2}"
+      "map_int64_int64: {key: 3 value: 4}");
+  ExpectParseFailureForJson(
+      "Int64MapFieldKeyNotQuoted", RECOMMENDED,
+      R"({"mapInt64Int64": {1: 2, 3: 4}})");
+  RunValidJsonTest(
+      "Uint64MapField", REQUIRED,
+      R"({"mapUint64Uint64": {"1": 2, "3": 4}})",
+      "map_uint64_uint64: {key: 1 value: 2}"
+      "map_uint64_uint64: {key: 3 value: 4}");
+  ExpectParseFailureForJson(
+      "Uint64MapFieldKeyNotQuoted", RECOMMENDED,
+      R"({"mapUint64Uint64": {1: 2, 3: 4}})");
+  RunValidJsonTest(
+      "BoolMapField", REQUIRED,
+      R"({"mapBoolBool": {"true": true, "false": false}})",
+      "map_bool_bool: {key: true value: true}"
+      "map_bool_bool: {key: false value: false}");
+  ExpectParseFailureForJson(
+      "BoolMapFieldKeyNotQuoted", RECOMMENDED,
+      R"({"mapBoolBool": {true: true, false: false}})");
+  RunValidJsonTest(
+      "MessageMapField", REQUIRED,
+      R"({
+        "mapStringNestedMessage": {
+          "hello": {"a": 1234},
+          "world": {"a": 5678}
+        }
+      })",
+      R"(
+        map_string_nested_message: {
+          key: "hello"
+          value: {a: 1234}
+        }
+        map_string_nested_message: {
+          key: "world"
+          value: {a: 5678}
+        }
+      )");
+  // Since Map keys are represented as JSON strings, escaping should be allowed.
+  RunValidJsonTest(
+      "Int32MapEscapedKey", REQUIRED,
+      R"({"mapInt32Int32": {"\u0031": 2}})",
+      "map_int32_int32: {key: 1 value: 2}");
+  RunValidJsonTest(
+      "Int64MapEscapedKey", REQUIRED,
+      R"({"mapInt64Int64": {"\u0031": 2}})",
+      "map_int64_int64: {key: 1 value: 2}");
+  RunValidJsonTest(
+      "BoolMapEscapedKey", REQUIRED,
+      R"({"mapBoolBool": {"tr\u0075e": true}})",
+      "map_bool_bool: {key: true value: true}");
+
+  // "null" is accepted for all fields types.
+  RunValidJsonTest(
+      "AllFieldAcceptNull", REQUIRED,
+      R"({
+        "optionalInt32": null,
+        "optionalInt64": null,
+        "optionalUint32": null,
+        "optionalUint64": null,
+        "optionalSint32": null,
+        "optionalSint64": null,
+        "optionalFixed32": null,
+        "optionalFixed64": null,
+        "optionalSfixed32": null,
+        "optionalSfixed64": null,
+        "optionalFloat": null,
+        "optionalDouble": null,
+        "optionalBool": null,
+        "optionalString": null,
+        "optionalBytes": null,
+        "optionalNestedEnum": null,
+        "optionalNestedMessage": null,
+        "repeatedInt32": null,
+        "repeatedInt64": null,
+        "repeatedUint32": null,
+        "repeatedUint64": null,
+        "repeatedSint32": null,
+        "repeatedSint64": null,
+        "repeatedFixed32": null,
+        "repeatedFixed64": null,
+        "repeatedSfixed32": null,
+        "repeatedSfixed64": null,
+        "repeatedFloat": null,
+        "repeatedDouble": null,
+        "repeatedBool": null,
+        "repeatedString": null,
+        "repeatedBytes": null,
+        "repeatedNestedEnum": null,
+        "repeatedNestedMessage": null,
+        "mapInt32Int32": null,
+        "mapBoolBool": null,
+        "mapStringNestedMessage": null
+      })",
+      "");
+
+  // Repeated field elements cannot be null.
+  ExpectParseFailureForJson(
+      "RepeatedFieldPrimitiveElementIsNull", RECOMMENDED,
+      R"({"repeatedInt32": [1, null, 2]})");
+  ExpectParseFailureForJson(
+      "RepeatedFieldMessageElementIsNull", RECOMMENDED,
+      R"({"repeatedNestedMessage": [{"a":1}, null, {"a":2}]})");
+  // Map field keys cannot be null.
+  ExpectParseFailureForJson(
+      "MapFieldKeyIsNull", RECOMMENDED,
+      R"({"mapInt32Int32": {null: 1}})");
+  // Map field values cannot be null.
+  ExpectParseFailureForJson(
+      "MapFieldValueIsNull", RECOMMENDED,
+      R"({"mapInt32Int32": {"0": null}})");
+
+  // http://www.rfc-editor.org/rfc/rfc7159.txt says strings have to use double
+  // quotes.
+  ExpectParseFailureForJson(
+      "StringFieldSingleQuoteKey", RECOMMENDED,
+      R"({'optionalString': "Hello world!"})");
+  ExpectParseFailureForJson(
+      "StringFieldSingleQuoteValue", RECOMMENDED,
+      R"({"optionalString": 'Hello world!'})");
+  ExpectParseFailureForJson(
+      "StringFieldSingleQuoteBoth", RECOMMENDED,
+      R"({'optionalString': 'Hello world!'})");
+
+  // Unknown fields.
+  {
+    TestAllTypesProto3 messageProto3;
+    TestAllTypesProto2 messageProto2;
+    //TODO(yilunchong): update this behavior when unknown field's behavior
+    // changed in open source. Also delete
+    // Required.Proto3.ProtobufInput.UnknownVarint.ProtobufOutput
+    // from failure list of python_cpp python java
+    TestUnknownMessage(messageProto3, true);
+    TestUnknownMessage(messageProto2, false);
+  }
+
+  // Wrapper types.
+  RunValidJsonTest(
+      "OptionalBoolWrapper", REQUIRED,
+      R"({"optionalBoolWrapper": false})",
+      "optional_bool_wrapper: {value: false}");
+  RunValidJsonTest(
+      "OptionalInt32Wrapper", REQUIRED,
+      R"({"optionalInt32Wrapper": 0})",
+      "optional_int32_wrapper: {value: 0}");
+  RunValidJsonTest(
+      "OptionalUint32Wrapper", REQUIRED,
+      R"({"optionalUint32Wrapper": 0})",
+      "optional_uint32_wrapper: {value: 0}");
+  RunValidJsonTest(
+      "OptionalInt64Wrapper", REQUIRED,
+      R"({"optionalInt64Wrapper": 0})",
+      "optional_int64_wrapper: {value: 0}");
+  RunValidJsonTest(
+      "OptionalUint64Wrapper", REQUIRED,
+      R"({"optionalUint64Wrapper": 0})",
+      "optional_uint64_wrapper: {value: 0}");
+  RunValidJsonTest(
+      "OptionalFloatWrapper", REQUIRED,
+      R"({"optionalFloatWrapper": 0})",
+      "optional_float_wrapper: {value: 0}");
+  RunValidJsonTest(
+      "OptionalDoubleWrapper", REQUIRED,
+      R"({"optionalDoubleWrapper": 0})",
+      "optional_double_wrapper: {value: 0}");
+  RunValidJsonTest(
+      "OptionalStringWrapper", REQUIRED,
+      R"({"optionalStringWrapper": ""})",
+      R"(optional_string_wrapper: {value: ""})");
+  RunValidJsonTest(
+      "OptionalBytesWrapper", REQUIRED,
+      R"({"optionalBytesWrapper": ""})",
+      R"(optional_bytes_wrapper: {value: ""})");
+  RunValidJsonTest(
+      "OptionalWrapperTypesWithNonDefaultValue", REQUIRED,
+      R"({
+        "optionalBoolWrapper": true,
+        "optionalInt32Wrapper": 1,
+        "optionalUint32Wrapper": 1,
+        "optionalInt64Wrapper": "1",
+        "optionalUint64Wrapper": "1",
+        "optionalFloatWrapper": 1,
+        "optionalDoubleWrapper": 1,
+        "optionalStringWrapper": "1",
+        "optionalBytesWrapper": "AQI="
+      })",
+      R"(
+        optional_bool_wrapper: {value: true}
+        optional_int32_wrapper: {value: 1}
+        optional_uint32_wrapper: {value: 1}
+        optional_int64_wrapper: {value: 1}
+        optional_uint64_wrapper: {value: 1}
+        optional_float_wrapper: {value: 1}
+        optional_double_wrapper: {value: 1}
+        optional_string_wrapper: {value: "1"}
+        optional_bytes_wrapper: {value: "\x01\x02"}
+      )");
+  RunValidJsonTest(
+      "RepeatedBoolWrapper", REQUIRED,
+      R"({"repeatedBoolWrapper": [true, false]})",
+      "repeated_bool_wrapper: {value: true}"
+      "repeated_bool_wrapper: {value: false}");
+  RunValidJsonTest(
+      "RepeatedInt32Wrapper", REQUIRED,
+      R"({"repeatedInt32Wrapper": [0, 1]})",
+      "repeated_int32_wrapper: {value: 0}"
+      "repeated_int32_wrapper: {value: 1}");
+  RunValidJsonTest(
+      "RepeatedUint32Wrapper", REQUIRED,
+      R"({"repeatedUint32Wrapper": [0, 1]})",
+      "repeated_uint32_wrapper: {value: 0}"
+      "repeated_uint32_wrapper: {value: 1}");
+  RunValidJsonTest(
+      "RepeatedInt64Wrapper", REQUIRED,
+      R"({"repeatedInt64Wrapper": [0, 1]})",
+      "repeated_int64_wrapper: {value: 0}"
+      "repeated_int64_wrapper: {value: 1}");
+  RunValidJsonTest(
+      "RepeatedUint64Wrapper", REQUIRED,
+      R"({"repeatedUint64Wrapper": [0, 1]})",
+      "repeated_uint64_wrapper: {value: 0}"
+      "repeated_uint64_wrapper: {value: 1}");
+  RunValidJsonTest(
+      "RepeatedFloatWrapper", REQUIRED,
+      R"({"repeatedFloatWrapper": [0, 1]})",
+      "repeated_float_wrapper: {value: 0}"
+      "repeated_float_wrapper: {value: 1}");
+  RunValidJsonTest(
+      "RepeatedDoubleWrapper", REQUIRED,
+      R"({"repeatedDoubleWrapper": [0, 1]})",
+      "repeated_double_wrapper: {value: 0}"
+      "repeated_double_wrapper: {value: 1}");
+  RunValidJsonTest(
+      "RepeatedStringWrapper", REQUIRED,
+      R"({"repeatedStringWrapper": ["", "AQI="]})",
+      R"(
+        repeated_string_wrapper: {value: ""}
+        repeated_string_wrapper: {value: "AQI="}
+      )");
+  RunValidJsonTest(
+      "RepeatedBytesWrapper", REQUIRED,
+      R"({"repeatedBytesWrapper": ["", "AQI="]})",
+      R"(
+        repeated_bytes_wrapper: {value: ""}
+        repeated_bytes_wrapper: {value: "\x01\x02"}
+      )");
+  RunValidJsonTest(
+      "WrapperTypesWithNullValue", REQUIRED,
+      R"({
+        "optionalBoolWrapper": null,
+        "optionalInt32Wrapper": null,
+        "optionalUint32Wrapper": null,
+        "optionalInt64Wrapper": null,
+        "optionalUint64Wrapper": null,
+        "optionalFloatWrapper": null,
+        "optionalDoubleWrapper": null,
+        "optionalStringWrapper": null,
+        "optionalBytesWrapper": null,
+        "repeatedBoolWrapper": null,
+        "repeatedInt32Wrapper": null,
+        "repeatedUint32Wrapper": null,
+        "repeatedInt64Wrapper": null,
+        "repeatedUint64Wrapper": null,
+        "repeatedFloatWrapper": null,
+        "repeatedDoubleWrapper": null,
+        "repeatedStringWrapper": null,
+        "repeatedBytesWrapper": null
+      })",
+      "");
+
+  // Duration
+  RunValidJsonTest(
+      "DurationMinValue", REQUIRED,
+      R"({"optionalDuration": "-315576000000.999999999s"})",
+      "optional_duration: {seconds: -315576000000 nanos: -999999999}");
+  RunValidJsonTest(
+      "DurationMaxValue", REQUIRED,
+      R"({"optionalDuration": "315576000000.999999999s"})",
+      "optional_duration: {seconds: 315576000000 nanos: 999999999}");
+  RunValidJsonTest(
+      "DurationRepeatedValue", REQUIRED,
+      R"({"repeatedDuration": ["1.5s", "-1.5s"]})",
+      "repeated_duration: {seconds: 1 nanos: 500000000}"
+      "repeated_duration: {seconds: -1 nanos: -500000000}");
+  RunValidJsonTest(
+      "DurationNull", REQUIRED,
+      R"({"optionalDuration": null})",
+      "");
+
+  ExpectParseFailureForJson(
+      "DurationMissingS", REQUIRED,
+      R"({"optionalDuration": "1"})");
+  ExpectParseFailureForJson(
+      "DurationJsonInputTooSmall", REQUIRED,
+      R"({"optionalDuration": "-315576000001.000000000s"})");
+  ExpectParseFailureForJson(
+      "DurationJsonInputTooLarge", REQUIRED,
+      R"({"optionalDuration": "315576000001.000000000s"})");
+  ExpectSerializeFailureForJson(
+      "DurationProtoInputTooSmall", REQUIRED,
+      "optional_duration: {seconds: -315576000001 nanos: 0}");
+  ExpectSerializeFailureForJson(
+      "DurationProtoInputTooLarge", REQUIRED,
+      "optional_duration: {seconds: 315576000001 nanos: 0}");
+
+  RunValidJsonTestWithValidator(
+      "DurationHasZeroFractionalDigit", RECOMMENDED,
+      R"({"optionalDuration": "1.000000000s"})",
+      [](const Json::Value& value) {
+        return value["optionalDuration"].asString() == "1s";
+      });
+  RunValidJsonTestWithValidator(
+      "DurationHas3FractionalDigits", RECOMMENDED,
+      R"({"optionalDuration": "1.010000000s"})",
+      [](const Json::Value& value) {
+        return value["optionalDuration"].asString() == "1.010s";
+      });
+  RunValidJsonTestWithValidator(
+      "DurationHas6FractionalDigits", RECOMMENDED,
+      R"({"optionalDuration": "1.000010000s"})",
+      [](const Json::Value& value) {
+        return value["optionalDuration"].asString() == "1.000010s";
+      });
+  RunValidJsonTestWithValidator(
+      "DurationHas9FractionalDigits", RECOMMENDED,
+      R"({"optionalDuration": "1.000000010s"})",
+      [](const Json::Value& value) {
+        return value["optionalDuration"].asString() == "1.000000010s";
+      });
+
+  // Timestamp
+  RunValidJsonTest(
+      "TimestampMinValue", REQUIRED,
+      R"({"optionalTimestamp": "0001-01-01T00:00:00Z"})",
+      "optional_timestamp: {seconds: -62135596800}");
+  RunValidJsonTest(
+      "TimestampMaxValue", REQUIRED,
+      R"({"optionalTimestamp": "9999-12-31T23:59:59.999999999Z"})",
+      "optional_timestamp: {seconds: 253402300799 nanos: 999999999}");
+  RunValidJsonTest(
+      "TimestampRepeatedValue", REQUIRED,
+      R"({
+        "repeatedTimestamp": [
+          "0001-01-01T00:00:00Z",
+          "9999-12-31T23:59:59.999999999Z"
+        ]
+      })",
+      "repeated_timestamp: {seconds: -62135596800}"
+      "repeated_timestamp: {seconds: 253402300799 nanos: 999999999}");
+  RunValidJsonTest(
+      "TimestampWithPositiveOffset", REQUIRED,
+      R"({"optionalTimestamp": "1970-01-01T08:00:00+08:00"})",
+      "optional_timestamp: {seconds: 0}");
+  RunValidJsonTest(
+      "TimestampWithNegativeOffset", REQUIRED,
+      R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})",
+      "optional_timestamp: {seconds: 0}");
+  RunValidJsonTest(
+      "TimestampNull", REQUIRED,
+      R"({"optionalTimestamp": null})",
+      "");
+
+  ExpectParseFailureForJson(
+      "TimestampJsonInputTooSmall", REQUIRED,
+      R"({"optionalTimestamp": "0000-01-01T00:00:00Z"})");
+  ExpectParseFailureForJson(
+      "TimestampJsonInputTooLarge", REQUIRED,
+      R"({"optionalTimestamp": "10000-01-01T00:00:00Z"})");
+  ExpectParseFailureForJson(
+      "TimestampJsonInputMissingZ", REQUIRED,
+      R"({"optionalTimestamp": "0001-01-01T00:00:00"})");
+  ExpectParseFailureForJson(
+      "TimestampJsonInputMissingT", REQUIRED,
+      R"({"optionalTimestamp": "0001-01-01 00:00:00Z"})");
+  ExpectParseFailureForJson(
+      "TimestampJsonInputLowercaseZ", REQUIRED,
+      R"({"optionalTimestamp": "0001-01-01T00:00:00z"})");
+  ExpectParseFailureForJson(
+      "TimestampJsonInputLowercaseT", REQUIRED,
+      R"({"optionalTimestamp": "0001-01-01t00:00:00Z"})");
+  ExpectSerializeFailureForJson(
+      "TimestampProtoInputTooSmall", REQUIRED,
+      "optional_timestamp: {seconds: -62135596801}");
+  ExpectSerializeFailureForJson(
+      "TimestampProtoInputTooLarge", REQUIRED,
+      "optional_timestamp: {seconds: 253402300800}");
+  RunValidJsonTestWithValidator(
+      "TimestampZeroNormalized", RECOMMENDED,
+      R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})",
+      [](const Json::Value& value) {
+        return value["optionalTimestamp"].asString() ==
+            "1970-01-01T00:00:00Z";
+      });
+  RunValidJsonTestWithValidator(
+      "TimestampHasZeroFractionalDigit", RECOMMENDED,
+      R"({"optionalTimestamp": "1970-01-01T00:00:00.000000000Z"})",
+      [](const Json::Value& value) {
+        return value["optionalTimestamp"].asString() ==
+            "1970-01-01T00:00:00Z";
+      });
+  RunValidJsonTestWithValidator(
+      "TimestampHas3FractionalDigits", RECOMMENDED,
+      R"({"optionalTimestamp": "1970-01-01T00:00:00.010000000Z"})",
+      [](const Json::Value& value) {
+        return value["optionalTimestamp"].asString() ==
+            "1970-01-01T00:00:00.010Z";
+      });
+  RunValidJsonTestWithValidator(
+      "TimestampHas6FractionalDigits", RECOMMENDED,
+      R"({"optionalTimestamp": "1970-01-01T00:00:00.000010000Z"})",
+      [](const Json::Value& value) {
+        return value["optionalTimestamp"].asString() ==
+            "1970-01-01T00:00:00.000010Z";
+      });
+  RunValidJsonTestWithValidator(
+      "TimestampHas9FractionalDigits", RECOMMENDED,
+      R"({"optionalTimestamp": "1970-01-01T00:00:00.000000010Z"})",
+      [](const Json::Value& value) {
+        return value["optionalTimestamp"].asString() ==
+            "1970-01-01T00:00:00.000000010Z";
+      });
+
+  // FieldMask
+  RunValidJsonTest(
+      "FieldMask", REQUIRED,
+      R"({"optionalFieldMask": "foo,barBaz"})",
+      R"(optional_field_mask: {paths: "foo" paths: "bar_baz"})");
+  ExpectParseFailureForJson(
+      "FieldMaskInvalidCharacter", RECOMMENDED,
+      R"({"optionalFieldMask": "foo,bar_bar"})");
+  ExpectSerializeFailureForJson(
+      "FieldMaskPathsDontRoundTrip", RECOMMENDED,
+      R"(optional_field_mask: {paths: "fooBar"})");
+  ExpectSerializeFailureForJson(
+      "FieldMaskNumbersDontRoundTrip", RECOMMENDED,
+      R"(optional_field_mask: {paths: "foo_3_bar"})");
+  ExpectSerializeFailureForJson(
+      "FieldMaskTooManyUnderscore", RECOMMENDED,
+      R"(optional_field_mask: {paths: "foo__bar"})");
+
+  // Struct
+  RunValidJsonTest(
+      "Struct", REQUIRED,
+      R"({
+        "optionalStruct": {
+          "nullValue": null,
+          "intValue": 1234,
+          "boolValue": true,
+          "doubleValue": 1234.5678,
+          "stringValue": "Hello world!",
+          "listValue": [1234, "5678"],
+          "objectValue": {
+            "value": 0
+          }
+        }
+      })",
+      R"(
+        optional_struct: {
+          fields: {
+            key: "nullValue"
+            value: {null_value: NULL_VALUE}
+          }
+          fields: {
+            key: "intValue"
+            value: {number_value: 1234}
+          }
+          fields: {
+            key: "boolValue"
+            value: {bool_value: true}
+          }
+          fields: {
+            key: "doubleValue"
+            value: {number_value: 1234.5678}
+          }
+          fields: {
+            key: "stringValue"
+            value: {string_value: "Hello world!"}
+          }
+          fields: {
+            key: "listValue"
+            value: {
+              list_value: {
+                values: {
+                  number_value: 1234
+                }
+                values: {
+                  string_value: "5678"
+                }
+              }
+            }
+          }
+          fields: {
+            key: "objectValue"
+            value: {
+              struct_value: {
+                fields: {
+                  key: "value"
+                  value: {
+                    number_value: 0
+                  }
+                }
+              }
+            }
+          }
+        }
+      )");
+  // Value
+  RunValidJsonTest(
+      "ValueAcceptInteger", REQUIRED,
+      R"({"optionalValue": 1})",
+      "optional_value: { number_value: 1}");
+  RunValidJsonTest(
+      "ValueAcceptFloat", REQUIRED,
+      R"({"optionalValue": 1.5})",
+      "optional_value: { number_value: 1.5}");
+  RunValidJsonTest(
+      "ValueAcceptBool", REQUIRED,
+      R"({"optionalValue": false})",
+      "optional_value: { bool_value: false}");
+  RunValidJsonTest(
+      "ValueAcceptNull", REQUIRED,
+      R"({"optionalValue": null})",
+      "optional_value: { null_value: NULL_VALUE}");
+  RunValidJsonTest(
+      "ValueAcceptString", REQUIRED,
+      R"({"optionalValue": "hello"})",
+      R"(optional_value: { string_value: "hello"})");
+  RunValidJsonTest(
+      "ValueAcceptList", REQUIRED,
+      R"({"optionalValue": [0, "hello"]})",
+      R"(
+        optional_value: {
+          list_value: {
+            values: {
+              number_value: 0
+            }
+            values: {
+              string_value: "hello"
+            }
+          }
+        }
+      )");
+  RunValidJsonTest(
+      "ValueAcceptObject", REQUIRED,
+      R"({"optionalValue": {"value": 1}})",
+      R"(
+        optional_value: {
+          struct_value: {
+            fields: {
+              key: "value"
+              value: {
+                number_value: 1
+              }
+            }
+          }
+        }
+      )");
+
+  // Any
+  RunValidJsonTest(
+      "Any", REQUIRED,
+      R"({
+        "optionalAny": {
+          "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3",
+          "optionalInt32": 12345
+        }
+      })",
+      R"(
+        optional_any: {
+          [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
+            optional_int32: 12345
+          }
+        }
+      )");
+  RunValidJsonTest(
+      "AnyNested", REQUIRED,
+      R"({
+        "optionalAny": {
+          "@type": "type.googleapis.com/google.protobuf.Any",
+          "value": {
+            "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3",
+            "optionalInt32": 12345
+          }
+        }
+      })",
+      R"(
+        optional_any: {
+          [type.googleapis.com/google.protobuf.Any] {
+            [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
+              optional_int32: 12345
+            }
+          }
+        }
+      )");
+  // The special "@type" tag is not required to appear first.
+  RunValidJsonTest(
+      "AnyUnorderedTypeTag", REQUIRED,
+      R"({
+        "optionalAny": {
+          "optionalInt32": 12345,
+          "@type": "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3"
+        }
+      })",
+      R"(
+        optional_any: {
+          [type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
+            optional_int32: 12345
+          }
+        }
+      )");
+  // Well-known types in Any.
+  RunValidJsonTest(
+      "AnyWithInt32ValueWrapper", REQUIRED,
+      R"({
+        "optionalAny": {
+          "@type": "type.googleapis.com/google.protobuf.Int32Value",
+          "value": 12345
+        }
+      })",
+      R"(
+        optional_any: {
+          [type.googleapis.com/google.protobuf.Int32Value] {
+            value: 12345
+          }
+        }
+      )");
+  RunValidJsonTest(
+      "AnyWithDuration", REQUIRED,
+      R"({
+        "optionalAny": {
+          "@type": "type.googleapis.com/google.protobuf.Duration",
+          "value": "1.5s"
+        }
+      })",
+      R"(
+        optional_any: {
+          [type.googleapis.com/google.protobuf.Duration] {
+            seconds: 1
+            nanos: 500000000
+          }
+        }
+      )");
+  RunValidJsonTest(
+      "AnyWithTimestamp", REQUIRED,
+      R"({
+        "optionalAny": {
+          "@type": "type.googleapis.com/google.protobuf.Timestamp",
+          "value": "1970-01-01T00:00:00Z"
+        }
+      })",
+      R"(
+        optional_any: {
+          [type.googleapis.com/google.protobuf.Timestamp] {
+            seconds: 0
+            nanos: 0
+          }
+        }
+      )");
+  RunValidJsonTest(
+      "AnyWithFieldMask", REQUIRED,
+      R"({
+        "optionalAny": {
+          "@type": "type.googleapis.com/google.protobuf.FieldMask",
+          "value": "foo,barBaz"
+        }
+      })",
+      R"(
+        optional_any: {
+          [type.googleapis.com/google.protobuf.FieldMask] {
+            paths: ["foo", "bar_baz"]
+          }
+        }
+      )");
+  RunValidJsonTest(
+      "AnyWithStruct", REQUIRED,
+      R"({
+        "optionalAny": {
+          "@type": "type.googleapis.com/google.protobuf.Struct",
+          "value": {
+            "foo": 1
+          }
+        }
+      })",
+      R"(
+        optional_any: {
+          [type.googleapis.com/google.protobuf.Struct] {
+            fields: {
+              key: "foo"
+              value: {
+                number_value: 1
+              }
+            }
+          }
+        }
+      )");
+  RunValidJsonTest(
+      "AnyWithValueForJsonObject", REQUIRED,
+      R"({
+        "optionalAny": {
+          "@type": "type.googleapis.com/google.protobuf.Value",
+          "value": {
+            "foo": 1
+          }
+        }
+      })",
+      R"(
+        optional_any: {
+          [type.googleapis.com/google.protobuf.Value] {
+            struct_value: {
+              fields: {
+                key: "foo"
+                value: {
+                  number_value: 1
+                }
+              }
+            }
+          }
+        }
+      )");
+  RunValidJsonTest(
+      "AnyWithValueForInteger", REQUIRED,
+      R"({
+        "optionalAny": {
+          "@type": "type.googleapis.com/google.protobuf.Value",
+          "value": 1
+        }
+      })",
+      R"(
+        optional_any: {
+          [type.googleapis.com/google.protobuf.Value] {
+            number_value: 1
+          }
+        }
+      )");
+
+  RunValidJsonIgnoreUnknownTest(
+      "IgnoreUnknownJsonNumber", REQUIRED,
+      R"({
+        "unknown": 1
+      })",
+      "");
+  RunValidJsonIgnoreUnknownTest(
+      "IgnoreUnknownJsonString", REQUIRED,
+      R"({
+        "unknown": "a"
+      })",
+      "");
+  RunValidJsonIgnoreUnknownTest(
+      "IgnoreUnknownJsonTrue", REQUIRED,
+      R"({
+        "unknown": true
+      })",
+      "");
+  RunValidJsonIgnoreUnknownTest(
+      "IgnoreUnknownJsonFalse", REQUIRED,
+      R"({
+        "unknown": false
+      })",
+      "");
+  RunValidJsonIgnoreUnknownTest(
+      "IgnoreUnknownJsonNull", REQUIRED,
+      R"({
+        "unknown": null
+      })",
+      "");
+  RunValidJsonIgnoreUnknownTest(
+      "IgnoreUnknownJsonObject", REQUIRED,
+      R"({
+        "unknown": {"a": 1}
+      })",
+      "");
+}
+
+struct StaticTestSuiteInitializer {
+  StaticTestSuiteInitializer() {
+    AddTestSuite(new ConformanceTestSuiteImpl());
+  }
+} static_test_suite_initializer;
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/conformance/conformance_test_runner.cc b/conformance/conformance_test_runner.cc
index b0357b8..3340f1c 100644
--- a/conformance/conformance_test_runner.cc
+++ b/conformance/conformance_test_runner.cc
@@ -66,9 +66,9 @@
 #include "conformance.pb.h"
 #include "conformance_test.h"
 
-using conformance::ConformanceRequest;
 using conformance::ConformanceResponse;
 using google::protobuf::StringAppendF;
+using google::protobuf::ConformanceTestSuite;
 using std::string;
 using std::vector;
 
@@ -287,7 +287,8 @@
 
 int main(int argc, char *argv[]) {
   char *program;
-  google::protobuf::ConformanceTestSuite suite;
+  const std::set<ConformanceTestSuite*>& test_suite_set =
+      ::google::protobuf::GetTestSuiteSet();
 
   string failure_list_filename;
   std::vector<string> failure_list;
@@ -298,9 +299,13 @@
       failure_list_filename = argv[arg];
       ParseFailureList(argv[arg], &failure_list);
     } else if (strcmp(argv[arg], "--verbose") == 0) {
-      suite.SetVerbose(true);
+      for (auto *suite : test_suite_set) {
+        suite->SetVerbose(true);
+      }
     } else if (strcmp(argv[arg], "--enforce_recommended") == 0) {
-      suite.SetEnforceRecommended(true);
+      for (auto suite : test_suite_set) {
+        suite->SetEnforceRecommended(true);
+      }
     } else if (argv[arg][0] == '-') {
       fprintf(stderr, "Unknown option: %s\n", argv[arg]);
       UsageError();
@@ -313,11 +318,16 @@
     }
   }
 
-  suite.SetFailureList(failure_list_filename, failure_list);
+  for (auto suite : test_suite_set) {
+    suite->SetFailureList(failure_list_filename, failure_list);
+  }
   ForkPipeRunner runner(program);
 
   std::string output;
-  bool ok = suite.RunSuite(&runner, &output);
+  bool ok = true;
+  for (auto suite : test_suite_set) {
+    ok &= suite->RunSuite(&runner, &output);
+  }
 
   fwrite(output.c_str(), 1, output.size(), stderr);
 
diff --git a/conformance/failure_list_php_c.txt b/conformance/failure_list_php_c.txt
index 5f7c0c8..bb32ace 100644
--- a/conformance/failure_list_php_c.txt
+++ b/conformance/failure_list_php_c.txt
@@ -63,44 +63,8 @@
 Required.Proto3.JsonInput.FloatFieldNan.JsonOutput
 Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput
 Required.Proto3.JsonInput.OneofFieldDuplicate
-Required.Proto3.JsonInput.OptionalBoolWrapper.JsonOutput
-Required.Proto3.JsonInput.OptionalBoolWrapper.ProtobufOutput
-Required.Proto3.JsonInput.OptionalBytesWrapper.JsonOutput
-Required.Proto3.JsonInput.OptionalBytesWrapper.ProtobufOutput
-Required.Proto3.JsonInput.OptionalDoubleWrapper.JsonOutput
-Required.Proto3.JsonInput.OptionalDoubleWrapper.ProtobufOutput
-Required.Proto3.JsonInput.OptionalFloatWrapper.JsonOutput
-Required.Proto3.JsonInput.OptionalFloatWrapper.ProtobufOutput
-Required.Proto3.JsonInput.OptionalInt32Wrapper.JsonOutput
-Required.Proto3.JsonInput.OptionalInt32Wrapper.ProtobufOutput
-Required.Proto3.JsonInput.OptionalInt64Wrapper.JsonOutput
-Required.Proto3.JsonInput.OptionalInt64Wrapper.ProtobufOutput
-Required.Proto3.JsonInput.OptionalStringWrapper.JsonOutput
-Required.Proto3.JsonInput.OptionalStringWrapper.ProtobufOutput
-Required.Proto3.JsonInput.OptionalUint32Wrapper.JsonOutput
-Required.Proto3.JsonInput.OptionalUint32Wrapper.ProtobufOutput
-Required.Proto3.JsonInput.OptionalUint64Wrapper.JsonOutput
-Required.Proto3.JsonInput.OptionalUint64Wrapper.ProtobufOutput
 Required.Proto3.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
 Required.Proto3.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
-Required.Proto3.JsonInput.RepeatedBoolWrapper.JsonOutput
-Required.Proto3.JsonInput.RepeatedBoolWrapper.ProtobufOutput
-Required.Proto3.JsonInput.RepeatedBytesWrapper.JsonOutput
-Required.Proto3.JsonInput.RepeatedBytesWrapper.ProtobufOutput
-Required.Proto3.JsonInput.RepeatedDoubleWrapper.JsonOutput
-Required.Proto3.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
-Required.Proto3.JsonInput.RepeatedFloatWrapper.JsonOutput
-Required.Proto3.JsonInput.RepeatedFloatWrapper.ProtobufOutput
-Required.Proto3.JsonInput.RepeatedInt32Wrapper.JsonOutput
-Required.Proto3.JsonInput.RepeatedInt32Wrapper.ProtobufOutput
-Required.Proto3.JsonInput.RepeatedInt64Wrapper.JsonOutput
-Required.Proto3.JsonInput.RepeatedInt64Wrapper.ProtobufOutput
-Required.Proto3.JsonInput.RepeatedStringWrapper.JsonOutput
-Required.Proto3.JsonInput.RepeatedStringWrapper.ProtobufOutput
-Required.Proto3.JsonInput.RepeatedUint32Wrapper.JsonOutput
-Required.Proto3.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
-Required.Proto3.JsonInput.RepeatedUint64Wrapper.JsonOutput
-Required.Proto3.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
 Required.Proto3.JsonInput.StringFieldEscape.JsonOutput
 Required.Proto3.JsonInput.StringFieldEscape.ProtobufOutput
 Required.Proto3.JsonInput.StringFieldSurrogatePair.JsonOutput
diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt
index 2d09acd..1bab135 100644
--- a/conformance/failure_list_ruby.txt
+++ b/conformance/failure_list_ruby.txt
@@ -120,8 +120,6 @@
 Required.Proto3.JsonInput.ValueAcceptInteger.ProtobufOutput
 Required.Proto3.JsonInput.ValueAcceptList.JsonOutput
 Required.Proto3.JsonInput.ValueAcceptList.ProtobufOutput
-Required.Proto3.JsonInput.ValueAcceptListWithNull.JsonOutput
-Required.Proto3.JsonInput.ValueAcceptListWithNull.ProtobufOutput
 Required.Proto3.JsonInput.ValueAcceptNull.JsonOutput
 Required.Proto3.JsonInput.ValueAcceptNull.ProtobufOutput
 Required.Proto3.JsonInput.ValueAcceptObject.JsonOutput
@@ -135,9 +133,3 @@
 Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput
 Required.TimestampProtoInputTooLarge.JsonOutput
 Required.TimestampProtoInputTooSmall.JsonOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonFalse.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonNull.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonNumber.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonObject.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonString.ProtobufOutput
-Required.Proto3.JsonInput.IgnoreUnknownJsonTrue.ProtobufOutput
diff --git a/csharp/src/Google.Protobuf.Conformance/Conformance.cs b/csharp/src/Google.Protobuf.Conformance/Conformance.cs
index 6ca52c3..46793ce 100644
--- a/csharp/src/Google.Protobuf.Conformance/Conformance.cs
+++ b/csharp/src/Google.Protobuf.Conformance/Conformance.cs
@@ -34,10 +34,11 @@
             "BiABKAlIABIXCg1ydW50aW1lX2Vycm9yGAIgASgJSAASGgoQcHJvdG9idWZf",
             "cGF5bG9hZBgDIAEoDEgAEhYKDGpzb25fcGF5bG9hZBgEIAEoCUgAEhEKB3Nr",
             "aXBwZWQYBSABKAlIAEIICgZyZXN1bHQqNQoKV2lyZUZvcm1hdBIPCgtVTlNQ",
-            "RUNJRklFRBAAEgwKCFBST1RPQlVGEAESCAoESlNPThACKlQKDFRlc3RDYXRl",
-            "Z29yeRIPCgtCSU5BUllfVEVTVBAAEg0KCUpTT05fVEVTVBABEiQKIEpTT05f",
-            "SUdOT1JFX1VOS05PV05fUEFSU0lOR19URVNUEAJCIQofY29tLmdvb2dsZS5w",
-            "cm90b2J1Zi5jb25mb3JtYW5jZWIGcHJvdG8z"));
+            "RUNJRklFRBAAEgwKCFBST1RPQlVGEAESCAoESlNPThACKmoKDFRlc3RDYXRl",
+            "Z29yeRIUChBVTlNQRUNJRklFRF9URVNUEAASDwoLQklOQVJZX1RFU1QQARIN",
+            "CglKU09OX1RFU1QQAhIkCiBKU09OX0lHTk9SRV9VTktOT1dOX1BBUlNJTkdf",
+            "VEVTVBADQiEKH2NvbS5nb29nbGUucHJvdG9idWYuY29uZm9ybWFuY2ViBnBy",
+            "b3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Conformance.WireFormat), typeof(global::Conformance.TestCategory), }, new pbr::GeneratedClrTypeInfo[] {
@@ -56,14 +57,15 @@
   }
 
   public enum TestCategory {
+    [pbr::OriginalName("UNSPECIFIED_TEST")] UnspecifiedTest = 0,
     /// <summary>
     /// Test binary wire format.
     /// </summary>
-    [pbr::OriginalName("BINARY_TEST")] BinaryTest = 0,
+    [pbr::OriginalName("BINARY_TEST")] BinaryTest = 1,
     /// <summary>
     /// Test json wire format.
     /// </summary>
-    [pbr::OriginalName("JSON_TEST")] JsonTest = 1,
+    [pbr::OriginalName("JSON_TEST")] JsonTest = 2,
     /// <summary>
     /// Similar to JSON_TEST. However, during parsing json, testee should ignore
     /// unknown fields. This feature is optional. Each implementation can descide
@@ -71,7 +73,7 @@
     /// https://developers.google.com/protocol-buffers/docs/proto3#json_options
     /// for more detail.
     /// </summary>
-    [pbr::OriginalName("JSON_IGNORE_UNKNOWN_PARSING_TEST")] JsonIgnoreUnknownParsingTest = 2,
+    [pbr::OriginalName("JSON_IGNORE_UNKNOWN_PARSING_TEST")] JsonIgnoreUnknownParsingTest = 3,
   }
 
   #endregion
@@ -185,9 +187,9 @@
     public const int TestCategoryFieldNumber = 5;
     private global::Conformance.TestCategory testCategory_ = 0;
     /// <summary>
-    /// Each test is given a specific test category. Some category may need spedific
-    /// support in testee programs. Refer to the defintion of TestCategory for
-    /// more information.
+    /// Each test is given a specific test category. Some category may need
+    /// spedific support in testee programs. Refer to the defintion of TestCategory
+    /// for more information.
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Conformance.TestCategory TestCategory {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
index b73930b..6ad31a5 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
@@ -25,11 +25,11 @@
       byte[] descriptorData = global::System.Convert.FromBase64String(
           string.Concat(
             "CiBnb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wcm90bxIPZ29vZ2xlLnBy",
-            "b3RvYnVmIhoKCUZpZWxkTWFzaxINCgVwYXRocxgBIAMoCUKJAQoTY29tLmdv",
+            "b3RvYnVmIhoKCUZpZWxkTWFzaxINCgVwYXRocxgBIAMoCUKMAQoTY29tLmdv",
             "b2dsZS5wcm90b2J1ZkIORmllbGRNYXNrUHJvdG9QAVo5Z29vZ2xlLmdvbGFu",
             "Zy5vcmcvZ2VucHJvdG8vcHJvdG9idWYvZmllbGRfbWFzaztmaWVsZF9tYXNr",
-            "ogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90",
-            "bzM="));
+            "+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZw",
+            "cm90bzM="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
@@ -108,57 +108,49 @@
   /// describe the updated values, the API ignores the values of all
   /// fields not covered by the mask.
   ///
-  /// If a repeated field is specified for an update operation, the existing
-  /// repeated values in the target resource will be overwritten by the new values.
-  /// Note that a repeated field is only allowed in the last position of a `paths`
-  /// string.
+  /// If a repeated field is specified for an update operation, new values will
+  /// be appended to the existing repeated field in the target resource. Note that
+  /// a repeated field is only allowed in the last position of a `paths` string.
   ///
   /// If a sub-message is specified in the last position of the field mask for an
-  /// update operation, then the existing sub-message in the target resource is
-  /// overwritten. Given the target message:
+  /// update operation, then new value will be merged into the existing sub-message
+  /// in the target resource.
+  ///
+  /// For example, given the target message:
   ///
   ///     f {
   ///       b {
-  ///         d : 1
-  ///         x : 2
+  ///         d: 1
+  ///         x: 2
   ///       }
-  ///       c : 1
+  ///       c: [1]
   ///     }
   ///
   /// And an update message:
   ///
   ///     f {
   ///       b {
-  ///         d : 10
+  ///         d: 10
   ///       }
+  ///       c: [2]
   ///     }
   ///
   /// then if the field mask is:
   ///
-  ///  paths: "f.b"
+  ///  paths: ["f.b", "f.c"]
   ///
   /// then the result will be:
   ///
   ///     f {
   ///       b {
-  ///         d : 10
+  ///         d: 10
+  ///         x: 2
   ///       }
-  ///       c : 1
+  ///       c: [1, 2]
   ///     }
   ///
-  /// However, if the update mask was:
-  ///
-  ///  paths: "f.b.d"
-  ///
-  /// then the result would be:
-  ///
-  ///     f {
-  ///       b {
-  ///         d : 10
-  ///         x : 2
-  ///       }
-  ///       c : 1
-  ///     }
+  /// An implementation may provide options to override this default behavior for
+  /// repeated and message fields.
   ///
   /// In order to reset a field's value to the default, the field must
   /// be in the mask and set to the default value in the provided resource.
diff --git a/java/core/pom.xml b/java/core/pom.xml
index 0c0fd8f..9dbaff1 100644
--- a/java/core/pom.xml
+++ b/java/core/pom.xml
@@ -34,6 +34,11 @@
       <artifactId>easymockclassextension</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
@@ -57,6 +62,15 @@
         </includes>
       </resource>
     </resources>
+    <testResources>
+      <testResource>
+        <directory>${protobuf.source.dir}</directory>
+        <includes>
+          <include>google/protobuf/testdata/golden_message_oneof_implemented</include>
+          <include>google/protobuf/testdata/golden_packed_fields_message</include>
+        </includes>
+      </testResource>
+    </testResources>
 
     <plugins>
       <!-- Use Antrun plugin to generate sources with protoc -->
diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
index fc3c2a5..09aaed1 100644
--- a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
@@ -32,7 +32,6 @@
 
 import com.google.protobuf.Descriptors.EnumValueDescriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
-import com.google.protobuf.Descriptors.FileDescriptor.Syntax;
 import com.google.protobuf.Descriptors.OneofDescriptor;
 import com.google.protobuf.Internal.EnumLite;
 import java.io.IOException;
@@ -446,10 +445,7 @@
         final CodedInputStream input,
         final ExtensionRegistryLite extensionRegistry)
         throws IOException {
-      boolean discardUnknown =
-          getDescriptorForType().getFile().getSyntax() == Syntax.PROTO3
-              ? input.shouldDiscardUnknownFieldsProto3()
-              : input.shouldDiscardUnknownFields();
+      boolean discardUnknown = input.shouldDiscardUnknownFields();
       final UnknownFieldSet.Builder unknownFields =
           discardUnknown ? null : UnknownFieldSet.newBuilder(getUnknownFields());
       while (true) {
diff --git a/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java b/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java
index 4d7a972..0dedb17 100644
--- a/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java
@@ -42,7 +42,8 @@
  *
  * @author dweis@google.com (Daniel Weis)
  */
-final class BooleanArrayList extends AbstractProtobufList<Boolean>
+final class BooleanArrayList
+    extends AbstractProtobufList<Boolean>
     implements BooleanList, RandomAccess, PrimitiveNonBoxingCollection {
 
   private static final BooleanArrayList EMPTY_LIST = new BooleanArrayList();
diff --git a/java/core/src/main/java/com/google/protobuf/ByteString.java b/java/core/src/main/java/com/google/protobuf/ByteString.java
index d67bb54..ddda0f2 100644
--- a/java/core/src/main/java/com/google/protobuf/ByteString.java
+++ b/java/core/src/main/java/com/google/protobuf/ByteString.java
@@ -46,6 +46,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
@@ -222,6 +223,67 @@
   }
 
   // =================================================================
+  // Comparison
+
+  private static final int UNSIGNED_BYTE_MASK = 0xFF;
+
+  /**
+   * Returns the value of the given byte as an integer, interpreting the byte as an unsigned value.
+   * That is, returns {@code value + 256} if {@code value} is negative; {@code value} itself
+   * otherwise.
+   *
+   * <p>Note: This code was copied from {@link com.google.common.primitives.UnsignedBytes#toInt}, as
+   * Guava libraries cannot be used in the {@code com.google.protobuf} package.
+   */
+  private static int toInt(byte value) {
+    return value & UNSIGNED_BYTE_MASK;
+  }
+
+  /**
+   * Compares two {@link ByteString}s lexicographically, treating their contents as unsigned byte
+   * values between 0 and 255 (inclusive).
+   *
+   * <p>For example, {@code (byte) -1} is considered to be greater than {@code (byte) 1} because
+   * it is interpreted as an unsigned value, {@code 255}.
+   */
+  private static final Comparator<ByteString> UNSIGNED_LEXICOGRAPHICAL_COMPARATOR =
+      new Comparator<ByteString>() {
+        @Override
+        public int compare(ByteString former, ByteString latter) {
+          ByteIterator formerBytes = former.iterator();
+          ByteIterator latterBytes = latter.iterator();
+
+          while (formerBytes.hasNext() && latterBytes.hasNext()) {
+            // Note: This code was copied from com.google.common.primitives.UnsignedBytes#compare,
+            // as Guava libraries cannot be used in the {@code com.google.protobuf} package.
+            int result =
+                Integer.compare(toInt(formerBytes.nextByte()), toInt(latterBytes.nextByte()));
+            if (result != 0) {
+              return result;
+            }
+          }
+
+          return Integer.compare(former.size(), latter.size());
+        }
+      };
+
+  /**
+   * Returns a {@link Comparator<ByteString>} which compares {@link ByteString}-s lexicographically
+   * as sequences of unsigned bytes (i.e. values between 0 and 255, inclusive).
+   *
+   * <p>For example, {@code (byte) -1} is considered to be greater than {@code (byte) 1} because
+   * it is interpreted as an unsigned value, {@code 255}:
+   *
+   * <ul>
+   * <li>{@code `-1` -> 0b11111111 (two's complement) -> 255}
+   * <li>{@code `1` -> 0b00000001 -> 1}
+   * </ul>
+   */
+  public static Comparator<ByteString> unsignedLexicographicalComparator() {
+    return UNSIGNED_LEXICOGRAPHICAL_COMPARATOR;
+  }
+
+  // =================================================================
   // ByteString -> substring
 
   /**
@@ -287,8 +349,10 @@
    * @param offset offset in source array
    * @param size number of bytes to copy
    * @return new {@code ByteString}
+   * @throws IndexOutOfBoundsException if {@code offset} or {@code size} are out of bounds
    */
   public static ByteString copyFrom(byte[] bytes, int offset, int size) {
+    checkRange(offset, offset + size, bytes.length);
     return new LiteralByteString(byteArrayCopier.copyFrom(bytes, offset, size));
   }
 
@@ -339,8 +403,10 @@
    * @param bytes source buffer
    * @param size number of bytes to copy
    * @return new {@code ByteString}
+   * @throws IndexOutOfBoundsException if {@code size > bytes.remaining()}
    */
   public static ByteString copyFrom(ByteBuffer bytes, int size) {
+    checkRange(0, size, bytes.remaining());
     byte[] copy = new byte[size];
     bytes.get(copy);
     return new LiteralByteString(copy);
@@ -578,6 +644,9 @@
   /**
    * Copies bytes into a buffer at the given offset.
    *
+   * <p>To copy a subset of bytes, you call this method on the return value of {@link
+   * #substring(int, int)}. Example: {@code byteString.substring(start, end).copyTo(target, offset)}
+   *
    * @param target buffer to copy into
    * @param offset in the target buffer
    * @throws IndexOutOfBoundsException if the offset is negative or too large
@@ -589,15 +658,16 @@
   /**
    * Copies bytes into a buffer.
    *
-   * @param target       buffer to copy into
+   * @param target buffer to copy into
    * @param sourceOffset offset within these bytes
    * @param targetOffset offset within the target buffer
    * @param numberToCopy number of bytes to copy
-   * @throws IndexOutOfBoundsException if an offset or size is negative or too
-   *     large
+   * @throws IndexOutOfBoundsException if an offset or size is negative or too large
+   * @deprecation Instead, call {@code byteString.substring(sourceOffset, sourceOffset +
+   *     numberToCopy).copyTo(target, targetOffset)}
    */
-  public final void copyTo(byte[] target, int sourceOffset, int targetOffset,
-      int numberToCopy) {
+  @Deprecated
+  public final void copyTo(byte[] target, int sourceOffset, int targetOffset, int numberToCopy) {
     checkRange(sourceOffset, sourceOffset + numberToCopy, size());
     checkRange(targetOffset, targetOffset + numberToCopy, target.length);
     if (numberToCopy > 0) {
@@ -617,10 +687,13 @@
   /**
    * Copies bytes into a ByteBuffer.
    *
+   * <p>To copy a subset of bytes, you call this method on the return value of {@link
+   * #substring(int, int)}. Example: {@code byteString.substring(start, end).copyTo(target)}
+   *
    * @param target ByteBuffer to copy into.
    * @throws java.nio.ReadOnlyBufferException if the {@code target} is read-only
-   * @throws java.nio.BufferOverflowException if the {@code target}'s
-   *     remaining() space is not large enough to hold the data.
+   * @throws java.nio.BufferOverflowException if the {@code target}'s remaining() space is not large
+   *     enough to hold the data.
    */
   public abstract void copyTo(ByteBuffer target);
 
@@ -1258,6 +1331,9 @@
      * @param bytes array to wrap
      */
     LiteralByteString(byte[] bytes) {
+      if (bytes == null) {
+        throw new NullPointerException();
+      }
       this.bytes = bytes;
     }
 
diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
index 1297462..4545d0a 100644
--- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
+++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
@@ -64,12 +64,6 @@
   // Integer.MAX_VALUE == 0x7FFFFFF == INT_MAX from limits.h
   private static final int DEFAULT_SIZE_LIMIT = Integer.MAX_VALUE;
 
-  /**
-   * Whether to enable our custom UTF-8 decode codepath which does not use {@link StringCoding}.
-   * Currently disabled.
-   */
-  private static final boolean ENABLE_CUSTOM_UTF8_DECODE = false;
-
   /** Visible for subclasses. See setRecursionLimit() */
   int recursionDepth;
 
@@ -417,21 +411,7 @@
   }
 
 
-  private boolean explicitDiscardUnknownFields = false;
-
-  private static volatile boolean proto3DiscardUnknownFieldsDefault = false;
-
-  static void setProto3DiscardUnknownsByDefaultForTest() {
-    proto3DiscardUnknownFieldsDefault = true;
-  }
-
-  static void setProto3KeepUnknownsByDefaultForTest() {
-    proto3DiscardUnknownFieldsDefault = false;
-  }
-
-  static boolean getProto3DiscardUnknownFieldsDefault() {
-    return proto3DiscardUnknownFieldsDefault;
-  }
+  private boolean shouldDiscardUnknownFields = false;
 
   /**
    * Sets this {@code CodedInputStream} to discard unknown fields. Only applies to full runtime
@@ -442,7 +422,7 @@
    * runtime.
    */
   final void discardUnknownFields() {
-    explicitDiscardUnknownFields = true;
+    shouldDiscardUnknownFields = true;
   }
 
   /**
@@ -450,7 +430,7 @@
    * default.
    */
   final void unsetDiscardUnknownFields() {
-    explicitDiscardUnknownFields = false;
+    shouldDiscardUnknownFields = false;
   }
 
   /**
@@ -458,19 +438,7 @@
    * runtime messages.
    */
   final boolean shouldDiscardUnknownFields() {
-    return explicitDiscardUnknownFields;
-  }
-
-  /**
-   * Whether unknown fields in this input stream should be discarded during parsing for proto3 full
-   * runtime messages.
-   *
-   * <p>This function was temporarily introduced before proto3 unknown fields behavior is changed.
-   * TODO(liujisi): remove this and related code in GeneratedMessage after proto3 unknown
-   * fields migration is done.
-   */
-  final boolean shouldDiscardUnknownFieldsProto3() {
-    return explicitDiscardUnknownFields ? true : proto3DiscardUnknownFieldsDefault;
+    return shouldDiscardUnknownFields;
   }
 
   /**
@@ -831,19 +799,9 @@
     public String readStringRequireUtf8() throws IOException {
       final int size = readRawVarint32();
       if (size > 0 && size <= (limit - pos)) {
-        if (ENABLE_CUSTOM_UTF8_DECODE) {
-          String result = Utf8.decodeUtf8(buffer, pos, size);
-          pos += size;
-          return result;
-        } else {
-          // TODO(martinrb): We could save a pass by validating while decoding.
-          if (!Utf8.isValidUtf8(buffer, pos, pos + size)) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          final int tempPos = pos;
-          pos += size;
-          return new String(buffer, tempPos, size, UTF_8);
-        }
+        String result = Utf8.decodeUtf8(buffer, pos, size);
+        pos += size;
+        return result;
       }
 
       if (size == 0) {
@@ -1559,25 +1517,10 @@
     public String readStringRequireUtf8() throws IOException {
       final int size = readRawVarint32();
       if (size > 0 && size <= remaining()) {
-        if (ENABLE_CUSTOM_UTF8_DECODE) {
-          final int bufferPos = bufferPos(pos);
-          String result = Utf8.decodeUtf8(buffer, bufferPos, size);
-          pos += size;
-          return result;
-        } else {
-          // TODO(nathanmittler): Is there a way to avoid this copy?
-          // The same as readBytes' logic
-          byte[] bytes = new byte[size];
-          UnsafeUtil.copyMemory(pos, bytes, 0, size);
-          // TODO(martinrb): We could save a pass by validating while decoding.
-          if (!Utf8.isValidUtf8(bytes)) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-
-          String result = new String(bytes, UTF_8);
-          pos += size;
-          return result;
-        }
+        final int bufferPos = bufferPos(pos);
+        String result = Utf8.decodeUtf8(buffer, bufferPos, size);
+        pos += size;
+        return result;
       }
 
       if (size == 0) {
@@ -2345,15 +2288,7 @@
         bytes = readRawBytesSlowPath(size);
         tempPos = 0;
       }
-      if (ENABLE_CUSTOM_UTF8_DECODE) {
-        return Utf8.decodeUtf8(bytes, tempPos, size);
-      } else {
-        // TODO(martinrb): We could save a pass by validating while decoding.
-        if (!Utf8.isValidUtf8(bytes, tempPos, tempPos + size)) {
-          throw InvalidProtocolBufferException.invalidUtf8();
-        }
-        return new String(bytes, tempPos, size, UTF_8);
-      }
+      return Utf8.decodeUtf8(bytes, tempPos, size);
     }
 
     @Override
@@ -3373,34 +3308,15 @@
     public String readStringRequireUtf8() throws IOException {
       final int size = readRawVarint32();
       if (size > 0 && size <= currentByteBufferLimit - currentByteBufferPos) {
-        if (ENABLE_CUSTOM_UTF8_DECODE) {
-          final int bufferPos = (int) (currentByteBufferPos - currentByteBufferStartPos);
-          String result = Utf8.decodeUtf8(currentByteBuffer, bufferPos, size);
-          currentByteBufferPos += size;
-          return result;
-        } else {
-          byte[] bytes = new byte[size];
-          UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, size);
-          if (!Utf8.isValidUtf8(bytes)) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          String result = new String(bytes, UTF_8);
-          currentByteBufferPos += size;
-          return result;
-        }
+        final int bufferPos = (int) (currentByteBufferPos - currentByteBufferStartPos);
+        String result = Utf8.decodeUtf8(currentByteBuffer, bufferPos, size);
+        currentByteBufferPos += size;
+        return result;
       }
       if (size >= 0 && size <= remaining()) {
         byte[] bytes = new byte[size];
         readRawBytesTo(bytes, 0, size);
-        if (ENABLE_CUSTOM_UTF8_DECODE) {
-          return Utf8.decodeUtf8(bytes, 0, size);
-        } else {
-          if (!Utf8.isValidUtf8(bytes)) {
-            throw InvalidProtocolBufferException.invalidUtf8();
-          }
-          String result = new String(bytes, UTF_8);
-          return result;
-        }
+        return Utf8.decodeUtf8(bytes, 0, size);
       }
 
       if (size == 0) {
diff --git a/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java b/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java
index 5b28b4a..8d987b2 100644
--- a/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java
@@ -42,7 +42,8 @@
  *
  * @author dweis@google.com (Daniel Weis)
  */
-final class DoubleArrayList extends AbstractProtobufList<Double>
+final class DoubleArrayList
+    extends AbstractProtobufList<Double>
     implements DoubleList, RandomAccess, PrimitiveNonBoxingCollection {
 
   private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList();
diff --git a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
index a6a774b..2c346e0 100644
--- a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
@@ -608,20 +608,12 @@
 
     @Override
     public Builder setUnknownFields(UnknownFieldSet unknownFields) {
-      if (getDescriptorForType().getFile().getSyntax() == Descriptors.FileDescriptor.Syntax.PROTO3
-          && CodedInputStream.getProto3DiscardUnknownFieldsDefault()) {
-        return this;
-      }
       this.unknownFields = unknownFields;
       return this;
     }
 
     @Override
     public Builder mergeUnknownFields(UnknownFieldSet unknownFields) {
-      if (getDescriptorForType().getFile().getSyntax() == Descriptors.FileDescriptor.Syntax.PROTO3
-          && CodedInputStream.getProto3DiscardUnknownFieldsDefault()) {
-        return this;
-      }
       this.unknownFields =
         UnknownFieldSet.newBuilder(this.unknownFields)
                        .mergeFrom(unknownFields)
diff --git a/java/core/src/main/java/com/google/protobuf/FloatArrayList.java b/java/core/src/main/java/com/google/protobuf/FloatArrayList.java
index 7c080af..41749f6 100644
--- a/java/core/src/main/java/com/google/protobuf/FloatArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/FloatArrayList.java
@@ -42,7 +42,8 @@
  *
  * @author dweis@google.com (Daniel Weis)
  */
-final class FloatArrayList extends AbstractProtobufList<Float>
+final class FloatArrayList
+    extends AbstractProtobufList<Float>
     implements FloatList, RandomAccess, PrimitiveNonBoxingCollection {
 
   private static final FloatArrayList EMPTY_LIST = new FloatArrayList();
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
index 1e122d1..ff670fd 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -33,7 +33,6 @@
 import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
 import com.google.protobuf.Internal.BooleanList;
 import com.google.protobuf.Internal.DoubleList;
-import com.google.protobuf.Internal.EnumLiteMap;
 import com.google.protobuf.Internal.FloatList;
 import com.google.protobuf.Internal.IntList;
 import com.google.protobuf.Internal.LongList;
@@ -1608,7 +1607,7 @@
   protected static class DefaultInstanceBasedParser<T extends GeneratedMessageLite<T, ?>>
       extends AbstractParser<T> {
 
-    private T defaultInstance;
+    private final T defaultInstance;
 
     public DefaultInstanceBasedParser(T defaultInstance) {
       this.defaultInstance = defaultInstance;
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 4acd8f2..53af544 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
@@ -38,6 +38,11 @@
 import com.google.protobuf.Descriptors.FieldDescriptor;
 import com.google.protobuf.Descriptors.FileDescriptor;
 import com.google.protobuf.Descriptors.OneofDescriptor;
+import com.google.protobuf.Internal.BooleanList;
+import com.google.protobuf.Internal.DoubleList;
+import com.google.protobuf.Internal.FloatList;
+import com.google.protobuf.Internal.IntList;
+import com.google.protobuf.Internal.LongList;
 // In opensource protobuf, we have versioned this GeneratedMessageV3 class to GeneratedMessageV3V3 and
 // in the future may have GeneratedMessageV3V4 etc. This allows us to change some aspects of this
 // class without breaking binary compatibility with old generated code that still subclasses
@@ -293,16 +298,17 @@
     return unknownFields.mergeFieldFrom(tag, input);
   }
 
+  /**
+   * Delegates to parseUnknownField. This method is obsolete, but we must retain it for
+   * compatibility with older generated code.
+   */
   protected boolean parseUnknownFieldProto3(
       CodedInputStream input,
       UnknownFieldSet.Builder unknownFields,
       ExtensionRegistryLite extensionRegistry,
       int tag)
       throws IOException {
-    if (input.shouldDiscardUnknownFieldsProto3()) {
-      return input.skipField(tag);
-    }
-    return unknownFields.mergeFieldFrom(tag, input);
+    return parseUnknownField(input, unknownFields, extensionRegistry, tag);
   }
 
   protected static <M extends Message> M parseWithIOException(Parser<M> parser, InputStream input)
@@ -363,6 +369,76 @@
     return UnsafeUtil.hasUnsafeArrayOperations() && UnsafeUtil.hasUnsafeByteBufferOperations();
   }
 
+  protected static IntList emptyIntList() {
+    return IntArrayList.emptyList();
+  }
+
+  protected static IntList newIntList() {
+    return new IntArrayList();
+  }
+
+  protected static IntList mutableCopy(IntList list) {
+    int size = list.size();
+    return list.mutableCopyWithCapacity(
+        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
+  }
+
+  protected static LongList emptyLongList() {
+    return LongArrayList.emptyList();
+  }
+
+  protected static LongList newLongList() {
+    return new LongArrayList();
+  }
+
+  protected static LongList mutableCopy(LongList list) {
+    int size = list.size();
+    return list.mutableCopyWithCapacity(
+        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
+  }
+
+  protected static FloatList emptyFloatList() {
+    return FloatArrayList.emptyList();
+  }
+
+  protected static FloatList newFloatList() {
+    return new FloatArrayList();
+  }
+
+  protected static FloatList mutableCopy(FloatList list) {
+    int size = list.size();
+    return list.mutableCopyWithCapacity(
+        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
+  }
+
+  protected static DoubleList emptyDoubleList() {
+    return DoubleArrayList.emptyList();
+  }
+
+  protected static DoubleList newDoubleList() {
+    return new DoubleArrayList();
+  }
+
+  protected static DoubleList mutableCopy(DoubleList list) {
+    int size = list.size();
+    return list.mutableCopyWithCapacity(
+        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
+  }
+
+  protected static BooleanList emptyBooleanList() {
+    return BooleanArrayList.emptyList();
+  }
+
+  protected static BooleanList newBooleanList() {
+    return new BooleanArrayList();
+  }
+
+  protected static BooleanList mutableCopy(BooleanList list) {
+    int size = list.size();
+    return list.mutableCopyWithCapacity(
+        size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
+  }
+
   @Override
   public void writeTo(final CodedOutputStream output) throws IOException {
     MessageReflection.writeMessageTo(this, getAllFieldsRaw(), output, false);
@@ -641,13 +717,12 @@
       return (BuilderType) this;
     }
 
+    /**
+     * Delegates to setUnknownFields. This method is obsolete, but we must retain it for
+     * compatibility with older generated code.
+     */
     protected BuilderType setUnknownFieldsProto3(final UnknownFieldSet unknownFields) {
-      if (CodedInputStream.getProto3DiscardUnknownFieldsDefault()) {
-        return (BuilderType) this;
-      }
-      this.unknownFields = unknownFields;
-      onChanged();
-      return (BuilderType) this;
+      return setUnknownFields(unknownFields);
     }
 
     @Override
@@ -1009,19 +1084,17 @@
           getDescriptorForType(), new MessageReflection.ExtensionAdapter(extensions), tag);
     }
 
+    /**
+     * Delegates to parseUnknownField. This method is obsolete, but we must retain it for
+     * compatibility with older generated code.
+     */
     @Override
     protected boolean parseUnknownFieldProto3(
         CodedInputStream input,
         UnknownFieldSet.Builder unknownFields,
         ExtensionRegistryLite extensionRegistry,
         int tag) throws IOException {
-      return MessageReflection.mergeFieldFrom(
-          input,
-          input.shouldDiscardUnknownFieldsProto3() ? null : unknownFields,
-          extensionRegistry,
-          getDescriptorForType(),
-          new MessageReflection.ExtensionAdapter(extensions),
-          tag);
+      return parseUnknownField(input, unknownFields, extensionRegistry, tag);
     }
 
 
diff --git a/java/core/src/main/java/com/google/protobuf/IntArrayList.java b/java/core/src/main/java/com/google/protobuf/IntArrayList.java
index aacd71e..4993eea 100644
--- a/java/core/src/main/java/com/google/protobuf/IntArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/IntArrayList.java
@@ -42,7 +42,8 @@
  *
  * @author dweis@google.com (Daniel Weis)
  */
-final class IntArrayList extends AbstractProtobufList<Integer>
+final class IntArrayList
+    extends AbstractProtobufList<Integer>
     implements IntList, RandomAccess, PrimitiveNonBoxingCollection {
 
   private static final IntArrayList EMPTY_LIST = new IntArrayList();
diff --git a/java/core/src/main/java/com/google/protobuf/Internal.java b/java/core/src/main/java/com/google/protobuf/Internal.java
index 848cad0..878573d 100644
--- a/java/core/src/main/java/com/google/protobuf/Internal.java
+++ b/java/core/src/main/java/com/google/protobuf/Internal.java
@@ -234,6 +234,11 @@
     T findValueByNumber(int number);
   }
 
+  /** Interface for an object which verifies integers are in range. */
+  public interface EnumVerifier {
+    boolean isInRange(int number);
+  }
+
   /**
    * Helper method for implementing {@link Message#hashCode()} for longs.
    * @see Long#hashCode()
diff --git a/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java b/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java
index d474c51..6cfc14a 100644
--- a/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java
@@ -69,7 +69,7 @@
   static {
     EMPTY_LIST.makeImmutable();
   }
-  
+
   static LazyStringArrayList emptyList() {
     return EMPTY_LIST;
   }
@@ -83,8 +83,8 @@
     this(DEFAULT_CAPACITY);
   }
 
-  public LazyStringArrayList(int intialCapacity) {
-    this(new ArrayList<Object>(intialCapacity));
+  public LazyStringArrayList(int initialCapacity) {
+    this(new ArrayList<Object>(initialCapacity));
   }
 
   public LazyStringArrayList(LazyStringList from) {
@@ -95,7 +95,7 @@
   public LazyStringArrayList(List<String> from) {
     this(new ArrayList<Object>(from));
   }
-  
+
   private LazyStringArrayList(ArrayList<Object> list) {
     this.list = list;
   }
@@ -150,13 +150,13 @@
     list.add(index, element);
     modCount++;
   }
-  
+
   private void add(int index, ByteString element) {
     ensureIsMutable();
     list.add(index, element);
     modCount++;
   }
-  
+
   private void add(int index, byte[] element) {
     ensureIsMutable();
     list.add(index, element);
@@ -221,7 +221,7 @@
     list.add(element);
     modCount++;
   }
-  
+
   @Override
   public void add(byte[] element) {
     ensureIsMutable();
@@ -233,7 +233,7 @@
   public Object getRaw(int index) {
     return list.get(index);
   }
-  
+
   @Override
   public ByteString getByteString(int index) {
     Object o = list.get(index);
@@ -243,7 +243,7 @@
     }
     return b;
   }
-  
+
   @Override
   public byte[] getByteArray(int index) {
     Object o = list.get(index);
@@ -258,7 +258,7 @@
   public void set(int index, ByteString s) {
     setAndReturn(index, s);
   }
-  
+
   private Object setAndReturn(int index, ByteString s) {
     ensureIsMutable();
     return list.set(index, s);
@@ -268,7 +268,7 @@
   public void set(int index, byte[] s) {
     setAndReturn(index, s);
   }
-  
+
   private Object setAndReturn(int index, byte[] s) {
     ensureIsMutable();
     return list.set(index, s);
@@ -283,7 +283,7 @@
       return Internal.toStringUtf8((byte[]) o);
     }
   }
-  
+
   private static ByteString asByteString(Object o) {
     if (o instanceof ByteString) {
       return (ByteString) o;
@@ -293,7 +293,7 @@
       return ByteString.copyFrom((byte[]) o);
     }
   }
-  
+
   private static byte[] asByteArray(Object o) {
     if (o instanceof byte[]) {
       return (byte[]) o;
@@ -327,11 +327,11 @@
   private static class ByteArrayListView extends AbstractList<byte[]>
       implements RandomAccess {
     private final LazyStringArrayList list;
-    
+
     ByteArrayListView(LazyStringArrayList list) {
       this.list = list;
     }
-    
+
     @Override
     public byte[] get(int index) {
       return list.getByteArray(index);
@@ -362,7 +362,7 @@
       return asByteArray(o);
     }
   }
-  
+
   @Override
   public List<byte[]> asByteArrayList() {
     return new ByteArrayListView(this);
diff --git a/java/core/src/main/java/com/google/protobuf/LongArrayList.java b/java/core/src/main/java/com/google/protobuf/LongArrayList.java
index 95945cb..9a5056b 100644
--- a/java/core/src/main/java/com/google/protobuf/LongArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/LongArrayList.java
@@ -42,7 +42,8 @@
  *
  * @author dweis@google.com (Daniel Weis)
  */
-final class LongArrayList extends AbstractProtobufList<Long>
+final class LongArrayList
+    extends AbstractProtobufList<Long>
     implements LongList, RandomAccess, PrimitiveNonBoxingCollection {
 
   private static final LongArrayList EMPTY_LIST = new LongArrayList();
diff --git a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
index 29f567d..b593b56 100644
--- a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
+++ b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
@@ -30,6 +30,8 @@
 
 package com.google.protobuf;
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 import java.util.AbstractList;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -290,9 +292,7 @@
    */
   public RepeatedFieldBuilder<MType, BType, IType> setMessage(
       int index, MType message) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(message);
     ensureMutableMessageList();
     messages.set(index, message);
     if (builders != null) {
@@ -315,9 +315,7 @@
    */
   public RepeatedFieldBuilder<MType, BType, IType> addMessage(
       MType message) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(message);
     ensureMutableMessageList();
     messages.add(message);
     if (builders != null) {
@@ -339,9 +337,7 @@
    */
   public RepeatedFieldBuilder<MType, BType, IType> addMessage(
       int index, MType message) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
+    checkNotNull(message);
     ensureMutableMessageList();
     messages.add(index, message);
     if (builders != null) {
@@ -363,9 +359,7 @@
   public RepeatedFieldBuilder<MType, BType, IType> addAllMessages(
       Iterable<? extends MType> values) {
     for (final MType value : values) {
-      if (value == null) {
-        throw new NullPointerException();
-      }
+      checkNotNull(value);
     }
 
     // If we can inspect the size, we can more efficiently add messages.
diff --git a/java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java b/java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java
index 941b5de..1f5ec8a 100644
--- a/java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java
+++ b/java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java
@@ -30,6 +30,8 @@
 
 package com.google.protobuf;
 
+import static com.google.protobuf.Internal.checkNotNull;
+
 /**
  * {@code SingleFieldBuilder} implements a structure that a protocol
  * message uses to hold a single field of another protocol message. It supports
@@ -84,10 +86,7 @@
       MType message,
       GeneratedMessage.BuilderParent parent,
       boolean isClean) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
-    this.message = message;
+    this.message = checkNotNull(message);
     this.parent = parent;
     this.isClean = isClean;
   }
@@ -169,10 +168,7 @@
    */
   public SingleFieldBuilder<MType, BType, IType> setMessage(
       MType message) {
-    if (message == null) {
-      throw new NullPointerException();
-    }
-    this.message = message;
+    this.message = checkNotNull(message);
     if (builder != null) {
       builder.dispose();
       builder = null;
diff --git a/java/core/src/main/java/com/google/protobuf/TextFormat.java b/java/core/src/main/java/com/google/protobuf/TextFormat.java
index 25c3474..79962e0 100644
--- a/java/core/src/main/java/com/google/protobuf/TextFormat.java
+++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java
@@ -1444,8 +1444,8 @@
           logger.warning(msg.toString());
       } else {
         String[] lineColumn = unknownFields.get(0).split(":");
-        throw new ParseException(Integer.valueOf(lineColumn[0]),
-            Integer.valueOf(lineColumn[1]), msg.toString());
+        throw new ParseException(
+            Integer.parseInt(lineColumn[0]), Integer.parseInt(lineColumn[1]), msg.toString());
       }
     }
 
diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
index 37d6463..b3fdebc 100644
--- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
+++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
@@ -786,6 +786,23 @@
     }
 
     /**
+     * Serializes the message to a {@code ByteString} and returns it. This is just a trivial wrapper
+     * around {@link #writeTo(int, CodedOutputStream)}.
+     */
+    public ByteString toByteString(int fieldNumber) {
+      try {
+        // TODO(lukes): consider caching serialized size in a volatile long
+        final ByteString.CodedBuilder out =
+            ByteString.newCodedBuilder(getSerializedSize(fieldNumber));
+        writeTo(fieldNumber, out.getCodedOutput());
+        return out.build();
+      } catch (IOException e) {
+        throw new RuntimeException(
+            "Serializing to a ByteString should never fail with an IOException", e);
+      }
+    }
+
+    /**
      * Serializes the field, including field number, and writes it to
      * {@code output}.
      */
diff --git a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
index d84ef3c..f822ce5 100644
--- a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
+++ b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
@@ -33,6 +33,7 @@
 import java.lang.reflect.Field;
 import java.nio.Buffer;
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
 import java.util.logging.Level;
@@ -146,6 +147,10 @@
     return MEMORY_ACCESSOR.getObject(target, offset);
   }
 
+  static void putObject(Object target, long offset, Object value) {
+    MEMORY_ACCESSOR.putObject(target, offset, value);
+  }
+
   static byte getByte(byte[] target, long index) {
     return MEMORY_ACCESSOR.getByte(target, BYTE_ARRAY_BASE_OFFSET + index);
   }
@@ -370,12 +375,6 @@
     return field != null && field.getType() == long.class ? field : null;
   }
 
-  /** Finds the value field within a {@link String}. */
-  private static Field stringValueField() {
-    Field field = field(String.class, "value");
-    return field != null && field.getType() == char[].class ? field : null;
-  }
-
   /**
    * Returns the offset of the provided field, or {@code -1} if {@code sun.misc.Unsafe} is not
    * available.
diff --git a/java/core/src/main/java/com/google/protobuf/Utf8.java b/java/core/src/main/java/com/google/protobuf/Utf8.java
index de75fe6..b4a81ca 100644
--- a/java/core/src/main/java/com/google/protobuf/Utf8.java
+++ b/java/core/src/main/java/com/google/protobuf/Utf8.java
@@ -42,7 +42,6 @@
 import static java.lang.Character.toCodePoint;
 
 import java.nio.ByteBuffer;
-import java.util.Arrays;
 
 /**
  * A set of low-level, high-performance static utility methods related
@@ -87,7 +86,9 @@
    * delegate for which all methods are delegated directly to.
    */
   private static final Processor processor =
-      UnsafeProcessor.isAvailable() ? new UnsafeProcessor() : new SafeProcessor();
+      (UnsafeProcessor.isAvailable() && !Android.isOnAndroidDevice())
+          ? new UnsafeProcessor()
+          : new SafeProcessor();
 
   /**
    * A mask used when performing unsafe reads to determine if a long value contains any non-ASCII
diff --git a/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java b/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java
index cb2d34e..bb11bd0 100644
--- a/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java
+++ b/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java
@@ -210,8 +210,8 @@
     new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
 
   TestUtil.ReflectionTester extensionsReflectionTester =
-    new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
-                                  TestUtil.getExtensionRegistry());
+      new TestUtil.ReflectionTester(
+          TestAllExtensions.getDescriptor(), TestUtil.getFullExtensionRegistry());
 
   public void testClear() throws Exception {
     AbstractMessageWrapper message =
diff --git a/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java b/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java
index 4906763..febe853 100644
--- a/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java
@@ -299,20 +299,22 @@
   }
 
   public void testRemoveEndOfCapacity() {
-    BooleanList toRemove = BooleanArrayList.emptyList().mutableCopyWithCapacity(1);
+    BooleanList toRemove =
+        BooleanArrayList.emptyList().mutableCopyWithCapacity(1);
     toRemove.addBoolean(true);
     toRemove.remove(0);
     assertEquals(0, toRemove.size());
   }
 
   public void testSublistRemoveEndOfCapacity() {
-    BooleanList toRemove = BooleanArrayList.emptyList().mutableCopyWithCapacity(1);
+    BooleanList toRemove =
+        BooleanArrayList.emptyList().mutableCopyWithCapacity(1);
     toRemove.addBoolean(true);
     toRemove.subList(0, 1).clear();
     assertEquals(0, toRemove.size());
   }
 
-  private void assertImmutable(BooleanArrayList list) {
+  private void assertImmutable(BooleanList list) {
 
     try {
       list.add(true);
diff --git a/java/core/src/test/java/com/google/protobuf/ByteStringTest.java b/java/core/src/test/java/com/google/protobuf/ByteStringTest.java
index be71f1f..fc22955 100644
--- a/java/core/src/test/java/com/google/protobuf/ByteStringTest.java
+++ b/java/core/src/test/java/com/google/protobuf/ByteStringTest.java
@@ -41,6 +41,7 @@
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
@@ -86,6 +87,40 @@
     return left.length == right.length && isArrayRange(left, right, 0, left.length);
   }
 
+  public void testCompare_equalByteStrings_compareEqual() throws Exception {
+    byte[] referenceBytes = getTestBytes();
+    ByteString string1 = ByteString.copyFrom(referenceBytes);
+    ByteString string2 = ByteString.copyFrom(referenceBytes);
+
+    assertEquals(
+        "ByteString instances containing the same data must compare equal.",
+        0,
+        ByteString.unsignedLexicographicalComparator().compare(string1, string2));
+  }
+
+  public void testCompare_byteStringsSortLexicographically() throws Exception {
+    ByteString app = ByteString.copyFromUtf8("app");
+    ByteString apple = ByteString.copyFromUtf8("apple");
+    ByteString banana = ByteString.copyFromUtf8("banana");
+
+    Comparator<ByteString> comparator = ByteString.unsignedLexicographicalComparator();
+
+    assertTrue("ByteString(app) < ByteString(apple)", comparator.compare(app, apple) < 0);
+    assertTrue("ByteString(app) < ByteString(banana)", comparator.compare(app, banana) < 0);
+    assertTrue("ByteString(apple) < ByteString(banana)", comparator.compare(apple, banana) < 0);
+  }
+
+  public void testCompare_interpretsByteValuesAsUnsigned() throws Exception {
+    // Two's compliment of `-1` == 0b11111111 == 255
+    ByteString twoHundredFiftyFive = ByteString.copyFrom(new byte[] {-1});
+    // 0b00000001 == 1
+    ByteString one = ByteString.copyFrom(new byte[] {1});
+
+    assertTrue(
+        "ByteString comparison treats bytes as unsigned values",
+        ByteString.unsignedLexicographicalComparator().compare(one, twoHundredFiftyFive) < 0);
+  }
+
   public void testSubstring_BeginIndex() {
     byte[] bytes = getTestBytes();
     ByteString substring = ByteString.copyFrom(bytes).substring(500);
@@ -161,6 +196,34 @@
         byteString, byteStringAlt);
   }
 
+  public void testCopyFrom_LengthTooBig() {
+    byte[] testBytes = getTestBytes(100);
+    try {
+      ByteString.copyFrom(testBytes, 0, 200);
+      fail("Should throw");
+    } catch (IndexOutOfBoundsException expected) {
+    }
+
+    try {
+      ByteString.copyFrom(testBytes, 99, 2);
+      fail();
+    } catch (IndexOutOfBoundsException expected) {
+    }
+
+    ByteBuffer buf = ByteBuffer.wrap(testBytes);
+    try {
+      ByteString.copyFrom(buf, 101);
+      fail();
+    } catch (IndexOutOfBoundsException expected) {
+    }
+
+    try {
+      ByteString.copyFrom(testBytes, -1, 10);
+      fail("Should throw");
+    } catch (IndexOutOfBoundsException expected) {
+    }
+  }
+
   public void testCopyTo_TargetOffset() {
     byte[] bytes = getTestBytes();
     ByteString byteString = ByteString.copyFrom(bytes);
@@ -761,6 +824,9 @@
    * Tests ByteString uses Arrays based byte copier when running under Hotstop VM.
    */
   public void testByteArrayCopier() throws Exception {
+    if (Android.isOnAndroidDevice()) {
+      return;
+    }
     Field field = ByteString.class.getDeclaredField("byteArrayCopier");
     field.setAccessible(true);
     Object byteArrayCopier = field.get(null);
diff --git a/java/core/src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java b/java/core/src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java
index 0f09a51..36c4611 100644
--- a/java/core/src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java
+++ b/java/core/src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java
@@ -62,22 +62,17 @@
   }
 
   private static void testProto2Message(Message message) throws Exception {
-    assertUnknownFieldsDefaultPreserved(message);
+    assertUnknownFieldsPreserved(message);
     assertUnknownFieldsExplicitlyDiscarded(message);
     assertReuseCodedInputStreamPreserve(message);
     assertUnknownFieldsInUnknownFieldSetArePreserve(message);
   }
 
   private static void testProto3Message(Message message) throws Exception {
-    CodedInputStream.setProto3KeepUnknownsByDefaultForTest();
-    assertUnknownFieldsDefaultPreserved(message);
+    assertUnknownFieldsPreserved(message);
     assertUnknownFieldsExplicitlyDiscarded(message);
     assertReuseCodedInputStreamPreserve(message);
     assertUnknownFieldsInUnknownFieldSetArePreserve(message);
-    CodedInputStream.setProto3DiscardUnknownsByDefaultForTest();
-    assertUnknownFieldsDefaultDiscarded(message);
-    assertUnknownFieldsExplicitlyDiscarded(message);
-    assertUnknownFieldsInUnknownFieldSetAreDiscarded(message);
   }
 
   private static void assertReuseCodedInputStreamPreserve(Message message) throws Exception {
@@ -122,7 +117,7 @@
     assertEquals(message.getClass().getName(), 0, built.getSerializedSize());
   }
 
-  private static void assertUnknownFieldsDefaultPreserved(MessageLite message) throws Exception {
+  private static void assertUnknownFieldsPreserved(MessageLite message) throws Exception {
     {
       MessageLite parsed = message.getParserForType().parseFrom(payload);
       assertEquals(message.getClass().getName(), payload, parsed.toByteString());
@@ -134,18 +129,6 @@
     }
   }
 
-  private static void assertUnknownFieldsDefaultDiscarded(MessageLite message) throws Exception {
-    {
-      MessageLite parsed = message.getParserForType().parseFrom(payload);
-      assertEquals(message.getClass().getName(), 0, parsed.getSerializedSize());
-    }
-
-    {
-      MessageLite parsed = message.newBuilderForType().mergeFrom(payload).build();
-      assertEquals(message.getClass().getName(), 0, parsed.getSerializedSize());
-    }
-  }
-
   private static void assertUnknownFieldsExplicitlyDiscarded(Message message) throws Exception {
     Message parsed =
         DiscardUnknownFieldsParser.wrap(message.getParserForType()).parseFrom(payload);
diff --git a/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java b/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java
index 923d7f4..a4c2f5a 100644
--- a/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java
@@ -78,10 +78,10 @@
     list.addAll(asList(1D, 2D, 3D, 4D));
     Iterator<Double> iterator = list.iterator();
     assertEquals(4, list.size());
-    assertEquals(1D, (double) list.get(0));
-    assertEquals(1D, (double) iterator.next());
+    assertEquals(1D, (double) list.get(0), 0.0);
+    assertEquals(1D, (double) iterator.next(), 0.0);
     list.set(0, 1D);
-    assertEquals(2D, (double) iterator.next());
+    assertEquals(2D, (double) iterator.next(), 0.0);
 
     list.remove(0);
     try {
@@ -102,9 +102,9 @@
   }
 
   public void testGet() {
-    assertEquals(1D, (double) TERTIARY_LIST.get(0));
-    assertEquals(2D, (double) TERTIARY_LIST.get(1));
-    assertEquals(3D, (double) TERTIARY_LIST.get(2));
+    assertEquals(1D, (double) TERTIARY_LIST.get(0), 0.0);
+    assertEquals(2D, (double) TERTIARY_LIST.get(1), 0.0);
+    assertEquals(3D, (double) TERTIARY_LIST.get(2), 0.0);
 
     try {
       TERTIARY_LIST.get(-1);
@@ -122,9 +122,9 @@
   }
 
   public void testGetDouble() {
-    assertEquals(1D, TERTIARY_LIST.getDouble(0));
-    assertEquals(2D, TERTIARY_LIST.getDouble(1));
-    assertEquals(3D, TERTIARY_LIST.getDouble(2));
+    assertEquals(1D, TERTIARY_LIST.getDouble(0), 0.0);
+    assertEquals(2D, TERTIARY_LIST.getDouble(1), 0.0);
+    assertEquals(3D, TERTIARY_LIST.getDouble(2), 0.0);
 
     try {
       TERTIARY_LIST.get(-1);
@@ -163,11 +163,11 @@
     list.addDouble(2);
     list.addDouble(4);
 
-    assertEquals(2D, (double) list.set(0, 3D));
-    assertEquals(3D, list.getDouble(0));
+    assertEquals(2D, (double) list.set(0, 3D), 0.0);
+    assertEquals(3D, list.getDouble(0), 0.0);
 
-    assertEquals(4D, (double) list.set(1, 0D));
-    assertEquals(0D, list.getDouble(1));
+    assertEquals(4D, (double) list.set(1, 0D), 0.0);
+    assertEquals(0D, list.getDouble(1), 0.0);
 
     try {
       list.set(-1, 0D);
@@ -188,11 +188,11 @@
     list.addDouble(1);
     list.addDouble(3);
 
-    assertEquals(1D, list.setDouble(0, 0));
-    assertEquals(0D, list.getDouble(0));
+    assertEquals(1D, list.setDouble(0, 0), 0.0);
+    assertEquals(0D, list.getDouble(0), 0.0);
 
-    assertEquals(3D, list.setDouble(1, 0));
-    assertEquals(0D, list.getDouble(1));
+    assertEquals(3D, list.setDouble(1, 0), 0.0);
+    assertEquals(0D, list.getDouble(1), 0.0);
 
     try {
       list.setDouble(-1, 0);
@@ -257,8 +257,8 @@
 
     assertTrue(list.addAll(Collections.singleton(1D)));
     assertEquals(1, list.size());
-    assertEquals(1D, (double) list.get(0));
-    assertEquals(1D, list.getDouble(0));
+    assertEquals(1D, (double) list.get(0), 0.0);
+    assertEquals(1D, list.getDouble(0), 0.0);
 
     assertTrue(list.addAll(asList(2D, 3D, 4D, 5D, 6D)));
     assertEquals(asList(1D, 2D, 3D, 4D, 5D, 6D), list);
@@ -272,7 +272,7 @@
 
   public void testRemove() {
     list.addAll(TERTIARY_LIST);
-    assertEquals(1D, (double) list.remove(0));
+    assertEquals(1D, (double) list.remove(0), 0.0);
     assertEquals(asList(2D, 3D), list);
 
     assertTrue(list.remove(Double.valueOf(3)));
@@ -281,7 +281,7 @@
     assertFalse(list.remove(Double.valueOf(3)));
     assertEquals(asList(2D), list);
 
-    assertEquals(2D, (double) list.remove(0));
+    assertEquals(2D, (double) list.remove(0), 0.0);
     assertEquals(asList(), list);
 
     try {
@@ -299,20 +299,22 @@
   }
 
   public void testRemoveEndOfCapacity() {
-    DoubleList toRemove = DoubleArrayList.emptyList().mutableCopyWithCapacity(1);
+    DoubleList toRemove =
+        DoubleArrayList.emptyList().mutableCopyWithCapacity(1);
     toRemove.addDouble(3);
     toRemove.remove(0);
     assertEquals(0, toRemove.size());
   }
 
   public void testSublistRemoveEndOfCapacity() {
-    DoubleList toRemove = DoubleArrayList.emptyList().mutableCopyWithCapacity(1);
+    DoubleList toRemove =
+        DoubleArrayList.emptyList().mutableCopyWithCapacity(1);
     toRemove.addDouble(3);
     toRemove.subList(0, 1).clear();
     assertEquals(0, toRemove.size());
   }
 
-  private void assertImmutable(DoubleArrayList list) {
+  private void assertImmutable(DoubleList list) {
     if (list.contains(1D)) {
       throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
     }
diff --git a/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java b/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java
index 77d14f6..346c1e6 100644
--- a/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java
+++ b/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java
@@ -51,8 +51,8 @@
     new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
 
   TestUtil.ReflectionTester extensionsReflectionTester =
-    new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
-                                  TestUtil.getExtensionRegistry());
+      new TestUtil.ReflectionTester(
+          TestAllExtensions.getDescriptor(), TestUtil.getFullExtensionRegistry());
   TestUtil.ReflectionTester packedReflectionTester =
     new TestUtil.ReflectionTester(TestPackedTypes.getDescriptor(), null);
 
@@ -194,9 +194,9 @@
 
   public void testDynamicMessageExtensionParsing() throws Exception {
     ByteString rawBytes = TestUtil.getAllExtensionsSet().toByteString();
-    Message message = DynamicMessage.parseFrom(
-        TestAllExtensions.getDescriptor(), rawBytes,
-        TestUtil.getExtensionRegistry());
+    Message message =
+        DynamicMessage.parseFrom(
+            TestAllExtensions.getDescriptor(), rawBytes, TestUtil.getFullExtensionRegistry());
     extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
 
     // Test Parser interface.
diff --git a/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java b/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java
index 903a79d..38eccc9 100644
--- a/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java
@@ -78,10 +78,10 @@
     list.addAll(asList(1F, 2F, 3F, 4F));
     Iterator<Float> iterator = list.iterator();
     assertEquals(4, list.size());
-    assertEquals(1F, (float) list.get(0));
-    assertEquals(1F, (float) iterator.next());
+    assertEquals(1F, (float) list.get(0), 0.0f);
+    assertEquals(1F, (float) iterator.next(), 0.0f);
     list.set(0, 1F);
-    assertEquals(2F, (float) iterator.next());
+    assertEquals(2F, (float) iterator.next(), 0.0f);
 
     list.remove(0);
     try {
@@ -102,9 +102,9 @@
   }
 
   public void testGet() {
-    assertEquals(1F, (float) TERTIARY_LIST.get(0));
-    assertEquals(2F, (float) TERTIARY_LIST.get(1));
-    assertEquals(3F, (float) TERTIARY_LIST.get(2));
+    assertEquals(1F, (float) TERTIARY_LIST.get(0), 0.0f);
+    assertEquals(2F, (float) TERTIARY_LIST.get(1), 0.0f);
+    assertEquals(3F, (float) TERTIARY_LIST.get(2), 0.0f);
 
     try {
       TERTIARY_LIST.get(-1);
@@ -122,9 +122,9 @@
   }
 
   public void testGetFloat() {
-    assertEquals(1F, TERTIARY_LIST.getFloat(0));
-    assertEquals(2F, TERTIARY_LIST.getFloat(1));
-    assertEquals(3F, TERTIARY_LIST.getFloat(2));
+    assertEquals(1F, TERTIARY_LIST.getFloat(0), 0.0f);
+    assertEquals(2F, TERTIARY_LIST.getFloat(1), 0.0f);
+    assertEquals(3F, TERTIARY_LIST.getFloat(2), 0.0f);
 
     try {
       TERTIARY_LIST.get(-1);
@@ -163,11 +163,11 @@
     list.addFloat(2);
     list.addFloat(4);
 
-    assertEquals(2F, (float) list.set(0, 3F));
-    assertEquals(3F, list.getFloat(0));
+    assertEquals(2F, (float) list.set(0, 3F), 0.0f);
+    assertEquals(3F, list.getFloat(0), 0.0f);
 
-    assertEquals(4F, (float) list.set(1, 0F));
-    assertEquals(0F, list.getFloat(1));
+    assertEquals(4F, (float) list.set(1, 0F), 0.0f);
+    assertEquals(0F, list.getFloat(1), 0.0f);
 
     try {
       list.set(-1, 0F);
@@ -188,11 +188,11 @@
     list.addFloat(1);
     list.addFloat(3);
 
-    assertEquals(1F, list.setFloat(0, 0));
-    assertEquals(0F, list.getFloat(0));
+    assertEquals(1F, list.setFloat(0, 0), 0.0f);
+    assertEquals(0F, list.getFloat(0), 0.0f);
 
-    assertEquals(3F, list.setFloat(1, 0));
-    assertEquals(0F, list.getFloat(1));
+    assertEquals(3F, list.setFloat(1, 0), 0.0f);
+    assertEquals(0F, list.getFloat(1), 0.0f);
 
     try {
       list.setFloat(-1, 0);
@@ -257,8 +257,8 @@
 
     assertTrue(list.addAll(Collections.singleton(1F)));
     assertEquals(1, list.size());
-    assertEquals(1F, (float) list.get(0));
-    assertEquals(1F, list.getFloat(0));
+    assertEquals(1F, (float) list.get(0), 0.0f);
+    assertEquals(1F, list.getFloat(0), 0.0f);
 
     assertTrue(list.addAll(asList(2F, 3F, 4F, 5F, 6F)));
     assertEquals(asList(1F, 2F, 3F, 4F, 5F, 6F), list);
@@ -272,7 +272,7 @@
 
   public void testRemove() {
     list.addAll(TERTIARY_LIST);
-    assertEquals(1F, (float) list.remove(0));
+    assertEquals(1F, (float) list.remove(0), 0.0f);
     assertEquals(asList(2F, 3F), list);
 
     assertTrue(list.remove(Float.valueOf(3)));
@@ -281,7 +281,7 @@
     assertFalse(list.remove(Float.valueOf(3)));
     assertEquals(asList(2F), list);
 
-    assertEquals(2F, (float) list.remove(0));
+    assertEquals(2F, (float) list.remove(0), 0.0f);
     assertEquals(asList(), list);
 
     try {
@@ -299,20 +299,22 @@
   }
 
   public void testRemoveEndOfCapacity() {
-    FloatList toRemove = FloatArrayList.emptyList().mutableCopyWithCapacity(1);
+    FloatList toRemove =
+        FloatArrayList.emptyList().mutableCopyWithCapacity(1);
     toRemove.addFloat(3);
     toRemove.remove(0);
     assertEquals(0, toRemove.size());
   }
 
   public void testSublistRemoveEndOfCapacity() {
-    FloatList toRemove = FloatArrayList.emptyList().mutableCopyWithCapacity(1);
+    FloatList toRemove =
+        FloatArrayList.emptyList().mutableCopyWithCapacity(1);
     toRemove.addFloat(3);
     toRemove.subList(0, 1).clear();
     assertEquals(0, toRemove.size());
   }
 
-  private void assertImmutable(FloatArrayList list) {
+  private void assertImmutable(FloatList list) {
     if (list.contains(1F)) {
       throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
     }
diff --git a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
index 4021f5a..4489dac 100644
--- a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
+++ b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -591,8 +591,8 @@
   // Extensions.
 
   TestUtil.ReflectionTester extensionsReflectionTester =
-    new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
-                                  TestUtil.getExtensionRegistry());
+      new TestUtil.ReflectionTester(
+          TestAllExtensions.getDescriptor(), TestUtil.getFullExtensionRegistry());
 
   public void testExtensionMessageOrBuilder() throws Exception {
     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
diff --git a/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java b/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java
index d8e97d4..9edc434 100644
--- a/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java
@@ -299,20 +299,22 @@
   }
 
   public void testRemoveEndOfCapacity() {
-    IntList toRemove = IntArrayList.emptyList().mutableCopyWithCapacity(1);
+    IntList toRemove =
+        IntArrayList.emptyList().mutableCopyWithCapacity(1);
     toRemove.addInt(3);
     toRemove.remove(0);
     assertEquals(0, toRemove.size());
   }
 
   public void testSublistRemoveEndOfCapacity() {
-    IntList toRemove = IntArrayList.emptyList().mutableCopyWithCapacity(1);
+    IntList toRemove =
+        IntArrayList.emptyList().mutableCopyWithCapacity(1);
     toRemove.addInt(3);
     toRemove.subList(0, 1).clear();
     assertEquals(0, toRemove.size());
   }
 
-  private void assertImmutable(IntArrayList list) {
+  private void assertImmutable(IntList list) {
     if (list.contains(1)) {
       throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
     }
diff --git a/java/core/src/test/java/com/google/protobuf/LiteTest.java b/java/core/src/test/java/com/google/protobuf/LiteTest.java
index 5ab80ca..b20114e 100644
--- a/java/core/src/test/java/com/google/protobuf/LiteTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LiteTest.java
@@ -57,6 +57,8 @@
 import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOneof;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
 import java.lang.reflect.Field;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
@@ -2378,4 +2380,63 @@
     } catch (NullPointerException expected) {
     }
   }
+
+  public void testSerializeToOutputStreamThrowsIOException() {
+    try {
+      TestAllTypesLite.newBuilder()
+          .setOptionalBytes(ByteString.copyFromUtf8("hello"))
+          .build()
+          .writeTo(
+              new OutputStream() {
+
+                @Override
+                public void write(int b) throws IOException {
+                  throw new IOException();
+                }
+              });
+      fail();
+    } catch (IOException expected) {
+    }
+  }
+
+  public void testUnpairedSurrogatesReplacedByQuestionMark() throws InvalidProtocolBufferException {
+    String testString = "foo \ud83d bar";
+    String expectedString = "foo ? bar";
+
+    TestAllTypesLite testMessage =
+        TestAllTypesLite.newBuilder().setOptionalString(testString).build();
+    ByteString serializedMessage = testMessage.toByteString();
+
+    // Behavior is compatible with String.getBytes("UTF-8"), which replaces
+    // unpaired surrogates with a question mark.
+    TestAllTypesLite parsedMessage = TestAllTypesLite.parseFrom(serializedMessage);
+    assertEquals(expectedString, parsedMessage.getOptionalString());
+
+    // Conversion happens during serialization.
+    ByteString expectedBytes = ByteString.copyFromUtf8(expectedString);
+    assertTrue(
+        String.format(
+            "Expected serializedMessage (%s) to contain \"%s\" (%s).",
+            encodeHex(serializedMessage), expectedString, encodeHex(expectedBytes)),
+        contains(serializedMessage, expectedBytes));
+  }
+
+  private String encodeHex(ByteString bytes) {
+    String hexDigits = "0123456789abcdef";
+    StringBuilder stringBuilder = new StringBuilder(bytes.size() * 2);
+    for (byte b : bytes) {
+      stringBuilder.append(hexDigits.charAt((b & 0xf0) >> 4));
+      stringBuilder.append(hexDigits.charAt(b & 0x0f));
+    }
+    return stringBuilder.toString();
+  }
+
+  private boolean contains(ByteString a, ByteString b) {
+    for (int i = 0; i <= a.size() - b.size(); ++i) {
+      if (a.substring(i, i + b.size()).equals(b)) {
+        return true;
+      }
+    }
+    return false;
+  }
 }
diff --git a/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java b/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java
index e50c7d1..14a8e15 100644
--- a/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java
@@ -299,20 +299,22 @@
   }
 
   public void testRemoveEndOfCapacity() {
-    LongList toRemove = LongArrayList.emptyList().mutableCopyWithCapacity(1);
+    LongList toRemove =
+        LongArrayList.emptyList().mutableCopyWithCapacity(1);
     toRemove.addLong(3);
     toRemove.remove(0);
     assertEquals(0, toRemove.size());
   }
 
   public void testSublistRemoveEndOfCapacity() {
-    LongList toRemove = LongArrayList.emptyList().mutableCopyWithCapacity(1);
+    LongList toRemove =
+        LongArrayList.emptyList().mutableCopyWithCapacity(1);
     toRemove.addLong(3);
     toRemove.subList(0, 1).clear();
     assertEquals(0, toRemove.size());
   }
 
-  private void assertImmutable(LongArrayList list) {
+  private void assertImmutable(LongList list) {
     if (list.contains(1L)) {
       throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
     }
diff --git a/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java b/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java
index af717bf..0a2c3e3 100644
--- a/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java
@@ -42,33 +42,33 @@
  * Tests for {@link ProtobufArrayList}.
  */
 public class ProtobufArrayListTest extends TestCase {
-  
+
   private static final ProtobufArrayList<Integer> UNARY_LIST = newImmutableProtoArrayList(1);
   private static final ProtobufArrayList<Integer> TERTIARY_LIST =
       newImmutableProtoArrayList(1, 2, 3);
-  
+
   private ProtobufArrayList<Integer> list;
-  
+
   @Override
   protected void setUp() throws Exception {
     list = new ProtobufArrayList<Integer>();
   }
-  
+
   public void testEmptyListReturnsSameInstance() {
     assertSame(ProtobufArrayList.emptyList(), ProtobufArrayList.emptyList());
   }
-  
+
   public void testEmptyListIsImmutable() {
     assertImmutable(ProtobufArrayList.<Integer>emptyList());
   }
-  
+
   public void testModificationWithIteration() {
     list.addAll(asList(1, 2, 3, 4));
     Iterator<Integer> iterator = list.iterator();
     assertEquals(4, list.size());
     assertEquals(1, (int) list.get(0));
     assertEquals(1, (int) iterator.next());
-    
+
     list.remove(0);
     try {
       iterator.next();
@@ -76,7 +76,7 @@
     } catch (ConcurrentModificationException e) {
       // expected
     }
-    
+
     iterator = list.iterator();
     list.set(0, 1);
     try {
@@ -85,7 +85,7 @@
     } catch (ConcurrentModificationException e) {
       // expected
     }
-    
+
     iterator = list.iterator();
     list.add(0, 0);
     try {
@@ -95,7 +95,7 @@
       // expected
     }
   }
-  
+
   public void testMakeImmutable() {
     list.add(2);
     list.add(4);
@@ -104,107 +104,213 @@
     list.makeImmutable();
     assertImmutable(list);
   }
-  
+
   public void testRemove() {
-    list.add(2);
-    list.add(4);
-    list.add(6);
+    list.addAll(TERTIARY_LIST);
+    assertEquals(1, (int) list.remove(0));
+    assertEquals(asList(2, 3), list);
 
-    list.remove(1);
-    assertEquals(asList(2, 6), list);
-
-    list.remove(1);
+    assertTrue(list.remove(Integer.valueOf(3)));
     assertEquals(asList(2), list);
 
-    list.remove(0);
+    assertFalse(list.remove(Integer.valueOf(3)));
+    assertEquals(asList(2), list);
+
+    assertEquals(2, (int) list.remove(0));
     assertEquals(asList(), list);
+
+    try {
+      list.remove(-1);
+      fail();
+    } catch (IndexOutOfBoundsException e) {
+      // expected
+    }
+
+    try {
+      list.remove(0);
+    } catch (IndexOutOfBoundsException e) {
+      // expected
+    }
   }
-  
+
   public void testGet() {
-    list.add(2);
-    list.add(6);
-    
-    assertEquals(2, (int) list.get(0));
-    assertEquals(6, (int) list.get(1));
+    assertEquals(1, (int) TERTIARY_LIST.get(0));
+    assertEquals(2, (int) TERTIARY_LIST.get(1));
+    assertEquals(3, (int) TERTIARY_LIST.get(2));
+
+    try {
+      TERTIARY_LIST.get(-1);
+      fail();
+    } catch (IndexOutOfBoundsException e) {
+      // expected
+    }
+
+    try {
+      TERTIARY_LIST.get(3);
+      fail();
+    } catch (IndexOutOfBoundsException e) {
+      // expected
+    }
   }
-  
+
   public void testSet() {
     list.add(2);
-    list.add(6);
-    
-    list.set(0, 1);
+    list.add(4);
+
+    assertEquals(2, (int) list.set(0, 3));
+    assertEquals(3, (int) list.get(0));
+
+    assertEquals(4, (int) list.set(1, 0));
+    assertEquals(0, (int) list.get(1));
+
+    try {
+      list.set(-1, 0);
+      fail();
+    } catch (IndexOutOfBoundsException e) {
+      // expected
+    }
+
+    try {
+      list.set(2, 0);
+      fail();
+    } catch (IndexOutOfBoundsException e) {
+      // expected
+    }
+  }
+
+  public void testAdd() {
+    assertEquals(0, list.size());
+
+    assertTrue(list.add(2));
+    assertEquals(asList(2), list);
+
+    assertTrue(list.add(3));
+    list.add(0, 4);
+    assertEquals(asList(4, 2, 3), list);
+
+    list.add(0, 1);
+    list.add(0, 0);
+    // Force a resize by getting up to 11 elements.
+    for (int i = 0; i < 6; i++) {
+      list.add(Integer.valueOf(5 + i));
+    }
+    assertEquals(asList(0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10), list);
+
+    try {
+      list.add(-1, 5);
+    } catch (IndexOutOfBoundsException e) {
+      // expected
+    }
+
+    try {
+      list.add(4, 5);
+    } catch (IndexOutOfBoundsException e) {
+      // expected
+    }
+  }
+
+  public void testAddAll() {
+    assertEquals(0, list.size());
+
+    assertTrue(list.addAll(Collections.singleton(1)));
+    assertEquals(1, list.size());
     assertEquals(1, (int) list.get(0));
-    list.set(1, 2);
-    assertEquals(2, (int) list.get(1));
+
+    assertTrue(list.addAll(asList(2, 3, 4, 5, 6)));
+    assertEquals(asList(1, 2, 3, 4, 5, 6), list);
+
+    assertTrue(list.addAll(TERTIARY_LIST));
+    assertEquals(asList(1, 2, 3, 4, 5, 6, 1, 2, 3), list);
+
+    assertFalse(list.addAll(Collections.<Integer>emptyList()));
+    assertFalse(list.addAll(IntArrayList.emptyList()));
+  }
+
+  public void testSize() {
+    assertEquals(0, ProtobufArrayList.emptyList().size());
+    assertEquals(1, UNARY_LIST.size());
+    assertEquals(3, TERTIARY_LIST.size());
+
+    list.add(3);
+    list.add(4);
+    list.add(6);
+    list.add(8);
+    assertEquals(4, list.size());
+
+    list.remove(0);
+    assertEquals(3, list.size());
+
+    list.add(17);
+    assertEquals(4, list.size());
   }
 
   private void assertImmutable(List<Integer> list) {
     if (list.contains(1)) {
       throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
     }
-    
+
     try {
       list.add(1);
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.add(0, 1);
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.addAll(Collections.<Integer>emptyList());
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.addAll(Collections.singletonList(1));
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.addAll(new ProtobufArrayList<Integer>());
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.addAll(UNARY_LIST);
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.addAll(0, Collections.singleton(1));
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.addAll(0, UNARY_LIST);
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.addAll(0, Collections.<Integer>emptyList());
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
-    } 
+    }
 
     try {
       list.clear();
@@ -219,56 +325,56 @@
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.remove(new Object());
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.removeAll(Collections.emptyList());
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.removeAll(Collections.singleton(1));
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.removeAll(UNARY_LIST);
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.retainAll(Collections.emptyList());
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.retainAll(Collections.singleton(1));
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.retainAll(UNARY_LIST);
       fail();
     } catch (UnsupportedOperationException e) {
       // expected
     }
-    
+
     try {
       list.set(0, 0);
       fail();
@@ -276,7 +382,7 @@
       // expected
     }
   }
-  
+
   private static ProtobufArrayList<Integer> newImmutableProtoArrayList(int... elements) {
     ProtobufArrayList<Integer> list = new ProtobufArrayList<Integer>();
     for (int element : elements) {
diff --git a/java/core/src/test/java/com/google/protobuf/TestUtil.java b/java/core/src/test/java/com/google/protobuf/TestUtil.java
index b4bc3a3..8ec22d3 100644
--- a/java/core/src/test/java/com/google/protobuf/TestUtil.java
+++ b/java/core/src/test/java/com/google/protobuf/TestUtil.java
@@ -130,8 +130,6 @@
 import static protobuf_unittest.UnittestProto.defaultFloatExtension;
 import static protobuf_unittest.UnittestProto.defaultForeignEnumExtension;
 import static protobuf_unittest.UnittestProto.defaultImportEnumExtension;
-// The static imports are to avoid 100+ char lines.  The following is roughly equivalent to
-// import static protobuf_unittest.UnittestProto.*;
 import static protobuf_unittest.UnittestProto.defaultInt32Extension;
 import static protobuf_unittest.UnittestProto.defaultInt64Extension;
 import static protobuf_unittest.UnittestProto.defaultNestedEnumExtension;
@@ -263,12 +261,14 @@
     return ByteString.copyFrom(str.getBytes(Internal.UTF_8));
   }
 
+  // BEGIN FULL-RUNTIME
   /**
    * Dirties the message by resetting the momoized serialized size.
    */
   public static void resetMemoizedSize(AbstractMessage message) {
     message.memoizedSize = -1;
   }
+  // END FULL-RUNTIME
 
   /**
    * Get a {@code TestAllTypes} with all fields set as they would be by
@@ -1201,17 +1201,29 @@
    * Get an unmodifiable {@link ExtensionRegistry} containing all the
    * extensions of {@code TestAllExtensions}.
    */
-  public static ExtensionRegistry getExtensionRegistry() {
+  public static ExtensionRegistryLite getExtensionRegistry() {
+    ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
+    registerAllExtensions(registry);
+    return registry.getUnmodifiable();
+  }
+
+  // BEGIN FULL-RUNTIME
+  /**
+   * Get an unmodifiable {@link ExtensionRegistry} containing all the
+   * extensions of {@code TestAllExtensions}.
+   */
+  public static ExtensionRegistry getFullExtensionRegistry() {
     ExtensionRegistry registry = ExtensionRegistry.newInstance();
     registerAllExtensions(registry);
     return registry.getUnmodifiable();
   }
+  // END FULL-RUNTIME
 
   /**
    * Register all of {@code TestAllExtensions}'s extensions with the
    * given {@link ExtensionRegistry}.
    */
-  public static void registerAllExtensions(ExtensionRegistry registry) {
+  public static void registerAllExtensions(ExtensionRegistryLite registry) {
     UnittestProto.registerAllExtensions(registry);
     TestUtilLite.registerAllExtensionsLite(registry);
   }
@@ -2634,6 +2646,7 @@
   }
 
   // =================================================================
+  // BEGIN FULL-RUNTIME
 
   /**
    * Performs the same things that the methods of {@code TestUtil} do, but
@@ -3819,6 +3832,16 @@
         "Couldn't read file: " + fullPath.getPath(), e);
     }
   }
+  // END FULL-RUNTIME
+
+  private static ByteString readBytesFromResource(String name) {
+    try {
+      return ByteString.copyFrom(
+          com.google.common.io.ByteStreams.toByteArray(TestUtil.class.getResourceAsStream(name)));
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+  }
 
   /**
    * Get the bytes of the "golden message".  This is a serialized TestAllTypes
@@ -3829,7 +3852,7 @@
    */
   public static ByteString getGoldenMessage() {
     if (goldenMessage == null) {
-      goldenMessage = readBytesFromFile("golden_message_oneof_implemented");
+      goldenMessage = readBytesFromResource("/google/protobuf/testdata/golden_message_oneof_implemented");
     }
     return goldenMessage;
   }
@@ -3846,12 +3869,13 @@
   public static ByteString getGoldenPackedFieldsMessage() {
     if (goldenPackedFieldsMessage == null) {
       goldenPackedFieldsMessage =
-          readBytesFromFile("golden_packed_fields_message");
+          readBytesFromResource("/google/protobuf/testdata/golden_packed_fields_message");
     }
     return goldenPackedFieldsMessage;
   }
   private static ByteString goldenPackedFieldsMessage = null;
 
+  // BEGIN FULL-RUNTIME
   /**
    * Mock implementation of {@link GeneratedMessage.BuilderParent} for testing.
    *
@@ -3871,4 +3895,5 @@
       return invalidations;
     }
   }
+  // END FULL-RUNTIME
 }
diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
index 720061d..24d5589 100644
--- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
+++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
@@ -382,17 +382,14 @@
 
   public void testMergeExtensions() throws Exception {
     TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
-    TextFormat.merge(allExtensionsSetText,
-                     TestUtil.getExtensionRegistry(),
-                     builder);
+    TextFormat.merge(allExtensionsSetText, TestUtil.getFullExtensionRegistry(), builder);
     TestUtil.assertAllExtensionsSet(builder.build());
   }
 
   public void testParseExtensions() throws Exception {
     TestUtil.assertAllExtensionsSet(
-        TextFormat.parse(allExtensionsSetText,
-                         TestUtil.getExtensionRegistry(),
-                         TestAllExtensions.class));
+        TextFormat.parse(
+            allExtensionsSetText, TestUtil.getFullExtensionRegistry(), TestAllExtensions.class));
   }
 
   public void testMergeAndParseCompatibility() throws Exception {
@@ -523,7 +520,7 @@
     // Test merge().
     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
     try {
-      TextFormat.merge(text, TestUtil.getExtensionRegistry(), builder);
+      TextFormat.merge(text, TestUtil.getFullExtensionRegistry(), builder);
       fail("Expected parse exception.");
     } catch (TextFormat.ParseException e) {
       assertEquals(error, e.getMessage());
@@ -531,8 +528,7 @@
 
     // Test parse().
     try {
-      TextFormat.parse(
-          text, TestUtil.getExtensionRegistry(), TestAllTypes.class);
+      TextFormat.parse(text, TestUtil.getFullExtensionRegistry(), TestAllTypes.class);
       fail("Expected parse exception.");
     } catch (TextFormat.ParseException e) {
       assertEquals(error, e.getMessage());
@@ -544,8 +540,7 @@
       String text) {
     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
     try {
-      parserWithOverwriteForbidden.merge(
-          text, TestUtil.getExtensionRegistry(), builder);
+      parserWithOverwriteForbidden.merge(text, TestUtil.getFullExtensionRegistry(), builder);
       fail("Expected parse exception.");
     } catch (TextFormat.ParseException e) {
       assertEquals(error, e.getMessage());
@@ -555,8 +550,7 @@
   private TestAllTypes assertParseSuccessWithOverwriteForbidden(
       String text) throws TextFormat.ParseException {
     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
-    parserWithOverwriteForbidden.merge(
-        text, TestUtil.getExtensionRegistry(), builder);
+    parserWithOverwriteForbidden.merge(text, TestUtil.getFullExtensionRegistry(), builder);
     return builder.build();
   }
 
@@ -1118,8 +1112,7 @@
     String input = "foo_string: \"stringvalue\" foo_int: 123";
     TestOneof2.Builder builder = TestOneof2.newBuilder();
     try {
-      parserWithOverwriteForbidden.merge(
-          input, TestUtil.getExtensionRegistry(), builder);
+      parserWithOverwriteForbidden.merge(input, TestUtil.getFullExtensionRegistry(), builder);
       fail("Expected parse exception.");
     } catch (TextFormat.ParseException e) {
       assertEquals("1:36: Field \"protobuf_unittest.TestOneof2.foo_int\""
@@ -1131,7 +1124,7 @@
   public void testOneofOverwriteAllowed() throws Exception {
     String input = "foo_string: \"stringvalue\" foo_int: 123";
     TestOneof2.Builder builder = TestOneof2.newBuilder();
-    defaultParser.merge(input, TestUtil.getExtensionRegistry(), builder);
+    defaultParser.merge(input, TestUtil.getFullExtensionRegistry(), builder);
     // Only the last value sticks.
     TestOneof2 oneof = builder.build();
     assertFalse(oneof.hasFooString());
diff --git a/java/core/src/test/java/com/google/protobuf/WireFormatTest.java b/java/core/src/test/java/com/google/protobuf/WireFormatTest.java
index 03c33ec..425b56d 100644
--- a/java/core/src/test/java/com/google/protobuf/WireFormatTest.java
+++ b/java/core/src/test/java/com/google/protobuf/WireFormatTest.java
@@ -132,7 +132,7 @@
     TestAllTypes message = TestUtil.getAllSet();
     ByteString rawBytes = message.toByteString();
 
-    ExtensionRegistry registry = TestUtil.getExtensionRegistry();
+    ExtensionRegistryLite registry = TestUtil.getExtensionRegistry();
 
     TestAllExtensions message2 =
       TestAllExtensions.parseFrom(rawBytes, registry);
@@ -145,7 +145,7 @@
     TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
     ByteString rawBytes = message.toByteString();
 
-    ExtensionRegistry registry = TestUtil.getExtensionRegistry();
+    ExtensionRegistryLite registry = TestUtil.getExtensionRegistry();
 
     TestPackedExtensions message2 =
         TestPackedExtensions.parseFrom(rawBytes, registry);
diff --git a/java/core/src/test/proto/com/google/protobuf/lazy_fields_lite.proto b/java/core/src/test/proto/com/google/protobuf/lazy_fields_lite.proto
index 5580f72..736a344 100644
--- a/java/core/src/test/proto/com/google/protobuf/lazy_fields_lite.proto
+++ b/java/core/src/test/proto/com/google/protobuf/lazy_fields_lite.proto
@@ -36,8 +36,6 @@
 
 package protobuf_unittest;
 
-option optimize_for = LITE_RUNTIME;
-
 message LazyMessageLite {
   optional int32 num = 1;
   optional int32 num_with_default = 2 [default = 421];
diff --git a/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto b/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto
index b18b0d7..20fa03b 100644
--- a/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto
+++ b/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto
@@ -34,7 +34,6 @@
 
 package protobuf_unittest.lite_equals_and_hash;
 
-option optimize_for = LITE_RUNTIME;
 
 message TestOneofEquals {
   oneof oneof_field {
diff --git a/java/util/src/main/java/com/google/protobuf/util/Durations.java b/java/util/src/main/java/com/google/protobuf/util/Durations.java
index fb7f434..17b41cb 100644
--- a/java/util/src/main/java/com/google/protobuf/util/Durations.java
+++ b/java/util/src/main/java/com/google/protobuf/util/Durations.java
@@ -61,6 +61,9 @@
   public static final Duration MAX_VALUE =
       Duration.newBuilder().setSeconds(DURATION_SECONDS_MAX).setNanos(999999999).build();
 
+  /** A constant holding the duration of zero. */
+  public static final Duration ZERO = Duration.newBuilder().setSeconds(0L).setNanos(0).build();
+
   private Durations() {}
 
   private static final Comparator<Duration> COMPARATOR =
diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
index 429579f..86f56ad 100644
--- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
+++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
@@ -249,12 +249,9 @@
           continue;
         }
         String childPath = path.isEmpty() ? entry.getKey() : path + "." + entry.getKey();
-        merge(
-            entry.getValue(),
-            childPath,
-            (Message) source.getField(field),
-            destination.getFieldBuilder(field),
-            options);
+        Message.Builder childBuilder = ((Message) destination.getField(field)).toBuilder();
+        merge(entry.getValue(), childPath, (Message) source.getField(field), childBuilder, options);
+        destination.setField(field, childBuilder.buildPartial());
         continue;
       }
       if (field.isRepeated()) {
@@ -275,7 +272,12 @@
             }
           } else {
             if (source.hasField(field)) {
-              destination.getFieldBuilder(field).mergeFrom((Message) source.getField(field));
+              destination.setField(
+                  field,
+                  ((Message) destination.getField(field))
+                      .toBuilder()
+                      .mergeFrom((Message) source.getField(field))
+                      .build());
             }
           }
         } else {
diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java
index b2f849c..aedc5ea 100644
--- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java
+++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java
@@ -235,7 +235,7 @@
   /**
    * Converts a FieldMask to its canonical form. In the canonical form of a
    * FieldMask, all field paths are sorted alphabetically and redundant field
-   * paths are moved.
+   * paths are removed.
    */
   public static FieldMask normalize(FieldMask mask) {
     return new FieldMaskTree(mask).toFieldMask();
diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
index a1e2d9c..955dfd8 100644
--- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
+++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java
@@ -611,7 +611,7 @@
     private final CharSequence blankOrNewLine;
 
     private static class GsonHolder {
-      private static final Gson DEFAULT_GSON = new GsonBuilder().disableHtmlEscaping().create();
+      private static final Gson DEFAULT_GSON = new GsonBuilder().create();
     }
 
     PrinterImpl(
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 853b615..a0d317d 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
@@ -30,9 +30,14 @@
 
 package com.google.protobuf.util;
 
+import com.google.protobuf.DynamicMessage;
+import com.google.protobuf.Message;
+import com.google.protobuf.UninitializedMessageException;
 import protobuf_unittest.UnittestProto.NestedTestAllTypes;
 import protobuf_unittest.UnittestProto.TestAllTypes;
 import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
+import protobuf_unittest.UnittestProto.TestRequired;
+import protobuf_unittest.UnittestProto.TestRequiredMessage;
 import junit.framework.TestCase;
 
 public class FieldMaskTreeTest extends TestCase {
@@ -90,8 +95,68 @@
     tree.intersectFieldPath("bar", result);
     assertEquals("bar.baz,bar.quz,foo", result.toString());
   }
-
+  
   public void testMerge() throws Exception {
+    testMergeImpl(true);
+    testMergeImpl(false);
+    testMergeRequire(false);
+    testMergeRequire(true);
+  }
+
+  private void merge(
+      FieldMaskTree tree,
+      Message source,
+      Message.Builder builder,
+      FieldMaskUtil.MergeOptions options,
+      boolean useDynamicMessage)
+      throws Exception {
+    if (useDynamicMessage) {
+      Message.Builder newBuilder =
+          DynamicMessage.newBuilder(source.getDescriptorForType())
+              .mergeFrom(builder.buildPartial().toByteArray());
+      tree.merge(
+          DynamicMessage.newBuilder(source.getDescriptorForType())
+              .mergeFrom(source.toByteArray())
+              .build(),
+          newBuilder,
+          options);
+      builder.clear();
+      builder.mergeFrom(newBuilder.buildPartial());
+    } else {
+      tree.merge(source, builder, options);
+    }
+  }
+
+  private void testMergeRequire(boolean useDynamicMessage) throws Exception {
+    TestRequired value = TestRequired.newBuilder().setA(4321).setB(8765).setC(233333).build();
+    TestRequiredMessage source = TestRequiredMessage.newBuilder().setRequiredMessage(value).build();
+
+    FieldMaskUtil.MergeOptions options = new FieldMaskUtil.MergeOptions();
+    TestRequiredMessage.Builder builder = TestRequiredMessage.newBuilder();
+    merge(
+        new FieldMaskTree().addFieldPath("required_message.a"),
+        source,
+        builder,
+        options,
+        useDynamicMessage);
+    assertTrue(builder.hasRequiredMessage());
+    assertTrue(builder.getRequiredMessage().hasA());
+    assertFalse(builder.getRequiredMessage().hasB());
+    assertFalse(builder.getRequiredMessage().hasC());
+    merge(
+        new FieldMaskTree().addFieldPath("required_message.b").addFieldPath("required_message.c"),
+        source,
+        builder,
+        options,
+        useDynamicMessage);
+    try {
+      assertEquals(builder.build(), source);
+    } catch (UninitializedMessageException e) {
+      throw new AssertionError("required field isn't set", e);
+    }
+  }
+
+  private void testMergeImpl(boolean useDynamicMessage) throws Exception {
     TestAllTypes value =
         TestAllTypes.newBuilder()
             .setOptionalInt32(1234)
@@ -119,45 +184,51 @@
 
     // Test merging each individual field.
     NestedTestAllTypes.Builder builder = NestedTestAllTypes.newBuilder();
-    new FieldMaskTree().addFieldPath("payload.optional_int32").merge(source, builder, options);
+    merge(new FieldMaskTree().addFieldPath("payload.optional_int32"),
+        source, builder, options, useDynamicMessage);
     NestedTestAllTypes.Builder expected = NestedTestAllTypes.newBuilder();
     expected.getPayloadBuilder().setOptionalInt32(1234);
     assertEquals(expected.build(), builder.build());
 
     builder = NestedTestAllTypes.newBuilder();
-    new FieldMaskTree()
-        .addFieldPath("payload.optional_nested_message")
-        .merge(source, builder, options);
+    merge(new FieldMaskTree().addFieldPath("payload.optional_nested_message"),
+        source, builder, options, useDynamicMessage);
     expected = NestedTestAllTypes.newBuilder();
     expected.getPayloadBuilder().setOptionalNestedMessage(NestedMessage.newBuilder().setBb(5678));
     assertEquals(expected.build(), builder.build());
 
     builder = NestedTestAllTypes.newBuilder();
-    new FieldMaskTree().addFieldPath("payload.repeated_int32").merge(source, builder, options);
+    merge(new FieldMaskTree().addFieldPath("payload.repeated_int32"),
+        source, builder, options, useDynamicMessage);
     expected = NestedTestAllTypes.newBuilder();
     expected.getPayloadBuilder().addRepeatedInt32(4321);
     assertEquals(expected.build(), builder.build());
 
     builder = NestedTestAllTypes.newBuilder();
-    new FieldMaskTree()
-        .addFieldPath("payload.repeated_nested_message")
-        .merge(source, builder, options);
+    merge(new FieldMaskTree().addFieldPath("payload.repeated_nested_message"),
+        source, builder, options, useDynamicMessage);
     expected = NestedTestAllTypes.newBuilder();
     expected.getPayloadBuilder().addRepeatedNestedMessage(NestedMessage.newBuilder().setBb(8765));
     assertEquals(expected.build(), builder.build());
 
     builder = NestedTestAllTypes.newBuilder();
-    new FieldMaskTree()
-        .addFieldPath("child.payload.optional_int32")
-        .merge(source, builder, options);
+    merge(
+        new FieldMaskTree().addFieldPath("child.payload.optional_int32"),
+        source,
+        builder,
+        options,
+        useDynamicMessage);
     expected = NestedTestAllTypes.newBuilder();
     expected.getChildBuilder().getPayloadBuilder().setOptionalInt32(1234);
     assertEquals(expected.build(), builder.build());
 
     builder = NestedTestAllTypes.newBuilder();
-    new FieldMaskTree()
-        .addFieldPath("child.payload.optional_nested_message")
-        .merge(source, builder, options);
+    merge(
+        new FieldMaskTree().addFieldPath("child.payload.optional_nested_message"),
+        source,
+        builder,
+        options,
+        useDynamicMessage);
     expected = NestedTestAllTypes.newBuilder();
     expected
         .getChildBuilder()
@@ -166,17 +237,15 @@
     assertEquals(expected.build(), builder.build());
 
     builder = NestedTestAllTypes.newBuilder();
-    new FieldMaskTree()
-        .addFieldPath("child.payload.repeated_int32")
-        .merge(source, builder, options);
+    merge(new FieldMaskTree().addFieldPath("child.payload.repeated_int32"),
+        source, builder, options, useDynamicMessage);
     expected = NestedTestAllTypes.newBuilder();
     expected.getChildBuilder().getPayloadBuilder().addRepeatedInt32(4321);
     assertEquals(expected.build(), builder.build());
 
     builder = NestedTestAllTypes.newBuilder();
-    new FieldMaskTree()
-        .addFieldPath("child.payload.repeated_nested_message")
-        .merge(source, builder, options);
+    merge(new FieldMaskTree().addFieldPath("child.payload.repeated_nested_message"),
+        source, builder, options, useDynamicMessage);
     expected = NestedTestAllTypes.newBuilder();
     expected
         .getChildBuilder()
@@ -186,23 +255,23 @@
 
     // Test merging all fields.
     builder = NestedTestAllTypes.newBuilder();
-    new FieldMaskTree()
-        .addFieldPath("child")
-        .addFieldPath("payload")
-        .merge(source, builder, options);
+    merge(new FieldMaskTree().addFieldPath("child").addFieldPath("payload"),
+        source, builder, options, useDynamicMessage);
     assertEquals(source, builder.build());
 
     // Test repeated options.
     builder = NestedTestAllTypes.newBuilder();
     builder.getPayloadBuilder().addRepeatedInt32(1000);
-    new FieldMaskTree().addFieldPath("payload.repeated_int32").merge(source, builder, options);
+    merge(new FieldMaskTree().addFieldPath("payload.repeated_int32"),
+        source, builder, options, useDynamicMessage);
     // Default behavior is to append repeated fields.
     assertEquals(2, builder.getPayload().getRepeatedInt32Count());
     assertEquals(1000, builder.getPayload().getRepeatedInt32(0));
     assertEquals(4321, builder.getPayload().getRepeatedInt32(1));
     // Change to replace repeated fields.
     options.setReplaceRepeatedFields(true);
-    new FieldMaskTree().addFieldPath("payload.repeated_int32").merge(source, builder, options);
+    merge(new FieldMaskTree().addFieldPath("payload.repeated_int32"),
+        source, builder, options, useDynamicMessage);
     assertEquals(1, builder.getPayload().getRepeatedInt32Count());
     assertEquals(4321, builder.getPayload().getRepeatedInt32(0));
 
@@ -210,7 +279,8 @@
     builder = NestedTestAllTypes.newBuilder();
     builder.getPayloadBuilder().setOptionalInt32(1000);
     builder.getPayloadBuilder().setOptionalUint32(2000);
-    new FieldMaskTree().addFieldPath("payload").merge(source, builder, options);
+    merge(new FieldMaskTree().addFieldPath("payload"),
+        source, builder, options, useDynamicMessage);
     // Default behavior is to merge message fields.
     assertEquals(1234, builder.getPayload().getOptionalInt32());
     assertEquals(2000, builder.getPayload().getOptionalUint32());
@@ -218,14 +288,14 @@
     // Test merging unset message fields.
     NestedTestAllTypes clearedSource = source.toBuilder().clearPayload().build();
     builder = NestedTestAllTypes.newBuilder();
-    new FieldMaskTree().addFieldPath("payload").merge(clearedSource, builder, options);
+    merge(new FieldMaskTree().addFieldPath("payload"),
+        clearedSource, builder, options, useDynamicMessage);
     assertEquals(false, builder.hasPayload());
 
     // Skip a message field if they are unset in both source and target.
     builder = NestedTestAllTypes.newBuilder();
-    new FieldMaskTree()
-        .addFieldPath("payload.optional_int32")
-        .merge(clearedSource, builder, options);
+    merge(new FieldMaskTree().addFieldPath("payload.optional_int32"),
+        clearedSource, builder, options, useDynamicMessage);
     assertEquals(false, builder.hasPayload());
 
     // Change to replace message fields.
@@ -233,7 +303,8 @@
     builder = NestedTestAllTypes.newBuilder();
     builder.getPayloadBuilder().setOptionalInt32(1000);
     builder.getPayloadBuilder().setOptionalUint32(2000);
-    new FieldMaskTree().addFieldPath("payload").merge(source, builder, options);
+    merge(new FieldMaskTree().addFieldPath("payload"),
+        source, builder, options, useDynamicMessage);
     assertEquals(1234, builder.getPayload().getOptionalInt32());
     assertEquals(0, builder.getPayload().getOptionalUint32());
 
@@ -241,7 +312,8 @@
     builder = NestedTestAllTypes.newBuilder();
     builder.getPayloadBuilder().setOptionalInt32(1000);
     builder.getPayloadBuilder().setOptionalUint32(2000);
-    new FieldMaskTree().addFieldPath("payload").merge(clearedSource, builder, options);
+    merge(new FieldMaskTree().addFieldPath("payload"),
+        clearedSource, builder, options, useDynamicMessage);
     assertEquals(false, builder.hasPayload());
 
     // Test merging unset primitive fields.
@@ -249,18 +321,16 @@
     builder.getPayloadBuilder().clearOptionalInt32();
     NestedTestAllTypes sourceWithPayloadInt32Unset = builder.build();
     builder = source.toBuilder();
-    new FieldMaskTree()
-        .addFieldPath("payload.optional_int32")
-        .merge(sourceWithPayloadInt32Unset, builder, options);
+    merge(new FieldMaskTree().addFieldPath("payload.optional_int32"),
+        sourceWithPayloadInt32Unset, builder, options, useDynamicMessage);
     assertEquals(true, builder.getPayload().hasOptionalInt32());
     assertEquals(0, builder.getPayload().getOptionalInt32());
 
     // Change to clear unset primitive fields.
     options.setReplacePrimitiveFields(true);
     builder = source.toBuilder();
-    new FieldMaskTree()
-        .addFieldPath("payload.optional_int32")
-        .merge(sourceWithPayloadInt32Unset, builder, options);
+    merge(new FieldMaskTree().addFieldPath("payload.optional_int32"),
+        sourceWithPayloadInt32Unset, builder, options, useDynamicMessage);
     assertEquals(true, builder.hasPayload());
     assertEquals(false, builder.getPayload().hasOptionalInt32());
   }
diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
index ede8de7..7637c26 100644
--- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
@@ -1236,10 +1236,14 @@
     assertRoundTripEquals(message);
   }
 
-  public void testDefaultGsonDoesNotHtmlEscape() throws Exception {
-    TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("=").build();
-    assertEquals(
-        "{\n" + "  \"optionalString\": \"=\"" + "\n}", JsonFormat.printer().print(message));
+  // Regression test for b/73832901. Make sure html tags are escaped.
+  public void testHtmlEscape() throws Exception {
+    TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("</script>").build();
+    assertEquals("{\n  \"optionalString\": \"\\u003c/script\\u003e\"\n}", toJsonString(message));
+
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    JsonFormat.parser().merge(toJsonString(message), builder);
+    assertEquals(message.getOptionalString(), builder.getOptionalString());
   }
 
   public void testIncludingDefaultValueFields() throws Exception {
diff --git a/js/binary/constants.js b/js/binary/constants.js
index 21c5889..5c53a36 100644
--- a/js/binary/constants.js
+++ b/js/binary/constants.js
@@ -174,7 +174,7 @@
 
 /**
  * A comparer function returns true if two protos are equal.
- * @typedef {!function(?jspb.ConstBinaryMessage,
+ * @typedef {function(?jspb.ConstBinaryMessage,
  *                     ?jspb.ConstBinaryMessage):boolean}
  */
 jspb.ComparerFunction;
diff --git a/js/binary/reader.js b/js/binary/reader.js
index cf80830..731587c 100644
--- a/js/binary/reader.js
+++ b/js/binary/reader.js
@@ -290,7 +290,9 @@
       nextWireType != jspb.BinaryConstants.WireType.DELIMITED &&
       nextWireType != jspb.BinaryConstants.WireType.START_GROUP &&
       nextWireType != jspb.BinaryConstants.WireType.END_GROUP) {
-    goog.asserts.fail('Invalid wire type');
+    goog.asserts.fail(
+        'Invalid wire type: %s (at position %s)', nextWireType,
+        this.fieldCursor_);
     this.error_ = true;
     return false;
   }
diff --git a/js/binary/reader_test.js b/js/binary/reader_test.js
index 6973972..eb2af0a 100644
--- a/js/binary/reader_test.js
+++ b/js/binary/reader_test.js
@@ -679,17 +679,17 @@
     writer.writeInt32(5, sentinel);
     var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
     writer.writeGroup(5, dummyMessage, function() {
-      // Previously the skipGroup implementation was wrong, which only consume 
-      // the decoder by nextField. This case is for making the previous 
+      // Previously the skipGroup implementation was wrong, which only consume
+      // the decoder by nextField. This case is for making the previous
       // implementation failed in skipGroup by an early end group tag.
-      // The reason is 44 = 5 * 8 + 4, this will be translated in to a field 
+      // The reason is 44 = 5 * 8 + 4, this will be translated in to a field
       // with number 5 and with type 4 (end group)
       writer.writeInt64(44, 44);
       // This will make previous implementation failed by invalid tag (7).
       writer.writeInt64(42, 47);
       writer.writeInt64(42, 42);
-      // This is for making the previous implementation failed by an invalid 
-      // varint. The bytes have at least 9 consecutive minus byte, which will 
+      // This is for making the previous implementation failed by an invalid
+      // varint. The bytes have at least 9 consecutive minus byte, which will
       // fail in this.nextField for previous implementation.
       writer.writeBytes(43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]);
       writer.writeGroup(6, dummyMessage, function() {
diff --git a/js/binary/utils.js b/js/binary/utils.js
index 55a9ccd..173c416 100644
--- a/js/binary/utils.js
+++ b/js/binary/utils.js
@@ -971,8 +971,9 @@
     return /** @type {!Uint8Array} */(new Uint8Array(data));
   }
 
-  if (data.constructor === Buffer) {
-    return /** @type {!Uint8Array} */(new Uint8Array(data));
+  if (typeof Buffer != 'undefined' && data.constructor === Buffer) {
+    return /** @type {!Uint8Array} */ (
+        new Uint8Array(/** @type {?} */ (data)));
   }
 
   if (data.constructor === Array) {
diff --git a/js/map.js b/js/map.js
index 2fb1483..671bd51 100644
--- a/js/map.js
+++ b/js/map.js
@@ -136,7 +136,7 @@
  *
  * @param {boolean=} includeInstance Whether to include the JSPB instance for
  *    transitional soy proto support: http://goto/soy-param-migration
- * @param {!function((boolean|undefined),V):!Object=} valueToObject
+ * @param {function((boolean|undefined),V):!Object=} valueToObject
  *    The static toObject() method, if V is a message type.
  * @return {!Array<!Array<!Object>>}
  */
@@ -165,9 +165,9 @@
  *
  * @template K, V
  * @param {!Array<!Array<!Object>>} entries
- * @param {!function(new:V,?=)} valueCtor
+ * @param {function(new:V,?=)} valueCtor
  *    The constructor for type V.
- * @param {!function(!Object):V} valueFromObject
+ * @param {function(!Object):V} valueFromObject
  *    The fromObject function for type V.
  * @return {!jspb.Map<K, V>}
  */
@@ -410,9 +410,9 @@
  * number.
  * @param {number} fieldNumber
  * @param {!jspb.BinaryWriter} writer
- * @param {!function(this:jspb.BinaryWriter,number,K)} keyWriterFn
+ * @param {function(this:jspb.BinaryWriter,number,K)} keyWriterFn
  *     The method on BinaryWriter that writes type K to the stream.
- * @param {!function(this:jspb.BinaryWriter,number,V,?=)|
+ * @param {function(this:jspb.BinaryWriter,number,V,?=)|
  *          function(this:jspb.BinaryWriter,number,V,?)} valueWriterFn
  *     The method on BinaryWriter that writes type V to the stream.  May be
  *     writeMessage, in which case the second callback arg form is used.
@@ -448,10 +448,10 @@
  * @template K, V
  * @param {!jspb.Map} map
  * @param {!jspb.BinaryReader} reader
- * @param {!function(this:jspb.BinaryReader):K} keyReaderFn
+ * @param {function(this:jspb.BinaryReader):K} keyReaderFn
  *     The method on BinaryReader that reads type K from the stream.
  *
- * @param {!function(this:jspb.BinaryReader):V|
+ * @param {function(this:jspb.BinaryReader):V|
  *          function(this:jspb.BinaryReader,V,
  *                  function(V,!jspb.BinaryReader))} valueReaderFn
  *    The method on BinaryReader that reads type V from the stream. May be
diff --git a/js/message.js b/js/message.js
index 86d1829..6a37745 100644
--- a/js/message.js
+++ b/js/message.js
@@ -439,9 +439,19 @@
  * @private
  */
 jspb.Message.initPivotAndExtensionObject_ = function(msg, suggestedPivot) {
-  if (msg.array.length) {
-    var foundIndex = msg.array.length - 1;
-    var obj = msg.array[foundIndex];
+  // There are 3 variants that need to be dealt with which are the
+  // combination of whether there exists an extension object (EO) and
+  // whether there is a suggested pivot (SP).
+  //
+  // EO,    ?    : pivot is the index of the EO
+  // no-EO, no-SP: pivot is MAX_INT
+  // no-EO, SP   : pivot is the max(lastindex + 1, SP)
+
+  var msgLength = msg.array.length;
+  var lastIndex = -1;
+  if (msgLength) {
+    lastIndex = msgLength - 1;
+    var obj = msg.array[lastIndex];
     // Normal fields are never objects, so we can be sure that if we find an
     // object here, then it's the extension object. However, we must ensure that
     // the object is not an array, since arrays are valid field values.
@@ -449,14 +459,17 @@
     // in Safari on iOS 8. See the description of CL/86511464 for details.
     if (obj && typeof obj == 'object' && !jspb.Message.isArray_(obj) &&
         !(jspb.Message.SUPPORTS_UINT8ARRAY_ && obj instanceof Uint8Array)) {
-      msg.pivot_ = jspb.Message.getFieldNumber_(msg, foundIndex);
+      msg.pivot_ = jspb.Message.getFieldNumber_(msg, lastIndex);
       msg.extensionObject_ = obj;
       return;
     }
   }
 
   if (suggestedPivot > -1) {
-    msg.pivot_ = suggestedPivot;
+    // If a extension object is not present, set the pivot value as being
+    // after the last value in the array to avoid overwriting values, etc.
+    msg.pivot_ = Math.max(
+        suggestedPivot, jspb.Message.getFieldNumber_(msg, lastIndex + 1));
     // Avoid changing the shape of the proto with an empty extension object by
     // deferring the materialization of the extension object until the first
     // time a field set into it (may be due to getting a repeated proto field
@@ -923,17 +936,6 @@
 
 
 /**
- * Sets the value of a non-extension integer, handled as string, field of a proto3
- * @param {!jspb.Message} msg A jspb proto.
- * @param {number} fieldNumber The field number.
- * @param {number} value New value
- * @protected
- */
-jspb.Message.setProto3StringIntField = function(msg, fieldNumber, value) {
-  jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, '0');
-};
-
-/**
  * Sets the value of a non-extension floating point field of a proto3
  * @param {!jspb.Message} msg A jspb proto.
  * @param {number} fieldNumber The field number.
@@ -993,12 +995,22 @@
 };
 
 
+/**
+ * Sets the value of a non-extension int field of a proto3 that has jstype set
+ * to String.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {string} value New value
+ * @protected
+ */
+jspb.Message.setProto3StringIntField = function(msg, fieldNumber, value) {
+  jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, "0");
+};
 
 /**
  * Sets the value of a non-extension primitive field, with proto3 (non-nullable
  * primitives) semantics of ignoring values that are equal to the type's
  * default.
- * @template T
  * @param {!jspb.Message} msg A jspb proto.
  * @param {number} fieldNumber The field number.
  * @param {!Uint8Array|string|number|boolean|undefined} value New value
@@ -1007,7 +1019,7 @@
  */
 jspb.Message.setFieldIgnoringDefault_ = function(
     msg, fieldNumber, value, defaultValue) {
-  if (value != defaultValue) {
+  if (value !== defaultValue) {
     jspb.Message.setField(msg, fieldNumber, value);
   } else {
     msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = null;
@@ -1127,7 +1139,7 @@
  * @param {!jspb.Message} msg A jspb proto.
  * @param {function(new:jspb.Message, Array)} ctor Constructor for the field.
  * @param {number} fieldNumber The field number.
- * @return {Array<!jspb.Message>} The repeated field as an array of protos.
+ * @return {!Array<!jspb.Message>} The repeated field as an array of protos.
  * @protected
  */
 jspb.Message.getRepeatedWrapperField = function(msg, ctor, fieldNumber) {
diff --git a/js/message_test.js b/js/message_test.js
index 1be4109..2bfec62 100644
--- a/js/message_test.js
+++ b/js/message_test.js
@@ -73,6 +73,7 @@
 goog.require('proto.jspb.test.Simple2');
 goog.require('proto.jspb.test.SpecialCases');
 goog.require('proto.jspb.test.TestClone');
+goog.require('proto.jspb.test.TestCloneExtension');
 goog.require('proto.jspb.test.TestEndsWithBytes');
 goog.require('proto.jspb.test.TestGroup');
 goog.require('proto.jspb.test.TestGroup1');
diff --git a/js/test.proto b/js/test.proto
index 7c881c0..3b538b5 100644
--- a/js/test.proto
+++ b/js/test.proto
@@ -165,6 +165,13 @@
   extensions 10 to max;
 }
 
+message TestCloneExtension {
+  extend TestClone {
+    optional TestCloneExtension low_ext = 11;
+  }
+  optional int32 f = 1;
+}
+
 message CloneExtension {
   extend TestClone {
     optional CloneExtension ext_field = 100;
diff --git a/kokoro/linux/bazel/build.sh b/kokoro/linux/bazel/build.sh
index e0c1ee4..1769301 100755
--- a/kokoro/linux/bazel/build.sh
+++ b/kokoro/linux/bazel/build.sh
@@ -1,6 +1,7 @@
 #!/bin/bash
 #
 # Build file to set up and run tests
+set -ex
 
 # Change to repo root
 cd $(dirname $0)/../../..
diff --git a/kokoro/linux/build_and_run_docker.sh b/kokoro/linux/build_and_run_docker.sh
index f9c6071..b81a368 100755
--- a/kokoro/linux/build_and_run_docker.sh
+++ b/kokoro/linux/build_and_run_docker.sh
@@ -8,7 +8,6 @@
 # OUTPUT_DIR - Directory that will be copied from inside docker after finishing.
 # $@ - Extra args to pass to docker run
 
-
 set -ex
 
 cd $(dirname $0)/../..
@@ -39,7 +38,6 @@
   -e KOKORO_BUILD_ID=$KOKORO_BUILD_ID \
   -e EXTERNAL_GIT_ROOT="/var/local/kokoro/protobuf" \
   -e TEST_SET="$TEST_SET" \
-  -e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \
   -v "$git_root:/var/local/kokoro/protobuf:ro" \
   -v $CCACHE_DIR:$CCACHE_DIR \
   -w /var/local/git/protobuf \
@@ -47,16 +45,9 @@
   $DOCKER_IMAGE_NAME \
   bash -l "/var/local/kokoro/protobuf/$DOCKER_RUN_SCRIPT" || FAILED="true"
 
-# Copy output artifacts
-if [ "$OUTPUT_DIR" != "" ]
-then
-  docker cp "$CONTAINER_NAME:/var/local/git/protobuf/$OUTPUT_DIR" "${git_root}/kokoro" || FAILED="true"
-fi
-
 # remove the container, possibly killing it first
 docker rm -f $CONTAINER_NAME || true
 
-if [ "$FAILED" != "" ]
-then
+[ -z "$FAILED" ] || {
   exit 1
-fi
+}
diff --git a/kokoro/linux/pull_request_in_docker.sh b/kokoro/linux/pull_request_in_docker.sh
index e28ef95..a048c47 100755
--- a/kokoro/linux/pull_request_in_docker.sh
+++ b/kokoro/linux/pull_request_in_docker.sh
@@ -22,52 +22,4 @@
 # Initialize any submodules:
 git submodule update --init --recursive
 
-# Set up the directory where our test output is going to go.
-OUTPUT_DIR=`mktemp -d`
-LOG_OUTPUT_DIR=$OUTPUT_DIR/logs
-mkdir -p $LOG_OUTPUT_DIR/1/cpp
-
-################################################################################
-# cpp build needs to run first, non-parallelized, so that protoc is available
-# for other builds.
-
-# Output filenames to follow the overall scheme used by parallel, ie:
-#  $DIR/logs/1/cpp/stdout
-#  $DIR/logs/1/cpp/stderr
-#  $DIR/logs/1/csharp/stdout
-#  $DIR/logs/1/csharp/stderr
-#  $DIR/logs/1/java_jdk7/stdout
-#  $DIR/logs/1/java_jdk7/stderr
-CPP_STDOUT=$LOG_OUTPUT_DIR/1/cpp/stdout
-CPP_STDERR=$LOG_OUTPUT_DIR/1/cpp/stderr
-
-# Time the C++ build, so we can put this info in the test output.
-# It's important that we get /usr/bin/time (which supports -f and -o) and not
-# the bash builtin "time" which doesn't.
-TIME_CMD="/usr/bin/time -f %e -o $LOG_OUTPUT_DIR/1/cpp/build_time"
-
-$TIME_CMD $TEST_SCRIPT cpp > >(tee $CPP_STDOUT) 2> >(tee $CPP_STDERR >&2)
-
-# Other tests are run in parallel. TEST_SET is defined in
-# buildcmds/pull_request{_32}.sh
-
-parallel --results $LOG_OUTPUT_DIR --joblog $OUTPUT_DIR/joblog $TEST_SCRIPT ::: \
-  $TEST_SET \
-  || FAILED="true"  # Process test results even if tests fail.
-
-cat $OUTPUT_DIR/joblog
-
-# The directory that is copied from Docker back into the Kokoro workspace.
-COPY_FROM_DOCKER=/var/local/git/protobuf/testoutput
-mkdir -p $COPY_FROM_DOCKER
-TESTOUTPUT_XML_FILE=$COPY_FROM_DOCKER/sponge_log.xml
-
-# Process all the output files from "parallel" and package them into a single
-# .xml file with detailed, broken-down test output.
-python $MY_DIR/make_test_output.py $OUTPUT_DIR > $TESTOUTPUT_XML_FILE
-
-ls -l $TESTOUTPUT_XML_FILE
-
-if [ "$FAILED" == "true" ]; then
-	exit 1
-fi
+$TEST_SCRIPT $TEST_SET
diff --git a/objectivec/google/protobuf/FieldMask.pbobjc.h b/objectivec/google/protobuf/FieldMask.pbobjc.h
index 73296d5..72cac9a 100644
--- a/objectivec/google/protobuf/FieldMask.pbobjc.h
+++ b/objectivec/google/protobuf/FieldMask.pbobjc.h
@@ -123,57 +123,49 @@
  * describe the updated values, the API ignores the values of all
  * fields not covered by the mask.
  *
- * If a repeated field is specified for an update operation, the existing
- * repeated values in the target resource will be overwritten by the new values.
- * Note that a repeated field is only allowed in the last position of a `paths`
- * string.
+ * If a repeated field is specified for an update operation, new values will
+ * be appended to the existing repeated field in the target resource. Note that
+ * a repeated field is only allowed in the last position of a `paths` string.
  *
  * If a sub-message is specified in the last position of the field mask for an
- * update operation, then the existing sub-message in the target resource is
- * overwritten. Given the target message:
+ * update operation, then new value will be merged into the existing sub-message
+ * in the target resource.
+ *
+ * For example, given the target message:
  *
  *     f {
  *       b {
- *         d : 1
- *         x : 2
+ *         d: 1
+ *         x: 2
  *       }
- *       c : 1
+ *       c: [1]
  *     }
  *
  * And an update message:
  *
  *     f {
  *       b {
- *         d : 10
+ *         d: 10
  *       }
+ *       c: [2]
  *     }
  *
  * then if the field mask is:
  *
- *  paths: "f.b"
+ *  paths: ["f.b", "f.c"]
  *
  * then the result will be:
  *
  *     f {
  *       b {
- *         d : 10
+ *         d: 10
+ *         x: 2
  *       }
- *       c : 1
+ *       c: [1, 2]
  *     }
  *
- * However, if the update mask was:
- *
- *  paths: "f.b.d"
- *
- * then the result would be:
- *
- *     f {
- *       b {
- *         d : 10
- *         x : 2
- *       }
- *       c : 1
- *     }
+ * An implementation may provide options to override this default behavior for
+ * repeated and message fields.
  *
  * In order to reset a field's value to the default, the field must
  * be in the mask and set to the default value in the provided resource.
diff --git a/php/ext/google/protobuf/upb.c b/php/ext/google/protobuf/upb.c
index 4644430..90c52aa 100644
--- a/php/ext/google/protobuf/upb.c
+++ b/php/ext/google/protobuf/upb.c
@@ -14280,6 +14280,39 @@
 
 #define UPB_JSON_MAX_DEPTH 64
 
+static const char *kDoubleValueFullMessageName = "google.protobuf.DoubleValue";
+static const char *kFloatValueFullMessageName = "google.protobuf.FloatValue";
+static const char *kInt64ValueFullMessageName = "google.protobuf.Int64Value";
+static const char *kUInt64ValueFullMessageName = "google.protobuf.UInt64Value";
+static const char *kInt32ValueFullMessageName = "google.protobuf.Int32Value";
+static const char *kUInt32ValueFullMessageName = "google.protobuf.UInt32Value";
+static const char *kBoolValueFullMessageName = "google.protobuf.BoolValue";
+static const char *kStringValueFullMessageName = "google.protobuf.StringValue";
+static const char *kBytesValueFullMessageName = "google.protobuf.BytesValue";
+
+/* Forward declare */
+static bool is_top_level(upb_json_parser *p);
+
+static bool is_number_wrapper_object(upb_json_parser *p);
+static bool does_number_wrapper_start(upb_json_parser *p);
+static bool does_number_wrapper_end(upb_json_parser *p);
+
+static bool is_string_wrapper_object(upb_json_parser *p);
+static bool does_string_wrapper_start(upb_json_parser *p);
+static bool does_string_wrapper_end(upb_json_parser *p);
+
+static bool is_boolean_wrapper_object(upb_json_parser *p);
+static bool does_boolean_wrapper_start(upb_json_parser *p);
+static bool does_boolean_wrapper_end(upb_json_parser *p);
+
+static void start_wrapper_object(upb_json_parser *p);
+static void end_wrapper_object(upb_json_parser *p);
+
+static bool start_subobject(upb_json_parser *p);
+static void end_subobject(upb_json_parser *p);
+
+static const char eof_ch = 'e';
+
 typedef struct {
   upb_sink sink;
 
@@ -14855,14 +14888,27 @@
   return capture_end(p, ptr);
 }
 
-static void start_number(upb_json_parser *p, const char *ptr) {
+static bool start_number(upb_json_parser *p, const char *ptr) {
+  if (is_top_level(p)) {
+    if (!is_number_wrapper_object(p)) {
+      return false;
+    }
+    start_wrapper_object(p);
+  } else if (does_number_wrapper_start(p)) {
+    if (!start_subobject(p)) {
+      return false;
+    }
+    start_wrapper_object(p);
+  }
+
   multipart_startaccum(p);
   capture_begin(p, ptr);
+  return true;
 }
 
 static bool parse_number(upb_json_parser *p, bool is_quoted);
 
-static bool end_number(upb_json_parser *p, const char *ptr) {
+static bool end_number_nontop(upb_json_parser *p, const char *ptr) {
   if (!capture_end(p, ptr)) {
     return false;
   }
@@ -14875,6 +14921,21 @@
   return parse_number(p, false);
 }
 
+static bool end_number(upb_json_parser *p, const char *ptr) {
+  if (!end_number_nontop(p, ptr)) {
+    return false;
+  }
+
+  if (does_number_wrapper_end(p)) {
+    end_wrapper_object(p);
+    if (!is_top_level(p)) {
+      end_subobject(p);
+    }
+  }
+
+  return true;
+}
+
 /* |buf| is NULL-terminated. |buf| itself will never include quotes;
  * |is_quoted| tells us whether this text originally appeared inside quotes. */
 static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
@@ -15042,7 +15103,46 @@
   return true;
 }
 
+static bool end_bool(upb_json_parser *p, bool val) {
+  if (is_top_level(p)) {
+    if (!is_boolean_wrapper_object(p)) {
+      return false;
+    }
+    start_wrapper_object(p);
+  } else if (does_boolean_wrapper_start(p)) {
+    if (!start_subobject(p)) {
+      return false;
+    }
+    start_wrapper_object(p);
+  }
+
+  if (!parser_putbool(p, val)) {
+    return false;
+  }
+
+  if (does_boolean_wrapper_end(p)) {
+    end_wrapper_object(p);
+    if (!is_top_level(p)) {
+      end_subobject(p);
+    }
+  }
+
+  return true;
+}
+
 static bool start_stringval(upb_json_parser *p) {
+  if (is_top_level(p)) {
+    if (!is_string_wrapper_object(p)) {
+      return false;
+    }
+    start_wrapper_object(p);
+  } else if (does_string_wrapper_start(p)) {
+    if (!start_subobject(p)) {
+      return false;
+    }
+    start_wrapper_object(p);
+  }
+
   if (p->top->f == NULL) {
     multipart_startaccum(p);
     return true;
@@ -15094,7 +15194,7 @@
   }
 }
 
-static bool end_stringval(upb_json_parser *p) {
+static bool end_stringval_nontop(upb_json_parser *p) {
   bool ok = true;
 
   if (p->top->f == NULL) {
@@ -15161,6 +15261,21 @@
   return ok;
 }
 
+static bool end_stringval(upb_json_parser *p) {
+  if (!end_stringval_nontop(p)) {
+    return false;
+  }
+
+  if (does_string_wrapper_end(p)) {
+    end_wrapper_object(p);
+    if (!is_top_level(p)) {
+      end_subobject(p);
+    }
+  }
+
+  return true;
+}
+
 static void start_member(upb_json_parser *p) {
   UPB_ASSERT(!p->top->f);
   multipart_startaccum(p);
@@ -15344,6 +15459,10 @@
 }
 
 static bool start_subobject(upb_json_parser *p) {
+  if (is_top_level(p)) {
+    return true;
+  }
+
   if (p->top->f == NULL) {
     upb_jsonparser_frame *inner;
     if (!check_stack(p)) return false;
@@ -15407,6 +15526,10 @@
 }
 
 static void end_subobject(upb_json_parser *p) {
+  if (is_top_level(p)) {
+    return;
+  }
+
   if (p->top->is_map) {
     upb_selector_t sel;
     p->top--;
@@ -15479,6 +15602,118 @@
   }
 }
 
+static bool is_double_value(const upb_msgdef *m) {
+  return strcmp(upb_msgdef_fullname(m), kDoubleValueFullMessageName) == 0;
+}
+
+static bool is_float_value(const upb_msgdef *m) {
+  return strcmp(upb_msgdef_fullname(m), kFloatValueFullMessageName) == 0;
+}
+
+static bool is_int64_value(const upb_msgdef *m) {
+  return strcmp(upb_msgdef_fullname(m), kInt64ValueFullMessageName) == 0;
+}
+
+static bool is_uint64_value(const upb_msgdef *m) {
+  return strcmp(upb_msgdef_fullname(m), kUInt64ValueFullMessageName) == 0;
+}
+
+static bool is_int32_value(const upb_msgdef *m) {
+  return strcmp(upb_msgdef_fullname(m), kInt32ValueFullMessageName) == 0;
+}
+
+static bool is_uint32_value(const upb_msgdef *m) {
+  return strcmp(upb_msgdef_fullname(m), kUInt32ValueFullMessageName) == 0;
+}
+
+static bool is_bool_value(const upb_msgdef *m) {
+  return strcmp(upb_msgdef_fullname(m), kBoolValueFullMessageName) == 0;
+}
+
+static bool is_string_value(const upb_msgdef *m) {
+  return strcmp(upb_msgdef_fullname(m), kStringValueFullMessageName) == 0;
+}
+
+static bool is_bytes_value(const upb_msgdef *m) {
+  return strcmp(upb_msgdef_fullname(m), kBytesValueFullMessageName) == 0;
+}
+
+static bool is_number_wrapper(const upb_msgdef *m) {
+  return is_double_value(m) ||
+         is_float_value(m) ||
+         is_int64_value(m) ||
+         is_uint64_value(m) ||
+         is_int32_value(m) ||
+         is_uint32_value(m);
+}
+
+static bool is_string_wrapper(const upb_msgdef *m) {
+  return is_string_value(m) ||
+         is_bytes_value(m);
+}
+
+static void start_wrapper_object(upb_json_parser *p) {
+  const char *membername = "value";
+
+  start_object(p);
+
+  /* Set up context for parsing value */
+  start_member(p);
+  capture_begin(p, membername);
+  capture_end(p, membername + 5);
+  end_membername(p);
+}
+
+static void end_wrapper_object(upb_json_parser *p) {
+  end_member(p);
+  end_object(p);
+}
+
+static bool is_top_level(upb_json_parser *p) {
+  return p->top == p->stack && p->top->f == NULL;
+}
+
+static bool does_number_wrapper_start(upb_json_parser *p) {
+  return p->top->f != NULL &&
+         upb_fielddef_issubmsg(p->top->f) &&
+         is_number_wrapper(upb_fielddef_msgsubdef(p->top->f));
+}
+
+static bool does_number_wrapper_end(upb_json_parser *p) {
+  return p->top->m != NULL && is_number_wrapper(p->top->m);
+}
+
+static bool is_number_wrapper_object(upb_json_parser *p) {
+  return p->top->m != NULL && is_number_wrapper(p->top->m);
+}
+
+static bool does_string_wrapper_start(upb_json_parser *p) {
+  return p->top->f != NULL &&
+         upb_fielddef_issubmsg(p->top->f) &&
+         is_string_wrapper(upb_fielddef_msgsubdef(p->top->f));
+}
+
+static bool does_string_wrapper_end(upb_json_parser *p) {
+  return p->top->m != NULL && is_string_wrapper(p->top->m);
+}
+
+static bool is_string_wrapper_object(upb_json_parser *p) {
+  return p->top->m != NULL && is_string_wrapper(p->top->m);
+}
+
+static bool does_boolean_wrapper_start(upb_json_parser *p) {
+  return p->top->f != NULL &&
+         upb_fielddef_issubmsg(p->top->f) &&
+         is_bool_value(upb_fielddef_msgsubdef(p->top->f));
+}
+
+static bool does_boolean_wrapper_end(upb_json_parser *p) {
+  return p->top->m != NULL && is_bool_value(p->top->m);
+}
+
+static bool is_boolean_wrapper_object(upb_json_parser *p) {
+  return p->top->m != NULL && is_bool_value(p->top->m);
+}
 
 #define CHECK_RETURN_TOP(x) if (!(x)) goto error
 
@@ -15501,160 +15736,204 @@
  * final state once, when the closing '"' is seen. */
 
 
-#line 1349 "upb/json/parser.rl"
+#line 1589 "upb/json/parser.rl"
 
 
 
-#line 1261 "upb/json/parser.c"
+#line 1496 "upb/json/parser.c"
 static const char _json_actions[] = {
-	0, 1, 0, 1, 2, 1, 3, 1, 
-	5, 1, 6, 1, 7, 1, 8, 1, 
-	10, 1, 12, 1, 13, 1, 14, 1, 
-	15, 1, 16, 1, 17, 1, 21, 1, 
-	25, 1, 27, 2, 3, 8, 2, 4, 
-	5, 2, 6, 2, 2, 6, 8, 2, 
-	11, 9, 2, 13, 15, 2, 14, 15, 
-	2, 18, 1, 2, 19, 27, 2, 20, 
-	9, 2, 22, 27, 2, 23, 27, 2, 
-	24, 27, 2, 26, 27, 3, 14, 11, 
-	9
+	0, 1, 0, 1, 1, 1, 3, 1, 
+	4, 1, 6, 1, 7, 1, 8, 1, 
+	9, 1, 11, 1, 13, 1, 14, 1, 
+	15, 1, 16, 1, 17, 1, 18, 1, 
+	20, 1, 22, 1, 23, 1, 24, 1, 
+	25, 1, 26, 1, 27, 1, 28, 2, 
+	4, 9, 2, 5, 6, 2, 7, 3, 
+	2, 7, 9, 2, 12, 10, 2, 14, 
+	16, 2, 15, 16, 2, 19, 2, 2, 
+	20, 28, 2, 21, 10, 2, 23, 28, 
+	2, 24, 28, 2, 25, 28, 2, 27, 
+	28, 3, 15, 12, 10
 };
 
 static const unsigned char _json_key_offsets[] = {
-	0, 0, 4, 9, 14, 15, 19, 24, 
-	29, 34, 38, 42, 45, 48, 50, 54, 
-	58, 60, 62, 67, 69, 71, 80, 86, 
-	92, 98, 104, 106, 115, 116, 116, 116, 
-	121, 126, 131, 132, 133, 134, 135, 135, 
-	136, 137, 138, 138, 139, 140, 141, 141, 
-	146, 151, 152, 156, 161, 166, 171, 175, 
-	175, 178, 178, 178
+	0, 0, 12, 13, 18, 23, 28, 29, 
+	30, 31, 32, 33, 34, 35, 36, 37, 
+	38, 43, 48, 49, 53, 58, 63, 68, 
+	72, 76, 79, 82, 84, 88, 92, 94, 
+	96, 101, 103, 105, 114, 120, 126, 132, 
+	138, 140, 149, 150, 150, 150, 155, 160, 
+	165, 166, 167, 168, 169, 169, 170, 171, 
+	172, 172, 173, 174, 175, 175, 180, 185, 
+	186, 190, 195, 200, 205, 209, 209, 212, 
+	215, 218, 221, 224, 227, 227, 227
 };
 
 static const char _json_trans_keys[] = {
-	32, 123, 9, 13, 32, 34, 125, 9, 
-	13, 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, 
+	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, 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, 48, 57, 65, 70, 97, 102, 
-	34, 92, 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, 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, 0
+	97, 102, 34, 92, 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, 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, 2, 3, 3, 1, 2, 3, 3, 
-	3, 2, 2, 1, 3, 0, 2, 2, 
-	0, 0, 3, 2, 2, 9, 0, 0, 
-	0, 0, 2, 7, 1, 0, 0, 3, 
-	3, 3, 1, 1, 1, 1, 0, 1, 
-	1, 1, 0, 1, 1, 1, 0, 3, 
-	3, 1, 2, 3, 3, 3, 2, 0, 
-	1, 0, 0, 0
+	0, 8, 1, 3, 3, 3, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	3, 3, 1, 2, 3, 3, 3, 2, 
+	2, 1, 3, 0, 2, 2, 0, 0, 
+	3, 2, 2, 9, 0, 0, 0, 0, 
+	2, 7, 1, 0, 0, 3, 3, 3, 
+	1, 1, 1, 1, 0, 1, 1, 1, 
+	0, 1, 1, 1, 0, 3, 3, 1, 
+	2, 3, 3, 3, 2, 0, 1, 1, 
+	1, 1, 1, 1, 0, 0, 0
 };
 
 static const char _json_range_lengths[] = {
-	0, 1, 1, 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, 0, 0, 0, 1, 
-	1, 1, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 1, 
-	1, 0, 1, 1, 1, 1, 1, 0, 
-	1, 0, 0, 0
+	0, 2, 0, 1, 1, 1, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	1, 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, 0, 0, 0, 1, 1, 1, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 1, 1, 0, 
+	1, 1, 1, 1, 1, 0, 1, 1, 
+	1, 1, 1, 1, 0, 0, 0
 };
 
 static const short _json_index_offsets[] = {
-	0, 0, 4, 9, 14, 16, 20, 25, 
-	30, 35, 39, 43, 46, 50, 52, 56, 
-	60, 62, 64, 69, 72, 75, 85, 89, 
-	93, 97, 101, 104, 113, 115, 116, 117, 
-	122, 127, 132, 134, 136, 138, 140, 141, 
-	143, 145, 147, 148, 150, 152, 154, 155, 
-	160, 165, 167, 171, 176, 181, 186, 190, 
-	191, 194, 195, 196
+	0, 0, 11, 13, 18, 23, 28, 30, 
+	32, 34, 36, 38, 40, 42, 44, 46, 
+	48, 53, 58, 60, 64, 69, 74, 79, 
+	83, 87, 90, 94, 96, 100, 104, 106, 
+	108, 113, 116, 119, 129, 133, 137, 141, 
+	145, 148, 157, 159, 160, 161, 166, 171, 
+	176, 178, 180, 182, 184, 185, 187, 189, 
+	191, 192, 194, 196, 198, 199, 204, 209, 
+	211, 215, 220, 225, 230, 234, 235, 238, 
+	241, 244, 247, 250, 253, 254, 255
 };
 
 static const char _json_indicies[] = {
-	0, 2, 0, 1, 3, 4, 5, 3, 
-	1, 6, 7, 8, 6, 1, 9, 1, 
-	10, 11, 10, 1, 11, 1, 1, 11, 
-	12, 13, 14, 15, 13, 1, 16, 17, 
-	8, 16, 1, 17, 7, 17, 1, 18, 
-	19, 20, 1, 19, 20, 1, 22, 23, 
-	23, 21, 24, 1, 23, 23, 24, 21, 
-	25, 25, 26, 1, 26, 1, 26, 21, 
-	22, 23, 23, 20, 21, 28, 29, 27, 
-	31, 32, 30, 33, 33, 33, 33, 33, 
-	33, 33, 33, 34, 1, 35, 35, 35, 
-	1, 36, 36, 36, 1, 37, 37, 37, 
-	1, 38, 38, 38, 1, 40, 41, 39, 
-	42, 43, 44, 45, 46, 47, 48, 43, 
-	1, 49, 1, 50, 51, 53, 54, 1, 
-	53, 52, 55, 56, 54, 55, 1, 56, 
-	1, 1, 56, 52, 57, 1, 58, 1, 
-	59, 1, 60, 1, 61, 62, 1, 63, 
-	1, 64, 1, 65, 66, 1, 67, 1, 
-	68, 1, 69, 70, 71, 72, 70, 1, 
-	73, 74, 75, 73, 1, 76, 1, 77, 
-	78, 77, 1, 78, 1, 1, 78, 79, 
-	80, 81, 82, 80, 1, 83, 84, 75, 
-	83, 1, 84, 74, 84, 1, 85, 86, 
-	86, 1, 1, 1, 1, 0
+	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, 29, 30, 
+	28, 1, 31, 1, 32, 33, 32, 1, 
+	33, 1, 1, 33, 34, 35, 36, 37, 
+	35, 1, 38, 39, 30, 38, 1, 39, 
+	29, 39, 1, 40, 41, 42, 1, 41, 
+	42, 1, 44, 45, 45, 43, 46, 1, 
+	45, 45, 46, 43, 47, 47, 48, 1, 
+	48, 1, 48, 43, 44, 45, 45, 42, 
+	43, 50, 51, 49, 53, 54, 52, 55, 
+	55, 55, 55, 55, 55, 55, 55, 56, 
+	1, 57, 57, 57, 1, 58, 58, 58, 
+	1, 59, 59, 59, 1, 60, 60, 60, 
+	1, 62, 63, 61, 64, 65, 66, 67, 
+	68, 69, 70, 65, 1, 71, 1, 72, 
+	73, 75, 76, 1, 75, 74, 77, 78, 
+	76, 77, 1, 78, 1, 1, 78, 74, 
+	79, 1, 80, 1, 81, 1, 82, 1, 
+	83, 84, 1, 85, 1, 86, 1, 87, 
+	88, 1, 89, 1, 90, 1, 91, 92, 
+	93, 94, 92, 1, 95, 96, 97, 95, 
+	1, 98, 1, 99, 100, 99, 1, 100, 
+	1, 1, 100, 101, 102, 103, 104, 102, 
+	1, 105, 106, 97, 105, 1, 106, 96, 
+	106, 1, 107, 108, 108, 1, 109, 109, 
+	1, 110, 110, 1, 111, 111, 1, 112, 
+	112, 1, 113, 113, 1, 1, 1, 1, 
+	0
 };
 
 static const char _json_trans_targs[] = {
-	1, 0, 2, 3, 4, 56, 3, 4, 
-	56, 5, 5, 6, 7, 8, 9, 56, 
-	8, 9, 11, 12, 18, 57, 13, 15, 
-	14, 16, 17, 20, 58, 21, 20, 58, 
-	21, 19, 22, 23, 24, 25, 26, 20, 
-	58, 21, 28, 30, 31, 34, 39, 43, 
-	47, 29, 59, 59, 32, 31, 29, 32, 
-	33, 35, 36, 37, 38, 59, 40, 41, 
-	42, 59, 44, 45, 46, 59, 48, 49, 
-	55, 48, 49, 55, 50, 50, 51, 52, 
-	53, 54, 55, 53, 54, 59, 56
+	1, 0, 2, 71, 3, 6, 10, 13, 
+	16, 70, 4, 3, 70, 4, 5, 7, 
+	8, 9, 72, 11, 12, 73, 14, 15, 
+	74, 17, 18, 75, 17, 18, 75, 19, 
+	19, 20, 21, 22, 23, 75, 22, 23, 
+	25, 26, 32, 76, 27, 29, 28, 30, 
+	31, 34, 77, 35, 34, 77, 35, 33, 
+	36, 37, 38, 39, 40, 34, 77, 35, 
+	42, 44, 45, 48, 53, 57, 61, 43, 
+	78, 78, 46, 45, 43, 46, 47, 49, 
+	50, 51, 52, 78, 54, 55, 56, 78, 
+	58, 59, 60, 78, 62, 63, 69, 62, 
+	63, 69, 64, 64, 65, 66, 67, 68, 
+	69, 67, 68, 78, 70, 70, 70, 70, 
+	70, 70
 };
 
 static const char _json_trans_actions[] = {
-	0, 0, 0, 21, 77, 53, 0, 47, 
-	23, 17, 0, 0, 15, 19, 19, 50, 
-	0, 0, 0, 0, 0, 1, 0, 0, 
-	0, 0, 0, 3, 13, 0, 0, 35, 
-	5, 11, 0, 38, 7, 7, 7, 41, 
-	44, 9, 62, 56, 25, 0, 0, 0, 
-	31, 29, 33, 59, 15, 0, 27, 0, 
-	0, 0, 0, 0, 0, 68, 0, 0, 
-	0, 71, 0, 0, 0, 65, 21, 77, 
-	53, 0, 47, 23, 17, 0, 0, 15, 
-	19, 19, 50, 0, 0, 74, 0
+	0, 0, 74, 68, 27, 0, 0, 0, 
+	41, 33, 17, 0, 29, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 23, 89, 65, 0, 59, 25, 19, 
+	0, 0, 17, 21, 21, 62, 0, 0, 
+	0, 0, 0, 3, 0, 0, 0, 0, 
+	0, 5, 15, 0, 0, 47, 7, 13, 
+	0, 50, 9, 9, 9, 53, 56, 11, 
+	74, 68, 27, 0, 0, 0, 41, 33, 
+	45, 71, 17, 0, 29, 0, 0, 0, 
+	0, 0, 0, 80, 0, 0, 0, 83, 
+	0, 0, 0, 77, 23, 89, 65, 0, 
+	59, 25, 19, 0, 0, 17, 21, 21, 
+	62, 0, 0, 86, 0, 31, 37, 39, 
+	35, 43
+};
+
+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, 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, 31, 
+	37, 39, 35, 43, 0, 0, 0
 };
 
 static const int json_start = 1;
 
-static const int json_en_number_machine = 10;
-static const int json_en_string_machine = 19;
-static const int json_en_value_machine = 27;
+static const int json_en_number_machine = 24;
+static const int json_en_string_machine = 33;
+static const int json_en_value_machine = 41;
 static const int json_en_main = 1;
 
 
-#line 1352 "upb/json/parser.rl"
+#line 1592 "upb/json/parser.rl"
 
 size_t parse(void *closure, const void *hd, const char *buf, size_t size,
              const upb_bufhandle *handle) {
@@ -15667,6 +15946,7 @@
 
   const char *p = buf;
   const char *pe = buf + size;
+  const char *eof = &eof_ch;
 
   parser->handle = handle;
 
@@ -15676,7 +15956,7 @@
   capture_resume(parser, buf);
 
   
-#line 1432 "upb/json/parser.c"
+#line 1712 "upb/json/parser.c"
 	{
 	int _klen;
 	unsigned int _trans;
@@ -15750,119 +16030,119 @@
 	{
 		switch ( *_acts++ )
 		{
-	case 0:
-#line 1264 "upb/json/parser.rl"
-	{ p--; {cs = stack[--top]; goto _again;} }
-	break;
 	case 1:
-#line 1265 "upb/json/parser.rl"
-	{ p--; {stack[top++] = cs; cs = 10; goto _again;} }
+#line 1503 "upb/json/parser.rl"
+	{ p--; {cs = stack[--top]; goto _again;} }
 	break;
 	case 2:
-#line 1269 "upb/json/parser.rl"
-	{ start_text(parser, p); }
+#line 1505 "upb/json/parser.rl"
+	{ p--; {stack[top++] = cs; cs = 24; goto _again;} }
 	break;
 	case 3:
-#line 1270 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_text(parser, p)); }
+#line 1509 "upb/json/parser.rl"
+	{ start_text(parser, p); }
 	break;
 	case 4:
-#line 1276 "upb/json/parser.rl"
-	{ start_hex(parser); }
+#line 1510 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(end_text(parser, p)); }
 	break;
 	case 5:
-#line 1277 "upb/json/parser.rl"
-	{ hexdigit(parser, p); }
+#line 1516 "upb/json/parser.rl"
+	{ start_hex(parser); }
 	break;
 	case 6:
-#line 1278 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_hex(parser)); }
+#line 1517 "upb/json/parser.rl"
+	{ hexdigit(parser, p); }
 	break;
 	case 7:
-#line 1284 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(escape(parser, p)); }
+#line 1518 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(end_hex(parser)); }
 	break;
 	case 8:
-#line 1290 "upb/json/parser.rl"
-	{ p--; {cs = stack[--top]; goto _again;} }
+#line 1524 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(escape(parser, p)); }
 	break;
 	case 9:
-#line 1293 "upb/json/parser.rl"
-	{ {stack[top++] = cs; cs = 19; goto _again;} }
-	break;
-	case 10:
-#line 1295 "upb/json/parser.rl"
-	{ p--; {stack[top++] = cs; cs = 27; goto _again;} }
-	break;
-	case 11:
-#line 1300 "upb/json/parser.rl"
-	{ start_member(parser); }
-	break;
-	case 12:
-#line 1301 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_membername(parser)); }
-	break;
-	case 13:
-#line 1304 "upb/json/parser.rl"
-	{ end_member(parser); }
-	break;
-	case 14:
-#line 1310 "upb/json/parser.rl"
-	{ start_object(parser); }
-	break;
-	case 15:
-#line 1313 "upb/json/parser.rl"
-	{ end_object(parser); }
-	break;
-	case 16:
-#line 1319 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(start_array(parser)); }
-	break;
-	case 17:
-#line 1323 "upb/json/parser.rl"
-	{ end_array(parser); }
-	break;
-	case 18:
-#line 1328 "upb/json/parser.rl"
-	{ start_number(parser, p); }
-	break;
-	case 19:
-#line 1329 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_number(parser, p)); }
-	break;
-	case 20:
-#line 1331 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(start_stringval(parser)); }
-	break;
-	case 21:
-#line 1332 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(end_stringval(parser)); }
-	break;
-	case 22:
-#line 1334 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(parser_putbool(parser, true)); }
-	break;
-	case 23:
-#line 1336 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(parser_putbool(parser, false)); }
-	break;
-	case 24:
-#line 1338 "upb/json/parser.rl"
-	{ /* null value */ }
-	break;
-	case 25:
-#line 1340 "upb/json/parser.rl"
-	{ CHECK_RETURN_TOP(start_subobject(parser)); }
-	break;
-	case 26:
-#line 1341 "upb/json/parser.rl"
-	{ end_subobject(parser); }
-	break;
-	case 27:
-#line 1346 "upb/json/parser.rl"
+#line 1530 "upb/json/parser.rl"
 	{ p--; {cs = stack[--top]; goto _again;} }
 	break;
-#line 1618 "upb/json/parser.c"
+	case 10:
+#line 1533 "upb/json/parser.rl"
+	{ {stack[top++] = cs; cs = 33; goto _again;} }
+	break;
+	case 11:
+#line 1535 "upb/json/parser.rl"
+	{ p--; {stack[top++] = cs; cs = 41; goto _again;} }
+	break;
+	case 12:
+#line 1540 "upb/json/parser.rl"
+	{ start_member(parser); }
+	break;
+	case 13:
+#line 1541 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(end_membername(parser)); }
+	break;
+	case 14:
+#line 1544 "upb/json/parser.rl"
+	{ end_member(parser); }
+	break;
+	case 15:
+#line 1550 "upb/json/parser.rl"
+	{ start_object(parser); }
+	break;
+	case 16:
+#line 1553 "upb/json/parser.rl"
+	{ end_object(parser); }
+	break;
+	case 17:
+#line 1559 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(start_array(parser)); }
+	break;
+	case 18:
+#line 1563 "upb/json/parser.rl"
+	{ end_array(parser); }
+	break;
+	case 19:
+#line 1568 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(start_number(parser, p)); }
+	break;
+	case 20:
+#line 1569 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(end_number(parser, p)); }
+	break;
+	case 21:
+#line 1571 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(start_stringval(parser)); }
+	break;
+	case 22:
+#line 1572 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(end_stringval(parser)); }
+	break;
+	case 23:
+#line 1574 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(end_bool(parser, true)); }
+	break;
+	case 24:
+#line 1576 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(end_bool(parser, false)); }
+	break;
+	case 25:
+#line 1578 "upb/json/parser.rl"
+	{ /* null value */ }
+	break;
+	case 26:
+#line 1580 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(start_subobject(parser)); }
+	break;
+	case 27:
+#line 1581 "upb/json/parser.rl"
+	{ end_subobject(parser); }
+	break;
+	case 28:
+#line 1586 "upb/json/parser.rl"
+	{ p--; {cs = stack[--top]; goto _again;} }
+	break;
+#line 1898 "upb/json/parser.c"
 		}
 	}
 
@@ -15872,10 +16152,47 @@
 	if ( ++p != pe )
 		goto _resume;
 	_test_eof: {}
+	if ( p == eof )
+	{
+	const char *__acts = _json_actions + _json_eof_actions[cs];
+	unsigned int __nacts = (unsigned int) *__acts++;
+	while ( __nacts-- > 0 ) {
+		switch ( *__acts++ ) {
+	case 0:
+#line 1499 "upb/json/parser.rl"
+	{
+            p--; {cs = stack[--top]; goto _again;}
+        }
+	break;
+	case 20:
+#line 1569 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(end_number(parser, p)); }
+	break;
+	case 23:
+#line 1574 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(end_bool(parser, true)); }
+	break;
+	case 24:
+#line 1576 "upb/json/parser.rl"
+	{ CHECK_RETURN_TOP(end_bool(parser, false)); }
+	break;
+	case 25:
+#line 1578 "upb/json/parser.rl"
+	{ /* null value */ }
+	break;
+	case 27:
+#line 1581 "upb/json/parser.rl"
+	{ end_subobject(parser); }
+	break;
+#line 1940 "upb/json/parser.c"
+		}
+	}
+	}
+
 	_out: {}
 	}
 
-#line 1373 "upb/json/parser.rl"
+#line 1614 "upb/json/parser.rl"
 
   if (p != pe) {
     upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p);
@@ -15893,8 +16210,7 @@
 }
 
 bool end(void *closure, const void *hd) {
-  UPB_UNUSED(closure);
-  UPB_UNUSED(hd);
+  upb_json_parser *parser = closure;
 
   /* Prevent compile warning on unused static constants. */
   UPB_UNUSED(json_start);
@@ -15902,7 +16218,14 @@
   UPB_UNUSED(json_en_string_machine);
   UPB_UNUSED(json_en_value_machine);
   UPB_UNUSED(json_en_main);
-  return true;
+
+  parse(parser, hd, &eof_ch, 0, NULL);
+
+  return parser->current_state >= 
+#line 1978 "upb/json/parser.c"
+70
+#line 1642 "upb/json/parser.rl"
+;
 }
 
 static void json_parser_reset(upb_json_parser *p) {
@@ -15916,13 +16239,13 @@
 
   /* Emit Ragel initialization of the parser. */
   
-#line 1672 "upb/json/parser.c"
+#line 1995 "upb/json/parser.c"
 	{
 	cs = json_start;
 	top = 0;
 	}
 
-#line 1413 "upb/json/parser.rl"
+#line 1656 "upb/json/parser.rl"
   p->current_state = cs;
   p->parser_top = top;
   accumulate_clear(p);
diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php
new file mode 100644
index 0000000..c928fbe
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/descriptor.proto
+
+namespace Google\Protobuf\Internal;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Google\Protobuf\Internal\DescriptorProto\ExtensionRange instead.
+     * @deprecated
+     */
+    class DescriptorProto_ExtensionRange {}
+}
+class_exists(DescriptorProto\ExtensionRange::class);
+@trigger_error('Google\Protobuf\Internal\DescriptorProto_ExtensionRange is deprecated and will be removed in the next major release. Use Google\Protobuf\Internal\DescriptorProto\ExtensionRange instead', E_USER_DEPRECATED);
+
diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php
new file mode 100644
index 0000000..e49e945
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/DescriptorProto_ReservedRange.php
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/descriptor.proto
+
+namespace Google\Protobuf\Internal;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Google\Protobuf\Internal\DescriptorProto\ReservedRange instead.
+     * @deprecated
+     */
+    class DescriptorProto_ReservedRange {}
+}
+class_exists(DescriptorProto\ReservedRange::class);
+@trigger_error('Google\Protobuf\Internal\DescriptorProto_ReservedRange is deprecated and will be removed in the next major release. Use Google\Protobuf\Internal\DescriptorProto\ReservedRange instead', E_USER_DEPRECATED);
+
diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php b/php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php
new file mode 100644
index 0000000..b1b59ed
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/EnumDescriptorProto_EnumReservedRange.php
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/descriptor.proto
+
+namespace Google\Protobuf\Internal;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange instead.
+     * @deprecated
+     */
+    class EnumDescriptorProto_EnumReservedRange {}
+}
+class_exists(EnumDescriptorProto\EnumReservedRange::class);
+@trigger_error('Google\Protobuf\Internal\EnumDescriptorProto_EnumReservedRange is deprecated and will be removed in the next major release. Use Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange instead', E_USER_DEPRECATED);
+
diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php
new file mode 100644
index 0000000..218a846
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/descriptor.proto
+
+namespace Google\Protobuf\Internal;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Google\Protobuf\Internal\FieldDescriptorProto\Label instead.
+     * @deprecated
+     */
+    class FieldDescriptorProto_Label {}
+}
+class_exists(FieldDescriptorProto\Label::class);
+@trigger_error('Google\Protobuf\Internal\FieldDescriptorProto_Label is deprecated and will be removed in the next major release. Use Google\Protobuf\Internal\FieldDescriptorProto\Label instead', E_USER_DEPRECATED);
+
diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php
new file mode 100644
index 0000000..fd8d449
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto_Type.php
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/descriptor.proto
+
+namespace Google\Protobuf\Internal;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Google\Protobuf\Internal\FieldDescriptorProto\Type instead.
+     * @deprecated
+     */
+    class FieldDescriptorProto_Type {}
+}
+class_exists(FieldDescriptorProto\Type::class);
+@trigger_error('Google\Protobuf\Internal\FieldDescriptorProto_Type is deprecated and will be removed in the next major release. Use Google\Protobuf\Internal\FieldDescriptorProto\Type instead', E_USER_DEPRECATED);
+
diff --git a/php/src/Google/Protobuf/Internal/FieldOptions_CType.php b/php/src/Google/Protobuf/Internal/FieldOptions_CType.php
new file mode 100644
index 0000000..4d18783
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/FieldOptions_CType.php
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/descriptor.proto
+
+namespace Google\Protobuf\Internal;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Google\Protobuf\Internal\FieldOptions\CType instead.
+     * @deprecated
+     */
+    class FieldOptions_CType {}
+}
+class_exists(FieldOptions\CType::class);
+@trigger_error('Google\Protobuf\Internal\FieldOptions_CType is deprecated and will be removed in the next major release. Use Google\Protobuf\Internal\FieldOptions\CType instead', E_USER_DEPRECATED);
+
diff --git a/php/src/Google/Protobuf/Internal/FieldOptions_JSType.php b/php/src/Google/Protobuf/Internal/FieldOptions_JSType.php
new file mode 100644
index 0000000..9db0782
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/FieldOptions_JSType.php
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/descriptor.proto
+
+namespace Google\Protobuf\Internal;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Google\Protobuf\Internal\FieldOptions\JSType instead.
+     * @deprecated
+     */
+    class FieldOptions_JSType {}
+}
+class_exists(FieldOptions\JSType::class);
+@trigger_error('Google\Protobuf\Internal\FieldOptions_JSType is deprecated and will be removed in the next major release. Use Google\Protobuf\Internal\FieldOptions\JSType instead', E_USER_DEPRECATED);
+
diff --git a/php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php b/php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php
new file mode 100644
index 0000000..8926e63
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/FileOptions_OptimizeMode.php
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/descriptor.proto
+
+namespace Google\Protobuf\Internal;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Google\Protobuf\Internal\FileOptions\OptimizeMode instead.
+     * @deprecated
+     */
+    class FileOptions_OptimizeMode {}
+}
+class_exists(FileOptions\OptimizeMode::class);
+@trigger_error('Google\Protobuf\Internal\FileOptions_OptimizeMode is deprecated and will be removed in the next major release. Use Google\Protobuf\Internal\FileOptions\OptimizeMode instead', E_USER_DEPRECATED);
+
diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php
new file mode 100644
index 0000000..e36f1e5
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/descriptor.proto
+
+namespace Google\Protobuf\Internal;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Google\Protobuf\Internal\GeneratedCodeInfo\Annotation instead.
+     * @deprecated
+     */
+    class GeneratedCodeInfo_Annotation {}
+}
+class_exists(GeneratedCodeInfo\Annotation::class);
+@trigger_error('Google\Protobuf\Internal\GeneratedCodeInfo_Annotation is deprecated and will be removed in the next major release. Use Google\Protobuf\Internal\GeneratedCodeInfo\Annotation instead', E_USER_DEPRECATED);
+
diff --git a/php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php b/php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php
new file mode 100644
index 0000000..a291311
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/MethodOptions_IdempotencyLevel.php
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/descriptor.proto
+
+namespace Google\Protobuf\Internal;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Google\Protobuf\Internal\MethodOptions\IdempotencyLevel instead.
+     * @deprecated
+     */
+    class MethodOptions_IdempotencyLevel {}
+}
+class_exists(MethodOptions\IdempotencyLevel::class);
+@trigger_error('Google\Protobuf\Internal\MethodOptions_IdempotencyLevel is deprecated and will be removed in the next major release. Use Google\Protobuf\Internal\MethodOptions\IdempotencyLevel instead', E_USER_DEPRECATED);
+
diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php
new file mode 100644
index 0000000..1346492
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo_Location.php
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/descriptor.proto
+
+namespace Google\Protobuf\Internal;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Google\Protobuf\Internal\SourceCodeInfo\Location instead.
+     * @deprecated
+     */
+    class SourceCodeInfo_Location {}
+}
+class_exists(SourceCodeInfo\Location::class);
+@trigger_error('Google\Protobuf\Internal\SourceCodeInfo_Location is deprecated and will be removed in the next major release. Use Google\Protobuf\Internal\SourceCodeInfo\Location instead', E_USER_DEPRECATED);
+
diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php b/php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php
new file mode 100644
index 0000000..9750eb0
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/UninterpretedOption_NamePart.php
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/descriptor.proto
+
+namespace Google\Protobuf\Internal;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Google\Protobuf\Internal\UninterpretedOption\NamePart instead.
+     * @deprecated
+     */
+    class UninterpretedOption_NamePart {}
+}
+class_exists(UninterpretedOption\NamePart::class);
+@trigger_error('Google\Protobuf\Internal\UninterpretedOption_NamePart is deprecated and will be removed in the next major release. Use Google\Protobuf\Internal\UninterpretedOption\NamePart instead', E_USER_DEPRECATED);
+
diff --git a/php/tests/encode_decode_test.php b/php/tests/encode_decode_test.php
index d36b883..870daca 100644
--- a/php/tests/encode_decode_test.php
+++ b/php/tests/encode_decode_test.php
@@ -11,9 +11,90 @@
 use Foo\TestPackedMessage;
 use Foo\TestRandomFieldOrder;
 use Foo\TestUnpackedMessage;
+use Google\Protobuf\DoubleValue;
+use Google\Protobuf\FloatValue;
+use Google\Protobuf\Int32Value;
+use Google\Protobuf\UInt32Value;
+use Google\Protobuf\Int64Value;
+use Google\Protobuf\UInt64Value;
+use Google\Protobuf\BoolValue;
+use Google\Protobuf\StringValue;
+use Google\Protobuf\BytesValue;
 
 class EncodeDecodeTest extends TestBase
 {
+    public function testDecodeJsonSimple()
+    {
+        $m = new TestMessage();
+        $m->mergeFromJsonString("{\"optionalInt32\":1}");
+    }
+
+    public function testDecodeTopLevelBoolValue()
+    {
+        $m = new BoolValue();
+
+        $m->mergeFromJsonString("true");
+        $this->assertEquals(true, $m->getValue());
+
+        $m->mergeFromJsonString("false");
+        $this->assertEquals(false, $m->getValue());
+    }
+
+    public function testDecodeTopLevelDoubleValue()
+    {
+        $m = new DoubleValue();
+        $m->mergeFromJsonString("1.5");
+        $this->assertEquals(1.5, $m->getValue());
+    }
+
+    public function testDecodeTopLevelFloatValue()
+    {
+        $m = new FloatValue();
+        $m->mergeFromJsonString("1.5");
+        $this->assertEquals(1.5, $m->getValue());
+    }
+
+    public function testDecodeTopLevelInt32Value()
+    {
+        $m = new Int32Value();
+        $m->mergeFromJsonString("1");
+        $this->assertEquals(1, $m->getValue());
+    }
+
+    public function testDecodeTopLevelUInt32Value()
+    {
+        $m = new UInt32Value();
+        $m->mergeFromJsonString("1");
+        $this->assertEquals(1, $m->getValue());
+    }
+
+    public function testDecodeTopLevelInt64Value()
+    {
+        $m = new Int64Value();
+        $m->mergeFromJsonString("1");
+        $this->assertEquals(1, $m->getValue());
+    }
+
+    public function testDecodeTopLevelUInt64Value()
+    {
+        $m = new UInt64Value();
+        $m->mergeFromJsonString("1");
+        $this->assertEquals(1, $m->getValue());
+    }
+
+    public function testDecodeTopLevelStringValue()
+    {
+        $m = new StringValue();
+        $m->mergeFromJsonString("\"a\"");
+        $this->assertSame("a", $m->getValue());
+    }
+
+    public function testDecodeTopLevelBytesValue()
+    {
+        $m = new BytesValue();
+        $m->mergeFromJsonString("\"YQ==\"");
+        $this->assertSame("a", $m->getValue());
+    }
 
     public function testEncode()
     {
diff --git a/protobuf.bzl b/protobuf.bzl
index 67d61d7..ae391aa 100644
--- a/protobuf.bzl
+++ b/protobuf.bzl
@@ -178,7 +178,7 @@
         "protoc": attr.label(
             cfg = "host",
             executable = True,
-            single_file = True,
+            allow_single_file = True,
             mandatory = True,
         ),
         "plugin": attr.label(
diff --git a/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/text_format_test.py b/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/text_format_test.py
index 8267cd2..bc53e25 100755
--- a/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/text_format_test.py
+++ b/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/text_format_test.py
@@ -410,7 +410,8 @@
     text = 'optional_nested_enum: BARR'
     self.assertRaisesWithMessage(
         text_format.ParseError,
-        ('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" '
+        ('1:23 : \'optional_nested_enum: BARR\': '
+         'Enum type "protobuf_unittest.TestAllTypes.NestedEnum" '
          'has no value named BARR.'),
         text_format.Merge, text, message)
 
@@ -418,7 +419,8 @@
     text = 'optional_nested_enum: 100'
     self.assertRaisesWithMessage(
         text_format.ParseError,
-        ('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" '
+        ('1:23 : \'optional_nested_enum: 100\': '
+         'Enum type "protobuf_unittest.TestAllTypes.NestedEnum" '
          'has no value with number 100.'),
         text_format.Merge, text, message)
 
@@ -427,7 +429,8 @@
     text = 'optional_int32: bork'
     self.assertRaisesWithMessage(
         text_format.ParseError,
-        ('1:17 : Couldn\'t parse integer: bork'),
+        ('1:17 : \'optional_int32: bork\': '
+         'Couldn\'t parse integer: bork'),
         text_format.Merge, text, message)
 
   def testMergeStringFieldUnescape(self):
diff --git a/python/google/protobuf/descriptor_database.py b/python/google/protobuf/descriptor_database.py
index 8b7715c..a7616cb 100644
--- a/python/google/protobuf/descriptor_database.py
+++ b/python/google/protobuf/descriptor_database.py
@@ -76,6 +76,9 @@
         self._AddSymbol(name, file_desc_proto)
     for enum in file_desc_proto.enum_type:
       self._AddSymbol(('.'.join((package, enum.name))), file_desc_proto)
+      for enum_value in enum.value:
+        self._file_desc_protos_by_symbol[
+            '.'.join((package, enum_value.name))] = file_desc_proto
     for extension in file_desc_proto.extension:
       self._AddSymbol(('.'.join((package, extension.name))), file_desc_proto)
     for service in file_desc_proto.service:
@@ -133,6 +136,14 @@
       top_level, _, _ = symbol.rpartition('.')
       return self._file_desc_protos_by_symbol[top_level]
 
+  def FindFileContainingExtension(self, extendee_name, extension_number):
+    # TODO(jieluo): implement this API.
+    return None
+
+  def FindAllExtensionNumbers(self, extendee_name):
+    # TODO(jieluo): implement this API.
+    return []
+
   def _AddSymbol(self, name, file_desc_proto):
     if name in self._file_desc_protos_by_symbol:
       warn_msg = ('Conflict register for file "' + file_desc_proto.name +
diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py
index 8983f76..42f7bcb 100644
--- a/python/google/protobuf/descriptor_pool.py
+++ b/python/google/protobuf/descriptor_pool.py
@@ -131,33 +131,46 @@
     # TODO(jieluo): Remove _file_desc_by_toplevel_extension after
     # maybe year 2020 for compatibility issue (with 3.4.1 only).
     self._file_desc_by_toplevel_extension = {}
+    self._top_enum_values = {}
     # We store extensions in two two-level mappings: The first key is the
     # descriptor of the message being extended, the second key is the extension
     # full name or its tag number.
     self._extensions_by_name = collections.defaultdict(dict)
     self._extensions_by_number = collections.defaultdict(dict)
 
-  def _CheckConflictRegister(self, desc):
+  def _CheckConflictRegister(self, desc, desc_name, file_name):
     """Check if the descriptor name conflicts with another of the same name.
 
     Args:
-      desc: Descriptor of a message, enum, service or extension.
+      desc: Descriptor of a message, enum, service, extension or enum value.
+      desc_name: the full name of desc.
+      file_name: The file name of descriptor.
     """
-    desc_name = desc.full_name
     for register, descriptor_type in [
         (self._descriptors, descriptor.Descriptor),
         (self._enum_descriptors, descriptor.EnumDescriptor),
         (self._service_descriptors, descriptor.ServiceDescriptor),
-        (self._toplevel_extensions, descriptor.FieldDescriptor)]:
+        (self._toplevel_extensions, descriptor.FieldDescriptor),
+        (self._top_enum_values, descriptor.EnumValueDescriptor)]:
       if desc_name in register:
-        file_name = register[desc_name].file.name
+        old_desc = register[desc_name]
+        if isinstance(old_desc, descriptor.EnumValueDescriptor):
+          old_file = old_desc.type.file.name
+        else:
+          old_file = old_desc.file.name
+
         if not isinstance(desc, descriptor_type) or (
-            file_name != desc.file.name):
-          warn_msg = ('Conflict register for file "' + desc.file.name +
+            old_file != file_name):
+          warn_msg = ('Conflict register for file "' + file_name +
                       '": ' + desc_name +
                       ' is already defined in file "' +
-                      file_name + '"')
+                      old_file + '"')
+          if isinstance(desc, descriptor.EnumValueDescriptor):
+            warn_msg += ('\nNote: enum values appear as '
+                         'siblings of the enum type instead of '
+                         'children of it.')
           warnings.warn(warn_msg, RuntimeWarning)
+
         return
 
   def Add(self, file_desc_proto):
@@ -196,7 +209,7 @@
     if not isinstance(desc, descriptor.Descriptor):
       raise TypeError('Expected instance of descriptor.Descriptor.')
 
-    self._CheckConflictRegister(desc)
+    self._CheckConflictRegister(desc, desc.full_name, desc.file.name)
 
     self._descriptors[desc.full_name] = desc
     self._AddFileDescriptor(desc.file)
@@ -213,8 +226,26 @@
     if not isinstance(enum_desc, descriptor.EnumDescriptor):
       raise TypeError('Expected instance of descriptor.EnumDescriptor.')
 
-    self._CheckConflictRegister(enum_desc)
+    file_name = enum_desc.file.name
+    self._CheckConflictRegister(enum_desc, enum_desc.full_name, file_name)
     self._enum_descriptors[enum_desc.full_name] = enum_desc
+
+    # Top enum values need to be indexed.
+    # Count the number of dots to see whether the enum is toplevel or nested
+    # in a message. We cannot use enum_desc.containing_type at this stage.
+    if enum_desc.file.package:
+      top_level = (enum_desc.full_name.count('.')
+                   - enum_desc.file.package.count('.') == 1)
+    else:
+      top_level = enum_desc.full_name.count('.') == 0
+    if top_level:
+      file_name = enum_desc.file.name
+      package = enum_desc.file.package
+      for enum_value in enum_desc.values:
+        full_name = _NormalizeFullyQualifiedName(
+            '.'.join((package, enum_value.name)))
+        self._CheckConflictRegister(enum_value, full_name, file_name)
+        self._top_enum_values[full_name] = enum_value
     self._AddFileDescriptor(enum_desc.file)
 
   def AddServiceDescriptor(self, service_desc):
@@ -227,7 +258,8 @@
     if not isinstance(service_desc, descriptor.ServiceDescriptor):
       raise TypeError('Expected instance of descriptor.ServiceDescriptor.')
 
-    self._CheckConflictRegister(service_desc)
+    self._CheckConflictRegister(service_desc, service_desc.full_name,
+                                service_desc.file.name)
     self._service_descriptors[service_desc.full_name] = service_desc
 
   def AddExtensionDescriptor(self, extension):
@@ -247,7 +279,6 @@
       raise TypeError('Expected an extension descriptor.')
 
     if extension.extension_scope is None:
-      self._CheckConflictRegister(extension)
       self._toplevel_extensions[extension.full_name] = extension
 
     try:
@@ -349,6 +380,30 @@
 
     symbol = _NormalizeFullyQualifiedName(symbol)
     try:
+      return self._InternalFindFileContainingSymbol(symbol)
+    except KeyError:
+      pass
+
+    try:
+      # Try fallback database. Build and find again if possible.
+      self._FindFileContainingSymbolInDb(symbol)
+      return self._InternalFindFileContainingSymbol(symbol)
+    except KeyError:
+      raise KeyError('Cannot find a file containing %s' % symbol)
+
+  def _InternalFindFileContainingSymbol(self, symbol):
+    """Gets the already built FileDescriptor containing the specified symbol.
+
+    Args:
+      symbol: The name of the symbol to search for.
+
+    Returns:
+      A FileDescriptor that contains the specified symbol.
+
+    Raises:
+      KeyError: if the file cannot be found in the pool.
+    """
+    try:
       return self._descriptors[symbol].file
     except KeyError:
       pass
@@ -364,7 +419,7 @@
       pass
 
     try:
-      return self._FindFileContainingSymbolInDb(symbol)
+      return self._top_enum_values[symbol].type.file
     except KeyError:
       pass
 
@@ -373,13 +428,15 @@
     except KeyError:
       pass
 
-    # Try nested extensions inside a message.
-    message_name, _, extension_name = symbol.rpartition('.')
+    # Try fields, enum values and nested extensions inside a message.
+    top_name, _, sub_name = symbol.rpartition('.')
     try:
-      message = self.FindMessageTypeByName(message_name)
-      assert message.extensions_by_name[extension_name]
+      message = self.FindMessageTypeByName(top_name)
+      assert (sub_name in message.extensions_by_name or
+              sub_name in message.fields_by_name or
+              sub_name in message.enum_values_by_name)
       return message.file
-    except KeyError:
+    except (KeyError, AssertionError):
       raise KeyError('Cannot find a file containing %s' % symbol)
 
   def FindMessageTypeByName(self, full_name):
@@ -499,7 +556,11 @@
       KeyError: when no extension with the given number is known for the
         specified message.
     """
-    return self._extensions_by_number[message_descriptor][number]
+    try:
+      return self._extensions_by_number[message_descriptor][number]
+    except KeyError:
+      self._TryLoadExtensionFromDB(message_descriptor, number)
+      return self._extensions_by_number[message_descriptor][number]
 
   def FindAllExtensions(self, message_descriptor):
     """Gets all the known extension of a given message.
@@ -513,8 +574,57 @@
     Returns:
       A list of FieldDescriptor describing the extensions.
     """
+    # Fallback to descriptor db if FindAllExtensionNumbers is provided.
+    if self._descriptor_db and hasattr(
+        self._descriptor_db, 'FindAllExtensionNumbers'):
+      full_name = message_descriptor.full_name
+      all_numbers = self._descriptor_db.FindAllExtensionNumbers(full_name)
+      for number in all_numbers:
+        if number in self._extensions_by_number[message_descriptor]:
+          continue
+        self._TryLoadExtensionFromDB(message_descriptor, number)
+
     return list(self._extensions_by_number[message_descriptor].values())
 
+  def _TryLoadExtensionFromDB(self, message_descriptor, number):
+    """Try to Load extensions from decriptor db.
+
+    Args:
+      message_descriptor: descriptor of the extended message.
+      number: the extension number that needs to be loaded.
+    """
+    if not self._descriptor_db:
+      return
+    # Only supported when FindFileContainingExtension is provided.
+    if not hasattr(
+        self._descriptor_db, 'FindFileContainingExtension'):
+      return
+
+    full_name = message_descriptor.full_name
+    file_proto = self._descriptor_db.FindFileContainingExtension(
+        full_name, number)
+
+    if file_proto is None:
+      return
+
+    try:
+      file_desc = self._ConvertFileProtoToFileDescriptor(file_proto)
+      for extension in file_desc.extensions_by_name.values():
+        self._extensions_by_number[extension.containing_type][
+            extension.number] = extension
+        self._extensions_by_name[extension.containing_type][
+            extension.full_name] = extension
+      for message_type in file_desc.message_types_by_name.values():
+        for extension in message_type.extensions:
+          self._extensions_by_number[extension.containing_type][
+              extension.number] = extension
+          self._extensions_by_name[extension.containing_type][
+              extension.full_name] = extension
+    except:
+      warn_msg = ('Unable to load proto file %s for extension number %d.' %
+                  (file_proto.name, number))
+      warnings.warn(warn_msg, RuntimeWarning)
+
   def FindServiceByName(self, full_name):
     """Loads the named service descriptor from the pool.
 
@@ -532,6 +642,23 @@
       self._FindFileContainingSymbolInDb(full_name)
     return self._service_descriptors[full_name]
 
+  def FindMethodByName(self, full_name):
+    """Loads the named service method descriptor from the pool.
+
+    Args:
+      full_name: The full name of the method descriptor to load.
+
+    Returns:
+      The method descriptor for the service method.
+
+    Raises:
+      KeyError: if the method cannot be found in the pool.
+    """
+    full_name = _NormalizeFullyQualifiedName(full_name)
+    service_name, _, method_name = full_name.rpartition('.')
+    service_descriptor = self.FindServiceByName(service_name)
+    return service_descriptor.methods_by_name[method_name]
+
   def _FindFileContainingSymbolInDb(self, symbol):
     """Finds the file in descriptor DB containing the specified symbol.
 
@@ -567,7 +694,6 @@
     Returns:
       A FileDescriptor matching the passed in proto.
     """
-
     if file_proto.name not in self._file_descriptors:
       built_deps = list(self._GetDeps(file_proto.dependency))
       direct_deps = [self.FindFileByName(n) for n in file_proto.dependency]
@@ -604,7 +730,7 @@
       for enum_type in file_proto.enum_type:
         file_descriptor.enum_types_by_name[enum_type.name] = (
             self._ConvertEnumDescriptor(enum_type, file_proto.package,
-                                        file_descriptor, None, scope))
+                                        file_descriptor, None, scope, True))
 
       for index, extension_proto in enumerate(file_proto.extension):
         extension_desc = self._MakeFieldDescriptor(
@@ -616,6 +742,8 @@
                            file_descriptor.package, scope)
         file_descriptor.extensions_by_name[extension_desc.name] = (
             extension_desc)
+        self._file_desc_by_toplevel_extension[extension_desc.full_name] = (
+            file_descriptor)
 
       for desc_proto in file_proto.message_type:
         self._SetAllFieldTypes(file_proto.package, desc_proto, scope)
@@ -673,7 +801,8 @@
             nested, desc_name, file_desc, scope, syntax)
         for nested in desc_proto.nested_type]
     enums = [
-        self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope)
+        self._ConvertEnumDescriptor(enum, desc_name, file_desc, None,
+                                    scope, False)
         for enum in desc_proto.enum_type]
     fields = [self._MakeFieldDescriptor(field, desc_name, index, file_desc)
               for index, field in enumerate(desc_proto.field)]
@@ -718,12 +847,12 @@
         fields[field_index].containing_oneof = oneofs[oneof_index]
 
     scope[_PrefixWithDot(desc_name)] = desc
-    self._CheckConflictRegister(desc)
+    self._CheckConflictRegister(desc, desc.full_name, desc.file.name)
     self._descriptors[desc_name] = desc
     return desc
 
   def _ConvertEnumDescriptor(self, enum_proto, package=None, file_desc=None,
-                             containing_type=None, scope=None):
+                             containing_type=None, scope=None, top_level=False):
     """Make a protobuf EnumDescriptor given an EnumDescriptorProto protobuf.
 
     Args:
@@ -732,6 +861,8 @@
       file_desc: The file containing the enum descriptor.
       containing_type: The type containing this enum.
       scope: Scope containing available types.
+      top_level: If True, the enum is a top level symbol. If False, the enum
+          is defined inside a message.
 
     Returns:
       The added descriptor
@@ -757,8 +888,17 @@
                                      containing_type=containing_type,
                                      options=_OptionsOrNone(enum_proto))
     scope['.%s' % enum_name] = desc
-    self._CheckConflictRegister(desc)
+    self._CheckConflictRegister(desc, desc.full_name, desc.file.name)
     self._enum_descriptors[enum_name] = desc
+
+    # Add top level enum values.
+    if top_level:
+      for value in values:
+        full_name = _NormalizeFullyQualifiedName(
+            '.'.join((package, value.name)))
+        self._CheckConflictRegister(value, full_name, file_name)
+        self._top_enum_values[full_name] = value
+
     return desc
 
   def _MakeFieldDescriptor(self, field_proto, message_name, index,
@@ -885,6 +1025,8 @@
       elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES:
         field_desc.default_value = text_encoding.CUnescape(
             field_proto.default_value)
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE:
+        field_desc.default_value = None
       else:
         # All other types are of the "int" type.
         field_desc.default_value = int(field_proto.default_value)
@@ -901,6 +1043,8 @@
         field_desc.default_value = field_desc.enum_type.values[0].number
       elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES:
         field_desc.default_value = b''
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE:
+        field_desc.default_value = None
       else:
         # All other types are of the "int" type.
         field_desc.default_value = 0
@@ -954,7 +1098,7 @@
                                         methods=methods,
                                         options=_OptionsOrNone(service_proto),
                                         file=file_desc)
-    self._CheckConflictRegister(desc)
+    self._CheckConflictRegister(desc, desc.full_name, desc.file.name)
     self._service_descriptors[service_name] = desc
     return desc
 
diff --git a/python/google/protobuf/internal/__init__.py b/python/google/protobuf/internal/__init__.py
index e69de29..7d2e571 100755
--- a/python/google/protobuf/internal/__init__.py
+++ b/python/google/protobuf/internal/__init__.py
@@ -0,0 +1,30 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/python/google/protobuf/internal/api_implementation.py b/python/google/protobuf/internal/api_implementation.py
index ab9e781..23cc2c0 100755
--- a/python/google/protobuf/internal/api_implementation.py
+++ b/python/google/protobuf/internal/api_implementation.py
@@ -145,29 +145,3 @@
 # For internal use only
 def IsPythonDefaultSerializationDeterministic():
   return _python_deterministic_proto_serialization
-
-# DO NOT USE: For migration and testing only. Will be removed when Proto3
-# defaults to preserve unknowns.
-if _implementation_type == 'cpp':
-  try:
-    # pylint: disable=g-import-not-at-top
-    from google.protobuf.pyext import _message
-
-    def GetPythonProto3PreserveUnknownsDefault():
-      return _message.GetPythonProto3PreserveUnknownsDefault()
-
-    def SetPythonProto3PreserveUnknownsDefault(preserve):
-      _message.SetPythonProto3PreserveUnknownsDefault(preserve)
-  except ImportError:
-    # Unrecognized cpp implementation. Skipping the unknown fields APIs.
-    pass
-else:
-  _python_proto3_preserve_unknowns_default = True
-
-  def GetPythonProto3PreserveUnknownsDefault():
-    return _python_proto3_preserve_unknowns_default
-
-  def SetPythonProto3PreserveUnknownsDefault(preserve):
-    global _python_proto3_preserve_unknowns_default
-    _python_proto3_preserve_unknowns_default = preserve
-
diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py
index c6a3692..182cac9 100755
--- a/python/google/protobuf/internal/containers.py
+++ b/python/google/protobuf/internal/containers.py
@@ -628,3 +628,130 @@
 
   def GetEntryClass(self):
     return self._entry_descriptor._concrete_class
+
+
+class _UnknownField(object):
+
+  """A parsed unknown field."""
+
+  # Disallows assignment to other attributes.
+  __slots__ = ['_field_number', '_wire_type', '_data']
+
+  def __init__(self, field_number, wire_type, data):
+    self._field_number = field_number
+    self._wire_type = wire_type
+    self._data = data
+    return
+
+  def __lt__(self, other):
+    # pylint: disable=protected-access
+    return self._field_number < other._field_number
+
+  def __eq__(self, other):
+    if self is other:
+      return True
+    # pylint: disable=protected-access
+    return (self._field_number == other._field_number and
+            self._wire_type == other._wire_type and
+            self._data == other._data)
+
+
+class UnknownFieldRef(object):
+
+  def __init__(self, parent, index):
+    self._parent = parent
+    self._index = index
+    return
+
+  def _check_valid(self):
+    if not self._parent:
+      raise ValueError('UnknownField does not exist. '
+                       'The parent message might be cleared.')
+    if self._index >= len(self._parent):
+      raise ValueError('UnknownField does not exist. '
+                       'The parent message might be cleared.')
+
+  @property
+  def field_number(self):
+    self._check_valid()
+    # pylint: disable=protected-access
+    return self._parent._internal_get(self._index)._field_number
+
+  @property
+  def wire_type(self):
+    self._check_valid()
+    # pylint: disable=protected-access
+    return self._parent._internal_get(self._index)._wire_type
+
+  @property
+  def data(self):
+    self._check_valid()
+    # pylint: disable=protected-access
+    return self._parent._internal_get(self._index)._data
+
+
+class UnknownFieldSet(object):
+
+  """UnknownField container"""
+
+  # Disallows assignment to other attributes.
+  __slots__ = ['_values']
+
+  def __init__(self):
+    self._values = []
+
+  def __getitem__(self, index):
+    if self._values is None:
+      raise ValueError('UnknownFields does not exist. '
+                       'The parent message might be cleared.')
+    size = len(self._values)
+    if index < 0:
+      index += size
+    if index < 0 or index >= size:
+      raise IndexError('index %d out of range'.index)
+
+    return UnknownFieldRef(self, index)
+
+  def _internal_get(self, index):
+    return self._values[index]
+
+  def __len__(self):
+    if self._values is None:
+      raise ValueError('UnknownFields does not exist. '
+                       'The parent message might be cleared.')
+    return len(self._values)
+
+  def _add(self, field_number, wire_type, data):
+    unknown_field = _UnknownField(field_number, wire_type, data)
+    self._values.append(unknown_field)
+    return unknown_field
+
+  def __iter__(self):
+    for i in range(len(self)):
+      yield UnknownFieldRef(self, i)
+
+  def _extend(self, other):
+    if other is None:
+      return
+    # pylint: disable=protected-access
+    self._values.extend(other._values)
+
+  def __eq__(self, other):
+    if self is other:
+      return True
+    # Sort unknown fields because their order shouldn't
+    # affect equality test.
+    values = list(self._values)
+    if other is None:
+      return not values
+    values.sort()
+    # pylint: disable=protected-access
+    other_values = sorted(other._values)
+    return values == other_values
+
+  def _clear(self):
+    for value in self._values:
+      # pylint: disable=protected-access
+      if isinstance(value._data, UnknownFieldSet):
+        value._data._clear()  # pylint: disable=protected-access
+    self._values = None
diff --git a/python/google/protobuf/internal/decoder.py b/python/google/protobuf/internal/decoder.py
index 52b6491..d2ec4f7 100755
--- a/python/google/protobuf/internal/decoder.py
+++ b/python/google/protobuf/internal/decoder.py
@@ -83,10 +83,16 @@
 import struct
 
 import six
+import sys
 
+_UCS2_MAXUNICODE = 65535
 if six.PY3:
   long = int
+else:
+  import re    # pylint: disable=g-import-not-at-top
+  _SURROGATE_PATTERN = re.compile(six.u(r'[\ud800-\udfff]'))
 
+from google.protobuf.internal import containers
 from google.protobuf.internal import encoder
 from google.protobuf.internal import wire_format
 from google.protobuf import message
@@ -167,7 +173,7 @@
 
 
 def ReadTag(buffer, pos):
-  """Read a tag from the buffer, and return a (tag_bytes, new_pos) tuple.
+  """Read a tag from the memoryview, and return a (tag_bytes, new_pos) tuple.
 
   We return the raw bytes of the tag rather than decoding them.  The raw
   bytes can then be used to look up the proper decoder.  This effectively allows
@@ -175,13 +181,21 @@
   for work that is done in C (searching for a byte string in a hash table).
   In a low-level language it would be much cheaper to decode the varint and
   use that, but not in Python.
-  """
 
+  Args:
+    buffer: memoryview object of the encoded bytes
+    pos: int of the current position to start from
+
+  Returns:
+    Tuple[bytes, int] of the tag data and new position.
+  """
   start = pos
   while six.indexbytes(buffer, pos) & 0x80:
     pos += 1
   pos += 1
-  return (six.binary_type(buffer[start:pos]), pos)
+
+  tag_bytes = buffer[start:pos].tobytes()
+  return tag_bytes, pos
 
 
 # --------------------------------------------------------------------
@@ -295,10 +309,20 @@
   local_unpack = struct.unpack
 
   def InnerDecode(buffer, pos):
+    """Decode serialized float to a float and new position.
+
+    Args:
+      buffer: memoryview of the serialized bytes
+      pos: int, position in the memory view to start at.
+
+    Returns:
+      Tuple[float, int] of the deserialized float value and new position
+      in the serialized data.
+    """
     # We expect a 32-bit value in little-endian byte order.  Bit 1 is the sign
     # bit, bits 2-9 represent the exponent, and bits 10-32 are the significand.
     new_pos = pos + 4
-    float_bytes = buffer[pos:new_pos]
+    float_bytes = buffer[pos:new_pos].tobytes()
 
     # If this value has all its exponent bits set, then it's non-finite.
     # In Python 2.4, struct.unpack will convert it to a finite 64-bit value.
@@ -329,10 +353,20 @@
   local_unpack = struct.unpack
 
   def InnerDecode(buffer, pos):
+    """Decode serialized double to a double and new position.
+
+    Args:
+      buffer: memoryview of the serialized bytes.
+      pos: int, position in the memory view to start at.
+
+    Returns:
+      Tuple[float, int] of the decoded double value and new position
+      in the serialized data.
+    """
     # We expect a 64-bit value in little-endian byte order.  Bit 1 is the sign
     # bit, bits 2-12 represent the exponent, and bits 13-64 are the significand.
     new_pos = pos + 8
-    double_bytes = buffer[pos:new_pos]
+    double_bytes = buffer[pos:new_pos].tobytes()
 
     # If this value has all its exponent bits set and at least one significand
     # bit set, it's not a number.  In Python 2.4, struct.unpack will treat it
@@ -355,6 +389,18 @@
   if is_packed:
     local_DecodeVarint = _DecodeVarint
     def DecodePackedField(buffer, pos, end, message, field_dict):
+      """Decode serialized packed enum to its value and a new position.
+
+      Args:
+        buffer: memoryview of the serialized bytes.
+        pos: int, position in the memory view to start at.
+        end: int, end position of serialized data
+        message: Message object to store unknown fields in
+        field_dict: Map[Descriptor, Any] to store decoded values in.
+
+      Returns:
+        int, new position in serialized data.
+      """
       value = field_dict.get(key)
       if value is None:
         value = field_dict.setdefault(key, new_default(message))
@@ -365,6 +411,7 @@
       while pos < endpoint:
         value_start_pos = pos
         (element, pos) = _DecodeSignedVarint32(buffer, pos)
+        # pylint: disable=protected-access
         if element in enum_type.values_by_number:
           value.append(element)
         else:
@@ -372,8 +419,10 @@
             message._unknown_fields = []
           tag_bytes = encoder.TagBytes(field_number,
                                        wire_format.WIRETYPE_VARINT)
+
           message._unknown_fields.append(
-              (tag_bytes, buffer[value_start_pos:pos]))
+              (tag_bytes, buffer[value_start_pos:pos].tobytes()))
+          # pylint: enable=protected-access
       if pos > endpoint:
         if element in enum_type.values_by_number:
           del value[-1]   # Discard corrupt value.
@@ -386,18 +435,32 @@
     tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT)
     tag_len = len(tag_bytes)
     def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+      """Decode serialized repeated enum to its value and a new position.
+
+      Args:
+        buffer: memoryview of the serialized bytes.
+        pos: int, position in the memory view to start at.
+        end: int, end position of serialized data
+        message: Message object to store unknown fields in
+        field_dict: Map[Descriptor, Any] to store decoded values in.
+
+      Returns:
+        int, new position in serialized data.
+      """
       value = field_dict.get(key)
       if value is None:
         value = field_dict.setdefault(key, new_default(message))
       while 1:
         (element, new_pos) = _DecodeSignedVarint32(buffer, pos)
+        # pylint: disable=protected-access
         if element in enum_type.values_by_number:
           value.append(element)
         else:
           if not message._unknown_fields:
             message._unknown_fields = []
           message._unknown_fields.append(
-              (tag_bytes, buffer[pos:new_pos]))
+              (tag_bytes, buffer[pos:new_pos].tobytes()))
+          # pylint: enable=protected-access
         # Predict that the next tag is another copy of the same repeated
         # field.
         pos = new_pos + tag_len
@@ -409,10 +472,23 @@
     return DecodeRepeatedField
   else:
     def DecodeField(buffer, pos, end, message, field_dict):
+      """Decode serialized repeated enum to its value and a new position.
+
+      Args:
+        buffer: memoryview of the serialized bytes.
+        pos: int, position in the memory view to start at.
+        end: int, end position of serialized data
+        message: Message object to store unknown fields in
+        field_dict: Map[Descriptor, Any] to store decoded values in.
+
+      Returns:
+        int, new position in serialized data.
+      """
       value_start_pos = pos
       (enum_value, pos) = _DecodeSignedVarint32(buffer, pos)
       if pos > end:
         raise _DecodeError('Truncated message.')
+      # pylint: disable=protected-access
       if enum_value in enum_type.values_by_number:
         field_dict[key] = enum_value
       else:
@@ -421,7 +497,8 @@
         tag_bytes = encoder.TagBytes(field_number,
                                      wire_format.WIRETYPE_VARINT)
         message._unknown_fields.append(
-          (tag_bytes, buffer[value_start_pos:pos]))
+            (tag_bytes, buffer[value_start_pos:pos].tobytes()))
+        # pylint: enable=protected-access
       return pos
     return DecodeField
 
@@ -458,20 +535,34 @@
     wire_format.WIRETYPE_VARINT, _DecodeVarint, bool)
 
 
-def StringDecoder(field_number, is_repeated, is_packed, key, new_default):
+def StringDecoder(field_number, is_repeated, is_packed, key, new_default,
+                  is_strict_utf8=False):
   """Returns a decoder for a string field."""
 
   local_DecodeVarint = _DecodeVarint
   local_unicode = six.text_type
 
-  def _ConvertToUnicode(byte_str):
+  def _ConvertToUnicode(memview):
+    """Convert byte to unicode."""
+    byte_str = memview.tobytes()
     try:
-      return local_unicode(byte_str, 'utf-8')
+      value = local_unicode(byte_str, 'utf-8')
     except UnicodeDecodeError as e:
       # add more information to the error message and re-raise it.
       e.reason = '%s in field: %s' % (e, key.full_name)
       raise
 
+    if is_strict_utf8 and six.PY2 and sys.maxunicode > _UCS2_MAXUNICODE:
+      # Only do the check for python2 ucs4 when is_strict_utf8 enabled
+      if _SURROGATE_PATTERN.search(value):
+        reason = ('String field %s contains invalid UTF-8 data when parsing'
+                  'a protocol buffer: surrogates not allowed. Use'
+                  'the bytes type if you intend to send raw bytes.') % (
+                      key.full_name)
+        raise message.DecodeError(reason)
+
+    return value
+
   assert not is_packed
   if is_repeated:
     tag_bytes = encoder.TagBytes(field_number,
@@ -523,7 +614,7 @@
         new_pos = pos + size
         if new_pos > end:
           raise _DecodeError('Truncated string.')
-        value.append(buffer[pos:new_pos])
+        value.append(buffer[pos:new_pos].tobytes())
         # Predict that the next tag is another copy of the same repeated field.
         pos = new_pos + tag_len
         if buffer[new_pos:pos] != tag_bytes or new_pos == end:
@@ -536,7 +627,7 @@
       new_pos = pos + size
       if new_pos > end:
         raise _DecodeError('Truncated string.')
-      field_dict[key] = buffer[pos:new_pos]
+      field_dict[key] = buffer[pos:new_pos].tobytes()
       return new_pos
     return DecodeField
 
@@ -665,6 +756,18 @@
   local_SkipField = SkipField
 
   def DecodeItem(buffer, pos, end, message, field_dict):
+    """Decode serialized message set to its value and new position.
+
+    Args:
+      buffer: memoryview of the serialized bytes.
+      pos: int, position in the memory view to start at.
+      end: int, end position of serialized data
+      message: Message object to store unknown fields in
+      field_dict: Map[Descriptor, Any] to store decoded values in.
+
+    Returns:
+      int, new position in serialized data.
+    """
     message_set_item_start = pos
     type_id = -1
     message_start = -1
@@ -695,6 +798,7 @@
       raise _DecodeError('MessageSet item missing message.')
 
     extension = message.Extensions._FindExtensionByNumber(type_id)
+    # pylint: disable=protected-access
     if extension is not None:
       value = field_dict.get(extension)
       if value is None:
@@ -707,8 +811,9 @@
     else:
       if not message._unknown_fields:
         message._unknown_fields = []
-      message._unknown_fields.append((MESSAGE_SET_ITEM_TAG,
-                                      buffer[message_set_item_start:pos]))
+      message._unknown_fields.append(
+          (MESSAGE_SET_ITEM_TAG, buffer[message_set_item_start:pos].tobytes()))
+      # pylint: enable=protected-access
 
     return pos
 
@@ -767,7 +872,7 @@
   # Previously ord(buffer[pos]) raised IndexError when pos is out of range.
   # With this code, ord(b'') raises TypeError.  Both are handled in
   # python_message.py to generate a 'Truncated message' error.
-  while ord(buffer[pos:pos+1]) & 0x80:
+  while ord(buffer[pos:pos+1].tobytes()) & 0x80:
     pos += 1
   pos += 1
   if pos > end:
@@ -782,6 +887,13 @@
     raise _DecodeError('Truncated message.')
   return pos
 
+
+def _DecodeFixed64(buffer, pos):
+  """Decode a fixed64."""
+  new_pos = pos + 8
+  return (struct.unpack('<Q', buffer[pos:new_pos])[0], new_pos)
+
+
 def _SkipLengthDelimited(buffer, pos, end):
   """Skip a length-delimited value.  Returns the new position."""
 
@@ -791,6 +903,7 @@
     raise _DecodeError('Truncated message.')
   return pos
 
+
 def _SkipGroup(buffer, pos, end):
   """Skip sub-group.  Returns the new position."""
 
@@ -801,11 +914,53 @@
       return pos
     pos = new_pos
 
+
+def _DecodeGroup(buffer, pos):
+  """Decode group.  Returns the UnknownFieldSet and new position."""
+
+  unknown_field_set = containers.UnknownFieldSet()
+  while 1:
+    (tag_bytes, pos) = ReadTag(buffer, pos)
+    (tag, _) = _DecodeVarint(tag_bytes, 0)
+    field_number, wire_type = wire_format.UnpackTag(tag)
+    if wire_type == wire_format.WIRETYPE_END_GROUP:
+      break
+    (data, pos) = _DecodeUnknownField(buffer, pos, wire_type)
+    # pylint: disable=protected-access
+    unknown_field_set._add(field_number, wire_type, data)
+
+  return (unknown_field_set, pos)
+
+
+def _DecodeUnknownField(buffer, pos, wire_type):
+  """Decode a unknown field.  Returns the UnknownField and new position."""
+
+  if wire_type == wire_format.WIRETYPE_VARINT:
+    (data, pos) = _DecodeVarint(buffer, pos)
+  elif wire_type == wire_format.WIRETYPE_FIXED64:
+    (data, pos) = _DecodeFixed64(buffer, pos)
+  elif wire_type == wire_format.WIRETYPE_FIXED32:
+    (data, pos) = _DecodeFixed32(buffer, pos)
+  elif wire_type == wire_format.WIRETYPE_LENGTH_DELIMITED:
+    (size, pos) = _DecodeVarint(buffer, pos)
+    data = buffer[pos:pos+size]
+    pos += size
+  elif wire_type == wire_format.WIRETYPE_START_GROUP:
+    (data, pos) = _DecodeGroup(buffer, pos)
+  elif wire_type == wire_format.WIRETYPE_END_GROUP:
+    return (0, -1)
+  else:
+    raise _DecodeError('Wrong wire type in tag.')
+
+  return (data, pos)
+
+
 def _EndGroup(buffer, pos, end):
   """Skipping an END_GROUP tag returns -1 to tell the parent loop to break."""
 
   return -1
 
+
 def _SkipFixed32(buffer, pos, end):
   """Skip a fixed32 value.  Returns the new position."""
 
@@ -814,6 +969,14 @@
     raise _DecodeError('Truncated message.')
   return pos
 
+
+def _DecodeFixed32(buffer, pos):
+  """Decode a fixed32."""
+
+  new_pos = pos + 4
+  return (struct.unpack('<I', buffer[pos:new_pos])[0], new_pos)
+
+
 def _RaiseInvalidWireType(buffer, pos, end):
   """Skip function for unknown wire types.  Raises an exception."""
 
diff --git a/python/google/protobuf/internal/descriptor_database_test.py b/python/google/protobuf/internal/descriptor_database_test.py
index f97477b..97e5315 100644
--- a/python/google/protobuf/internal/descriptor_database_test.py
+++ b/python/google/protobuf/internal/descriptor_database_test.py
@@ -43,6 +43,7 @@
 from google.protobuf import unittest_pb2
 from google.protobuf import descriptor_pb2
 from google.protobuf.internal import factory_test2_pb2
+from google.protobuf.internal import no_package_pb2
 from google.protobuf import descriptor_database
 
 
@@ -52,7 +53,10 @@
     db = descriptor_database.DescriptorDatabase()
     file_desc_proto = descriptor_pb2.FileDescriptorProto.FromString(
         factory_test2_pb2.DESCRIPTOR.serialized_pb)
+    file_desc_proto2 = descriptor_pb2.FileDescriptorProto.FromString(
+        no_package_pb2.DESCRIPTOR.serialized_pb)
     db.Add(file_desc_proto)
+    db.Add(file_desc_proto2)
 
     self.assertEqual(file_desc_proto, db.FindFileByName(
         'google/protobuf/internal/factory_test2.proto'))
@@ -76,6 +80,10 @@
     # Can find enum value.
     self.assertEqual(file_desc_proto, db.FindFileContainingSymbol(
         'google.protobuf.python.internal.Factory2Enum.FACTORY_2_VALUE_0'))
+    self.assertEqual(file_desc_proto, db.FindFileContainingSymbol(
+        'google.protobuf.python.internal.FACTORY_2_VALUE_0'))
+    self.assertEqual(file_desc_proto2, db.FindFileContainingSymbol(
+        '.NO_PACKAGE_VALUE_0'))
     # Can find top level extension.
     self.assertEqual(file_desc_proto, db.FindFileContainingSymbol(
         'google.protobuf.python.internal.another_field'))
diff --git a/python/google/protobuf/internal/descriptor_pool_test.py b/python/google/protobuf/internal/descriptor_pool_test.py
index 2cbf781..1b72b0b 100644
--- a/python/google/protobuf/internal/descriptor_pool_test.py
+++ b/python/google/protobuf/internal/descriptor_pool_test.py
@@ -36,7 +36,6 @@
 
 import copy
 import os
-import sys
 import warnings
 
 try:
@@ -55,6 +54,7 @@
 from google.protobuf.internal import factory_test2_pb2
 from google.protobuf.internal import file_options_test_pb2
 from google.protobuf.internal import more_messages_pb2
+from google.protobuf.internal import no_package_pb2
 from google.protobuf import descriptor
 from google.protobuf import descriptor_database
 from google.protobuf import descriptor_pool
@@ -120,7 +120,6 @@
     self.assertIsInstance(file_desc5, descriptor.FileDescriptor)
     self.assertEqual('google/protobuf/unittest.proto',
                      file_desc5.name)
-
     # Tests the generated pool.
     assert descriptor_pool.Default().FindFileContainingSymbol(
         'google.protobuf.python.internal.Factory2Message.one_more_field')
@@ -129,6 +128,32 @@
     assert descriptor_pool.Default().FindFileContainingSymbol(
         'protobuf_unittest.TestService')
 
+    # Can find field.
+    file_desc6 = self.pool.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory1Message.list_value')
+    self.assertIsInstance(file_desc6, descriptor.FileDescriptor)
+    self.assertEqual('google/protobuf/internal/factory_test1.proto',
+                     file_desc6.name)
+
+    # Can find top level Enum value.
+    file_desc7 = self.pool.FindFileContainingSymbol(
+        'google.protobuf.python.internal.FACTORY_1_VALUE_0')
+    self.assertIsInstance(file_desc7, descriptor.FileDescriptor)
+    self.assertEqual('google/protobuf/internal/factory_test1.proto',
+                     file_desc7.name)
+
+    # Can find nested Enum value.
+    file_desc8 = self.pool.FindFileContainingSymbol(
+        'protobuf_unittest.TestAllTypes.FOO')
+    self.assertIsInstance(file_desc8, descriptor.FileDescriptor)
+    self.assertEqual('google/protobuf/unittest.proto',
+                     file_desc8.name)
+
+    # TODO(jieluo): Add tests for no package when b/13860351 is fixed.
+
+    self.assertRaises(KeyError, self.pool.FindFileContainingSymbol,
+                      'google.protobuf.python.internal.Factory1Message.none_field')
+
   def testFindFileContainingSymbolFailure(self):
     with self.assertRaises(KeyError):
       self.pool.FindFileContainingSymbol('Does not exist')
@@ -217,11 +242,10 @@
 
   def testFindTypeErrors(self):
     self.assertRaises(TypeError, self.pool.FindExtensionByNumber, '')
+    self.assertRaises(KeyError, self.pool.FindMethodByName, '')
 
     # TODO(jieluo): Fix python to raise correct errors.
     if api_implementation.Type() == 'cpp':
-      self.assertRaises(TypeError, self.pool.FindMethodByName, 0)
-      self.assertRaises(KeyError, self.pool.FindMethodByName, '')
       error_type = TypeError
     else:
       error_type = AttributeError
@@ -231,6 +255,7 @@
     self.assertRaises(error_type, self.pool.FindEnumTypeByName, 0)
     self.assertRaises(error_type, self.pool.FindOneofByName, 0)
     self.assertRaises(error_type, self.pool.FindServiceByName, 0)
+    self.assertRaises(error_type, self.pool.FindMethodByName, 0)
     self.assertRaises(error_type, self.pool.FindFileContainingSymbol, 0)
     if api_implementation.Type() == 'python':
       error_type = KeyError
@@ -275,11 +300,6 @@
       self.pool.FindEnumTypeByName('Does not exist')
 
   def testFindFieldByName(self):
-    if isinstance(self, SecondaryDescriptorFromDescriptorDB):
-      if api_implementation.Type() == 'cpp':
-        # TODO(jieluo): Fix cpp extension to find field correctly
-        # when descriptor pool is using an underlying database.
-        return
     field = self.pool.FindFieldByName(
         'google.protobuf.python.internal.Factory1Message.list_value')
     self.assertEqual(field.name, 'list_value')
@@ -290,11 +310,6 @@
       self.pool.FindFieldByName('Does not exist')
 
   def testFindOneofByName(self):
-    if isinstance(self, SecondaryDescriptorFromDescriptorDB):
-      if api_implementation.Type() == 'cpp':
-        # TODO(jieluo): Fix cpp extension to find oneof correctly
-        # when descriptor pool is using an underlying database.
-        return
     oneof = self.pool.FindOneofByName(
         'google.protobuf.python.internal.Factory2Message.oneof_field')
     self.assertEqual(oneof.name, 'oneof_field')
@@ -302,11 +317,6 @@
       self.pool.FindOneofByName('Does not exist')
 
   def testFindExtensionByName(self):
-    if isinstance(self, SecondaryDescriptorFromDescriptorDB):
-      if api_implementation.Type() == 'cpp':
-        # TODO(jieluo): Fix cpp extension to find extension correctly
-        # when descriptor pool is using an underlying database.
-        return
     # An extension defined in a message.
     extension = self.pool.FindExtensionByName(
         'google.protobuf.python.internal.Factory2Message.one_more_field')
@@ -382,6 +392,11 @@
     with self.assertRaises(KeyError):
       self.pool.FindServiceByName('Does not exist')
 
+    method = self.pool.FindMethodByName('protobuf_unittest.TestService.Foo')
+    self.assertIs(method.containing_service, service)
+    with self.assertRaises(KeyError):
+      self.pool.FindMethodByName('protobuf_unittest.TestService.Doesnotexist')
+
   def testUserDefinedDB(self):
     db = descriptor_database.DescriptorDatabase()
     self.pool = descriptor_pool.DescriptorPool(db)
@@ -601,6 +616,8 @@
         unittest_import_pb2.DESCRIPTOR.serialized_pb))
     self.pool.Add(descriptor_pb2.FileDescriptorProto.FromString(
         unittest_pb2.DESCRIPTOR.serialized_pb))
+    self.pool.Add(descriptor_pb2.FileDescriptorProto.FromString(
+        no_package_pb2.DESCRIPTOR.serialized_pb))
 
 
 class SecondaryDescriptorFromDescriptorDB(DescriptorPoolTestBase,
@@ -620,6 +637,8 @@
         unittest_import_pb2.DESCRIPTOR.serialized_pb))
     db.Add(descriptor_pb2.FileDescriptorProto.FromString(
         unittest_pb2.DESCRIPTOR.serialized_pb))
+    db.Add(descriptor_pb2.FileDescriptorProto.FromString(
+        no_package_pb2.DESCRIPTOR.serialized_pb))
     self.pool = descriptor_pool.DescriptorPool(descriptor_db=db)
 
 
@@ -746,11 +765,7 @@
     test.assertEqual(msg_desc, field_desc.containing_type)
     test.assertEqual(field_type_desc, field_desc.message_type)
     test.assertEqual(file_desc, field_desc.file)
-    # TODO(jieluo): Fix python and cpp extension diff for message field
-    # default value.
-    if api_implementation.Type() == 'cpp':
-      test.assertRaises(
-          NotImplementedError, getattr, field_desc, 'default_value')
+    test.assertEqual(field_desc.default_value, None)
 
 
 class StringField(object):
diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py
index 02a43d1..af6bece 100755
--- a/python/google/protobuf/internal/descriptor_test.py
+++ b/python/google/protobuf/internal/descriptor_test.py
@@ -452,6 +452,17 @@
     self.assertEqual('attribute is not writable: has_options',
                      str(e.exception))
 
+  def testDefault(self):
+    message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
+    field = message_descriptor.fields_by_name['repeated_int32']
+    self.assertEqual(field.default_value, [])
+    field = message_descriptor.fields_by_name['repeated_nested_message']
+    self.assertEqual(field.default_value, [])
+    field = message_descriptor.fields_by_name['optionalgroup']
+    self.assertEqual(field.default_value, None)
+    field = message_descriptor.fields_by_name['optional_nested_message']
+    self.assertEqual(field.default_value, None)
+
 
 class NewDescriptorTest(DescriptorTest):
   """Redo the same tests as above, but with a separate DescriptorPool."""
diff --git a/python/google/protobuf/internal/factory_test1.proto b/python/google/protobuf/internal/factory_test1.proto
index d2fbbee..f5bd038 100644
--- a/python/google/protobuf/internal/factory_test1.proto
+++ b/python/google/protobuf/internal/factory_test1.proto
@@ -56,3 +56,17 @@
 
   extensions 1000 to max;
 }
+
+message Factory1MethodRequest {
+  optional string argument = 1;
+}
+
+message Factory1MethodResponse {
+  optional string result = 1;
+}
+
+service Factory1Service {
+  // Dummy method for this dummy service.
+  rpc Factory1Method(Factory1MethodRequest) returns (Factory1MethodResponse) {
+  }
+}
diff --git a/python/google/protobuf/internal/message_factory_test.py b/python/google/protobuf/internal/message_factory_test.py
index 6df52ed..b97e3f6 100644
--- a/python/google/protobuf/internal/message_factory_test.py
+++ b/python/google/protobuf/internal/message_factory_test.py
@@ -142,10 +142,8 @@
       self.assertEqual('test2', msg1.Extensions[ext2])
       self.assertEqual(None,
                        msg1.Extensions._FindExtensionByNumber(12321))
+      self.assertRaises(TypeError, len, msg1.Extensions)
       if api_implementation.Type() == 'cpp':
-        # TODO(jieluo): Fix len to return the correct value.
-        # self.assertEqual(2, len(msg1.Extensions))
-        self.assertEqual(len(msg1.Extensions), len(msg1.Extensions))
         self.assertRaises(TypeError,
                           msg1.Extensions._FindExtensionByName, 0)
         self.assertRaises(TypeError,
diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py
index 61a56a6..ccb9221 100755
--- a/python/google/protobuf/internal/message_test.py
+++ b/python/google/protobuf/internal/message_test.py
@@ -1,4 +1,5 @@
 #! /usr/bin/env python
+# -*- coding: utf-8 -*-
 #
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
@@ -49,6 +50,7 @@
 import math
 import operator
 import pickle
+import pydoc
 import six
 import sys
 import warnings
@@ -72,12 +74,14 @@
 from google.protobuf import text_format
 from google.protobuf.internal import api_implementation
 from google.protobuf.internal import encoder
+from google.protobuf.internal import more_extensions_pb2
 from google.protobuf.internal import packed_field_test_pb2
 from google.protobuf.internal import test_util
 from google.protobuf.internal import testing_refleaks
 from google.protobuf import message
 from google.protobuf.internal import _parameterized
 
+UCS2_MAXUNICODE = 65535
 if six.PY3:
   long = int
 
@@ -415,6 +419,37 @@
     empty.ParseFromString(populated.SerializeToString())
     self.assertEqual(str(empty), '')
 
+  def testMergeFromRepeatedField(self, message_module):
+    msg = message_module.TestAllTypes()
+    msg.repeated_int32.append(1)
+    msg.repeated_int32.append(3)
+    msg.repeated_nested_message.add(bb=1)
+    msg.repeated_nested_message.add(bb=2)
+    other_msg = message_module.TestAllTypes()
+    other_msg.repeated_nested_message.add(bb=3)
+    other_msg.repeated_nested_message.add(bb=4)
+    other_msg.repeated_int32.append(5)
+    other_msg.repeated_int32.append(7)
+
+    msg.repeated_int32.MergeFrom(other_msg.repeated_int32)
+    self.assertEqual(4, len(msg.repeated_int32))
+
+    msg.repeated_nested_message.MergeFrom(other_msg.repeated_nested_message)
+    self.assertEqual([1, 2, 3, 4],
+                     [m.bb for m in msg.repeated_nested_message])
+
+  def testAddWrongRepeatedNestedField(self, message_module):
+    msg = message_module.TestAllTypes()
+    try:
+      msg.repeated_nested_message.add('wrong')
+    except TypeError:
+      pass
+    try:
+      msg.repeated_nested_message.add(value_field='wrong')
+    except ValueError:
+      pass
+    self.assertEqual(len(msg.repeated_nested_message), 0)
+
   def testRepeatedNestedFieldIteration(self, message_module):
     msg = message_module.TestAllTypes()
     msg.repeated_nested_message.add(bb=1)
@@ -645,6 +680,82 @@
     m.payload.repeated_int32.extend([])
     self.assertTrue(m.HasField('payload'))
 
+  def testMergeFrom(self, message_module):
+    m1 = message_module.TestAllTypes()
+    m2 = message_module.TestAllTypes()
+    # Cpp extension will lazily create a sub message which is immutable.
+    self.assertEqual(0, m1.optional_nested_message.bb)
+    m2.optional_nested_message.bb = 1
+    # Make sure cmessage pointing to a mutable message after merge instead of
+    # the lazily created message.
+    m1.MergeFrom(m2)
+    self.assertEqual(1, m1.optional_nested_message.bb)
+
+    # Test more nested sub message.
+    msg1 = message_module.NestedTestAllTypes()
+    msg2 = message_module.NestedTestAllTypes()
+    self.assertEqual(0, msg1.child.payload.optional_nested_message.bb)
+    msg2.child.payload.optional_nested_message.bb = 1
+    msg1.MergeFrom(msg2)
+    self.assertEqual(1, msg1.child.payload.optional_nested_message.bb)
+
+    # Test repeated field.
+    self.assertEqual(msg1.payload.repeated_nested_message,
+                     msg1.payload.repeated_nested_message)
+    msg2.payload.repeated_nested_message.add().bb = 1
+    msg1.MergeFrom(msg2)
+    self.assertEqual(1, len(msg1.payload.repeated_nested_message))
+    self.assertEqual(1, msg1.payload.repeated_nested_message[0].bb)
+
+  def testMergeFromString(self, message_module):
+    m1 = message_module.TestAllTypes()
+    m2 = message_module.TestAllTypes()
+    # Cpp extension will lazily create a sub message which is immutable.
+    self.assertEqual(0, m1.optional_nested_message.bb)
+    m2.optional_nested_message.bb = 1
+    # Make sure cmessage pointing to a mutable message after merge instead of
+    # the lazily created message.
+    m1.MergeFromString(m2.SerializeToString())
+    self.assertEqual(1, m1.optional_nested_message.bb)
+
+  @unittest.skipIf(six.PY2, 'memoryview objects are not supported on py2')
+  def testMergeFromStringUsingMemoryViewWorksInPy3(self, message_module):
+    m2 = message_module.TestAllTypes()
+    m2.optional_string = 'scalar string'
+    m2.repeated_string.append('repeated string')
+    m2.optional_bytes = b'scalar bytes'
+    m2.repeated_bytes.append(b'repeated bytes')
+
+    serialized = m2.SerializeToString()
+    memview = memoryview(serialized)
+    m1 = message_module.TestAllTypes.FromString(memview)
+
+    self.assertEqual(m1.optional_bytes, b'scalar bytes')
+    self.assertEqual(m1.repeated_bytes, [b'repeated bytes'])
+    self.assertEqual(m1.optional_string, 'scalar string')
+    self.assertEqual(m1.repeated_string, ['repeated string'])
+    # Make sure that the memoryview was correctly converted to bytes, and
+    # that a sub-sliced memoryview is not being used.
+    self.assertIsInstance(m1.optional_bytes, bytes)
+    self.assertIsInstance(m1.repeated_bytes[0], bytes)
+    self.assertIsInstance(m1.optional_string, six.text_type)
+    self.assertIsInstance(m1.repeated_string[0], six.text_type)
+
+  @unittest.skipIf(six.PY3, 'memoryview is supported by py3')
+  def testMergeFromStringUsingMemoryViewIsPy2Error(self, message_module):
+    memview = memoryview(b'')
+    with self.assertRaises(TypeError):
+      message_module.TestAllTypes.FromString(memview)
+
+  def testMergeFromEmpty(self, message_module):
+    m1 = message_module.TestAllTypes()
+    # Cpp extension will lazily create a sub message which is immutable.
+    self.assertEqual(0, m1.optional_nested_message.bb)
+    self.assertFalse(m1.HasField('optional_nested_message'))
+    # Make sure the sub message is still immutable after merge from empty.
+    m1.MergeFromString(b'')  # field state should not change
+    self.assertFalse(m1.HasField('optional_nested_message'))
+
   def ensureNestedMessageExists(self, msg, attribute):
     """Make sure that a nested message object exists.
 
@@ -1067,14 +1178,8 @@
     with self.assertRaises(AttributeError):
       m.repeated_int32 = []
     m.repeated_int32.append(1)
-    if api_implementation.Type() == 'cpp':
-      # For test coverage: cpp has a different path if composite
-      # field is in cache
-      with self.assertRaises(TypeError):
-        m.repeated_int32 = []
-    else:
-      with self.assertRaises(AttributeError):
-        m.repeated_int32 = []
+    with self.assertRaises(AttributeError):
+      m.repeated_int32 = []
 
 
 # Class to test proto2-only features (required, extensions, etc.)
@@ -1169,6 +1274,21 @@
     msg = unittest_pb2.TestAllTypes()
     self.assertRaises(AttributeError, getattr, msg, 'Extensions')
 
+  def testMergeFromExtensions(self):
+    msg1 = more_extensions_pb2.TopLevelMessage()
+    msg2 = more_extensions_pb2.TopLevelMessage()
+    # Cpp extension will lazily create a sub message which is immutable.
+    self.assertEqual(0, msg1.submessage.Extensions[
+        more_extensions_pb2.optional_int_extension])
+    self.assertFalse(msg1.HasField('submessage'))
+    msg2.submessage.Extensions[
+        more_extensions_pb2.optional_int_extension] = 123
+    # Make sure cmessage and extensions pointing to a mutable message
+    # after merge instead of the lazily created message.
+    msg1.MergeFrom(msg2)
+    self.assertEqual(123, msg1.submessage.Extensions[
+        more_extensions_pb2.optional_int_extension])
+
   def testGoldenExtensions(self):
     golden_data = test_util.GoldenFileData('golden_message')
     golden_message = unittest_pb2.TestAllExtensions()
@@ -1316,6 +1436,15 @@
       unittest_pb2.TestAllTypes(repeated_nested_enum='FOO')
 
 
+  def test_documentation(self):
+    # Also used by the interactive help() function.
+    doc = pydoc.html.document(unittest_pb2.TestAllTypes, 'message')
+    self.assertIn('class TestAllTypes', doc)
+    self.assertIn('SerializePartialToString', doc)
+    self.assertIn('repeated_float', doc)
+    base = unittest_pb2.TestAllTypes.__bases__[0]
+    self.assertRaises(AttributeError, getattr, base, '_extensions_by_name')
+
 
 # Class to test proto3-only features/behavior (updated field presence & enums)
 class Proto3Test(BaseTestCase):
@@ -1539,10 +1668,8 @@
     self.assertEqual(True, msg2.map_bool_bool[True])
     self.assertEqual(2, msg2.map_int32_enum[888])
     self.assertEqual(456, msg2.map_int32_enum[123])
-    # TODO(jieluo): Add cpp extension support.
-    if api_implementation.Type() == 'python':
-      self.assertEqual('{-123: -456}',
-                       str(msg2.map_int32_int32))
+    self.assertEqual('{-123: -456}',
+                     str(msg2.map_int32_int32))
 
   def testMapEntryAlwaysSerialized(self):
     msg = map_unittest_pb2.TestMap()
@@ -1603,11 +1730,10 @@
     self.assertIn(123, msg2.map_int32_foreign_message)
     self.assertIn(-456, msg2.map_int32_foreign_message)
     self.assertEqual(2, len(msg2.map_int32_foreign_message))
+    msg2.map_int32_foreign_message[123].c = 1
     # TODO(jieluo): Fix text format for message map.
-    # TODO(jieluo): Add cpp extension support.
-    if api_implementation.Type() == 'python':
-      self.assertEqual(15,
-                       len(str(msg2.map_int32_foreign_message)))
+    self.assertIn(str(msg2.map_int32_foreign_message),
+                  ('{-456: , 123: c: 1\n}', '{123: c: 1\n, -456: }'))
 
   def testNestedMessageMapItemDelete(self):
     msg = map_unittest_pb2.TestMap()
@@ -1721,6 +1847,15 @@
     self.assertEqual(10, msg2.map_int32_foreign_message[222].c)
     self.assertFalse(msg2.map_int32_foreign_message[222].HasField('d'))
 
+    # Test when cpp extension cache a map.
+    m1 = map_unittest_pb2.TestMap()
+    m2 = map_unittest_pb2.TestMap()
+    self.assertEqual(m1.map_int32_foreign_message,
+                     m1.map_int32_foreign_message)
+    m2.map_int32_foreign_message[123].c = 10
+    m1.MergeFrom(m2)
+    self.assertEqual(10, m2.map_int32_foreign_message[123].c)
+
   def testMergeFromBadType(self):
     msg = map_unittest_pb2.TestMap()
     with self.assertRaisesRegexp(
@@ -1972,7 +2107,7 @@
   def testMapValidAfterFieldCleared(self):
     # Map needs to work even if field is cleared.
     # For the C++ implementation this tests the correctness of
-    # ScalarMapContainer::Release()
+    # MapContainer::Release()
     msg = map_unittest_pb2.TestMap()
     int32_map = msg.map_int32_int32
 
@@ -1988,7 +2123,7 @@
   def testMessageMapValidAfterFieldCleared(self):
     # Map needs to work even if field is cleared.
     # For the C++ implementation this tests the correctness of
-    # ScalarMapContainer::Release()
+    # MapContainer::Release()
     msg = map_unittest_pb2.TestMap()
     int32_foreign_message = msg.map_int32_foreign_message
 
@@ -1998,6 +2133,24 @@
     self.assertEqual(b'', msg.SerializeToString())
     self.assertTrue(2 in int32_foreign_message.keys())
 
+  def testMessageMapItemValidAfterTopMessageCleared(self):
+    # Message map item needs to work even if it is cleared.
+    # For the C++ implementation this tests the correctness of
+    # MapContainer::Release()
+    msg = map_unittest_pb2.TestMap()
+    msg.map_int32_all_types[2].optional_string = 'bar'
+
+    if api_implementation.Type() == 'cpp':
+      # Need to keep the map reference because of b/27942626.
+      # TODO(jieluo): Remove it.
+      unused_map = msg.map_int32_all_types  # pylint: disable=unused-variable
+    msg_value = msg.map_int32_all_types[2]
+    msg.Clear()
+
+    # Reset to trigger sync between repeated field and map in c++.
+    msg.map_int32_all_types[3].optional_string = 'foo'
+    self.assertEqual(msg_value.optional_string, 'bar')
+
   def testMapIterInvalidatedByClearField(self):
     # Map iterator is invalidated when field is cleared.
     # But this case does need to not crash the interpreter.
@@ -2057,7 +2210,84 @@
     msg.map_int32_int32[35] = 64
     msg.map_string_foreign_message['foo'].c = 5
     self.assertEqual(0, len(msg.FindInitializationErrors()))
+ 
+  @unittest.skipIf(sys.maxunicode == UCS2_MAXUNICODE,
+                   'Skip for ucs2')
+  def testStrictUtf8Check(self):
+    # Test u'\ud801' is rejected at parser in both python2 and python3.
+    serialized = (b'r\x03\xed\xa0\x81')
+    msg = unittest_proto3_arena_pb2.TestAllTypes()
+    with self.assertRaises(Exception) as context:
+      msg.MergeFromString(serialized)
+    if api_implementation.Type() == 'python':
+      self.assertIn('optional_string', str(context.exception))
+    else:
+      self.assertIn('Error parsing message', str(context.exception))
 
+    # Test optional_string=u'😍' is accepted.
+    serialized = unittest_proto3_arena_pb2.TestAllTypes(
+        optional_string=u'😍').SerializeToString()
+    msg2 = unittest_proto3_arena_pb2.TestAllTypes()
+    msg2.MergeFromString(serialized)
+    self.assertEqual(msg2.optional_string, u'😍')
+
+    msg = unittest_proto3_arena_pb2.TestAllTypes(
+        optional_string=u'\ud001')
+    self.assertEqual(msg.optional_string, u'\ud001')
+
+  @unittest.skipIf(six.PY2, 'Surrogates are acceptable in python2')
+  def testSurrogatesInPython3(self):
+    # Surrogates like U+D83D is an invalid unicode character, it is
+    # supported by Python2 only because in some builds, unicode strings
+    # use 2-bytes code units. Since Python 3.3, we don't have this problem.
+    #
+    # Surrogates are utf16 code units, in a unicode string they are invalid
+    # characters even when they appear in pairs like u'\ud801\udc01'. Protobuf
+    # Python3 reject such cases at setters and parsers. Python2 accpect it
+    # to keep same features with the language itself. 'Unpaired pairs'
+    # like u'\ud801' are rejected at parsers when strict utf8 check is enabled
+    # in proto3 to keep same behavior with c extension.
+
+    # Surrogates are rejected at setters in Python3.
+    with self.assertRaises(ValueError):
+      unittest_proto3_arena_pb2.TestAllTypes(
+          optional_string=u'\ud801\udc01')
+    with self.assertRaises(ValueError):
+      unittest_proto3_arena_pb2.TestAllTypes(
+          optional_string=b'\xed\xa0\x81')
+    with self.assertRaises(ValueError):
+      unittest_proto3_arena_pb2.TestAllTypes(
+          optional_string=u'\ud801')
+    with self.assertRaises(ValueError):
+      unittest_proto3_arena_pb2.TestAllTypes(
+          optional_string=u'\ud801\ud801')
+
+  @unittest.skipIf(six.PY3 or sys.maxunicode == UCS2_MAXUNICODE,
+                   'Surrogates are rejected at setters in Python3')
+  def testSurrogatesInPython2(self):
+    # Test optional_string=u'\ud801\udc01'.
+    # surrogate pair is acceptable in python2.
+    msg = unittest_proto3_arena_pb2.TestAllTypes(
+        optional_string=u'\ud801\udc01')
+    # TODO(jieluo): Change pure python to have same behavior with c extension.
+    # Some build in python2 consider u'\ud801\udc01' and u'\U00010401' are
+    # equal, some are not equal.
+    if api_implementation.Type() == 'python':
+      self.assertEqual(msg.optional_string, u'\ud801\udc01')
+    else:
+      self.assertEqual(msg.optional_string, u'\U00010401')
+    serialized = msg.SerializeToString()
+    msg2 = unittest_proto3_arena_pb2.TestAllTypes()
+    msg2.MergeFromString(serialized)
+    self.assertEqual(msg2.optional_string, u'\U00010401')
+
+    # Python2 does not reject surrogates at setters.
+    msg = unittest_proto3_arena_pb2.TestAllTypes(
+        optional_string=b'\xed\xa0\x81')
+    unittest_proto3_arena_pb2.TestAllTypes(
+        optional_string=u'\ud801')
+    unittest_proto3_arena_pb2.TestAllTypes(
+        optional_string=u'\ud801\ud801')
 
 
 class ValidTypeNamesTest(BaseTestCase):
diff --git a/python/google/protobuf/internal/no_package.proto b/python/google/protobuf/internal/no_package.proto
index 3546dcc..49eda95 100644
--- a/python/google/protobuf/internal/no_package.proto
+++ b/python/google/protobuf/internal/no_package.proto
@@ -1,3 +1,33 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
 syntax = "proto2";
 
 enum NoPackageEnum {
diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py
index 975e3b4..ab5d160 100755
--- a/python/google/protobuf/internal/python_message.py
+++ b/python/google/protobuf/internal/python_message.py
@@ -56,6 +56,7 @@
 import weakref
 
 import six
+from six.moves import range
 
 # We use "as" to avoid name collisions with variables.
 from google.protobuf.internal import api_implementation
@@ -124,6 +125,21 @@
       Newly-allocated class.
     """
     descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
+
+    # If a concrete class already exists for this descriptor, don't try to
+    # create another.  Doing so will break any messages that already exist with
+    # the existing class.
+    #
+    # The C++ implementation appears to have its own internal `PyMessageFactory`
+    # to achieve similar results.
+    #
+    # This most commonly happens in `text_format.py` when using descriptors from
+    # a custom pool; it calls symbol_database.Global().getPrototype() on a
+    # descriptor which already has an existing concrete class.
+    new_class = getattr(descriptor, '_concrete_class', None)
+    if new_class:
+      return new_class
+
     if descriptor.full_name in well_known_types.WKTBASES:
       bases += (well_known_types.WKTBASES[descriptor.full_name],)
     _AddClassAttributesForNestedExtensions(descriptor, dictionary)
@@ -151,6 +167,16 @@
         type.
     """
     descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
+
+    # If this is an _existing_ class looked up via `_concrete_class` in the
+    # __new__ method above, then we don't need to re-initialize anything.
+    existing_class = getattr(descriptor, '_concrete_class', None)
+    if existing_class:
+      assert existing_class is cls, (
+          'Duplicate `GeneratedProtocolMessageType` created for descriptor %r'
+          % (descriptor.full_name))
+      return
+
     cls._decoders_by_tag = {}
     if (descriptor.has_options and
         descriptor.GetOptions().message_set_wire_format):
@@ -245,6 +271,7 @@
                              '_cached_byte_size_dirty',
                              '_fields',
                              '_unknown_fields',
+                             '_unknown_field_set',
                              '_is_present_in_parent',
                              '_listener',
                              '_listener_for_children',
@@ -271,6 +298,13 @@
   return value_type.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE
 
 
+def _IsStrictUtf8Check(field):
+  if field.containing_type.syntax != 'proto3':
+    return False
+  enforce_utf8 = True
+  return enforce_utf8
+
+
 def _AttachFieldHelpers(cls, field_descriptor):
   is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED)
   is_packable = (is_repeated and
@@ -322,10 +356,16 @@
       field_decoder = decoder.MapDecoder(
           field_descriptor, _GetInitializeDefaultForMap(field_descriptor),
           is_message_map)
+    elif decode_type == _FieldDescriptor.TYPE_STRING:
+      is_strict_utf8_check = _IsStrictUtf8Check(field_descriptor)
+      field_decoder = decoder.StringDecoder(
+          field_descriptor.number, is_repeated, is_packed,
+          field_descriptor, field_descriptor._default_constructor,
+          is_strict_utf8_check)
     else:
       field_decoder = type_checkers.TYPE_TO_DECODER[decode_type](
-              field_descriptor.number, is_repeated, is_packed,
-              field_descriptor, field_descriptor._default_constructor)
+          field_descriptor.number, is_repeated, is_packed,
+          field_descriptor, field_descriptor._default_constructor)
 
     cls._decoders_by_tag[tag_bytes] = (field_decoder, oneof_descriptor)
 
@@ -422,6 +462,9 @@
     # _concrete_class may not yet be initialized.
     message_type = field.message_type
     def MakeSubMessageDefault(message):
+      assert getattr(message_type, '_concrete_class', None), (
+          'Uninitialized concrete class found for field %r (message type %r)'
+          % (field.full_name, message_type.full_name))
       result = message_type._concrete_class()
       result._SetListener(
           _OneofListener(message, field)
@@ -477,6 +520,9 @@
     # _unknown_fields is () when empty for efficiency, and will be turned into
     # a list if fields are added.
     self._unknown_fields = ()
+    # _unknown_field_set is None when empty for efficiency, and will be
+    # turned into UnknownFieldSet struct if fields are added.
+    self._unknown_field_set = None      # pylint: disable=protected-access
     self._is_present_in_parent = False
     self._listener = message_listener_mod.NullMessageListener()
     self._listener_for_children = _Listener(self)
@@ -584,6 +630,14 @@
     _AddPropertiesForNonRepeatedScalarField(field, cls)
 
 
+class _FieldProperty(property):
+  __slots__ = ('DESCRIPTOR',)
+
+  def __init__(self, descriptor, getter, setter, doc):
+    property.__init__(self, getter, setter, doc=doc)
+    self.DESCRIPTOR = descriptor
+
+
 def _AddPropertiesForRepeatedField(field, cls):
   """Adds a public property for a "repeated" protocol message field.  Clients
   can use this property to get the value of the field, which will be either a
@@ -625,7 +679,7 @@
                          '"%s" in protocol message object.' % proto_field_name)
 
   doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
-  setattr(cls, property_name, property(getter, setter, doc=doc))
+  setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc))
 
 
 def _AddPropertiesForNonRepeatedScalarField(field, cls):
@@ -681,7 +735,7 @@
 
   # Add a property to encapsulate the getter/setter.
   doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
-  setattr(cls, property_name, property(getter, setter, doc=doc))
+  setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc))
 
 
 def _AddPropertiesForNonRepeatedCompositeField(field, cls):
@@ -725,7 +779,7 @@
 
   # Add a property to encapsulate the getter.
   doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
-  setattr(cls, property_name, property(getter, setter, doc=doc))
+  setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc))
 
 
 def _AddPropertiesForExtensions(descriptor, cls):
@@ -949,13 +1003,8 @@
     if not self.ListFields() == other.ListFields():
       return False
 
-    # Sort unknown fields because their order shouldn't affect equality test.
-    unknown_fields = list(self._unknown_fields)
-    unknown_fields.sort()
-    other_unknown_fields = list(other._unknown_fields)
-    other_unknown_fields.sort()
-
-    return unknown_fields == other_unknown_fields
+    # pylint: disable=protected-access
+    return self._unknown_field_set == other._unknown_field_set
 
   cls.__eq__ = __eq__
 
@@ -1078,6 +1127,13 @@
 def _AddMergeFromStringMethod(message_descriptor, cls):
   """Helper for _AddMessageMethods()."""
   def MergeFromString(self, serialized):
+    if isinstance(serialized, memoryview) and six.PY2:
+      raise TypeError(
+          'memoryview not supported in Python 2 with the pure Python proto '
+          'implementation: this is to maintain compatibility with the C++ '
+          'implementation')
+
+    serialized = memoryview(serialized)
     length = len(serialized)
     try:
       if self._InternalParse(serialized, 0, length) != length:
@@ -1095,26 +1151,54 @@
   local_ReadTag = decoder.ReadTag
   local_SkipField = decoder.SkipField
   decoders_by_tag = cls._decoders_by_tag
-  is_proto3 = message_descriptor.syntax == "proto3"
 
   def InternalParse(self, buffer, pos, end):
+    """Create a message from serialized bytes.
+
+    Args:
+      self: Message, instance of the proto message object.
+      buffer: memoryview of the serialized data.
+      pos: int, position to start in the serialized data.
+      end: int, end position of the serialized data.
+
+    Returns:
+      Message object.
+    """
+    # Guard against internal misuse, since this function is called internally
+    # quite extensively, and its easy to accidentally pass bytes.
+    assert isinstance(buffer, memoryview)
     self._Modified()
     field_dict = self._fields
-    unknown_field_list = self._unknown_fields
+    # pylint: disable=protected-access
+    unknown_field_set = self._unknown_field_set
     while pos != end:
       (tag_bytes, new_pos) = local_ReadTag(buffer, pos)
       field_decoder, field_desc = decoders_by_tag.get(tag_bytes, (None, None))
       if field_decoder is None:
-        value_start_pos = new_pos
-        new_pos = local_SkipField(buffer, new_pos, end, tag_bytes)
+        if not self._unknown_fields:   # pylint: disable=protected-access
+          self._unknown_fields = []    # pylint: disable=protected-access
+        if unknown_field_set is None:
+          # pylint: disable=protected-access
+          self._unknown_field_set = containers.UnknownFieldSet()
+          # pylint: disable=protected-access
+          unknown_field_set = self._unknown_field_set
+        # pylint: disable=protected-access
+        (tag, _) = decoder._DecodeVarint(tag_bytes, 0)
+        field_number, wire_type = wire_format.UnpackTag(tag)
+        # TODO(jieluo): remove old_pos.
+        old_pos = new_pos
+        (data, new_pos) = decoder._DecodeUnknownField(
+            buffer, new_pos, wire_type)  # pylint: disable=protected-access
         if new_pos == -1:
           return pos
-        if (not is_proto3 or
-            api_implementation.GetPythonProto3PreserveUnknownsDefault()):
-          if not unknown_field_list:
-            unknown_field_list = self._unknown_fields = []
-          unknown_field_list.append(
-              (tag_bytes, buffer[value_start_pos:new_pos]))
+        # pylint: disable=protected-access
+        unknown_field_set._add(field_number, wire_type, data)
+        # TODO(jieluo): remove _unknown_fields.
+        new_pos = local_SkipField(buffer, old_pos, end, tag_bytes)
+        if new_pos == -1:
+          return pos
+        self._unknown_fields.append(
+            (tag_bytes, buffer[old_pos:new_pos].tobytes()))
         pos = new_pos
       else:
         pos = field_decoder(buffer, new_pos, end, self, field_dict)
@@ -1259,6 +1343,10 @@
       if not self._unknown_fields:
         self._unknown_fields = []
       self._unknown_fields.extend(msg._unknown_fields)
+      # pylint: disable=protected-access
+      if self._unknown_field_set is None:
+        self._unknown_field_set = containers.UnknownFieldSet()
+      self._unknown_field_set._extend(msg._unknown_field_set)
 
   cls.MergeFrom = MergeFrom
 
@@ -1291,12 +1379,25 @@
   # Clear fields.
   self._fields = {}
   self._unknown_fields = ()
+  # pylint: disable=protected-access
+  if self._unknown_field_set is not None:
+    self._unknown_field_set._clear()
+    self._unknown_field_set = None
+
   self._oneofs = {}
   self._Modified()
 
 
+def _UnknownFields(self):
+  if self._unknown_field_set is None:  # pylint: disable=protected-access
+    # pylint: disable=protected-access
+    self._unknown_field_set = containers.UnknownFieldSet()
+  return self._unknown_field_set    # pylint: disable=protected-access
+
+
 def _DiscardUnknownFields(self):
   self._unknown_fields = []
+  self._unknown_field_set = None      # pylint: disable=protected-access
   for field, value in self.ListFields():
     if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
       if field.label == _FieldDescriptor.LABEL_REPEATED:
@@ -1335,6 +1436,7 @@
   _AddReduceMethod(cls)
   # Adds methods which do not depend on cls.
   cls.Clear = _Clear
+  cls.UnknownFields = _UnknownFields
   cls.DiscardUnknownFields = _DiscardUnknownFields
   cls._SetListener = _SetListener
 
@@ -1471,6 +1573,10 @@
     if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
       result = extension_handle._default_constructor(self._extended_message)
     elif extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+      assert getattr(extension_handle.message_type, '_concrete_class', None), (
+          'Uninitialized concrete class found for field %r (message type %r)'
+          % (extension_handle.full_name,
+             extension_handle.message_type.full_name))
       result = extension_handle.message_type._concrete_class()
       try:
         result._SetListener(self._extended_message._listener_for_children)
diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py
index 0306ff4..31ceda2 100755
--- a/python/google/protobuf/internal/reflection_test.py
+++ b/python/google/protobuf/internal/reflection_test.py
@@ -64,6 +64,10 @@
 from google.protobuf.internal import decoder
 
 
+if six.PY3:
+  long = int  # pylint: disable=redefined-builtin,invalid-name
+
+
 BaseTestCase = testing_refleaks.BaseTestCase
 
 
@@ -647,10 +651,7 @@
     TestGetAndDeserialize('optional_int32', 1, int)
     TestGetAndDeserialize('optional_int32', 1 << 30, int)
     TestGetAndDeserialize('optional_uint32', 1 << 30, int)
-    try:
-      integer_64 = long
-    except NameError:  # Python3
-      integer_64 = int
+    integer_64 = long
     if struct.calcsize('L') == 4:
       # Python only has signed ints, so 32-bit python can't fit an uint32
       # in an int.
@@ -1103,6 +1104,7 @@
     self.assertEqual(23, myproto_instance.foo_field)
     self.assertTrue(myproto_instance.HasField('foo_field'))
 
+  @testing_refleaks.SkipReferenceLeakChecker('MakeDescriptor is not repeatable')
   def testDescriptorProtoSupport(self):
     # Hand written descriptors/reflection are only supported by the pure-Python
     # implementation of the API.
@@ -1141,7 +1143,8 @@
     self.assertTrue('price' in desc.fields_by_name)
     self.assertTrue('owners' in desc.fields_by_name)
 
-    class CarMessage(six.with_metaclass(reflection.GeneratedProtocolMessageType, message.Message)):
+    class CarMessage(six.with_metaclass(reflection.GeneratedProtocolMessageType,
+                                        message.Message)):
       DESCRIPTOR = desc
 
     prius = CarMessage()
@@ -2435,7 +2438,7 @@
 
     first_proto = unittest_pb2.TestAllTypes()
     test_util.SetAllFields(first_proto)
-    serialized = first_proto.SerializeToString()
+    serialized = memoryview(first_proto.SerializeToString())
 
     for truncation_point in range(len(serialized) + 1):
       try:
@@ -2857,6 +2860,38 @@
     self.assertEqual(unittest_pb2.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER,
       51)
 
+  def testFieldProperties(self):
+    cls = unittest_pb2.TestAllTypes
+    self.assertIs(cls.optional_int32.DESCRIPTOR,
+                  cls.DESCRIPTOR.fields_by_name['optional_int32'])
+    self.assertEqual(cls.OPTIONAL_INT32_FIELD_NUMBER,
+                     cls.optional_int32.DESCRIPTOR.number)
+    self.assertIs(cls.optional_nested_message.DESCRIPTOR,
+                  cls.DESCRIPTOR.fields_by_name['optional_nested_message'])
+    self.assertEqual(cls.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER,
+                     cls.optional_nested_message.DESCRIPTOR.number)
+    self.assertIs(cls.repeated_int32.DESCRIPTOR,
+                  cls.DESCRIPTOR.fields_by_name['repeated_int32'])
+    self.assertEqual(cls.REPEATED_INT32_FIELD_NUMBER,
+                     cls.repeated_int32.DESCRIPTOR.number)
+
+  def testFieldDataDescriptor(self):
+    msg = unittest_pb2.TestAllTypes()
+    msg.optional_int32 = 42
+    self.assertEqual(unittest_pb2.TestAllTypes.optional_int32.__get__(msg), 42)
+    unittest_pb2.TestAllTypes.optional_int32.__set__(msg, 25)
+    self.assertEqual(msg.optional_int32, 25)
+    with self.assertRaises(AttributeError):
+      del msg.optional_int32
+    try:
+      unittest_pb2.ForeignMessage.c.__get__(msg)
+    except TypeError:
+      pass  # The cpp implementation cannot mix fields from other messages.
+            # This test exercises a specific check that avoids a crash.
+    else:
+      pass  # The python implementation allows fields from other messages.
+            # This is useless, but works.
+
   def testInitKwargs(self):
     proto = unittest_pb2.TestAllTypes(
         optional_int32=1,
@@ -2963,6 +2998,7 @@
   @unittest.skipIf(
       api_implementation.Type() == 'cpp' and api_implementation.Version() == 2,
       'C++ implementation requires a call to MakeDescriptor()')
+  @testing_refleaks.SkipReferenceLeakChecker('MakeClass is not repeatable')
   def testMakeClassWithNestedDescriptor(self):
     leaf_desc = descriptor.Descriptor('leaf', 'package.parent.child.leaf', '',
                                       containing_type=None, fields=[],
@@ -2980,10 +3016,7 @@
                                         containing_type=None, fields=[],
                                         nested_types=[child_desc, sibling_desc],
                                         enum_types=[], extensions=[])
-    message_class = reflection.MakeClass(parent_desc)
-    self.assertIn('child', message_class.__dict__)
-    self.assertIn('sibling', message_class.__dict__)
-    self.assertIn('leaf', message_class.child.__dict__)
+    reflection.MakeClass(parent_desc)
 
   def _GetSerializedFileDescriptor(self, name):
     """Get a serialized representation of a test FileDescriptorProto.
diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py
index 237a2d5..c68f42d 100755
--- a/python/google/protobuf/internal/text_format_test.py
+++ b/python/google/protobuf/internal/text_format_test.py
@@ -33,20 +33,19 @@
 
 """Test for google.protobuf.text_format."""
 
-__author__ = 'kenton@google.com (Kenton Varda)'
-
-
+import io
 import math
 import re
-import six
 import string
+import textwrap
 
+import six
+
+# pylint: disable=g-import-not-at-top
 try:
-  import unittest2 as unittest  # PY26, pylint: disable=g-import-not-at-top
+  import unittest2 as unittest  # PY26
 except ImportError:
-  import unittest  # pylint: disable=g-import-not-at-top
-
-from google.protobuf.internal import _parameterized
+  import unittest
 
 from google.protobuf import any_pb2
 from google.protobuf import any_test_pb2
@@ -54,12 +53,13 @@
 from google.protobuf import unittest_mset_pb2
 from google.protobuf import unittest_pb2
 from google.protobuf import unittest_proto3_arena_pb2
-from google.protobuf.internal import api_implementation
 from google.protobuf.internal import any_test_pb2 as test_extend_any
 from google.protobuf.internal import message_set_extensions_pb2
 from google.protobuf.internal import test_util
 from google.protobuf import descriptor_pool
 from google.protobuf import text_format
+from google.protobuf.internal import _parameterized
+# pylint: enable=g-import-not-at-top
 
 
 # Low-level nuts-n-bolts tests.
@@ -100,8 +100,8 @@
     return text
 
 
-@_parameterized.parameters((unittest_pb2), (unittest_proto3_arena_pb2))
-class TextFormatTest(TextFormatBase):
+@_parameterized.parameters(unittest_pb2, unittest_proto3_arena_pb2)
+class TextFormatMessageToStringTests(TextFormatBase):
 
   def testPrintExotic(self, message_module):
     message = message_module.TestAllTypes()
@@ -154,6 +154,40 @@
         'repeated_int32: 1 repeated_int32: 1 repeated_int32: 3 '
         'repeated_string: "Google" repeated_string: "Zurich"')
 
+  def VerifyPrintShortFormatRepeatedFields(self, message_module, as_one_line):
+    message = message_module.TestAllTypes()
+    message.repeated_int32.append(1)
+    message.repeated_string.append('Google')
+    message.repeated_string.append('Hello,World')
+    message.repeated_foreign_enum.append(unittest_pb2.FOREIGN_FOO)
+    message.repeated_foreign_enum.append(unittest_pb2.FOREIGN_BAR)
+    message.repeated_foreign_enum.append(unittest_pb2.FOREIGN_BAZ)
+    message.optional_nested_message.bb = 3
+    for i in (21, 32):
+      msg = message.repeated_nested_message.add()
+      msg.bb = i
+    expected_ascii = (
+        'optional_nested_message {\n  bb: 3\n}\n'
+        'repeated_int32: [1]\n'
+        'repeated_string: "Google"\n'
+        'repeated_string: "Hello,World"\n'
+        'repeated_nested_message {\n  bb: 21\n}\n'
+        'repeated_nested_message {\n  bb: 32\n}\n'
+        'repeated_foreign_enum: [FOREIGN_FOO, FOREIGN_BAR, FOREIGN_BAZ]\n')
+    if as_one_line:
+      expected_ascii = expected_ascii.replace('\n ', '').replace('\n', '')
+    actual_ascii = text_format.MessageToString(
+        message, use_short_repeated_primitives=True,
+        as_one_line=as_one_line)
+    self.CompareToGoldenText(actual_ascii, expected_ascii)
+    parsed_message = message_module.TestAllTypes()
+    text_format.Parse(actual_ascii, parsed_message)
+    self.assertEqual(parsed_message, message)
+
+  def tesPrintShortFormatRepeatedFields(self, message_module, as_one_line):
+    self.VerifyPrintShortFormatRepeatedFields(message_module, False)
+    self.VerifyPrintShortFormatRepeatedFields(message_module, True)
+
   def testPrintNestedNewLineInStringAsOneLine(self, message_module):
     message = message_module.TestAllTypes()
     message.optional_string = 'a\nnew\nline'
@@ -213,13 +247,18 @@
 
   def testPrintRawUtf8String(self, message_module):
     message = message_module.TestAllTypes()
-    message.repeated_string.append(u'\u00fc\ua71f')
+    message.repeated_string.append(u'\u00fc\t\ua71f')
     text = text_format.MessageToString(message, as_utf8=True)
-    self.CompareToGoldenText(text, 'repeated_string: "\303\274\352\234\237"\n')
+    golden_unicode = u'repeated_string: "\u00fc\\t\ua71f"\n'
+    golden_text = golden_unicode if six.PY3 else golden_unicode.encode('utf-8')
+    # MessageToString always returns a native str.
+    self.CompareToGoldenText(text, golden_text)
     parsed_message = message_module.TestAllTypes()
     text_format.Parse(text, parsed_message)
-    self.assertEqual(message, parsed_message,
-                     '\n%s != %s' % (message, parsed_message))
+    self.assertEqual(
+        message, parsed_message, '\n%s != %s  (%s != %s)' %
+        (message, parsed_message, message.repeated_string[0],
+         parsed_message.repeated_string[0]))
 
   def testPrintFloatFormat(self, message_module):
     # Check that float_format argument is passed to sub-message formatting.
@@ -259,6 +298,36 @@
     message.c = 123
     self.assertEqual('c: 123\n', str(message))
 
+  def testMessageToStringUnicode(self, message_module):
+    golden_unicode = u'Á short desçription and a 🍌.'
+    golden_bytes = golden_unicode.encode('utf-8')
+    message = message_module.TestAllTypes()
+    message.optional_string = golden_unicode
+    message.optional_bytes = golden_bytes
+    text = text_format.MessageToString(message, as_utf8=True)
+    golden_message = textwrap.dedent(
+        'optional_string: "Á short desçription and a 🍌."\n'
+        'optional_bytes: '
+        r'"\303\201 short des\303\247ription and a \360\237\215\214."'
+        '\n')
+    self.CompareToGoldenText(text, golden_message)
+
+  def testMessageToStringASCII(self, message_module):
+    golden_unicode = u'Á short desçription and a 🍌.'
+    golden_bytes = golden_unicode.encode('utf-8')
+    message = message_module.TestAllTypes()
+    message.optional_string = golden_unicode
+    message.optional_bytes = golden_bytes
+    text = text_format.MessageToString(message, as_utf8=False)  # ASCII
+    golden_message = (
+        'optional_string: '
+        r'"\303\201 short des\303\247ription and a \360\237\215\214."'
+        '\n'
+        'optional_bytes: '
+        r'"\303\201 short des\303\247ription and a \360\237\215\214."'
+        '\n')
+    self.CompareToGoldenText(text, golden_message)
+
   def testPrintField(self, message_module):
     message = message_module.TestAllTypes()
     field = message.DESCRIPTOR.fields_by_name['optional_float']
@@ -289,6 +358,45 @@
     self.assertEqual('0.0', out.getvalue())
     out.close()
 
+
+@_parameterized.parameters(unittest_pb2, unittest_proto3_arena_pb2)
+class TextFormatMessageToTextBytesTests(TextFormatBase):
+
+  def testMessageToBytes(self, message_module):
+    message = message_module.ForeignMessage()
+    message.c = 123
+    self.assertEqual(b'c: 123\n', text_format.MessageToBytes(message))
+
+  def testRawUtf8RoundTrip(self, message_module):
+    message = message_module.TestAllTypes()
+    message.repeated_string.append(u'\u00fc\t\ua71f')
+    utf8_text = text_format.MessageToBytes(message, as_utf8=True)
+    golden_bytes = b'repeated_string: "\xc3\xbc\\t\xea\x9c\x9f"\n'
+    self.CompareToGoldenText(utf8_text, golden_bytes)
+    parsed_message = message_module.TestAllTypes()
+    text_format.Parse(utf8_text, parsed_message)
+    self.assertEqual(
+        message, parsed_message, '\n%s != %s  (%s != %s)' %
+        (message, parsed_message, message.repeated_string[0],
+         parsed_message.repeated_string[0]))
+
+  def testEscapedUtf8ASCIIRoundTrip(self, message_module):
+    message = message_module.TestAllTypes()
+    message.repeated_string.append(u'\u00fc\t\ua71f')
+    ascii_text = text_format.MessageToBytes(message)  # as_utf8=False default
+    golden_bytes = b'repeated_string: "\\303\\274\\t\\352\\234\\237"\n'
+    self.CompareToGoldenText(ascii_text, golden_bytes)
+    parsed_message = message_module.TestAllTypes()
+    text_format.Parse(ascii_text, parsed_message)
+    self.assertEqual(
+        message, parsed_message, '\n%s != %s  (%s != %s)' %
+        (message, parsed_message, message.repeated_string[0],
+         parsed_message.repeated_string[0]))
+
+
+@_parameterized.parameters(unittest_pb2, unittest_proto3_arena_pb2)
+class TextFormatParserTests(TextFormatBase):
+
   def testParseAllFields(self, message_module):
     message = message_module.TestAllTypes()
     test_util.SetAllFields(message)
@@ -318,14 +426,14 @@
     if message_module is unittest_pb2:
       test_util.ExpectAllFieldsSet(self, message)
 
-    if six.PY2:
-      msg2 = message_module.TestAllTypes()
-      text = (u'optional_string: "café"')
-      text_format.Merge(text, msg2)
-      self.assertEqual(msg2.optional_string, u'café')
-      msg2.Clear()
-      text_format.Parse(text, msg2)
-      self.assertEqual(msg2.optional_string, u'café')
+    msg2 = message_module.TestAllTypes()
+    text = (u'optional_string: "café"')
+    text_format.Merge(text, msg2)
+    self.assertEqual(msg2.optional_string, u'café')
+    msg2.Clear()
+    self.assertEqual(msg2.optional_string, u'')
+    text_format.Parse(text, msg2)
+    self.assertEqual(msg2.optional_string, u'café')
 
   def testParseExotic(self, message_module):
     message = message_module.TestAllTypes()
@@ -425,7 +533,8 @@
     message = message_module.TestAllTypes()
     text = 'optional_nested_enum: BARR'
     six.assertRaisesRegex(self, text_format.ParseError,
-                          (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" '
+                          (r'1:23 : \'optional_nested_enum: BARR\': '
+                           r'Enum type "\w+.TestAllTypes.NestedEnum" '
                            r'has no value named BARR.'), text_format.Parse,
                           text, message)
 
@@ -433,7 +542,8 @@
     message = message_module.TestAllTypes()
     text = 'optional_int32: bork'
     six.assertRaisesRegex(self, text_format.ParseError,
-                          ('1:17 : Couldn\'t parse integer: bork'),
+                          ('1:17 : \'optional_int32: bork\': '
+                           'Couldn\'t parse integer: bork'),
                           text_format.Parse, text, message)
 
   def testParseStringFieldUnescape(self, message_module):
@@ -457,6 +567,96 @@
                      message.repeated_string[4])
     self.assertEqual(SLASH + 'x20', message.repeated_string[5])
 
+  def testParseOneof(self, message_module):
+    m = message_module.TestAllTypes()
+    m.oneof_uint32 = 11
+    m2 = message_module.TestAllTypes()
+    text_format.Parse(text_format.MessageToString(m), m2)
+    self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
+
+  def testParseMultipleOneof(self, message_module):
+    m_string = '\n'.join(['oneof_uint32: 11', 'oneof_string: "foo"'])
+    m2 = message_module.TestAllTypes()
+    with six.assertRaisesRegex(self, text_format.ParseError,
+                               ' is specified along with field '):
+      text_format.Parse(m_string, m2)
+
+  # This example contains non-ASCII codepoint unicode data as literals
+  # which should come through as utf-8 for bytes, and as the unicode
+  # itself for string fields.  It also demonstrates escaped binary data.
+  # The ur"" string prefix is unfortunately missing from Python 3
+  # so we resort to double escaping our \s so that they come through.
+  _UNICODE_SAMPLE = u"""
+      optional_bytes: 'Á short desçription'
+      optional_string: 'Á short desçription'
+      repeated_bytes: '\\303\\201 short des\\303\\247ription'
+      repeated_bytes: '\\x12\\x34\\x56\\x78\\x90\\xab\\xcd\\xef'
+      repeated_string: '\\xd0\\x9f\\xd1\\x80\\xd0\\xb8\\xd0\\xb2\\xd0\\xb5\\xd1\\x82'
+      """
+  _BYTES_SAMPLE = _UNICODE_SAMPLE.encode('utf-8')
+  _GOLDEN_UNICODE = u'Á short desçription'
+  _GOLDEN_BYTES = _GOLDEN_UNICODE.encode('utf-8')
+  _GOLDEN_BYTES_1 = b'\x12\x34\x56\x78\x90\xab\xcd\xef'
+  _GOLDEN_STR_0 = u'Привет'
+
+  def testParseUnicode(self, message_module):
+    m = message_module.TestAllTypes()
+    text_format.Parse(self._UNICODE_SAMPLE, m)
+    self.assertEqual(m.optional_bytes, self._GOLDEN_BYTES)
+    self.assertEqual(m.optional_string, self._GOLDEN_UNICODE)
+    self.assertEqual(m.repeated_bytes[0], self._GOLDEN_BYTES)
+    # repeated_bytes[1] contained simple \ escaped non-UTF-8 raw binary data.
+    self.assertEqual(m.repeated_bytes[1], self._GOLDEN_BYTES_1)
+    # repeated_string[0] contained \ escaped data representing the UTF-8
+    # representation of _GOLDEN_STR_0 - it needs to decode as such.
+    self.assertEqual(m.repeated_string[0], self._GOLDEN_STR_0)
+
+  def testParseBytes(self, message_module):
+    m = message_module.TestAllTypes()
+    text_format.Parse(self._BYTES_SAMPLE, m)
+    self.assertEqual(m.optional_bytes, self._GOLDEN_BYTES)
+    self.assertEqual(m.optional_string, self._GOLDEN_UNICODE)
+    self.assertEqual(m.repeated_bytes[0], self._GOLDEN_BYTES)
+    # repeated_bytes[1] contained simple \ escaped non-UTF-8 raw binary data.
+    self.assertEqual(m.repeated_bytes[1], self._GOLDEN_BYTES_1)
+    # repeated_string[0] contained \ escaped data representing the UTF-8
+    # representation of _GOLDEN_STR_0 - it needs to decode as such.
+    self.assertEqual(m.repeated_string[0], self._GOLDEN_STR_0)
+
+  def testFromBytesFile(self, message_module):
+    m = message_module.TestAllTypes()
+    f = io.BytesIO(self._BYTES_SAMPLE)
+    text_format.ParseLines(f, m)
+    self.assertEqual(m.optional_bytes, self._GOLDEN_BYTES)
+    self.assertEqual(m.optional_string, self._GOLDEN_UNICODE)
+    self.assertEqual(m.repeated_bytes[0], self._GOLDEN_BYTES)
+
+  def testFromUnicodeFile(self, message_module):
+    m = message_module.TestAllTypes()
+    f = io.StringIO(self._UNICODE_SAMPLE)
+    text_format.ParseLines(f, m)
+    self.assertEqual(m.optional_bytes, self._GOLDEN_BYTES)
+    self.assertEqual(m.optional_string, self._GOLDEN_UNICODE)
+    self.assertEqual(m.repeated_bytes[0], self._GOLDEN_BYTES)
+
+  def testFromBytesLines(self, message_module):
+    m = message_module.TestAllTypes()
+    text_format.ParseLines(self._BYTES_SAMPLE.split(b'\n'), m)
+    self.assertEqual(m.optional_bytes, self._GOLDEN_BYTES)
+    self.assertEqual(m.optional_string, self._GOLDEN_UNICODE)
+    self.assertEqual(m.repeated_bytes[0], self._GOLDEN_BYTES)
+
+  def testFromUnicodeLines(self, message_module):
+    m = message_module.TestAllTypes()
+    text_format.ParseLines(self._UNICODE_SAMPLE.split(u'\n'), m)
+    self.assertEqual(m.optional_bytes, self._GOLDEN_BYTES)
+    self.assertEqual(m.optional_string, self._GOLDEN_UNICODE)
+    self.assertEqual(m.repeated_bytes[0], self._GOLDEN_BYTES)
+
+
+@_parameterized.parameters(unittest_pb2, unittest_proto3_arena_pb2)
+class TextFormatMergeTests(TextFormatBase):
+
   def testMergeDuplicateScalars(self, message_module):
     message = message_module.TestAllTypes()
     text = ('optional_int32: 42 ' 'optional_int32: 67')
@@ -472,26 +672,12 @@
     self.assertTrue(r is message)
     self.assertEqual(2, message.optional_nested_message.bb)
 
-  def testParseOneof(self, message_module):
-    m = message_module.TestAllTypes()
-    m.oneof_uint32 = 11
-    m2 = message_module.TestAllTypes()
-    text_format.Parse(text_format.MessageToString(m), m2)
-    self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
-
   def testMergeMultipleOneof(self, message_module):
     m_string = '\n'.join(['oneof_uint32: 11', 'oneof_string: "foo"'])
     m2 = message_module.TestAllTypes()
     text_format.Merge(m_string, m2)
     self.assertEqual('oneof_string', m2.WhichOneof('oneof_field'))
 
-  def testParseMultipleOneof(self, message_module):
-    m_string = '\n'.join(['oneof_uint32: 11', 'oneof_string: "foo"'])
-    m2 = message_module.TestAllTypes()
-    with self.assertRaisesRegexp(text_format.ParseError,
-                                 ' is specified along with field '):
-      text_format.Parse(m_string, m2)
-
 
 # These are tests that aren't fundamentally specific to proto2, but are at
 # the moment because of differences between the proto2 and proto3 test schemas.
@@ -938,7 +1124,7 @@
                  '}\n')
     six.assertRaisesRegex(self,
                           text_format.ParseError,
-                          '5:1 : Expected ">".',
+                          '5:1 : \'}\': Expected ">".',
                           text_format.Parse,
                           malformed,
                           message,
@@ -981,7 +1167,8 @@
     with self.assertRaises(text_format.ParseError) as e:
       text_format.Parse(text, message)
     self.assertEqual(str(e.exception),
-                     '1:27 : Expected identifier or number, got "bb".')
+                     '1:27 : \'optional_nested_message { "bb": 1 }\': '
+                     'Expected identifier or number, got "bb".')
 
   def testParseBadExtension(self):
     message = unittest_pb2.TestAllExtensions()
@@ -998,7 +1185,8 @@
     message = unittest_pb2.TestAllTypes()
     text = 'optional_nested_enum: 100'
     six.assertRaisesRegex(self, text_format.ParseError,
-                          (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" '
+                          (r'1:23 : \'optional_nested_enum: 100\': '
+                           r'Enum type "\w+.TestAllTypes.NestedEnum" '
                            r'has no value with number 100.'), text_format.Parse,
                           text, message)
 
@@ -1448,6 +1636,26 @@
     self.assertEqual(0, text_format._ConsumeUint64(tokenizer))
     self.assertTrue(tokenizer.AtEnd())
 
+  def testConsumeOctalIntegers(self):
+    """Test support for C style octal integers."""
+    text = '00 -00 04 0755 -010 007 -0033 08 -09 01'
+    tokenizer = text_format.Tokenizer(text.splitlines())
+    self.assertEqual(0, tokenizer.ConsumeInteger())
+    self.assertEqual(0, tokenizer.ConsumeInteger())
+    self.assertEqual(4, tokenizer.ConsumeInteger())
+    self.assertEqual(0o755, tokenizer.ConsumeInteger())
+    self.assertEqual(-0o10, tokenizer.ConsumeInteger())
+    self.assertEqual(7, tokenizer.ConsumeInteger())
+    self.assertEqual(-0o033, tokenizer.ConsumeInteger())
+    with self.assertRaises(text_format.ParseError):
+      tokenizer.ConsumeInteger()  # 08
+    tokenizer.NextToken()
+    with self.assertRaises(text_format.ParseError):
+      tokenizer.ConsumeInteger()  # -09
+    tokenizer.NextToken()
+    self.assertEqual(1, tokenizer.ConsumeInteger())
+    self.assertTrue(tokenizer.AtEnd())
+
   def testConsumeByteString(self):
     text = '"string1\''
     tokenizer = text_format.Tokenizer(text.splitlines())
@@ -1556,6 +1764,12 @@
                      tokenizer.ConsumeCommentOrTrailingComment())
     self.assertTrue(tokenizer.AtEnd())
 
+  def testHugeString(self):
+    # With pathologic backtracking, fails with Forge OOM.
+    text = '"' + 'a' * (10 * 1024 * 1024) + '"'
+    tokenizer = text_format.Tokenizer(text.splitlines(), skip_comments=False)
+    tokenizer.ConsumeString()
+
 
 # Tests for pretty printer functionality.
 @_parameterized.parameters((unittest_pb2), (unittest_proto3_arena_pb2))
diff --git a/python/google/protobuf/internal/type_checkers.py b/python/google/protobuf/internal/type_checkers.py
index 4a76cd4..0807e7f 100755
--- a/python/google/protobuf/internal/type_checkers.py
+++ b/python/google/protobuf/internal/type_checkers.py
@@ -185,6 +185,14 @@
                          'encoding. Non-UTF-8 strings must be converted to '
                          'unicode objects before being added.' %
                          (proposed_value))
+    else:
+      try:
+        proposed_value.encode('utf8')
+      except UnicodeEncodeError:
+        raise ValueError('%.1024r isn\'t a valid unicode string and '
+                         'can\'t be encoded in UTF-8.'%
+                         (proposed_value))
+
     return proposed_value
 
   def DefaultValue(self):
diff --git a/python/google/protobuf/internal/unknown_fields_test.py b/python/google/protobuf/internal/unknown_fields_test.py
index 8b7de2e..fceadf7 100755
--- a/python/google/protobuf/internal/unknown_fields_test.py
+++ b/python/google/protobuf/internal/unknown_fields_test.py
@@ -49,20 +49,12 @@
 from google.protobuf.internal import test_util
 from google.protobuf.internal import testing_refleaks
 from google.protobuf.internal import type_checkers
+from google.protobuf import descriptor
 
 
 BaseTestCase = testing_refleaks.BaseTestCase
 
 
-# CheckUnknownField() cannot be used by the C++ implementation because
-# some protect members are called. It is not a behavior difference
-# for python and C++ implementation.
-def SkipCheckUnknownFieldIfCppImplementation(func):
-  return unittest.skipIf(
-      api_implementation.Type() == 'cpp' and api_implementation.Version() == 2,
-      'Addtional test for pure python involved protect members')(func)
-
-
 class UnknownFieldsTest(BaseTestCase):
 
   def setUp(self):
@@ -80,23 +72,11 @@
     # stdout.
     self.assertTrue(data == self.all_fields_data)
 
-  def expectSerializeProto3(self, preserve):
+  def testSerializeProto3(self):
+    # Verify proto3 unknown fields behavior.
     message = unittest_proto3_arena_pb2.TestEmptyMessage()
     message.ParseFromString(self.all_fields_data)
-    if preserve:
-      self.assertEqual(self.all_fields_data, message.SerializeToString())
-    else:
-      self.assertEqual(0, len(message.SerializeToString()))
-
-  def testSerializeProto3(self):
-    # Verify that proto3 unknown fields behavior.
-    default_preserve = (api_implementation
-                        .GetPythonProto3PreserveUnknownsDefault())
-    self.expectSerializeProto3(default_preserve)
-    api_implementation.SetPythonProto3PreserveUnknownsDefault(
-        not default_preserve)
-    self.expectSerializeProto3(not default_preserve)
-    api_implementation.SetPythonProto3PreserveUnknownsDefault(default_preserve)
+    self.assertEqual(self.all_fields_data, message.SerializeToString())
 
   def testByteSize(self):
     self.assertEqual(self.all_fields.ByteSize(), self.empty_message.ByteSize())
@@ -169,13 +149,15 @@
     self.empty_message = unittest_pb2.TestEmptyMessage()
     self.empty_message.ParseFromString(self.all_fields_data)
 
-  # CheckUnknownField() is an additional Pure Python check which checks
+  # InternalCheckUnknownField() is an additional Pure Python check which checks
   # a detail of unknown fields. It cannot be used by the C++
   # implementation because some protect members are called.
   # The test is added for historical reasons. It is not necessary as
   # serialized string is checked.
-
-  def CheckUnknownField(self, name, expected_value):
+  # TODO(jieluo): Remove message._unknown_fields.
+  def InternalCheckUnknownField(self, name, expected_value):
+    if api_implementation.Type() == 'cpp':
+      return
     field_descriptor = self.descriptor.fields_by_name[name]
     wire_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type]
     field_tag = encoder.TagBytes(field_descriptor.number, wire_type)
@@ -183,36 +165,80 @@
     for tag_bytes, value in self.empty_message._unknown_fields:
       if tag_bytes == field_tag:
         decoder = unittest_pb2.TestAllTypes._decoders_by_tag[tag_bytes][0]
-        decoder(value, 0, len(value), self.all_fields, result_dict)
+        decoder(memoryview(value), 0, len(value), self.all_fields, result_dict)
     self.assertEqual(expected_value, result_dict[field_descriptor])
 
-  @SkipCheckUnknownFieldIfCppImplementation
+  def CheckUnknownField(self, name, unknown_fields, expected_value):
+    field_descriptor = self.descriptor.fields_by_name[name]
+    expected_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[
+        field_descriptor.type]
+    for unknown_field in unknown_fields:
+      if unknown_field.field_number == field_descriptor.number:
+        self.assertEqual(expected_type, unknown_field.wire_type)
+        if expected_type == 3:
+          # Check group
+          self.assertEqual(expected_value[0],
+                           unknown_field.data[0].field_number)
+          self.assertEqual(expected_value[1], unknown_field.data[0].wire_type)
+          self.assertEqual(expected_value[2], unknown_field.data[0].data)
+          continue
+        if field_descriptor.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+          self.assertIn(unknown_field.data, expected_value)
+        else:
+          self.assertEqual(expected_value, unknown_field.data)
+
   def testCheckUnknownFieldValue(self):
+    unknown_fields = self.empty_message.UnknownFields()
     # Test enum.
     self.CheckUnknownField('optional_nested_enum',
+                           unknown_fields,
                            self.all_fields.optional_nested_enum)
+    self.InternalCheckUnknownField('optional_nested_enum',
+                                   self.all_fields.optional_nested_enum)
+
     # Test repeated enum.
     self.CheckUnknownField('repeated_nested_enum',
+                           unknown_fields,
                            self.all_fields.repeated_nested_enum)
+    self.InternalCheckUnknownField('repeated_nested_enum',
+                                   self.all_fields.repeated_nested_enum)
 
     # Test varint.
     self.CheckUnknownField('optional_int32',
+                           unknown_fields,
                            self.all_fields.optional_int32)
+    self.InternalCheckUnknownField('optional_int32',
+                                   self.all_fields.optional_int32)
+
     # Test fixed32.
     self.CheckUnknownField('optional_fixed32',
+                           unknown_fields,
                            self.all_fields.optional_fixed32)
+    self.InternalCheckUnknownField('optional_fixed32',
+                                   self.all_fields.optional_fixed32)
 
     # Test fixed64.
     self.CheckUnknownField('optional_fixed64',
+                           unknown_fields,
                            self.all_fields.optional_fixed64)
+    self.InternalCheckUnknownField('optional_fixed64',
+                                   self.all_fields.optional_fixed64)
 
     # Test lengthd elimited.
     self.CheckUnknownField('optional_string',
-                           self.all_fields.optional_string)
+                           unknown_fields,
+                           self.all_fields.optional_string.encode('utf-8'))
+    self.InternalCheckUnknownField('optional_string',
+                                   self.all_fields.optional_string)
 
     # Test group.
     self.CheckUnknownField('optionalgroup',
-                           self.all_fields.optionalgroup)
+                           unknown_fields,
+                           (17, 0, 117))
+    self.InternalCheckUnknownField('optionalgroup',
+                                   self.all_fields.optionalgroup)
+
+    self.assertEqual(97, len(unknown_fields))
 
   def testCopyFrom(self):
     message = unittest_pb2.TestEmptyMessage()
@@ -230,9 +256,18 @@
     message.optional_int64 = 3
     message.optional_uint32 = 4
     destination = unittest_pb2.TestEmptyMessage()
+    unknown_fields = destination.UnknownFields()
+    self.assertEqual(0, len(unknown_fields))
     destination.ParseFromString(message.SerializeToString())
-
+    # ParseFromString clears the message thus unknown fields is invalid.
+    with self.assertRaises(ValueError) as context:
+      len(unknown_fields)
+    self.assertIn('UnknownFields does not exist.',
+                  str(context.exception))
+    unknown_fields = destination.UnknownFields()
+    self.assertEqual(2, len(unknown_fields))
     destination.MergeFrom(source)
+    self.assertEqual(4, len(unknown_fields))
     # Check that the fields where correctly merged, even stored in the unknown
     # fields set.
     message.ParseFromString(destination.SerializeToString())
@@ -241,9 +276,58 @@
     self.assertEqual(message.optional_int64, 3)
 
   def testClear(self):
+    unknown_fields = self.empty_message.UnknownFields()
     self.empty_message.Clear()
     # All cleared, even unknown fields.
     self.assertEqual(self.empty_message.SerializeToString(), b'')
+    with self.assertRaises(ValueError) as context:
+      len(unknown_fields)
+    self.assertIn('UnknownFields does not exist.',
+                  str(context.exception))
+
+  def testSubUnknownFields(self):
+    message = unittest_pb2.TestAllTypes()
+    message.optionalgroup.a = 123
+    destination = unittest_pb2.TestEmptyMessage()
+    destination.ParseFromString(message.SerializeToString())
+    sub_unknown_fields = destination.UnknownFields()[0].data
+    self.assertEqual(1, len(sub_unknown_fields))
+    self.assertEqual(sub_unknown_fields[0].data, 123)
+    destination.Clear()
+    with self.assertRaises(ValueError) as context:
+      len(sub_unknown_fields)
+    self.assertIn('UnknownFields does not exist.',
+                  str(context.exception))
+    with self.assertRaises(ValueError) as context:
+      # pylint: disable=pointless-statement
+      sub_unknown_fields[0]
+    self.assertIn('UnknownFields does not exist.',
+                  str(context.exception))
+    message.Clear()
+    message.optional_uint32 = 456
+    nested_message = unittest_pb2.NestedTestAllTypes()
+    nested_message.payload.optional_nested_message.ParseFromString(
+        message.SerializeToString())
+    unknown_fields = (
+        nested_message.payload.optional_nested_message.UnknownFields())
+    self.assertEqual(unknown_fields[0].data, 456)
+    nested_message.ClearField('payload')
+    self.assertEqual(unknown_fields[0].data, 456)
+    unknown_fields = (
+        nested_message.payload.optional_nested_message.UnknownFields())
+    self.assertEqual(0, len(unknown_fields))
+
+  def testUnknownField(self):
+    message = unittest_pb2.TestAllTypes()
+    message.optional_int32 = 123
+    destination = unittest_pb2.TestEmptyMessage()
+    destination.ParseFromString(message.SerializeToString())
+    unknown_field = destination.UnknownFields()[0]
+    destination.Clear()
+    with self.assertRaises(ValueError) as context:
+      unknown_field.data    # pylint: disable=pointless-statement
+    self.assertIn('The parent message might be cleared.',
+                  str(context.exception))
 
   def testUnknownExtensions(self):
     message = unittest_pb2.TestEmptyMessageWithExtensions()
@@ -280,15 +364,13 @@
 
   def CheckUnknownField(self, name, expected_value):
     field_descriptor = self.descriptor.fields_by_name[name]
-    wire_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type]
-    field_tag = encoder.TagBytes(field_descriptor.number, wire_type)
-    result_dict = {}
-    for tag_bytes, value in self.missing_message._unknown_fields:
-      if tag_bytes == field_tag:
-        decoder = missing_enum_values_pb2.TestEnumValues._decoders_by_tag[
-            tag_bytes][0]
-        decoder(value, 0, len(value), self.message, result_dict)
-    self.assertEqual(expected_value, result_dict[field_descriptor])
+    unknown_fields = self.missing_message.UnknownFields()
+    for field in unknown_fields:
+      if field.field_number == field_descriptor.number:
+        if field_descriptor.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+          self.assertIn(field.data, expected_value)
+        else:
+          self.assertEqual(expected_value, field.data)
 
   def testUnknownParseMismatchEnumValue(self):
     just_string = missing_enum_values_pb2.JustString()
@@ -317,7 +399,6 @@
   def testUnknownPackedEnumValue(self):
     self.assertEqual([], self.missing_message.packed_nested_enum)
 
-  @SkipCheckUnknownFieldIfCppImplementation
   def testCheckUnknownFieldValueForEnum(self):
     self.CheckUnknownField('optional_nested_enum',
                            self.message.optional_nested_enum)
diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py
index 58c94a4..ce1db7d 100644
--- a/python/google/protobuf/json_format.py
+++ b/python/google/protobuf/json_format.py
@@ -482,7 +482,7 @@
               ('Message type "{0}" has no field named "{1}".\n'
                ' Available Fields(except extensions): {2}').format(
                    message_descriptor.full_name, name,
-                   message_descriptor.fields))
+                   [f.json_name for f in message_descriptor.fields]))
         if name in names:
           raise ParseError('Message type "{0}" should not have multiple '
                            '"{1}" fields.'.format(
diff --git a/python/google/protobuf/message.py b/python/google/protobuf/message.py
index eeb0d57..eca2e0a 100755
--- a/python/google/protobuf/message.py
+++ b/python/google/protobuf/message.py
@@ -268,6 +268,10 @@
   def ClearExtension(self, extension_handle):
     raise NotImplementedError
 
+  def UnknownFields(self):
+    """Returns the UnknownFieldSet."""
+    raise NotImplementedError
+
   def DiscardUnknownFields(self):
     raise NotImplementedError
 
diff --git a/python/google/protobuf/message_factory.py b/python/google/protobuf/message_factory.py
index e4fb065..f3ab0a5 100644
--- a/python/google/protobuf/message_factory.py
+++ b/python/google/protobuf/message_factory.py
@@ -39,9 +39,18 @@
 
 __author__ = 'matthewtoia@google.com (Matt Toia)'
 
+from google.protobuf.internal import api_implementation
 from google.protobuf import descriptor_pool
 from google.protobuf import message
-from google.protobuf import reflection
+
+if api_implementation.Type() == 'cpp':
+  from google.protobuf.pyext import cpp_message as message_impl
+else:
+  from google.protobuf.internal import python_message as message_impl
+
+
+# The type of all Message classes.
+_GENERATED_PROTOCOL_MESSAGE_TYPE = message_impl.GeneratedProtocolMessageType
 
 
 class MessageFactory(object):
@@ -70,11 +79,11 @@
       descriptor_name = descriptor.name
       if str is bytes:  # PY2
         descriptor_name = descriptor.name.encode('ascii', 'ignore')
-      result_class = reflection.GeneratedProtocolMessageType(
+      result_class = _GENERATED_PROTOCOL_MESSAGE_TYPE(
           descriptor_name,
           (message.Message,),
           {'DESCRIPTOR': descriptor, '__module__': None})
-          # If module not set, it wrongly points to the reflection.py module.
+      # If module not set, it wrongly points to message_factory module.
       self._classes[descriptor] = result_class
       for field in descriptor.fields:
         if field.message_type:
diff --git a/python/google/protobuf/proto_api.h b/python/google/protobuf/proto_api.h
index 5c076d2..47edf0e 100644
--- a/python/google/protobuf/proto_api.h
+++ b/python/google/protobuf/proto_api.h
@@ -42,16 +42,15 @@
 // Then use the methods of the returned class:
 //    py_proto_api->GetMessagePointer(...);
 
-#ifndef PYTHON_GOOGLE_PROTOBUF_PROTO_API_H__
-#define PYTHON_GOOGLE_PROTOBUF_PROTO_API_H__
+#ifndef GOOGLE_PROTOBUF_PYTHON_PROTO_API_H__
+#define GOOGLE_PROTOBUF_PYTHON_PROTO_API_H__
 
 #include <Python.h>
 
+#include <google/protobuf/message.h>
+
 namespace google {
 namespace protobuf {
-
-class Message;
-
 namespace python {
 
 // Note on the implementation:
@@ -89,4 +88,4 @@
 }  // namespace protobuf
 }  // namespace google
 
-#endif  // PYTHON_GOOGLE_PROTOBUF_PROTO_API_H__
+#endif  // GOOGLE_PROTOBUF_PYTHON_PROTO_API_H__
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc
index 19a1c38..3cb16b7 100644
--- a/python/google/protobuf/pyext/descriptor.cc
+++ b/python/google/protobuf/pyext/descriptor.cc
@@ -32,8 +32,8 @@
 
 #include <Python.h>
 #include <frameobject.h>
-#include <google/protobuf/stubs/hash.h>
 #include <string>
+#include <unordered_map>
 
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/descriptor.pb.h>
@@ -44,6 +44,7 @@
 #include <google/protobuf/pyext/message.h>
 #include <google/protobuf/pyext/message_factory.h>
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+#include <google/protobuf/stubs/hash.h>
 
 #if PY_MAJOR_VERSION >= 3
   #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
@@ -54,10 +55,12 @@
   #if PY_VERSION_HEX < 0x03030000
     #error "Python 3.0 - 3.2 are not supported."
   #endif
-  #define PyString_AsStringAndSize(ob, charpp, sizep) \
-    (PyUnicode_Check(ob)? \
-       ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \
-       PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
+#define PyString_AsStringAndSize(ob, charpp, sizep)                           \
+  (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>(                     \
+                               PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
+                              ? -1                                            \
+                              : 0)                                            \
+                       : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
 #endif
 
 namespace google {
@@ -70,7 +73,7 @@
 // released.
 // This is enough to support the "is" operator on live objects.
 // All descriptors are stored here.
-hash_map<const void*, PyObject*> interned_descriptors;
+std::unordered_map<const void*, PyObject*>* interned_descriptors;
 
 PyObject* PyString_FromCppString(const string& str) {
   return PyString_FromStringAndSize(str.c_str(), str.size());
@@ -119,8 +122,10 @@
     PyErr_Clear();
     return false;
   }
-  if ((filename_size < 3) || (strcmp(&filename[filename_size - 3], ".py") != 0)) {
-    // Cython's stack does not have .py file name and is not at global module scope.
+  if ((filename_size < 3) ||
+      (strcmp(&filename[filename_size - 3], ".py") != 0)) {
+    // Cython's stack does not have .py file name and is not at global module
+    // scope.
     return true;
   }
   if (filename_size < 7) {
@@ -131,7 +136,7 @@
     // Filename is not ending with _pb2.
     return false;
   }
-  
+
   if (frame->f_globals != frame->f_locals) {
     // Not at global module scope
     return false;
@@ -197,7 +202,7 @@
   // First search in the cache.
   PyDescriptorPool* caching_pool = GetDescriptorPool_FromPool(
       GetFileDescriptor(descriptor)->pool());
-  hash_map<const void*, PyObject*>* descriptor_options =
+  std::unordered_map<const void*, PyObject*>* descriptor_options =
       caching_pool->descriptor_options;
   if (descriptor_options->find(descriptor) != descriptor_options->end()) {
     PyObject *value = (*descriptor_options)[descriptor];
@@ -232,7 +237,7 @@
   if (value == NULL) {
     return NULL;
   }
-  if (!PyObject_TypeCheck(value.get(), &CMessage_Type)) {
+  if (!PyObject_TypeCheck(value.get(), CMessage_Type)) {
       PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s",
                    message_type->full_name().c_str(),
                    Py_TYPE(value.get())->tp_name);
@@ -275,7 +280,7 @@
   const Descriptor* self_descriptor =
       DescriptorProtoClass::default_instance().GetDescriptor();
   CMessage* message = reinterpret_cast<CMessage*>(target);
-  if (!PyObject_TypeCheck(target, &CMessage_Type) ||
+  if (!PyObject_TypeCheck(target, CMessage_Type) ||
       message->message->GetDescriptor() != self_descriptor) {
     PyErr_Format(PyExc_TypeError, "Not a %s message",
                  self_descriptor->full_name().c_str());
@@ -332,9 +337,9 @@
   }
 
   // See if the object is in the map of interned descriptors
-  hash_map<const void*, PyObject*>::iterator it =
-      interned_descriptors.find(descriptor);
-  if (it != interned_descriptors.end()) {
+  std::unordered_map<const void*, PyObject*>::iterator it =
+      interned_descriptors->find(descriptor);
+  if (it != interned_descriptors->end()) {
     GOOGLE_DCHECK(Py_TYPE(it->second) == type);
     Py_INCREF(it->second);
     return it->second;
@@ -348,7 +353,7 @@
   py_descriptor->descriptor = descriptor;
 
   // and cache it.
-  interned_descriptors.insert(
+  interned_descriptors->insert(
       std::make_pair(descriptor, reinterpret_cast<PyObject*>(py_descriptor)));
 
   // Ensures that the DescriptorPool stays alive.
@@ -370,7 +375,7 @@
 
 static void Dealloc(PyBaseDescriptor* self) {
   // Remove from interned dictionary
-  interned_descriptors.erase(self->descriptor);
+  interned_descriptors->erase(self->descriptor);
   Py_CLEAR(self->pool);
   Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
 }
@@ -758,6 +763,11 @@
 static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) {
   PyObject *result;
 
+  if (_GetDescriptor(self)->is_repeated()) {
+    return PyList_New(0);
+  }
+
+
   switch (_GetDescriptor(self)->cpp_type()) {
     case FieldDescriptor::CPPTYPE_INT32: {
       int32 value = _GetDescriptor(self)->default_value_int32();
@@ -805,6 +815,10 @@
       result = PyInt_FromLong(value->number());
       break;
     }
+    case FieldDescriptor::CPPTYPE_MESSAGE: {
+      Py_RETURN_NONE;
+      break;
+    }
     default:
       PyErr_Format(PyExc_NotImplementedError, "default value for %s",
                    _GetDescriptor(self)->full_name().c_str());
@@ -1919,6 +1933,9 @@
   if (!InitDescriptorMappingTypes())
     return false;
 
+  // Initialize globals defined in this file.
+  interned_descriptors = new std::unordered_map<const void*, PyObject*>;
+
   return true;
 }
 
diff --git a/python/google/protobuf/pyext/descriptor.h b/python/google/protobuf/pyext/descriptor.h
index f081df8..c4dde9e 100644
--- a/python/google/protobuf/pyext/descriptor.h
+++ b/python/google/protobuf/pyext/descriptor.h
@@ -100,6 +100,6 @@
 
 }  // namespace python
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_H__
diff --git a/python/google/protobuf/pyext/descriptor_containers.cc b/python/google/protobuf/pyext/descriptor_containers.cc
index 0153664..d5b5dc6 100644
--- a/python/google/protobuf/pyext/descriptor_containers.cc
+++ b/python/google/protobuf/pyext/descriptor_containers.cc
@@ -33,7 +33,7 @@
 //
 // They avoid the allocation of a full dictionary or a full list: they simply
 // store a pointer to the parent descriptor, use the C++ Descriptor methods (see
-// google/protobuf/descriptor.h) to retrieve other descriptors, and create
+// net/proto2/public/descriptor.h) to retrieve other descriptors, and create
 // Python objects on the fly.
 //
 // The containers fully conform to abc.Mapping and abc.Sequence, and behave just
@@ -64,10 +64,12 @@
   #if PY_VERSION_HEX < 0x03030000
     #error "Python 3.0 - 3.2 are not supported."
   #endif
-  #define PyString_AsStringAndSize(ob, charpp, sizep) \
-    (PyUnicode_Check(ob)? \
-       ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \
-       PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
+#define PyString_AsStringAndSize(ob, charpp, sizep)                           \
+  (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>(                     \
+                               PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
+                              ? -1                                            \
+                              : 0)                                            \
+                       : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
 #endif
 
 namespace google {
diff --git a/python/google/protobuf/pyext/descriptor_containers.h b/python/google/protobuf/pyext/descriptor_containers.h
index 83de07b..4e05c58 100644
--- a/python/google/protobuf/pyext/descriptor_containers.h
+++ b/python/google/protobuf/pyext/descriptor_containers.h
@@ -104,6 +104,6 @@
 
 }  // namespace python
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_CONTAINERS_H__
diff --git a/python/google/protobuf/pyext/descriptor_database.cc b/python/google/protobuf/pyext/descriptor_database.cc
index daa40cc..0514b35 100644
--- a/python/google/protobuf/pyext/descriptor_database.cc
+++ b/python/google/protobuf/pyext/descriptor_database.cc
@@ -70,7 +70,7 @@
   const Descriptor* filedescriptor_descriptor =
       FileDescriptorProto::default_instance().GetDescriptor();
   CMessage* message = reinterpret_cast<CMessage*>(py_descriptor);
-  if (PyObject_TypeCheck(py_descriptor, &CMessage_Type) &&
+  if (PyObject_TypeCheck(py_descriptor, CMessage_Type) &&
       message->message->GetDescriptor() == filedescriptor_descriptor) {
     // Fast path: Just use the pointer.
     FileDescriptorProto* file_proto =
@@ -143,6 +143,43 @@
   return GetFileDescriptorProto(py_descriptor.get(), output);
 }
 
+// Finds the tag numbers used by all known extensions of
+// containing_type, and appends them to output in an undefined
+// order.
+// Python DescriptorDatabases are not required to implement this method.
+bool PyDescriptorDatabase::FindAllExtensionNumbers(
+    const string& containing_type, std::vector<int>* output) {
+  ScopedPyObjectPtr py_method(
+      PyObject_GetAttrString(py_database_, "FindAllExtensionNumbers"));
+  if (py_method == NULL) {
+    // This method is not implemented, returns without error.
+    PyErr_Clear();
+    return false;
+  }
+  ScopedPyObjectPtr py_list(
+      PyObject_CallFunction(py_method.get(), "s#", containing_type.c_str(),
+                            containing_type.size()));
+  if (py_list == NULL) {
+    PyErr_Print();
+    return false;
+  }
+  Py_ssize_t size = PyList_Size(py_list.get());
+  int64 item_value;
+  for (Py_ssize_t i = 0 ; i < size; ++i) {
+    ScopedPyObjectPtr item(PySequence_GetItem(py_list.get(), i));
+    item_value = PyLong_AsLong(item.get());
+    if (item_value < 0) {
+      GOOGLE_LOG(ERROR)
+          << "FindAllExtensionNumbers method did not return "
+          << "valid extension numbers.";
+      PyErr_Print();
+      return false;
+    }
+    output->push_back(item_value);
+  }
+  return true;
+}
+
 }  // namespace python
 }  // namespace protobuf
 }  // namespace google
diff --git a/python/google/protobuf/pyext/descriptor_database.h b/python/google/protobuf/pyext/descriptor_database.h
index fc71c4b..daf25e0 100644
--- a/python/google/protobuf/pyext/descriptor_database.h
+++ b/python/google/protobuf/pyext/descriptor_database.h
@@ -63,6 +63,13 @@
                                    int field_number,
                                    FileDescriptorProto* output);
 
+  // Finds the tag numbers used by all known extensions of
+  // containing_type, and appends them to output in an undefined
+  // order.
+  // Python objects are not required to implement this method.
+  bool FindAllExtensionNumbers(const string& containing_type,
+                               std::vector<int>* output);
+
  private:
   // The python object that implements the database. The reference is owned.
   PyObject* py_database_;
@@ -70,6 +77,6 @@
 
 }  // namespace python
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_DATABASE_H__
diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc
index 962accc..d0038b1 100644
--- a/python/google/protobuf/pyext/descriptor_pool.cc
+++ b/python/google/protobuf/pyext/descriptor_pool.cc
@@ -30,6 +30,8 @@
 
 // Implements the DescriptorPool, which collects all descriptors.
 
+#include <unordered_map>
+
 #include <Python.h>
 
 #include <google/protobuf/descriptor.pb.h>
@@ -46,10 +48,12 @@
   #if PY_VERSION_HEX < 0x03030000
     #error "Python 3.0 - 3.2 are not supported."
   #endif
-  #define PyString_AsStringAndSize(ob, charpp, sizep) \
-    (PyUnicode_Check(ob)? \
-       ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \
-       PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
+#define PyString_AsStringAndSize(ob, charpp, sizep)                           \
+  (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>(                     \
+                               PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
+                              ? -1                                            \
+                              : 0)                                            \
+                       : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
 #endif
 
 namespace google {
@@ -58,7 +62,8 @@
 
 // A map to cache Python Pools per C++ pointer.
 // Pointers are not owned here, and belong to the PyDescriptorPool.
-static hash_map<const DescriptorPool*, PyDescriptorPool*> descriptor_pool_map;
+static std::unordered_map<const DescriptorPool*, PyDescriptorPool*>*
+    descriptor_pool_map;
 
 namespace cdescriptor_pool {
 
@@ -74,8 +79,7 @@
   cpool->underlay = NULL;
   cpool->database = NULL;
 
-  cpool->descriptor_options =
-      new hash_map<const void*, PyObject *>();
+  cpool->descriptor_options = new std::unordered_map<const void*, PyObject*>();
 
   cpool->py_message_factory = message_factory::NewMessageFactory(
       &PyMessageFactory_Type, cpool);
@@ -101,7 +105,7 @@
   cpool->pool = new DescriptorPool(underlay);
   cpool->underlay = underlay;
 
-  if (!descriptor_pool_map.insert(
+  if (!descriptor_pool_map->insert(
       std::make_pair(cpool->pool, cpool)).second) {
     // Should never happen -- would indicate an internal error / bug.
     PyErr_SetString(PyExc_ValueError, "DescriptorPool already registered");
@@ -124,7 +128,7 @@
     cpool->pool = new DescriptorPool();
   }
 
-  if (!descriptor_pool_map.insert(std::make_pair(cpool->pool, cpool)).second) {
+  if (!descriptor_pool_map->insert(std::make_pair(cpool->pool, cpool)).second) {
     // Should never happen -- would indicate an internal error / bug.
     PyErr_SetString(PyExc_ValueError, "DescriptorPool already registered");
     return NULL;
@@ -151,9 +155,9 @@
 
 static void Dealloc(PyObject* pself) {
   PyDescriptorPool* self = reinterpret_cast<PyDescriptorPool*>(pself);
-  descriptor_pool_map.erase(self->pool);
+  descriptor_pool_map->erase(self->pool);
   Py_CLEAR(self->py_message_factory);
-  for (hash_map<const void*, PyObject*>::iterator it =
+  for (std::unordered_map<const void*, PyObject*>::iterator it =
            self->descriptor_options->begin();
        it != self->descriptor_options->end(); ++it) {
     Py_DECREF(it->second);
@@ -180,6 +184,7 @@
     return NULL;
   }
 
+
   return PyMessageDescriptor_FromDescriptor(message_descriptor);
 }
 
@@ -218,6 +223,7 @@
     return NULL;
   }
 
+
   return PyFieldDescriptor_FromDescriptor(field_descriptor);
 }
 
@@ -239,6 +245,7 @@
     return NULL;
   }
 
+
   return PyFieldDescriptor_FromDescriptor(field_descriptor);
 }
 
@@ -260,6 +267,7 @@
     return NULL;
   }
 
+
   return PyEnumDescriptor_FromDescriptor(enum_descriptor);
 }
 
@@ -281,6 +289,7 @@
     return NULL;
   }
 
+
   return PyOneofDescriptor_FromDescriptor(oneof_descriptor);
 }
 
@@ -303,6 +312,7 @@
     return NULL;
   }
 
+
   return PyServiceDescriptor_FromDescriptor(service_descriptor);
 }
 
@@ -321,6 +331,7 @@
     return NULL;
   }
 
+
   return PyMethodDescriptor_FromDescriptor(method_descriptor);
 }
 
@@ -339,6 +350,7 @@
     return NULL;
   }
 
+
   return PyFileDescriptor_FromDescriptor(file_descriptor);
 }
 
@@ -362,6 +374,7 @@
     return NULL;
   }
 
+
   return PyFieldDescriptor_FromDescriptor(extension_descriptor);
 }
 
@@ -668,13 +681,17 @@
   // The Pool of messages declared in Python libraries.
   // generated_pool() contains all messages already linked in C++ libraries, and
   // is used as underlay.
+  descriptor_pool_map =
+      new std::unordered_map<const DescriptorPool*, PyDescriptorPool*>;
   python_generated_pool = cdescriptor_pool::PyDescriptorPool_NewWithUnderlay(
       DescriptorPool::generated_pool());
   if (python_generated_pool == NULL) {
+    delete descriptor_pool_map;
     return false;
   }
+
   // Register this pool to be found for C++-generated descriptors.
-  descriptor_pool_map.insert(
+  descriptor_pool_map->insert(
       std::make_pair(DescriptorPool::generated_pool(),
                      python_generated_pool));
 
@@ -695,9 +712,9 @@
       pool == DescriptorPool::generated_pool()) {
     return python_generated_pool;
   }
-  hash_map<const DescriptorPool*, PyDescriptorPool*>::iterator it =
-      descriptor_pool_map.find(pool);
-  if (it == descriptor_pool_map.end()) {
+  std::unordered_map<const DescriptorPool*, PyDescriptorPool*>::iterator it =
+      descriptor_pool_map->find(pool);
+  if (it == descriptor_pool_map->end()) {
     PyErr_SetString(PyExc_KeyError, "Unknown descriptor pool");
     return NULL;
   }
diff --git a/python/google/protobuf/pyext/descriptor_pool.h b/python/google/protobuf/pyext/descriptor_pool.h
index 53ee53d..8289dae 100644
--- a/python/google/protobuf/pyext/descriptor_pool.h
+++ b/python/google/protobuf/pyext/descriptor_pool.h
@@ -33,7 +33,7 @@
 
 #include <Python.h>
 
-#include <google/protobuf/stubs/hash.h>
+#include <unordered_map>
 #include <google/protobuf/descriptor.h>
 
 namespace google {
@@ -77,7 +77,7 @@
   // Cache the options for any kind of descriptor.
   // Descriptor pointers are owned by the DescriptorPool above.
   // Python objects are owned by the map.
-  hash_map<const void*, PyObject*>* descriptor_options;
+  std::unordered_map<const void*, PyObject*>* descriptor_options;
 } PyDescriptorPool;
 
 
@@ -140,6 +140,6 @@
 
 }  // namespace python
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_POOL_H__
diff --git a/python/google/protobuf/pyext/extension_dict.cc b/python/google/protobuf/pyext/extension_dict.cc
index 174c547..b73368e 100644
--- a/python/google/protobuf/pyext/extension_dict.cc
+++ b/python/google/protobuf/pyext/extension_dict.cc
@@ -51,10 +51,12 @@
   #if PY_VERSION_HEX < 0x03030000
     #error "Python 3.0 - 3.2 are not supported."
   #endif
-  #define PyString_AsStringAndSize(ob, charpp, sizep) \
-    (PyUnicode_Check(ob)? \
-       ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \
-       PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
+#define PyString_AsStringAndSize(ob, charpp, sizep)                           \
+  (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>(                     \
+                               PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
+                              ? -1                                            \
+                              : 0)                                            \
+                       : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
 #endif
 
 namespace google {
@@ -63,40 +65,25 @@
 
 namespace extension_dict {
 
-PyObject* len(ExtensionDict* self) {
-#if PY_MAJOR_VERSION >= 3
-  return PyLong_FromLong(PyDict_Size(self->values));
-#else
-  return PyInt_FromLong(PyDict_Size(self->values));
-#endif
-}
-
 PyObject* subscript(ExtensionDict* self, PyObject* key) {
   const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key);
   if (descriptor == NULL) {
     return NULL;
   }
-  if (!CheckFieldBelongsToMessage(descriptor, self->message)) {
+  if (!CheckFieldBelongsToMessage(descriptor, self->parent->message)) {
     return NULL;
   }
 
   if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
       descriptor->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
-    return cmessage::InternalGetScalar(self->message, descriptor);
+    return cmessage::InternalGetScalar(self->parent->message, descriptor);
   }
 
-  PyObject* value = PyDict_GetItem(self->values, key);
-  if (value != NULL) {
-    Py_INCREF(value);
-    return value;
-  }
-
-  if (self->parent == NULL) {
-    // We are in "detached" state. Don't allow further modifications.
-    // TODO(amauryfa): Support adding non-scalars to a detached extension dict.
-    // This probably requires to store the type of the main message.
-    PyErr_SetObject(PyExc_KeyError, key);
-    return NULL;
+  CMessage::CompositeFieldsMap::iterator iterator =
+      self->parent->composite_fields->find(descriptor);
+  if (iterator != self->parent->composite_fields->end()) {
+    Py_INCREF(iterator->second);
+    return iterator->second;
   }
 
   if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
@@ -107,7 +94,8 @@
     if (sub_message == NULL) {
       return NULL;
     }
-    PyDict_SetItem(self->values, key, sub_message);
+    Py_INCREF(sub_message);
+    (*self->parent->composite_fields)[descriptor] = sub_message;
     return sub_message;
   }
 
@@ -136,7 +124,8 @@
       if (py_container == NULL) {
         return NULL;
       }
-      PyDict_SetItem(self->values, key, py_container);
+      Py_INCREF(py_container);
+      (*self->parent->composite_fields)[descriptor] = py_container;
       return py_container;
     } else {
       PyObject* py_container = repeated_scalar_container::NewContainer(
@@ -144,7 +133,8 @@
       if (py_container == NULL) {
         return NULL;
       }
-      PyDict_SetItem(self->values, key, py_container);
+      Py_INCREF(py_container);
+      (*self->parent->composite_fields)[descriptor] = py_container;
       return py_container;
     }
   }
@@ -157,7 +147,7 @@
   if (descriptor == NULL) {
     return -1;
   }
-  if (!CheckFieldBelongsToMessage(descriptor, self->message)) {
+  if (!CheckFieldBelongsToMessage(descriptor, self->parent->message)) {
     return -1;
   }
 
@@ -167,14 +157,10 @@
                     "type");
     return -1;
   }
-  if (self->parent) {
-    cmessage::AssureWritable(self->parent);
-    if (cmessage::InternalSetScalar(self->parent, descriptor, value) < 0) {
-      return -1;
-    }
+  cmessage::AssureWritable(self->parent);
+  if (cmessage::InternalSetScalar(self->parent, descriptor, value) < 0) {
+    return -1;
   }
-  // TODO(tibell): We shouldn't write scalars to the cache.
-  PyDict_SetItem(self->values, key, value);
   return 0;
 }
 
@@ -232,22 +218,36 @@
     return NULL;
   }
 
-  self->parent = parent;  // Store a borrowed reference.
-  self->message = parent->message;
-  self->owner = parent->owner;
-  self->values = PyDict_New();
+  Py_INCREF(parent);
+  self->parent = parent;
   return self;
 }
 
 void dealloc(ExtensionDict* self) {
-  Py_CLEAR(self->values);
-  self->owner.reset();
+  Py_CLEAR(self->parent);
   Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
 }
 
+static PyObject* RichCompare(ExtensionDict* self, PyObject* other, int opid) {
+  // Only equality comparisons are implemented.
+  if (opid != Py_EQ && opid != Py_NE) {
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+  }
+  bool equals = false;
+  if (PyObject_TypeCheck(other, &ExtensionDict_Type)) {
+    equals = self->parent == reinterpret_cast<ExtensionDict*>(other)->parent;;
+  }
+  if (equals ^ (opid == Py_EQ)) {
+    Py_RETURN_FALSE;
+  } else {
+    Py_RETURN_TRUE;
+  }
+}
+
 static PyMappingMethods MpMethods = {
-  (lenfunc)len,               /* mp_length */
-  (binaryfunc)subscript,      /* mp_subscript */
+  (lenfunc)NULL,               /* mp_length */
+  (binaryfunc)subscript,       /* mp_subscript */
   (objobjargproc)ass_subscript,/* mp_ass_subscript */
 };
 
@@ -286,7 +286,7 @@
   "An extension dict",                 //  tp_doc
   0,                                   //  tp_traverse
   0,                                   //  tp_clear
-  0,                                   //  tp_richcompare
+  (richcmpfunc)extension_dict::RichCompare,  //  tp_richcompare
   0,                                   //  tp_weaklistoffset
   0,                                   //  tp_iter
   0,                                   //  tp_iternext
diff --git a/python/google/protobuf/pyext/extension_dict.h b/python/google/protobuf/pyext/extension_dict.h
index 0de2c4e..a7d6bb7 100644
--- a/python/google/protobuf/pyext/extension_dict.h
+++ b/python/google/protobuf/pyext/extension_dict.h
@@ -51,23 +51,8 @@
 typedef struct ExtensionDict {
   PyObject_HEAD;
 
-  // This is the top-level C++ Message object that owns the whole
-  // proto tree.  Every Python container class holds a
-  // reference to it in order to keep it alive as long as there's a
-  // Python object that references any part of the tree.
-  CMessage::OwnerRef owner;
-
-  // Weak reference to parent message. Used to make sure
-  // the parent is writable when an extension field is modified.
+  // Strong, owned reference to the parent message. Never NULL.
   CMessage* parent;
-
-  // Pointer to the C++ Message that this ExtensionDict extends.
-  // Not owned by us.
-  Message* message;
-
-  // A dict of child messages, indexed by Extension descriptors.
-  // Similar to CMessage::composite_fields.
-  PyObject* values;
 } ExtensionDict;
 
 extern PyTypeObject ExtensionDict_Type;
@@ -80,6 +65,6 @@
 }  // namespace extension_dict
 }  // namespace python
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_EXTENSION_DICT_H__
diff --git a/python/google/protobuf/pyext/field.cc b/python/google/protobuf/pyext/field.cc
new file mode 100755
index 0000000..1afd458
--- /dev/null
+++ b/python/google/protobuf/pyext/field.cc
@@ -0,0 +1,142 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/pyext/field.h>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/pyext/descriptor.h>
+#include <google/protobuf/pyext/message.h>
+
+#if PY_MAJOR_VERSION >= 3
+  #define PyString_FromFormat PyUnicode_FromFormat
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+namespace field {
+
+static PyObject* Repr(PyMessageFieldProperty* self) {
+  return PyString_FromFormat("<field property '%s'>",
+                             self->field_descriptor->full_name().c_str());
+}
+
+static PyObject* DescrGet(PyMessageFieldProperty* self, PyObject* obj,
+                          PyObject* type) {
+  if (obj == NULL) {
+    Py_INCREF(self);
+    return reinterpret_cast<PyObject*>(self);
+  }
+  return cmessage::GetFieldValue(reinterpret_cast<CMessage*>(obj),
+                                 self->field_descriptor);
+}
+
+static int DescrSet(PyMessageFieldProperty* self, PyObject* obj,
+                    PyObject* value) {
+  if (value == NULL) {
+    PyErr_SetString(PyExc_AttributeError, "Cannot delete field attribute");
+    return -1;
+  }
+  return cmessage::SetFieldValue(reinterpret_cast<CMessage*>(obj),
+                                 self->field_descriptor, value);
+}
+
+static PyObject* GetDescriptor(PyMessageFieldProperty* self, void* closure) {
+  return PyFieldDescriptor_FromDescriptor(self->field_descriptor);
+}
+
+static PyObject* GetDoc(PyMessageFieldProperty* self, void* closure) {
+  return PyString_FromFormat("Field %s",
+                             self->field_descriptor->full_name().c_str());
+}
+
+static PyGetSetDef Getters[] = {
+    {"DESCRIPTOR", (getter)GetDescriptor, NULL, "Field descriptor"},
+    {"__doc__", (getter)GetDoc, NULL, NULL},
+    {NULL}};
+}  // namespace field
+
+static PyTypeObject _CFieldProperty_Type = {
+    PyVarObject_HEAD_INIT(&PyType_Type, 0)    // head
+    FULL_MODULE_NAME ".FieldProperty",        // tp_name
+    sizeof(PyMessageFieldProperty),           // tp_basicsize
+    0,                                        // tp_itemsize
+    0,                                        // tp_dealloc
+    0,                                        // tp_print
+    0,                                        // tp_getattr
+    0,                                        // tp_setattr
+    0,                                        // tp_compare
+    (reprfunc)field::Repr,                    // tp_repr
+    0,                                        // tp_as_number
+    0,                                        // tp_as_sequence
+    0,                                        // tp_as_mapping
+    0,                                        // tp_hash
+    0,                                        // tp_call
+    0,                                        // tp_str
+    0,                                        // tp_getattro
+    0,                                        // tp_setattro
+    0,                                        // tp_as_buffer
+    Py_TPFLAGS_DEFAULT,                       // tp_flags
+    "Field property of a Message",            // tp_doc
+    0,                                        // tp_traverse
+    0,                                        // tp_clear
+    0,                                        // tp_richcompare
+    0,                                        // tp_weaklistoffset
+    0,                                        // tp_iter
+    0,                                        // tp_iternext
+    0,                                        // tp_methods
+    0,                                        // tp_members
+    field::Getters,                           // tp_getset
+    0,                                        // tp_base
+    0,                                        // tp_dict
+    (descrgetfunc)field::DescrGet,            // tp_descr_get
+    (descrsetfunc)field::DescrSet,            // tp_descr_set
+    0,                                        // tp_dictoffset
+    0,                                        // tp_init
+    0,                                        // tp_alloc
+    0,                                        // tp_new
+};
+PyTypeObject* CFieldProperty_Type = &_CFieldProperty_Type;
+
+PyObject* NewFieldProperty(const FieldDescriptor* field_descriptor) {
+  // Create a new descriptor object
+  PyMessageFieldProperty* property =
+      PyObject_New(PyMessageFieldProperty, CFieldProperty_Type);
+  if (property == NULL) {
+    return NULL;
+  }
+  property->field_descriptor = field_descriptor;
+  return reinterpret_cast<PyObject*>(property);
+}
+
+}  // namespace python
+}  // namespace protobuf
+}  // namespace google
diff --git a/python/google/protobuf/pyext/field.h b/python/google/protobuf/pyext/field.h
new file mode 100755
index 0000000..7b4660c
--- /dev/null
+++ b/python/google/protobuf/pyext/field.h
@@ -0,0 +1,59 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_FIELD_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_FIELD_H__
+
+#include <Python.h>
+
+namespace google {
+namespace protobuf {
+
+class FieldDescriptor;
+
+namespace python {
+
+// A data descriptor that represents a field in a Message class.
+struct PyMessageFieldProperty {
+  PyObject_HEAD;
+
+  // This pointer is owned by the same pool as the Message class it belongs to.
+  const FieldDescriptor* field_descriptor;
+};
+
+extern PyTypeObject* CFieldProperty_Type;
+
+PyObject* NewFieldProperty(const FieldDescriptor* field_descriptor);
+
+}  // namespace python
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_PYTHON_CPP_FIELD_H__
diff --git a/python/google/protobuf/pyext/map_container.cc b/python/google/protobuf/pyext/map_container.cc
index 6d7ee28..77c6170 100644
--- a/python/google/protobuf/pyext/map_container.cc
+++ b/python/google/protobuf/pyext/map_container.cc
@@ -68,6 +68,8 @@
   static PyObject* MessageMapGetItem(PyObject* _self, PyObject* key);
   static int ScalarMapSetItem(PyObject* _self, PyObject* key, PyObject* v);
   static int MessageMapSetItem(PyObject* _self, PyObject* key, PyObject* v);
+  static PyObject* ScalarMapToStr(PyObject* _self);
+  static PyObject* MessageMapToStr(PyObject* _self);
 };
 
 struct MapIterator {
@@ -199,26 +201,26 @@
 // This is only used for ScalarMap, so we don't need to handle the
 // CPPTYPE_MESSAGE case.
 PyObject* MapValueRefToPython(const FieldDescriptor* field_descriptor,
-                              MapValueRef* value) {
+                              const MapValueRef& value) {
   switch (field_descriptor->cpp_type()) {
     case FieldDescriptor::CPPTYPE_INT32:
-      return PyInt_FromLong(value->GetInt32Value());
+      return PyInt_FromLong(value.GetInt32Value());
     case FieldDescriptor::CPPTYPE_INT64:
-      return PyLong_FromLongLong(value->GetInt64Value());
+      return PyLong_FromLongLong(value.GetInt64Value());
     case FieldDescriptor::CPPTYPE_UINT32:
-      return PyInt_FromSize_t(value->GetUInt32Value());
+      return PyInt_FromSize_t(value.GetUInt32Value());
     case FieldDescriptor::CPPTYPE_UINT64:
-      return PyLong_FromUnsignedLongLong(value->GetUInt64Value());
+      return PyLong_FromUnsignedLongLong(value.GetUInt64Value());
     case FieldDescriptor::CPPTYPE_FLOAT:
-      return PyFloat_FromDouble(value->GetFloatValue());
+      return PyFloat_FromDouble(value.GetFloatValue());
     case FieldDescriptor::CPPTYPE_DOUBLE:
-      return PyFloat_FromDouble(value->GetDoubleValue());
+      return PyFloat_FromDouble(value.GetDoubleValue());
     case FieldDescriptor::CPPTYPE_BOOL:
-      return PyBool_FromLong(value->GetBoolValue());
+      return PyBool_FromLong(value.GetBoolValue());
     case FieldDescriptor::CPPTYPE_STRING:
-      return ToStringObject(field_descriptor, value->GetStringValue());
+      return ToStringObject(field_descriptor, value.GetStringValue());
     case FieldDescriptor::CPPTYPE_ENUM:
-      return PyInt_FromLong(value->GetEnumValue());
+      return PyInt_FromLong(value.GetEnumValue());
     default:
       PyErr_Format(
           PyExc_SystemError, "Couldn't convert type %d to value",
@@ -472,7 +474,7 @@
     self->version++;
   }
 
-  return MapValueRefToPython(self->value_field_descriptor, &value);
+  return MapValueRefToPython(self->value_field_descriptor, value);
 }
 
 int MapReflectionFriend::ScalarMapSetItem(PyObject* _self, PyObject* key,
@@ -535,10 +537,47 @@
   }
 }
 
+PyObject* MapReflectionFriend::ScalarMapToStr(PyObject* _self) {
+  ScopedPyObjectPtr dict(PyDict_New());
+  if (dict == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr key;
+  ScopedPyObjectPtr value;
+
+  MapContainer* self = GetMap(_self);
+  Message* message = self->GetMutableMessage();
+  const Reflection* reflection = message->GetReflection();
+  for (google::protobuf::MapIterator it = reflection->MapBegin(
+           message, self->parent_field_descriptor);
+       it != reflection->MapEnd(message, self->parent_field_descriptor);
+       ++it) {
+    key.reset(MapKeyToPython(self->key_field_descriptor,
+                             it.GetKey()));
+    if (key == NULL) {
+      return NULL;
+    }
+    value.reset(MapValueRefToPython(self->value_field_descriptor,
+                                    it.GetValueRef()));
+    if (value == NULL) {
+      return NULL;
+    }
+    if (PyDict_SetItem(dict.get(), key.get(), value.get()) < 0) {
+      return NULL;
+    }
+  }
+  return PyObject_Repr(dict.get());
+}
+
 static void ScalarMapDealloc(PyObject* _self) {
   MapContainer* self = GetMap(_self);
   self->owner.reset();
-  Py_TYPE(_self)->tp_free(_self);
+  PyTypeObject *type = Py_TYPE(_self);
+  type->tp_free(_self);
+  if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+    // With Python3, the Map class is not static, and must be managed.
+    Py_DECREF(type);
+  }
 }
 
 static PyMethodDef ScalarMapMethods[] = {
@@ -570,6 +609,7 @@
       {Py_mp_ass_subscript, (void *)MapReflectionFriend::ScalarMapSetItem},
       {Py_tp_methods, (void *)ScalarMapMethods},
       {Py_tp_iter, (void *)MapReflectionFriend::GetIterator},
+      {Py_tp_repr, (void *)MapReflectionFriend::ScalarMapToStr},
       {0, 0},
   };
 
@@ -597,7 +637,7 @@
     0,                                   //  tp_getattr
     0,                                   //  tp_setattr
     0,                                   //  tp_compare
-    0,                                   //  tp_repr
+    MapReflectionFriend::ScalarMapToStr,  //  tp_repr
     0,                                   //  tp_as_number
     0,                                   //  tp_as_sequence
     &ScalarMapMappingMethods,            //  tp_as_mapping
@@ -634,7 +674,8 @@
   return reinterpret_cast<MessageMapContainer*>(obj);
 }
 
-static PyObject* GetCMessage(MessageMapContainer* self, Message* message) {
+static PyObject* GetCMessage(MessageMapContainer* self, Message* message,
+                             bool insert_message_dict) {
   // Get or create the CMessage object corresponding to this message.
   ScopedPyObjectPtr key(PyLong_FromVoidPtr(message));
   PyObject* ret = PyDict_GetItem(self->message_dict, key.get());
@@ -649,10 +690,11 @@
     cmsg->owner = self->owner;
     cmsg->message = message;
     cmsg->parent = self->parent;
-
-    if (PyDict_SetItem(self->message_dict, key.get(), ret) < 0) {
-      Py_DECREF(ret);
-      return NULL;
+    if (insert_message_dict) {
+      if (PyDict_SetItem(self->message_dict, key.get(), ret) < 0) {
+        Py_DECREF(ret);
+        return NULL;
+      }
     }
   } else {
     Py_INCREF(ret);
@@ -781,7 +823,41 @@
     self->version++;
   }
 
-  return GetCMessage(self, value.MutableMessageValue());
+  return GetCMessage(self, value.MutableMessageValue(), true);
+}
+
+PyObject* MapReflectionFriend::MessageMapToStr(PyObject* _self) {
+  ScopedPyObjectPtr dict(PyDict_New());
+  if (dict == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr key;
+  ScopedPyObjectPtr value;
+
+  MessageMapContainer* self = GetMessageMap(_self);
+  Message* message = self->GetMutableMessage();
+  const Reflection* reflection = message->GetReflection();
+  for (google::protobuf::MapIterator it = reflection->MapBegin(
+           message, self->parent_field_descriptor);
+       it != reflection->MapEnd(message, self->parent_field_descriptor);
+       ++it) {
+    key.reset(MapKeyToPython(self->key_field_descriptor,
+                             it.GetKey()));
+    if (key == NULL) {
+      return NULL;
+    }
+    // Do not insert the cmessage to self->message_dict because
+    // the returned CMessage will not escape this function.
+    value.reset(GetCMessage(
+        self, it.MutableValueRef()->MutableMessageValue(), false));
+    if (value == NULL) {
+      return NULL;
+    }
+    if (PyDict_SetItem(dict.get(), key.get(), value.get()) < 0) {
+      return NULL;
+    }
+  }
+  return PyObject_Repr(dict.get());
 }
 
 PyObject* MessageMapGet(PyObject* self, PyObject* args) {
@@ -813,7 +889,12 @@
   self->owner.reset();
   Py_DECREF(self->message_dict);
   Py_DECREF(self->message_class);
-  Py_TYPE(_self)->tp_free(_self);
+  PyTypeObject *type = Py_TYPE(_self);
+  type->tp_free(_self);
+  if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+    // With Python3, the Map class is not static, and must be managed.
+    Py_DECREF(type);
+  }
 }
 
 static PyMethodDef MessageMapMethods[] = {
@@ -847,6 +928,7 @@
       {Py_mp_ass_subscript, (void *)MapReflectionFriend::MessageMapSetItem},
       {Py_tp_methods, (void *)MessageMapMethods},
       {Py_tp_iter, (void *)MapReflectionFriend::GetIterator},
+      {Py_tp_repr, (void *)MapReflectionFriend::MessageMapToStr},
       {0, 0}
   };
 
@@ -874,7 +956,7 @@
     0,                                   //  tp_getattr
     0,                                   //  tp_setattr
     0,                                   //  tp_compare
-    0,                                   //  tp_repr
+    MapReflectionFriend::MessageMapToStr,  //  tp_repr
     0,                                   //  tp_as_number
     0,                                   //  tp_as_sequence
     &MessageMapMappingMethods,           //  tp_as_mapping
@@ -1027,17 +1109,15 @@
     return false;
   }
 
-  if (!PyObject_TypeCheck(mutable_mapping.get(), &PyType_Type)) {
+  Py_INCREF(mutable_mapping.get());
+#if PY_MAJOR_VERSION >= 3
+  ScopedPyObjectPtr bases(PyTuple_Pack(1, mutable_mapping.get()));
+  if (bases == NULL) {
     return false;
   }
 
-  Py_INCREF(mutable_mapping.get());
-#if PY_MAJOR_VERSION >= 3
-  PyObject* bases = PyTuple_New(1);
-  PyTuple_SET_ITEM(bases, 0, mutable_mapping.get());
-
   ScalarMapContainer_Type = reinterpret_cast<PyTypeObject*>(
-      PyType_FromSpecWithBases(&ScalarMapContainer_Type_spec, bases));
+      PyType_FromSpecWithBases(&ScalarMapContainer_Type_spec, bases.get()));
 #else
   _ScalarMapContainer_Type.tp_base =
       reinterpret_cast<PyTypeObject*>(mutable_mapping.get());
@@ -1055,7 +1135,7 @@
 
 #if PY_MAJOR_VERSION >= 3
   MessageMapContainer_Type = reinterpret_cast<PyTypeObject*>(
-      PyType_FromSpecWithBases(&MessageMapContainer_Type_spec, bases));
+      PyType_FromSpecWithBases(&MessageMapContainer_Type_spec, bases.get()));
 #else
   Py_INCREF(mutable_mapping.get());
   _MessageMapContainer_Type.tp_base =
diff --git a/python/google/protobuf/pyext/map_container.h b/python/google/protobuf/pyext/map_container.h
index 111fafb..7e77b02 100644
--- a/python/google/protobuf/pyext/map_container.h
+++ b/python/google/protobuf/pyext/map_container.h
@@ -120,6 +120,6 @@
 
 }  // namespace python
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_MAP_CONTAINER_H__
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index b298450..2205f12 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -45,12 +45,11 @@
 #ifndef Py_TYPE
 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
 #endif
-#include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
-#include <google/protobuf/util/message_differencer.h>
+#include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/message.h>
 #include <google/protobuf/text_format.h>
@@ -58,12 +57,16 @@
 #include <google/protobuf/pyext/descriptor.h>
 #include <google/protobuf/pyext/descriptor_pool.h>
 #include <google/protobuf/pyext/extension_dict.h>
-#include <google/protobuf/pyext/repeated_composite_container.h>
-#include <google/protobuf/pyext/repeated_scalar_container.h>
+#include <google/protobuf/pyext/field.h>
 #include <google/protobuf/pyext/map_container.h>
 #include <google/protobuf/pyext/message_factory.h>
+#include <google/protobuf/pyext/repeated_composite_container.h>
+#include <google/protobuf/pyext/repeated_scalar_container.h>
+#include <google/protobuf/pyext/unknown_fields.h>
 #include <google/protobuf/pyext/safe_numerics.h>
 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+#include <google/protobuf/util/message_differencer.h>
+#include <google/protobuf/stubs/strutil.h>
 
 #if PY_MAJOR_VERSION >= 3
   #define PyInt_AsLong PyLong_AsLong
@@ -72,16 +75,19 @@
   #define PyString_Check PyUnicode_Check
   #define PyString_FromString PyUnicode_FromString
   #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
+  #define PyString_FromFormat PyUnicode_FromFormat
   #if PY_VERSION_HEX < 0x03030000
     #error "Python 3.0 - 3.2 are not supported."
   #else
   #define PyString_AsString(ob) \
     (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AsString(ob))
-  #define PyString_AsStringAndSize(ob, charpp, sizep) \
-    (PyUnicode_Check(ob)? \
-       ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \
-       PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
-  #endif
+#define PyString_AsStringAndSize(ob, charpp, sizep)                           \
+  (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>(                     \
+                               PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \
+                              ? -1                                            \
+                              : 0)                                            \
+                       : PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
+#endif
 #endif
 
 namespace google {
@@ -99,44 +105,27 @@
 static int InsertEmptyWeakref(PyTypeObject* base);
 
 namespace {
-// Copied oveer from internal 'google/protobuf/stubs/strutil.h'.
-inline void UpperString(string * s) {
+// Copied over from internal 'google/protobuf/stubs/strutil.h'.
+inline void LowerString(string * s) {
   string::iterator end = s->end();
   for (string::iterator i = s->begin(); i != end; ++i) {
-    // toupper() changes based on locale.  We don't want this!
-    if ('a' <= *i && *i <= 'z') *i += 'A' - 'a';
+    // tolower() changes based on locale.  We don't want this!
+    if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A';
   }
 }
 }
 
-// Add the number of a field descriptor to the containing message class.
-// Equivalent to:
-//   _cls.<field>_FIELD_NUMBER = <number>
-static bool AddFieldNumberToClass(
-    PyObject* cls, const FieldDescriptor* field_descriptor) {
-  string constant_name = field_descriptor->name() + "_FIELD_NUMBER";
-  UpperString(&constant_name);
-  ScopedPyObjectPtr attr_name(PyString_FromStringAndSize(
-      constant_name.c_str(), constant_name.size()));
-  if (attr_name == NULL) {
-    return false;
-  }
-  ScopedPyObjectPtr number(PyInt_FromLong(field_descriptor->number()));
-  if (number == NULL) {
-    return false;
-  }
-  if (PyObject_SetAttr(cls, attr_name.get(), number.get()) == -1) {
-    return false;
-  }
-  return true;
-}
-
-
 // Finalize the creation of the Message class.
 static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) {
   // For each field set: cls.<field>_FIELD_NUMBER = <number>
   for (int i = 0; i < descriptor->field_count(); ++i) {
-    if (!AddFieldNumberToClass(cls, descriptor->field(i))) {
+    const FieldDescriptor* field_descriptor = descriptor->field(i);
+    ScopedPyObjectPtr property(NewFieldProperty(field_descriptor));
+    if (property == NULL) {
+      return -1;
+    }
+    if (PyObject_SetAttrString(cls, field_descriptor->name().c_str(),
+                               property.get()) < 0) {
       return -1;
     }
   }
@@ -193,11 +182,6 @@
             cls, field->name().c_str(), extension_field.get()) == -1) {
       return -1;
     }
-
-    // For each extension set cls.<extension name>_FIELD_NUMBER = <number>.
-    if (!AddFieldNumberToClass(cls, field)) {
-      return -1;
-    }
   }
 
   return 0;
@@ -265,10 +249,10 @@
   PyObject* well_known_class = PyDict_GetItemString(
       WKT_classes, message_descriptor->full_name().c_str());
   if (well_known_class == NULL) {
-    new_args.reset(Py_BuildValue("s(OO)O", name, &CMessage_Type,
+    new_args.reset(Py_BuildValue("s(OO)O", name, CMessage_Type,
                                  PythonMessage_class, dict));
   } else {
-    new_args.reset(Py_BuildValue("s(OOO)O", name, &CMessage_Type,
+    new_args.reset(Py_BuildValue("s(OOO)O", name, CMessage_Type,
                                  PythonMessage_class, well_known_class, dict));
   }
 
@@ -285,7 +269,7 @@
   // Insert the empty weakref into the base classes.
   if (InsertEmptyWeakref(
           reinterpret_cast<PyTypeObject*>(PythonMessage_class)) < 0 ||
-      InsertEmptyWeakref(&CMessage_Type) < 0) {
+      InsertEmptyWeakref(CMessage_Type) < 0) {
     return NULL;
   }
 
@@ -353,6 +337,13 @@
 // The _extensions_by_name dictionary is built on every access.
 // TODO(amauryfa): Migrate all users to pool.FindAllExtensions()
 static PyObject* GetExtensionsByName(CMessageClass *self, void *closure) {
+  if (self->message_descriptor == NULL) {
+    // This is the base Message object, simply raise AttributeError.
+    PyErr_SetString(PyExc_AttributeError,
+                    "Base Message class has no DESCRIPTOR");
+    return NULL;
+  }
+
   const PyDescriptorPool* pool = self->py_message_factory->pool;
 
   std::vector<const FieldDescriptor*> extensions;
@@ -376,6 +367,13 @@
 // The _extensions_by_number dictionary is built on every access.
 // TODO(amauryfa): Migrate all users to pool.FindExtensionByNumber()
 static PyObject* GetExtensionsByNumber(CMessageClass *self, void *closure) {
+  if (self->message_descriptor == NULL) {
+    // This is the base Message object, simply raise AttributeError.
+    PyErr_SetString(PyExc_AttributeError,
+                    "Base Message class has no DESCRIPTOR");
+    return NULL;
+  }
+
   const PyDescriptorPool* pool = self->py_message_factory->pool;
 
   std::vector<const FieldDescriptor*> extensions;
@@ -405,9 +403,51 @@
   {NULL}
 };
 
+// Compute some class attributes on the fly:
+// - All the _FIELD_NUMBER attributes, for all fields and nested extensions.
+// Returns a new reference, or NULL with an exception set.
+static PyObject* GetClassAttribute(CMessageClass *self, PyObject* name) {
+  char* attr;
+  Py_ssize_t attr_size;
+  static const char kSuffix[] = "_FIELD_NUMBER";
+  if (PyString_AsStringAndSize(name, &attr, &attr_size) >= 0 &&
+      strings::EndsWith(StringPiece(attr, attr_size), kSuffix)) {
+    string field_name(attr, attr_size - sizeof(kSuffix) + 1);
+    LowerString(&field_name);
+
+    // Try to find a field with the given name, without the suffix.
+    const FieldDescriptor* field =
+        self->message_descriptor->FindFieldByLowercaseName(field_name);
+    if (!field) {
+      // Search nested extensions as well.
+      field =
+          self->message_descriptor->FindExtensionByLowercaseName(field_name);
+    }
+    if (field) {
+      return PyInt_FromLong(field->number());
+    }
+  }
+  PyErr_SetObject(PyExc_AttributeError, name);
+  return NULL;
+}
+
+static PyObject* GetAttr(CMessageClass* self, PyObject* name) {
+  PyObject* result = CMessageClass_Type->tp_base->tp_getattro(
+      reinterpret_cast<PyObject*>(self), name);
+  if (result != NULL) {
+    return result;
+  }
+  if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+    return NULL;
+  }
+
+  PyErr_Clear();
+  return GetClassAttribute(self, name);
+}
+
 }  // namespace message_meta
 
-PyTypeObject CMessageClass_Type = {
+static PyTypeObject _CMessageClass_Type = {
   PyVarObject_HEAD_INIT(&PyType_Type, 0)
   FULL_MODULE_NAME ".MessageMeta",     // tp_name
   sizeof(CMessageClass),               // tp_basicsize
@@ -424,7 +464,7 @@
   0,                                   // tp_hash
   0,                                   // tp_call
   0,                                   // tp_str
-  0,                                   // tp_getattro
+  (getattrofunc)message_meta::GetAttr,  // tp_getattro
   0,                                   // tp_setattro
   0,                                   // tp_as_buffer
   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  // tp_flags
@@ -447,9 +487,10 @@
   0,                                   // tp_alloc
   message_meta::New,                   // tp_new
 };
+PyTypeObject* CMessageClass_Type = &_CMessageClass_Type;
 
 static CMessageClass* CheckMessageClass(PyTypeObject* cls) {
-  if (!PyObject_TypeCheck(cls, &CMessageClass_Type)) {
+  if (!PyObject_TypeCheck(cls, CMessageClass_Type)) {
     PyErr_Format(PyExc_TypeError, "Class %s is not a Message", cls->tp_name);
     return NULL;
   }
@@ -487,10 +528,20 @@
   }
 
   // Returns 0 on success, -1 on failure.
+  int VisitMapContainer(MapContainer* container) {
+    return 0;
+  }
+
+  // Returns 0 on success, -1 on failure.
   int VisitCMessage(CMessage* cmessage,
                     const FieldDescriptor* field_descriptor) {
     return 0;
   }
+
+  // Returns 0 on success, -1 on failure.
+  int VisitUnknownFieldSet(PyUnknownFields* unknown_field_set) {
+    return 0;
+  }
 };
 
 // Apply a function to a composite field.  Does nothing if child is of
@@ -538,34 +589,19 @@
 
   // Visit normal fields.
   if (self->composite_fields) {
-    // Never use self->message in this function, it may be already freed.
-    const Descriptor* message_descriptor =
-        GetMessageDescriptor(Py_TYPE(self));
-    while (PyDict_Next(self->composite_fields, &pos, &key, &field)) {
-      Py_ssize_t key_str_size;
-      char *key_str_data;
-      if (PyString_AsStringAndSize(key, &key_str_data, &key_str_size) != 0)
-        return -1;
-      const string key_str(key_str_data, key_str_size);
-      const FieldDescriptor* descriptor =
-        message_descriptor->FindFieldByName(key_str);
-      if (descriptor != NULL) {
-        if (VisitCompositeField(descriptor, field, visitor) == -1)
-          return -1;
-      }
+    for (CMessage::CompositeFieldsMap::iterator it =
+             self->composite_fields->begin();
+         it != self->composite_fields->end(); it++) {
+      const FieldDescriptor* descriptor = it->first;
+      PyObject* field = it->second;
+      if (VisitCompositeField(descriptor, field, visitor) == -1) return -1;
     }
   }
 
-  // Visit extension fields.
-  if (self->extensions != NULL) {
-    pos = 0;
-    while (PyDict_Next(self->extensions->values, &pos, &key, &field)) {
-      const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key);
-      if (descriptor == NULL)
-        return -1;
-      if (VisitCompositeField(descriptor, field, visitor) == -1)
-        return -1;
-    }
+  if (self->unknown_field_set) {
+    PyUnknownFields* unknown_field_set =
+      reinterpret_cast<PyUnknownFields*>(self->unknown_field_set);
+    visitor.VisitUnknownFieldSet(unknown_field_set);
   }
 
   return 0;
@@ -577,8 +613,12 @@
 PyObject* DecodeError_class;
 PyObject* PickleError_class;
 
-/* Is 64bit */
+// Format an error message for unexpected types.
+// Always return with an exception set.
 void FormatTypeError(PyObject* arg, char* expected_types) {
+  // This function is often called with an exception set.
+  // Clear it to call PyObject_Repr() in good conditions.
+  PyErr_Clear();
   PyObject* repr = PyObject_Repr(arg);
   if (repr) {
     PyErr_Format(PyExc_TypeError,
@@ -859,7 +899,7 @@
 namespace cmessage {
 
 PyMessageFactory* GetFactoryForMessage(CMessage* message) {
-  GOOGLE_DCHECK(PyObject_TypeCheck(message, &CMessage_Type));
+  GOOGLE_DCHECK(PyObject_TypeCheck(message, CMessage_Type));
   return reinterpret_cast<CMessageClass*>(Py_TYPE(message))->py_message_factory;
 }
 
@@ -883,22 +923,20 @@
     // Non-message fields don't need to be released.
     return 0;
   }
-  const char* field_name = existing_field->name().c_str();
-  PyObject* child_message = cmessage->composite_fields ?
-      PyDict_GetItemString(cmessage->composite_fields, field_name) : NULL;
-  if (child_message == NULL) {
-    // No python reference to this field so no need to release.
-    return 0;
+  if (cmessage->composite_fields) {
+    CMessage::CompositeFieldsMap::iterator iterator =
+        cmessage->composite_fields->find(existing_field);
+    if (iterator != cmessage->composite_fields->end()) {
+      if (InternalReleaseFieldByDescriptor(cmessage, existing_field,
+                                           iterator->second) < 0) {
+        return -1;
+      }
+      Py_DECREF(iterator->second);
+      cmessage->composite_fields->erase(iterator);
+    }
   }
-
-  if (InternalReleaseFieldByDescriptor(
-          cmessage, existing_field, child_message) < 0) {
-    return -1;
-  }
-  return PyDict_DelItemString(cmessage->composite_fields, field_name);
-#else
-  return 0;
 #endif
+  return 0;
 }
 
 // ---------------------------------------------------------------------
@@ -937,10 +975,49 @@
     return 0;
   }
 
+  int VisitUnknownFieldSet(PyUnknownFields* unknown_field_set) {
+    const Reflection* reflection = message_->GetReflection();
+    unknown_field_set->fields = &reflection->GetUnknownFields(*message_);
+    return 0;
+  }
+
  private:
   Message* message_;
 };
 
+// After a Merge, visit every sub-message that was read-only, and
+// eventually update their pointer if the Merge operation modified them.
+struct FixupMessageAfterMerge : public FixupMessageReference {
+  explicit FixupMessageAfterMerge(CMessage* parent) :
+      FixupMessageReference(parent->message),
+      parent_cmessage(parent), message(parent->message) {}
+
+  int VisitCMessage(CMessage* cmessage,
+                    const FieldDescriptor* field_descriptor) {
+    if (cmessage->read_only == false) {
+      return 0;
+    }
+    if (message->GetReflection()->HasField(*message, field_descriptor)) {
+      Message* mutable_message = GetMutableMessage(
+          parent_cmessage, field_descriptor);
+      if (mutable_message == NULL) {
+        return -1;
+      }
+      cmessage->message = mutable_message;
+      cmessage->read_only = false;
+      if (ForEachCompositeField(
+              cmessage, FixupMessageAfterMerge(cmessage)) == -1) {
+        return -1;
+      }
+    }
+    return 0;
+  }
+
+ private:
+  CMessage* parent_cmessage;
+  Message* message;
+};
+
 int AssureWritable(CMessage* self) {
   if (self == NULL || !self->read_only) {
     return 0;
@@ -974,10 +1051,8 @@
   // When a CMessage is made writable its Message pointer is updated
   // to point to a new mutable Message.  When that happens we need to
   // update any references to the old, read-only CMessage.  There are
-  // four places such references occur: RepeatedScalarContainer,
-  // RepeatedCompositeContainer, MapContainer, and ExtensionDict.
-  if (self->extensions != NULL)
-    self->extensions->message = self->message;
+  // three places such references occur: RepeatedScalarContainer,
+  // RepeatedCompositeContainer, and MapContainer.
   if (ForEachCompositeField(self, FixupMessageReference(self->message)) == -1)
     return -1;
 
@@ -986,27 +1061,6 @@
 
 // --- Globals:
 
-// Retrieve a C++ FieldDescriptor for a message attribute.
-// The C++ message must be valid.
-// TODO(amauryfa): This function should stay internal, because exception
-// handling is not consistent.
-static const FieldDescriptor* GetFieldDescriptor(
-    CMessage* self, PyObject* name) {
-  const Descriptor *message_descriptor = self->message->GetDescriptor();
-  char* field_name;
-  Py_ssize_t size;
-  if (PyString_AsStringAndSize(name, &field_name, &size) < 0) {
-    return NULL;
-  }
-  const FieldDescriptor *field_descriptor =
-      message_descriptor->FindFieldByName(string(field_name, size));
-  if (field_descriptor == NULL) {
-    // Note: No exception is set!
-    return NULL;
-  }
-  return field_descriptor;
-}
-
 // Retrieve a C++ FieldDescriptor for an extension handle.
 const FieldDescriptor* GetExtensionDescriptor(PyObject* extension) {
   ScopedPyObjectPtr cdescriptor;
@@ -1038,7 +1092,7 @@
     const EnumValueDescriptor* enum_value_descriptor =
         enum_descriptor->FindValueByName(string(enum_label, size));
     if (enum_value_descriptor == NULL) {
-      PyErr_SetString(PyExc_ValueError, "unknown enum label");
+      PyErr_Format(PyExc_ValueError, "unknown enum label \"%s\"", enum_label);
       return NULL;
     }
     return PyInt_FromLong(enum_value_descriptor->number());
@@ -1164,19 +1218,24 @@
       PyErr_SetString(PyExc_ValueError, "Field name must be a string");
       return -1;
     }
-    const FieldDescriptor* descriptor = GetFieldDescriptor(self, name);
-    if (descriptor == NULL) {
+    ScopedPyObjectPtr property(
+        PyObject_GetAttr(reinterpret_cast<PyObject*>(Py_TYPE(self)), name));
+    if (property == NULL ||
+        !PyObject_TypeCheck(property.get(), CFieldProperty_Type)) {
       PyErr_Format(PyExc_ValueError, "Protocol message %s has no \"%s\" field.",
                    self->message->GetDescriptor()->name().c_str(),
                    PyString_AsString(name));
       return -1;
     }
+    const FieldDescriptor* descriptor =
+        reinterpret_cast<PyMessageFieldProperty*>(property.get())
+            ->field_descriptor;
     if (value == Py_None) {
       // field=None is the same as no field at all.
       continue;
     }
     if (descriptor->is_map()) {
-      ScopedPyObjectPtr map(GetAttr(reinterpret_cast<PyObject*>(self), name));
+      ScopedPyObjectPtr map(GetFieldValue(self, descriptor));
       const FieldDescriptor* value_descriptor =
           descriptor->message_type()->FindFieldByName("value");
       if (value_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
@@ -1204,8 +1263,7 @@
         }
       }
     } else if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
-      ScopedPyObjectPtr container(
-          GetAttr(reinterpret_cast<PyObject*>(self), name));
+      ScopedPyObjectPtr container(GetFieldValue(self, descriptor));
       if (container == NULL) {
         return -1;
       }
@@ -1272,8 +1330,7 @@
         }
       }
     } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
-      ScopedPyObjectPtr message(
-          GetAttr(reinterpret_cast<PyObject*>(self), name));
+      ScopedPyObjectPtr message(GetFieldValue(self, descriptor));
       if (message == NULL) {
         return -1;
       }
@@ -1297,9 +1354,9 @@
         if (new_val == NULL) {
           return -1;
         }
+        value = new_val.get();
       }
-      if (SetAttr(reinterpret_cast<PyObject*>(self), name,
-                  (new_val.get() == NULL) ? value : new_val.get()) < 0) {
+      if (SetFieldValue(self, descriptor, value) < 0) {
         return -1;
       }
     }
@@ -1322,10 +1379,11 @@
   self->parent = NULL;
   self->parent_field_descriptor = NULL;
   self->read_only = false;
-  self->extensions = NULL;
 
   self->composite_fields = NULL;
 
+  self->unknown_field_set = NULL;
+
   return self;
 }
 
@@ -1408,12 +1466,20 @@
   }
   // Null out all weak references from children to this message.
   GOOGLE_CHECK_EQ(0, ForEachCompositeField(self, ClearWeakReferences()));
-  if (self->extensions) {
-    self->extensions->parent = NULL;
-  }
 
-  Py_CLEAR(self->extensions);
-  Py_CLEAR(self->composite_fields);
+  if (self->composite_fields) {
+    for (CMessage::CompositeFieldsMap::iterator it =
+             self->composite_fields->begin();
+         it != self->composite_fields->end(); it++) {
+      Py_DECREF(it->second);
+    }
+    delete self->composite_fields;
+  }
+  if (self->unknown_field_set) {
+    unknown_fields::Clear(
+        reinterpret_cast<PyUnknownFields*>(self->unknown_field_set));
+    Py_CLEAR(self->unknown_field_set);
+  }
   self->owner.~ThreadUnsafeSharedPtr<Message>();
   Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
 }
@@ -1564,13 +1630,16 @@
   if (descriptor == NULL) {
     return NULL;
   }
-  if (self->extensions != NULL) {
-    PyObject* value = PyDict_GetItem(self->extensions->values, extension);
-    if (value != NULL) {
-      if (InternalReleaseFieldByDescriptor(self, descriptor, value) < 0) {
+  if (self->composite_fields != NULL) {
+    CMessage::CompositeFieldsMap::iterator iterator =
+        self->composite_fields->find(descriptor);
+    if (iterator != self->composite_fields->end()) {
+      if (InternalReleaseFieldByDescriptor(self, descriptor,
+                                           iterator->second) < 0) {
         return NULL;
       }
-      PyDict_DelItem(self->extensions->values, extension);
+      Py_DECREF(iterator->second);
+      self->composite_fields->erase(iterator);
     }
   }
   return ClearFieldByDescriptor(self, descriptor);
@@ -1770,14 +1839,16 @@
     arg = arg_in_oneof.get();
   }
 
-  // Release the field if it exists in the dict of composite fields.
   if (self->composite_fields) {
-    PyObject* value = PyDict_GetItem(self->composite_fields, arg);
-    if (value != NULL) {
-      if (InternalReleaseFieldByDescriptor(self, field_descriptor, value) < 0) {
+    CMessage::CompositeFieldsMap::iterator iterator =
+        self->composite_fields->find(field_descriptor);
+    if (iterator != self->composite_fields->end()) {
+      if (InternalReleaseFieldByDescriptor(self, field_descriptor,
+                                           iterator->second) < 0) {
         return NULL;
       }
-      PyDict_DelItem(self->composite_fields, arg);
+      Py_DECREF(iterator->second);
+      self->composite_fields->erase(iterator);
     }
   }
   return ClearFieldByDescriptor(self, field_descriptor);
@@ -1787,9 +1858,18 @@
   AssureWritable(self);
   if (ForEachCompositeField(self, ReleaseChild(self)) == -1)
     return NULL;
-  Py_CLEAR(self->extensions);
   if (self->composite_fields) {
-    PyDict_Clear(self->composite_fields);
+    for (CMessage::CompositeFieldsMap::iterator it =
+             self->composite_fields->begin();
+         it != self->composite_fields->end(); it++) {
+      Py_DECREF(it->second);
+    }
+    self->composite_fields->clear();
+  }
+  if (self->unknown_field_set) {
+    unknown_fields::Clear(
+        reinterpret_cast<PyUnknownFields*>(self->unknown_field_set));
+    Py_CLEAR(self->unknown_field_set);
   }
   self->message->Clear();
   Py_RETURN_NONE;
@@ -1946,7 +2026,7 @@
 
 PyObject* MergeFrom(CMessage* self, PyObject* arg) {
   CMessage* other_message;
-  if (!PyObject_TypeCheck(arg, &CMessage_Type)) {
+  if (!PyObject_TypeCheck(arg, CMessage_Type)) {
     PyErr_Format(PyExc_TypeError,
                  "Parameter to MergeFrom() must be instance of same class: "
                  "expected %s got %s.",
@@ -1967,18 +2047,19 @@
   }
   AssureWritable(self);
 
-  // TODO(tibell): Message::MergeFrom might turn some child Messages
-  // into mutable messages, invalidating the message field in the
-  // corresponding CMessages.  We should run a FixupMessageReferences
-  // pass here.
-
   self->message->MergeFrom(*other_message->message);
+  // Child message might be lazily created before MergeFrom. Make sure they
+  // are mutable at this point if child messages are really created.
+  if (ForEachCompositeField(self, FixupMessageAfterMerge(self)) == -1) {
+    return NULL;
+  }
+
   Py_RETURN_NONE;
 }
 
 static PyObject* CopyFrom(CMessage* self, PyObject* arg) {
   CMessage* other_message;
-  if (!PyObject_TypeCheck(arg, &CMessage_Type)) {
+  if (!PyObject_TypeCheck(arg, CMessage_Type)) {
     PyErr_Format(PyExc_TypeError,
                  "Parameter to CopyFrom() must be instance of same class: "
                  "expected %s got %s.",
@@ -2050,6 +2131,7 @@
   }
 
   AssureWritable(self);
+
   io::CodedInputStream input(
       reinterpret_cast<const uint8*>(data), data_length);
   if (allow_oversize_protos) {
@@ -2058,6 +2140,12 @@
   PyMessageFactory* factory = GetFactoryForMessage(self);
   input.SetExtensionRegistry(factory->pool->pool, factory->message_factory);
   bool success = self->message->MergePartialFromCodedStream(&input);
+  // Child message might be lazily created before MergeFrom. Make sure they
+  // are mutable at this point if child messages are really created.
+  if (ForEachCompositeField(self, FixupMessageAfterMerge(self)) == -1) {
+    return NULL;
+  }
+
   if (success) {
     if (!input.ConsumedEntireMessage()) {
       // TODO(jieluo): Raise error and return NULL instead.
@@ -2088,7 +2176,7 @@
   if (descriptor == NULL) {
     return NULL;
   }
-  if (!PyObject_TypeCheck(cls, &CMessageClass_Type)) {
+  if (!PyObject_TypeCheck(cls, CMessageClass_Type)) {
     PyErr_Format(PyExc_TypeError, "Expected a message class, got %s",
                  cls->ob_type->tp_name);
     return NULL;
@@ -2192,23 +2280,15 @@
       PyTuple_SET_ITEM(t.get(), 1, extension);
     } else {
       // Normal field
-      const string& field_name = fields[i]->name();
-      ScopedPyObjectPtr py_field_name(PyString_FromStringAndSize(
-          field_name.c_str(), field_name.length()));
-      if (py_field_name == NULL) {
-        PyErr_SetString(PyExc_ValueError, "bad string");
-        return NULL;
-      }
       ScopedPyObjectPtr field_descriptor(
           PyFieldDescriptor_FromDescriptor(fields[i]));
       if (field_descriptor == NULL) {
         return NULL;
       }
 
-      PyObject* field_value =
-          GetAttr(reinterpret_cast<PyObject*>(self), py_field_name.get());
+      PyObject* field_value = GetFieldValue(self, fields[i]);
       if (field_value == NULL) {
-        PyErr_SetObject(PyExc_ValueError, py_field_name.get());
+        PyErr_SetString(PyExc_ValueError, fields[i]->name().c_str());
         return NULL;
       }
       PyTuple_SET_ITEM(t.get(), 0, field_descriptor.release());
@@ -2261,7 +2341,7 @@
   }
   bool equals = true;
   // If other is not a message, it cannot be equal.
-  if (!PyObject_TypeCheck(other, &CMessage_Type)) {
+  if (!PyObject_TypeCheck(other, CMessage_Type)) {
     equals = false;
   }
   const google::protobuf::Message* other_message =
@@ -2277,6 +2357,7 @@
           *reinterpret_cast<CMessage*>(other)->message)) {
     equals = false;
   }
+
   if (equals ^ (opid == Py_EQ)) {
     Py_RETURN_FALSE;
   } else {
@@ -2498,7 +2579,7 @@
   if (clone == NULL) {
     return NULL;
   }
-  if (!PyObject_TypeCheck(clone, &CMessage_Type)) {
+  if (!PyObject_TypeCheck(clone, CMessage_Type)) {
     Py_DECREF(clone);
     return NULL;
   }
@@ -2592,26 +2673,29 @@
 }
 
 static PyObject* GetExtensionDict(CMessage* self, void *closure) {
-  if (self->extensions)  {
-    Py_INCREF(self->extensions);
-    return reinterpret_cast<PyObject*>(self->extensions);
-  }
-
   // If there are extension_ranges, the message is "extendable". Allocate a
   // dictionary to store the extension fields.
   const Descriptor* descriptor = GetMessageDescriptor(Py_TYPE(self));
-  if (descriptor->extension_range_count() > 0) {
-    ExtensionDict* extension_dict = extension_dict::NewExtensionDict(self);
-    if (extension_dict == NULL) {
-      return NULL;
-    }
-    self->extensions = extension_dict;
-    Py_INCREF(self->extensions);
-    return reinterpret_cast<PyObject*>(self->extensions);
+  if (!descriptor->extension_range_count()) {
+    PyErr_SetNone(PyExc_AttributeError);
+    return NULL;
   }
+  if (!self->composite_fields) {
+    self->composite_fields = new CMessage::CompositeFieldsMap();
+  }
+  if (!self->composite_fields) {
+    return NULL;
+  }
+  ExtensionDict* extension_dict = extension_dict::NewExtensionDict(self);
+  return reinterpret_cast<PyObject*>(extension_dict);
+}
 
-  PyErr_SetNone(PyExc_AttributeError);
-  return NULL;
+static PyObject* UnknownFieldSet(CMessage* self) {
+  if (self->unknown_field_set == NULL) {
+    self->unknown_field_set = unknown_fields::NewPyUnknownFields(self);
+  }
+  Py_INCREF(self->unknown_field_set);
+  return self->unknown_field_set;
 }
 
 static PyObject* GetExtensionsByName(CMessage *self, void *closure) {
@@ -2682,6 +2766,8 @@
     "Serializes the message to a string, only for initialized messages." },
   { "SetInParent", (PyCFunction)SetInParent, METH_NOARGS,
     "Sets the has bit of the given field in its parent message." },
+  { "UnknownFields", (PyCFunction)UnknownFieldSet, METH_NOARGS,
+    "Parse unknown field set"},
   { "WhichOneof", (PyCFunction)WhichOneof, METH_O,
     "Returns the name of the field set inside a oneof, "
     "or None if no field is set." },
@@ -2693,30 +2779,53 @@
   { NULL, NULL}
 };
 
-static bool SetCompositeField(
-    CMessage* self, PyObject* name, PyObject* value) {
+static bool SetCompositeField(CMessage* self, const FieldDescriptor* field,
+                              PyObject* value) {
   if (self->composite_fields == NULL) {
-    self->composite_fields = PyDict_New();
-    if (self->composite_fields == NULL) {
-      return false;
-    }
+    self->composite_fields = new CMessage::CompositeFieldsMap();
   }
-  return PyDict_SetItem(self->composite_fields, name, value) == 0;
+  Py_INCREF(value);
+  Py_XDECREF((*self->composite_fields)[field]);
+  (*self->composite_fields)[field] = value;
+  return true;
 }
 
 PyObject* GetAttr(PyObject* pself, PyObject* name) {
   CMessage* self = reinterpret_cast<CMessage*>(pself);
-  PyObject* value = self->composite_fields ?
-      PyDict_GetItem(self->composite_fields, name) : NULL;
-  if (value != NULL) {
-    Py_INCREF(value);
-    return value;
+  PyObject* result = PyObject_GenericGetAttr(
+      reinterpret_cast<PyObject*>(self), name);
+  if (result != NULL) {
+    return result;
+  }
+  if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+    return NULL;
   }
 
-  const FieldDescriptor* field_descriptor = GetFieldDescriptor(self, name);
-  if (field_descriptor == NULL) {
-    return CMessage_Type.tp_base->tp_getattro(
-        reinterpret_cast<PyObject*>(self), name);
+  PyErr_Clear();
+  return message_meta::GetClassAttribute(
+      CheckMessageClass(Py_TYPE(self)), name);
+}
+
+PyObject* GetFieldValue(CMessage* self,
+                        const FieldDescriptor* field_descriptor) {
+  if (self->composite_fields) {
+    CMessage::CompositeFieldsMap::iterator it =
+        self->composite_fields->find(field_descriptor);
+    if (it != self->composite_fields->end()) {
+      PyObject* value = it->second;
+      Py_INCREF(value);
+      return value;
+    }
+  }
+
+  const Descriptor* message_descriptor =
+      (reinterpret_cast<CMessageClass*>(Py_TYPE(self)))->message_descriptor;
+  if (self->message->GetDescriptor() != field_descriptor->containing_type()) {
+    PyErr_Format(PyExc_TypeError,
+                 "descriptor to field '%s' doesn't apply to '%s' object",
+                 field_descriptor->full_name().c_str(),
+                 Py_TYPE(self)->tp_name);
+    return NULL;
   }
 
   if (field_descriptor->is_map()) {
@@ -2737,7 +2846,7 @@
     if (py_container == NULL) {
       return NULL;
     }
-    if (!SetCompositeField(self, name, py_container)) {
+    if (!SetCompositeField(self, field_descriptor, py_container)) {
       Py_DECREF(py_container);
       return NULL;
     }
@@ -2761,7 +2870,7 @@
     if (py_container == NULL) {
       return NULL;
     }
-    if (!SetCompositeField(self, name, py_container)) {
+    if (!SetCompositeField(self, field_descriptor, py_container)) {
       Py_DECREF(py_container);
       return NULL;
     }
@@ -2773,7 +2882,7 @@
     if (sub_message == NULL) {
       return NULL;
     }
-    if (!SetCompositeField(self, name, sub_message)) {
+    if (!SetCompositeField(self, field_descriptor, sub_message)) {
       Py_DECREF(sub_message);
       return NULL;
     }
@@ -2783,44 +2892,35 @@
   return InternalGetScalar(self->message, field_descriptor);
 }
 
-int SetAttr(PyObject* pself, PyObject* name, PyObject* value) {
-  CMessage* self = reinterpret_cast<CMessage*>(pself);
-  if (self->composite_fields && PyDict_Contains(self->composite_fields, name)) {
-    PyErr_SetString(PyExc_TypeError, "Can't set composite field");
+int SetFieldValue(CMessage* self, const FieldDescriptor* field_descriptor,
+                  PyObject* value) {
+  if (self->message->GetDescriptor() != field_descriptor->containing_type()) {
+    PyErr_Format(PyExc_TypeError,
+                 "descriptor to field '%s' doesn't apply to '%s' object",
+                 field_descriptor->full_name().c_str(),
+                 Py_TYPE(self)->tp_name);
     return -1;
-  }
-
-  const FieldDescriptor* field_descriptor = GetFieldDescriptor(self, name);
-  if (field_descriptor != NULL) {
+  } else if (field_descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
+    PyErr_Format(PyExc_AttributeError,
+                 "Assignment not allowed to repeated "
+                 "field \"%s\" in protocol message object.",
+                 field_descriptor->name().c_str());
+    return -1;
+  } else if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+    PyErr_Format(PyExc_AttributeError,
+                 "Assignment not allowed to "
+                 "field \"%s\" in protocol message object.",
+                 field_descriptor->name().c_str());
+    return -1;
+  } else {
     AssureWritable(self);
-    if (field_descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
-      PyErr_Format(PyExc_AttributeError, "Assignment not allowed to repeated "
-                   "field \"%s\" in protocol message object.",
-                   field_descriptor->name().c_str());
-      return -1;
-    } else {
-      if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
-        PyErr_Format(PyExc_AttributeError, "Assignment not allowed to "
-                     "field \"%s\" in protocol message object.",
-                     field_descriptor->name().c_str());
-        return -1;
-      } else {
-        return InternalSetScalar(self, field_descriptor, value);
-      }
-    }
+    return InternalSetScalar(self, field_descriptor, value);
   }
-
-  PyErr_Format(PyExc_AttributeError,
-               "Assignment not allowed "
-               "(no field \"%s\" in protocol message object).",
-               PyString_AsString(name));
-  return -1;
 }
-
 }  // namespace cmessage
 
-PyTypeObject CMessage_Type = {
-  PyVarObject_HEAD_INIT(&CMessageClass_Type, 0)
+static CMessageClass _CMessage_Type = { { {
+  PyVarObject_HEAD_INIT(&_CMessageClass_Type, 0)
   FULL_MODULE_NAME ".CMessage",        // tp_name
   sizeof(CMessage),                    // tp_basicsize
   0,                                   //  tp_itemsize
@@ -2837,9 +2937,10 @@
   0,                                   //  tp_call
   (reprfunc)cmessage::ToStr,           //  tp_str
   cmessage::GetAttr,                   //  tp_getattro
-  cmessage::SetAttr,                   //  tp_setattro
+  0,                                   //  tp_setattro
   0,                                   //  tp_as_buffer
-  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  //  tp_flags
+  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
+      | Py_TPFLAGS_HAVE_VERSION_TAG,   //  tp_flags
   "A ProtocolMessage",                 //  tp_doc
   0,                                   //  tp_traverse
   0,                                   //  tp_clear
@@ -2858,7 +2959,8 @@
   (initproc)cmessage::Init,            //  tp_init
   0,                                   //  tp_alloc
   cmessage::New,                       //  tp_new
-};
+} } };
+PyTypeObject* CMessage_Type = &_CMessage_Type.super.ht_type;
 
 // --- Exposing the C proto living inside Python proto to C code:
 
@@ -2884,7 +2986,7 @@
 }
 
 const Message* PyMessage_GetMessagePointer(PyObject* msg) {
-  if (!PyObject_TypeCheck(msg, &CMessage_Type)) {
+  if (!PyObject_TypeCheck(msg, CMessage_Type)) {
     PyErr_SetString(PyExc_TypeError, "Not a Message instance");
     return NULL;
   }
@@ -2893,15 +2995,14 @@
 }
 
 Message* PyMessage_GetMutableMessagePointer(PyObject* msg) {
-  if (!PyObject_TypeCheck(msg, &CMessage_Type)) {
+  if (!PyObject_TypeCheck(msg, CMessage_Type)) {
     PyErr_SetString(PyExc_TypeError, "Not a Message instance");
     return NULL;
   }
 
+
   CMessage* cmsg = reinterpret_cast<CMessage*>(msg);
-  if ((cmsg->composite_fields && PyDict_Size(cmsg->composite_fields) != 0) ||
-      (cmsg->extensions != NULL &&
-       PyDict_Size(cmsg->extensions->values) != 0)) {
+  if (cmsg->composite_fields && !cmsg->composite_fields->empty()) {
     // There is currently no way of accurately syncing arbitrary changes to
     // the underlying C++ message back to the CMessage (e.g. removed repeated
     // composite containers). We only allow direct mutation of the underlying
@@ -2945,22 +3046,29 @@
   // Initialize constants defined in this file.
   InitGlobals();
 
-  CMessageClass_Type.tp_base = &PyType_Type;
-  if (PyType_Ready(&CMessageClass_Type) < 0) {
+  CMessageClass_Type->tp_base = &PyType_Type;
+  if (PyType_Ready(CMessageClass_Type) < 0) {
     return false;
   }
   PyModule_AddObject(m, "MessageMeta",
-                     reinterpret_cast<PyObject*>(&CMessageClass_Type));
+                     reinterpret_cast<PyObject*>(CMessageClass_Type));
 
-  if (PyType_Ready(&CMessage_Type) < 0) {
+  if (PyType_Ready(CMessage_Type) < 0) {
+    return false;
+  }
+  if (PyType_Ready(CFieldProperty_Type) < 0) {
     return false;
   }
 
   // DESCRIPTOR is set on each protocol buffer message class elsewhere, but set
   // it here as well to document that subclasses need to set it.
-  PyDict_SetItem(CMessage_Type.tp_dict, kDESCRIPTOR, Py_None);
+  PyDict_SetItem(CMessage_Type->tp_dict, kDESCRIPTOR, Py_None);
+  // Invalidate any cached data for the CMessage type.
+  // This call is necessary to correctly support Py_TPFLAGS_HAVE_VERSION_TAG,
+  // after we have modified CMessage_Type.tp_dict.
+  PyType_Modified(CMessage_Type);
 
-  PyModule_AddObject(m, "Message", reinterpret_cast<PyObject*>(&CMessage_Type));
+  PyModule_AddObject(m, "Message", reinterpret_cast<PyObject*>(CMessage_Type));
 
   // Initialize Repeated container types.
   {
@@ -3003,6 +3111,22 @@
     }
   }
 
+  if (PyType_Ready(&PyUnknownFields_Type) < 0) {
+    return false;
+  }
+
+  PyModule_AddObject(m, "UnknownFieldSet",
+                     reinterpret_cast<PyObject*>(
+                         &PyUnknownFields_Type));
+
+  if (PyType_Ready(&PyUnknownFieldRef_Type) < 0) {
+    return false;
+  }
+
+  PyModule_AddObject(m, "UnknownField",
+                     reinterpret_cast<PyObject*>(
+                         &PyUnknownFieldRef_Type));
+
   // Initialize Map container types.
   if (!InitMapContainers()) {
     return false;
diff --git a/python/google/protobuf/pyext/message.h b/python/google/protobuf/pyext/message.h
index d754e62..cbd422b 100644
--- a/python/google/protobuf/pyext/message.h
+++ b/python/google/protobuf/pyext/message.h
@@ -38,6 +38,7 @@
 
 #include <memory>
 #include <string>
+#include <unordered_map>
 
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/pyext/thread_unsafe_shared_ptr.h>
@@ -96,26 +97,25 @@
   // made writable, at which point this field is set to false.
   bool read_only;
 
-  // A reference to a Python dictionary containing CMessage,
+  // A mapping indexed by field, containing CMessage,
   // RepeatedCompositeContainer, and RepeatedScalarContainer
   // objects. Used as a cache to make sure we don't have to make a
   // Python wrapper for the C++ Message objects on every access, or
   // deal with the synchronization nightmare that could create.
-  PyObject* composite_fields;
+  // Also cache extension fields.
+  // The FieldDescriptor is owned by the message's pool; PyObject references
+  // are owned.
+  typedef std::unordered_map<const FieldDescriptor*, PyObject*>
+      CompositeFieldsMap;
+  CompositeFieldsMap* composite_fields;
 
-  // A reference to the dictionary containing the message's extensions.
-  // Similar to composite_fields, acting as a cache, but also contains the
-  // required extension dict logic.
-  ExtensionDict* extensions;
+  // A reference to PyUnknownFields.
+  PyObject* unknown_field_set;
 
   // Implements the "weakref" protocol for this object.
   PyObject* weakreflist;
 } CMessage;
 
-extern PyTypeObject CMessageClass_Type;
-extern PyTypeObject CMessage_Type;
-
-
 // The (meta) type of all Messages classes.
 // It allows us to cache some C++ pointers in the class object itself, they are
 // faster to extract than from the type's dictionary.
@@ -142,6 +142,8 @@
   }
 };
 
+extern PyTypeObject* CMessageClass_Type;
+extern PyTypeObject* CMessage_Type;
 
 namespace cmessage {
 
@@ -235,15 +237,13 @@
 // has been registered with the same field number on this class.
 PyObject* RegisterExtension(PyObject* cls, PyObject* extension_handle);
 
-// Retrieves an attribute named 'name' from 'self', which is interpreted as a
-// CMessage. Returns the attribute value on success, or null on failure.
-//
-// Returns a new reference.
-PyObject* GetAttr(PyObject* self, PyObject* name);
-
-// Set the value of the attribute named 'name', for 'self', which is interpreted
-// as a CMessage, to the value 'value'. Returns -1 on failure.
-int SetAttr(PyObject* self, PyObject* name, PyObject* value);
+// Get a field from a message.
+PyObject* GetFieldValue(CMessage* self,
+                        const FieldDescriptor* field_descriptor);
+// Sets the value of a scalar field in a message.
+// On error, return -1 with an extension set.
+int SetFieldValue(CMessage* self, const FieldDescriptor* field_descriptor,
+                  PyObject* value);
 
 PyObject* FindInitializationErrors(CMessage* self);
 
@@ -357,6 +357,6 @@
 
 }  // namespace python
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__
diff --git a/python/google/protobuf/pyext/message_factory.cc b/python/google/protobuf/pyext/message_factory.cc
index bacc76a..efaa261 100644
--- a/python/google/protobuf/pyext/message_factory.cc
+++ b/python/google/protobuf/pyext/message_factory.cc
@@ -28,6 +28,8 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+#include <unordered_map>
+
 #include <Python.h>
 
 #include <google/protobuf/dynamic_message.h>
@@ -137,7 +139,7 @@
   // This is the same implementation as MessageFactory.GetPrototype().
 
   // Do not create a MessageClass that already exists.
-  hash_map<const Descriptor*, CMessageClass*>::iterator it =
+  std::unordered_map<const Descriptor*, CMessageClass*>::iterator it =
       self->classes_by_descriptor->find(descriptor);
   if (it != self->classes_by_descriptor->end()) {
     Py_INCREF(it->second);
@@ -158,7 +160,7 @@
     return NULL;
   }
   ScopedPyObjectPtr message_class(PyObject_CallObject(
-      reinterpret_cast<PyObject*>(&CMessageClass_Type), args.get()));
+      reinterpret_cast<PyObject*>(CMessageClass_Type), args.get()));
   if (message_class == NULL) {
     return NULL;
   }
diff --git a/python/google/protobuf/pyext/message_factory.h b/python/google/protobuf/pyext/message_factory.h
index 36092f7..06444b0 100644
--- a/python/google/protobuf/pyext/message_factory.h
+++ b/python/google/protobuf/pyext/message_factory.h
@@ -33,7 +33,7 @@
 
 #include <Python.h>
 
-#include <google/protobuf/stubs/hash.h>
+#include <unordered_map>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/pyext/descriptor_pool.h>
 
@@ -66,7 +66,8 @@
   //
   // Descriptor pointers stored here are owned by the DescriptorPool above.
   // Python references to classes are owned by this PyDescriptorPool.
-  typedef hash_map<const Descriptor*, CMessageClass*> ClassesByMessageMap;
+  typedef std::unordered_map<const Descriptor*, CMessageClass*>
+      ClassesByMessageMap;
   ClassesByMessageMap* classes_by_descriptor;
 };
 
@@ -98,6 +99,6 @@
 
 }  // namespace python
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_FACTORY_H__
diff --git a/python/google/protobuf/pyext/message_module.cc b/python/google/protobuf/pyext/message_module.cc
index 8c93386..8d465eb 100644
--- a/python/google/protobuf/pyext/message_module.cc
+++ b/python/google/protobuf/pyext/message_module.cc
@@ -39,39 +39,16 @@
 
 // C++ API.  Clients get at this via proto_api.h
 struct ApiImplementation : google::protobuf::python::PyProto_API {
-  const google::protobuf::Message*
-      GetMessagePointer(PyObject* msg) const override {
+  const google::protobuf::Message* GetMessagePointer(PyObject* msg) const override {
     return google::protobuf::python::PyMessage_GetMessagePointer(msg);
   }
-  google::protobuf::Message*
-      GetMutableMessagePointer(PyObject* msg) const override {
+  google::protobuf::Message* GetMutableMessagePointer(PyObject* msg) const override {
     return google::protobuf::python::PyMessage_GetMutableMessagePointer(msg);
   }
 };
 
 }  // namespace
 
-static PyObject* GetPythonProto3PreserveUnknownsDefault(
-    PyObject* /*m*/, PyObject* /*args*/) {
-  if (google::protobuf::internal::GetProto3PreserveUnknownsDefault()) {
-    Py_RETURN_TRUE;
-  } else {
-    Py_RETURN_FALSE;
-  }
-}
-
-static PyObject* SetPythonProto3PreserveUnknownsDefault(
-    PyObject* /*m*/, PyObject* arg) {
-  if (!arg || !PyBool_Check(arg)) {
-    PyErr_SetString(
-        PyExc_TypeError,
-        "Argument to SetPythonProto3PreserveUnknownsDefault must be boolean");
-    return NULL;
-  }
-  google::protobuf::internal::SetProto3PreserveUnknownsDefault(PyObject_IsTrue(arg));
-  Py_RETURN_NONE;
-}
-
 static const char module_docstring[] =
 "python-proto2 is a module that can be used to enhance proto2 Python API\n"
 "performance.\n"
@@ -84,13 +61,6 @@
     (PyCFunction)google::protobuf::python::cmessage::SetAllowOversizeProtos,
     METH_O, "Enable/disable oversize proto parsing."},
   // DO NOT USE: For migration and testing only.
-  {"GetPythonProto3PreserveUnknownsDefault",
-    (PyCFunction)GetPythonProto3PreserveUnknownsDefault,
-    METH_NOARGS, "Get Proto3 preserve unknowns default."},
-  // DO NOT USE: For migration and testing only.
-  {"SetPythonProto3PreserveUnknownsDefault",
-    (PyCFunction)SetPythonProto3PreserveUnknownsDefault,
-    METH_O, "Enable/disable proto3 unknowns preservation."},
   { NULL, NULL}
 };
 
@@ -113,35 +83,32 @@
 #define INITFUNC_ERRORVAL
 #endif
 
-extern "C" {
-  PyMODINIT_FUNC INITFUNC(void) {
-    PyObject* m;
+PyMODINIT_FUNC INITFUNC() {
+  PyObject* m;
 #if PY_MAJOR_VERSION >= 3
-    m = PyModule_Create(&_module);
+  m = PyModule_Create(&_module);
 #else
-    m = Py_InitModule3("_message", ModuleMethods,
-                       module_docstring);
+  m = Py_InitModule3("_message", ModuleMethods, module_docstring);
 #endif
-    if (m == NULL) {
-      return INITFUNC_ERRORVAL;
-    }
+  if (m == NULL) {
+    return INITFUNC_ERRORVAL;
+  }
 
-    if (!google::protobuf::python::InitProto2MessageModule(m)) {
-      Py_DECREF(m);
-      return INITFUNC_ERRORVAL;
-    }
-    
-    // Adds the C++ API
-    if (PyObject* api =
-            PyCapsule_New(new ApiImplementation(),
-                          google::protobuf::python::PyProtoAPICapsuleName(), NULL)) {
-      PyModule_AddObject(m, "proto_API", api);
-    } else {
-      return INITFUNC_ERRORVAL;
-    }
+  if (!google::protobuf::python::InitProto2MessageModule(m)) {
+    Py_DECREF(m);
+    return INITFUNC_ERRORVAL;
+  }
+
+  // Adds the C++ API
+  if (PyObject* api =
+          PyCapsule_New(new ApiImplementation(),
+                        google::protobuf::python::PyProtoAPICapsuleName(), NULL)) {
+    PyModule_AddObject(m, "proto_API", api);
+  } else {
+    return INITFUNC_ERRORVAL;
+  }
 
 #if PY_MAJOR_VERSION >= 3
-    return m;
+  return m;
 #endif
-  }
 }
diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc
index 5874d5d..d6bc3d7 100644
--- a/python/google/protobuf/pyext/repeated_composite_container.cc
+++ b/python/google/protobuf/pyext/repeated_composite_container.cc
@@ -61,9 +61,9 @@
 
 // TODO(tibell): We might also want to check:
 //   GOOGLE_CHECK_NOTNULL((self)->owner.get());
-#define GOOGLE_CHECK_ATTACHED(self)             \
-  do {                                   \
-    GOOGLE_CHECK_NOTNULL((self)->message);      \
+#define GOOGLE_CHECK_ATTACHED(self)                           \
+  do {                                                 \
+    GOOGLE_CHECK_NOTNULL((self)->message);                 \
     GOOGLE_CHECK_NOTNULL((self)->parent_field_descriptor); \
   } while (0);
 
@@ -152,6 +152,8 @@
   cmsg->message = sub_message;
   cmsg->parent = self->parent;
   if (cmessage::InitAttributes(cmsg, args, kwargs) < 0) {
+    message->GetReflection()->RemoveLast(
+        message, self->parent_field_descriptor);
     Py_DECREF(cmsg);
     return NULL;
   }
@@ -210,7 +212,7 @@
   }
   ScopedPyObjectPtr next;
   while ((next.reset(PyIter_Next(iter.get()))) != NULL) {
-    if (!PyObject_TypeCheck(next.get(), &CMessage_Type)) {
+    if (!PyObject_TypeCheck(next.get(), CMessage_Type)) {
       PyErr_SetString(PyExc_TypeError, "Not a cmessage");
       return NULL;
     }
@@ -487,9 +489,9 @@
 void ReleaseLastTo(CMessage* parent,
                    const FieldDescriptor* field,
                    CMessage* target) {
-  GOOGLE_CHECK_NOTNULL(parent);
-  GOOGLE_CHECK_NOTNULL(field);
-  GOOGLE_CHECK_NOTNULL(target);
+  GOOGLE_CHECK(parent != nullptr);
+  GOOGLE_CHECK(field != nullptr);
+  GOOGLE_CHECK(target != nullptr);
 
   CMessage::OwnerRef released_message(
       parent->message->GetReflection()->ReleaseLast(parent->message, field));
diff --git a/python/google/protobuf/pyext/repeated_composite_container.h b/python/google/protobuf/pyext/repeated_composite_container.h
index e5e946a..464699a 100644
--- a/python/google/protobuf/pyext/repeated_composite_container.h
+++ b/python/google/protobuf/pyext/repeated_composite_container.h
@@ -161,6 +161,6 @@
 }  // namespace repeated_composite_container
 }  // namespace python
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__
diff --git a/python/google/protobuf/pyext/repeated_scalar_container.cc b/python/google/protobuf/pyext/repeated_scalar_container.cc
index de3b6e1..cdb6426 100644
--- a/python/google/protobuf/pyext/repeated_scalar_container.cc
+++ b/python/google/protobuf/pyext/repeated_scalar_container.cc
@@ -663,6 +663,10 @@
   return PyObject_Repr(list.get());
 }
 
+static PyObject* MergeFrom(PyObject* pself, PyObject* arg) {
+  return Extend(reinterpret_cast<RepeatedScalarContainer*>(pself), arg);
+}
+
 // The private constructor of RepeatedScalarContainer objects.
 PyObject *NewContainer(
     CMessage* parent, const FieldDescriptor* parent_field_descriptor) {
@@ -776,6 +780,8 @@
     "Removes an object from the repeated container." },
   { "sort", (PyCFunction)Sort, METH_VARARGS | METH_KEYWORDS,
     "Sorts the repeated container."},
+  { "MergeFrom", (PyCFunction)MergeFrom, METH_O,
+    "Merges a repeated container into the current container." },
   { NULL, NULL }
 };
 
diff --git a/python/google/protobuf/pyext/repeated_scalar_container.h b/python/google/protobuf/pyext/repeated_scalar_container.h
index 559dec9..4dcecba 100644
--- a/python/google/protobuf/pyext/repeated_scalar_container.h
+++ b/python/google/protobuf/pyext/repeated_scalar_container.h
@@ -104,6 +104,6 @@
 }  // namespace repeated_scalar_container
 }  // namespace python
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_SCALAR_CONTAINER_H__
diff --git a/python/google/protobuf/pyext/safe_numerics.h b/python/google/protobuf/pyext/safe_numerics.h
index 639ba2c..60112cf 100644
--- a/python/google/protobuf/pyext/safe_numerics.h
+++ b/python/google/protobuf/pyext/safe_numerics.h
@@ -159,6 +159,6 @@
 
 }  // namespace python
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_SAFE_NUMERICS_H__
diff --git a/python/google/protobuf/pyext/thread_unsafe_shared_ptr.h b/python/google/protobuf/pyext/thread_unsafe_shared_ptr.h
index ad804b5..79fa9e3 100644
--- a/python/google/protobuf/pyext/thread_unsafe_shared_ptr.h
+++ b/python/google/protobuf/pyext/thread_unsafe_shared_ptr.h
@@ -99,6 +99,6 @@
 
 }  // namespace python
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_THREAD_UNSAFE_SHARED_PTR_H__
diff --git a/python/google/protobuf/pyext/unknown_fields.cc b/python/google/protobuf/pyext/unknown_fields.cc
new file mode 100755
index 0000000..760452f
--- /dev/null
+++ b/python/google/protobuf/pyext/unknown_fields.cc
@@ -0,0 +1,355 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/pyext/unknown_fields.h>
+
+#include <Python.h>
+#include <set>
+#include <memory>
+
+#include <google/protobuf/message.h>
+#include <google/protobuf/pyext/message.h>
+#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/wire_format_lite.h>
+
+#if PY_MAJOR_VERSION >= 3
+  #define PyInt_FromLong PyLong_FromLong
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+namespace unknown_fields {
+
+static Py_ssize_t Len(PyObject* pself) {
+  PyUnknownFields* self =
+      reinterpret_cast<PyUnknownFields*>(pself);
+  if (self->fields == NULL) {
+    PyErr_Format(PyExc_ValueError,
+                 "UnknownFields does not exist. "
+                 "The parent message might be cleared.");
+    return -1;
+  }
+  return self->fields->field_count();
+}
+
+void Clear(PyUnknownFields* self) {
+  for (std::set<PyUnknownFields*>::iterator it =
+           self->sub_unknown_fields.begin();
+       it != self->sub_unknown_fields.end(); it++) {
+    Clear(*it);
+  }
+  self->fields = NULL;
+  self->sub_unknown_fields.clear();
+}
+
+PyObject* NewPyUnknownFieldRef(PyUnknownFields* parent,
+                               Py_ssize_t index);
+
+static PyObject* Item(PyObject* pself, Py_ssize_t index) {
+  PyUnknownFields* self =
+      reinterpret_cast<PyUnknownFields*>(pself);
+  if (self->fields == NULL) {
+    PyErr_Format(PyExc_ValueError,
+                 "UnknownFields does not exist. "
+                 "The parent message might be cleared.");
+    return NULL;
+  }
+  Py_ssize_t total_size = self->fields->field_count();
+  if (index < 0) {
+    index = total_size + index;
+  }
+  if (index < 0 || index >= total_size) {
+    PyErr_Format(PyExc_IndexError,
+                 "index (%zd) out of range",
+                 index);
+    return NULL;
+  }
+
+  return unknown_fields::NewPyUnknownFieldRef(self, index);
+}
+
+PyObject* NewPyUnknownFields(CMessage* c_message) {
+  PyUnknownFields* self = reinterpret_cast<PyUnknownFields*>(
+      PyType_GenericAlloc(&PyUnknownFields_Type, 0));
+  if (self == NULL) {
+    return NULL;
+  }
+  // Call "placement new" to initialize PyUnknownFields.
+  new (self) PyUnknownFields;
+
+  Py_INCREF(c_message);
+  self->parent = reinterpret_cast<PyObject*>(c_message);
+  Message* message = c_message->message;
+  const Reflection* reflection = message->GetReflection();
+  self->fields = &reflection->GetUnknownFields(*message);
+
+  return reinterpret_cast<PyObject*>(self);
+}
+
+PyObject* NewPyUnknownFieldRef(PyUnknownFields* parent,
+                               Py_ssize_t index) {
+  PyUnknownFieldRef* self = reinterpret_cast<PyUnknownFieldRef*>(
+      PyType_GenericAlloc(&PyUnknownFieldRef_Type, 0));
+  if (self == NULL) {
+    return NULL;
+  }
+
+  Py_INCREF(parent);
+  self->parent = parent;
+  self->index = index;
+
+  return reinterpret_cast<PyObject*>(self);
+}
+
+static void Dealloc(PyObject* pself) {
+  PyUnknownFields* self =
+      reinterpret_cast<PyUnknownFields*>(pself);
+  if (PyObject_TypeCheck(self->parent, &PyUnknownFields_Type)) {
+    reinterpret_cast<PyUnknownFields*>(
+        self->parent)->sub_unknown_fields.erase(self);
+  }
+  Py_CLEAR(self->parent);
+  self->~PyUnknownFields();
+}
+
+static PySequenceMethods SqMethods = {
+  Len,        /* sq_length */
+  0,          /* sq_concat */
+  0,          /* sq_repeat */
+  Item,       /* sq_item */
+  0,          /* sq_slice */
+  0,          /* sq_ass_item */
+};
+
+}  // namespace unknown_fields
+
+PyTypeObject PyUnknownFields_Type = {
+  PyVarObject_HEAD_INIT(&PyType_Type, 0)
+  FULL_MODULE_NAME ".PyUnknownFields",  // tp_name
+  sizeof(PyUnknownFields),             // tp_basicsize
+  0,                                   //  tp_itemsize
+  unknown_fields::Dealloc,             //  tp_dealloc
+  0,                                   //  tp_print
+  0,                                   //  tp_getattr
+  0,                                   //  tp_setattr
+  0,                                   //  tp_compare
+  0,                                   //  tp_repr
+  0,                                   //  tp_as_number
+  &unknown_fields::SqMethods,          //  tp_as_sequence
+  0,                                   //  tp_as_mapping
+  PyObject_HashNotImplemented,         //  tp_hash
+  0,                                   //  tp_call
+  0,                                   //  tp_str
+  0,                                   //  tp_getattro
+  0,                                   //  tp_setattro
+  0,                                   //  tp_as_buffer
+  Py_TPFLAGS_DEFAULT,                  //  tp_flags
+  "unknown field set",                 //  tp_doc
+  0,                                   //  tp_traverse
+  0,                                   //  tp_clear
+  0,                                   //  tp_richcompare
+  0,                                   //  tp_weaklistoffset
+  0,                                   //  tp_iter
+  0,                                   //  tp_iternext
+  0,                                   //  tp_methods
+  0,                                   //  tp_members
+  0,                                   //  tp_getset
+  0,                                   //  tp_base
+  0,                                   //  tp_dict
+  0,                                   //  tp_descr_get
+  0,                                   //  tp_descr_set
+  0,                                   //  tp_dictoffset
+  0,                                   //  tp_init
+};
+
+namespace unknown_field {
+static PyObject* PyUnknownFields_FromUnknownFieldSet(
+    PyUnknownFields* parent, const UnknownFieldSet& fields) {
+  PyUnknownFields* self = reinterpret_cast<PyUnknownFields*>(
+      PyType_GenericAlloc(&PyUnknownFields_Type, 0));
+  if (self == NULL) {
+    return NULL;
+  }
+  // Call "placement new" to initialize PyUnknownFields.
+  new (self) PyUnknownFields;
+
+  Py_INCREF(parent);
+  self->parent = reinterpret_cast<PyObject*>(parent);
+  self->fields = &fields;
+  parent->sub_unknown_fields.emplace(self);
+
+  return reinterpret_cast<PyObject*>(self);
+}
+
+const UnknownField* GetUnknownField(PyUnknownFieldRef* self) {
+  const UnknownFieldSet* fields = self->parent->fields;
+  if (fields == NULL) {
+    PyErr_Format(PyExc_ValueError,
+                 "UnknownField does not exist. "
+                 "The parent message might be cleared.");
+    return NULL;
+  }
+  ssize_t total_size = fields->field_count();
+  if (self->index >= total_size) {
+    PyErr_Format(PyExc_ValueError,
+                 "UnknownField does not exist. "
+                 "The parent message might be cleared.");
+    return NULL;
+  }
+  return &fields->field(self->index);
+}
+
+static PyObject* GetFieldNumber(PyUnknownFieldRef* self, void *closure) {
+  const UnknownField* unknown_field = GetUnknownField(self);
+  if (unknown_field == NULL) {
+    return NULL;
+  }
+  return PyInt_FromLong(unknown_field->number());
+}
+
+using internal::WireFormatLite;
+static PyObject* GetWireType(PyUnknownFieldRef* self, void *closure) {
+  const UnknownField* unknown_field = GetUnknownField(self);
+  if (unknown_field == NULL) {
+    return NULL;
+  }
+
+  // Assign a default value to suppress may-unintialized warnings (errors
+  // when built in some places).
+  WireFormatLite::WireType wire_type = WireFormatLite::WIRETYPE_VARINT;
+  switch (unknown_field->type()) {
+    case UnknownField::TYPE_VARINT:
+      wire_type = WireFormatLite::WIRETYPE_VARINT;
+      break;
+    case UnknownField::TYPE_FIXED32:
+      wire_type = WireFormatLite::WIRETYPE_FIXED32;
+      break;
+    case UnknownField::TYPE_FIXED64:
+      wire_type = WireFormatLite::WIRETYPE_FIXED64;
+      break;
+    case UnknownField::TYPE_LENGTH_DELIMITED:
+      wire_type = WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
+      break;
+    case UnknownField::TYPE_GROUP:
+      wire_type = WireFormatLite::WIRETYPE_START_GROUP;
+      break;
+  }
+  return PyInt_FromLong(wire_type);
+}
+
+static PyObject* GetData(PyUnknownFieldRef* self, void *closure) {
+  const UnknownField* field = GetUnknownField(self);
+  if (field == NULL) {
+    return NULL;
+  }
+  PyObject* data = NULL;
+  switch (field->type()) {
+    case UnknownField::TYPE_VARINT:
+      data = PyInt_FromLong(field->varint());
+      break;
+    case UnknownField::TYPE_FIXED32:
+      data = PyInt_FromLong(field->fixed32());
+      break;
+    case UnknownField::TYPE_FIXED64:
+      data = PyInt_FromLong(field->fixed64());
+      break;
+    case UnknownField::TYPE_LENGTH_DELIMITED:
+      data = PyBytes_FromStringAndSize(field->length_delimited().data(),
+                                       field->GetLengthDelimitedSize());
+      break;
+    case UnknownField::TYPE_GROUP:
+      data = PyUnknownFields_FromUnknownFieldSet(
+          self->parent, field->group());
+      break;
+  }
+  return data;
+}
+
+static void Dealloc(PyObject* pself) {
+  PyUnknownFieldRef* self =
+      reinterpret_cast<PyUnknownFieldRef*>(pself);
+  Py_CLEAR(self->parent);
+}
+
+static PyGetSetDef Getters[] = {
+  {"field_number", (getter)GetFieldNumber, NULL},
+  {"wire_type", (getter)GetWireType, NULL},
+  {"data", (getter)GetData, NULL},
+  {NULL}
+};
+
+}  // namespace unknown_field
+
+PyTypeObject PyUnknownFieldRef_Type = {
+  PyVarObject_HEAD_INIT(&PyType_Type, 0)
+  FULL_MODULE_NAME ".PyUnknownFieldRef",  // tp_name
+  sizeof(PyUnknownFieldRef),           //  tp_basicsize
+  0,                                   //  tp_itemsize
+  unknown_field::Dealloc,              //  tp_dealloc
+  0,                                   //  tp_print
+  0,                                   //  tp_getattr
+  0,                                   //  tp_setattr
+  0,                                   //  tp_compare
+  0,                                   //  tp_repr
+  0,                                   //  tp_as_number
+  0,                                   //  tp_as_sequence
+  0,                                   //  tp_as_mapping
+  PyObject_HashNotImplemented,         //  tp_hash
+  0,                                   //  tp_call
+  0,                                   //  tp_str
+  0,                                   //  tp_getattro
+  0,                                   //  tp_setattro
+  0,                                   //  tp_as_buffer
+  Py_TPFLAGS_DEFAULT,                  //  tp_flags
+  "unknown field",                     //  tp_doc
+  0,                                   //  tp_traverse
+  0,                                   //  tp_clear
+  0,                                   //  tp_richcompare
+  0,                                   //  tp_weaklistoffset
+  0,                                   //  tp_iter
+  0,                                   //  tp_iternext
+  0,                                   //  tp_methods
+  0,                                   //  tp_members
+  unknown_field::Getters,              //  tp_getset
+  0,                                   //  tp_base
+  0,                                   //  tp_dict
+  0,                                   //  tp_descr_get
+  0,                                   //  tp_descr_set
+  0,                                   //  tp_dictoffset
+  0,                                   //  tp_init
+};
+
+
+}  // namespace python
+}  // namespace protobuf
+}  // namespace google
diff --git a/python/google/protobuf/pyext/unknown_fields.h b/python/google/protobuf/pyext/unknown_fields.h
new file mode 100755
index 0000000..94d55e1
--- /dev/null
+++ b/python/google/protobuf/pyext/unknown_fields.h
@@ -0,0 +1,90 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_UNKNOWN_FIELDS_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_UNKNOWN_FIELDS_H__
+
+#include <Python.h>
+
+#include <memory>
+#include <set>
+
+#include <google/protobuf/pyext/message.h>
+
+namespace google {
+namespace protobuf {
+
+class UnknownField;
+class UnknownFieldSet;
+
+namespace python {
+struct CMessage;
+
+typedef struct PyUnknownFields {
+  PyObject_HEAD;
+  // Strong pointer to the parent CMessage or PyUnknownFields.
+  // The top PyUnknownFields holds a reference to its parent CMessage
+  // object before release.
+  // Sub PyUnknownFields holds reference to parent PyUnknownFields.
+  PyObject* parent;
+
+  // Pointer to the C++ UnknownFieldSet.
+  // PyUnknownFields does not own this pointer.
+  const UnknownFieldSet* fields;
+
+  // Weak references to child unknown fields.
+  std::set<PyUnknownFields*> sub_unknown_fields;
+} PyUnknownFields;
+
+typedef struct PyUnknownFieldRef {
+  PyObject_HEAD;
+  // Every Python PyUnknownFieldRef holds a reference to its parent
+  // PyUnknownFields in order to keep it alive.
+  PyUnknownFields* parent;
+
+  // The UnknownField index in UnknownFields.
+  Py_ssize_t index;
+} UknownFieldRef;
+
+extern PyTypeObject PyUnknownFields_Type;
+extern PyTypeObject PyUnknownFieldRef_Type;
+
+namespace unknown_fields {
+
+// Builds an PyUnknownFields for a specific message.
+PyObject* NewPyUnknownFields(CMessage *parent);
+void Clear(PyUnknownFields* self);
+
+}  // namespace unknown_fields
+}  // namespace python
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_PYTHON_CPP_UNKNOWN_FIELDS_H__
diff --git a/python/google/protobuf/python_protobuf.h b/python/google/protobuf/python_protobuf.h
index beb6e46..8db1ffb 100644
--- a/python/google/protobuf/python_protobuf.h
+++ b/python/google/protobuf/python_protobuf.h
@@ -52,6 +52,6 @@
 
 }  // namespace python
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py
index f4ce8ca..81e1885 100755
--- a/python/google/protobuf/reflection.py
+++ b/python/google/protobuf/reflection.py
@@ -48,25 +48,23 @@
 __author__ = 'robinson@google.com (Will Robinson)'
 
 
-from google.protobuf.internal import api_implementation
-from google.protobuf import message
-
-
-if api_implementation.Type() == 'cpp':
-  from google.protobuf.pyext import cpp_message as message_impl
-else:
-  from google.protobuf.internal import python_message as message_impl
+from google.protobuf import message_factory
+from google.protobuf import symbol_database
 
 # The type of all Message classes.
 # Part of the public interface, but normally only used by message factories.
-GeneratedProtocolMessageType = message_impl.GeneratedProtocolMessageType
+GeneratedProtocolMessageType = message_factory._GENERATED_PROTOCOL_MESSAGE_TYPE
 
 MESSAGE_CLASS_CACHE = {}
 
 
+# Deprecated. Please NEVER use reflection.ParseMessage().
 def ParseMessage(descriptor, byte_str):
   """Generate a new Message instance from this Descriptor and a byte string.
 
+  DEPRECATED: ParseMessage is deprecated because it is using MakeClass().
+  Please use MessageFactory.GetPrototype() instead.
+
   Args:
     descriptor: Protobuf Descriptor object
     byte_str: Serialized protocol buffer byte string
@@ -80,42 +78,18 @@
   return new_msg
 
 
+# Deprecated. Please NEVER use reflection.MakeClass().
 def MakeClass(descriptor):
   """Construct a class object for a protobuf described by descriptor.
 
-  Composite descriptors are handled by defining the new class as a member of the
-  parent class, recursing as deep as necessary.
-  This is the dynamic equivalent to:
-
-  class Parent(message.Message):
-    __metaclass__ = GeneratedProtocolMessageType
-    DESCRIPTOR = descriptor
-    class Child(message.Message):
-      __metaclass__ = GeneratedProtocolMessageType
-      DESCRIPTOR = descriptor.nested_types[0]
-
-  Sample usage:
-    file_descriptor = descriptor_pb2.FileDescriptorProto()
-    file_descriptor.ParseFromString(proto2_string)
-    msg_descriptor = descriptor.MakeDescriptor(file_descriptor.message_type[0])
-    msg_class = reflection.MakeClass(msg_descriptor)
-    msg = msg_class()
+  DEPRECATED: use MessageFactory.GetPrototype() instead.
 
   Args:
     descriptor: A descriptor.Descriptor object describing the protobuf.
   Returns:
     The Message class object described by the descriptor.
   """
-  if descriptor in MESSAGE_CLASS_CACHE:
-    return MESSAGE_CLASS_CACHE[descriptor]
-
-  attributes = {}
-  for name, nested_type in descriptor.nested_types_by_name.items():
-    attributes[name] = MakeClass(nested_type)
-
-  attributes[GeneratedProtocolMessageType._DESCRIPTOR_KEY] = descriptor
-
-  result = GeneratedProtocolMessageType(
-      str(descriptor.name), (message.Message,), attributes)
-  MESSAGE_CLASS_CACHE[descriptor] = result
-  return result
+  # Original implementation leads to duplicate message classes, which won't play
+  # well with extensions. Message factory info is also missing.
+  # Redirect to message_factory.
+  return symbol_database.Default().GetPrototype(descriptor)
diff --git a/python/google/protobuf/text_encoding.py b/python/google/protobuf/text_encoding.py
index 9899563..3989876 100644
--- a/python/google/protobuf/text_encoding.py
+++ b/python/google/protobuf/text_encoding.py
@@ -33,59 +33,70 @@
 
 import six
 
-# Lookup table for utf8
-_cescape_utf8_to_str = [chr(i) for i in range(0, 256)]
-_cescape_utf8_to_str[9] = r'\t'  # optional escape
-_cescape_utf8_to_str[10] = r'\n'  # optional escape
-_cescape_utf8_to_str[13] = r'\r'  # optional escape
-_cescape_utf8_to_str[39] = r"\'"  # optional escape
+_cescape_chr_to_symbol_map = {}
+_cescape_chr_to_symbol_map[9] = r'\t'  # optional escape
+_cescape_chr_to_symbol_map[10] = r'\n'  # optional escape
+_cescape_chr_to_symbol_map[13] = r'\r'  # optional escape
+_cescape_chr_to_symbol_map[34] = r'\"'  # necessary escape
+_cescape_chr_to_symbol_map[39] = r"\'"  # optional escape
+_cescape_chr_to_symbol_map[92] = r'\\'  # necessary escape
 
-_cescape_utf8_to_str[34] = r'\"'  # necessary escape
-_cescape_utf8_to_str[92] = r'\\'  # necessary escape
+# Lookup table for unicode
+_cescape_unicode_to_str = [chr(i) for i in range(0, 256)]
+for byte, string in _cescape_chr_to_symbol_map.items():
+  _cescape_unicode_to_str[byte] = string
 
 # Lookup table for non-utf8, with necessary escapes at (o >= 127 or o < 32)
 _cescape_byte_to_str = ([r'\%03o' % i for i in range(0, 32)] +
                         [chr(i) for i in range(32, 127)] +
                         [r'\%03o' % i for i in range(127, 256)])
-_cescape_byte_to_str[9] = r'\t'  # optional escape
-_cescape_byte_to_str[10] = r'\n'  # optional escape
-_cescape_byte_to_str[13] = r'\r'  # optional escape
-_cescape_byte_to_str[39] = r"\'"  # optional escape
-
-_cescape_byte_to_str[34] = r'\"'  # necessary escape
-_cescape_byte_to_str[92] = r'\\'  # necessary escape
+for byte, string in _cescape_chr_to_symbol_map.items():
+  _cescape_byte_to_str[byte] = string
+del byte, string
 
 
 def CEscape(text, as_utf8):
-  """Escape a bytes string for use in an ascii protocol buffer.
-
-  text.encode('string_escape') does not seem to satisfy our needs as it
-  encodes unprintable characters using two-digit hex escapes whereas our
-  C++ unescaping function allows hex escapes to be any length.  So,
-  "\0011".encode('string_escape') ends up being "\\x011", which will be
-  decoded in C++ as a single-character string with char code 0x11.
+  # type: (...) -> str
+  """Escape a bytes string for use in an text protocol buffer.
 
   Args:
-    text: A byte string to be escaped
-    as_utf8: Specifies if result should be returned in UTF-8 encoding
+    text: A byte string to be escaped.
+    as_utf8: Specifies if result may contain non-ASCII characters.
+        In Python 3 this allows unescaped non-ASCII Unicode characters.
+        In Python 2 the return value will be valid UTF-8 rather than only ASCII.
   Returns:
-    Escaped string
+    Escaped string (str).
   """
-  # PY3 hack: make Ord work for str and bytes:
-  # //platforms/networking/data uses unicode here, hence basestring.
-  Ord = ord if isinstance(text, six.string_types) else lambda x: x
+  # Python's text.encode() 'string_escape' or 'unicode_escape' codecs do not
+  # satisfy our needs; they encodes unprintable characters using two-digit hex
+  # escapes whereas our C++ unescaping function allows hex escapes to be any
+  # length.  So, "\0011".encode('string_escape') ends up being "\\x011", which
+  # will be decoded in C++ as a single-character string with char code 0x11.
+  if six.PY3:
+    text_is_unicode = isinstance(text, str)
+    if as_utf8 and text_is_unicode:
+      # We're already unicode, no processing beyond control char escapes.
+      return text.translate(_cescape_chr_to_symbol_map)
+    ord_ = ord if text_is_unicode else lambda x: x  # bytes iterate as ints.
+  else:
+    ord_ = ord  # PY2
   if as_utf8:
-    return ''.join(_cescape_utf8_to_str[Ord(c)] for c in text)
-  return ''.join(_cescape_byte_to_str[Ord(c)] for c in text)
+    return ''.join(_cescape_unicode_to_str[ord_(c)] for c in text)
+  return ''.join(_cescape_byte_to_str[ord_(c)] for c in text)
 
 
 _CUNESCAPE_HEX = re.compile(r'(\\+)x([0-9a-fA-F])(?![0-9a-fA-F])')
-_cescape_highbit_to_str = ([chr(i) for i in range(0, 127)] +
-                           [r'\%03o' % i for i in range(127, 256)])
 
 
 def CUnescape(text):
-  """Unescape a text string with C-style escape sequences to UTF-8 bytes."""
+  # type: (str) -> bytes
+  """Unescape a text string with C-style escape sequences to UTF-8 bytes.
+
+  Args:
+    text: The data to parse in a str.
+  Returns:
+    A byte string.
+  """
 
   def ReplaceHex(m):
     # Only replace the match if the number of leading back slashes is odd. i.e.
@@ -98,10 +109,9 @@
   # allow single-digit hex escapes (like '\xf').
   result = _CUNESCAPE_HEX.sub(ReplaceHex, text)
 
-  if str is bytes:  # PY2
+  if six.PY2:
     return result.decode('string_escape')
-  result = ''.join(_cescape_highbit_to_str[ord(c)] for c in result)
-  return (result.encode('ascii')  # Make it bytes to allow decode.
+  return (result.encode('utf-8')  # PY3: Make it bytes to allow decode.
           .decode('unicode_escape')
           # Make it bytes again to return the proper type.
           .encode('raw_unicode_escape'))
diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py
index 2cbd21b..5dd4183 100755
--- a/python/google/protobuf/text_format.py
+++ b/python/google/protobuf/text_format.py
@@ -55,15 +55,15 @@
 from google.protobuf import descriptor
 from google.protobuf import text_encoding
 
-__all__ = ['MessageToString', 'PrintMessage', 'PrintField', 'PrintFieldValue',
-           'Merge']
+__all__ = ['MessageToString', 'Parse', 'PrintMessage', 'PrintField',
+           'PrintFieldValue', 'Merge', 'MessageToBytes']
 
 _INTEGER_CHECKERS = (type_checkers.Uint32ValueChecker(),
                      type_checkers.Int32ValueChecker(),
                      type_checkers.Uint64ValueChecker(),
                      type_checkers.Int64ValueChecker())
-_FLOAT_INFINITY = re.compile('-?inf(?:inity)?f?', re.IGNORECASE)
-_FLOAT_NAN = re.compile('nanf?', re.IGNORECASE)
+_FLOAT_INFINITY = re.compile('-?inf(?:inity)?f?$', re.IGNORECASE)
+_FLOAT_NAN = re.compile('nanf?$', re.IGNORECASE)
 _FLOAT_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_FLOAT,
                           descriptor.FieldDescriptor.CPPTYPE_DOUBLE])
 _QUOTES = frozenset(("'", '"'))
@@ -121,6 +121,7 @@
 def MessageToString(message,
                     as_utf8=False,
                     as_one_line=False,
+                    use_short_repeated_primitives=False,
                     pointy_brackets=False,
                     use_index_order=False,
                     float_format=None,
@@ -128,6 +129,7 @@
                     descriptor_pool=None,
                     indent=0,
                     message_formatter=None):
+  # type: (...) -> str
   """Convert protobuf message to text format.
 
   Floating point values can be formatted compactly with 15 digits of
@@ -137,8 +139,11 @@
 
   Args:
     message: The protocol buffers message.
-    as_utf8: Produce text output in UTF8 format.
+    as_utf8: Return unescaped Unicode for non-ASCII characters.
+        In Python 3 actual Unicode characters may appear as is in strings.
+        In Python 2 the return value will be valid UTF-8 rather than only ASCII.
     as_one_line: Don't introduce newlines between fields.
+    use_short_repeated_primitives: Use short repeated format for primitives.
     pointy_brackets: If True, use angle brackets instead of curly braces for
       nesting.
     use_index_order: If True, fields of a proto message will be printed using
@@ -159,7 +164,8 @@
     A string of the text formatted protocol buffer message.
   """
   out = TextWriter(as_utf8)
-  printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets,
+  printer = _Printer(out, indent, as_utf8, as_one_line,
+                     use_short_repeated_primitives, pointy_brackets,
                      use_index_order, float_format, use_field_number,
                      descriptor_pool, message_formatter)
   printer.PrintMessage(message)
@@ -170,6 +176,16 @@
   return result
 
 
+def MessageToBytes(message, **kwargs):
+  # type: (...) -> bytes
+  """Convert protobuf message to encoded text format.  See MessageToString."""
+  text = MessageToString(message, **kwargs)
+  if isinstance(text, bytes):
+    return text
+  codec = 'utf-8' if kwargs.get('as_utf8') else 'ascii'
+  return text.encode(codec)
+
+
 def _IsMapEntry(field):
   return (field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
           field.message_type.has_options and
@@ -181,13 +197,15 @@
                  indent=0,
                  as_utf8=False,
                  as_one_line=False,
+                 use_short_repeated_primitives=False,
                  pointy_brackets=False,
                  use_index_order=False,
                  float_format=None,
                  use_field_number=False,
                  descriptor_pool=None,
                  message_formatter=None):
-  printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets,
+  printer = _Printer(out, indent, as_utf8, as_one_line,
+                     use_short_repeated_primitives, pointy_brackets,
                      use_index_order, float_format, use_field_number,
                      descriptor_pool, message_formatter)
   printer.PrintMessage(message)
@@ -199,12 +217,14 @@
                indent=0,
                as_utf8=False,
                as_one_line=False,
+               use_short_repeated_primitives=False,
                pointy_brackets=False,
                use_index_order=False,
                float_format=None,
                message_formatter=None):
   """Print a single field name/value pair."""
-  printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets,
+  printer = _Printer(out, indent, as_utf8, as_one_line,
+                     use_short_repeated_primitives, pointy_brackets,
                      use_index_order, float_format, message_formatter)
   printer.PrintField(field, value)
 
@@ -215,12 +235,14 @@
                     indent=0,
                     as_utf8=False,
                     as_one_line=False,
+                    use_short_repeated_primitives=False,
                     pointy_brackets=False,
                     use_index_order=False,
                     float_format=None,
                     message_formatter=None):
   """Print a single field value (not including name)."""
-  printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets,
+  printer = _Printer(out, indent, as_utf8, as_one_line,
+                     use_short_repeated_primitives, pointy_brackets,
                      use_index_order, float_format, message_formatter)
   printer.PrintFieldValue(field, value)
 
@@ -258,6 +280,7 @@
                indent=0,
                as_utf8=False,
                as_one_line=False,
+               use_short_repeated_primitives=False,
                pointy_brackets=False,
                use_index_order=False,
                float_format=None,
@@ -274,8 +297,11 @@
     Args:
       out: To record the text format result.
       indent: The indent level for pretty print.
-      as_utf8: Produce text output in UTF8 format.
+      as_utf8: Return unescaped Unicode for non-ASCII characters.
+          In Python 3 actual Unicode characters may appear as is in strings.
+          In Python 2 the return value will be valid UTF-8 rather than ASCII.
       as_one_line: Don't introduce newlines between fields.
+      use_short_repeated_primitives: Use short repeated format for primitives.
       pointy_brackets: If True, use angle brackets instead of curly braces for
         nesting.
       use_index_order: If True, print fields of a proto message using the order
@@ -294,6 +320,7 @@
     self.indent = indent
     self.as_utf8 = as_utf8
     self.as_one_line = as_one_line
+    self.use_short_repeated_primitives = use_short_repeated_primitives
     self.pointy_brackets = pointy_brackets
     self.use_index_order = use_index_order
     self.float_format = float_format
@@ -351,13 +378,18 @@
           entry_submsg = value.GetEntryClass()(key=key, value=value[key])
           self.PrintField(field, entry_submsg)
       elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
-        for element in value:
-          self.PrintField(field, element)
+        if (self.use_short_repeated_primitives
+            and field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE
+            and field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_STRING):
+          self._PrintShortRepeatedPrimitivesValue(field, value)
+        else:
+          for element in value:
+            self.PrintField(field, element)
       else:
         self.PrintField(field, value)
 
-  def PrintField(self, field, value):
-    """Print a single field name/value pair."""
+  def _PrintFieldName(self, field):
+    """Print field name."""
     out = self.out
     out.write(' ' * self.indent)
     if self.use_field_number:
@@ -383,11 +415,22 @@
       # don't include it.
       out.write(': ')
 
+  def PrintField(self, field, value):
+    """Print a single field name/value pair."""
+    self._PrintFieldName(field)
     self.PrintFieldValue(field, value)
-    if self.as_one_line:
-      out.write(' ')
-    else:
-      out.write('\n')
+    self.out.write(' ' if self.as_one_line else '\n')
+
+  def _PrintShortRepeatedPrimitivesValue(self, field, value):
+    # Note: this is called only when value has at least one element.
+    self._PrintFieldName(field)
+    self.out.write('[')
+    for i in xrange(len(value) - 1):
+      self.PrintFieldValue(field, value[i])
+      self.out.write(', ')
+    self.PrintFieldValue(field, value[-1])
+    self.out.write(']')
+    self.out.write(' ' if self.as_one_line else '\n')
 
   def _PrintMessageFieldValue(self, value):
     if self.pointy_brackets:
@@ -428,12 +471,12 @@
         out.write(str(value))
     elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING:
       out.write('\"')
-      if isinstance(value, six.text_type):
+      if isinstance(value, six.text_type) and (six.PY2 or not self.as_utf8):
         out_value = value.encode('utf-8')
       else:
         out_value = value
       if field.type == descriptor.FieldDescriptor.TYPE_BYTES:
-        # We need to escape non-UTF8 chars in TYPE_BYTES field.
+        # We always need to escape all binary data in TYPE_BYTES fields.
         out_as_utf8 = False
       else:
         out_as_utf8 = self.as_utf8
@@ -487,12 +530,7 @@
   Raises:
     ParseError: On text parsing problems.
   """
-  if not isinstance(text, str):
-    if six.PY3:
-      text = text.decode('utf-8')
-    else:
-      text = text.encode('utf-8')
-  return ParseLines(text.split('\n'),
+  return ParseLines(text.split(b'\n' if isinstance(text, bytes) else u'\n'),
                     message,
                     allow_unknown_extension,
                     allow_field_number,
@@ -523,13 +561,8 @@
   Raises:
     ParseError: On text parsing problems.
   """
-  if not isinstance(text, str):
-    if six.PY3:
-      text = text.decode('utf-8')
-    else:
-      text = text.encode('utf-8')
   return MergeLines(
-      text.split('\n'),
+      text.split(b'\n' if isinstance(text, bytes) else u'\n'),
       message,
       allow_unknown_extension,
       allow_field_number,
@@ -570,6 +603,9 @@
                descriptor_pool=None):
   """Parses a text representation of a protocol message into a message.
 
+  Like ParseLines(), but allows repeated values for a non-repeated field, and
+  uses the last one.
+
   Args:
     lines: An iterable of lines of a message's text representation.
     message: A protocol buffer message to merge into.
@@ -601,22 +637,12 @@
     self.allow_field_number = allow_field_number
     self.descriptor_pool = descriptor_pool
 
-  def ParseFromString(self, text, message):
-    """Parses a text representation of a protocol message into a message."""
-    if not isinstance(text, str):
-      text = text.decode('utf-8')
-    return self.ParseLines(text.split('\n'), message)
-
   def ParseLines(self, lines, message):
     """Parses a text representation of a protocol message into a message."""
     self._allow_multiple_scalars = False
     self._ParseOrMerge(lines, message)
     return message
 
-  def MergeFromString(self, text, message):
-    """Merges a text representation of a protocol message into a message."""
-    return self._MergeLines(text.split('\n'), message)
-
   def MergeLines(self, lines, message):
     """Merges a text representation of a protocol message into a message."""
     self._allow_multiple_scalars = True
@@ -633,7 +659,14 @@
     Raises:
       ParseError: On text parsing problems.
     """
-    tokenizer = Tokenizer(lines)
+    # Tokenize expects native str lines.
+    if six.PY2:
+      str_lines = (line if isinstance(line, str) else line.encode('utf-8')
+                   for line in lines)
+    else:
+      str_lines = (line if isinstance(line, str) else line.decode('utf-8')
+                   for line in lines)
+    tokenizer = Tokenizer(str_lines)
     while not tokenizer.AtEnd():
       self._MergeField(tokenizer, message)
 
@@ -1019,7 +1052,9 @@
       r'[a-zA-Z_][0-9a-zA-Z_+-]*',  # an identifier
       r'([0-9+-]|(\.[0-9]))[0-9a-zA-Z_.+-]*',  # a number
   ] + [  # quoted str for each quote mark
-      r'{qt}([^{qt}\n\\]|\\.)*({qt}|\\?$)'.format(qt=mark) for mark in _QUOTES
+      # Avoid backtracking! https://stackoverflow.com/a/844267
+      r'{qt}[^{qt}\n\\]*((\\.)+[^{qt}\n\\]*)*({qt}|\\?$)'.format(qt=mark)
+      for mark in _QUOTES
   ]))
 
   _IDENTIFIER = re.compile(r'[^\d\W]\w*')
@@ -1316,7 +1351,8 @@
 
   def ParseError(self, message):
     """Creates and *returns* a ParseError for the current token."""
-    return ParseError(message, self._line + 1, self._column + 1)
+    return ParseError('\'' + self._current_line + '\': ' + message,
+                      self._line + 1, self._column + 1)
 
   def _StringParseError(self, e):
     return self.ParseError('Couldn\'t parse string: ' + str(e))
@@ -1490,6 +1526,12 @@
     ValueError: Thrown Iff the text is not a valid integer.
   """
   # Do the actual parsing. Exception handling is propagated to caller.
+  orig_text = text
+  c_octal_match = re.match(r'(-?)0(\d+)$', text)
+  if c_octal_match:
+    # Python 3 no longer supports 0755 octal syntax without the 'o', so
+    # we always use the '0o' prefix for multi-digit numbers starting with 0.
+    text = c_octal_match.group(1) + '0o' + c_octal_match.group(2)
   try:
     # We force 32-bit values to int and 64-bit values to long to make
     # alternate implementations where the distinction is more significant
@@ -1499,7 +1541,7 @@
     else:
       return int(text, 0)
   except ValueError:
-    raise ValueError('Couldn\'t parse integer: %s' % text)
+    raise ValueError('Couldn\'t parse integer: %s' % orig_text)
 
 
 def ParseFloat(text):
diff --git a/python/setup.py b/python/setup.py
index 5ec4dcb..63c2d0e 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -185,8 +185,12 @@
         extra_compile_args.append('-Wno-write-strings')
         extra_compile_args.append('-Wno-invalid-offsetof')
         extra_compile_args.append('-Wno-sign-compare')
+        extra_compile_args.append('-Wno-unused-variable')
         extra_compile_args.append('-std=c++11')
 
+    if sys.platform == 'darwin':
+      extra_compile_args.append("-Wno-shorten-64-to-32");
+
     # https://github.com/Theano/Theano/issues/4926
     if sys.platform == 'win32':
       extra_compile_args.append('-D_hypot=hypot')
diff --git a/src/Makefile.am b/src/Makefile.am
index 9f829bf..1aabf97 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -112,6 +112,9 @@
   google/protobuf/message_lite.h                                 \
   google/protobuf/metadata.h                                     \
   google/protobuf/metadata_lite.h                                \
+  google/protobuf/port.h                                         \
+  google/protobuf/port_def.inc                                   \
+  google/protobuf/port_undef.inc                                 \
   google/protobuf/reflection.h                                   \
   google/protobuf/reflection_ops.h                               \
   google/protobuf/repeated_field.h                               \
@@ -311,6 +314,8 @@
   google/protobuf/compiler/command_line_interface.cc           \
   google/protobuf/compiler/plugin.cc                           \
   google/protobuf/compiler/plugin.pb.cc                        \
+  google/protobuf/compiler/scc.cc                              \
+  google/protobuf/compiler/scc.h                               \
   google/protobuf/compiler/subprocess.cc                       \
   google/protobuf/compiler/subprocess.h                        \
   google/protobuf/compiler/zip_writer.cc                       \
@@ -499,6 +504,7 @@
   google/protobuf/unittest_preserve_unknown_enum2.proto           \
   google/protobuf/unittest_preserve_unknown_enum.proto            \
   google/protobuf/unittest.proto                                  \
+  google/protobuf/unittest_proto3.proto                           \
   google/protobuf/unittest_proto3_arena.proto                     \
   google/protobuf/unittest_proto3_arena_lite.proto                \
   google/protobuf/unittest_proto3_lite.proto                      \
@@ -514,6 +520,7 @@
   google/protobuf/util/internal/testdata/struct.proto             \
   google/protobuf/util/internal/testdata/timestamp_duration.proto \
   google/protobuf/util/internal/testdata/wrappers.proto           \
+  google/protobuf/util/json_format.proto                          \
   google/protobuf/util/json_format_proto3.proto                   \
   google/protobuf/util/message_differencer_unittest.proto         \
   google/protobuf/compiler/cpp/cpp_test_large_enum_value.proto
@@ -522,7 +529,6 @@
   $(protoc_inputs)                                             \
   $(js_well_known_types_sources)                               \
   solaris/libstdc++.la                                         \
-  google/protobuf/unittest_proto3.proto                        \
   google/protobuf/test_messages_proto3.proto                   \
   google/protobuf/test_messages_proto2.proto                   \
   google/protobuf/io/gzip_stream.h                             \
@@ -620,6 +626,8 @@
   google/protobuf/unittest_preserve_unknown_enum2.pb.h            \
   google/protobuf/unittest_preserve_unknown_enum.pb.cc            \
   google/protobuf/unittest_preserve_unknown_enum.pb.h             \
+  google/protobuf/unittest_proto3.pb.cc                           \
+  google/protobuf/unittest_proto3.pb.h                            \
   google/protobuf/unittest_proto3_arena.pb.cc                     \
   google/protobuf/unittest_proto3_arena.pb.h                      \
   google/protobuf/unittest_proto3_arena_lite.pb.cc                \
@@ -650,6 +658,8 @@
   google/protobuf/util/internal/testdata/timestamp_duration.pb.h  \
   google/protobuf/util/internal/testdata/wrappers.pb.cc           \
   google/protobuf/util/internal/testdata/wrappers.pb.h            \
+  google/protobuf/util/json_format.pb.cc                          \
+  google/protobuf/util/json_format.pb.h                           \
   google/protobuf/util/json_format_proto3.pb.cc                   \
   google/protobuf/util/json_format_proto3.pb.h                    \
   google/protobuf/util/message_differencer_unittest.pb.cc         \
@@ -683,6 +693,7 @@
   google/protobuf/test_util.cc                                 \
   google/protobuf/test_util.h                                  \
   google/protobuf/test_util.inc                                \
+  google/protobuf/test_util2.h                                 \
   google/protobuf/testing/googletest.cc                        \
   google/protobuf/testing/googletest.h                         \
   google/protobuf/testing/file.cc                              \
@@ -736,6 +747,7 @@
   google/protobuf/proto3_arena_lite_unittest.cc                \
   google/protobuf/proto3_arena_unittest.cc                     \
   google/protobuf/proto3_lite_unittest.cc                      \
+  google/protobuf/proto3_lite_unittest.inc                     \
   google/protobuf/reflection_ops_unittest.cc                   \
   google/protobuf/repeated_field_reflection_unittest.cc        \
   google/protobuf/repeated_field_unittest.cc                   \
diff --git a/src/README.md b/src/README.md
index 4ca9a02..e38e59b 100644
--- a/src/README.md
+++ b/src/README.md
@@ -1,7 +1,7 @@
 Protocol Buffers - Google's data interchange format
 ===================================================
 
-[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-cpp_distcheck.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fcpp_distcheck%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fcpp%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-cpp_distcheck.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fcpp_distcheck%2Fcontinuous) [![Build status](https://ci.appveyor.com/api/projects/status/73ctee6ua4w2ruin?svg=true)](https://ci.appveyor.com/project/protobuf/protobuf)
+[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-cpp_distcheck.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fcpp_distcheck%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-bazel.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fbazel%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fcpp%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-cpp_distcheck.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fcpp_distcheck%2Fcontinuous) [![Build status](https://ci.appveyor.com/api/projects/status/73ctee6ua4w2ruin?svg=true)](https://ci.appveyor.com/project/protobuf/protobuf)
 
 Copyright 2008 Google Inc.
 
diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h
index a34e5f8..61dc717 100644
--- a/src/google/protobuf/any.h
+++ b/src/google/protobuf/any.h
@@ -113,6 +113,6 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_ANY_H__
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc
index d0fc290..7b10893 100644
--- a/src/google/protobuf/any.pb.cc
+++ b/src/google/protobuf/any.pb.cc
@@ -6,8 +6,8 @@
 #include <algorithm>
 
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
@@ -18,18 +18,17 @@
 #include "third_party/protobuf/version.h"
 #endif
 // @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
 
 namespace google {
 namespace protobuf {
 class AnyDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Any>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Any> _instance;
 } _Any_default_instance_;
 }  // namespace protobuf
 }  // namespace google
-namespace protobuf_google_2fprotobuf_2fany_2eproto {
-static void InitDefaultsAny() {
+static void InitDefaultsAny_google_2fprotobuf_2fany_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -40,16 +39,18 @@
   ::google::protobuf::Any::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Any =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsAny}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Any_google_2fprotobuf_2fany_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsAny_google_2fprotobuf_2fany_2eproto}, {}};
 
-void InitDefaults() {
-  ::google::protobuf::internal::InitSCC(&scc_info_Any.base);
+void InitDefaults_google_2fprotobuf_2fany_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_Any_google_2fprotobuf_2fany_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata[1];
+::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fany_2eproto[1];
+constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto = nullptr;
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fany_2eproto = nullptr;
 
-const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fany_2eproto::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Any, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -66,51 +67,33 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Any_default_instance_),
 };
 
-static void protobuf_AssignDescriptors() {
-  AddDescriptors();
-  AssignDescriptors(
-      "google/protobuf/any.proto", schemas, file_default_instances, TableStruct::offsets,
-      file_level_metadata, NULL, NULL);
-}
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fany_2eproto = {
+  {}, AddDescriptors_google_2fprotobuf_2fany_2eproto, "google/protobuf/any.proto", schemas,
+  file_default_instances, TableStruct_google_2fprotobuf_2fany_2eproto::offsets,
+  file_level_metadata_google_2fprotobuf_2fany_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto, file_level_service_descriptors_google_2fprotobuf_2fany_2eproto,
+};
 
-static void protobuf_AssignDescriptorsOnce() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
-}
+::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto = {
+  false, InitDefaults_google_2fprotobuf_2fany_2eproto, 
+  "\n\031google/protobuf/any.proto\022\017google.prot"
+  "obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002"
+  " \001(\014Bo\n\023com.google.protobufB\010AnyProtoP\001Z"
+  "%github.com/golang/protobuf/ptypes/any\242\002"
+  "\003GPB\252\002\036Google.Protobuf.WellKnownTypesb\006p"
+  "roto3"
+,
+  "google/protobuf/any.proto", &assign_descriptors_table_google_2fprotobuf_2fany_2eproto, 205,
+};
 
-void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
-void protobuf_RegisterTypes(const ::std::string&) {
-  protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
-}
-
-static void AddDescriptorsImpl() {
-  InitDefaults();
-  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
-      "\n\031google/protobuf/any.proto\022\017google.prot"
-      "obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002"
-      " \001(\014Bo\n\023com.google.protobufB\010AnyProtoP\001Z"
-      "%github.com/golang/protobuf/ptypes/any\242\002"
-      "\003GPB\252\002\036Google.Protobuf.WellKnownTypesb\006p"
-      "roto3"
+void AddDescriptors_google_2fprotobuf_2fany_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
   };
-  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 205);
-  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
-    "google/protobuf/any.proto", &protobuf_RegisterTypes);
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fany_2eproto, deps, 0);
 }
 
-void AddDescriptors() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
-}
-// Force AddDescriptors() to be called at dynamic initialization time.
-struct StaticDescriptorInitializer {
-  StaticDescriptorInitializer() {
-    AddDescriptors();
-  }
-} static_descriptor_initializer;
-}  // namespace protobuf_google_2fprotobuf_2fany_2eproto
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_google_2fprotobuf_2fany_2eproto = []() { AddDescriptors_google_2fprotobuf_2fany_2eproto(); return true; }();
 namespace google {
 namespace protobuf {
 
@@ -135,6 +118,17 @@
   return ::google::protobuf::internal::ParseAnyTypeUrl(type_url,
                                              full_type_name);
 }
+bool Any::GetAnyFieldDescriptors(
+    const ::google::protobuf::Message& message,
+    const ::google::protobuf::FieldDescriptor** type_url_field,
+    const ::google::protobuf::FieldDescriptor** value_field) {
+  return ::google::protobuf::internal::GetAnyFieldDescriptors(
+      message, type_url_field, value_field);
+}
+
+class Any::HasBitSetters {
+ public:
+};
 
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Any::kTypeUrlFieldNumber;
@@ -143,8 +137,6 @@
 
 Any::Any()
   : ::google::protobuf::Message(), _internal_metadata_(NULL), _any_metadata_(&type_url_, &value_) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fany_2eproto::scc_info_Any.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Any)
 }
@@ -165,6 +157,8 @@
 }
 
 void Any::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Any_google_2fprotobuf_2fany_2eproto.base);
   type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
@@ -182,13 +176,8 @@
 void Any::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Any::descriptor() {
-  ::protobuf_google_2fprotobuf_2fany_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fany_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Any& Any::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fany_2eproto::scc_info_Any.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Any_google_2fprotobuf_2fany_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -204,9 +193,79 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Any::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Any*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // string type_url = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Any.type_url");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_type_url();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // bytes value = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::internal::StringParser;
+        ::std::string* str = msg->mutable_value();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Any::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Any)
   for (;;) {
@@ -216,8 +275,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // string type_url = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_type_url()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -232,8 +290,7 @@
 
       // bytes value = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                 input, this->mutable_value()));
         } else {
@@ -261,6 +318,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Any::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -284,9 +342,9 @@
       2, this->value(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Any)
 }
@@ -316,9 +374,9 @@
         2, this->value(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Any)
   return target;
@@ -328,11 +386,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Any)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // string type_url = 1;
   if (this->type_url().size() > 0) {
     total_size += 1 +
@@ -356,7 +418,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Any)
   GOOGLE_DCHECK_NE(&from, this);
   const Any* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Any>(
+      ::google::protobuf::DynamicCastToGenerated<Any>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Any)
@@ -408,16 +470,16 @@
 }
 void Any::InternalSwap(Any* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   type_url_.Swap(&other->type_url_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   value_.Swap(&other->value_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata Any::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fany_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fany_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fany_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fany_2eproto[kIndexInFileMessages];
 }
 
 
diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h
index 157fc80..a5ad582 100644
--- a/src/google/protobuf/any.pb.h
+++ b/src/google/protobuf/any.pb.h
@@ -4,18 +4,18 @@
 #ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto
 #define PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto
 
+#include <limits>
 #include <string>
 
 #include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 3006001
+#if GOOGLE_PROTOBUF_VERSION < 3006000
 #error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please update
+#error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
 #if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
 #error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please
+#error incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.
 #endif
 
@@ -32,29 +32,27 @@
 #include <google/protobuf/unknown_field_set.h>
 #include <google/protobuf/any.h>
 // @@protoc_insertion_point(includes)
-#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fany_2eproto LIBPROTOBUF_EXPORT
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fany_2eproto LIBPROTOBUF_EXPORT
 
-namespace protobuf_google_2fprotobuf_2fany_2eproto {
 // Internal implementation detail -- do not use these members.
-struct LIBPROTOBUF_EXPORT TableStruct {
-  static const ::google::protobuf::internal::ParseTableField entries[];
-  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
-  static const ::google::protobuf::internal::ParseTable schema[1];
+struct LIBPROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fany_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[1]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
   static const ::google::protobuf::uint32 offsets[];
 };
-void LIBPROTOBUF_EXPORT AddDescriptors();
-}  // namespace protobuf_google_2fprotobuf_2fany_2eproto
+void LIBPROTOBUF_EXPORT AddDescriptors_google_2fprotobuf_2fany_2eproto();
 namespace google {
 namespace protobuf {
 class Any;
 class AnyDefaultTypeInternal;
 LIBPROTOBUF_EXPORT extern AnyDefaultTypeInternal _Any_default_instance_;
-}  // namespace protobuf
-}  // namespace google
-namespace google {
-namespace protobuf {
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::Any* Arena::CreateMaybeMessage<::google::protobuf::Any>(Arena*);
 }  // namespace protobuf
 }  // namespace google
@@ -89,7 +87,9 @@
     return *this;
   }
   #endif
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Any& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -111,7 +111,10 @@
   }
   static bool ParseAnyTypeUrl(const string& type_url,
                               string* full_type_name);
-
+  static bool GetAnyFieldDescriptors(
+      const ::google::protobuf::Message& message,
+      const ::google::protobuf::FieldDescriptor** type_url_field,
+      const ::google::protobuf::FieldDescriptor** value_field);
   void Swap(Any* other);
   friend void swap(Any& a, Any& b) {
     a.Swap(&b);
@@ -134,8 +137,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -192,13 +200,14 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Any)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::internal::ArenaStringPtr type_url_;
   ::google::protobuf::internal::ArenaStringPtr value_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::internal::AnyMetadata _any_metadata_;
-  friend struct ::protobuf_google_2fprotobuf_2fany_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fany_2eproto;
 };
 // ===================================================================
 
@@ -328,4 +337,5 @@
 
 // @@protoc_insertion_point(global_scope)
 
+#include <google/protobuf/port_undef.inc>
 #endif  // PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto
diff --git a/src/google/protobuf/any_test.cc b/src/google/protobuf/any_test.cc
index 1bfaa63..514ac51 100644
--- a/src/google/protobuf/any_test.cc
+++ b/src/google/protobuf/any_test.cc
@@ -31,6 +31,7 @@
 #include <google/protobuf/any_test.pb.h>
 #include <gtest/gtest.h>
 
+
 namespace google {
 namespace protobuf {
 namespace {
@@ -67,6 +68,28 @@
   EXPECT_EQ(12345, submessage.int32_value());
 }
 
+TEST(AnyType, TestPackWithCustomTypeUrl) {
+  protobuf_unittest::TestAny submessage;
+  submessage.set_int32_value(12345);
+  google::protobuf::Any any;
+  // Pack with a custom type URL prefix.
+  any.PackFrom(submessage, "type.myservice.com");
+  EXPECT_EQ("type.myservice.com/" + submessage.GetDescriptor()->full_name(),
+            any.type_url());
+  // Pack with a custom type URL prefix ending with '/'.
+  any.PackFrom(submessage, "type.myservice.com/");
+  EXPECT_EQ("type.myservice.com/" + submessage.GetDescriptor()->full_name(),
+            any.type_url());
+  // Pack with an empty type URL prefix.
+  any.PackFrom(submessage, "");
+  EXPECT_EQ("/" + submessage.GetDescriptor()->full_name(), any.type_url());
+
+  // Test unpacking the type.
+  submessage.Clear();
+  EXPECT_TRUE(any.UnpackTo(&submessage));
+  EXPECT_EQ(12345, submessage.int32_value());
+}
+
 TEST(AnyTest, TestIs) {
   protobuf_unittest::TestAny submessage;
   submessage.set_int32_value(12345);
@@ -83,7 +106,39 @@
   EXPECT_TRUE(message.any_value().Is<google::protobuf::Any>());
 }
 
+TEST(AnyTest, MoveConstructor) {
+  protobuf_unittest::TestAny payload;
+  payload.set_int32_value(12345);
+
+  google::protobuf::Any src;
+  src.PackFrom(payload);
+
+  const char* type_url = src.type_url().data();
+
+  google::protobuf::Any dst(std::move(src));
+  EXPECT_EQ(type_url, dst.type_url().data());
+  ASSERT_TRUE(dst.UnpackTo(&payload));
+  EXPECT_EQ(12345, payload.int32_value());
+}
+
+TEST(AnyTest, MoveAssignment) {
+  protobuf_unittest::TestAny payload;
+  payload.set_int32_value(12345);
+
+  google::protobuf::Any src;
+  src.PackFrom(payload);
+
+  const char* type_url = src.type_url().data();
+
+  google::protobuf::Any dst;
+  dst = std::move(src);
+  EXPECT_EQ(type_url, dst.type_url().data());
+  ASSERT_TRUE(dst.UnpackTo(&payload));
+  EXPECT_EQ(12345, payload.int32_value());
+}
+
+
 }  // namespace
 }  // namespace protobuf
-
 }  // namespace google
+
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index 273307c..ac2a0e8 100644
--- a/src/google/protobuf/api.pb.cc
+++ b/src/google/protobuf/api.pb.cc
@@ -6,8 +6,8 @@
 #include <algorithm>
 
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
@@ -18,38 +18,29 @@
 #include "third_party/protobuf/version.h"
 #endif
 // @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
 
-namespace protobuf_google_2fprotobuf_2fapi_2eproto {
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fapi_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Mixin;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fapi_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_Method;
-}  // namespace protobuf_google_2fprotobuf_2fapi_2eproto
-namespace protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto {
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_SourceContext;
-}  // namespace protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto
-namespace protobuf_google_2fprotobuf_2ftype_2eproto {
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2ftype_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_Option;
-}  // namespace protobuf_google_2fprotobuf_2ftype_2eproto
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fapi_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Mixin_google_2fprotobuf_2fapi_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fapi_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_Method_google_2fprotobuf_2fapi_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fsource_5fcontext_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_Option_google_2fprotobuf_2ftype_2eproto;
 namespace google {
 namespace protobuf {
 class ApiDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Api>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Api> _instance;
 } _Api_default_instance_;
 class MethodDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Method>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Method> _instance;
 } _Method_default_instance_;
 class MixinDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Mixin>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Mixin> _instance;
 } _Mixin_default_instance_;
 }  // namespace protobuf
 }  // namespace google
-namespace protobuf_google_2fprotobuf_2fapi_2eproto {
-static void InitDefaultsApi() {
+static void InitDefaultsApi_google_2fprotobuf_2fapi_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -60,14 +51,14 @@
   ::google::protobuf::Api::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<4> scc_info_Api =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 4, InitDefaultsApi}, {
-      &protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Method.base,
-      &protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Option.base,
-      &protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::scc_info_SourceContext.base,
-      &protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Mixin.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<4> scc_info_Api_google_2fprotobuf_2fapi_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 4, InitDefaultsApi_google_2fprotobuf_2fapi_2eproto}, {
+      &scc_info_Method_google_2fprotobuf_2fapi_2eproto.base,
+      &scc_info_Option_google_2fprotobuf_2ftype_2eproto.base,
+      &scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto.base,
+      &scc_info_Mixin_google_2fprotobuf_2fapi_2eproto.base,}};
 
-static void InitDefaultsMethod() {
+static void InitDefaultsMethod_google_2fprotobuf_2fapi_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -78,11 +69,11 @@
   ::google::protobuf::Method::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_Method =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMethod}, {
-      &protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Option.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_Method_google_2fprotobuf_2fapi_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMethod_google_2fprotobuf_2fapi_2eproto}, {
+      &scc_info_Option_google_2fprotobuf_2ftype_2eproto.base,}};
 
-static void InitDefaultsMixin() {
+static void InitDefaultsMixin_google_2fprotobuf_2fapi_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -93,18 +84,20 @@
   ::google::protobuf::Mixin::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Mixin =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsMixin}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Mixin_google_2fprotobuf_2fapi_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsMixin_google_2fprotobuf_2fapi_2eproto}, {}};
 
-void InitDefaults() {
-  ::google::protobuf::internal::InitSCC(&scc_info_Api.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_Method.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_Mixin.base);
+void InitDefaults_google_2fprotobuf_2fapi_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_Api_google_2fprotobuf_2fapi_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Method_google_2fprotobuf_2fapi_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Mixin_google_2fprotobuf_2fapi_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata[3];
+::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fapi_2eproto[3];
+constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr;
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto = nullptr;
 
-const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fapi_2eproto::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Api, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -149,66 +142,48 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Mixin_default_instance_),
 };
 
-static void protobuf_AssignDescriptors() {
-  AddDescriptors();
-  AssignDescriptors(
-      "google/protobuf/api.proto", schemas, file_default_instances, TableStruct::offsets,
-      file_level_metadata, NULL, NULL);
-}
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fapi_2eproto = {
+  {}, AddDescriptors_google_2fprotobuf_2fapi_2eproto, "google/protobuf/api.proto", schemas,
+  file_default_instances, TableStruct_google_2fprotobuf_2fapi_2eproto::offsets,
+  file_level_metadata_google_2fprotobuf_2fapi_2eproto, 3, file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto, file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto,
+};
 
-static void protobuf_AssignDescriptorsOnce() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
-}
+::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto = {
+  false, InitDefaults_google_2fprotobuf_2fapi_2eproto, 
+  "\n\031google/protobuf/api.proto\022\017google.prot"
+  "obuf\032$google/protobuf/source_context.pro"
+  "to\032\032google/protobuf/type.proto\"\201\002\n\003Api\022\014"
+  "\n\004name\030\001 \001(\t\022(\n\007methods\030\002 \003(\0132\027.google.p"
+  "rotobuf.Method\022(\n\007options\030\003 \003(\0132\027.google"
+  ".protobuf.Option\022\017\n\007version\030\004 \001(\t\0226\n\016sou"
+  "rce_context\030\005 \001(\0132\036.google.protobuf.Sour"
+  "ceContext\022&\n\006mixins\030\006 \003(\0132\026.google.proto"
+  "buf.Mixin\022\'\n\006syntax\030\007 \001(\0162\027.google.proto"
+  "buf.Syntax\"\325\001\n\006Method\022\014\n\004name\030\001 \001(\t\022\030\n\020r"
+  "equest_type_url\030\002 \001(\t\022\031\n\021request_streami"
+  "ng\030\003 \001(\010\022\031\n\021response_type_url\030\004 \001(\t\022\032\n\022r"
+  "esponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\013"
+  "2\027.google.protobuf.Option\022\'\n\006syntax\030\007 \001("
+  "\0162\027.google.protobuf.Syntax\"#\n\005Mixin\022\014\n\004n"
+  "ame\030\001 \001(\t\022\014\n\004root\030\002 \001(\tBu\n\023com.google.pr"
+  "otobufB\010ApiProtoP\001Z+google.golang.org/ge"
+  "nproto/protobuf/api;api\242\002\003GPB\252\002\036Google.P"
+  "rotobuf.WellKnownTypesb\006proto3"
+,
+  "google/protobuf/api.proto", &assign_descriptors_table_google_2fprotobuf_2fapi_2eproto, 750,
+};
 
-void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
-void protobuf_RegisterTypes(const ::std::string&) {
-  protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 3);
-}
-
-static void AddDescriptorsImpl() {
-  InitDefaults();
-  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
-      "\n\031google/protobuf/api.proto\022\017google.prot"
-      "obuf\032$google/protobuf/source_context.pro"
-      "to\032\032google/protobuf/type.proto\"\201\002\n\003Api\022\014"
-      "\n\004name\030\001 \001(\t\022(\n\007methods\030\002 \003(\0132\027.google.p"
-      "rotobuf.Method\022(\n\007options\030\003 \003(\0132\027.google"
-      ".protobuf.Option\022\017\n\007version\030\004 \001(\t\0226\n\016sou"
-      "rce_context\030\005 \001(\0132\036.google.protobuf.Sour"
-      "ceContext\022&\n\006mixins\030\006 \003(\0132\026.google.proto"
-      "buf.Mixin\022\'\n\006syntax\030\007 \001(\0162\027.google.proto"
-      "buf.Syntax\"\325\001\n\006Method\022\014\n\004name\030\001 \001(\t\022\030\n\020r"
-      "equest_type_url\030\002 \001(\t\022\031\n\021request_streami"
-      "ng\030\003 \001(\010\022\031\n\021response_type_url\030\004 \001(\t\022\032\n\022r"
-      "esponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\013"
-      "2\027.google.protobuf.Option\022\'\n\006syntax\030\007 \001("
-      "\0162\027.google.protobuf.Syntax\"#\n\005Mixin\022\014\n\004n"
-      "ame\030\001 \001(\t\022\014\n\004root\030\002 \001(\tBu\n\023com.google.pr"
-      "otobufB\010ApiProtoP\001Z+google.golang.org/ge"
-      "nproto/protobuf/api;api\242\002\003GPB\252\002\036Google.P"
-      "rotobuf.WellKnownTypesb\006proto3"
+void AddDescriptors_google_2fprotobuf_2fapi_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[2] =
+  {
+    ::AddDescriptors_google_2fprotobuf_2fsource_5fcontext_2eproto,
+    ::AddDescriptors_google_2fprotobuf_2ftype_2eproto,
   };
-  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 750);
-  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
-    "google/protobuf/api.proto", &protobuf_RegisterTypes);
-  ::protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::AddDescriptors();
-  ::protobuf_google_2fprotobuf_2ftype_2eproto::AddDescriptors();
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fapi_2eproto, deps, 2);
 }
 
-void AddDescriptors() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
-}
-// Force AddDescriptors() to be called at dynamic initialization time.
-struct StaticDescriptorInitializer {
-  StaticDescriptorInitializer() {
-    AddDescriptors();
-  }
-} static_descriptor_initializer;
-}  // namespace protobuf_google_2fprotobuf_2fapi_2eproto
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_google_2fprotobuf_2fapi_2eproto = []() { AddDescriptors_google_2fprotobuf_2fapi_2eproto(); return true; }();
 namespace google {
 namespace protobuf {
 
@@ -218,6 +193,15 @@
   ::google::protobuf::_Api_default_instance_._instance.get_mutable()->source_context_ = const_cast< ::google::protobuf::SourceContext*>(
       ::google::protobuf::SourceContext::internal_default_instance());
 }
+class Api::HasBitSetters {
+ public:
+  static const ::google::protobuf::SourceContext& source_context(const Api* msg);
+};
+
+const ::google::protobuf::SourceContext&
+Api::HasBitSetters::source_context(const Api* msg) {
+  return *msg->source_context_;
+}
 void Api::clear_options() {
   options_.Clear();
 }
@@ -239,8 +223,6 @@
 
 Api::Api()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Api.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Api)
 }
@@ -269,6 +251,8 @@
 }
 
 void Api::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Api_google_2fprotobuf_2fapi_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   version_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   ::memset(&source_context_, 0, static_cast<size_t>(
@@ -290,13 +274,8 @@
 void Api::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Api::descriptor() {
-  ::protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Api& Api::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Api.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Api_google_2fprotobuf_2fapi_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -320,9 +299,151 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Api::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Api*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Api.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated .google.protobuf.Method methods = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::Method::_InternalParse;
+          object = msg->add_methods();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 18 && (ptr += 1));
+        break;
+      }
+      // repeated .google.protobuf.Option options = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::Option::_InternalParse;
+          object = msg->add_options();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 26 && (ptr += 1));
+        break;
+      }
+      // string version = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Api.version");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_version();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // .google.protobuf.SourceContext source_context = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::SourceContext::_InternalParse;
+        object = msg->mutable_source_context();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated .google.protobuf.Mixin mixins = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::Mixin::_InternalParse;
+          object = msg->add_mixins();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 50 && (ptr += 1));
+        break;
+      }
+      // .google.protobuf.Syntax syntax = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::Syntax value = static_cast<::google::protobuf::Syntax>(val);
+        msg->set_syntax(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Api::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Api)
   for (;;) {
@@ -332,8 +453,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -348,8 +468,7 @@
 
       // repeated .google.protobuf.Method methods = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_methods()));
         } else {
@@ -360,8 +479,7 @@
 
       // repeated .google.protobuf.Option options = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_options()));
         } else {
@@ -372,8 +490,7 @@
 
       // string version = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_version()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -388,8 +505,7 @@
 
       // .google.protobuf.SourceContext source_context = 5;
       case 5: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_source_context()));
         } else {
@@ -400,8 +516,7 @@
 
       // repeated .google.protobuf.Mixin mixins = 6;
       case 6: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_mixins()));
         } else {
@@ -412,8 +527,7 @@
 
       // .google.protobuf.Syntax syntax = 7;
       case 7: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (56 & 0xFF)) {
           int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -444,6 +558,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Api::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -492,7 +607,7 @@
   // .google.protobuf.SourceContext source_context = 5;
   if (this->has_source_context()) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      5, this->_internal_source_context(), output);
+      5, HasBitSetters::source_context(this), output);
   }
 
   // repeated .google.protobuf.Mixin mixins = 6;
@@ -510,9 +625,9 @@
       7, this->syntax(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Api)
 }
@@ -566,7 +681,7 @@
   if (this->has_source_context()) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        5, this->_internal_source_context(), deterministic, target);
+        5, HasBitSetters::source_context(this), deterministic, target);
   }
 
   // repeated .google.protobuf.Mixin mixins = 6;
@@ -583,9 +698,9 @@
       7, this->syntax(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Api)
   return target;
@@ -595,11 +710,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Api)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.Method methods = 2;
   {
     unsigned int count = static_cast<unsigned int>(this->methods_size());
@@ -669,7 +788,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Api)
   GOOGLE_DCHECK_NE(&from, this);
   const Api* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Api>(
+      ::google::protobuf::DynamicCastToGenerated<Api>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Api)
@@ -730,6 +849,7 @@
 }
 void Api::InternalSwap(Api* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   CastToBase(&methods_)->InternalSwap(CastToBase(&other->methods_));
   CastToBase(&options_)->InternalSwap(CastToBase(&other->options_));
   CastToBase(&mixins_)->InternalSwap(CastToBase(&other->mixins_));
@@ -739,12 +859,11 @@
     GetArenaNoVirtual());
   swap(source_context_, other->source_context_);
   swap(syntax_, other->syntax_);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata Api::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fapi_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fapi_2eproto[kIndexInFileMessages];
 }
 
 
@@ -752,6 +871,10 @@
 
 void Method::InitAsDefaultInstance() {
 }
+class Method::HasBitSetters {
+ public:
+};
+
 void Method::clear_options() {
   options_.Clear();
 }
@@ -767,8 +890,6 @@
 
 Method::Method()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Method.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Method)
 }
@@ -796,6 +917,8 @@
 }
 
 void Method::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Method_google_2fprotobuf_2fapi_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   request_type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   response_type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -818,13 +941,8 @@
 void Method::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Method::descriptor() {
-  ::protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Method& Method::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Method.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Method_google_2fprotobuf_2fapi_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -845,9 +963,142 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Method::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Method*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Method.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // string request_type_url = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Method.request_type_url");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_request_type_url();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // bool request_streaming = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_request_streaming(value);
+        break;
+      }
+      // string response_type_url = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Method.response_type_url");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_response_type_url();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // bool response_streaming = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_response_streaming(value);
+        break;
+      }
+      // repeated .google.protobuf.Option options = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::Option::_InternalParse;
+          object = msg->add_options();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 50 && (ptr += 1));
+        break;
+      }
+      // .google.protobuf.Syntax syntax = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::Syntax value = static_cast<::google::protobuf::Syntax>(val);
+        msg->set_syntax(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Method::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Method)
   for (;;) {
@@ -857,8 +1108,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -873,8 +1123,7 @@
 
       // string request_type_url = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_request_type_url()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -889,8 +1138,7 @@
 
       // bool request_streaming = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
@@ -903,8 +1151,7 @@
 
       // string response_type_url = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_response_type_url()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -919,8 +1166,7 @@
 
       // bool response_streaming = 5;
       case 5: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
@@ -933,8 +1179,7 @@
 
       // repeated .google.protobuf.Option options = 6;
       case 6: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_options()));
         } else {
@@ -945,8 +1190,7 @@
 
       // .google.protobuf.Syntax syntax = 7;
       case 7: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (56 & 0xFF)) {
           int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -977,6 +1221,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Method::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -1039,9 +1284,9 @@
       7, this->syntax(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Method)
 }
@@ -1110,9 +1355,9 @@
       7, this->syntax(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Method)
   return target;
@@ -1122,11 +1367,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Method)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.Option options = 6;
   {
     unsigned int count = static_cast<unsigned int>(this->options_size());
@@ -1184,7 +1433,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Method)
   GOOGLE_DCHECK_NE(&from, this);
   const Method* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Method>(
+      ::google::protobuf::DynamicCastToGenerated<Method>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Method)
@@ -1250,6 +1499,7 @@
 }
 void Method::InternalSwap(Method* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   CastToBase(&options_)->InternalSwap(CastToBase(&other->options_));
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
@@ -1260,12 +1510,11 @@
   swap(request_streaming_, other->request_streaming_);
   swap(response_streaming_, other->response_streaming_);
   swap(syntax_, other->syntax_);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata Method::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fapi_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fapi_2eproto[kIndexInFileMessages];
 }
 
 
@@ -1273,6 +1522,10 @@
 
 void Mixin::InitAsDefaultInstance() {
 }
+class Mixin::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Mixin::kNameFieldNumber;
 const int Mixin::kRootFieldNumber;
@@ -1280,8 +1533,6 @@
 
 Mixin::Mixin()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Mixin.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Mixin)
 }
@@ -1301,6 +1552,8 @@
 }
 
 void Mixin::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Mixin_google_2fprotobuf_2fapi_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   root_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
@@ -1318,13 +1571,8 @@
 void Mixin::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Mixin::descriptor() {
-  ::protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Mixin& Mixin::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fapi_2eproto::scc_info_Mixin.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Mixin_google_2fprotobuf_2fapi_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -1340,9 +1588,80 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Mixin::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Mixin*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Mixin.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // string root = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Mixin.root");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_root();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Mixin::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Mixin)
   for (;;) {
@@ -1352,8 +1671,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1368,8 +1686,7 @@
 
       // string root = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_root()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1401,6 +1718,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Mixin::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -1428,9 +1746,9 @@
       2, this->root(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Mixin)
 }
@@ -1464,9 +1782,9 @@
         2, this->root(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Mixin)
   return target;
@@ -1476,11 +1794,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Mixin)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     total_size += 1 +
@@ -1504,7 +1826,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Mixin)
   GOOGLE_DCHECK_NE(&from, this);
   const Mixin* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Mixin>(
+      ::google::protobuf::DynamicCastToGenerated<Mixin>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Mixin)
@@ -1556,16 +1878,16 @@
 }
 void Mixin::InternalSwap(Mixin* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   root_.Swap(&other->root_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata Mixin::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fapi_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fapi_2eproto[kIndexInFileMessages];
 }
 
 
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h
index 581e21a..5af8aaf 100644
--- a/src/google/protobuf/api.pb.h
+++ b/src/google/protobuf/api.pb.h
@@ -4,18 +4,18 @@
 #ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto
 #define PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto
 
+#include <limits>
 #include <string>
 
 #include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 3006001
+#if GOOGLE_PROTOBUF_VERSION < 3006000
 #error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please update
+#error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
 #if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
 #error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please
+#error incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.
 #endif
 
@@ -33,20 +33,22 @@
 #include <google/protobuf/source_context.pb.h>
 #include <google/protobuf/type.pb.h>
 // @@protoc_insertion_point(includes)
-#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fapi_2eproto LIBPROTOBUF_EXPORT
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fapi_2eproto LIBPROTOBUF_EXPORT
 
-namespace protobuf_google_2fprotobuf_2fapi_2eproto {
 // Internal implementation detail -- do not use these members.
-struct LIBPROTOBUF_EXPORT TableStruct {
-  static const ::google::protobuf::internal::ParseTableField entries[];
-  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
-  static const ::google::protobuf::internal::ParseTable schema[3];
+struct LIBPROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fapi_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[3]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
   static const ::google::protobuf::uint32 offsets[];
 };
-void LIBPROTOBUF_EXPORT AddDescriptors();
-}  // namespace protobuf_google_2fprotobuf_2fapi_2eproto
+void LIBPROTOBUF_EXPORT AddDescriptors_google_2fprotobuf_2fapi_2eproto();
 namespace google {
 namespace protobuf {
 class Api;
@@ -58,10 +60,6 @@
 class Mixin;
 class MixinDefaultTypeInternal;
 LIBPROTOBUF_EXPORT extern MixinDefaultTypeInternal _Mixin_default_instance_;
-}  // namespace protobuf
-}  // namespace google
-namespace google {
-namespace protobuf {
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::Api* Arena::CreateMaybeMessage<::google::protobuf::Api>(Arena*);
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::Method* Arena::CreateMaybeMessage<::google::protobuf::Method>(Arena*);
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::Mixin* Arena::CreateMaybeMessage<::google::protobuf::Mixin>(Arena*);
@@ -98,7 +96,9 @@
     return *this;
   }
   #endif
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Api& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -131,8 +131,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -227,9 +232,6 @@
   bool has_source_context() const;
   void clear_source_context();
   static const int kSourceContextFieldNumber = 5;
-  private:
-  const ::google::protobuf::SourceContext& _internal_source_context() const;
-  public:
   const ::google::protobuf::SourceContext& source_context() const;
   ::google::protobuf::SourceContext* release_source_context();
   ::google::protobuf::SourceContext* mutable_source_context();
@@ -243,6 +245,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Api)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method > methods_;
@@ -253,7 +256,7 @@
   ::google::protobuf::SourceContext* source_context_;
   int syntax_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -283,7 +286,9 @@
     return *this;
   }
   #endif
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Method& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -316,8 +321,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -418,6 +428,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Method)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
@@ -428,7 +439,7 @@
   bool response_streaming_;
   int syntax_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -458,7 +469,9 @@
     return *this;
   }
   #endif
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Mixin& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -491,8 +504,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -549,12 +567,13 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Mixin)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::internal::ArenaStringPtr root_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto;
 };
 // ===================================================================
 
@@ -734,9 +753,6 @@
 inline bool Api::has_source_context() const {
   return this != internal_default_instance() && source_context_ != NULL;
 }
-inline const ::google::protobuf::SourceContext& Api::_internal_source_context() const {
-  return *source_context_;
-}
 inline const ::google::protobuf::SourceContext& Api::source_context() const {
   const ::google::protobuf::SourceContext* p = source_context_;
   // @@protoc_insertion_point(field_get:google.protobuf.Api.source_context)
@@ -1179,4 +1195,5 @@
 
 // @@protoc_insertion_point(global_scope)
 
+#include <google/protobuf/port_undef.inc>
 #endif  // PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto
diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc
index c117c9e..1d81c32 100644
--- a/src/google/protobuf/arena.cc
+++ b/src/google/protobuf/arena.cc
@@ -38,12 +38,12 @@
 #include <sanitizer/asan_interface.h>
 #endif  // ADDRESS_SANITIZER
 
-#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/port_def.inc>
 
-namespace google {
 static const size_t kMinCleanupListElements = 8;
 static const size_t kMaxCleanupListElements = 64;  // 1kB on 64-bit.
 
+namespace google {
 namespace protobuf {
 namespace internal {
 
@@ -187,8 +187,8 @@
   GetSerialArena()->AddCleanup(elem, cleanup);
 }
 
-inline GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
-bool ArenaImpl::GetSerialArenaFast(ArenaImpl::SerialArena** arena) {
+inline GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE bool
+ArenaImpl::GetSerialArenaFast(ArenaImpl::SerialArena** arena) {
   // If this thread already owns a block in this arena then try to use that.
   // This fast path optimizes the case where multiple threads allocate from the
   // same arena.
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index 9928c8e..53099ff 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -49,22 +49,25 @@
 #endif
 
 #include <google/protobuf/arena_impl.h>
-#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/port.h>
 #include <type_traits>
 
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 
 struct ArenaOptions;  // defined below
 
 }  // namespace protobuf
+}  // namespace google
 
-namespace quality_webanswers {
 
-void TempPrivateWorkAround(::google::protobuf::ArenaOptions* arena_options);
-
-}  // namespace quality_webanswers
-
+namespace google {
 namespace protobuf {
 
 class Arena;          // defined below
@@ -73,7 +76,7 @@
 
 namespace arena_metrics {
 
-void EnableArenaMetrics(::google::protobuf::ArenaOptions* options);
+void EnableArenaMetrics(ArenaOptions* options);
 
 }  // namespace arena_metrics
 
@@ -177,15 +180,14 @@
   static const size_t kDefaultStartBlockSize = 256;
   static const size_t kDefaultMaxBlockSize = 8192;
 
-  friend void ::google::protobuf::arena_metrics::EnableArenaMetrics(ArenaOptions*);
-  friend void quality_webanswers::TempPrivateWorkAround(ArenaOptions*);
+  friend void arena_metrics::EnableArenaMetrics(ArenaOptions*);
   friend class Arena;
   friend class ArenaOptionsTestFriend;
 };
 
 // Support for non-RTTI environments. (The metrics hooks API uses type
 // information.)
-#ifndef GOOGLE_PROTOBUF_NO_RTTI
+#if GOOGLE_PROTOBUF_RTTI
 #define RTTI_TYPE_ID(type) (&typeid(type))
 #else
 #define RTTI_TYPE_ID(type) (NULL)
@@ -216,7 +218,7 @@
 //
 // - The type T must have (at least) two constructors: a constructor with no
 //   arguments, called when a T is allocated on the heap; and a constructor with
-//   a google::protobuf::Arena* argument, called when a T is allocated on an arena. If the
+//   a Arena* argument, called when a T is allocated on an arena. If the
 //   second constructor is called with a NULL arena pointer, it must be
 //   equivalent to invoking the first (no-argument) constructor.
 //
@@ -237,7 +239,9 @@
 //   arg1, arg2).
 //
 // This protocol is implemented by all arena-enabled proto2 message classes as
-// well as RepeatedPtrField.
+// well as protobuf container types like RepeatedPtrField and Map. The protocol
+// is internal to protobuf and is not guaranteed to be stable. Non-proto types
+// should not rely on this protocol.
 //
 // Do NOT subclass Arena. This class will be marked as final when C++11 is
 // enabled.
@@ -319,7 +323,7 @@
   // is obtained from the arena).
   template <typename T, typename... Args>
   GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static T* Create(Arena* arena,
-                                                           Args&&... args) {
+                                                            Args&&... args) {
     return CreateNoMessage<T>(arena, is_arena_constructable<T>(),
                               std::forward<Args>(args)...);
   }
@@ -359,7 +363,8 @@
   //
   // Combines SpaceAllocated and SpaceUsed. Returns a pair of
   // <space_allocated, space_used>.
-  PROTOBUF_RUNTIME_DEPRECATED("Please use SpaceAllocated() and SpaceUsed()")
+  GOOGLE_PROTOBUF_DEPRECATED_MSG(
+      "Please use SpaceAllocated() and SpaceUsed()")
   std::pair<uint64, uint64> SpaceAllocatedAndUsed() const {
     return std::make_pair(SpaceAllocated(), SpaceUsed());
   }
@@ -602,8 +607,8 @@
   }
 
   // CreateInArenaStorage is used to implement map field. Without it,
-  // google::protobuf::Map need to call generated message's protected arena constructor,
-  // which needs to declare google::protobuf::Map as friend of generated message.
+  // Map need to call generated message's protected arena constructor,
+  // which needs to declare Map as friend of generated message.
   template <typename T>
   static void CreateInArenaStorage(T* ptr, Arena* arena) {
     CreateInArenaStorageInternal(ptr, arena,
@@ -635,19 +640,19 @@
 
   // These implement Own(), which registers an object for deletion (destructor
   // call and operator delete()). The second parameter has type 'true_type' if T
-  // is a subtype of ::google::protobuf::Message and 'false_type' otherwise. Collapsing
+  // is a subtype of Message and 'false_type' otherwise. Collapsing
   // all template instantiations to one for generic Message reduces code size,
   // using the virtual destructor instead.
   template <typename T>
   GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void OwnInternal(T* object,
-                                                           std::true_type) {
+                                                            std::true_type) {
     if (object != NULL) {
       impl_.AddCleanup(object, &internal::arena_delete_object<Message>);
     }
   }
   template <typename T>
   GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void OwnInternal(T* object,
-                                                           std::false_type) {
+                                                            std::false_type) {
     if (object != NULL) {
       impl_.AddCleanup(object, &internal::arena_delete_object<T>);
     }
@@ -698,6 +703,8 @@
 #undef RTTI_TYPE_ID
 
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_ARENA_H__
diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h
index f648f16..0b71819 100644
--- a/src/google/protobuf/arena_impl.h
+++ b/src/google/protobuf/arena_impl.h
@@ -39,14 +39,14 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
 
-#include <google/protobuf/stubs/port.h>
-
 #ifdef ADDRESS_SANITIZER
 #include <sanitizer/asan_interface.h>
 #endif  // ADDRESS_SANITIZER
 
-namespace google {
+#include <google/protobuf/port_def.inc>
 
+
+namespace google {
 namespace protobuf {
 namespace internal {
 
@@ -316,6 +316,8 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_ARENA_IMPL_H__
diff --git a/src/google/protobuf/arena_test_util.h b/src/google/protobuf/arena_test_util.h
index df56ece..9c821b9 100644
--- a/src/google/protobuf/arena_test_util.h
+++ b/src/google/protobuf/arena_test_util.h
@@ -48,9 +48,8 @@
   for (int i = start; i < s.size(); i += stride) {
     for (int c = 1 + (i % 17); c < 256; c += 2 * c + (i & 3)) {
       s[i] ^= c;
-      google::protobuf::Arena arena;
-      T* message =
-          google::protobuf::Arena::CreateMessage<T>(use_arena ? &arena : nullptr);
+      Arena arena;
+      T* message = Arena::CreateMessage<T>(use_arena ? &arena : nullptr);
       if (message->ParseFromString(s)) {
         ++success_count;
       }
@@ -86,6 +85,6 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__
diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc
index eaaffce..92e5c84 100644
--- a/src/google/protobuf/arena_unittest.cc
+++ b/src/google/protobuf/arena_unittest.cc
@@ -52,18 +52,19 @@
 #include <google/protobuf/message.h>
 #include <google/protobuf/message_lite.h>
 #include <google/protobuf/repeated_field.h>
-#include <google/protobuf/wire_format_lite.h>
 #include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/wire_format_lite.h>
 #include <gtest/gtest.h>
 
 
-namespace google {
+
 using proto2_arena_unittest::ArenaMessage;
 using protobuf_unittest::TestAllTypes;
 using protobuf_unittest::TestAllExtensions;
 using protobuf_unittest::TestOneof2;
 using protobuf_unittest::TestEmptyMessage;
 
+namespace google {
 namespace protobuf {
 
 class Notifier {
@@ -279,7 +280,7 @@
   options.initial_block_size = arena_block.size();
   Arena arena(options);
 
-  char* p = ::google::protobuf::Arena::CreateArray<char>(&arena, 96);
+  char* p = Arena::CreateArray<char>(&arena, 96);
   uintptr_t allocation = reinterpret_cast<uintptr_t>(p);
 
   // Ensure that the arena allocator did not return memory pointing into the
@@ -585,7 +586,7 @@
   delete nested_string;
 }
 
-#ifndef GOOGLE_PROTOBUF_NO_RTTI
+#if GOOGLE_PROTOBUF_RTTI
 TEST(ArenaTest, ReleaseFromArenaMessageUsingReflectionMakesCopy) {
   TestAllTypes::NestedMessage* nested_msg = NULL;
   // Note: no string: reflection API only supports releasing submessages.
@@ -602,7 +603,7 @@
   EXPECT_EQ(42, nested_msg->bb());
   delete nested_msg;
 }
-#endif  // !GOOGLE_PROTOBUF_NO_RTTI
+#endif  // GOOGLE_PROTOBUF_RTTI
 
 TEST(ArenaTest, SetAllocatedAcrossArenas) {
   Arena arena1;
@@ -1128,7 +1129,7 @@
 }
 
 
-#ifndef GOOGLE_PROTOBUF_NO_RTTI
+#if GOOGLE_PROTOBUF_RTTI
 TEST(ArenaTest, MutableMessageReflection) {
   Arena arena;
   TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
@@ -1152,7 +1153,7 @@
   EXPECT_EQ(submessage_expected, submessage);
   EXPECT_EQ(&arena, submessage->GetArena());
 }
-#endif  // !GOOGLE_PROTOBUF_NO_RTTI
+#endif  // GOOGLE_PROTOBUF_RTTI
 
 
 void FillArenaAwareFields(TestAllTypes* message) {
@@ -1198,7 +1199,7 @@
   TestParseCorruptedString<TestAllTypes, false>(message);
 }
 
-#ifndef GOOGLE_PROTOBUF_NO_RTTI
+#if GOOGLE_PROTOBUF_RTTI
 // Test construction on an arena via generic MessageLite interface. We should be
 // able to successfully deserialize on the arena without incurring heap
 // allocations, i.e., everything should still be arena-allocation-aware.
@@ -1208,7 +1209,7 @@
   options.initial_block = &arena_block[0];
   options.initial_block_size = arena_block.size();
   Arena arena(options);
-  const google::protobuf::MessageLite* prototype = &TestAllTypes::default_instance();
+  const MessageLite* prototype = &TestAllTypes::default_instance();
 
   TestAllTypes initial_message;
   FillArenaAwareFields(&initial_message);
@@ -1217,7 +1218,7 @@
 
   {
 
-    google::protobuf::MessageLite* generic_message = prototype->New(&arena);
+    MessageLite* generic_message = prototype->New(&arena);
     EXPECT_TRUE(generic_message != NULL);
     EXPECT_EQ(&arena, generic_message->GetArena());
     EXPECT_TRUE(generic_message->ParseFromString(serialized));
@@ -1227,7 +1228,7 @@
 
   arena.Reset();
 }
-#endif  // !GOOGLE_PROTOBUF_NO_RTTI
+#endif  // GOOGLE_PROTOBUF_RTTI
 
 
 // RepeatedField should support non-POD types, and invoke constructors and
@@ -1260,7 +1261,7 @@
   EXPECT_EQ(0, arena_1.SpaceAllocated());
   EXPECT_EQ(0, arena_1.SpaceUsed());
   EXPECT_EQ(0, arena_1.Reset());
-  ::google::protobuf::Arena::CreateArray<char>(&arena_1, 320);
+  Arena::CreateArray<char>(&arena_1, 320);
   // Arena will allocate slightly more than 320 for the block headers.
   EXPECT_LE(320, arena_1.SpaceAllocated());
   EXPECT_EQ(Align8(320), arena_1.SpaceUsed());
@@ -1274,7 +1275,7 @@
   EXPECT_EQ(1024, arena_2.SpaceAllocated());
   EXPECT_EQ(0, arena_2.SpaceUsed());
   EXPECT_EQ(1024, arena_2.Reset());
-  ::google::protobuf::Arena::CreateArray<char>(&arena_2, 55);
+  Arena::CreateArray<char>(&arena_2, 55);
   EXPECT_EQ(1024, arena_2.SpaceAllocated());
   EXPECT_EQ(Align8(55), arena_2.SpaceUsed());
   EXPECT_EQ(1024, arena_2.Reset());
@@ -1284,41 +1285,41 @@
   options.initial_block_size = 0;
   Arena arena_3(options);
   EXPECT_EQ(0, arena_3.SpaceUsed());
-  ::google::protobuf::Arena::CreateArray<char>(&arena_3, 160);
+  Arena::CreateArray<char>(&arena_3, 160);
   EXPECT_EQ(256, arena_3.SpaceAllocated());
   EXPECT_EQ(Align8(160), arena_3.SpaceUsed());
-  ::google::protobuf::Arena::CreateArray<char>(&arena_3, 70);
+  Arena::CreateArray<char>(&arena_3, 70);
   EXPECT_EQ(256 + 512, arena_3.SpaceAllocated());
   EXPECT_EQ(Align8(160) + Align8(70), arena_3.SpaceUsed());
   EXPECT_EQ(256 + 512, arena_3.Reset());
 }
 
 TEST(ArenaTest, Alignment) {
-  ::google::protobuf::Arena arena;
+  Arena arena;
   for (int i = 0; i < 200; i++) {
-    void* p = ::google::protobuf::Arena::CreateArray<char>(&arena, i);
+    void* p = Arena::CreateArray<char>(&arena, i);
     GOOGLE_CHECK_EQ(reinterpret_cast<uintptr_t>(p) % 8, 0) << i << ": " << p;
   }
 }
 
 TEST(ArenaTest, BlockSizeSmallerThanAllocation) {
   for (size_t i = 0; i <= 8; ++i) {
-    ::google::protobuf::ArenaOptions opt;
+    ArenaOptions opt;
     opt.start_block_size = opt.max_block_size = i;
-    ::google::protobuf::Arena arena(opt);
+    Arena arena(opt);
 
-    *::google::protobuf::Arena::Create<int64>(&arena) = 42;
+    *Arena::Create<int64>(&arena) = 42;
     EXPECT_GE(arena.SpaceAllocated(), 8);
     EXPECT_EQ(8, arena.SpaceUsed());
 
-    *::google::protobuf::Arena::Create<int64>(&arena) = 42;
+    *Arena::Create<int64>(&arena) = 42;
     EXPECT_GE(arena.SpaceAllocated(), 16);
     EXPECT_EQ(16, arena.SpaceUsed());
   }
 }
 
 TEST(ArenaTest, GetArenaShouldReturnTheArenaForArenaAllocatedMessages) {
-  ::google::protobuf::Arena arena;
+  Arena arena;
   ArenaMessage* message = Arena::CreateMessage<ArenaMessage>(&arena);
   const ArenaMessage* const_pointer_to_message = message;
   EXPECT_EQ(&arena, Arena::GetArena(message));
@@ -1333,14 +1334,14 @@
 }
 
 TEST(ArenaTest, AddCleanup) {
-  ::google::protobuf::Arena arena;
+  Arena arena;
   for (int i = 0; i < 100; i++) {
     arena.Own(new int);
   }
 }
 
 TEST(ArenaTest, UnsafeSetAllocatedOnArena) {
-  ::google::protobuf::Arena arena;
+  Arena arena;
   TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
   EXPECT_FALSE(message->has_optional_string());
 
@@ -1357,7 +1358,7 @@
 // value to be verified.
 class ArenaHooksTestUtil {
  public:
-  static void* on_init(::google::protobuf::Arena* arena) {
+  static void* on_init(Arena* arena) {
     ++num_init;
     int* cookie = new int(kCookieValue);
     return static_cast<void*>(cookie);
@@ -1370,15 +1371,13 @@
     EXPECT_EQ(kCookieValue, cookie_value);
   }
 
-  static void on_reset(::google::protobuf::Arena* arena, void* cookie,
-                       uint64 space_used) {
+  static void on_reset(Arena* arena, void* cookie, uint64 space_used) {
     ++num_reset;
     int cookie_value = *static_cast<int*>(cookie);
     EXPECT_EQ(kCookieValue, cookie_value);
   }
 
-  static void on_destruction(::google::protobuf::Arena* arena, void* cookie,
-                             uint64 space_used) {
+  static void on_destruction(Arena* arena, void* cookie, uint64 space_used) {
     ++num_destruct;
     int cookie_value = *static_cast<int*>(cookie);
     EXPECT_EQ(kCookieValue, cookie_value);
@@ -1399,7 +1398,7 @@
 
 class ArenaOptionsTestFriend {
  public:
-  static void Set(::google::protobuf::ArenaOptions* options) {
+  static void Set(ArenaOptions* options) {
     options->on_arena_init = ArenaHooksTestUtil::on_init;
     options->on_arena_allocation = ArenaHooksTestUtil::on_allocation;
     options->on_arena_reset = ArenaHooksTestUtil::on_reset;
@@ -1409,15 +1408,15 @@
 
 // Test the hooks are correctly called and that the cookie is passed.
 TEST(ArenaTest, ArenaHooksSanity) {
-  ::google::protobuf::ArenaOptions options;
+  ArenaOptions options;
   ArenaOptionsTestFriend::Set(&options);
 
   // Scope for defining the arena
   {
-    ::google::protobuf::Arena arena(options);
+    Arena arena(options);
     EXPECT_EQ(1, ArenaHooksTestUtil::num_init);
     EXPECT_EQ(0, ArenaHooksTestUtil::num_allocations);
-    ::google::protobuf::Arena::Create<uint64>(&arena);
+    Arena::Create<uint64>(&arena);
     if (std::is_trivially_destructible<uint64>::value) {
       EXPECT_EQ(1, ArenaHooksTestUtil::num_allocations);
     } else {
diff --git a/src/google/protobuf/arenastring_unittest.cc b/src/google/protobuf/arenastring_unittest.cc
index adc44fe..c5f89a7 100644
--- a/src/google/protobuf/arenastring_unittest.cc
+++ b/src/google/protobuf/arenastring_unittest.cc
@@ -45,11 +45,12 @@
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 
 
-namespace google {
-using google::protobuf::internal::ArenaStringPtr;
 
+namespace google {
 namespace protobuf {
 
+using internal::ArenaStringPtr;
+
 
 static string WrapString(const char* value) {
   return value;
@@ -81,7 +82,7 @@
 }
 
 TEST(ArenaStringPtrTest, ArenaStringPtrOnArena) {
-  google::protobuf::Arena arena;
+  Arena arena;
   ArenaStringPtr field;
   ::std::string default_value = "default";
   field.UnsafeSetDefault(&default_value);
@@ -107,7 +108,7 @@
 }
 
 TEST(ArenaStringPtrTest, ArenaStringPtrOnArenaNoSSO) {
-  google::protobuf::Arena arena;
+  Arena arena;
   ArenaStringPtr field;
   ::std::string default_value = "default";
   field.UnsafeSetDefault(&default_value);
diff --git a/src/google/protobuf/compiler/annotation_test_util.h b/src/google/protobuf/compiler/annotation_test_util.h
index 90bd88b..34c3f6a 100644
--- a/src/google/protobuf/compiler/annotation_test_util.h
+++ b/src/google/protobuf/compiler/annotation_test_util.h
@@ -77,7 +77,7 @@
 bool DecodeMetadata(const string& path, GeneratedCodeInfo* info);
 
 // Finds all of the Annotations for a given source file and path.
-// See Location.path in http://google/protobuf/descriptor.proto for
+// See Location.path in http://google3/net/proto2/proto/descriptor.proto for
 // explanation of what path vector is.
 void FindAnnotationsOnPath(
     const GeneratedCodeInfo& info, const string& source_file,
@@ -87,7 +87,7 @@
 // Finds the Annotation for a given source file and path (or returns null if it
 // couldn't). If there are several annotations for given path, returns the first
 // one. See Location.path in
-// http://google/protobuf/descriptor.proto for explanation of what path
+// http://google3/net/proto2/proto/descriptor.proto for explanation of what path
 // vector is.
 const GeneratedCodeInfo::Annotation* FindAnnotationOnPath(
     const GeneratedCodeInfo& info, const string& source_file,
@@ -109,6 +109,6 @@
 }  // namespace annotation_test_util
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_ANNOTATION_TEST_UTIL_H__
diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h
index 4c2b3ee..a1cd611 100644
--- a/src/google/protobuf/compiler/code_generator.h
+++ b/src/google/protobuf/compiler/code_generator.h
@@ -171,6 +171,6 @@
 
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index a1f3baf..8005677 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -396,7 +396,7 @@
  private:
   friend class MemoryOutputStream;
 
-  // map instead of hash_map so that files are written in order (good when
+  // map instead of unordered_map so that files are written in order (good when
   // writing zips).
   std::map<string, string*> files_;
   const std::vector<const FileDescriptor*>& parsed_files_;
@@ -750,7 +750,7 @@
 
       // Now copy in the data.
       string::size_type data_pos = 0;
-      char* target_ptr = string_as_array(target) + pos;
+      char* target_ptr = ::google::protobuf::string_as_array(target) + pos;
       while (data_pos < data_.size()) {
         // Copy indent.
         memcpy(target_ptr, indent_.data(), indent_.size());
@@ -767,7 +767,7 @@
       }
 
       GOOGLE_CHECK_EQ(target_ptr,
-          string_as_array(target) + pos + data_.size() + indent_size);
+               ::google::protobuf::string_as_array(target) + pos + data_.size() + indent_size);
     }
   }
 }
@@ -989,6 +989,7 @@
   if (!MakeInputsBeProtoPathRelative(source_tree)) {
     return false;
   }
+
   return true;
 }
 
@@ -1040,15 +1041,15 @@
     std::vector<const FileDescriptor*>* parsed_files) {
 
   // Parse each file.
-  for (int i = 0; i < input_files_.size(); i++) {
+  for (const auto& input_file : input_files_) {
     // Import the file.
-    descriptor_pool->AddUnusedImportTrackFile(input_files_[i]);
+    descriptor_pool->AddUnusedImportTrackFile(input_file);
     const FileDescriptor* parsed_file =
-        descriptor_pool->FindFileByName(input_files_[i]);
+        descriptor_pool->FindFileByName(input_file);
     descriptor_pool->ClearUnusedImportTrackFiles();
     if (parsed_file == NULL) {
       if (!descriptor_set_in_names_.empty()) {
-        std::cerr << input_files_[i] << ": " << strerror(ENOENT) << std::endl;
+        std::cerr << input_file << ": " << strerror(ENOENT) << std::endl;
       }
       return false;
     }
@@ -1097,6 +1098,7 @@
   descriptor_set_out_name_.clear();
   dependency_out_name_.clear();
 
+
   mode_ = MODE_COMPILE;
   print_mode_ = PRINT_NONE;
   imports_in_descriptor_set_ = false;
@@ -1105,64 +1107,73 @@
   direct_dependencies_explicitly_set_ = false;
 }
 
-bool CommandLineInterface::MakeInputsBeProtoPathRelative(
-    DiskSourceTree* source_tree) {
-  for (int i = 0; i < input_files_.size(); i++) {
-    // If the input file path is not a physical file path, it must be a virtual
-    // path.
-    if (access(input_files_[i].c_str(), F_OK) < 0) {
+bool CommandLineInterface::MakeProtoProtoPathRelative(
+    DiskSourceTree* source_tree, string* proto) {
+  // If the input file path is not a physical file path, it must be a virtual
+  // path.
+  if (access(proto->c_str(), F_OK) < 0) {
+    string disk_file;
+    if (source_tree->VirtualFileToDiskFile(*proto, &disk_file)) {
+      return true;
+    } else {
+      std::cerr << *proto << ": " << strerror(ENOENT) << std::endl;
+      return false;
+    }
+  }
+  string virtual_file, shadowing_disk_file;
+  switch (source_tree->DiskFileToVirtualFile(
+      *proto, &virtual_file, &shadowing_disk_file)) {
+    case DiskSourceTree::SUCCESS:
+      *proto = virtual_file;
+      break;
+    case DiskSourceTree::SHADOWED:
+      std::cerr << *proto
+                << ": Input is shadowed in the --proto_path by \""
+                << shadowing_disk_file
+                << "\".  Either use the latter file as your input or reorder "
+                   "the --proto_path so that the former file's location "
+                   "comes first." << std::endl;
+      return false;
+    case DiskSourceTree::CANNOT_OPEN:
+      std::cerr << *proto << ": " << strerror(errno) << std::endl;
+      return false;
+    case DiskSourceTree::NO_MAPPING: {
+      // Try to interpret the path as a virtual path.
       string disk_file;
-      if (source_tree->VirtualFileToDiskFile(input_files_[i], &disk_file)) {
-        return true;
+      if (source_tree->VirtualFileToDiskFile(*proto, &disk_file)) {
+       return true;
       } else {
-        std::cerr << input_files_[i] << ": " << strerror(ENOENT) << std::endl;
+        // The input file path can't be mapped to any --proto_path and it also
+        // can't be interpreted as a virtual path.
+        std::cerr
+            << *proto
+            << ": File does not reside within any path "
+               "specified using --proto_path (or -I).  You must specify a "
+               "--proto_path which encompasses this file.  Note that the "
+               "proto_path must be an exact prefix of the .proto file "
+               "names -- protoc is too dumb to figure out when two paths "
+               "(e.g. absolute and relative) are equivalent (it's harder "
+               "than you think)."
+            << std::endl;
         return false;
       }
     }
-    string virtual_file, shadowing_disk_file;
-    switch (source_tree->DiskFileToVirtualFile(
-        input_files_[i], &virtual_file, &shadowing_disk_file)) {
-      case DiskSourceTree::SUCCESS:
-        input_files_[i] = virtual_file;
-        break;
-      case DiskSourceTree::SHADOWED:
-        std::cerr << input_files_[i]
-                  << ": Input is shadowed in the --proto_path by \""
-                  << shadowing_disk_file
-                  << "\".  Either use the latter file as your input or reorder "
-                     "the --proto_path so that the former file's location "
-                     "comes first." << std::endl;
-        return false;
-      case DiskSourceTree::CANNOT_OPEN:
-        std::cerr << input_files_[i] << ": " << strerror(errno) << std::endl;
-        return false;
-      case DiskSourceTree::NO_MAPPING: {
-        // Try to interpret the path as a virtual path.
-        string disk_file;
-        if (source_tree->VirtualFileToDiskFile(input_files_[i], &disk_file)) {
-          return true;
-        } else {
-          // The input file path can't be mapped to any --proto_path and it also
-          // can't be interpreted as a virtual path.
-          std::cerr
-              << input_files_[i]
-              << ": File does not reside within any path "
-                 "specified using --proto_path (or -I).  You must specify a "
-                 "--proto_path which encompasses this file.  Note that the "
-                 "proto_path must be an exact prefix of the .proto file "
-                 "names -- protoc is too dumb to figure out when two paths "
-                 "(e.g. absolute and relative) are equivalent (it's harder "
-                 "than you think)."
-              << std::endl;
-          return false;
-        }
-      }
+  }
+  return true;
+}
+
+bool CommandLineInterface::MakeInputsBeProtoPathRelative(
+    DiskSourceTree* source_tree) {
+  for (auto& input_file : input_files_) {
+    if (!MakeProtoProtoPathRelative(source_tree, &input_file)) {
+      return false;
     }
   }
 
   return true;
 }
 
+
 bool CommandLineInterface::ExpandArgumentFile(const string& file,
                                               std::vector<string>* arguments) {
   // The argument file is searched in the working directory only. We don't
diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h
index 7d3037a..8dba994 100644
--- a/src/google/protobuf/compiler/command_line_interface.h
+++ b/src/google/protobuf/compiler/command_line_interface.h
@@ -38,13 +38,14 @@
 #ifndef GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
 #define GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
 
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/hash.h>
-#include <string>
-#include <vector>
 #include <map>
 #include <set>
+#include <string>
+#include <unordered_map>
 #include <utility>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
 
 namespace google {
 namespace protobuf {
@@ -206,17 +207,21 @@
   class ErrorPrinter;
   class GeneratorContextImpl;
   class MemoryOutputStream;
-  typedef hash_map<string, GeneratorContextImpl*> GeneratorContextMap;
+  typedef std::unordered_map<string, GeneratorContextImpl*> GeneratorContextMap;
 
   // Clear state from previous Run().
   void Clear();
 
+  // Remaps the proto file so that it is relative to one of the ddirectories
+  // in proto_path_.  Returns false if an error occurred.
+  bool MakeProtoProtoPathRelative(DiskSourceTree* source_tree, string* proto);
+
   // Remaps each file in input_files_ so that it is relative to one of the
-  // directories in proto_path_.  Returns false if an error occurred.  This
-  // is only used if inputs_are_proto_path_relative_ is false.
+  // directories in proto_path_.  Returns false if an error occurred.
   bool MakeInputsBeProtoPathRelative(
     DiskSourceTree* source_tree);
 
+
   // Return status for ParseArguments() and InterpretArgument().
   enum ParseArgumentStatus {
     PARSE_ARGUMENT_DONE_AND_CONTINUE,
@@ -430,6 +435,6 @@
 
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index 41eb244..4e6f4af 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -49,6 +49,7 @@
 #include <google/protobuf/compiler/subprocess.h>
 #include <google/protobuf/compiler/code_generator.h>
 #include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/test_util2.h>
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream.h>
@@ -2284,12 +2285,11 @@
     SplitStringUsing(command, " ", &args);
     switch (GetParam()) {
       case PROTO_PATH:
-        args.push_back("--proto_path=" + TestSourceDir());
+        args.push_back("--proto_path=" + TestUtil::TestSourceDir());
         break;
       case DESCRIPTOR_SET_IN:
-        args.push_back(StrCat(
-            "--descriptor_set_in=",
-            unittest_proto_descriptor_set_filename_));
+        args.push_back(StrCat("--descriptor_set_in=",
+                                    unittest_proto_descriptor_set_filename_));
         break;
       default:
         ADD_FAILURE() << "unexpected EncodeDecodeTestMode: " << GetParam();
@@ -2369,30 +2369,34 @@
 };
 
 TEST_P(EncodeDecodeTest, Encode) {
-  RedirectStdinFromFile(TestSourceDir() + "/google/protobuf/"
-    "testdata/text_format_unittest_data_oneof_implemented.txt");
-  EXPECT_TRUE(Run("google/protobuf/unittest.proto "
-                  "--encode=protobuf_unittest.TestAllTypes"));
-  ExpectStdoutMatchesBinaryFile(TestSourceDir() +
-    "/google/protobuf/testdata/golden_message_oneof_implemented");
+  RedirectStdinFromFile(TestUtil::GetTestDataPath(
+      "net/proto2/internal/"
+      "testdata/text_format_unittest_data_oneof_implemented.txt"));
+  EXPECT_TRUE(
+      Run(TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto") +
+          " --encode=protobuf_unittest.TestAllTypes"));
+  ExpectStdoutMatchesBinaryFile(TestUtil::GetTestDataPath(
+      "net/proto2/internal/testdata/golden_message_oneof_implemented"));
   ExpectStderrMatchesText("");
 }
 
 TEST_P(EncodeDecodeTest, Decode) {
-  RedirectStdinFromFile(TestSourceDir() +
-    "/google/protobuf/testdata/golden_message_oneof_implemented");
-  EXPECT_TRUE(Run("google/protobuf/unittest.proto "
-                  "--decode=protobuf_unittest.TestAllTypes"));
-  ExpectStdoutMatchesTextFile(TestSourceDir() +
-    "/google/protobuf/"
-    "testdata/text_format_unittest_data_oneof_implemented.txt");
+  RedirectStdinFromFile(TestUtil::GetTestDataPath(
+      "net/proto2/internal/testdata/golden_message_oneof_implemented"));
+  EXPECT_TRUE(
+      Run(TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto") +
+          " --decode=protobuf_unittest.TestAllTypes"));
+  ExpectStdoutMatchesTextFile(TestUtil::GetTestDataPath(
+      "net/proto2/internal/"
+      "testdata/text_format_unittest_data_oneof_implemented.txt"));
   ExpectStderrMatchesText("");
 }
 
 TEST_P(EncodeDecodeTest, Partial) {
   RedirectStdinFromText("");
-  EXPECT_TRUE(Run("google/protobuf/unittest.proto "
-                  "--encode=protobuf_unittest.TestRequired"));
+  EXPECT_TRUE(
+      Run(TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto") +
+          " --encode=protobuf_unittest.TestRequired"));
   ExpectStdoutMatchesText("");
   ExpectStderrMatchesText(
     "warning:  Input message is missing required fields:  a, b, c\n");
@@ -2413,18 +2417,20 @@
 }
 
 TEST_P(EncodeDecodeTest, UnknownType) {
-  EXPECT_FALSE(Run("google/protobuf/unittest.proto "
-                   "--encode=NoSuchType"));
+  EXPECT_FALSE(
+      Run(TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto") +
+          " --encode=NoSuchType"));
   ExpectStdoutMatchesText("");
   ExpectStderrMatchesText("Type not defined: NoSuchType\n");
 }
 
 TEST_P(EncodeDecodeTest, ProtoParseError) {
-  EXPECT_FALSE(Run("google/protobuf/no_such_file.proto "
-                   "--encode=NoSuchType"));
+  EXPECT_FALSE(
+      Run("net/proto2/internal/no_such_file.proto "
+          "--encode=NoSuchType"));
   ExpectStdoutMatchesText("");
   ExpectStderrMatchesText(
-      "google/protobuf/no_such_file.proto: No such file or directory\n");
+      "net/proto2/internal/no_such_file.proto: No such file or directory\n");
 }
 
 INSTANTIATE_TEST_CASE_P(FileDescriptorSetSource,
diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
index 24f1fe4..4c13564 100644
--- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -32,7 +32,7 @@
 //  Based on original Protocol Buffers design by
 //  Sanjay Ghemawat, Jeff Dean, and others.
 //
-// This test insures that google/protobuf/descriptor.pb.{h,cc} match exactly
+// This test insures that net/proto2/proto/descriptor.pb.{h,cc} match exactly
 // what would be generated by the protocol compiler.  These files are not
 // generated automatically at build time because they are compiled into the
 // protocol compiler itself.  So, if they were auto-generated, you'd have a
@@ -47,6 +47,7 @@
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/compiler/cpp/cpp_generator.h>
 #include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/test_util2.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/stubs/substitute.h>
@@ -83,9 +84,7 @@
 class MockGeneratorContext : public GeneratorContext {
  public:
   MockGeneratorContext() {}
-  ~MockGeneratorContext() {
-    STLDeleteValues(&files_);
-  }
+  ~MockGeneratorContext() { STLDeleteValues(&files_); }
 
   void ExpectFileMatches(const string& virtual_filename,
                          const string& physical_filename) {
@@ -95,9 +94,11 @@
 
     string actual_contents;
     GOOGLE_CHECK_OK(
-        File::GetContentsAsText(TestSourceDir() + "/" + physical_filename,
-                          &actual_contents, true));
-    EXPECT_TRUE(actual_contents == *expected_contents)
+        File::GetContents(TestUtil::TestSourceDir() + "/" + physical_filename,
+                          &actual_contents, true))
+        << physical_filename;
+    CleanStringLineEndings(&actual_contents, false);
+    EXPECT_EQ(*expected_contents, actual_contents)
         << physical_filename
         << " needs to be regenerated.  Please run "
            "generate_descriptor_proto.sh. "
@@ -136,11 +137,11 @@
       "net/proto2/z_generated_example/test_messages_proto2";
   rpath_map["third_party/protobuf/src/google/protobuf/test_messages_proto3"] =
       "net/proto2/z_generated_example/test_messages_proto3";
-  rpath_map["google/protobuf/proto2_weak"] =
+  rpath_map["net/proto2/internal/proto2_weak"] =
       "net/proto2/z_generated_example/proto2_weak";
 
   DiskSourceTree source_tree;
-  source_tree.MapPath("", TestSourceDir());
+  source_tree.MapPath("", TestUtil::TestSourceDir());
 
   for (auto file_parameter : test_protos) {
     MockErrorCollector error_collector;
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc
index 0d6a9e2..39fe9e6 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc
@@ -46,7 +46,7 @@
 
 namespace {
 // The GOOGLE_ARRAYSIZE constant is the max enum value plus 1. If the max enum value
-// is ::google::protobuf::kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the
+// is kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the
 // generation of the GOOGLE_ARRAYSIZE constant.
 bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) {
   int32 max_value = descriptor->value(0)->number();
@@ -55,61 +55,53 @@
       max_value = descriptor->value(i)->number();
     }
   }
-  return max_value != ::google::protobuf::kint32max;
+  return max_value != kint32max;
 }
 }  // namespace
 
 EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
+                             const std::map<string, string>& vars,
                              const Options& options)
-  : descriptor_(descriptor),
-    classname_(ClassName(descriptor, false)),
-    options_(options),
-    generate_array_size_(ShouldGenerateArraySize(descriptor)) {
+    : descriptor_(descriptor),
+      classname_(ClassName(descriptor, false)),
+      options_(options),
+      generate_array_size_(ShouldGenerateArraySize(descriptor)),
+      variables_(vars) {
+  variables_["classname"] = classname_;
+  variables_["classtype"] = QualifiedClassName(descriptor_);
+  variables_["short_name"] = descriptor_->name();
+  variables_["enumbase"] = options_.proto_h ? " : int" : "";
+  variables_["nested_name"] = descriptor_->name();
+  variables_["constexpr"] = options_.proto_h ? "constexpr" : "";
+  variables_["prefix"] =
+      (descriptor_->containing_type() == NULL) ? "" : classname_ + "_";
 }
 
 EnumGenerator::~EnumGenerator() {}
 
-void EnumGenerator::FillForwardDeclaration(
-    std::map<string, const EnumDescriptor*>* enum_names) {
-  if (!options_.proto_h) {
-    return;
-  }
-  (*enum_names)[classname_] = descriptor_;
-}
-
 void EnumGenerator::GenerateDefinition(io::Printer* printer) {
-  std::map<string, string> vars;
-  vars["classname"] = classname_;
-  vars["short_name"] = descriptor_->name();
-  vars["enumbase"] = options_.proto_h ? " : int" : "";
-  // These variables are placeholders to pick out the beginning and ends of
-  // identifiers for annotations (when doing so with existing variables would
-  // be ambiguous or impossible). They should never be set to anything but the
-  // empty string.
-  vars["{"] = "";
-  vars["}"] = "";
-
-  printer->Print(vars, "enum $classname$$enumbase$ {\n");
-  printer->Annotate("classname", descriptor_);
-  printer->Indent();
+  Formatter format(printer, variables_);
+  format("enum ${1$$classname$$}$$enumbase$ {\n", descriptor_);
+  format.Indent();
 
   const EnumValueDescriptor* min_value = descriptor_->value(0);
   const EnumValueDescriptor* max_value = descriptor_->value(0);
 
   for (int i = 0; i < descriptor_->value_count(); i++) {
-    vars["name"] = EnumValueName(descriptor_->value(i));
+    auto format_value = format;
+    format_value.Set("name", EnumValueName(descriptor_->value(i)));
     // In C++, an value of -2147483648 gets interpreted as the negative of
     // 2147483648, and since 2147483648 can't fit in an integer, this produces a
     // compiler warning.  This works around that issue.
-    vars["number"] = Int32ToString(descriptor_->value(i)->number());
-    vars["prefix"] = (descriptor_->containing_type() == NULL) ?
-      "" : classname_ + "_";
-    vars["deprecation"] = descriptor_->value(i)->options().deprecated() ?
-        " PROTOBUF_DEPRECATED" : "";
+    format_value.Set("number", Int32ToString(descriptor_->value(i)->number()));
+    format_value.Set(
+        "deprecation",
+        DeprecatedAttribute(options_,
+                            descriptor_->value(i)->options().deprecated()));
 
-    if (i > 0) printer->Print(",\n");
-    printer->Print(vars, "${$$prefix$$name$$}$$deprecation$ = $number$");
-    printer->Annotate("{", "}", descriptor_->value(i));
+    if (i > 0) format_value(",\n");
+    format_value("${1$$prefix$$name$$}$ $deprecation$= $number$",
+                 descriptor_->value(i));
 
     if (descriptor_->value(i)->number() < min_value->number()) {
       min_value = descriptor_->value(i);
@@ -122,153 +114,163 @@
   if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
     // For new enum semantics: generate min and max sentinel values equal to
     // INT32_MIN and INT32_MAX
-    if (descriptor_->value_count() > 0) printer->Print(",\n");
-    printer->Print(vars,
-        "$classname$_$prefix$INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,\n"
-        "$classname$_$prefix$INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max");
+    if (descriptor_->value_count() > 0) format(",\n");
+    format(
+        "$classname$_$prefix$INT_MIN_SENTINEL_DO_NOT_USE_ = "
+        "std::numeric_limits<$int32$>::min(),\n"
+        "$classname$_$prefix$INT_MAX_SENTINEL_DO_NOT_USE_ = "
+        "std::numeric_limits<$int32$>::max()");
   }
 
-  printer->Outdent();
-  printer->Print("\n};\n");
+  format.Outdent();
+  format("\n};\n");
 
-  vars["min_name"] = EnumValueName(min_value);
-  vars["max_name"] = EnumValueName(max_value);
-
-  if (options_.dllexport_decl.empty()) {
-    vars["dllexport"] = "";
-  } else {
-    vars["dllexport"] = options_.dllexport_decl + " ";
-  }
-
-  printer->Print(vars,
-                 "$dllexport$bool $classname$_IsValid(int value);\n"
-                 "const $classname$ ${$$prefix$$short_name$_MIN$}$ = "
-                 "$prefix$$min_name$;\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(vars,
-                 "const $classname$ ${$$prefix$$short_name$_MAX$}$ = "
-                 "$prefix$$max_name$;\n");
-  printer->Annotate("{", "}", descriptor_);
+  format(
+      "$dllexport_decl $bool $classname$_IsValid(int value);\n"
+      "const $classname$ ${1$$prefix$$short_name$_MIN$}$ = "
+      "$prefix$$2$;\n"
+      "const $classname$ ${1$$prefix$$short_name$_MAX$}$ = "
+      "$prefix$$3$;\n",
+      descriptor_, EnumValueName(min_value), EnumValueName(max_value));
 
   if (generate_array_size_) {
-    printer->Print(vars,
-                   "const int ${$$prefix$$short_name$_ARRAYSIZE$}$ = "
-                   "$prefix$$short_name$_MAX + 1;\n\n");
-    printer->Annotate("{", "}", descriptor_);
+    format(
+        "const int ${1$$prefix$$short_name$_ARRAYSIZE$}$ = "
+        "$prefix$$short_name$_MAX + 1;\n\n",
+        descriptor_);
   }
 
   if (HasDescriptorMethods(descriptor_->file(), options_)) {
-    printer->Print(vars,
-      "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n");
+    format(
+        "$dllexport_decl $const ::$proto_ns$::EnumDescriptor* "
+        "$classname$_descriptor();\n");
     // The _Name and _Parse methods
-    printer->Print(
-        vars,
-        "inline const ::std::string& $classname$_Name($classname$ value) {\n"
-        "  return ::google::protobuf::internal::NameOfEnum(\n"
-        "    $classname$_descriptor(), value);\n"
+    if (options_.opensource_runtime) {
+      // TODO(haberman): consider removing this in favor of the stricter
+      // version below.  Would this break our compatibility guarantees?
+      format(
+          "inline const $string$& $classname$_Name($classname$ value) {\n"
+          "  return ::$proto_ns$::internal::NameOfEnum(\n"
+          "    $classname$_descriptor(), value);\n"
+          "}\n");
+    } else {
+      // Support a stricter, type-checked enum-to-string method that
+      // statically checks whether the parameter is the exact enum type or is
+      // an integral type.
+      format(
+          "template<typename T>\n"
+          "inline const $string$& $classname$_Name(T enum_t_value) {\n"
+          "  static_assert(::std::is_same<T, $classname$>::value ||\n"
+          "    ::std::is_integral<T>::value,\n"
+          "    \"Incorrect type passed to function $classname$_Name.\");\n"
+          "  return ::$proto_ns$::internal::NameOfEnum(\n"
+          "    $classname$_descriptor(), enum_t_value);\n"
+          "}\n");
+    }
+    format(
+        "inline bool $classname$_Parse(\n"
+        "    const $string$& name, $classname$* value) {\n"
+        "  return ::$proto_ns$::internal::ParseNamedEnum<$classname$>(\n"
+        "    $classname$_descriptor(), name, value);\n"
         "}\n");
-    printer->Print(vars,
-      "inline bool $classname$_Parse(\n"
-      "    const ::std::string& name, $classname$* value) {\n"
-      "  return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n"
-      "    $classname$_descriptor(), name, value);\n"
-      "}\n");
   }
 }
 
-void EnumGenerator::
-GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
-  printer->Print(
-      "template <> struct is_proto_enum< $classname$> : ::std::true_type "
-      "{};\n",
-      "classname", ClassName(descriptor_, true));
+void EnumGenerator::GenerateGetEnumDescriptorSpecializations(
+    io::Printer* printer) {
+  Formatter format(printer, variables_);
+  format(
+      "template <> struct is_proto_enum< $classtype$> : ::std::true_type "
+      "{};\n");
   if (HasDescriptorMethods(descriptor_->file(), options_)) {
-    printer->Print(
-      "template <>\n"
-      "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n"
-      "  return $classname$_descriptor();\n"
-      "}\n",
-      "classname", ClassName(descriptor_, true));
+    format(
+        "template <>\n"
+        "inline const EnumDescriptor* GetEnumDescriptor< $classtype$>() {\n"
+        "  return $classtype$_descriptor();\n"
+        "}\n");
   }
 }
 
-void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
-  std::map<string, string> vars;
-  vars["nested_name"] = descriptor_->name();
-  vars["classname"] = classname_;
-  vars["constexpr"] = options_.proto_h ? "constexpr " : "";
-  vars["{"] = "";
-  vars["}"] = "";
-  printer->Print(vars, "typedef $classname$ $nested_name$;\n");
+void EnumGenerator::GenerateSymbolImports(io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format("typedef $classname$ $nested_name$;\n");
 
   for (int j = 0; j < descriptor_->value_count(); j++) {
-    vars["tag"] = EnumValueName(descriptor_->value(j));
-    vars["deprecated_attr"] = descriptor_->value(j)->options().deprecated() ?
-      "GOOGLE_PROTOBUF_DEPRECATED_ATTR " : "";
-    printer->Print(vars,
-      "$deprecated_attr$static $constexpr$const $nested_name$ ${$$tag$$}$ =\n"
-      "  $classname$_$tag$;\n");
-    printer->Annotate("{", "}", descriptor_->value(j));
+    string deprecated_attr = DeprecatedAttribute(
+        options_, descriptor_->value(j)->options().deprecated());
+    format(
+        "$1$static $constexpr $const $nested_name$ ${2$$3$$}$ =\n"
+        "  $classname$_$3$;\n",
+        deprecated_attr, descriptor_->value(j),
+        EnumValueName(descriptor_->value(j)));
   }
 
-  printer->Print(vars,
-    "static inline bool $nested_name$_IsValid(int value) {\n"
-    "  return $classname$_IsValid(value);\n"
-    "}\n"
-    "static const $nested_name$ ${$$nested_name$_MIN$}$ =\n"
-    "  $classname$_$nested_name$_MIN;\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(vars,
-    "static const $nested_name$ ${$$nested_name$_MAX$}$ =\n"
-    "  $classname$_$nested_name$_MAX;\n");
-  printer->Annotate("{", "}", descriptor_);
+  format(
+      "static inline bool $nested_name$_IsValid(int value) {\n"
+      "  return $classname$_IsValid(value);\n"
+      "}\n"
+      "static const $nested_name$ ${1$$nested_name$_MIN$}$ =\n"
+      "  $classname$_$nested_name$_MIN;\n"
+      "static const $nested_name$ ${1$$nested_name$_MAX$}$ =\n"
+      "  $classname$_$nested_name$_MAX;\n",
+      descriptor_);
   if (generate_array_size_) {
-    printer->Print(vars,
-      "static const int ${$$nested_name$_ARRAYSIZE$}$ =\n"
-      "  $classname$_$nested_name$_ARRAYSIZE;\n");
-    printer->Annotate("{", "}", descriptor_);
+    format(
+        "static const int ${1$$nested_name$_ARRAYSIZE$}$ =\n"
+        "  $classname$_$nested_name$_ARRAYSIZE;\n",
+        descriptor_);
   }
 
   if (HasDescriptorMethods(descriptor_->file(), options_)) {
-    printer->Print(vars,
-      "static inline const ::google::protobuf::EnumDescriptor*\n"
-      "$nested_name$_descriptor() {\n"
-      "  return $classname$_descriptor();\n"
-      "}\n");
-    printer->Print(vars,
-                   "static inline const ::std::string& "
-                   "$nested_name$_Name($nested_name$ value) {"
-                   "\n"
-                   "  return $classname$_Name(value);\n"
-                   "}\n");
-    printer->Print(vars,
-      "static inline bool $nested_name$_Parse(const ::std::string& name,\n"
-      "    $nested_name$* value) {\n"
-      "  return $classname$_Parse(name, value);\n"
-      "}\n");
+    format(
+        "static inline const ::$proto_ns$::EnumDescriptor*\n"
+        "$nested_name$_descriptor() {\n"
+        "  return $classname$_descriptor();\n"
+        "}\n");
+    if (options_.opensource_runtime) {
+      // TODO(haberman): consider removing this in favor of the stricter
+      // version below.  Would this break our compatibility guarantees?
+      format(
+          "static inline const $string$& "
+          "$nested_name$_Name($nested_name$ value) {"
+          "\n"
+          "  return $classname$_Name(value);\n"
+          "}\n");
+    } else {
+      // Support a stricter, type-checked enum-to-string method that
+      // statically checks whether the parameter is the exact enum type or is
+      // an integral type.
+      format(
+          "template<typename T>\n"
+          "static inline const $string$& $nested_name$_Name(T enum_t_value) {\n"
+          "  static_assert(::std::is_same<T, $nested_name$>::value ||\n"
+          "    ::std::is_integral<T>::value,\n"
+          "    \"Incorrect type passed to function $nested_name$_Name.\");\n"
+          "  return $classname$_Name(enum_t_value);\n"
+          "}\n");
+    }
+    format(
+        "static inline bool $nested_name$_Parse(const $string$& name,\n"
+        "    $nested_name$* value) {\n"
+        "  return $classname$_Parse(name, value);\n"
+        "}\n");
   }
 }
 
 void EnumGenerator::GenerateMethods(int idx, io::Printer* printer) {
-  std::map<string, string> vars;
-  vars["classname"] = classname_;
-  vars["index_in_metadata"] = SimpleItoa(idx);
-  vars["constexpr"] = options_.proto_h ? "constexpr " : "";
-  vars["file_namespace"] = FileLevelNamespace(descriptor_->file()->name());
-
+  Formatter format(printer, variables_);
   if (HasDescriptorMethods(descriptor_->file(), options_)) {
-    printer->Print(
-        vars,
-        "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n"
-        "  $file_namespace$::protobuf_AssignDescriptorsOnce();\n"
-        "  return "
-        "$file_namespace$::file_level_enum_descriptors[$index_in_metadata$];\n"
-        "}\n");
+    format(
+        "const ::$proto_ns$::EnumDescriptor* $classname$_descriptor() {\n"
+        "  ::$proto_ns$::internal::AssignDescriptors(&$assign_desc_table$);\n"
+        "  return $file_level_enum_descriptors$[$1$];\n"
+        "}\n",
+        idx);
   }
 
-  printer->Print(vars,
-    "bool $classname$_IsValid(int value) {\n"
-    "  switch (value) {\n");
+  format(
+      "bool $classname$_IsValid(int value) {\n"
+      "  switch (value) {\n");
 
   // Multiple values may have the same number.  Make sure we only cover
   // each number once by first constructing a set containing all valid
@@ -280,44 +282,40 @@
     numbers.insert(value->number());
   }
 
-  for (std::set<int>::iterator iter = numbers.begin();
-       iter != numbers.end(); ++iter) {
-    printer->Print(
-      "    case $number$:\n",
-      "number", Int32ToString(*iter));
+  for (std::set<int>::iterator iter = numbers.begin(); iter != numbers.end();
+       ++iter) {
+    format("    case $1$:\n", Int32ToString(*iter));
   }
 
-  printer->Print(vars,
-    "      return true;\n"
-    "    default:\n"
-    "      return false;\n"
-    "  }\n"
-    "}\n"
-    "\n");
+  format(
+      "      return true;\n"
+      "    default:\n"
+      "      return false;\n"
+      "  }\n"
+      "}\n"
+      "\n");
 
   if (descriptor_->containing_type() != NULL) {
+    string parent = ClassName(descriptor_->containing_type(), false);
     // We need to "define" the static constants which were declared in the
     // header, to give the linker a place to put them.  Or at least the C++
     // standard says we have to.  MSVC actually insists that we do _not_ define
     // them again in the .cc file, prior to VC++ 2015.
-    printer->Print("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n");
+    format("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n");
 
-    vars["parent"] = ClassName(descriptor_->containing_type(), false);
-    vars["nested_name"] = descriptor_->name();
     for (int i = 0; i < descriptor_->value_count(); i++) {
-      vars["value"] = EnumValueName(descriptor_->value(i));
-      printer->Print(vars,
-        "$constexpr$const $classname$ $parent$::$value$;\n");
+      format("$constexpr $const $classname$ $1$::$2$;\n", parent,
+             EnumValueName(descriptor_->value(i)));
     }
-    printer->Print(vars,
-      "const $classname$ $parent$::$nested_name$_MIN;\n"
-      "const $classname$ $parent$::$nested_name$_MAX;\n");
+    format(
+        "const $classname$ $1$::$nested_name$_MIN;\n"
+        "const $classname$ $1$::$nested_name$_MAX;\n",
+        parent);
     if (generate_array_size_) {
-      printer->Print(vars,
-        "const int $parent$::$nested_name$_ARRAYSIZE;\n");
+      format("const int $1$::$nested_name$_ARRAYSIZE;\n", parent);
     }
 
-    printer->Print("#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900\n");
+    format("#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900\n");
   }
 }
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.h b/src/google/protobuf/compiler/cpp/cpp_enum.h
index 0d2488a..55e6b83 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.h
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.h
@@ -46,8 +46,10 @@
   namespace io {
     class Printer;             // printer.h
   }
-}
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace cpp {
@@ -55,20 +57,10 @@
 class EnumGenerator {
  public:
   // See generator.cc for the meaning of dllexport_decl.
-  EnumGenerator(const EnumDescriptor* descriptor, const Options& options);
+  EnumGenerator(const EnumDescriptor* descriptor,
+                const std::map<string, string>& vars, const Options& options);
   ~EnumGenerator();
 
-  // Header stuff.
-
-  // Fills the name to use when declaring the enum. This is for use when
-  // generating other .proto.h files. This code should be placed within the
-  // enum's package namespace, but NOT within any class, even for nested
-  // enums. A given key in enum_names will map from an enum class name to the
-  // EnumDescriptor that was responsible for its inclusion in the map. This can
-  // be used to associate the descriptor with the code generated for it.
-  void FillForwardDeclaration(
-      std::map<string, const EnumDescriptor*>* enum_names);
-
   // Generate header code defining the enum.  This code should be placed
   // within the enum's package namespace, but NOT within any class, even for
   // nested enums.
@@ -82,7 +74,7 @@
   // symbols (e.g. the enum type name, all its values, etc.) into the class's
   // namespace.  This should be placed inside the class definition in the
   // header.
-  void GenerateSymbolImports(io::Printer* printer);
+  void GenerateSymbolImports(io::Printer* printer) const;
 
   // Source file stuff.
 
@@ -98,6 +90,8 @@
   // whether to generate the *_ARRAYSIZE constant.
   const bool generate_array_size_;
 
+  std::map<string, string> variables_;
+
   friend class FileGenerator;
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
 };
@@ -105,6 +99,6 @@
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index 828d0be..a406f2e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -61,457 +61,452 @@
 
 EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor,
                                        const Options& options)
-    : FieldGenerator(options), descriptor_(descriptor) {
+    : FieldGenerator(descriptor, options) {
   SetEnumVariables(descriptor, &variables_, options);
 }
 
 EnumFieldGenerator::~EnumFieldGenerator() {}
 
-void EnumFieldGenerator::
-GeneratePrivateMembers(io::Printer* printer) const {
-  printer->Print(variables_, "int $name$_;\n");
+void EnumFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format("int $name$_;\n");
 }
 
-void EnumFieldGenerator::
-GenerateAccessorDeclarations(io::Printer* printer) const {
-  printer->Print(variables_, "$deprecated_attr$$type$ $name$() const;\n");
-  printer->Annotate("name", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$void ${$set_$name$$}$($type$ value);\n");
-  printer->Annotate("{", "}", descriptor_);
+void EnumFieldGenerator::GenerateAccessorDeclarations(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format(
+      "$deprecated_attr$$type$ ${1$$name$$}$() const;\n"
+      "$deprecated_attr$void ${1$set_$name$$}$($type$ value);\n",
+      descriptor_);
 }
 
-void EnumFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline $type$ $classname$::$name$() const {\n"
-    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
-    "  return static_cast< $type$ >($name$_);\n"
-    "}\n"
-    "inline void $classname$::set_$name$($type$ value) {\n");
+void EnumFieldGenerator::GenerateInlineAccessorDefinitions(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format(
+      "inline $type$ $classname$::$name$() const {\n"
+      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+      "  return static_cast< $type$ >($name$_);\n"
+      "}\n"
+      "inline void $classname$::set_$name$($type$ value) {\n");
   if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
-    printer->Print(variables_,
-    "  assert($type$_IsValid(value));\n");
+    format("  assert($type$_IsValid(value));\n");
   }
-  printer->Print(variables_,
-    "  $set_hasbit$\n"
-    "  $name$_ = value;\n"
-    "  // @@protoc_insertion_point(field_set:$full_name$)\n"
-    "}\n");
-}
-
-void EnumFieldGenerator::
-GenerateClearingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_ = $default$;\n");
-}
-
-void EnumFieldGenerator::
-GenerateMergingCode(io::Printer* printer) const {
-  printer->Print(variables_, "set_$name$(from.$name$());\n");
-}
-
-void EnumFieldGenerator::
-GenerateSwappingCode(io::Printer* printer) const {
-  printer->Print(variables_, "swap($name$_, other->$name$_);\n");
-}
-
-void EnumFieldGenerator::
-GenerateConstructorCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_ = $default$;\n");
-}
-
-void EnumFieldGenerator::
-GenerateCopyConstructorCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_ = from.$name$_;\n");
-}
-
-void EnumFieldGenerator::
-GenerateMergeFromCodedStream(io::Printer* printer) const {
-  printer->Print(variables_,
-    "int value = 0;\n"
-    "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
-    "         int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
-    "       input, &value)));\n");
-  if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
-    printer->Print(variables_,
-      "set_$name$(static_cast< $type$ >(value));\n");
-  } else {
-    printer->Print(variables_,
-      "if ($type$_IsValid(value)) {\n"
-      "  set_$name$(static_cast< $type$ >(value));\n");
-    if (UseUnknownFieldSet(descriptor_->file(), options_)) {
-      printer->Print(variables_,
-        "} else {\n"
-        "  mutable_unknown_fields()->AddVarint(\n"
-        "      $number$, static_cast< ::google::protobuf::uint64>(value));\n");
-    } else {
-      printer->Print(
-        "} else {\n"
-        "  unknown_fields_stream.WriteVarint32($tag$u);\n"
-        "  unknown_fields_stream.WriteVarint32(\n"
-        "      static_cast< ::google::protobuf::uint32>(value));\n",
-        "tag", SimpleItoa(internal::WireFormat::MakeTag(descriptor_)));
-    }
-    printer->Print(variables_,
+  format(
+      "  $set_hasbit$\n"
+      "  $name$_ = value;\n"
+      "  // @@protoc_insertion_point(field_set:$full_name$)\n"
       "}\n");
+}
+
+void EnumFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format("$name$_ = $default$;\n");
+}
+
+void EnumFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format("set_$name$(from.$name$());\n");
+}
+
+void EnumFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format("swap($name$_, other->$name$_);\n");
+}
+
+void EnumFieldGenerator::GenerateConstructorCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format("$name$_ = $default$;\n");
+}
+
+void EnumFieldGenerator::GenerateCopyConstructorCode(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format("$name$_ = from.$name$_;\n");
+}
+
+void EnumFieldGenerator::GenerateMergeFromCodedStream(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format(
+      "int value = 0;\n"
+      "DO_((::$proto_ns$::internal::WireFormatLite::ReadPrimitive<\n"
+      "         int, ::$proto_ns$::internal::WireFormatLite::TYPE_ENUM>(\n"
+      "       input, &value)));\n");
+  if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
+    format("set_$name$(static_cast< $type$ >(value));\n");
+  } else {
+    format(
+        "if ($type$_IsValid(value)) {\n"
+        "  set_$name$(static_cast< $type$ >(value));\n");
+    if (UseUnknownFieldSet(descriptor_->file(), options_)) {
+      format(
+          "} else {\n"
+          "  mutable_unknown_fields()->AddVarint(\n"
+          "      $number$, static_cast<$uint64$>(value));\n");
+    } else {
+      format(
+          "} else {\n"
+          "  unknown_fields_stream.WriteVarint32($1$u);\n"
+          "  unknown_fields_stream.WriteVarint32(\n"
+          "      static_cast<$uint32$>(value));\n",
+          internal::WireFormat::MakeTag(descriptor_));
+    }
+    format("}\n");
   }
 }
 
-void EnumFieldGenerator::
-GenerateSerializeWithCachedSizes(io::Printer* printer) const {
-  printer->Print(variables_,
-    "::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
-    "  $number$, this->$name$(), output);\n");
+void EnumFieldGenerator::GenerateSerializeWithCachedSizes(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format(
+      "::$proto_ns$::internal::WireFormatLite::WriteEnum(\n"
+      "  $number$, this->$name$(), output);\n");
 }
 
-void EnumFieldGenerator::
-GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
-  printer->Print(variables_,
-    "target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
-    "  $number$, this->$name$(), target);\n");
+void EnumFieldGenerator::GenerateSerializeWithCachedSizesToArray(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format(
+      "target = ::$proto_ns$::internal::WireFormatLite::WriteEnumToArray(\n"
+      "  $number$, this->$name$(), target);\n");
 }
 
-void EnumFieldGenerator::
-GenerateByteSize(io::Printer* printer) const {
-  printer->Print(variables_,
-    "total_size += $tag_size$ +\n"
-    "  ::google::protobuf::internal::WireFormatLite::EnumSize(this->$name$());\n");
+void EnumFieldGenerator::GenerateByteSize(io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format(
+      "total_size += $tag_size$ +\n"
+      "  ::$proto_ns$::internal::WireFormatLite::EnumSize(this->$name$());\n");
 }
 
 // ===================================================================
 
-EnumOneofFieldGenerator::
-EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
-                        const Options& options)
-  : EnumFieldGenerator(descriptor, options) {
+EnumOneofFieldGenerator::EnumOneofFieldGenerator(
+    const FieldDescriptor* descriptor, const Options& options)
+    : EnumFieldGenerator(descriptor, options) {
   SetCommonOneofFieldVariables(descriptor, &variables_);
 }
 
 EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {}
 
-void EnumOneofFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline $type$ $classname$::$name$() const {\n"
-    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
-    "  if (has_$name$()) {\n"
-    "    return static_cast< $type$ >($field_member$);\n"
-    "  }\n"
-    "  return static_cast< $type$ >($default$);\n"
-    "}\n"
-    "inline void $classname$::set_$name$($type$ value) {\n");
+void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format(
+      "inline $type$ $classname$::$name$() const {\n"
+      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+      "  if (has_$name$()) {\n"
+      "    return static_cast< $type$ >($field_member$);\n"
+      "  }\n"
+      "  return static_cast< $type$ >($default$);\n"
+      "}\n"
+      "inline void $classname$::set_$name$($type$ value) {\n");
   if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
-    printer->Print(variables_,
-    "  assert($type$_IsValid(value));\n");
+    format("  assert($type$_IsValid(value));\n");
   }
-  printer->Print(variables_,
-    "  if (!has_$name$()) {\n"
-    "    clear_$oneof_name$();\n"
-    "    set_has_$name$();\n"
-    "  }\n"
-    "  $field_member$ = value;\n"
-    "  // @@protoc_insertion_point(field_set:$full_name$)\n"
-    "}\n");
+  format(
+      "  if (!has_$name$()) {\n"
+      "    clear_$oneof_name$();\n"
+      "    set_has_$name$();\n"
+      "  }\n"
+      "  $field_member$ = value;\n"
+      "  // @@protoc_insertion_point(field_set:$full_name$)\n"
+      "}\n");
 }
 
-void EnumOneofFieldGenerator::
-GenerateClearingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$field_member$ = $default$;\n");
+void EnumOneofFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format("$field_member$ = $default$;\n");
 }
 
-void EnumOneofFieldGenerator::
-GenerateSwappingCode(io::Printer* printer) const {
+void EnumOneofFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
   // Don't print any swapping code. Swapping the union will swap this field.
 }
 
-void EnumOneofFieldGenerator::
-GenerateConstructorCode(io::Printer* printer) const {
-  printer->Print(variables_,
-                 "$ns$::_$classname$_default_instance_.$name$_ = $default$;\n");
+void EnumOneofFieldGenerator::GenerateConstructorCode(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format("$ns$::_$classname$_default_instance_.$name$_ = $default$;\n");
 }
 
 // ===================================================================
 
 RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
     const FieldDescriptor* descriptor, const Options& options)
-    : FieldGenerator(options), descriptor_(descriptor) {
+    : FieldGenerator(descriptor, options) {
   SetEnumVariables(descriptor, &variables_, options);
 }
 
 RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
 
-void RepeatedEnumFieldGenerator::
-GeneratePrivateMembers(io::Printer* printer) const {
-  printer->Print(variables_,
-    "::google::protobuf::RepeatedField<int> $name$_;\n");
+void RepeatedEnumFieldGenerator::GeneratePrivateMembers(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format("::$proto_ns$::RepeatedField<int> $name$_;\n");
   if (descriptor_->is_packed() &&
       HasGeneratedMethods(descriptor_->file(), options_)) {
-    printer->Print(variables_,
-      "mutable int _$name$_cached_byte_size_;\n");
+    format("mutable std::atomic<int> _$name$_cached_byte_size_;\n");
   }
 }
 
-void RepeatedEnumFieldGenerator::
-GenerateAccessorDeclarations(io::Printer* printer) const {
-  printer->Print(variables_,
-                 "$deprecated_attr$$type$ $name$(int index) const;\n");
-  printer->Annotate("name", descriptor_);
-  printer->Print(
-      variables_,
-      "$deprecated_attr$void ${$set_$name$$}$(int index, $type$ value);\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$void ${$add_$name$$}$($type$ value);\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(
-      variables_,
-      "$deprecated_attr$const ::google::protobuf::RepeatedField<int>& $name$() const;\n");
-  printer->Annotate("name", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$::google::protobuf::RepeatedField<int>* "
-                 "${$mutable_$name$$}$();\n");
-  printer->Annotate("{", "}", descriptor_);
+void RepeatedEnumFieldGenerator::GenerateAccessorDeclarations(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format(
+      "$deprecated_attr$$type$ ${1$$name$$}$(int index) const;\n"
+      "$deprecated_attr$void ${1$set_$name$$}$(int index, $type$ value);\n"
+      "$deprecated_attr$void ${1$add_$name$$}$($type$ value);\n"
+      "$deprecated_attr$const ::$proto_ns$::RepeatedField<int>& "
+      "${1$$name$$}$() const;\n"
+      "$deprecated_attr$::$proto_ns$::RepeatedField<int>* "
+      "${1$mutable_$name$$}$();\n",
+      descriptor_);
 }
 
-void RepeatedEnumFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline $type$ $classname$::$name$(int index) const {\n"
-    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
-    "  return static_cast< $type$ >($name$_.Get(index));\n"
-    "}\n"
-    "inline void $classname$::set_$name$(int index, $type$ value) {\n");
+void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format(
+      "inline $type$ $classname$::$name$(int index) const {\n"
+      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+      "  return static_cast< $type$ >($name$_.Get(index));\n"
+      "}\n"
+      "inline void $classname$::set_$name$(int index, $type$ value) {\n");
   if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
-    printer->Print(variables_,
-    "  assert($type$_IsValid(value));\n");
+    format("  assert($type$_IsValid(value));\n");
   }
-  printer->Print(variables_,
-    "  $name$_.Set(index, value);\n"
-    "  // @@protoc_insertion_point(field_set:$full_name$)\n"
-    "}\n"
-    "inline void $classname$::add_$name$($type$ value) {\n");
+  format(
+      "  $name$_.Set(index, value);\n"
+      "  // @@protoc_insertion_point(field_set:$full_name$)\n"
+      "}\n"
+      "inline void $classname$::add_$name$($type$ value) {\n");
   if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
-    printer->Print(variables_,
-    "  assert($type$_IsValid(value));\n");
+    format("  assert($type$_IsValid(value));\n");
   }
-  printer->Print(variables_,
-    "  $name$_.Add(value);\n"
-    "  // @@protoc_insertion_point(field_add:$full_name$)\n"
-    "}\n"
-    "inline const ::google::protobuf::RepeatedField<int>&\n"
-    "$classname$::$name$() const {\n"
-    "  // @@protoc_insertion_point(field_list:$full_name$)\n"
-    "  return $name$_;\n"
-    "}\n"
-    "inline ::google::protobuf::RepeatedField<int>*\n"
-    "$classname$::mutable_$name$() {\n"
-    "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
-    "  return &$name$_;\n"
-    "}\n");
+  format(
+      "  $name$_.Add(value);\n"
+      "  // @@protoc_insertion_point(field_add:$full_name$)\n"
+      "}\n"
+      "inline const ::$proto_ns$::RepeatedField<int>&\n"
+      "$classname$::$name$() const {\n"
+      "  // @@protoc_insertion_point(field_list:$full_name$)\n"
+      "  return $name$_;\n"
+      "}\n"
+      "inline ::$proto_ns$::RepeatedField<int>*\n"
+      "$classname$::mutable_$name$() {\n"
+      "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+      "  return &$name$_;\n"
+      "}\n");
 }
 
-void RepeatedEnumFieldGenerator::
-GenerateClearingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.Clear();\n");
+void RepeatedEnumFieldGenerator::GenerateClearingCode(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format("$name$_.Clear();\n");
 }
 
-void RepeatedEnumFieldGenerator::
-GenerateMergingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+void RepeatedEnumFieldGenerator::GenerateMergingCode(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format("$name$_.MergeFrom(from.$name$_);\n");
 }
 
-void RepeatedEnumFieldGenerator::
-GenerateSwappingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.InternalSwap(&other->$name$_);\n");
+void RepeatedEnumFieldGenerator::GenerateSwappingCode(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format("$name$_.InternalSwap(&other->$name$_);\n");
 }
 
-void RepeatedEnumFieldGenerator::
-GenerateConstructorCode(io::Printer* printer) const {
+void RepeatedEnumFieldGenerator::GenerateConstructorCode(
+    io::Printer* printer) const {
   // Not needed for repeated fields.
 }
 
-void RepeatedEnumFieldGenerator::
-GenerateMergeFromCodedStream(io::Printer* printer) const {
+void RepeatedEnumFieldGenerator::GenerateMergeFromCodedStream(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
   // Don't use ReadRepeatedPrimitive here so that the enum can be validated.
-  printer->Print(variables_,
-    "int value = 0;\n"
-    "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
-    "         int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
-    "       input, &value)));\n");
-  if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
-    printer->Print(variables_,
-      "add_$name$(static_cast< $type$ >(value));\n");
-  } else {
-    printer->Print(variables_,
-      "if ($type$_IsValid(value)) {\n"
-      "  add_$name$(static_cast< $type$ >(value));\n");
-    if (UseUnknownFieldSet(descriptor_->file(), options_)) {
-      printer->Print(variables_,
-        "} else {\n"
-        "  mutable_unknown_fields()->AddVarint(\n"
-        "      $number$, static_cast< ::google::protobuf::uint64>(value));\n");
-    } else {
-      printer->Print(
-        "} else {\n"
-        "  unknown_fields_stream.WriteVarint32(tag);\n"
-        "  unknown_fields_stream.WriteVarint32(\n"
-        "      static_cast< ::google::protobuf::uint32>(value));\n");
-    }
-    printer->Print("}\n");
-  }
-}
-
-void RepeatedEnumFieldGenerator::
-GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
-  if (!descriptor_->is_packed()) {
-      // This path is rarely executed, so we use a non-inlined implementation.
-    if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
-      printer->Print(variables_,
-        "DO_((::google::protobuf::internal::"
-                    "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n"
-        "       input,\n"
-        "       $number$,\n"
-        "       NULL,\n"
-        "       NULL,\n"
-        "       this->mutable_$name$())));\n");
-    } else if (UseUnknownFieldSet(descriptor_->file(), options_)) {
-      printer->Print(variables_,
-        "DO_((::google::protobuf::internal::WireFormat::ReadPackedEnumPreserveUnknowns(\n"
-        "       input,\n"
-        "       $number$,\n"
-        "       $type$_IsValid,\n"
-        "       mutable_unknown_fields(),\n"
-        "       this->mutable_$name$())));\n");
-    } else {
-      printer->Print(variables_,
-        "DO_((::google::protobuf::internal::"
-                     "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n"
-        "       input,\n"
-        "       $number$,\n"
-        "       $type$_IsValid,\n"
-        "       &unknown_fields_stream,\n"
-        "       this->mutable_$name$())));\n");
-    }
-  } else {
-    printer->Print(variables_,
-      "::google::protobuf::uint32 length;\n"
-      "DO_(input->ReadVarint32(&length));\n"
-      "::google::protobuf::io::CodedInputStream::Limit limit = "
-          "input->PushLimit(static_cast<int>(length));\n"
-      "while (input->BytesUntilLimit() > 0) {\n"
-      "  int value = 0;\n"
-      "  DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
-      "         int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
+  format(
+      "int value = 0;\n"
+      "DO_((::$proto_ns$::internal::WireFormatLite::ReadPrimitive<\n"
+      "         int, ::$proto_ns$::internal::WireFormatLite::TYPE_ENUM>(\n"
       "       input, &value)));\n");
-    if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
-      printer->Print(variables_,
-      "  add_$name$(static_cast< $type$ >(value));\n");
+  if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
+    format("add_$name$(static_cast< $type$ >(value));\n");
+  } else {
+    format(
+        "if ($type$_IsValid(value)) {\n"
+        "  add_$name$(static_cast< $type$ >(value));\n");
+    if (UseUnknownFieldSet(descriptor_->file(), options_)) {
+      format(
+          "} else {\n"
+          "  mutable_unknown_fields()->AddVarint(\n"
+          "      $number$, static_cast<$uint64$>(value));\n");
     } else {
-      printer->Print(variables_,
-      "  if ($type$_IsValid(value)) {\n"
-      "    add_$name$(static_cast< $type$ >(value));\n"
-      "  } else {\n");
-      if (UseUnknownFieldSet(descriptor_->file(), options_)) {
-        printer->Print(variables_,
-        "  mutable_unknown_fields()->AddVarint(\n"
-        "      $number$, static_cast< ::google::protobuf::uint64>(value));\n");
-      } else {
-        printer->Print(variables_,
-        "    unknown_fields_stream.WriteVarint32(tag);\n"
-        "    unknown_fields_stream.WriteVarint32(\n"
-        "        static_cast< ::google::protobuf::uint32>(value));\n");
-      }
-      printer->Print(
-      "  }\n");
+      format(
+          "} else {\n"
+          "  unknown_fields_stream.WriteVarint32(tag);\n"
+          "  unknown_fields_stream.WriteVarint32(\n"
+          "      static_cast<$uint32$>(value));\n");
     }
-    printer->Print(variables_,
-      "}\n"
-      "input->PopLimit(limit);\n");
+    format("}\n");
   }
 }
 
-void RepeatedEnumFieldGenerator::
-GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+void RepeatedEnumFieldGenerator::GenerateMergeFromCodedStreamWithPacking(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  if (!descriptor_->is_packed()) {
+    // This path is rarely executed, so we use a non-inlined implementation.
+    if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
+      format(
+          "DO_((::$proto_ns$::internal::"
+          "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n"
+          "       input,\n"
+          "       $number$,\n"
+          "       NULL,\n"
+          "       NULL,\n"
+          "       this->mutable_$name$())));\n");
+    } else if (UseUnknownFieldSet(descriptor_->file(), options_)) {
+      format(
+          "DO_((::$proto_ns$::internal::WireFormat::"
+          "ReadPackedEnumPreserveUnknowns(\n"
+          "       input,\n"
+          "       $number$,\n"
+          "       $type$_IsValid,\n"
+          "       mutable_unknown_fields(),\n"
+          "       this->mutable_$name$())));\n");
+    } else {
+      format(
+          "DO_((::$proto_ns$::internal::"
+          "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n"
+          "       input,\n"
+          "       $number$,\n"
+          "       $type$_IsValid,\n"
+          "       &unknown_fields_stream,\n"
+          "       this->mutable_$name$())));\n");
+    }
+  } else {
+    format(
+        "$uint32$ length;\n"
+        "DO_(input->ReadVarint32(&length));\n"
+        "::$proto_ns$::io::CodedInputStream::Limit limit = "
+        "input->PushLimit(static_cast<int>(length));\n"
+        "while (input->BytesUntilLimit() > 0) {\n"
+        "  int value = 0;\n"
+        "  DO_((::$proto_ns$::internal::WireFormatLite::ReadPrimitive<\n"
+        "         int, ::$proto_ns$::internal::WireFormatLite::TYPE_ENUM>(\n"
+        "       input, &value)));\n");
+    if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
+      format("  add_$name$(static_cast< $type$ >(value));\n");
+    } else {
+      format(
+          "  if ($type$_IsValid(value)) {\n"
+          "    add_$name$(static_cast< $type$ >(value));\n"
+          "  } else {\n");
+      if (UseUnknownFieldSet(descriptor_->file(), options_)) {
+        format(
+            "  mutable_unknown_fields()->AddVarint(\n"
+            "      $number$, static_cast<$uint64$>(value));\n");
+      } else {
+        format(
+            "    unknown_fields_stream.WriteVarint32(tag);\n"
+            "    unknown_fields_stream.WriteVarint32(\n"
+            "        static_cast<$uint32$>(value));\n");
+      }
+      format("  }\n");
+    }
+    format(
+        "}\n"
+        "input->PopLimit(limit);\n");
+  }
+}
+
+void RepeatedEnumFieldGenerator::GenerateSerializeWithCachedSizes(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (descriptor_->is_packed()) {
     // Write the tag and the size.
-    printer->Print(variables_,
-      "if (this->$name$_size() > 0) {\n"
-      "  ::google::protobuf::internal::WireFormatLite::WriteTag(\n"
-      "    $number$,\n"
-      "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
-      "    output);\n"
-      "  output->WriteVarint32(\n"
-      "      static_cast< ::google::protobuf::uint32>(_$name$_cached_byte_size_));\n"
-      "}\n");
+    format(
+        "if (this->$name$_size() > 0) {\n"
+        "  ::$proto_ns$::internal::WireFormatLite::WriteTag(\n"
+        "    $number$,\n"
+        "    "
+        "::$proto_ns$::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+        "    output);\n"
+        "  output->WriteVarint32(_$name$_cached_byte_size_.load(\n"
+        "      std::memory_order_relaxed));\n"
+        "}\n");
   }
-  printer->Print(variables_,
-      "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
+  format("for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
   if (descriptor_->is_packed()) {
-    printer->Print(variables_,
-      "  ::google::protobuf::internal::WireFormatLite::WriteEnumNoTag(\n"
-      "    this->$name$(i), output);\n");
+    format(
+        "  ::$proto_ns$::internal::WireFormatLite::WriteEnumNoTag(\n"
+        "    this->$name$(i), output);\n");
   } else {
-    printer->Print(variables_,
-      "  ::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
-      "    $number$, this->$name$(i), output);\n");
+    format(
+        "  ::$proto_ns$::internal::WireFormatLite::WriteEnum(\n"
+        "    $number$, this->$name$(i), output);\n");
   }
-  printer->Print("}\n");
+  format("}\n");
 }
 
-void RepeatedEnumFieldGenerator::
-GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+void RepeatedEnumFieldGenerator::GenerateSerializeWithCachedSizesToArray(
+    io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (descriptor_->is_packed()) {
     // Write the tag and the size.
-    printer->Print(variables_,
-      "if (this->$name$_size() > 0) {\n"
-      "  target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n"
-      "    $number$,\n"
-      "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
-      "    target);\n"
-      "  target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray("
-      "      static_cast< ::google::protobuf::uint32>(\n"
-      "          _$name$_cached_byte_size_), target);\n"
-      "  target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n"
-      "    this->$name$_, target);\n"
-      "}\n");
+    format(
+        "if (this->$name$_size() > 0) {\n"
+        "  target = ::$proto_ns$::internal::WireFormatLite::WriteTagToArray(\n"
+        "    $number$,\n"
+        "    "
+        "::$proto_ns$::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+        "    target);\n"
+        "  target = ::$proto_ns$::io::CodedOutputStream::WriteVarint32ToArray("
+        "      _$name$_cached_byte_size_.load(std::memory_order_relaxed),\n"
+        "      target);\n"
+        "  target = "
+        "::$proto_ns$::internal::WireFormatLite::WriteEnumNoTagToArray(\n"
+        "    this->$name$_, target);\n"
+        "}\n");
   } else {
-    printer->Print(variables_,
-      "target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
-      "  $number$, this->$name$_, target);\n");
+    format(
+        "target = ::$proto_ns$::internal::WireFormatLite::WriteEnumToArray(\n"
+        "  $number$, this->$name$_, target);\n");
   }
 }
 
-void RepeatedEnumFieldGenerator::
-GenerateByteSize(io::Printer* printer) const {
-  printer->Print(variables_,
-    "{\n"
-    "  size_t data_size = 0;\n"
-    "  unsigned int count = static_cast<unsigned int>(this->$name$_size());");
-  printer->Indent();
-  printer->Print(variables_,
+void RepeatedEnumFieldGenerator::GenerateByteSize(io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  format(
+      "{\n"
+      "  size_t data_size = 0;\n"
+      "  unsigned int count = static_cast<unsigned int>(this->$name$_size());");
+  format.Indent();
+  format(
       "for (unsigned int i = 0; i < count; i++) {\n"
-      "  data_size += ::google::protobuf::internal::WireFormatLite::EnumSize(\n"
+      "  data_size += ::$proto_ns$::internal::WireFormatLite::EnumSize(\n"
       "    this->$name$(static_cast<int>(i)));\n"
       "}\n");
 
   if (descriptor_->is_packed()) {
-    printer->Print(variables_,
-      "if (data_size > 0) {\n"
-      "  total_size += $tag_size$ +\n"
-      "    ::google::protobuf::internal::WireFormatLite::Int32Size(\n"
-      "        static_cast< ::google::protobuf::int32>(data_size));\n"
-      "}\n"
-      "int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);\n"
-      "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
-      "_$name$_cached_byte_size_ = cached_size;\n"
-      "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
-      "total_size += data_size;\n");
+    format(
+        "if (data_size > 0) {\n"
+        "  total_size += $tag_size$ +\n"
+        "    ::$proto_ns$::internal::WireFormatLite::Int32Size(\n"
+        "        static_cast<$int32$>(data_size));\n"
+        "}\n"
+        "int cached_size = ::$proto_ns$::internal::ToCachedSize(data_size);\n"
+        "_$name$_cached_byte_size_.store(cached_size,\n"
+        "                                std::memory_order_relaxed);\n"
+        "total_size += data_size;\n");
   } else {
-    printer->Print(variables_,
-      "total_size += ($tag_size$UL * count) + data_size;\n");
+    format("total_size += ($tag_size$UL * count) + data_size;\n");
   }
-  printer->Outdent();
-  printer->Print("}\n");
+  format.Outdent();
+  format("}\n");
 }
 
 }  // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/src/google/protobuf/compiler/cpp/cpp_enum_field.h
index d0e87b7..b43d402 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.h
@@ -63,10 +63,6 @@
   void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
   void GenerateByteSize(io::Printer* printer) const;
 
- protected:
-  const FieldDescriptor* descriptor_;
-  std::map<string, string> variables_;
-
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
 };
@@ -109,15 +105,12 @@
   void GenerateByteSize(io::Printer* printer) const;
 
  private:
-  const FieldDescriptor* descriptor_;
-  std::map<string, string> variables_;
-
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
 };
 
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc
index c416ba1..25bcc33 100644
--- a/src/google/protobuf/compiler/cpp/cpp_extension.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc
@@ -84,86 +84,88 @@
       break;
     default:
       type_traits_.append("PrimitiveTypeTraits< ");
-      type_traits_.append(PrimitiveTypeName(descriptor_->cpp_type()));
+      type_traits_.append(PrimitiveTypeName(options_, descriptor_->cpp_type()));
       type_traits_.append(" >");
       break;
   }
+  SetCommonVars(options, &variables_);
+  variables_["extendee"] = ExtendeeClassName(descriptor_);
+  variables_["type_traits"] = type_traits_;
+  string name = descriptor_->name();
+  variables_["name"] = name;
+  variables_["constant_name"] = FieldConstantName(descriptor_);
+  variables_["field_type"] =
+      SimpleItoa(static_cast<int>(descriptor_->type()));
+  variables_["packed"] = descriptor_->options().packed() ? "true" : "false";
+
+  string scope =
+      IsScoped() ? ClassName(descriptor_->extension_scope(), false) + "::" : "";
+  variables_["scope"] = scope;
+  string scoped_name = scope + name;
+  variables_["scoped_name"] = scoped_name;
+  variables_["number"] = SimpleItoa(descriptor_->number());
 }
 
 ExtensionGenerator::~ExtensionGenerator() {}
 
-void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
-  std::map<string, string> vars;
-  vars["extendee"     ] = ExtendeeClassName(descriptor_);
-  vars["number"       ] = SimpleItoa(descriptor_->number());
-  vars["type_traits"  ] = type_traits_;
-  vars["name"         ] = descriptor_->name();
-  vars["field_type"   ] = SimpleItoa(static_cast<int>(descriptor_->type()));
-  vars["packed"       ] = descriptor_->options().packed() ? "true" : "false";
-  vars["constant_name"] = FieldConstantName(descriptor_);
+bool ExtensionGenerator::IsScoped() const {
+  return descriptor_->extension_scope() != nullptr;
+}
+
+void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) const {
+  Formatter format(printer, variables_);
 
   // If this is a class member, it needs to be declared "static".  Otherwise,
   // it needs to be "extern".  In the latter case, it also needs the DLL
   // export/import specifier.
-  if (descriptor_->extension_scope() == NULL) {
-    vars["qualifier"] = "extern";
+  string qualifier;
+  if (!IsScoped()) {
+    qualifier = "extern";
     if (!options_.dllexport_decl.empty()) {
-      vars["qualifier"] = options_.dllexport_decl + " " + vars["qualifier"];
+      qualifier = options_.dllexport_decl + " " + qualifier;
     }
   } else {
-    vars["qualifier"] = "static";
+    qualifier = "static";
   }
 
-  printer->Print(vars,
-    "static const int $constant_name$ = $number$;\n"
-    "$qualifier$ ::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
-    "    ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
-    "  $name$;\n"
-    );
+  format(
+      "static const int $constant_name$ = $number$;\n"
+      "$1$ ::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n"
+      "    ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n"
+      "  $name$;\n",
+      qualifier);
 }
 
 void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
+  Formatter format(printer, variables_);
+  string default_str;
   // If this is a class member, it needs to be declared in its class scope.
-  string scope = (descriptor_->extension_scope() == NULL) ? "" :
-    ClassName(descriptor_->extension_scope(), false) + "::";
-  string name = scope + descriptor_->name();
-
-  std::map<string, string> vars;
-  vars["extendee"     ] = ExtendeeClassName(descriptor_);
-  vars["type_traits"  ] = type_traits_;
-  vars["name"         ] = name;
-  vars["constant_name"] = FieldConstantName(descriptor_);
-  vars["default"      ] = DefaultValue(descriptor_);
-  vars["field_type"   ] = SimpleItoa(static_cast<int>(descriptor_->type()));
-  vars["packed"       ] = descriptor_->options().packed() ? "true" : "false";
-  vars["scope"        ] = scope;
-
   if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
     // We need to declare a global string which will contain the default value.
     // We cannot declare it at class scope because that would require exposing
     // it in the header which would be annoying for other reasons.  So we
     // replace :: with _ in the name and declare it as a global.
-    string global_name = StringReplace(name, "::", "_", true);
-    vars["global_name"] = global_name;
-    printer->Print(vars,
-      "const ::std::string $global_name$_default($default$);\n");
-
-    // Update the default to refer to the string global.
-    vars["default"] = global_name + "_default";
+    default_str =
+        StringReplace(variables_["scoped_name"], "::", "_", true) + "_default";
+    format("const ::std::string $1$($2$);\n", default_str,
+           DefaultValue(options_, descriptor_));
+  } else {
+    default_str = DefaultValue(options_, descriptor_);
   }
 
   // Likewise, class members need to declare the field constant variable.
-  if (descriptor_->extension_scope() != NULL) {
-    printer->Print(vars,
-      "#if !defined(_MSC_VER) || _MSC_VER >= 1900\n"
-      "const int $scope$$constant_name$;\n"
-      "#endif\n");
+  if (IsScoped()) {
+    format(
+        "#if !defined(_MSC_VER) || _MSC_VER >= 1900\n"
+        "const int $scope$$constant_name$;\n"
+        "#endif\n");
   }
 
-  printer->Print(vars,
-    "::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
-    "    ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
-    "  $name$($constant_name$, $default$);\n");
+  format(
+      "::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n"
+      "    ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n"
+      "  $scoped_name$($constant_name$, $1$);\n",
+      default_str);
 }
 
 }  // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.h b/src/google/protobuf/compiler/cpp/cpp_extension.h
index 30236d7..c316f5d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_extension.h
+++ b/src/google/protobuf/compiler/cpp/cpp_extension.h
@@ -35,18 +35,22 @@
 #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__
 #define GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__
 
+#include <map>
 #include <string>
+
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/compiler/cpp/cpp_options.h>
 
 namespace google {
 namespace protobuf {
-  class FieldDescriptor;       // descriptor.h
-  namespace io {
-    class Printer;             // printer.h
-  }
+class FieldDescriptor;  // descriptor.h
+namespace io {
+class Printer;  // printer.h
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace cpp {
@@ -62,22 +66,26 @@
   ~ExtensionGenerator();
 
   // Header stuff.
-  void GenerateDeclaration(io::Printer* printer);
+  void GenerateDeclaration(io::Printer* printer) const;
 
   // Source file stuff.
   void GenerateDefinition(io::Printer* printer);
 
+  bool IsScoped() const;
+
  private:
   const FieldDescriptor* descriptor_;
   string type_traits_;
   Options options_;
 
+  std::map<string, string> variables_;
+
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
 };
 
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc
index 0de20f8..582da4a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_field.cc
@@ -38,6 +38,7 @@
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
 #include <google/protobuf/compiler/cpp/cpp_string_field.h>
+
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/compiler/cpp/cpp_enum_field.h>
@@ -58,6 +59,7 @@
 void SetCommonFieldVariables(const FieldDescriptor* descriptor,
                              std::map<string, string>* variables,
                              const Options& options) {
+  SetCommonVars(options, variables);
   (*variables)["ns"] = Namespace(descriptor);
   (*variables)["name"] = FieldName(descriptor);
   (*variables)["index"] = SimpleItoa(descriptor->index());
@@ -67,20 +69,17 @@
   (*variables)["field_member"] = FieldName(descriptor) + "_";
 
   (*variables)["tag_size"] = SimpleItoa(
-    WireFormat::TagSize(descriptor->number(), descriptor->type()));
-  (*variables)["deprecation"] = descriptor->options().deprecated()
-      ? " PROTOBUF_DEPRECATED" : "";
-  (*variables)["deprecated_attr"] = descriptor->options().deprecated()
-      ? "GOOGLE_PROTOBUF_DEPRECATED_ATTR " : "";
+      WireFormat::TagSize(descriptor->number(), descriptor->type()));
+  (*variables)["deprecated_attr"] =
+      DeprecatedAttribute(options, descriptor->options().deprecated());
 
+  (*variables)["set_hasbit"] = "";
+  (*variables)["clear_hasbit"] = "";
   if (HasFieldPresence(descriptor->file())) {
-    (*variables)["set_hasbit"] =
-        "set_has_" + FieldName(descriptor) + "();";
-    (*variables)["clear_hasbit"] =
-        "clear_has_" + FieldName(descriptor) + "();";
+    (*variables)["set_hasbit_io"] =
+        "HasBitSetters::set_has_" + FieldName(descriptor) + "(this);";
   } else {
-    (*variables)["set_hasbit"] = "";
-    (*variables)["clear_hasbit"] = "";
+    (*variables)["set_hasbit_io"] = "";
   }
 
   // These variables are placeholders to pick out the beginning and ends of
@@ -91,11 +90,24 @@
   (*variables)["}"] = "";
 }
 
+void FieldGenerator::SetHasBitIndex(int32 has_bit_index) {
+  if (!HasFieldPresence(descriptor_->file()) || has_bit_index == -1) {
+    return;
+  }
+  variables_["set_hasbit"] = StrCat(
+      "_has_bits_[", has_bit_index / 32, "] |= 0x",
+      strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;");
+  variables_["clear_hasbit"] = StrCat(
+      "_has_bits_[", has_bit_index / 32, "] &= ~0x",
+      strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;");
+}
+
 void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor,
                                   std::map<string, string>* variables) {
   const string prefix = descriptor->containing_oneof()->name() + "_.";
   (*variables)["oneof_name"] = descriptor->containing_oneof()->name();
-  (*variables)["field_member"] = StrCat(prefix, (*variables)["name"], "_");
+  (*variables)["field_member"] =
+      StrCat(prefix, (*variables)["name"], "_");
 }
 
 FieldGenerator::~FieldGenerator() {}
@@ -114,7 +126,7 @@
 
 FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
                                      const Options& options,
-                                     SCCAnalyzer* scc_analyzer)
+                                     MessageSCCAnalyzer* scc_analyzer)
     : descriptor_(descriptor),
       options_(options),
       field_generators_(descriptor->field_count()) {
@@ -125,9 +137,22 @@
   }
 }
 
-FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
-                                                 const Options& options,
-                                                 SCCAnalyzer* scc_analyzer) {
+FieldGenerator* FieldGeneratorMap::MakeGoogleInternalGenerator(
+    const FieldDescriptor* field, const Options& options,
+    MessageSCCAnalyzer* scc_analyzer) {
+
+  return nullptr;
+}
+
+FieldGenerator* FieldGeneratorMap::MakeGenerator(
+    const FieldDescriptor* field, const Options& options,
+    MessageSCCAnalyzer* scc_analyzer) {
+  FieldGenerator* generator =
+      MakeGoogleInternalGenerator(field, options, scc_analyzer);
+  if (generator) {
+    return generator;
+  }
+
   if (field->is_repeated()) {
     switch (field->cpp_type()) {
       case FieldDescriptor::CPPTYPE_MESSAGE:
@@ -138,11 +163,7 @@
                                                    scc_analyzer);
         }
       case FieldDescriptor::CPPTYPE_STRING:
-        switch (field->options().ctype()) {
-          default:  // RepeatedStringFieldGenerator handles unknown ctypes.
-          case FieldOptions::STRING:
-            return new RepeatedStringFieldGenerator(field, options);
-        }
+        return new RepeatedStringFieldGenerator(field, options);
       case FieldDescriptor::CPPTYPE_ENUM:
         return new RepeatedEnumFieldGenerator(field, options);
       default:
@@ -153,11 +174,7 @@
       case FieldDescriptor::CPPTYPE_MESSAGE:
         return new MessageOneofFieldGenerator(field, options, scc_analyzer);
       case FieldDescriptor::CPPTYPE_STRING:
-        switch (field->options().ctype()) {
-          default:  // StringOneofFieldGenerator handles unknown ctypes.
-          case FieldOptions::STRING:
-            return new StringOneofFieldGenerator(field, options);
-        }
+        return new StringOneofFieldGenerator(field, options);
       case FieldDescriptor::CPPTYPE_ENUM:
         return new EnumOneofFieldGenerator(field, options);
       default:
@@ -168,11 +185,7 @@
       case FieldDescriptor::CPPTYPE_MESSAGE:
         return new MessageFieldGenerator(field, options, scc_analyzer);
       case FieldDescriptor::CPPTYPE_STRING:
-        switch (field->options().ctype()) {
-          default:  // StringFieldGenerator handles unknown ctypes.
-          case FieldOptions::STRING:
-            return new StringFieldGenerator(field, options);
-        }
+        return new StringFieldGenerator(field, options);
       case FieldDescriptor::CPPTYPE_ENUM:
         return new EnumFieldGenerator(field, options);
       default:
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h
index 8cdbe88..4561b33 100644
--- a/src/google/protobuf/compiler/cpp/cpp_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_field.h
@@ -45,11 +45,13 @@
 
 namespace google {
 namespace protobuf {
-  namespace io {
-    class Printer;             // printer.h
-  }
+namespace io {
+class Printer;  // printer.h
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace cpp {
@@ -67,7 +69,9 @@
 
 class FieldGenerator {
  public:
-  explicit FieldGenerator(const Options& options) : options_(options) {}
+  explicit FieldGenerator(const FieldDescriptor* descriptor,
+                          const Options& options)
+      : descriptor_(descriptor), options_(options) {}
   virtual ~FieldGenerator();
 
   // Generate lines of code declaring members fields of the message class
@@ -95,17 +99,27 @@
   virtual void GenerateNonInlineAccessorDefinitions(
       io::Printer* /*printer*/) const {}
 
+  // Generate declarations of accessors that are for internal purposes only.
+  // Most field types don't need this, so the default implementation is empty.
+  virtual void GenerateInternalAccessorDefinitions(
+      io::Printer* /*printer*/) const {}
+
+  // Generate definitions of accessors that are for internal purposes only.
+  // Most field types don't need this, so the default implementation is empty.
+  virtual void GenerateInternalAccessorDeclarations(
+      io::Printer* /*printer*/) const {}
+
   // Generate lines of code (statements, not declarations) which clear the
   // field.  This is used to define the clear_$name$() method
   virtual void GenerateClearingCode(io::Printer* printer) const = 0;
 
-  // Generate lines of code (statements, not declarations) which clear the field
-  // as part of the Clear() method for the whole message.  For message types
-  // which have field presence bits, MessageGenerator::GenerateClear will have
-  // already checked the presence bits.
+  // Generate lines of code (statements, not declarations) which clear the
+  // field as part of the Clear() method for the whole message.  For message
+  // types which have field presence bits, MessageGenerator::GenerateClear
+  // will have already checked the presence bits.
   //
-  // Since most field types can re-use GenerateClearingCode, this method is not
-  // pure virtual.
+  // Since most field types can re-use GenerateClearingCode, this method is
+  // not pure virtual.
   virtual void GenerateMessageClearingCode(io::Printer* printer) const {
     GenerateClearingCode(printer);
   }
@@ -140,17 +154,17 @@
 
   // Generate a manual destructor invocation for use when the message is on an
   // arena. The code that this method generates will be executed inside a
-  // shared-for-the-whole-message-class method registered with OwnDestructor().
-  // The method should return |true| if it generated any code that requires a
-  // call; this allows the message generator to eliminate the OwnDestructor()
-  // registration if no fields require it.
+  // shared-for-the-whole-message-class method registered with
+  // OwnDestructor(). The method should return |true| if it generated any code
+  // that requires a call; this allows the message generator to eliminate the
+  // OwnDestructor() registration if no fields require it.
   virtual bool GenerateArenaDestructorCode(io::Printer* printer) const {
     return false;
   }
 
   // Generate code that allocates the fields's default instance.
-  virtual void GenerateDefaultInstanceAllocator(io::Printer* /*printer*/)
-      const {}
+  virtual void GenerateDefaultInstanceAllocator(
+      io::Printer* /*printer*/) const {}
 
   // Generate lines to decode this field, which will be placed inside the
   // message's MergeFromCodedStream() method.
@@ -162,8 +176,8 @@
 
   // Generate lines to decode this field from a packed value, which will be
   // placed inside the message's MergeFromCodedStream() method.
-  virtual void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer)
-      const;
+  virtual void GenerateMergeFromCodedStreamWithPacking(
+      io::Printer* printer) const;
 
   // Generate lines to serialize this field, which are placed within the
   // message's SerializeWithCachedSizes() method.
@@ -184,8 +198,12 @@
   virtual uint32 CalculateFieldTag() const { return 0; }
   virtual bool IsInlined() const { return false; }
 
+  void SetHasBitIndex(int32 has_bit_index);
+
  protected:
+  const FieldDescriptor* descriptor_;
   const Options& options_;
+  std::map<string, string> variables_;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
@@ -195,19 +213,28 @@
 class FieldGeneratorMap {
  public:
   FieldGeneratorMap(const Descriptor* descriptor, const Options& options,
-                    SCCAnalyzer* scc_analyzer);
+                    MessageSCCAnalyzer* scc_analyzer);
   ~FieldGeneratorMap();
 
   const FieldGenerator& get(const FieldDescriptor* field) const;
 
+  void SetHasBitIndices(const std::vector<int>& has_bit_indices_) {
+    for (int i = 0; i < descriptor_->field_count(); ++i) {
+      field_generators_[i]->SetHasBitIndex(has_bit_indices_[i]);
+    }
+  }
+
  private:
   const Descriptor* descriptor_;
   const Options& options_;
   std::vector<std::unique_ptr<FieldGenerator>> field_generators_;
 
+  static FieldGenerator* MakeGoogleInternalGenerator(
+      const FieldDescriptor* field, const Options& options,
+      MessageSCCAnalyzer* scc_analyzer);
   static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
                                        const Options& options,
-                                       SCCAnalyzer* scc_analyzer);
+                                       MessageSCCAnalyzer* scc_analyzer);
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
 };
@@ -215,6 +242,6 @@
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 02f360b..414da2f 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -44,72 +44,79 @@
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/compiler/cpp/cpp_message.h>
 #include <google/protobuf/compiler/cpp/cpp_service.h>
+#include <google/protobuf/compiler/scc.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/stubs/strutil.h>
 
+
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 namespace compiler {
 namespace cpp {
 
 FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
-    : file_(file),
-      options_(options),
-      scc_analyzer_(options),
-      enum_generators_owner_(
-          new std::unique_ptr<EnumGenerator>[file->enum_type_count()]),
-      service_generators_owner_(
-          new std::unique_ptr<ServiceGenerator>[file->service_count()]),
-      extension_generators_owner_(
-          new std::unique_ptr<ExtensionGenerator>[file->extension_count()]) {
+    : file_(file), options_(options), scc_analyzer_(options) {
+  // These variables are the same on a file level
+  SetCommonVars(options, &variables_);
+  variables_["dllexport_decl"] = options.dllexport_decl;
+  variables_["tablename"] = UniqueName("TableStruct", file_, options_);
+  variables_["assign_desc_table"] =
+      UniqueName("assign_descriptors_table", file_, options_);
+  variables_["file_level_metadata"] =
+      UniqueName("file_level_metadata", file_, options_);
+  variables_["file_level_enum_descriptors"] =
+      UniqueName("file_level_enum_descriptors", file_, options_);
+  variables_["file_level_service_descriptors"] =
+      UniqueName("file_level_service_descriptors", file_, options_);
+  variables_["add_descriptors"] = UniqueName("AddDescriptors", file_, options_);
+  variables_["filename"] = file_->name();
+  variables_["package_ns"] = Namespace(file_);
+  variables_["init_defaults"] = UniqueName("InitDefaults", file_, options_);
+
   std::vector<const Descriptor*> msgs = FlattenMessagesInFile(file);
   for (int i = 0; i < msgs.size(); i++) {
     // Deleted in destructor
     MessageGenerator* msg_gen =
-        new MessageGenerator(msgs[i], i, options, &scc_analyzer_);
-    message_generators_.push_back(msg_gen);
+        new MessageGenerator(msgs[i], variables_, i, options, &scc_analyzer_);
+    message_generators_.emplace_back(msg_gen);
     msg_gen->AddGenerators(&enum_generators_, &extension_generators_);
   }
 
   for (int i = 0; i < file->enum_type_count(); i++) {
-    enum_generators_owner_[i].reset(
-        new EnumGenerator(file->enum_type(i), options));
-    enum_generators_.push_back(enum_generators_owner_[i].get());
+    enum_generators_.emplace_back(
+        new EnumGenerator(file->enum_type(i), variables_, options));
   }
 
   for (int i = 0; i < file->service_count(); i++) {
-    service_generators_owner_[i].reset(
-        new ServiceGenerator(file->service(i), options));
-    service_generators_.push_back(service_generators_owner_[i].get());
+    service_generators_.emplace_back(
+        new ServiceGenerator(file->service(i), variables_, options));
   }
   if (HasGenericServices(file_, options_)) {
     for (int i = 0; i < service_generators_.size(); i++) {
       service_generators_[i]->index_in_metadata_ = i;
     }
   }
-
   for (int i = 0; i < file->extension_count(); i++) {
-    extension_generators_owner_[i].reset(
+    extension_generators_.emplace_back(
         new ExtensionGenerator(file->extension(i), options));
-    extension_generators_.push_back(extension_generators_owner_[i].get());
   }
-
-
-  package_parts_ = Split(file_->package(), ".", true);
-}
-
-FileGenerator::~FileGenerator() {
-  for (int i = 0; i < message_generators_.size(); i++) {
-    delete message_generators_[i];
+  for (int i = 0; i < file->weak_dependency_count(); ++i) {
+    weak_deps_.insert(file->weak_dependency(i));
   }
 }
 
+FileGenerator::~FileGenerator() = default;
+
 void FileGenerator::GenerateMacroUndefs(io::Printer* printer) {
+  Formatter format(printer, variables_);
   // Only do this for protobuf's own types. There are some google3 protos using
   // macros as field names and the generated code compiles after the macro
   // expansion. Undefing these macros actually breaks such code.
-  if (file_->name() != "google/protobuf/compiler/plugin.proto") {
+  if (file_->name() != "net/proto2/compiler/proto/plugin.proto" &&
+      file_->name() != "google/protobuf/compiler/plugin.proto") {
     return;
   }
   std::vector<string> names_to_undef;
@@ -126,70 +133,89 @@
     }
   }
   for (int i = 0; i < names_to_undef.size(); ++i) {
-    printer->Print(
-        "#ifdef $name$\n"
-        "#undef $name$\n"
+    format(
+        "#ifdef $1$\n"
+        "#undef $1$\n"
         "#endif\n",
-        "name", names_to_undef[i]);
+        names_to_undef[i]);
   }
 }
 
 void FileGenerator::GenerateHeader(io::Printer* printer) {
-  printer->Print(
-    "// @@protoc_insertion_point(includes)\n");
+  Formatter format(printer, variables_);
 
-  printer->Print("#define PROTOBUF_INTERNAL_EXPORT_$filename$ $export$\n",
-                 "filename", FileLevelNamespace(file_),
-                 "export", options_.dllexport_decl);
+  // port_def.inc must be included after all other includes.
+  IncludeFile("net/proto2/public/port_def.inc", printer);
+  format("#define $1$$ dllexport_decl$\n",
+         UniqueName("PROTOBUF_INTERNAL_EXPORT", file_, options_));
   GenerateMacroUndefs(printer);
+  if (IsProto2MessageSetFile(file_, options_)) {
+    // Proto2 MessageSet overrides GetMapper() so we forward declare TagMapper
+    // to avoid inclusion of "tagmapper.h".
+    format("class TagMapper;\n");
+  }
+
+  if (!options_.opensource_runtime) {
+    // EmbeddedMessageHolder is a proxy class to provide access into arena
+    // constructors for proto1 message objects.
+    // See net/proto/proto_arena_internal.h
+    format(
+        "namespace proto {\n"
+        "namespace internal {\n"
+        "template <typename T> struct EmbeddedMessageHolder;\n"
+        "}  //  namespace internal\n"
+        "}  //  namespace proto\n");
+  }
 
   GenerateGlobalStateFunctionDeclarations(printer);
 
   GenerateForwardDeclarations(printer);
 
   {
-    NamespaceOpener ns(Namespace(file_), printer);
+    NamespaceOpener ns(Namespace(file_), format);
 
-    printer->Print("\n");
+    format("\n");
 
     GenerateEnumDefinitions(printer);
 
-    printer->Print(kThickSeparator);
-    printer->Print("\n");
+    format(kThickSeparator);
+    format("\n");
 
     GenerateMessageDefinitions(printer);
 
-    printer->Print("\n");
-    printer->Print(kThickSeparator);
-    printer->Print("\n");
+    format("\n");
+    format(kThickSeparator);
+    format("\n");
 
     GenerateServiceDefinitions(printer);
 
     GenerateExtensionIdentifiers(printer);
 
-    printer->Print("\n");
-    printer->Print(kThickSeparator);
-    printer->Print("\n");
+    format("\n");
+    format(kThickSeparator);
+    format("\n");
 
     GenerateInlineFunctionDefinitions(printer);
 
-    printer->Print(
-      "\n"
-      "// @@protoc_insertion_point(namespace_scope)\n"
-      "\n");
+    format(
+        "\n"
+        "// @@protoc_insertion_point(namespace_scope)\n"
+        "\n");
   }
 
   // We need to specialize some templates in the ::google::protobuf namespace:
   GenerateProto2NamespaceEnumSpecializations(printer);
 
-  printer->Print(
-    "\n"
-    "// @@protoc_insertion_point(global_scope)\n"
-    "\n");
+  format(
+      "\n"
+      "// @@protoc_insertion_point(global_scope)\n"
+      "\n");
+  IncludeFile("net/proto2/public/port_undef.inc", printer);
 }
 
 void FileGenerator::GenerateProtoHeader(io::Printer* printer,
                                         const string& info_path) {
+  Formatter format(printer, variables_);
   if (!options_.proto_h) {
     return;
   }
@@ -197,18 +223,35 @@
   string filename_identifier = FilenameIdentifier(file_->name());
   GenerateTopHeaderGuard(printer, filename_identifier);
 
+  if (!options_.opensource_runtime) {
+    format(
+        "#ifdef SWIG\n"
+        "#error \"Do not SWIG-wrap protobufs.\"\n"
+        "#endif  // SWIG\n"
+        "\n");
+  }
+
+  if (IsBootstrapProto(options_, file_)) {
+    format("// IWYU pragma: private, include \"$1$.proto.h\"\n\n",
+           StripProto(file_->name()));
+  }
 
   GenerateLibraryIncludes(printer);
 
   for (int i = 0; i < file_->public_dependency_count(); i++) {
     const FileDescriptor* dep = file_->public_dependency(i);
     const char* extension = ".proto.h";
+    // The proto1 compiler only generates .pb.h files, so even if we are
+    // running in proto-h mode, we can only use the .pb.h.
+    if (IsProto1(dep, options_)) {
+      extension = ".pb.h";
+    }
     string dependency = StripProto(dep->name()) + extension;
-    printer->Print(
-      "#include \"$dependency$\"  // IWYU pragma: export\n",
-      "dependency", dependency);
+    format("#include \"$1$\"\n", dependency);
   }
 
+  format("// @@protoc_insertion_point(includes)\n");
+
   GenerateMetadataPragma(printer, info_path);
 
   GenerateHeader(printer);
@@ -218,78 +261,147 @@
 
 void FileGenerator::GeneratePBHeader(io::Printer* printer,
                                      const string& info_path) {
+  Formatter format(printer, variables_);
   string filename_identifier =
       FilenameIdentifier(file_->name() + (options_.proto_h ? ".pb.h" : ""));
   GenerateTopHeaderGuard(printer, filename_identifier);
 
   if (options_.proto_h) {
     string target_basename = StripProto(file_->name());
-    printer->Print("#include \"$basename$.proto.h\"  // IWYU pragma: export\n",
-                   "basename", target_basename);
+    if (!options_.opensource_runtime) {
+      GetBootstrapBasename(options_, target_basename, &target_basename);
+    }
+    format("#include \"$1$.proto.h\"  // IWYU pragma: export\n",
+           target_basename);
   } else {
     GenerateLibraryIncludes(printer);
   }
 
-  GenerateDependencyIncludes(printer);
+  if (options_.transitive_pb_h) {
+    GenerateDependencyIncludes(printer);
+  }
+
+  // This is unfortunately necessary for some plugins. I don't see why we
+  // need two of the same insertion points.
+  // TODO(gerbens) remove this.
+  format("// @@protoc_insertion_point(includes)\n");
+
   GenerateMetadataPragma(printer, info_path);
 
   if (!options_.proto_h) {
     GenerateHeader(printer);
   } else {
-    // This is unfortunately necessary for some plugins. I don't see why we
-    // need two of the same insertion points.
-    // TODO(gerbens) remove this.
-    printer->Print(
-      "// @@protoc_insertion_point(includes)\n");
     {
-      NamespaceOpener ns(Namespace(file_), printer);
-      printer->Print(
-        "\n"
-        "// @@protoc_insertion_point(namespace_scope)\n");
+      NamespaceOpener ns(Namespace(file_), format);
+      format(
+          "\n"
+          "// @@protoc_insertion_point(namespace_scope)\n");
     }
-    printer->Print(
-      "\n"
-      "// @@protoc_insertion_point(global_scope)\n"
-      "\n");
+    format(
+        "\n"
+        "// @@protoc_insertion_point(global_scope)\n"
+        "\n");
   }
 
   GenerateBottomHeaderGuard(printer, filename_identifier);
 }
 
-void FileGenerator::GenerateSourceIncludes(io::Printer* printer) {
-  string target_basename = StripProto(file_->name());
-  const bool use_system_include = IsWellKnownMessage(file_);
+void FileGenerator::DoIncludeFile(const string& google3_name, bool do_export,
+                                  io::Printer* printer) {
+  Formatter format(printer, variables_);
+  const string prefix = "net/proto2/";
+  GOOGLE_CHECK(google3_name.find(prefix) == 0) << google3_name;
 
-  string header = target_basename + (options_.proto_h ? ".proto.h" : ".pb.h");
-  printer->Print(
-    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
-    "// source: $filename$\n"
-    "\n"
-    "#include $left$$header$$right$\n"
-    "\n"
-    "#include <algorithm>\n"    // for swap()
-    "\n"
-    "#include <google/protobuf/stubs/common.h>\n"
-    "#include <google/protobuf/stubs/port.h>\n"
-    "#include <google/protobuf/io/coded_stream.h>\n"
-    "#include <google/protobuf/wire_format_lite_inl.h>\n",
-    "filename", file_->name(),
-    "header", header,
-    "left", use_system_include ? "<" : "\"",
-    "right", use_system_include ? ">" : "\"");
+  if (options_.opensource_runtime) {
+    string path = google3_name.substr(prefix.size());
+
+    path = StringReplace(path, "internal/", "", false);
+    path = StringReplace(path, "proto/", "", false);
+    path = StringReplace(path, "public/", "", false);
+    if (options_.opensource_include_paths) {
+      format("#include <google/protobuf/$1$>", path);
+    } else {
+      format(
+          "#include "
+          "\"third_party/protobuf/testing/extracted/src/google/protobuf/$1$\"",
+          path);
+    }
+  } else {
+    format("#include \"$1$\"", google3_name);
+  }
+
+  if (do_export) {
+    format("  // IWYU pragma: export");
+  }
+
+  format("\n");
+}
+
+string FileGenerator::CreateHeaderInclude(const string& basename,
+                                          const FileDescriptor* file) {
+  bool use_system_include = false;
+  string name = basename;
+
+  if (options_.opensource_runtime) {
+    if (IsWellKnownMessage(file)) {
+      if (options_.opensource_include_paths) {
+        use_system_include = true;
+      } else {
+        name = "third_party/protobuf/testing/extracted/src/" + basename;
+      }
+    }
+  }
+
+  string left = "\"";
+  string right = "\"";
+  if (use_system_include) {
+    left = "<";
+    right = ">";
+  }
+  return left + name + right;
+}
+
+void FileGenerator::GenerateSourceIncludes(io::Printer* printer) {
+  Formatter format(printer, variables_);
+  string target_basename = StripProto(file_->name());
+  if (!options_.opensource_runtime) {
+    GetBootstrapBasename(options_, target_basename, &target_basename);
+  }
+  target_basename += options_.proto_h ? ".proto.h" : ".pb.h";
+  format(
+      "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
+      "// source: $filename$\n"
+      "\n"
+      "#include $1$\n"
+      "\n"
+      "#include <algorithm>\n"  // for swap()
+      "\n",
+      CreateHeaderInclude(target_basename, file_));
+
+  if (options_.opensource_runtime) {
+    DoIncludeFile("net/proto2/public/stubs/common.h", false, printer);
+  }
+
+  IncludeFile("net/proto2/io/public/coded_stream.h", printer);
+  // TODO(gerbens) This is to include parse_context.h, we need a better way
+  IncludeFile("net/proto2/public/extension_set.h", printer);
+  IncludeFile("net/proto2/public/wire_format_lite_inl.h", printer);
 
   // Unknown fields implementation in lite mode uses StringOutputStream
   if (!UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) {
-    printer->Print(
-      "#include <google/protobuf/io/zero_copy_stream_impl_lite.h>\n");
+    IncludeFile("net/proto2/io/public/zero_copy_stream_impl_lite.h", printer);
   }
 
   if (HasDescriptorMethods(file_, options_)) {
-    printer->Print(
-      "#include <google/protobuf/descriptor.h>\n"
-      "#include <google/protobuf/generated_message_reflection.h>\n"
-      "#include <google/protobuf/reflection_ops.h>\n"
-      "#include <google/protobuf/wire_format.h>\n");
+    IncludeFile("net/proto2/public/descriptor.h", printer);
+    IncludeFile("net/proto2/public/generated_message_reflection.h", printer);
+    IncludeFile("net/proto2/public/reflection_ops.h", printer);
+    IncludeFile("net/proto2/public/wire_format.h", printer);
+  }
+  if (IsProto2MessageSetFile(file_, options_)) {
+    format(
+        // Implementation of proto1 MessageSet API methods.
+        "#include \"net/proto2/bridge/internal/message_set_util.h\"\n");
   }
 
   if (options_.proto_h) {
@@ -298,10 +410,18 @@
       const FileDescriptor* dep = file_->dependency(i);
       const char* extension = ".proto.h";
       string basename = StripProto(dep->name());
+      // Do not import weak deps.
+      if (!options_.opensource_runtime && IsDepWeak(dep)) continue;
+      // The proto1 compiler only generates .pb.h files, so even if we are
+      // running in proto-h mode, we can only use the .pb.h.
+      if (IsProto1(dep, options_)) {
+        extension = ".pb.h";
+      }
+      if (IsBootstrapProto(options_, file_)) {
+        GetBootstrapBasename(options_, basename, &basename);
+      }
       string dependency = basename + extension;
-      printer->Print(
-          "#include \"$dependency$\"\n",
-          "dependency", dependency);
+      format("#include \"$1$\"\n", dependency);
     }
   }
 
@@ -311,91 +431,93 @@
   // and is also linking internal proto2. This is to prevent regressions while
   // we work cleaning up the code base. After this is completed and we have
   // one proto lib all code uses this should be removed.
-  printer->Print(
-    "// This is a temporary google only hack\n"
-    "#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS\n"
-    "#include \"third_party/protobuf/version.h\"\n"
-    "#endif\n");
+  if (options_.opensource_runtime) {
+    format(
+        "// This is a temporary google only hack\n"
+        "#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS\n"
+        "#include \"third_party/protobuf/version.h\"\n"
+        "#endif\n");
+  }
 
-  printer->Print(
-    "// @@protoc_insertion_point(includes)\n");
+  format("// @@protoc_insertion_point(includes)\n");
+  IncludeFile("net/proto2/public/port_def.inc", printer);
 }
 
 void FileGenerator::GenerateSourceDefaultInstance(int idx,
                                                   io::Printer* printer) {
-  printer->Print(
-      "class $classname$DefaultTypeInternal {\n"
+  Formatter format(printer, variables_);
+  format(
+      "class $1$DefaultTypeInternal {\n"
       " public:\n"
-      "  ::google::protobuf::internal::ExplicitlyConstructed<$classname$>\n"
-      "      _instance;\n",
-      "classname", message_generators_[idx]->classname_);
-  printer->Indent();
+      "  ::$proto_ns$::internal::ExplicitlyConstructed<$1$> _instance;\n",
+      message_generators_[idx]->classname_);
+  format.Indent();
   message_generators_[idx]->GenerateExtraDefaultFields(printer);
-  printer->Outdent();
-  printer->Print("} _$classname$_default_instance_;\n", "classname",
-                 message_generators_[idx]->classname_);
+  format.Outdent();
+  format("} _$1$_default_instance_;\n", message_generators_[idx]->classname_);
 }
 
-namespace {
-
 // Generates weak symbol declarations for types that are to be considered weakly
 // referenced.
-void GenerateInternalForwardDeclarations(
+void FileGenerator::GenerateInternalForwardDeclarations(
     const std::vector<const FieldDescriptor*>& fields, const Options& options,
-    SCCAnalyzer* scc_analyzer, io::Printer* printer) {
+    MessageSCCAnalyzer* scc_analyzer, io::Printer* printer) {
+  Formatter format(printer);
   // To ensure determinism and minimize the number of namespace statements,
   // we output the forward declarations sorted on namespace and type / function
   // name.
+  std::set<string> global_namespace_decls;
+  // weak defaults
   std::set<std::pair<string, string> > messages;
-  std::set<std::pair<string, string> > sccs;
-  std::set<std::pair<string, string> > inits;
   for (int i = 0; i < fields.size(); ++i) {
     const FieldDescriptor* field = fields[i];
     const Descriptor* msg = field->message_type();
     if (msg == nullptr) continue;
     bool is_weak = IsImplicitWeakField(field, options, scc_analyzer);
-    string flns = FileLevelNamespace(msg);
-    auto scc = scc_analyzer->GetSCC(msg);
-    string repr = ClassName(scc->GetRepresentative());
+    if (field->options().weak()) {
+      GOOGLE_CHECK(!options_.opensource_runtime);
+      is_weak = true;
+    }
     string weak_attr;
     if (is_weak) {
-      inits.insert(std::make_pair(flns, "AddDescriptors"));
+      global_namespace_decls.insert(
+          "void " + UniqueName("AddDescriptors", msg, options_) +
+          "() __attribute__((weak))");
       messages.insert(std::make_pair(Namespace(msg), ClassName(msg)));
       weak_attr = " __attribute__((weak))";
     }
-    string dllexport = "PROTOBUF_INTERNAL_EXPORT_" + FileLevelNamespace(msg);
-    sccs.insert(std::make_pair(flns, "extern " + dllexport + weak_attr +
-                                     " ::google::protobuf::internal::SCCInfo<" +
-                                     SimpleItoa(scc->children.size()) +
-                                     "> scc_info_" + repr + ";\n"));
+    string dllexport = UniqueName("PROTOBUF_INTERNAL_EXPORT", msg, options_);
+    if (IsProto1(msg->file(), options_) || IsWeak(field, options_)) {
+      dllexport = "";
+    }
+    auto scc = scc_analyzer->GetSCC(msg);
+    string repr =
+        UniqueName(ClassName(scc->GetRepresentative()), msg, options_);
+    global_namespace_decls.insert(
+        "extern " + dllexport + weak_attr + " ::" + ProtobufNamespace(options) +
+        "::internal::SCCInfo<" + SimpleItoa(scc->children.size()) +
+        "> scc_info_" + repr);
   }
 
-  printer->Print("\n");
-  NamespaceOpener ns(printer);
-  for (std::set<std::pair<string, string> >::const_iterator it =
-           messages.begin();
-       it != messages.end(); ++it) {
-    ns.ChangeTo(it->first);
-    printer->Print(
-        "extern __attribute__((weak)) $classname$DefaultTypeInternal "
-        "_$classname$_default_instance_;\n",
-        "classname", it->second);
+  format("\n");
+
+  for (const string& decl : global_namespace_decls) {
+    format("$1$;\n", decl);
   }
-  for (std::set<std::pair<string, string> >::const_iterator it = inits.begin();
-       it != inits.end(); ++it) {
-    ns.ChangeTo(it->first);
-    printer->Print("void $name$() __attribute__((weak));\n",
-                   "name", it->second);
-  }
-  for (const auto& p : sccs) {
-    ns.ChangeTo(p.first);
-    printer->Print(p.second.c_str());
+
+  // Weak external fields
+  NamespaceOpener ns(format);
+  for (const auto& pair : messages) {
+    ns.ChangeTo(pair.first);
+    format(
+        "extern __attribute__((weak)) $1$DefaultTypeInternal "
+        "_$1$_default_instance_;\n",
+        pair.second);
   }
 }
 
-}  // namespace
-
 void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) {
+  Formatter format(printer, variables_);
   GenerateSourceIncludes(printer);
 
   // Generate weak declarations. We do this for the whole strongly-connected
@@ -411,45 +533,43 @@
                                       printer);
 
   if (IsSCCRepresentative(message_generators_[idx]->descriptor_)) {
-    NamespaceOpener ns(FileLevelNamespace(file_), printer);
     GenerateInitForSCC(GetSCC(message_generators_[idx]->descriptor_), printer);
   }
 
   {  // package namespace
-    NamespaceOpener ns(Namespace(file_), printer);
+    NamespaceOpener ns(Namespace(file_), format);
 
     // Define default instances
     GenerateSourceDefaultInstance(idx, printer);
     if (options_.lite_implicit_weak_fields) {
-      printer->Print("void $classname$_ReferenceStrong() {}\n", "classname",
-                     message_generators_[idx]->classname_);
+      format("void $1$_ReferenceStrong() {}\n",
+             message_generators_[idx]->classname_);
     }
 
     // Generate classes.
-    printer->Print("\n");
+    format("\n");
     message_generators_[idx]->GenerateClassMethods(printer);
 
-    printer->Print(
+    format(
         "\n"
         "// @@protoc_insertion_point(namespace_scope)\n");
   }  // end package namespace
 
-  printer->Print(
-      "namespace google {\nnamespace protobuf {\n");
-  message_generators_[idx]->GenerateSourceInProto2Namespace(printer);
-  printer->Print(
-      "}  // namespace protobuf\n}  // namespace google\n");
+  {
+    NamespaceOpener proto_ns(ProtobufNamespace(options_), format);
+    message_generators_[idx]->GenerateSourceInProto2Namespace(printer);
+  }
 
-  printer->Print(
+  format(
       "\n"
       "// @@protoc_insertion_point(global_scope)\n");
 }
 
 void FileGenerator::GenerateGlobalSource(io::Printer* printer) {
+  Formatter format(printer, variables_);
   GenerateSourceIncludes(printer);
 
   {
-    NamespaceOpener ns(FileLevelNamespace(file_), printer);
     GenerateTables(printer);
 
     // Define the code to initialize reflection. This code uses a global
@@ -459,7 +579,7 @@
     }
   }
 
-  NamespaceOpener ns(Namespace(file_), printer);
+  NamespaceOpener ns(Namespace(file_), format);
 
   // Generate enums.
   for (int i = 0; i < enum_generators_.size(); i++) {
@@ -474,15 +594,16 @@
   if (HasGenericServices(file_, options_)) {
     // Generate services.
     for (int i = 0; i < service_generators_.size(); i++) {
-      if (i == 0) printer->Print("\n");
-      printer->Print(kThickSeparator);
-      printer->Print("\n");
+      if (i == 0) format("\n");
+      format(kThickSeparator);
+      format("\n");
       service_generators_[i]->GenerateImplementation(printer);
     }
   }
 }
 
 void FileGenerator::GenerateSource(io::Printer* printer) {
+  Formatter format(printer, variables_);
   GenerateSourceIncludes(printer);
   std::vector<const FieldDescriptor*> fields;
   ListAllFields(file_, &fields);
@@ -490,20 +611,19 @@
                                       printer);
 
   {
-    NamespaceOpener ns(Namespace(file_), printer);
+    NamespaceOpener ns(Namespace(file_), format);
 
     // Define default instances
     for (int i = 0; i < message_generators_.size(); i++) {
       GenerateSourceDefaultInstance(i, printer);
       if (options_.lite_implicit_weak_fields) {
-        printer->Print("void $classname$_ReferenceStrong() {}\n", "classname",
-                       message_generators_[i]->classname_);
+        format("void $1$_ReferenceStrong() {}\n",
+               message_generators_[i]->classname_);
       }
     }
   }
 
   {
-    NamespaceOpener ns(FileLevelNamespace(file_), printer);
     GenerateTables(printer);
 
     // Now generate the InitDefaults for each SCC.
@@ -514,26 +634,28 @@
       }
     }
 
-    printer->Print("void InitDefaults() {\n");
-    for (int i = 0; i < message_generators_.size(); i++) {
-      if (!IsSCCRepresentative(message_generators_[i]->descriptor_)) continue;
-      string scc_name = ClassName(message_generators_[i]->descriptor_);
-      printer->Print(
-          "  ::google::protobuf::internal::InitSCC(&scc_info_$scc_name$.base);\n",
-          "scc_name", scc_name);
-    }
-    printer->Print("}\n\n");
-
-    // Define the code to initialize reflection. This code uses a global
-    // constructor to register reflection data with the runtime pre-main.
     if (HasDescriptorMethods(file_, options_)) {
+      // TODO(gerbens) This is for proto1 interoperability. Remove when proto1
+      // is gone.
+      format("void $init_defaults$() {\n");
+      for (int i = 0; i < message_generators_.size(); i++) {
+        if (!IsSCCRepresentative(message_generators_[i]->descriptor_)) continue;
+        string scc_name =
+            UniqueName(ClassName(message_generators_[i]->descriptor_),
+                       message_generators_[i]->descriptor_, options_);
+        format("  ::$proto_ns$::internal::InitSCC(&scc_info_$1$.base);\n",
+               scc_name);
+      }
+      format("}\n\n");
+
+      // Define the code to initialize reflection. This code uses a global
+      // constructor to register reflection data with the runtime pre-main.
       GenerateReflectionInitializationCode(printer);
     }
   }
 
-
   {
-    NamespaceOpener ns(Namespace(file_), printer);
+    NamespaceOpener ns(Namespace(file_), format);
 
     // Actually implement the protos
 
@@ -544,18 +666,18 @@
 
     // Generate classes.
     for (int i = 0; i < message_generators_.size(); i++) {
-      printer->Print("\n");
-      printer->Print(kThickSeparator);
-      printer->Print("\n");
+      format("\n");
+      format(kThickSeparator);
+      format("\n");
       message_generators_[i]->GenerateClassMethods(printer);
     }
 
     if (HasGenericServices(file_, options_)) {
       // Generate services.
       for (int i = 0; i < service_generators_.size(); i++) {
-        if (i == 0) printer->Print("\n");
-        printer->Print(kThickSeparator);
-        printer->Print("\n");
+        if (i == 0) format("\n");
+        format(kThickSeparator);
+        format("\n");
         service_generators_[i]->GenerateImplementation(printer);
       }
     }
@@ -565,144 +687,26 @@
       extension_generators_[i]->GenerateDefinition(printer);
     }
 
-    printer->Print(
+    format(
+        "\n"
+        "// @@protoc_insertion_point(namespace_scope)\n");
+  }
+
+  {
+    NamespaceOpener proto_ns(ProtobufNamespace(options_), format);
+    for (int i = 0; i < message_generators_.size(); i++) {
+      message_generators_[i]->GenerateSourceInProto2Namespace(printer);
+    }
+  }
+
+  format(
       "\n"
-      "// @@protoc_insertion_point(namespace_scope)\n");
-  }
-
-  printer->Print(
-      "namespace google {\nnamespace protobuf {\n");
-  for (int i = 0; i < message_generators_.size(); i++) {
-    message_generators_[i]->GenerateSourceInProto2Namespace(printer);
-  }
-  printer->Print(
-      "}  // namespace protobuf\n}  // namespace google\n");
-
-  printer->Print(
-    "\n"
-    "// @@protoc_insertion_point(global_scope)\n");
+      "// @@protoc_insertion_point(global_scope)\n");
 }
 
-class FileGenerator::ForwardDeclarations {
- public:
-  ~ForwardDeclarations() {
-    for (std::map<string, ForwardDeclarations*>::iterator
-             it = namespaces_.begin(),
-             end = namespaces_.end();
-         it != end; ++it) {
-      delete it->second;
-    }
-    namespaces_.clear();
-  }
-
-  ForwardDeclarations* AddOrGetNamespace(const string& ns_name) {
-    ForwardDeclarations*& ns = namespaces_[ns_name];
-    if (ns == nullptr) {
-      ns = new ForwardDeclarations;
-    }
-    return ns;
-  }
-
-  std::map<string, const Descriptor*>& classes() { return classes_; }
-  std::map<string, const EnumDescriptor*>& enums() { return enums_; }
-
-  void PrintForwardDeclarations(io::Printer* printer,
-                                const Options& options) const {
-    PrintNestedDeclarations(printer, options);
-    PrintTopLevelDeclarations(printer, options);
-  }
-
-
- private:
-  void PrintNestedDeclarations(io::Printer* printer,
-                               const Options& options) const {
-    PrintDeclarationsInsideNamespace(printer, options);
-    for (std::map<string, ForwardDeclarations *>::const_iterator
-             it = namespaces_.begin(),
-             end = namespaces_.end();
-         it != end; ++it) {
-      printer->Print("namespace $nsname$ {\n",
-                     "nsname", it->first);
-      it->second->PrintNestedDeclarations(printer, options);
-      printer->Print("}  // namespace $nsname$\n",
-                     "nsname", it->first);
-    }
-  }
-
-  void PrintTopLevelDeclarations(io::Printer* printer,
-                                 const Options& options) const {
-    PrintDeclarationsOutsideNamespace(printer, options);
-    for (std::map<string, ForwardDeclarations *>::const_iterator
-             it = namespaces_.begin(),
-             end = namespaces_.end();
-         it != end; ++it) {
-      it->second->PrintTopLevelDeclarations(printer, options);
-    }
-  }
-
-  void PrintDeclarationsInsideNamespace(io::Printer* printer,
-                                        const Options& options) const {
-    for (std::map<string, const EnumDescriptor *>::const_iterator
-             it = enums_.begin(),
-             end = enums_.end();
-         it != end; ++it) {
-      printer->Print("enum $enumname$ : int;\n", "enumname", it->first);
-      printer->Annotate("enumname", it->second);
-      printer->Print("bool $enumname$_IsValid(int value);\n", "enumname",
-                     it->first);
-    }
-    for (std::map<string, const Descriptor*>::const_iterator
-             it = classes_.begin(),
-             end = classes_.end();
-         it != end; ++it) {
-      printer->Print("class $classname$;\n", "classname", it->first);
-      printer->Annotate("classname", it->second);
-
-      printer->Print(
-          "class $classname$DefaultTypeInternal;\n"
-          "$dllexport_decl$"
-          "extern $classname$DefaultTypeInternal "
-          "_$classname$_default_instance_;\n",  // NOLINT
-          "dllexport_decl",
-          options.dllexport_decl.empty() ? "" : options.dllexport_decl + " ",
-          "classname",
-          it->first);
-      if (options.lite_implicit_weak_fields) {
-        printer->Print("void $classname$_ReferenceStrong();\n",
-                       "classname", it->first);
-      }
-    }
-  }
-
-  void PrintDeclarationsOutsideNamespace(io::Printer* printer,
-                                         const Options& options) const {
-    if (classes_.size() == 0) return;
-
-    printer->Print(
-        "namespace google {\nnamespace protobuf {\n");
-    for (std::map<string, const Descriptor*>::const_iterator
-             it = classes_.begin(),
-             end = classes_.end();
-         it != end; ++it) {
-      const Descriptor* d = it->second;
-      printer->Print(
-          "template<> "
-          "$dllexport_decl$"
-          "$classname$* Arena::CreateMaybeMessage<$classname$>"
-          "(Arena*);\n",
-          "classname", QualifiedClassName(d), "dllexport_decl",
-          options.dllexport_decl.empty() ? "" : options.dllexport_decl + " ");
-    }
-    printer->Print(
-        "}  // namespace protobuf\n}  // namespace google\n");
-  }
-
-  std::map<string, ForwardDeclarations*> namespaces_;
-  std::map<string, const Descriptor*> classes_;
-  std::map<string, const EnumDescriptor*> enums_;
-};
-
 void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
+  Formatter format(printer, variables_);
+
   // AddDescriptors() is a file-level procedure which adds the encoded
   // FileDescriptorProto for this .proto file to the global DescriptorPool for
   // generated files (DescriptorPool::generated_pool()). It ordinarily runs at
@@ -716,39 +720,50 @@
   // in the file.
 
   if (!message_generators_.empty()) {
-    printer->Print("::google::protobuf::Metadata file_level_metadata[$size$];\n", "size",
-                   SimpleItoa(message_generators_.size()));
+    format("::$proto_ns$::Metadata $file_level_metadata$[$1$];\n",
+           message_generators_.size());
+  } else {
+    format(
+        "constexpr ::$proto_ns$::Metadata* $file_level_metadata$ = nullptr;\n");
   }
   if (!enum_generators_.empty()) {
-    printer->Print(
-        "const ::google::protobuf::EnumDescriptor* "
-        "file_level_enum_descriptors[$size$];\n",
-        "size", SimpleItoa(enum_generators_.size()));
+    format(
+        "const ::$proto_ns$::EnumDescriptor* "
+        "$file_level_enum_descriptors$[$1$];\n",
+        enum_generators_.size());
+  } else {
+    format(
+        "constexpr ::$proto_ns$::EnumDescriptor const** "
+        "$file_level_enum_descriptors$ = nullptr;\n");
   }
   if (HasGenericServices(file_, options_) && file_->service_count() > 0) {
-    printer->Print(
-        "const ::google::protobuf::ServiceDescriptor* "
-        "file_level_service_descriptors[$size$];\n",
-        "size", SimpleItoa(file_->service_count()));
+    format(
+        "const ::$proto_ns$::ServiceDescriptor* "
+        "$file_level_service_descriptors$[$1$];\n",
+        file_->service_count());
+  } else {
+    format(
+        "constexpr ::$proto_ns$::ServiceDescriptor const** "
+        "$file_level_service_descriptors$ = nullptr;\n");
   }
 
   if (!message_generators_.empty()) {
-    printer->Print(
+    format(
         "\n"
-        "const ::google::protobuf::uint32 TableStruct::offsets[] "
-        "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
-    printer->Indent();
+        "const $uint32$ $tablename$::offsets[] "
+        "$GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
+    format.Indent();
     std::vector<std::pair<size_t, size_t> > pairs;
     pairs.reserve(message_generators_.size());
     for (int i = 0; i < message_generators_.size(); i++) {
       pairs.push_back(message_generators_[i]->GenerateOffsets(printer));
     }
-    printer->Outdent();
-    printer->Print(
+    format.Outdent();
+    format(
         "};\n"
-        "static const ::google::protobuf::internal::MigrationSchema schemas[] "
-        "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
-    printer->Indent();
+        "static const ::$proto_ns$::internal::MigrationSchema schemas[] "
+        "$GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
+    format.Indent();
     {
       int offset = 0;
       for (int i = 0; i < message_generators_.size(); i++) {
@@ -757,30 +772,33 @@
         offset += pairs[i].first;
       }
     }
-    printer->Outdent();
-    printer->Print(
+    format.Outdent();
+    format(
         "};\n"
         "\nstatic "
-        "::google::protobuf::Message const * const file_default_instances[] = {\n");
-    printer->Indent();
+        "::$proto_ns$::Message const * const file_default_instances[] = {\n");
+    format.Indent();
     for (int i = 0; i < message_generators_.size(); i++) {
       const Descriptor* descriptor = message_generators_[i]->descriptor_;
-      printer->Print(
+      format(
           "reinterpret_cast<const "
-          "::google::protobuf::Message*>(&$ns$::_$classname$_default_instance_),\n",
-          "classname", ClassName(descriptor), "ns", Namespace(descriptor));
+          "::$proto_ns$::Message*>(&$1$::_$2$_default_instance_),\n",
+          Namespace(descriptor),   // 1
+          ClassName(descriptor));  // 2
     }
-    printer->Outdent();
-    printer->Print(
+    format.Outdent();
+    format(
         "};\n"
         "\n");
   } else {
     // we still need these symbols to exist
-    printer->Print(
+    format(
         // MSVC doesn't like empty arrays, so we add a dummy.
-        "const ::google::protobuf::uint32 TableStruct::offsets[1] = {};\n"
-        "static const ::google::protobuf::internal::MigrationSchema* schemas = NULL;\n"
-        "static const ::google::protobuf::Message* const* "
+        "const $uint32$ $tablename$::offsets[1] = {};\n"
+        "static constexpr ::$proto_ns$::internal::MigrationSchema* schemas = "
+        "NULL;"
+        "\n"
+        "static constexpr ::$proto_ns$::Message* const* "
         "file_default_instances = NULL;\n"
         "\n");
   }
@@ -790,161 +808,90 @@
   // protobuf_AssignDescriptorsOnce():  The first time it is called, calls
   // AssignDescriptors().  All later times, waits for the first call to
   // complete and then returns.
-    printer->Print(
-        "static void protobuf_AssignDescriptors() {\n"
-        // Make sure the file has found its way into the pool.  If a descriptor
-        // is requested *during* static init then AddDescriptors() may not have
-        // been called yet, so we call it manually.  Note that it's fine if
-        // AddDescriptors() is called multiple times.
-        "  AddDescriptors();\n"
-        "  AssignDescriptors(\n"
-        "      \"$filename$\", schemas, file_default_instances, "
-        "TableStruct::offsets,\n"
-        "      $metadata$, $enum_descriptors$, $service_descriptors$);\n",
-        "filename", file_->name(), "metadata",
-        !message_generators_.empty() ? "file_level_metadata" : "NULL",
-        "enum_descriptors",
-        !enum_generators_.empty() ? "file_level_enum_descriptors" : "NULL",
-        "service_descriptors",
-        HasGenericServices(file_, options_) && file_->service_count() > 0
-            ? "file_level_service_descriptors"
-            : "NULL");
-    printer->Print(
-        "}\n"
-        "\n"
-        "static void protobuf_AssignDescriptorsOnce() {\n"
-        "  static ::google::protobuf::internal::once_flag once;\n"
-        "  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);\n"
-        "}\n"
-        "\n",
-        "filename", file_->name(), "metadata",
-        !message_generators_.empty() ? "file_level_metadata" : "NULL",
-        "enum_descriptors",
-        !enum_generators_.empty() ? "file_level_enum_descriptors" : "NULL",
-        "service_descriptors",
-        HasGenericServices(file_, options_) && file_->service_count() > 0
-            ? "file_level_service_descriptors"
-            : "NULL");
+  format(
+      "::$proto_ns$::internal::AssignDescriptorsTable $assign_desc_table$ = "
+      "{\n"
+      "  {}, $add_descriptors$, \"$filename$\", schemas,\n"
+      "  file_default_instances, $tablename$::offsets,\n"
+      "  $file_level_metadata$, $1$, $file_level_enum_descriptors$, "
+      "$file_level_service_descriptors$,\n"
+      "};\n"
+      "\n",
+      message_generators_.size());
 
-    // Only here because of useless string reference that we don't want in
-    // protobuf_AssignDescriptorsOnce, because that is called from all the
-    // GetMetadata member methods.
-    printer->Print(
-        "void protobuf_RegisterTypes(const ::std::string&) "
-        "GOOGLE_PROTOBUF_ATTRIBUTE_COLD;\n"
-        "void protobuf_RegisterTypes(const ::std::string&) {\n"
-        "  protobuf_AssignDescriptorsOnce();\n");
-    printer->Indent();
+  // Now generate the AddDescriptors() function.
+  format(
+      "::$proto_ns$::internal::DescriptorTable $1$ = {\n"
+      "  false, $init_defaults$, \n",
+      UniqueName("descriptor_table", file_, options_));
+  format.Indent();
 
-    // All normal messages can be done generically
-    if (!message_generators_.empty()) {
-      printer->Print(
-        "::google::protobuf::internal::RegisterAllTypes(file_level_metadata, $size$);\n",
-        "size", SimpleItoa(message_generators_.size()));
+  // Embed the descriptor.  We simply serialize the entire
+  // FileDescriptorProto
+  // and embed it as a string literal, which is parsed and built into real
+  // descriptors at initialization time.
+  FileDescriptorProto file_proto;
+  file_->CopyTo(&file_proto);
+  string file_data;
+  file_proto.SerializeToString(&file_data);
+
+  {
+    // Only write 40 bytes per line.
+    static const int kBytesPerLine = 40;
+    for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
+      format(
+          "\"$1$\"\n",
+          EscapeTrigraphs(CEscape(file_data.substr(i, kBytesPerLine))));
     }
-
-    printer->Outdent();
-    printer->Print(
-        "}\n"
-        "\n");
-
-    // Now generate the AddDescriptors() function.
-    printer->Print(
-        "static void AddDescriptorsImpl() {\n"
-        "  InitDefaults();\n");
-    printer->Indent();
-
-    // Embed the descriptor.  We simply serialize the entire
-    // FileDescriptorProto
-    // and embed it as a string literal, which is parsed and built into real
-    // descriptors at initialization time.
-    FileDescriptorProto file_proto;
-    file_->CopyTo(&file_proto);
-    string file_data;
-    file_proto.SerializeToString(&file_data);
-
-    printer->Print("static const char descriptor[] "
-                   "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) "
-                   "= {\n");
-    printer->Indent();
-
-    if (file_data.size() > 65535) {
-      // Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535
-      // bytes in length". Declare a static array of characters rather than use
-      // a string literal. Only write 25 bytes per line.
-      static const int kBytesPerLine = 25;
-      for (int i = 0; i < file_data.size();) {
-        for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) {
-          printer->Print("'$char$', ", "char",
-                         CEscape(file_data.substr(i, 1)));
-        }
-        printer->Print("\n");
-      }
-    } else {
-      // Only write 40 bytes per line.
-      static const int kBytesPerLine = 40;
-      for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
-        printer->Print("  \"$data$\"\n", "data",
-                       EscapeTrigraphs(CEscape(
-                           file_data.substr(i, kBytesPerLine))));
-      }
-    }
-
-    printer->Outdent();
-    printer->Print("};\n");
-    printer->Print(
-        "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(\n"
-        "    descriptor, $size$);\n",
-        "size", SimpleItoa(file_data.size()));
-
-    // Call MessageFactory::InternalRegisterGeneratedFile().
-    printer->Print(
-      "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n"
-      "  \"$filename$\", &protobuf_RegisterTypes);\n",
-      "filename", file_->name());
-
-  // Call the AddDescriptors() methods for all of our dependencies, to make
-  // sure they get added first.
-  for (int i = 0; i < file_->dependency_count(); i++) {
-    const FileDescriptor* dependency = file_->dependency(i);
-    // Print the namespace prefix for the dependency.
-    string file_namespace = FileLevelNamespace(dependency);
-    // Call its AddDescriptors function.
-    printer->Print("::$file_namespace$::AddDescriptors();\n", "file_namespace",
-                   file_namespace);
   }
 
-  printer->Outdent();
-  printer->Print(
-      "}\n"
-      "\n"
-      "void AddDescriptors() {\n"
-        "  static ::google::protobuf::internal::once_flag once;\n"
-        "  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);\n"
-      "}\n");
-
-    printer->Print(
-        "// Force AddDescriptors() to be called at dynamic initialization "
-        "time.\n"
-        "struct StaticDescriptorInitializer {\n"
-        "  StaticDescriptorInitializer() {\n"
-        "    AddDescriptors();\n"
-        "  }\n"
-        "} static_descriptor_initializer;\n");
+  format.Outdent();
+  const int num_deps = file_->dependency_count();
+  format(
+      ",\n  \"$filename$\", &$assign_desc_table$, $1$,\n"
+      "};\n\n"
+      "void $add_descriptors$() {\n"
+      "  static constexpr ::$proto_ns$::internal::InitFunc deps[$2$] =\n"
+      "  {\n",
+      file_data.size(), std::max(num_deps, 1));
+  for (int i = 0; i < num_deps; i++) {
+    const FileDescriptor* dependency = file_->dependency(i);
+    format("    ::$1$,\n", UniqueName("AddDescriptors", dependency, options_));
+  }
+  format(
+      "  };\n"
+      " ::$proto_ns$::internal::AddDescriptors(&$1$, deps, $2$);\n"
+      "}\n\n",
+      UniqueName("descriptor_table", file_, options_),  // 1
+      num_deps);                                        // 2
+  format(
+      "// Force running AddDescriptors() at dynamic initialization time.\n"
+      "static bool $1$ = []() { $add_descriptors$(); return true; }();\n",
+      UniqueName("dynamic_init_dummy", file_, options_));
 }
 
 void FileGenerator::GenerateInitForSCC(const SCC* scc, io::Printer* printer) {
+  Formatter format(printer, variables_);
   const string scc_name = ClassName(scc->GetRepresentative());
   // We use static and not anonymous namespace because symbol names are
   // substantially shorter.
-  printer->Print(
-      "static void InitDefaults$scc_name$() {\n"
-      "  GOOGLE_PROTOBUF_VERIFY_VERSION;\n\n"
-      ,  // awkward comma due to macro
-      "scc_name", scc_name);
+  format("static void InitDefaults$1$() {\n",
+         UniqueName(scc_name, scc->GetRepresentative(), options_));
 
-  printer->Indent();
+  if (options_.opensource_runtime) {
+    format("  GOOGLE_PROTOBUF_VERIFY_VERSION;\n\n");
+  }
 
+  format.Indent();
+
+  if (!options_.opensource_runtime) {
+    for (int i = 0; i < scc->children.size(); i++) {
+      const SCC* child_scc = scc->children[i];
+      const FileDescriptor* dependency = child_scc->GetRepresentative()->file();
+      if (!IsProto1(dependency, options_)) continue;
+      format("$1$();\n", UniqueName("InitDefaults", dependency, options_));
+    }
+  }
 
   // First construct all the necessary default instances.
   for (int i = 0; i < message_generators_.size(); i++) {
@@ -954,17 +901,18 @@
     // TODO(gerbens) This requires this function to be friend. Remove
     // the need for this.
     message_generators_[i]->GenerateFieldDefaultInstances(printer);
-    printer->Print(
+    format(
         "{\n"
-        "  void* ptr = &$ns$::_$classname$_default_instance_;\n"
-        "  new (ptr) $ns$::$classname$();\n",
-        "ns", Namespace(message_generators_[i]->descriptor_),
-        "classname", ClassName(message_generators_[i]->descriptor_));
-    if (!IsMapEntryMessage(message_generators_[i]->descriptor_)) {
-      printer->Print(
+        "  void* ptr = &$1$::_$2$_default_instance_;\n"
+        "  new (ptr) $1$::$2$();\n",
+        Namespace(message_generators_[i]->descriptor_),   // 1
+        ClassName(message_generators_[i]->descriptor_));  // 2
+    if (options_.opensource_runtime &&
+        !IsMapEntryMessage(message_generators_[i]->descriptor_)) {
+      format(
           "  ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);\n");
     }
-    printer->Print("}\n");
+    format("}\n");
   }
 
   // TODO(gerbens) make default instances be the same as normal instances.
@@ -974,37 +922,44 @@
     if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) {
       continue;
     }
-    printer->Print("$classname$::InitAsDefaultInstance();\n", "classname",
-                   QualifiedClassName(message_generators_[i]->descriptor_));
+    format("$1$::InitAsDefaultInstance();\n",
+           QualifiedClassName(message_generators_[i]->descriptor_));
   }
-  printer->Outdent();
-  printer->Print("}\n\n");
+  format.Outdent();
+  format("}\n\n");
 
-  printer->Print(
-      "$dllexport_decl$::google::protobuf::internal::SCCInfo<$size$> "
-      "scc_info_$scc_name$ =\n"
-      "    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), "
-      "$size$, InitDefaults$scc_name$}, {",
-      "size", SimpleItoa(scc->children.size()), "scc_name",
-      ClassName(scc->GetRepresentative()), "dllexport_decl",
-      options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ");
+  format(
+      "$dllexport_decl $::$proto_ns$::internal::SCCInfo<$1$> "
+      "scc_info_$2$ =\n"
+      "    "
+      "{{ATOMIC_VAR_INIT(::$proto_ns$::internal::SCCInfoBase::kUninitialized), "
+      "$1$, InitDefaults$2$}, {",
+      scc->children.size(),  // 1
+      UniqueName(ClassName(scc->GetRepresentative()), scc->GetRepresentative(),
+                 options_));
   for (const SCC* child : scc->children) {
     auto repr = child->GetRepresentative();
-    printer->Print("\n      &$ns$::scc_info_$child$.base,", "ns",
-                   FileLevelNamespace(repr), "child", ClassName(repr));
+    if (IsProto1(repr->file(), options_)) {
+      GOOGLE_CHECK(!options_.opensource_runtime);
+      format("\n      nullptr,");
+      continue;
+    }
+    format("\n      &scc_info_$1$.base,",
+           UniqueName(ClassName(repr), repr, options_));
   }
-  printer->Print("}};\n\n");
+  format("}};\n\n");
 }
 
 void FileGenerator::GenerateTables(io::Printer* printer) {
+  Formatter format(printer, variables_);
   if (options_.table_driven_parsing) {
     // TODO(ckennelly): Gate this with the same options flag to enable
     // table-driven parsing.
-    printer->Print(
-        "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField\n"
-        "    const TableStruct::entries[] "
-        "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
-    printer->Indent();
+    format(
+        "PROTOBUF_CONSTEXPR_VAR ::$proto_ns$::internal::ParseTableField\n"
+        "    const $tablename$::entries[] "
+        "$GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
+    format.Indent();
 
     std::vector<size_t> entries;
     size_t count = 0;
@@ -1016,17 +971,18 @@
 
     // We need these arrays to exist, and MSVC does not like empty arrays.
     if (count == 0) {
-      printer->Print("{0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},\n");
+      format("{0, 0, 0, ::$proto_ns$::internal::kInvalidMask, 0, 0},\n");
     }
 
-    printer->Outdent();
-    printer->Print(
+    format.Outdent();
+    format(
         "};\n"
         "\n"
-        "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField\n"
-        "    const TableStruct::aux[] "
-        "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
-    printer->Indent();
+        "PROTOBUF_CONSTEXPR_VAR "
+        "::$proto_ns$::internal::AuxillaryParseTableField\n"
+        "    const $tablename$::aux[] "
+        "$GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
+    format.Indent();
 
     std::vector<size_t> aux_entries;
     count = 0;
@@ -1037,16 +993,16 @@
     }
 
     if (count == 0) {
-      printer->Print("::google::protobuf::internal::AuxillaryParseTableField(),\n");
+      format("::$proto_ns$::internal::AuxillaryParseTableField(),\n");
     }
 
-    printer->Outdent();
-    printer->Print(
+    format.Outdent();
+    format(
         "};\n"
-        "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const\n"
-        "    TableStruct::schema[] "
-        "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
-    printer->Indent();
+        "PROTOBUF_CONSTEXPR_VAR ::$proto_ns$::internal::ParseTable const\n"
+        "    $tablename$::schema[] "
+        "$GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
+    format.Indent();
 
     size_t offset = 0;
     size_t aux_offset = 0;
@@ -1057,20 +1013,21 @@
     }
 
     if (message_generators_.empty()) {
-      printer->Print("{ NULL, NULL, 0, -1, -1, false },\n");
+      format("{ NULL, NULL, 0, -1, -1, false },\n");
     }
 
-    printer->Outdent();
-    printer->Print(
+    format.Outdent();
+    format(
         "};\n"
         "\n");
   }
 
   if (!message_generators_.empty() && options_.table_driven_serialization) {
-    printer->Print(
-        "const ::google::protobuf::internal::FieldMetadata TableStruct::field_metadata[] "
+    format(
+        "const ::$proto_ns$::internal::FieldMetadata "
+        "$tablename$::field_metadata[] "
         "= {\n");
-    printer->Indent();
+    format.Indent();
     std::vector<int> field_metadata_offsets;
     int idx = 0;
     for (int i = 0; i < message_generators_.size(); i++) {
@@ -1078,12 +1035,12 @@
       idx += message_generators_[i]->GenerateFieldMetadata(printer);
     }
     field_metadata_offsets.push_back(idx);
-    printer->Outdent();
-    printer->Print(
+    format.Outdent();
+    format(
         "};\n"
-        "const ::google::protobuf::internal::SerializationTable "
-        "TableStruct::serialization_table[] = {\n");
-    printer->Indent();
+        "const ::$proto_ns$::internal::SerializationTable "
+        "$tablename$::serialization_table[] = {\n");
+    format.Indent();
     // We rely on the order we layout the tables to match the order we
     // calculate them with FlattenMessagesInFile, so we check here that
     // these match exactly.
@@ -1092,235 +1049,327 @@
     GOOGLE_CHECK_EQ(calculated_order.size(), message_generators_.size());
     for (int i = 0; i < message_generators_.size(); i++) {
       GOOGLE_CHECK_EQ(calculated_order[i], message_generators_[i]->descriptor_);
-      printer->Print(
-          "{$num_fields$, TableStruct::field_metadata + $index$},\n",
-          "classname", message_generators_[i]->classname_, "num_fields",
-          SimpleItoa(field_metadata_offsets[i + 1] - field_metadata_offsets[i]),
-          "index", SimpleItoa(field_metadata_offsets[i]));
+      format("{$1$, $tablename$::field_metadata + $2$},\n",
+             field_metadata_offsets[i + 1] - field_metadata_offsets[i],  // 1
+             field_metadata_offsets[i]);                                 // 2
     }
-    printer->Outdent();
-    printer->Print(
+    format.Outdent();
+    format(
         "};\n"
         "\n");
   }
 }
 
-void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) {
-  ForwardDeclarations decls;
-  FillForwardDeclarations(&decls);
-  decls.PrintForwardDeclarations(printer, options_);
+class FileGenerator::ForwardDeclarations {
+ public:
+  void AddMessage(const Descriptor* d) { classes_[ClassName(d)] = d; }
+  void AddEnum(const EnumDescriptor* d) { enums_[ClassName(d)] = d; }
+
+  void Print(const Formatter& format, const Options& options) const {
+    for (const auto& p : enums_) {
+      const string& enumname = p.first;
+      const EnumDescriptor* enum_desc = p.second;
+      format(
+          "enum ${1$$2$$}$ : int;\n"
+          "bool $2$_IsValid(int value);\n",
+          enum_desc, enumname);
+    }
+    for (const auto& p : classes_) {
+      const string& classname = p.first;
+      const Descriptor* class_desc = p.second;
+      format(
+          "class ${1$$2$$}$;\n"
+          "class $2$DefaultTypeInternal;\n"
+          "$dllexport_decl $extern "
+          "$2$DefaultTypeInternal _$2$_default_instance_;\n",
+          class_desc, classname);
+      if (options.lite_implicit_weak_fields) {
+        format("void $1$_ReferenceStrong();\n", classname);
+      }
+    }
+  }
+
+  void PrintTopLevelDecl(const Formatter& format) const {
+    for (const auto& pair : classes_) {
+      format(
+          "template<> $dllexport_decl $"
+          "$1$* Arena::CreateMaybeMessage<$1$>(Arena*);\n",
+          QualifiedClassName(pair.second));
+    }
+  }
+
+ private:
+  std::map<string, const Descriptor*> classes_;
+  std::map<string, const EnumDescriptor*> enums_;
+};
+
+static void PublicImportDFS(const FileDescriptor* fd,
+                            std::unordered_set<const FileDescriptor*>* fd_set) {
+  for (int i = 0; i < fd->public_dependency_count(); i++) {
+    const FileDescriptor* dep = fd->public_dependency(i);
+    if (fd_set->insert(dep).second) PublicImportDFS(dep, fd_set);
+  }
 }
 
-void FileGenerator::FillForwardDeclarations(ForwardDeclarations* decls) {
-  for (int i = 0; i < package_parts_.size(); i++) {
-    decls = decls->AddOrGetNamespace(package_parts_[i]);
+void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) {
+  Formatter format(printer, variables_);
+  std::vector<const Descriptor*> classes;
+  std::vector<const EnumDescriptor*> enums;
+
+  FlattenMessagesInFile(file_, &classes);  // All messages need forward decls.
+
+  if (options_.proto_h) {  // proto.h needs extra forward declarations.
+    // All classes / enums refered to as field members
+    std::vector<const FieldDescriptor*> fields;
+    ListAllFields(file_, &fields);
+    for (int i = 0; i < fields.size(); i++) {
+      classes.push_back(fields[i]->containing_type());
+      classes.push_back(fields[i]->message_type());
+      enums.push_back(fields[i]->enum_type());
+    }
+    ListAllTypesForServices(file_, &classes);
   }
-  // Generate enum definitions.
-  for (int i = 0; i < enum_generators_.size(); i++) {
-    enum_generators_[i]->FillForwardDeclaration(&decls->enums());
+
+  // Calculate the set of files whose definitions we get through include.
+  // No need to forward declare types that are defined in these.
+  std::unordered_set<const FileDescriptor*> public_set;
+  PublicImportDFS(file_, &public_set);
+
+  std::map<string, ForwardDeclarations> decls;
+  for (int i = 0; i < classes.size(); i++) {
+    const Descriptor* d = classes[i];
+    if (d && !public_set.count(d->file())) decls[Namespace(d)].AddMessage(d);
   }
-  // Generate forward declarations of classes.
-  for (int i = 0; i < message_generators_.size(); i++) {
-    message_generators_[i]->FillMessageForwardDeclarations(
-        &decls->classes());
+  for (int i = 0; i < enums.size(); i++) {
+    const EnumDescriptor* d = enums[i];
+    if (d && !public_set.count(d->file())) decls[Namespace(d)].AddEnum(d);
+  }
+
+
+  NamespaceOpener ns(format);
+  for (const auto& pair : decls) {
+    ns.ChangeTo(pair.first);
+    pair.second.Print(format, options_);
+  }
+  ns.ChangeTo(variables_["proto_ns"]);
+  for (const auto& pair : decls) {
+    pair.second.PrintTopLevelDecl(format);
   }
 }
 
 void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer,
                                            const string& filename_identifier) {
+  Formatter format(printer, variables_);
   // Generate top of header.
-  printer->Print(
+  format(
       "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
       "// source: $filename$\n"
       "\n"
-      "#ifndef PROTOBUF_INCLUDED_$filename_identifier$\n"
-      "#define PROTOBUF_INCLUDED_$filename_identifier$\n"
+      "#ifndef PROTOBUF_INCLUDED_$1$\n"
+      "#define PROTOBUF_INCLUDED_$1$\n"
       "\n"
+      "#include <limits>\n"
       "#include <string>\n",
-      "filename", file_->name(), "filename_identifier", filename_identifier);
-  printer->Print("\n");
+      filename_identifier);
+  if (!options_.opensource_runtime && !enum_generators_.empty()) {
+    // Add header to provide std::is_integral for safe Enum_Name() function.
+    format("#include <type_traits>\n");
+  }
+  format("\n");
 }
 
 void FileGenerator::GenerateBottomHeaderGuard(
     io::Printer* printer, const string& filename_identifier) {
-  printer->Print(
-    "#endif  // PROTOBUF_INCLUDED_$filename_identifier$\n",
-    "filename_identifier", filename_identifier);
+  Formatter format(printer, variables_);
+  format("#endif  // PROTOBUF_INCLUDED_$1$\n", filename_identifier);
 }
 
 void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
+  Formatter format(printer, variables_);
   if (UsingImplicitWeakFields(file_, options_)) {
-    printer->Print("#include <google/protobuf/implicit_weak_message.h>\n");
+    IncludeFile("net/proto2/public/implicit_weak_message.h", printer);
+  }
+  if (HasWeakFields(file_, options_)) {
+    GOOGLE_CHECK(!options_.opensource_runtime);
+    IncludeFile("net/proto2/public/weak_field_map.h", printer);
+  }
+  if (HasLazyFields(file_, options_)) {
+    GOOGLE_CHECK(!options_.opensource_runtime);
+    IncludeFile("net/proto2/public/lazy_field.h", printer);
   }
 
-  printer->Print(
-    "#include <google/protobuf/stubs/common.h>\n"
-    "\n");
+  if (options_.opensource_runtime) {
+    DoIncludeFile("net/proto2/public/stubs/common.h", false, printer);
 
-  // Verify the protobuf library header version is compatible with the protoc
-  // version before going any further.
-  printer->Print(
-    "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\n"
-    "#error This file was generated by a newer version of protoc which is\n"
-    "#error incompatible with your Protocol Buffer headers.  Please update\n"
-    "#error your headers.\n"
-    "#endif\n"
-    "#if $protoc_version$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n"
-    "#error This file was generated by an older version of protoc which is\n"
-    "#error incompatible with your Protocol Buffer headers.  Please\n"
-    "#error regenerate this file with a newer version of protoc.\n"
-    "#endif\n"
-    "\n",
-    "min_header_version",
-      SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc),
-    "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION));
+    // Verify the protobuf library header version is compatible with the protoc
+    // version before going any further.
+    format(
+        "#if GOOGLE_PROTOBUF_VERSION < $1$\n"
+        "#error This file was generated by a newer version of protoc which is\n"
+        "#error incompatible with your Protocol Buffer headers. Please update\n"
+        "#error your headers.\n"
+        "#endif\n"
+        "#if $2$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n"
+        "#error This file was generated by an older version of protoc which "
+        "is\n"
+        "#error incompatible with your Protocol Buffer headers. Please\n"
+        "#error regenerate this file with a newer version of protoc.\n"
+        "#endif\n"
+        "\n",
+        GOOGLE_PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC,  // 1
+        GOOGLE_PROTOBUF_VERSION);                       // 2
+  }
 
   // OK, it's now safe to #include other files.
-  printer->Print(
-      "#include <google/protobuf/io/coded_stream.h>\n"
-      "#include <google/protobuf/arena.h>\n"
-      "#include <google/protobuf/arenastring.h>\n"
-      "#include <google/protobuf/generated_message_table_driven.h>\n"
-      "#include <google/protobuf/generated_message_util.h>\n"
-      "#include <google/protobuf/inlined_string_field.h>\n");
-
+  IncludeFile("net/proto2/io/public/coded_stream.h", printer);
+  IncludeFile("net/proto2/public/arena.h", printer);
+  IncludeFile("net/proto2/public/arenastring.h", printer);
+  IncludeFile("net/proto2/public/generated_message_table_driven.h", printer);
+  IncludeFile("net/proto2/public/generated_message_util.h", printer);
+  IncludeFile("net/proto2/public/inlined_string_field.h", printer);
 
   if (HasDescriptorMethods(file_, options_)) {
-    printer->Print(
-      "#include <google/protobuf/metadata.h>\n");
+    IncludeFile("net/proto2/public/metadata.h", printer);
   } else {
-    printer->Print(
-      "#include <google/protobuf/metadata_lite.h>\n");
+    IncludeFile("net/proto2/public/metadata_lite.h", printer);
   }
 
   if (!message_generators_.empty()) {
     if (HasDescriptorMethods(file_, options_)) {
-      printer->Print(
-        "#include <google/protobuf/message.h>\n");
+      IncludeFile("net/proto2/public/message.h", printer);
     } else {
-      printer->Print(
-        "#include <google/protobuf/message_lite.h>\n");
+      IncludeFile("net/proto2/public/message_lite.h", printer);
     }
   }
-  printer->Print(
-    "#include <google/protobuf/repeated_field.h>"
-    "  // IWYU pragma: export\n"
-    "#include <google/protobuf/extension_set.h>"
-    "  // IWYU pragma: export\n");
+  if (options_.opensource_runtime) {
+    // Open-source relies on unconditional includes of these.
+    IncludeFileAndExport("net/proto2/public/repeated_field.h", printer);
+    IncludeFileAndExport("net/proto2/public/extension_set.h", printer);
+  } else {
+    // Google3 includes these files only when they are necessary.
+    if (HasExtensionsOrExtendableMessage(file_)) {
+      IncludeFileAndExport("net/proto2/public/extension_set.h", printer);
+    }
+    if (HasRepeatedFields(file_)) {
+      IncludeFileAndExport("net/proto2/public/repeated_field.h", printer);
+    }
+    if (HasStringPieceFields(file_, options_)) {
+      IncludeFile("net/proto2/public/string_piece_field_support.h", printer);
+    }
+    if (HasCordFields(file_, options_)) {
+      format("#include \"third_party/absl/strings/cord.h\"\n");
+    }
+  }
   if (HasMapFields(file_)) {
-    printer->Print(
-        "#include <google/protobuf/map.h>"
-        "  // IWYU pragma: export\n");
+    IncludeFileAndExport("net/proto2/public/map.h", printer);
     if (HasDescriptorMethods(file_, options_)) {
-      printer->Print("#include <google/protobuf/map_entry.h>\n");
-      printer->Print("#include <google/protobuf/map_field_inl.h>\n");
+      IncludeFile("net/proto2/public/map_entry.h", printer);
+      IncludeFile("net/proto2/public/map_field_inl.h", printer);
     } else {
-      printer->Print("#include <google/protobuf/map_entry_lite.h>\n");
-      printer->Print("#include <google/protobuf/map_field_lite.h>\n");
+      IncludeFile("net/proto2/public/map_entry_lite.h", printer);
+      IncludeFile("net/proto2/public/map_field_lite.h", printer);
     }
   }
 
   if (HasEnumDefinitions(file_)) {
     if (HasDescriptorMethods(file_, options_)) {
-      printer->Print(
-          "#include <google/protobuf/generated_enum_reflection.h>\n");
+      IncludeFile("net/proto2/public/generated_enum_reflection.h", printer);
     } else {
-      printer->Print(
-          "#include <google/protobuf/generated_enum_util.h>\n");
+      IncludeFile("net/proto2/public/generated_enum_util.h", printer);
     }
   }
 
   if (HasGenericServices(file_, options_)) {
-    printer->Print(
-      "#include <google/protobuf/service.h>\n");
+    IncludeFile("net/proto2/public/service.h", printer);
   }
 
   if (UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) {
-    printer->Print(
-      "#include <google/protobuf/unknown_field_set.h>\n");
+    IncludeFile("net/proto2/public/unknown_field_set.h", printer);
   }
 
-
   if (IsAnyMessage(file_)) {
-    printer->Print(
-      "#include <google/protobuf/any.h>\n");
+    IncludeFile("net/proto2/internal/any.h", printer);
   }
 }
 
 void FileGenerator::GenerateMetadataPragma(io::Printer* printer,
                                            const string& info_path) {
+  Formatter format(printer, variables_);
   if (!info_path.empty() && !options_.annotation_pragma_name.empty() &&
       !options_.annotation_guard_name.empty()) {
-    printer->Print(
+    format.Set("guard", options_.annotation_guard_name);
+    format.Set("pragma", options_.annotation_pragma_name);
+    format.Set("info_path", info_path);
+    format(
         "#ifdef $guard$\n"
         "#pragma $pragma$ \"$info_path$\"\n"
-        "#endif  // $guard$\n",
-        "guard", options_.annotation_guard_name, "pragma",
-        options_.annotation_pragma_name, "info_path", info_path);
+        "#endif  // $guard$\n");
   }
 }
 
 void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) {
-  std::set<string> public_import_names;
-  for (int i = 0; i < file_->public_dependency_count(); i++) {
-    public_import_names.insert(file_->public_dependency(i)->name());
-  }
-
+  Formatter format(printer, variables_);
   for (int i = 0; i < file_->dependency_count(); i++) {
-    const bool use_system_include = IsWellKnownMessage(file_->dependency(i));
-    const string& name = file_->dependency(i)->name();
-    bool public_import = (public_import_names.count(name) != 0);
-    string basename = StripProto(name);
+    string basename = StripProto(file_->dependency(i)->name());
 
+    // Do not import weak deps.
+    if (IsDepWeak(file_->dependency(i))) continue;
 
-    printer->Print(
-      "#include $left$$dependency$.pb.h$right$$iwyu$\n",
-      "dependency", basename,
-      "iwyu", (public_import) ? "  // IWYU pragma: export" : "",
-      "left", use_system_include ? "<" : "\"",
-      "right", use_system_include ? ">" : "\"");
+    if (IsBootstrapProto(options_, file_)) {
+      GetBootstrapBasename(options_, basename, &basename);
+    }
+
+    format("#include $1$\n",
+           CreateHeaderInclude(basename + ".pb.h", file_->dependency(i)));
   }
 }
 
 void FileGenerator::GenerateGlobalStateFunctionDeclarations(
     io::Printer* printer) {
-// Forward-declare the AddDescriptors, InitDefaults because these are called
-// by .pb.cc files depending on this file.
-  printer->Print(
+  Formatter format(printer, variables_);
+  // Forward-declare the AddDescriptors, InitDefaults because these are called
+  // by .pb.cc files depending on this file.
+  //
+  // The TableStruct is also outputted in weak_message_field.cc, because the
+  // weak fields must refer to table struct but cannot include the header.
+  // Also it annotates extra weak attributes.
+  // TODO(gerbens) make sure this situation is handled better.
+  format(
       "\n"
-      "namespace $file_namespace$ {\n"
       "// Internal implementation detail -- do not use these members.\n"
-      "struct $dllexport_decl$TableStruct {\n"
+      "struct $dllexport_decl $$tablename$ {\n"
       // These tables describe how to serialize and parse messages. Used
       // for table driven code.
-      "  static const ::google::protobuf::internal::ParseTableField entries[];\n"
-      "  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];\n"
-      "  static const ::google::protobuf::internal::ParseTable schema[$num$];\n"
-      "  static const ::google::protobuf::internal::FieldMetadata field_metadata[];\n"
-      "  static const ::google::protobuf::internal::SerializationTable "
+      "  static const ::$proto_ns$::internal::ParseTableField entries[]\n"
+      "    $GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);\n"
+      "  static const ::$proto_ns$::internal::AuxillaryParseTableField aux[]\n"
+      "    $GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);\n"
+      "  static const ::$proto_ns$::internal::ParseTable schema[$1$]\n"
+      "    $GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);\n"
+      "  static const ::$proto_ns$::internal::FieldMetadata field_metadata[];\n"
+      "  static const ::$proto_ns$::internal::SerializationTable "
       "serialization_table[];\n"
-      "  static const ::google::protobuf::uint32 offsets[];\n"
+      "  static const $uint32$ offsets[];\n"
       "};\n",
-      "file_namespace", FileLevelNamespace(file_), "dllexport_decl",
-      options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ",
-      "num", SimpleItoa(std::max(size_t(1), message_generators_.size())));
+      std::max(size_t(1), message_generators_.size()));
   if (HasDescriptorMethods(file_, options_)) {
-    printer->Print(
-        "void $dllexport_decl$AddDescriptors();\n", "dllexport_decl",
-        options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ");
+    format("void $dllexport_decl $$add_descriptors$();\n");
+    if (!options_.opensource_runtime) {
+      // TODO(gerbens) This is for proto1 interoperability. Remove when proto1
+      // is gone.
+      format("void $dllexport_decl $$init_defaults$();\n");
+    }
   }
-  printer->Print(
-      "}  // namespace $file_namespace$\n",
-      "file_namespace", FileLevelNamespace(file_));
 }
 
 void FileGenerator::GenerateMessageDefinitions(io::Printer* printer) {
+  Formatter format(printer, variables_);
   // Generate class definitions.
   for (int i = 0; i < message_generators_.size(); i++) {
     if (i > 0) {
-      printer->Print("\n");
-      printer->Print(kThinSeparator);
-      printer->Print("\n");
+      format("\n");
+      format(kThinSeparator);
+      format("\n");
     }
     message_generators_[i]->GenerateClassDefinition(printer);
   }
@@ -1334,74 +1383,77 @@
 }
 
 void FileGenerator::GenerateServiceDefinitions(io::Printer* printer) {
+  Formatter format(printer, variables_);
   if (HasGenericServices(file_, options_)) {
     // Generate service definitions.
     for (int i = 0; i < service_generators_.size(); i++) {
       if (i > 0) {
-        printer->Print("\n");
-        printer->Print(kThinSeparator);
-        printer->Print("\n");
+        format("\n");
+        format(kThinSeparator);
+        format("\n");
       }
       service_generators_[i]->GenerateDeclarations(printer);
     }
 
-    printer->Print("\n");
-    printer->Print(kThickSeparator);
-    printer->Print("\n");
+    format("\n");
+    format(kThickSeparator);
+    format("\n");
   }
 }
 
 void FileGenerator::GenerateExtensionIdentifiers(io::Printer* printer) {
   // Declare extension identifiers. These are in global scope and so only
   // the global scope extensions.
-  for (int i = 0; i < file_->extension_count(); i++) {
-    extension_generators_owner_[i]->GenerateDeclaration(printer);
+  for (auto& extension_generator : extension_generators_) {
+    if (extension_generator->IsScoped()) continue;
+    extension_generator->GenerateDeclaration(printer);
   }
 }
 
 void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) {
+  Formatter format(printer, variables_);
   // TODO(gerbens) remove pragmas when gcc is no longer used. Current version
   // of gcc fires a bogus error when compiled with strict-aliasing.
-  printer->Print(
-    "#ifdef __GNUC__\n"
-    "  #pragma GCC diagnostic push\n"
-    "  #pragma GCC diagnostic ignored \"-Wstrict-aliasing\"\n"
-    "#endif  // __GNUC__\n");
+  format(
+      "#ifdef __GNUC__\n"
+      "  #pragma GCC diagnostic push\n"
+      "  #pragma GCC diagnostic ignored \"-Wstrict-aliasing\"\n"
+      "#endif  // __GNUC__\n");
   // Generate class inline methods.
   for (int i = 0; i < message_generators_.size(); i++) {
     if (i > 0) {
-      printer->Print(kThinSeparator);
-      printer->Print("\n");
+      format(kThinSeparator);
+      format("\n");
     }
     message_generators_[i]->GenerateInlineMethods(printer);
   }
-  printer->Print(
-    "#ifdef __GNUC__\n"
-    "  #pragma GCC diagnostic pop\n"
-    "#endif  // __GNUC__\n");
+  format(
+      "#ifdef __GNUC__\n"
+      "  #pragma GCC diagnostic pop\n"
+      "#endif  // __GNUC__\n");
 
   for (int i = 0; i < message_generators_.size(); i++) {
     if (i > 0) {
-      printer->Print(kThinSeparator);
-      printer->Print("\n");
+      format(kThinSeparator);
+      format("\n");
     }
   }
 }
 
 void FileGenerator::GenerateProto2NamespaceEnumSpecializations(
     io::Printer* printer) {
+  Formatter format(printer, variables_);
   // Emit GetEnumDescriptor specializations into google::protobuf namespace:
   if (HasEnumDefinitions(file_)) {
-    printer->Print(
-        "\n"
-        "namespace google {\nnamespace protobuf {\n"
-        "\n");
-    for (int i = 0; i < enum_generators_.size(); i++) {
-      enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+    format("\n");
+    {
+      NamespaceOpener proto_ns(ProtobufNamespace(options_), format);
+      format("\n");
+      for (int i = 0; i < enum_generators_.size(); i++) {
+        enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+      }
+      format("\n");
     }
-    printer->Print(
-        "\n"
-        "}  // namespace protobuf\n}  // namespace google\n");
   }
 }
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h
index 94da9a1..9dfdf50 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.h
+++ b/src/google/protobuf/compiler/cpp/cpp_file.h
@@ -44,23 +44,26 @@
 #include <google/protobuf/compiler/cpp/cpp_field.h>
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/compiler/cpp/cpp_options.h>
+#include <google/protobuf/compiler/scc.h>
 
 namespace google {
 namespace protobuf {
-  class FileDescriptor;        // descriptor.h
-  namespace io {
-    class Printer;             // printer.h
-  }
+class FileDescriptor;  // descriptor.h
+namespace io {
+class Printer;  // printer.h
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace cpp {
 
-class EnumGenerator;           // enum.h
-class MessageGenerator;        // message.h
-class ServiceGenerator;        // service.h
-class ExtensionGenerator;      // extension.h
+class EnumGenerator;       // enum.h
+class MessageGenerator;    // message.h
+class ServiceGenerator;    // service.h
+class ExtensionGenerator;  // extension.h
 
 class FileGenerator {
  public:
@@ -71,14 +74,12 @@
   // Shared code between the two header generators below.
   void GenerateHeader(io::Printer* printer);
 
-  // info_path, if non-empty, should be the path (relative to printer's output)
-  // to the metadata file describing this proto header.
-  void GenerateProtoHeader(io::Printer* printer,
-                           const string& info_path);
-  // info_path, if non-empty, should be the path (relative to printer's output)
-  // to the metadata file describing this PB header.
-  void GeneratePBHeader(io::Printer* printer,
-                        const string& info_path);
+  // info_path, if non-empty, should be the path (relative to printer's
+  // output) to the metadata file describing this proto header.
+  void GenerateProtoHeader(io::Printer* printer, const string& info_path);
+  // info_path, if non-empty, should be the path (relative to printer's
+  // output) to the metadata file describing this PB header.
+  void GeneratePBHeader(io::Printer* printer, const string& info_path);
   void GenerateSource(io::Printer* printer);
 
   int NumMessages() const { return message_generators_.size(); }
@@ -90,6 +91,20 @@
   // Internal type used by GenerateForwardDeclarations (defined in file.cc).
   class ForwardDeclarations;
 
+  void IncludeFile(const string& google3_name, io::Printer* printer) {
+    DoIncludeFile(google3_name, false, printer);
+  }
+  void IncludeFileAndExport(const string& google3_name, io::Printer* printer) {
+    DoIncludeFile(google3_name, true, printer);
+  }
+  void DoIncludeFile(const string& google3_name, bool do_export,
+                     io::Printer* printer);
+
+  string CreateHeaderInclude(const string& basename,
+                             const FileDescriptor* file);
+  void GenerateInternalForwardDeclarations(
+      const std::vector<const FieldDescriptor*>& fields, const Options& options,
+      MessageSCCAnalyzer* scc_analyzer, io::Printer* printer);
   void GenerateSourceIncludes(io::Printer* printer);
   void GenerateSourceDefaultInstance(int idx, io::Printer* printer);
 
@@ -100,11 +115,6 @@
   // For other imports, generates their forward-declarations.
   void GenerateForwardDeclarations(io::Printer* printer);
 
-  // Internal helper used by GenerateForwardDeclarations: fills 'decls'
-  // with all necessary forward-declarations for this file and its
-  // transient depednencies.
-  void FillForwardDeclarations(ForwardDeclarations* decls);
-
   // Generates top or bottom of a header file.
   void GenerateTopHeaderGuard(io::Printer* printer,
                               const string& filename_identifier);
@@ -138,13 +148,13 @@
 
   void GenerateProto2NamespaceEnumSpecializations(io::Printer* printer);
 
-  // Sometimes the names we use in a .proto file happen to be defined as macros
-  // on some platforms (e.g., macro/minor used in plugin.proto are defined as
-  // macros in sys/types.h on FreeBSD and a few other platforms). To make the
-  // generated code compile on these platforms, we either have to undef the
-  // macro for these few platforms, or rename the field name for all platforms.
-  // Since these names are part of protobuf public API, renaming is generally
-  // a breaking change so we prefer the #undef approach.
+  // Sometimes the names we use in a .proto file happen to be defined as
+  // macros on some platforms (e.g., macro/minor used in plugin.proto are
+  // defined as macros in sys/types.h on FreeBSD and a few other platforms).
+  // To make the generated code compile on these platforms, we either have to
+  // undef the macro for these few platforms, or rename the field name for all
+  // platforms. Since these names are part of protobuf public API, renaming is
+  // generally a breaking change so we prefer the #undef approach.
   void GenerateMacroUndefs(io::Printer* printer);
 
   bool IsSCCRepresentative(const Descriptor* d) {
@@ -157,30 +167,29 @@
     return scc_analyzer_.GetSCC(d);
   }
 
+  bool IsDepWeak(const FileDescriptor* dep) const {
+    if (weak_deps_.count(dep) != 0) {
+      GOOGLE_CHECK(!options_.opensource_runtime);
+      return true;
+    }
+    return false;
+  }
+
+  std::set<const FileDescriptor*> weak_deps_;
 
   const FileDescriptor* file_;
   const Options options_;
 
-  SCCAnalyzer scc_analyzer_;
+  MessageSCCAnalyzer scc_analyzer_;
 
+  std::map<string, string> variables_;
 
   // Contains the post-order walk of all the messages (and child messages) in
   // this file. If you need a pre-order walk just reverse iterate.
-  std::vector<MessageGenerator*> message_generators_;
-  std::vector<EnumGenerator*> enum_generators_;
-  std::vector<ServiceGenerator*> service_generators_;
-  std::vector<ExtensionGenerator*> extension_generators_;
-
-  // These members are just for owning (and thus proper deleting).
-  // Nested (enum/extension)_generators are owned by child messages.
-  std::unique_ptr<std::unique_ptr<EnumGenerator> []> enum_generators_owner_;
-  std::unique_ptr<std::unique_ptr<ServiceGenerator> []>
-      service_generators_owner_;
-  std::unique_ptr<std::unique_ptr<ExtensionGenerator> []>
-      extension_generators_owner_;
-
-  // E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}.
-  std::vector<string> package_parts_;
+  std::vector<std::unique_ptr<MessageGenerator>> message_generators_;
+  std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
+  std::vector<std::unique_ptr<ServiceGenerator>> service_generators_;
+  std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
 };
@@ -188,6 +197,6 @@
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc
index 20bb8a1..79f773e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_generator.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -77,6 +77,21 @@
   // __declspec(dllimport) depending on what is being compiled.
   //
   Options file_options;
+
+  switch (runtime_) {
+    case Runtime::kGoogle3:
+      file_options.opensource_runtime = false;
+      break;
+    case Runtime::kOpensource:
+      file_options.opensource_runtime = true;
+      file_options.opensource_include_paths = true;
+      break;
+    case Runtime::kOpensourceGoogle3:
+      file_options.opensource_runtime = true;
+      file_options.opensource_include_paths = false;
+      break;
+  }
+
   for (int i = 0; i < options.size(); i++) {
     if (options[i].first == "dllexport_decl") {
       file_options.dllexport_decl = options[i].second;
@@ -108,7 +123,7 @@
 
   // The safe_boundary_check option controls behavior for Google-internal
   // protobuf APIs.
-  if (file_options.safe_boundary_check) {
+  if (file_options.safe_boundary_check && file_options.opensource_runtime) {
     *error =
         "The safe_boundary_check option is not supported outside of Google.";
     return false;
@@ -119,6 +134,10 @@
 
   string basename = StripProto(file->name());
 
+  if (MaybeBootstrap(file_options, generator_context, file_options.bootstrap,
+                     &basename)) {
+    return true;
+  }
 
   FileGenerator file_generator(file, file_options);
 
@@ -184,8 +203,8 @@
     }
     for (int i = 0; i < num_cc_files; i++) {
       // TODO(gerbens) Agree on naming scheme.
-      std::unique_ptr<io::ZeroCopyOutputStream> output(
-          generator_context->Open(basename + "." + SimpleItoa(i) + ".cc"));
+      std::unique_ptr<io::ZeroCopyOutputStream> output(generator_context->Open(
+          basename + ".out/" + SimpleItoa(i) + ".cc"));
       io::Printer printer(output.get(), '$');
       if (i < file_generator.NumMessages()) {
         file_generator.GenerateSourceForMessage(i, &printer);
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.h b/src/google/protobuf/compiler/cpp/cpp_generator.h
index 3d517cf..06d3c36 100644
--- a/src/google/protobuf/compiler/cpp/cpp_generator.h
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.h
@@ -54,6 +54,20 @@
   CppGenerator();
   ~CppGenerator();
 
+  enum class LIBPROTOC_EXPORT Runtime {
+    kGoogle3,     // Use the internal google3 runtime.
+    kOpensource,  // Use the open-source runtime.
+
+    // Use the open-source runtime with google3 #include paths.  We make these
+    // absolute to avoid ambiguity, so the runtime will be #included like:
+    //   #include "third_party/protobuf/<...>/google/protobuf/message.h"
+    kOpensourceGoogle3
+  };
+
+  void set_runtime(Runtime runtime) {
+    runtime_ = runtime;
+  }
+
   // implements CodeGenerator ----------------------------------------
   bool Generate(const FileDescriptor* file,
                 const string& parameter,
@@ -61,12 +75,13 @@
                 string* error) const;
 
  private:
+  Runtime runtime_ = Runtime::kOpensource;
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CppGenerator);
 };
 
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index 163dac0..bc0a926 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -32,21 +32,25 @@
 //  Based on original Protocol Buffers design by
 //  Sanjay Ghemawat, Jeff Dean, and others.
 
-#include <google/protobuf/stubs/hash.h>
 #include <limits>
 #include <map>
 #include <queue>
+#include <unordered_set>
 #include <vector>
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/compiler/scc.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/wire_format_lite.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/substitute.h>
 
 
+#include <google/protobuf/stubs/hash.h>
 
 
 namespace google {
@@ -83,15 +87,15 @@
   "while", "xor", "xor_eq"
 };
 
-hash_set<string> MakeKeywordsMap() {
-  hash_set<string> result;
+std::unordered_set<string> MakeKeywordsMap() {
+  std::unordered_set<string> result;
   for (int i = 0; i < GOOGLE_ARRAYSIZE(kKeywordList); i++) {
     result.insert(kKeywordList[i]);
   }
   return result;
 }
 
-hash_set<string> kKeywords = MakeKeywordsMap();
+std::unordered_set<string> kKeywords = MakeKeywordsMap();
 
 // Returns whether the provided descriptor has an extension. This includes its
 // nested types.
@@ -131,8 +135,55 @@
   return res;
 }
 
+string IntTypeName(const Options& options, const string& type) {
+  if (options.opensource_runtime) {
+    return "::google::protobuf::" + type;
+  } else {
+    return "::" + type;
+  }
+}
+
+string StringTypeName(const Options& options) {
+  return options.opensource_runtime ? "::std::string" : "::std::string";
+}
+
+void SetIntVar(const Options& options, const string& type,
+               std::map<string, string>* variables) {
+  (*variables)[type] = IntTypeName(options, type);
+}
+
 }  // namespace
 
+void SetCommonVars(const Options& options,
+                   std::map<string, string>* variables) {
+  (*variables)["proto_ns"] = ProtobufNamespace(options);
+
+  // Warning: there is some clever naming/splitting here to avoid extract script
+  // rewrites.  The names of these variables must not be things that the extract
+  // script will rewrite.  That's why we use "CHK" (for example) instead of
+  // "GOOGLE_CHECK".
+  if (options.opensource_runtime) {
+    (*variables)["GOOGLE_PROTOBUF"] = "GOOGLE_PROTOBUF";
+    (*variables)["CHK"] = "GOOGLE_CHECK";
+    (*variables)["DCHK"] = "GOOGLE_DCHECK";
+  } else {
+    // These values are things the extract script would rewrite if we did not
+    // split them.  It might not strictly matter since we don't generate google3
+    // code in open-source.  But it's good to prevent surprising things from
+    // happening.
+    (*variables)["GOOGLE_PROTOBUF"] = "GOOGLE3" "_PROTOBUF";
+    (*variables)["CHK"] = "CH" "ECK";
+    (*variables)["DCHK"] = "DCH" "ECK";
+  }
+
+  SetIntVar(options, "uint8", variables);
+  SetIntVar(options, "uint32", variables);
+  SetIntVar(options, "uint64", variables);
+  SetIntVar(options, "int32", variables);
+  SetIntVar(options, "int64", variables);
+  (*variables)["string"] = StringTypeName(options);
+}
+
 string UnderscoresToCamelCase(const string& input, bool cap_next_letter) {
   string result;
   // Note:  I distrust ctype.h due to locales.
@@ -205,11 +256,25 @@
   }
 }
 
+string QualifiedClassName(const Descriptor* d) {
+  return Namespace(d) + "::" + ClassName(d);
+}
+
+string QualifiedClassName(const EnumDescriptor* d) {
+  return Namespace(d) + "::" + ClassName(d);
+}
+
 string Namespace(const string& package) {
   if (package.empty()) return "";
   return "::" + DotsToColons(package);
 }
 
+string Namespace(const Descriptor* d) { return Namespace(d->file()); }
+
+string Namespace(const FieldDescriptor* d) { return Namespace(d->file()); }
+
+string Namespace(const EnumDescriptor* d) { return Namespace(d->file()); }
+
 string DefaultInstanceName(const Descriptor* descriptor) {
   string prefix = descriptor->file()->package().empty() ? "" : "::";
   return prefix + DotsToColons(descriptor->file()->package()) + "::_" +
@@ -221,9 +286,9 @@
 }
 
 string SuperClassName(const Descriptor* descriptor, const Options& options) {
-  return HasDescriptorMethods(descriptor->file(), options)
-             ? "::google::protobuf::Message"
-             : "::google::protobuf::MessageLite";
+  return "::" + ProtobufNamespace(options) +
+         (HasDescriptorMethods(descriptor->file(), options) ? "::Message"
+                                                            : "::MessageLite");
 }
 
 string FieldName(const FieldDescriptor* field) {
@@ -318,6 +383,38 @@
   return NULL;
 }
 
+string PrimitiveTypeName(const Options& options,
+                         FieldDescriptor::CppType type) {
+  switch (type) {
+    case FieldDescriptor::CPPTYPE_INT32:
+      return IntTypeName(options, "int32");
+    case FieldDescriptor::CPPTYPE_INT64:
+      return IntTypeName(options, "int64");
+    case FieldDescriptor::CPPTYPE_UINT32:
+      return IntTypeName(options, "uint32");
+    case FieldDescriptor::CPPTYPE_UINT64:
+      return IntTypeName(options, "uint64");
+    case FieldDescriptor::CPPTYPE_DOUBLE:
+      return "double";
+    case FieldDescriptor::CPPTYPE_FLOAT:
+      return "float";
+    case FieldDescriptor::CPPTYPE_BOOL:
+      return "bool";
+    case FieldDescriptor::CPPTYPE_ENUM:
+      return "int";
+    case FieldDescriptor::CPPTYPE_STRING:
+      return StringTypeName(options);
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      return "";
+
+      // No default because we want the compiler to complain if any new
+      // CppTypes are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return "";
+}
+
 const char* DeclaredTypeMethodName(FieldDescriptor::Type type) {
   switch (type) {
     case FieldDescriptor::TYPE_INT32   : return "Int32";
@@ -349,44 +446,59 @@
 }
 
 string Int32ToString(int number) {
-  // gcc rejects the decimal form of kint32min.
   if (number == kint32min) {
-    GOOGLE_COMPILE_ASSERT(kint32min == (~0x7fffffff), kint32min_value_error);
-    return "(~0x7fffffff)";
+    // This needs to be special-cased, see explanation here:
+    // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661
+    return SimpleItoa(number + 1) + " - 1";
   } else {
     return SimpleItoa(number);
   }
 }
 
-string Int64ToString(int64 number) {
-  // gcc rejects the decimal form of kint64min
+string Int64ToString(const string& macro_prefix, int64 number) {
   if (number == kint64min) {
-    // Make sure we are in a 2's complement system.
-    GOOGLE_COMPILE_ASSERT(kint64min == GOOGLE_LONGLONG(~0x7fffffffffffffff),
-                   kint64min_value_error);
-    return "GOOGLE_LONGLONG(~0x7fffffffffffffff)";
+    // This needs to be special-cased, see explanation here:
+    // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661
+    return macro_prefix + "_LONGLONG(" + SimpleItoa(number + 1) +
+           ") - 1";
   }
-  return "GOOGLE_LONGLONG(" + SimpleItoa(number) + ")";
+  return macro_prefix + "_LONGLONG(" + SimpleItoa(number) + ")";
+}
+
+string UInt64ToString(const string& macro_prefix, uint64 number) {
+  return macro_prefix + "_ULONGLONG(" + SimpleItoa(number) + ")";
 }
 
 string DefaultValue(const FieldDescriptor* field) {
   switch (field->cpp_type()) {
+    case FieldDescriptor::CPPTYPE_INT64:
+      return Int64ToString("GG", field->default_value_int64());
+    case FieldDescriptor::CPPTYPE_UINT64:
+      return UInt64ToString("GG", field->default_value_uint64());
+    default:
+      return DefaultValue(Options(), field);
+  }
+}
+
+string DefaultValue(const Options& options, const FieldDescriptor* field) {
+  switch (field->cpp_type()) {
     case FieldDescriptor::CPPTYPE_INT32:
       return Int32ToString(field->default_value_int32());
     case FieldDescriptor::CPPTYPE_UINT32:
       return SimpleItoa(field->default_value_uint32()) + "u";
     case FieldDescriptor::CPPTYPE_INT64:
-      return Int64ToString(field->default_value_int64());
+      return Int64ToString(MacroPrefix(options), field->default_value_int64());
     case FieldDescriptor::CPPTYPE_UINT64:
-      return "GOOGLE_ULONGLONG(" + SimpleItoa(field->default_value_uint64())+ ")";
+      return UInt64ToString(MacroPrefix(options),
+                            field->default_value_uint64());
     case FieldDescriptor::CPPTYPE_DOUBLE: {
       double value = field->default_value_double();
       if (value == std::numeric_limits<double>::infinity()) {
-        return "::google::protobuf::internal::Infinity()";
+        return "std::numeric_limits<double>::infinity()";
       } else if (value == -std::numeric_limits<double>::infinity()) {
-        return "-::google::protobuf::internal::Infinity()";
+        return "-std::numeric_limits<double>::infinity()";
       } else if (value != value) {
-        return "::google::protobuf::internal::NaN()";
+        return "std::numeric_limits<double>::quiet_NaN()";
       } else {
         return SimpleDtoa(value);
       }
@@ -395,11 +507,11 @@
       {
         float value = field->default_value_float();
         if (value == std::numeric_limits<float>::infinity()) {
-          return "static_cast<float>(::google::protobuf::internal::Infinity())";
+          return "std::numeric_limits<float>::infinity()";
         } else if (value == -std::numeric_limits<float>::infinity()) {
-          return "static_cast<float>(-::google::protobuf::internal::Infinity())";
+          return "-std::numeric_limits<float>::infinity()";
         } else if (value != value) {
-          return "static_cast<float>(::google::protobuf::internal::NaN())";
+          return "std::numeric_limits<float>::quiet_NaN()";
         } else {
           string float_value = SimpleFtoa(value);
           // If floating point value contains a period (.) or an exponent
@@ -450,8 +562,9 @@
   return result;
 }
 
-string FileLevelNamespace(const string& filename) {
-  return "protobuf_" + FilenameIdentifier(filename);
+string UniqueName(const string& name, const string& filename,
+                  const Options& options) {
+  return name + "_" + FilenameIdentifier(filename);
 }
 
 // Return the qualified C++ name for a file level symbol.
@@ -487,6 +600,126 @@
   return function_name;
 }
 
+static bool HasLazyFields(const Descriptor* descriptor,
+                          const Options& options) {
+  for (int field_idx = 0; field_idx < descriptor->field_count(); field_idx++) {
+    if (IsLazy(descriptor->field(field_idx), options)) {
+      return true;
+    }
+  }
+  for (int idx = 0; idx < descriptor->extension_count(); idx++) {
+    if (IsLazy(descriptor->extension(idx), options)) {
+      return true;
+    }
+  }
+  for (int idx = 0; idx < descriptor->nested_type_count(); idx++) {
+    if (HasLazyFields(descriptor->nested_type(idx), options)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// Does the given FileDescriptor use lazy fields?
+bool HasLazyFields(const FileDescriptor* file, const Options& options) {
+  for (int i = 0; i < file->message_type_count(); i++) {
+    const Descriptor* descriptor(file->message_type(i));
+    if (HasLazyFields(descriptor, options)) {
+      return true;
+    }
+  }
+  for (int field_idx = 0; field_idx < file->extension_count(); field_idx++) {
+    if (IsLazy(file->extension(field_idx), options)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+static bool HasRepeatedFields(const Descriptor* descriptor) {
+  for (int i = 0; i < descriptor->field_count(); ++i) {
+    if (descriptor->field(i)->label() == FieldDescriptor::LABEL_REPEATED) {
+      return true;
+    }
+  }
+  for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+    if (HasRepeatedFields(descriptor->nested_type(i))) return true;
+  }
+  return false;
+}
+
+bool HasRepeatedFields(const FileDescriptor* file) {
+  for (int i = 0; i < file->message_type_count(); ++i) {
+    if (HasRepeatedFields(file->message_type(i))) return true;
+  }
+  return false;
+}
+
+static bool IsStringPieceField(const FieldDescriptor* field,
+                               const Options& options) {
+  return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
+         EffectiveStringCType(field, options) == FieldOptions::STRING_PIECE;
+}
+
+static bool HasStringPieceFields(const Descriptor* descriptor,
+                                 const Options& options) {
+  for (int i = 0; i < descriptor->field_count(); ++i) {
+    if (IsStringPieceField(descriptor->field(i), options)) return true;
+  }
+  for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+    if (HasStringPieceFields(descriptor->nested_type(i), options)) return true;
+  }
+  return false;
+}
+
+bool HasStringPieceFields(const FileDescriptor* file, const Options& options) {
+  for (int i = 0; i < file->message_type_count(); ++i) {
+    if (HasStringPieceFields(file->message_type(i), options)) return true;
+  }
+  return false;
+}
+
+static bool IsCordField(const FieldDescriptor* field, const Options& options) {
+  return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
+         EffectiveStringCType(field, options) == FieldOptions::CORD;
+}
+
+static bool HasCordFields(const Descriptor* descriptor,
+                          const Options& options) {
+  for (int i = 0; i < descriptor->field_count(); ++i) {
+    if (IsCordField(descriptor->field(i), options)) return true;
+  }
+  for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+    if (HasCordFields(descriptor->nested_type(i), options)) return true;
+  }
+  return false;
+}
+
+bool HasCordFields(const FileDescriptor* file, const Options& options) {
+  for (int i = 0; i < file->message_type_count(); ++i) {
+    if (HasCordFields(file->message_type(i), options)) return true;
+  }
+  return false;
+}
+
+static bool HasExtensionsOrExtendableMessage(const Descriptor* descriptor) {
+  if (descriptor->extension_range_count() > 0) return true;
+  if (descriptor->extension_count() > 0) return true;
+  for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+    if (HasExtensionsOrExtendableMessage(descriptor->nested_type(i))) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool HasExtensionsOrExtendableMessage(const FileDescriptor* file) {
+  if (file->extension_count() > 0) return true;
+  for (int i = 0; i < file->message_type_count(); ++i) {
+    if (HasExtensionsOrExtendableMessage(file->message_type(i))) return true;
+  }
+  return false;
+}
 
 static bool HasMapFields(const Descriptor* descriptor) {
   for (int i = 0; i < descriptor->field_count(); ++i) {
@@ -543,11 +776,16 @@
   return false;
 }
 
-FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field) {
+FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field,
+                                         const Options& options) {
   GOOGLE_DCHECK(field->cpp_type() == FieldDescriptor::CPPTYPE_STRING);
-  // Open-source protobuf release only supports STRING ctype.
-  return FieldOptions::STRING;
-
+  if (options.opensource_runtime) {
+    // Open-source protobuf release only supports STRING ctype.
+    return FieldOptions::STRING;
+  } else {
+    // Google-internal supports all ctypes.
+    return field->options().ctype();
+  }
 }
 
 bool IsAnyMessage(const FileDescriptor* descriptor) {
@@ -569,62 +807,81 @@
   NONE = 2,  // No UTF-8 check.
 };
 
+static bool FieldEnforceUtf8(const FieldDescriptor* field,
+                             const Options& options) {
+  return true;
+}
+
+static bool FileUtf8Verification(const FileDescriptor* file,
+                                 const Options& options) {
+  return true;
+}
+
 // Which level of UTF-8 enforcemant is placed on this file.
 static Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
                                       const Options& options) {
-  if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
+  if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
+      FieldEnforceUtf8(field, options)) {
     return STRICT;
   } else if (GetOptimizeFor(field->file(), options) !=
-             FileOptions::LITE_RUNTIME) {
+                 FileOptions::LITE_RUNTIME &&
+             FileUtf8Verification(field->file(), options)) {
     return VERIFY;
   } else {
     return NONE;
   }
 }
 
+string GetUtf8Suffix(const FieldDescriptor* field, const Options& options) {
+  switch (GetUtf8CheckMode(field, options)) {
+    case STRICT:
+      return "UTF8";
+    case VERIFY:
+      return "UTF8Verify";
+    case NONE:
+    default:  // Some build configs warn on missing return without default.
+      return "";
+  }
+}
+
 static void GenerateUtf8CheckCode(const FieldDescriptor* field,
                                   const Options& options, bool for_parse,
-                                  const std::map<string, string>& variables,
                                   const char* parameters,
                                   const char* strict_function,
                                   const char* verify_function,
-                                  io::Printer* printer) {
+                                  const Formatter& format) {
   switch (GetUtf8CheckMode(field, options)) {
     case STRICT: {
       if (for_parse) {
-        printer->Print("DO_(");
+        format("DO_(");
       }
-      printer->Print(
-          "::google::protobuf::internal::WireFormatLite::$function$(\n",
-          "function", strict_function);
-      printer->Indent();
-      printer->Print(variables, parameters);
+      format("::$proto_ns$::internal::WireFormatLite::$1$(\n", strict_function);
+      format.Indent();
+      format(parameters);
       if (for_parse) {
-        printer->Print("::google::protobuf::internal::WireFormatLite::PARSE,\n");
+        format("::$proto_ns$::internal::WireFormatLite::PARSE,\n");
       } else {
-        printer->Print("::google::protobuf::internal::WireFormatLite::SERIALIZE,\n");
+        format("::$proto_ns$::internal::WireFormatLite::SERIALIZE,\n");
       }
-      printer->Print("\"$full_name$\")", "full_name", field->full_name());
+      format("\"$1$\")", field->full_name());
       if (for_parse) {
-        printer->Print(")");
+        format(")");
       }
-      printer->Print(";\n");
-      printer->Outdent();
+      format(";\n");
+      format.Outdent();
       break;
     }
     case VERIFY: {
-      printer->Print(
-          "::google::protobuf::internal::WireFormat::$function$(\n",
-          "function", verify_function);
-      printer->Indent();
-      printer->Print(variables, parameters);
+      format("::$proto_ns$::internal::WireFormat::$1$(\n", verify_function);
+      format.Indent();
+      format(parameters);
       if (for_parse) {
-        printer->Print("::google::protobuf::internal::WireFormat::PARSE,\n");
+        format("::$proto_ns$::internal::WireFormat::PARSE,\n");
       } else {
-        printer->Print("::google::protobuf::internal::WireFormat::SERIALIZE,\n");
+        format("::$proto_ns$::internal::WireFormat::SERIALIZE,\n");
       }
-      printer->Print("\"$full_name$\");\n", "full_name", field->full_name());
-      printer->Outdent();
+      format("\"$1$\");\n", field->full_name());
+      format.Outdent();
       break;
     }
     case NONE:
@@ -634,21 +891,19 @@
 
 void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
                                     const Options& options, bool for_parse,
-                                    const std::map<string, string>& variables,
                                     const char* parameters,
-                                    io::Printer* printer) {
-  GenerateUtf8CheckCode(field, options, for_parse, variables, parameters,
+                                    const Formatter& format) {
+  GenerateUtf8CheckCode(field, options, for_parse, parameters,
                         "VerifyUtf8String", "VerifyUTF8StringNamedField",
-                        printer);
+                        format);
 }
 
 void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
                                   const Options& options, bool for_parse,
-                                  const std::map<string, string>& variables,
                                   const char* parameters,
-                                  io::Printer* printer) {
-  GenerateUtf8CheckCode(field, options, for_parse, variables, parameters,
-                        "VerifyUtf8Cord", "VerifyUTF8CordNamedField", printer);
+                                  const Formatter& format) {
+  GenerateUtf8CheckCode(field, options, for_parse, parameters, "VerifyUtf8Cord",
+                        "VerifyUTF8CordNamedField", format);
 }
 
 namespace {
@@ -669,11 +924,17 @@
   }
 }
 
-bool HasWeakFields(const Descriptor* descriptor) {
+bool HasWeakFields(const Descriptor* descriptor, const Options& options) {
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    if (IsWeak(descriptor->field(i), options)) return true;
+  }
   return false;
 }
 
-bool HasWeakFields(const FileDescriptor* file) {
+bool HasWeakFields(const FileDescriptor* file, const Options& options) {
+  for (int i = 0; i < file->message_type_count(); ++i) {
+    if (HasWeakFields(file->message_type(i), options)) return true;
+  }
   return false;
 }
 
@@ -684,7 +945,7 @@
 }
 
 bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
-                         SCCAnalyzer* scc_analyzer) {
+                         MessageSCCAnalyzer* scc_analyzer) {
   return UsingImplicitWeakFields(field->file(), options) &&
          field->type() == FieldDescriptor::TYPE_MESSAGE &&
          !field->is_required() && !field->is_map() &&
@@ -696,85 +957,18 @@
              scc_analyzer->GetSCC(field->message_type());
 }
 
-struct CompareDescriptors {
-  bool operator()(const Descriptor* a, const Descriptor* b) {
-    return a->full_name() < b->full_name();
-  }
-};
-
-SCCAnalyzer::NodeData SCCAnalyzer::DFS(const Descriptor* descriptor) {
-  // Must not have visited already.
-  GOOGLE_DCHECK_EQ(cache_.count(descriptor), 0);
-
-  // Mark visited by inserting in map.
-  NodeData& result = cache_[descriptor];
-  // Initialize data structures.
-  result.index = result.lowlink = index_++;
-  stack_.push_back(descriptor);
-
-  // Recurse the fields / nodes in graph
-  for (int i = 0; i < descriptor->field_count(); i++) {
-    const Descriptor* child = descriptor->field(i)->message_type();
-    if (child) {
-      if (cache_.count(child) == 0) {
-        // unexplored node
-        NodeData child_data = DFS(child);
-        result.lowlink = std::min(result.lowlink, child_data.lowlink);
-      } else {
-        NodeData child_data = cache_[child];
-        if (child_data.scc == NULL) {
-          // Still in the stack_ so we found a back edge
-          result.lowlink = std::min(result.lowlink, child_data.index);
-        }
-      }
-    }
-  }
-  if (result.index == result.lowlink) {
-    // This is the root of a strongly connected component
-    SCC* scc = CreateSCC();
-    while (true) {
-      const Descriptor* scc_desc = stack_.back();
-      scc->descriptors.push_back(scc_desc);
-      // Remove from stack
-      stack_.pop_back();
-      cache_[scc_desc].scc = scc;
-
-      if (scc_desc == descriptor) break;
-    }
-
-    // The order of descriptors is random and depends how this SCC was
-    // discovered. In-order to ensure maximum stability we sort it by name.
-    std::sort(scc->descriptors.begin(), scc->descriptors.end(),
-              CompareDescriptors());
-    AddChildren(scc);
-  }
-  return result;
-}
-
-void SCCAnalyzer::AddChildren(SCC* scc) {
-  std::set<const SCC*> seen;
-  for (int i = 0; i < scc->descriptors.size(); i++) {
-    const Descriptor* descriptor = scc->descriptors[i];
-    for (int j = 0; j < descriptor->field_count(); j++) {
-      const Descriptor* child_msg = descriptor->field(j)->message_type();
-      if (child_msg) {
-        const SCC* child = GetSCC(child_msg);
-        if (child == scc) continue;
-        if (seen.insert(child).second) {
-          scc->children.push_back(child);
-        }
-      }
-    }
-  }
-}
-
-MessageAnalysis SCCAnalyzer::GetSCCAnalysis(const SCC* scc) {
+MessageAnalysis MessageSCCAnalyzer::GetSCCAnalysis(const SCC* scc) {
   if (analysis_cache_.count(scc)) return analysis_cache_[scc];
-  MessageAnalysis result = MessageAnalysis();
+  MessageAnalysis result{};
   for (int i = 0; i < scc->descriptors.size(); i++) {
     const Descriptor* descriptor = scc->descriptors[i];
     if (descriptor->extension_range_count() > 0) {
       result.contains_extension = true;
+      // Extensions are found by looking up default_instance and extension
+      // number in a map. So you'd maybe expect here
+      // result.constructor_requires_initialization = true;
+      // However the extension registration mechanism already makes sure
+      // the default will be initialized.
     }
     for (int i = 0; i < descriptor->field_count(); i++) {
       const FieldDescriptor* field = descriptor->field(i);
@@ -784,6 +978,7 @@
       switch (field->type()) {
         case FieldDescriptor::TYPE_STRING:
         case FieldDescriptor::TYPE_BYTES: {
+          result.constructor_requires_initialization = true;
           if (field->options().ctype() == FieldOptions::CORD) {
             result.contains_cord = true;
           }
@@ -791,7 +986,8 @@
         }
         case FieldDescriptor::TYPE_GROUP:
         case FieldDescriptor::TYPE_MESSAGE: {
-          const SCC* child = GetSCC(field->message_type());
+          result.constructor_requires_initialization = true;
+          const SCC* child = analyzer_.GetSCC(field->message_type());
           if (child != scc) {
             MessageAnalysis analysis = GetSCCAnalysis(child);
             result.contains_cord |= analysis.contains_cord;
@@ -860,6 +1056,543 @@
   }
 }
 
+bool GetBootstrapBasename(const Options& options, const string& basename,
+                          string* bootstrap_basename) {
+  if (options.opensource_runtime) {
+    return false;
+  }
+
+  std::unordered_map<string, string> bootstrap_mapping{
+      {"net/proto2/proto/descriptor",
+       "net/proto2/internal/descriptor"},
+      {"net/proto2/compiler/proto/plugin",
+       "net/proto2/compiler/proto/plugin"},
+      {"net/proto2/compiler/proto/profile",
+       "net/proto2/compiler/proto/profile_bootstrap"},
+  };
+  auto iter = bootstrap_mapping.find(basename);
+  if (iter == bootstrap_mapping.end()) {
+    *bootstrap_basename = basename;
+    return false;
+  } else {
+    *bootstrap_basename = iter->second;
+    return true;
+  }
+}
+
+bool IsBootstrapProto(const Options& options, const FileDescriptor* file) {
+  string my_name = StripProto(file->name());
+  return GetBootstrapBasename(options, my_name, &my_name);
+}
+
+bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context,
+                    bool bootstrap_flag, string* basename) {
+  string bootstrap_basename;
+  if (!GetBootstrapBasename(options, *basename, &bootstrap_basename)) {
+    return false;
+  }
+
+  if (bootstrap_flag) {
+    // Adjust basename, but don't abort code generation.
+    *basename = bootstrap_basename;
+    return false;
+  } else {
+    string forward_to_basename = bootstrap_basename;
+
+    // Generate forwarding headers and empty .pb.cc.
+    {
+      std::unique_ptr<io::ZeroCopyOutputStream> output(
+          generator_context->Open(*basename + ".pb.h"));
+      io::Printer printer(output.get(), '$', nullptr);
+      printer.Print(
+          "#ifndef PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PB_H\n"
+          "#define PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PB_H\n"
+          "#include \"$forward_to_basename$.pb.h\"  // IWYU pragma: export\n"
+          "#endif  // PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PB_H\n",
+          "forward_to_basename", forward_to_basename,
+          "filename_identifier", FilenameIdentifier(*basename));
+
+      if (!options.opensource_runtime) {
+        // HACK HACK HACK, tech debt from the deeps of proto1 and SWIG
+        // protocoltype is SWIG'ed and we need to forward
+        if (*basename == "net/proto/protocoltype") {
+          printer.Print(
+              "#ifdef SWIG\n"
+              "%include \"$forward_to_basename$.pb.h\"\n"
+              "#endif  // SWIG\n",
+              "forward_to_basename", forward_to_basename);
+        }
+      }
+    }
+
+    {
+      std::unique_ptr<io::ZeroCopyOutputStream> output(
+          generator_context->Open(*basename + ".proto.h"));
+      io::Printer printer(output.get(), '$', nullptr);
+      printer.Print(
+          "#ifndef PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PROTO_H\n"
+          "#define PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PROTO_H\n"
+          "#include \"$forward_to_basename$.proto.h\"  // IWYU pragma: "
+          "export\n"
+          "#endif  // "
+          "PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PROTO_H\n",
+          "forward_to_basename", forward_to_basename,
+          "filename_identifier", FilenameIdentifier(*basename));
+    }
+
+    {
+      std::unique_ptr<io::ZeroCopyOutputStream> output(
+          generator_context->Open(*basename + ".pb.cc"));
+      io::Printer printer(output.get(), '$', nullptr);
+      printer.Print("\n");
+    }
+
+    {
+      std::unique_ptr<io::ZeroCopyOutputStream> output(
+          generator_context->Open(*basename + ".pb.h.meta"));
+    }
+
+    {
+      std::unique_ptr<io::ZeroCopyOutputStream> output(
+          generator_context->Open(*basename + ".proto.h.meta"));
+    }
+
+    // Abort code generation.
+    return true;
+  }
+}
+
+bool ShouldRepeat(const FieldDescriptor* descriptor,
+                  internal::WireFormatLite::WireType wiretype) {
+  return descriptor->is_repeated() &&
+         (!descriptor->is_packable() ||
+          wiretype != internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+}
+
+void GenerateCaseBody(internal::WireFormatLite::WireType wiretype,
+                      const FieldDescriptor* field, const Options& options,
+                      MessageSCCAnalyzer* scc_analyzer,
+                      const Formatter& format) {
+  using internal::WireFormat;
+  using internal::WireFormatLite;
+
+  if (ShouldRepeat(field, wiretype)) {
+    format("do {\n");
+    format.Indent();
+  }
+  switch (wiretype) {
+    case WireFormatLite::WIRETYPE_VARINT: {
+      format(
+          "$uint64$ val;\n"
+          "ptr = Varint::Parse64(ptr, &val);\n"
+          "if (!ptr) goto error;\n");
+      string type = PrimitiveTypeName(options, field->cpp_type());
+      if (field->type() == FieldDescriptor::TYPE_SINT32 ||
+          field->type() == FieldDescriptor::TYPE_SINT64) {
+        int size = EstimateAlignmentSize(field) * 8;
+        format(
+            "$1$ value = "
+            "::$proto_ns$::internal::WireFormatLite::ZigZagDecode$2$(val);\n",
+            type, size);
+      } else if (field->type() == FieldDescriptor::TYPE_ENUM &&
+                 !IsProto1(field->file(), options)) {
+        if (!HasPreservingUnknownEnumSemantics(field->file())) {
+          format(
+              "if (!$1$_IsValid(val)) {\n"
+              "  ::$proto_ns$::internal::WriteVarint($2$, val, "
+              "msg->mutable_unknown_fields());\n"
+              "  break;\n"
+              "}\n",
+              QualifiedClassName(field->enum_type()), field->number());
+        }
+        format("$1$ value = static_cast<$1$>(val);\n",
+               QualifiedClassName(field->enum_type()));
+      } else {
+        format("$1$ value = val;\n", type);
+      }
+      if (field->is_repeated()) {
+        format("msg->add_$1$(value);\n", FieldName(field));
+      } else {
+        format("msg->set_$1$(value);\n", FieldName(field));
+      }
+      break;
+    }
+    case WireFormatLite::WIRETYPE_FIXED64: {
+      string type = PrimitiveTypeName(options, field->cpp_type());
+      format(
+          "$1$ val;\n"
+          "::std::memcpy(&val, ptr, 8);\n"
+          "ptr += 8;\n",
+          type);
+      if (field->is_repeated()) {
+        format("msg->add_$1$(val);\n", FieldName(field));
+      } else {
+        format("msg->set_$1$(val);\n", FieldName(field));
+      }
+      break;
+    }
+    case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
+      format(
+          "ptr = Varint::Parse32Inline(ptr, &size);\n"
+          "if (!ptr) goto error;\n");
+      if (!IsProto1(field->file(), options) && field->is_packable()) {
+        if (!HasPreservingUnknownEnumSemantics(field->file()) &&
+            field->type() == FieldDescriptor::TYPE_ENUM) {
+          format(
+              "ctx->extra_parse_data().SetEnumValidator($1$_IsValid, "
+              "msg->mutable_unknown_fields(), $2$);\n"
+              "parser_till_end = "
+              "::$proto_ns$::internal::PackedValidEnumParser$3$;\n"
+              "object = msg->mutable_$4$();\n",
+              QualifiedClassName(field->enum_type()), field->number(),
+              UseUnknownFieldSet(field->file(), options) ? "" : "Lite",
+              FieldName(field));
+        } else {
+          format(
+              "parser_till_end = ::$proto_ns$::internal::Packed$1$Parser;\n"
+              "object = msg->mutable_$2$();\n",
+              DeclaredTypeMethodName(field->type()), FieldName(field));
+        }
+      } else {
+        auto field_type = field->type();
+        if (IsProto1(field->file(), options)) {
+          if (field->is_packable()) {
+            // Sigh ... packed fields endup as a string in proto1
+            field_type = FieldDescriptor::TYPE_BYTES;
+          }
+          if (field_type == FieldDescriptor::TYPE_STRING) {
+            // In proto1 strings are treated as bytes
+            field_type = FieldDescriptor::TYPE_BYTES;
+          }
+        }
+        string utf8 = "";
+        switch (field_type) {
+          case FieldDescriptor::TYPE_STRING:
+            utf8 = GetUtf8Suffix(field, options);
+            if (!utf8.empty()) {
+              string name = "nullptr";
+              if (HasDescriptorMethods(field->file(), options)) {
+                name = field->full_name();
+              }
+              format("ctx->extra_parse_data().SetFieldName(\"$1$\");\n", name);
+            }
+            [[clang::fallthrough]];
+          case FieldDescriptor::TYPE_BYTES: {
+            if (field->options().ctype() == FieldOptions::STRING ||
+                (IsProto1(field->file(), options) &&
+                 field->options().ctype() == FieldOptions::STRING_PIECE)) {
+              format(
+                  "parser_till_end = ::$proto_ns$::internal::StringParser$1$;\n"
+                  "$string$* str = msg->$2$_$3$();\n"
+                  "str->clear();\n",
+                  utf8,
+                  field->is_repeated() && !field->is_map() &&
+                          !field->is_packable()
+                      ? "add"
+                      : "mutable",
+                  FieldName(field));
+            } else if (field->options().ctype() == FieldOptions::CORD) {
+              string cord_parser = "CordParser" + utf8;
+              format(
+                  "parser_till_end = ::$proto_ns$::internal::$1$;\n"
+                  "auto* str = msg->$2$_$3$();\n"
+                  "str->Clear();\n",
+                  cord_parser,
+                  field->is_repeated() && !field->is_map() ? "add" : "mutable",
+                  FieldName(field));
+            } else if (field->options().ctype() == FieldOptions::STRING_PIECE) {
+              format(
+                  "parser_till_end = "
+                  "::$proto_ns$::internal::StringPieceParser$1$;\n"
+                  "::$proto_ns$::internal::StringPieceField* str = "
+                  "msg->$2$_$3$();\n"
+                  "str->Clear();\n",
+                  utf8,
+                  field->is_repeated() && !field->is_map() ? "add" : "mutable",
+                  FieldName(field));
+            }
+            format("object = str;\n");
+            break;
+          }
+          case FieldDescriptor::TYPE_MESSAGE: {
+            GOOGLE_CHECK(field->message_type());
+            if (IsImplicitWeakField(field, options, scc_analyzer)) {
+              if (!field->is_repeated()) {
+                format("object = HasBitSetters::mutable_$1$(msg);\n",
+                       FieldName(field));
+              } else {
+                format(
+                    "object = "
+                    "CastToBase(&msg->$1$_)->AddWeak(reinterpret_cast<const "
+                    "::google::protobuf::MessageLite*>(&$2$::_$3$_default_instance_));\n",
+                    FieldName(field), Namespace(field->message_type()),
+                    ClassName(field->message_type()));
+              }
+              format(
+                  "parser_till_end = static_cast<::$proto_ns$::MessageLite*>("
+                  "object)->_ParseFunc();\n");
+              break;
+            } else if (IsWeak(field, options)) {
+              if (IsProto1(field->file(), options)) {
+                format("object = msg->internal_mutable_$1$();\n",
+                       FieldName(field));
+              } else {
+                format(
+                    "object = msg->_weak_field_map_.MutableMessage($1$, "
+                    "_$classname$_default_instance_.$2$_);\n",
+                    field->number(), FieldName(field));
+              }
+              format(
+                  "parser_till_end = static_cast<::$proto_ns$::MessageLite*>("
+                  "object)->_ParseFunc();\n");
+              break;
+            }
+            format(
+                "parser_till_end = $1$::_InternalParse;\n"
+                "object = msg->$2$_$3$();\n",
+                QualifiedClassName(field->message_type()),
+                field->is_repeated() && !field->is_map() ? "add" : "mutable",
+                FieldName(field));
+            break;
+          }
+          default:
+            GOOGLE_LOG(FATAL) << "Illegal combination for length delimited wiretype "
+                       << " filed type is " << field->type();
+        }
+      }
+      format(
+          "if (size > end - ptr) goto len_delim_till_end;\n"
+          "auto newend = ptr + size;\n"
+          "if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) "
+          "goto error;\n"
+          "ptr = newend;\n");
+      break;
+    }
+    case WireFormatLite::WIRETYPE_START_GROUP: {
+      format(
+          "parser_till_end = $1$::_InternalParse;\n"
+          "object = msg->$2$_$3$();\n"
+          "if (!ctx->PrepareGroup(tag, &depth)) goto error;\n"
+          "ptr = parser_till_end(ptr, end, object, ctx);\n"
+          "if (!ptr) goto error;\n"
+          "if (ctx->GroupContinues(depth)) goto group_continues;\n",
+          QualifiedClassName(field->message_type()),
+          field->is_repeated() ? "add" : "mutable", FieldName(field));
+      break;
+    }
+    case WireFormatLite::WIRETYPE_END_GROUP: {
+      GOOGLE_LOG(FATAL) << "Can't have end group field\n";
+      break;
+    }
+    case WireFormatLite::WIRETYPE_FIXED32: {
+      string type = PrimitiveTypeName(options, field->cpp_type());
+      format(
+          "$1$ val;\n"
+          "std::memcpy(&val, ptr, 4);\n"
+          "ptr += 4;\n",
+          type);
+      if (field->is_repeated()) {
+        format("msg->add_$1$(val);\n", FieldName(field));
+      } else {
+        format("msg->set_$1$(val);\n", FieldName(field));
+      }
+      break;
+    }
+  }  // switch (wire_type)
+
+  if (ShouldRepeat(field, wiretype)) {
+    format("if (ptr >= end) break;\n");
+    uint32 x = field->number() * 8 + wiretype;
+    uint64 y = 0;
+    int cnt = 0;
+    do {
+      y += static_cast<uint64>((x & 0x7F) + (x >= 128 ? 128 : 0))
+           << (cnt++ * 8);
+      x >>= 7;
+    } while (x);
+    uint64 mask = (1ull << (cnt * 8)) - 1;
+    format.Outdent();
+    format(
+        "} while((*reinterpret_cast<const $uint64$*>(ptr) & $1$) == $2$ && "
+        "(ptr += $3$));\n",
+        mask, y, cnt);
+  }
+  format("break;\n");
+}
+
+void GenerateCaseBody(const FieldDescriptor* field, const Options& options,
+                      MessageSCCAnalyzer* scc_analyzer,
+                      const Formatter& format) {
+  using internal::WireFormat;
+  using internal::WireFormatLite;
+
+  if (!IsProto1(field->file(), options) && field->is_packable()) {
+    auto expected_wiretype = WireFormat::WireTypeForFieldType(field->type());
+    GOOGLE_CHECK(expected_wiretype != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+    uint32 expected_tag =
+        WireFormatLite::MakeTag(field->number(), expected_wiretype);
+    auto fallback_wiretype = WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
+    uint32 fallback_tag =
+        WireFormatLite::MakeTag(field->number(), fallback_wiretype);
+
+    if (field->is_packed()) {
+      std::swap(expected_tag, fallback_tag);
+      std::swap(expected_wiretype, fallback_wiretype);
+    }
+
+    format("if (static_cast<$uint8$>(tag) == $1$) {\n", expected_tag & 0xFF);
+    format.Indent();
+    GenerateCaseBody(expected_wiretype, field, options, scc_analyzer, format);
+    format.Outdent();
+    format(
+        "} else if (static_cast<$uint8$>(tag) != $1$) goto handle_unusual;\n",
+        fallback_tag & 0xFF);
+    GenerateCaseBody(fallback_wiretype, field, options, scc_analyzer, format);
+  } else {
+    auto wiretype = WireFormat::WireTypeForField(field);
+    format("if (static_cast<$uint8$>(tag) != $1$) goto handle_unusual;\n",
+           WireFormat::MakeTag(field) & 0xFF);
+    GenerateCaseBody(wiretype, field, options, scc_analyzer, format);
+  }
+}
+
+void GenerateParserLoop(const Descriptor* descriptor, const Options& options,
+                        MessageSCCAnalyzer* scc_analyzer,
+                        io::Printer* printer) {
+  using internal::WireFormat;
+  using internal::WireFormatLite;
+
+  Formatter format(printer);
+  format.Set("classname", ClassName(descriptor));
+  format.Set("proto_ns", ProtobufNamespace(options));
+  std::map<string, string> vars;
+  SetCommonVars(options, &vars);
+  format.AddMap(vars);
+
+  std::vector<const FieldDescriptor*> ordered_fields;
+  for (auto field : FieldRange(descriptor)) {
+    ordered_fields.push_back(field);
+  }
+  std::sort(ordered_fields.begin(), ordered_fields.end(),
+            [](const FieldDescriptor* a, const FieldDescriptor* b) {
+              return a->number() < b->number();
+            });
+
+  format(
+      "const char* $classname$::_InternalParse(const char* begin, const char* "
+      "end, void* object,\n"
+      "                  ::$proto_ns$::internal::ParseContext* ctx) {\n"
+      "  auto msg = static_cast<$classname$*>(object);\n"
+      "  $uint32$ size; (void)size;\n"
+      "  int depth; (void)depth;\n"
+      "  ::$proto_ns$::internal::ParseFunc parser_till_end; "
+      "(void)parser_till_end;\n"
+      "  auto ptr = begin;\n"
+      "  while (ptr < end) {\n"
+      "    $uint32$ tag;\n"
+      "    ptr = Varint::Parse32Inline(ptr, &tag);\n"
+      "    if (!ptr) goto error;\n"
+      "    switch (tag >> 3) {\n"
+      "      case 0: goto error;\n");
+
+  format.Indent();
+  format.Indent();
+  format.Indent();
+
+  for (const auto* field : ordered_fields) {
+    if (IsProto1(descriptor->file(), options)) {
+      if (field->number() >= (1 << 14)) continue;
+    }
+    // Print the field's (or oneof's) proto-syntax definition as a comment.
+    // We don't want to print group bodies so we cut off after the first
+    // line.
+    string def;
+    {
+      DebugStringOptions options;
+      options.elide_group_body = true;
+      options.elide_oneof_body = true;
+      def = field->DebugStringWithOptions(options);
+      def = def.substr(0, def.find_first_of('\n'));
+    }
+    format(
+        "// $1$\n"
+        "case $2$: {\n",
+        def, field->number());
+    format.Indent();
+    GenerateCaseBody(field, options, scc_analyzer, format);
+    format.Outdent();
+    format("}\n");  // case
+  }                 // for fields
+  format(
+      "default: {\n"
+      "handle_unusual: (void)&&handle_unusual;\n"
+      "  if ((tag & 7) == 4) {\n"
+      "    if (!ctx->ValidEndGroup(tag)) goto error;\n"
+      "    return ptr;\n"
+      "  }\n");
+  if (IsMapEntryMessage(descriptor)) {
+    format(
+        "  break;\n"
+        "}\n");
+  } else {
+    if (descriptor->extension_range_count() > 0) {
+      format("if (");
+      for (int i = 0; i < descriptor->extension_range_count(); i++) {
+        const Descriptor::ExtensionRange* range =
+            descriptor->extension_range(i);
+        if (i > 0) format(" ||\n    ");
+
+        uint32 start_tag = WireFormatLite::MakeTag(
+            range->start, static_cast<WireFormatLite::WireType>(0));
+        uint32 end_tag = WireFormatLite::MakeTag(
+            range->end, static_cast<WireFormatLite::WireType>(0));
+
+        if (range->end > FieldDescriptor::kMaxNumber) {
+          format("($1$u <= tag)", start_tag);
+        } else {
+          format("($1$u <= tag && tag < $2$u)", start_tag, end_tag);
+        }
+      }
+      format(") {\n");
+      format(
+          "  auto res = msg->_extensions_.ParseField(tag, {_InternalParse, "
+          "msg}, ptr, end,\n"
+          "      internal_default_instance(), &msg->_internal_metadata_, "
+          "ctx);\n"
+          "  ptr = res.first;\n"
+          "  if (res.second) return ptr;\n"
+          "  continue;\n"
+          "}\n");
+    }
+    format(
+        "  auto res = UnknownFieldParse(tag, {_InternalParse, msg},\n"
+        "    ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), "
+        "ctx);\n"
+        "  ptr = res.first;\n"
+        "  if (res.second) return ptr;\n"
+        "}\n");  // default case
+  }
+  format.Outdent();
+  format.Outdent();
+  format.Outdent();
+  format(
+      "    }  // switch\n"
+      "  }  // while\n"
+      "  return ptr;\n"
+      "error:\n"
+      "  return nullptr;\n"
+      "len_delim_till_end: (void)&&len_delim_till_end;\n"
+      "  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},\n"
+      "                                 {parser_till_end, object}, size);\n"
+      "group_continues: (void)&&group_continues;\n"
+      "  $DCHK$(ptr >= end);\n"
+      // Group crossed end and must be continued. Either this a parse failure
+      // or we need to resume on the next chunk and thus save the state.
+      "  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, "
+      "depth);\n"
+      "  return ptr;\n"
+      "}\n");
+}
 
 }  // namespace cpp
 }  // namespace compiler
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
index eac6512..c01329f 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -35,25 +35,57 @@
 #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
 #define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
 
+#include <iterator>
 #include <map>
 #include <string>
+
 #include <google/protobuf/compiler/cpp/cpp_options.h>
+#include <google/protobuf/compiler/scc.h>
 #include <google/protobuf/compiler/code_generator.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/descriptor.h>
+#include <google/protobuf/port.h>
 #include <google/protobuf/stubs/strutil.h>
 
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 namespace compiler {
 namespace cpp {
 
+inline string ProtobufNamespace(const Options& options) {
+  return options.opensource_runtime ? "google::protobuf" : "proto2";
+}
+
+inline string MacroPrefix(const Options& options) {
+  return options.opensource_runtime ? "GOOGLE_PROTOBUF" : "GOOGLE_PROTOBUF";
+}
+
+inline string DeprecatedAttribute(const Options& options, bool deprecated) {
+  if (!deprecated) {
+    return "";
+  }
+  return MacroPrefix(options) + "_DEPRECATED ";
+}
+
 // Commonly-used separator comments.  Thick is a line of '=', thin is a line
 // of '-'.
 extern const char kThickSeparator[];
 extern const char kThinSeparator[];
 
+inline bool IsProto1(const FileDescriptor* file, const Options& options) {
+  return false;
+}
+
+void SetCommonVars(const Options& options, std::map<string, string>* variables);
+
+bool GetBootstrapBasename(const Options& options, const string& basename,
+                          string* bootstrap_basename);
+bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context,
+                    bool bootstrap_flag, string* basename);
+bool IsBootstrapProto(const Options& options, const FileDescriptor* file);
 
 // Name space of the proto file. This namespace is such that the string
 // "<namespace>::some_name" is the correct fully qualified namespace.
@@ -63,20 +95,19 @@
 inline string Namespace(const FileDescriptor* d) {
   return Namespace(d->package());
 }
-template <typename Desc>
-string Namespace(const Desc* d) {
-  return Namespace(d->file());
-}
+
+string Namespace(const Descriptor* d);
+string Namespace(const FieldDescriptor* d);
+string Namespace(const EnumDescriptor* d);
 
 // Returns true if it's safe to reset "field" to zero.
 bool CanInitializeByZeroing(const FieldDescriptor* field);
 
 string ClassName(const Descriptor* descriptor);
 string ClassName(const EnumDescriptor* enum_descriptor);
-template <typename Desc>
-string QualifiedClassName(const Desc* d) {
-  return Namespace(d) + "::" + ClassName(d);
-}
+
+string QualifiedClassName(const Descriptor* d);
+string QualifiedClassName(const EnumDescriptor* d);
 
 // DEPRECATED just use ClassName or QualifiedClassName, a boolean is very
 // unreadable at the callsite.
@@ -141,11 +172,8 @@
 LIBPROTOC_EXPORT string StripProto(const string& filename);
 
 // Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
-// Note:  non-built-in type names will be qualified, meaning they will start
-// with a ::.  If you are using the type as a template parameter, you will
-// need to insure there is a space between the < and the ::, because the
-// ridiculous C++ standard defines "<:" to be a synonym for "[".
 const char* PrimitiveTypeName(FieldDescriptor::CppType type);
+string PrimitiveTypeName(const Options& options, FieldDescriptor::CppType type);
 
 // Get the declared type name in CamelCase format, as is used e.g. for the
 // methods of WireFormat.  For example, TYPE_INT32 becomes "Int32".
@@ -155,22 +183,59 @@
 string Int32ToString(int number);
 
 // Return the code that evaluates to the number when compiled.
-string Int64ToString(int64 number);
+string Int64ToString(const Options& options, int64 number);
 
 // Get code that evaluates to the field's default value.
+string DefaultValue(const Options& options, const FieldDescriptor* field);
+
+// Compatibility function for callers outside proto2.
 string DefaultValue(const FieldDescriptor* field);
 
 // Convert a file name into a valid identifier.
 string FilenameIdentifier(const string& filename);
 
-// For each .proto file generates a unique namespace. In this namespace global
-// definitions are put to prevent collisions.
-string FileLevelNamespace(const string& filename);
-inline string FileLevelNamespace(const FileDescriptor* file) {
-  return FileLevelNamespace(file->name());
+// For each .proto file generates a unique name. To prevent collisions of
+// symbols in the global namespace
+string UniqueName(const string& name, const string& filename,
+                  const Options& options);
+inline string UniqueName(const string& name, const FileDescriptor* d,
+                         const Options& options) {
+  return UniqueName(name, d->name(), options);
 }
-inline string FileLevelNamespace(const Descriptor* d) {
-  return FileLevelNamespace(d->file());
+inline string UniqueName(const string& name, const Descriptor* d,
+                         const Options& options) {
+  return UniqueName(name, d->file(), options);
+}
+inline string UniqueName(const string& name, const EnumDescriptor* d,
+                         const Options& options) {
+  return UniqueName(name, d->file(), options);
+}
+inline string UniqueName(const string& name, const ServiceDescriptor* d,
+                         const Options& options) {
+  return UniqueName(name, d->file(), options);
+}
+
+// Versions for call sites that only support the internal runtime (like proto1
+// support).
+inline Options InternalRuntimeOptions() {
+  Options options;
+  options.opensource_runtime = false;
+  return options;
+}
+inline string UniqueName(const string& name, const string& filename) {
+  return UniqueName(name, filename, InternalRuntimeOptions());
+}
+inline string UniqueName(const string& name, const FileDescriptor* d) {
+  return UniqueName(name, d->name(), InternalRuntimeOptions());
+}
+inline string UniqueName(const string& name, const Descriptor* d) {
+  return UniqueName(name, d->file(), InternalRuntimeOptions());
+}
+inline string UniqueName(const string& name, const EnumDescriptor* d) {
+  return UniqueName(name, d->file(), InternalRuntimeOptions());
+}
+inline string UniqueName(const string& name, const ServiceDescriptor* d) {
+  return UniqueName(name, d->file(), InternalRuntimeOptions());
 }
 
 // Return the qualified C++ name for a file level symbol.
@@ -184,24 +249,14 @@
                         const FieldDescriptor* field,
                         const string& prefix);
 
-// Returns true if unknown fields are always preserved after parsing.
-inline bool AlwaysPreserveUnknownFields(const FileDescriptor* file) {
-  return file->syntax() != FileDescriptor::SYNTAX_PROTO3;
-}
-
-// Returns true if unknown fields are preserved after parsing.
-inline bool AlwaysPreserveUnknownFields(const Descriptor* message) {
-  return AlwaysPreserveUnknownFields(message->file());
-}
-
 // Returns true if generated messages have public unknown fields accessors
 inline bool PublicUnknownFieldsAccessors(const Descriptor* message) {
   return message->file()->syntax() != FileDescriptor::SYNTAX_PROTO3;
 }
 
 // Returns the optimize mode for <file>, respecting <options.enforce_lite>.
-::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor(
-    const FileDescriptor* file, const Options& options);
+FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
+                                        const Options& options);
 
 // Determines whether unknown fields will be stored in an UnknownFieldSet or
 // a string.
@@ -210,6 +265,56 @@
   return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
 }
 
+inline bool IsWeak(const FieldDescriptor* field, const Options& options) {
+  if (field->options().weak()) {
+    GOOGLE_CHECK(!options.opensource_runtime);
+    return true;
+  }
+  return false;
+}
+
+// For a string field, returns the effective ctype.  If the actual ctype is
+// not supported, returns the default of STRING.
+FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field,
+                                         const Options& options);
+
+inline bool IsCord(const FieldDescriptor* field, const Options& options) {
+  return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
+         EffectiveStringCType(field, options) == FieldOptions::CORD;
+}
+
+inline bool IsStringPiece(const FieldDescriptor* field,
+                          const Options& options) {
+  return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
+         EffectiveStringCType(field, options) == FieldOptions::STRING_PIECE;
+}
+
+// Does the given FileDescriptor use lazy fields?
+bool HasLazyFields(const FileDescriptor* file, const Options& options);
+
+// Is the given field a supported lazy field?
+inline bool IsLazy(const FieldDescriptor* field, const Options& options) {
+  return field->options().lazy() && !field->is_repeated() &&
+         field->type() == FieldDescriptor::TYPE_MESSAGE &&
+         GetOptimizeFor(field->file(), options) != FileOptions::LITE_RUNTIME &&
+         !options.opensource_runtime;
+}
+
+// Does the file contain any definitions that need extension_set.h?
+bool HasExtensionsOrExtendableMessage(const FileDescriptor* file);
+
+// Does the file have any repeated fields, necessitating the file to include
+// repeated_field.h? This does not include repeated extensions, since those are
+// all stored internally in an ExtensionSet, not a separate RepeatedField*.
+bool HasRepeatedFields(const FileDescriptor* file);
+
+// Does the file have any string/bytes fields with ctype=STRING_PIECE? This
+// does not include extensions, since ctype is ignored for extensions.
+bool HasStringPieceFields(const FileDescriptor* file, const Options& options);
+
+// Does the file have any string/bytes fields with ctype=CORD? This does not
+// include extensions, since ctype is ignored for extensions.
+bool HasCordFields(const FileDescriptor* file, const Options& options);
 
 // Does the file have any map fields, necessitating the file to include
 // map_field_inl.h and map.h.
@@ -247,6 +352,18 @@
   return GetOptimizeFor(file, options) == FileOptions::SPEED;
 }
 
+inline bool IsProto2MessageSet(const Descriptor* descriptor,
+                               const Options& options) {
+  return !options.opensource_runtime &&
+         descriptor->options().message_set_wire_format() &&
+         descriptor->full_name() == "google.protobuf.bridge.MessageSet";
+}
+
+inline bool IsProto2MessageSetFile(const FileDescriptor* file,
+                                   const Options& options) {
+  return !options.opensource_runtime &&
+         file->name() == "net/proto2/bridge/proto/message_set.proto";
+}
 
 inline bool IsMapEntryMessage(const Descriptor* descriptor) {
   return descriptor->options().map_entry();
@@ -255,10 +372,6 @@
 // Returns true if the field's CPPTYPE is string or message.
 bool IsStringOrMessage(const FieldDescriptor* field);
 
-// For a string field, returns the effective ctype.  If the actual ctype is
-// not supported, returns the default of STRING.
-FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field);
-
 string UnderscoresToCamelCase(const string& input, bool cap_next_letter);
 
 inline bool HasFieldPresence(const FileDescriptor* file) {
@@ -302,19 +415,8 @@
 
 bool IsWellKnownMessage(const FileDescriptor* descriptor);
 
-void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
-                                    const Options& options, bool for_parse,
-                                    const std::map<string, string>& variables,
-                                    const char* parameters,
-                                    io::Printer* printer);
-
-void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
-                                  const Options& options, bool for_parse,
-                                  const std::map<string, string>& variables,
-                                  const char* parameters, io::Printer* printer);
-
-inline ::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor(
-    const FileDescriptor* file, const Options& options) {
+inline FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
+                                               const Options& options) {
   return options.enforce_lite
       ? FileOptions::LITE_RUNTIME
       : file->options().optimize_for();
@@ -330,21 +432,173 @@
   return result;
 }
 
-bool HasWeakFields(const Descriptor* desc);
-bool HasWeakFields(const FileDescriptor* desc);
+bool HasWeakFields(const Descriptor* desc, const Options& options);
+bool HasWeakFields(const FileDescriptor* desc, const Options& options);
 
 // Returns true if the "required" restriction check should be ignored for the
 // given field.
 inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field,
                                                   const Options& options) {
-  return false;
+  // Do not check "required" for lazy fields.
+  return IsLazy(field, options);
 }
 
+struct MessageAnalysis {
+  bool is_recursive;
+  bool contains_cord;
+  bool contains_extension;
+  bool contains_required;
+  bool constructor_requires_initialization;
+};
+
+// This class is used in FileGenerator, to ensure linear instead of
+// quadratic performance, if we do this per message we would get O(V*(V+E)).
+// Logically this is just only used in message.cc, but in the header for
+// FileGenerator to help share it.
+class LIBPROTOC_EXPORT MessageSCCAnalyzer {
+ public:
+  explicit MessageSCCAnalyzer(const Options& options) : options_(options) {}
+
+  MessageAnalysis GetSCCAnalysis(const SCC* scc);
+
+  bool HasRequiredFields(const Descriptor* descriptor) {
+    MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor));
+    return result.contains_required || result.contains_extension;
+  }
+  const SCC* GetSCC(const Descriptor* descriptor) {
+    return analyzer_.GetSCC(descriptor);
+  }
+
+ private:
+  SCCAnalyzer analyzer_;
+  Options options_;
+  std::map<const SCC*, MessageAnalysis> analysis_cache_;
+};
+
+void ListAllFields(const Descriptor* d,
+                   std::vector<const FieldDescriptor*>* fields);
+void ListAllFields(const FileDescriptor* d,
+                   std::vector<const FieldDescriptor*>* fields);
+void ListAllTypesForServices(const FileDescriptor* fd,
+                             std::vector<const Descriptor*>* types);
+
+// Indicates whether we should use implicit weak fields for this file.
+bool UsingImplicitWeakFields(const FileDescriptor* file,
+                             const Options& options);
+
+// Indicates whether to treat this field as implicitly weak.
+bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
+                         MessageSCCAnalyzer* scc_analyzer);
+
+// Formatter is a functor class which acts as a closure around printer and
+// the variable map. It's much like printer->Print except it supports both named
+// variables that are substituted using a key value map and direct arguments. In
+// the format string $1$, $2$, etc... are substituted for the first, second, ...
+// direct argument respectively in the format call, it accepts both strings and
+// integers. The implementation verifies all arguments are used and are "first"
+// used in order of appearance in the argument list. For example,
+//
+// Format("return array[$1$];", 3) -> "return array[3];"
+// Format("array[$2$] = $1$;", "Bla", 3) -> FATAL error (wrong order)
+// Format("array[$1$] = $2$;", 3, "Bla") -> "array[3] = Bla;"
+//
+// The arguments can be used more than once like
+//
+// Format("array[$1$] = $2$;  // Index = $1$", 3, "Bla") ->
+//        "array[3] = Bla;  // Index = 3"
+//
+// If you use more arguments use the following style to help the reader,
+//
+// Format("int $1$() {\n"
+//        "  array[$2$] = $3$;\n"
+//        "  return $4$;"
+//        "}\n",
+//        funname, // 1
+//        idx,  // 2
+//        varname,  // 3
+//        retval);  // 4
+//
+// but consider using named variables. Named variables like $foo$, with some
+// identifier foo, are looked up in the map. One additional feature is that
+// spaces are accepted between the '$' delimiters, $ foo$ will
+// substiture to " bar" if foo stands for "bar", but in case it's empty
+// will substitute to "". Hence, for example,
+//
+// Format(vars, "$dllexport $void fun();") -> "void fun();"
+//                                            "__declspec(export) void fun();"
+//
+// which is convenient to prevent double, leading or trailing spaces.
+class LIBPROTOC_EXPORT Formatter {
+ public:
+  explicit Formatter(io::Printer* printer) : printer_(printer) {}
+  Formatter(io::Printer* printer, const std::map<string, string>& vars)
+      : printer_(printer), vars_(vars) {}
+
+  template <typename T>
+  void Set(const string& key, const T& value) {
+    vars_[key] = ToString(value);
+  }
+
+  void AddMap(const std::map<string, string>& vars) {
+    for (const auto& keyval : vars) vars_[keyval.first] = keyval.second;
+  }
+
+  template <typename... Args>
+  void operator()(const char* format, const Args&... args) const {
+    printer_->FormatInternal({ToString(args)...}, vars_, format);
+  }
+
+  void Indent() const { printer_->Indent(); }
+  void Outdent() const { printer_->Outdent(); }
+  io::Printer* printer() const { return printer_; }
+
+  class LIBPROTOC_EXPORT SaveState {
+   public:
+    explicit SaveState(Formatter* format)
+        : format_(format), vars_(format->vars_) {}
+    ~SaveState() { format_->vars_.swap(vars_); }
+
+   private:
+    Formatter* format_;
+    std::map<string, string> vars_;
+  };
+
+ private:
+  io::Printer* printer_;
+  std::map<string, string> vars_;
+
+  // Convenience overloads to accept different types as arguments.
+  static string ToString(const string& s) { return s; }
+  template <typename I, typename = typename std::enable_if<
+                            std::is_integral<I>::value>::type>
+  static string ToString(I x) {
+    return SimpleItoa(x);
+  }
+  static string ToString(strings::Hex x) { return StrCat(x); }
+  static string ToString(const FieldDescriptor* d) { return Payload(d); }
+  static string ToString(const Descriptor* d) { return Payload(d); }
+  static string ToString(const EnumDescriptor* d) { return Payload(d); }
+  static string ToString(const EnumValueDescriptor* d) { return Payload(d); }
+
+  template <typename Descriptor>
+  static string Payload(const Descriptor* descriptor) {
+    std::vector<int> path;
+    descriptor->GetLocationPath(&path);
+    GeneratedCodeInfo::Annotation annotation;
+    for (int i = 0; i < path.size(); ++i) {
+      annotation.add_path(path[i]);
+    }
+    annotation.set_source_file(descriptor->file()->name());
+    return annotation.SerializeAsString();
+  }
+};
+
 class LIBPROTOC_EXPORT NamespaceOpener {
  public:
-  explicit NamespaceOpener(io::Printer* printer) : printer_(printer) {}
-  NamespaceOpener(const string& name, io::Printer* printer)
-      : printer_(printer) {
+  explicit NamespaceOpener(const Formatter& format)
+      : printer_(format.printer()) {}
+  NamespaceOpener(const string& name, const Formatter& format)
+      : NamespaceOpener(format) {
     ChangeTo(name);
   }
   ~NamespaceOpener() { ChangeTo(""); }
@@ -372,90 +626,97 @@
   std::vector<string> name_stack_;
 };
 
-// Description of each strongly connected component. Note that the order
-// of both the descriptors in this SCC and the order of children is
-// deterministic.
-struct SCC {
-  std::vector<const Descriptor*> descriptors;
-  std::vector<const SCC*> children;
+string GetUtf8Suffix(const FieldDescriptor* field, const Options& options);
+void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
+                                    const Options& options, bool for_parse,
+                                    const char* parameters,
+                                    const Formatter& format);
 
-  const Descriptor* GetRepresentative() const { return descriptors[0]; }
-};
+void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
+                                  const Options& options, bool for_parse,
+                                  const char* parameters,
+                                  const Formatter& format);
 
-struct MessageAnalysis {
-  bool is_recursive;
-  bool contains_cord;
-  bool contains_extension;
-  bool contains_required;
-};
+template <typename T>
+struct FieldRangeImpl {
+  struct Iterator {
+    using iterator_category = std::forward_iterator_tag;
+    using value_type = const FieldDescriptor*;
+    using difference_type = int;
 
-// This class is used in FileGenerator, to ensure linear instead of
-// quadratic performance, if we do this per message we would get O(V*(V+E)).
-// Logically this is just only used in message.cc, but in the header for
-// FileGenerator to help share it.
-class LIBPROTOC_EXPORT SCCAnalyzer {
- public:
-  explicit SCCAnalyzer(const Options& options) : options_(options), index_(0) {}
-  ~SCCAnalyzer() {
-    for (int i = 0; i < garbage_bin_.size(); i++) delete garbage_bin_[i];
-  }
+    value_type operator*() { return descriptor->field(idx); }
 
-  const SCC* GetSCC(const Descriptor* descriptor) {
-    if (cache_.count(descriptor)) return cache_[descriptor].scc;
-    return DFS(descriptor).scc;
-  }
+    friend bool operator==(const Iterator& a, const Iterator& b) {
+      GOOGLE_DCHECK(a.descriptor == b.descriptor);
+      return a.idx == b.idx;
+    }
+    friend bool operator!=(const Iterator& a, const Iterator& b) {
+      return !(a == b);
+    }
 
-  MessageAnalysis GetSCCAnalysis(const SCC* scc);
+    Iterator& operator++() {
+      idx++;
+      return *this;
+    }
 
-  bool HasRequiredFields(const Descriptor* descriptor) {
-    MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor));
-    return result.contains_required || result.contains_extension;
-  }
-
- private:
-  struct NodeData {
-    const SCC* scc;  // if null it means its still on the stack
-    int index;
-    int lowlink;
+    int idx;
+    const T* descriptor;
   };
 
-  Options options_;
-  std::map<const Descriptor*, NodeData> cache_;
-  std::map<const SCC*, MessageAnalysis> analysis_cache_;
-  std::vector<const Descriptor*> stack_;
-  int index_;
-  std::vector<SCC*> garbage_bin_;
+  Iterator begin() const { return {0, descriptor}; }
+  Iterator end() const { return {descriptor->field_count(), descriptor}; }
 
-  SCC* CreateSCC() {
-    garbage_bin_.push_back(new SCC());
-    return garbage_bin_.back();
-  }
-
-  // Tarjan's Strongly Connected Components algo
-  NodeData DFS(const Descriptor* descriptor);
-
-  // Add the SCC's that are children of this SCC to its children.
-  void AddChildren(SCC* scc);
+  const T* descriptor;
 };
 
-void ListAllFields(const Descriptor* d,
-                   std::vector<const FieldDescriptor*>* fields);
-void ListAllFields(const FileDescriptor* d,
-                   std::vector<const FieldDescriptor*>* fields);
-void ListAllTypesForServices(const FileDescriptor* fd,
-                             std::vector<const Descriptor*>* types);
+template <typename T>
+FieldRangeImpl<T> FieldRange(const T* desc) {
+  return {desc};
+}
 
-// Indicates whether we should use implicit weak fields for this file.
-bool UsingImplicitWeakFields(const FileDescriptor* file,
-                             const Options& options);
+struct OneOfRangeImpl {
+  struct Iterator {
+    using iterator_category = std::forward_iterator_tag;
+    using value_type = const OneofDescriptor*;
+    using difference_type = int;
 
-// Indicates whether to treat this field as implicitly weak.
-bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
-                         SCCAnalyzer* scc_analyzer);
+    value_type operator*() { return descriptor->oneof_decl(idx); }
+
+    friend bool operator==(const Iterator& a, const Iterator& b) {
+      GOOGLE_DCHECK(a.descriptor == b.descriptor);
+      return a.idx == b.idx;
+    }
+    friend bool operator!=(const Iterator& a, const Iterator& b) {
+      return !(a == b);
+    }
+
+    Iterator& operator++() {
+      idx++;
+      return *this;
+    }
+
+    int idx;
+    const Descriptor* descriptor;
+  };
+
+  Iterator begin() const { return {0, descriptor}; }
+  Iterator end() const {
+    return {descriptor->oneof_decl_count(), descriptor};
+  }
+
+  const Descriptor* descriptor;
+};
+
+inline OneOfRangeImpl OneOfRange(const Descriptor* desc) { return {desc}; }
+
+void GenerateParserLoop(const Descriptor* descriptor, const Options& options,
+                        MessageSCCAnalyzer* scc_analyzer, io::Printer* printer);
 
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
index 0e485ca..4ab407d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
@@ -32,9 +32,9 @@
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/wire_format.h>
-
 #include <google/protobuf/stubs/strutil.h>
 
+
 namespace google {
 namespace protobuf {
 namespace compiler {
@@ -50,8 +50,6 @@
                          const Options& options) {
   SetCommonFieldVariables(descriptor, variables, options);
   (*variables)["type"] = ClassName(descriptor->message_type(), false);
-  (*variables)["file_namespace"] =
-      FileLevelNamespace(descriptor->file()->name());
   (*variables)["stream_writer"] =
       (*variables)["declared_type"] +
       (HasFastArraySerialization(descriptor->message_type()->file(), options)
@@ -63,7 +61,7 @@
       descriptor->message_type()->FindFieldByName("key");
   const FieldDescriptor* val =
       descriptor->message_type()->FindFieldByName("value");
-  (*variables)["key_cpp"] = PrimitiveTypeName(key->cpp_type());
+  (*variables)["key_cpp"] = PrimitiveTypeName(options, key->cpp_type());
   switch (val->cpp_type()) {
     case FieldDescriptor::CPPTYPE_MESSAGE:
       (*variables)["val_cpp"] = FieldMessageTypeName(val);
@@ -74,18 +72,17 @@
       (*variables)["wrapper"] = "EnumEntryWrapper";
       break;
     default:
-      (*variables)["val_cpp"] = PrimitiveTypeName(val->cpp_type());
+      (*variables)["val_cpp"] = PrimitiveTypeName(options, val->cpp_type());
       (*variables)["wrapper"] = "EntryWrapper";
   }
   (*variables)["key_wire_type"] =
-      "::google::protobuf::internal::WireFormatLite::TYPE_" +
-      ToUpper(DeclaredTypeMethodName(key->type()));
+      "TYPE_" + ToUpper(DeclaredTypeMethodName(key->type()));
   (*variables)["val_wire_type"] =
-      "::google::protobuf::internal::WireFormatLite::TYPE_" +
-      ToUpper(DeclaredTypeMethodName(val->type()));
+      "TYPE_" + ToUpper(DeclaredTypeMethodName(val->type()));
   (*variables)["map_classname"] = ClassName(descriptor->message_type(), false);
   (*variables)["number"] = SimpleItoa(descriptor->number());
-  (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
+  (*variables)["tag"] =
+      SimpleItoa(internal::WireFormat::MakeTag(descriptor));
 
   if (HasDescriptorMethods(descriptor->file(), options)) {
     (*variables)["lite"] = "";
@@ -104,7 +101,7 @@
 
 MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
                                      const Options& options)
-    : FieldGenerator(options), descriptor_(descriptor) {
+    : FieldGenerator(descriptor, options) {
   SetMessageVariables(descriptor, &variables_, options);
 }
 
@@ -112,37 +109,37 @@
 
 void MapFieldGenerator::
 GeneratePrivateMembers(io::Printer* printer) const {
-  printer->Print(variables_,
-                 "::google::protobuf::internal::MapField$lite$<\n"
-                 "    $map_classname$,\n"
-                 "    $key_cpp$, $val_cpp$,\n"
-                 "    $key_wire_type$,\n"
-                 "    $val_wire_type$,\n"
-                 "    $default_enum_value$ > $name$_;\n");
+  Formatter format(printer, variables_);
+  format(
+      "::$proto_ns$::internal::MapField$lite$<\n"
+      "    $map_classname$,\n"
+      "    $key_cpp$, $val_cpp$,\n"
+      "    ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
+      "    ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
+      "    $default_enum_value$ > $name$_;\n");
 }
 
 void MapFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
-  printer->Print(
-      variables_,
-      "$deprecated_attr$const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n"
-      "    $name$() const;\n");
-  printer->Annotate("name", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n"
-                 "    ${$mutable_$name$$}$();\n");
-  printer->Annotate("{", "}", descriptor_);
+  Formatter format(printer, variables_);
+  format(
+      "$deprecated_attr$const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
+      "    ${1$$name$$}$() const;\n"
+      "$deprecated_attr$::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
+      "    ${1$mutable_$name$$}$();\n",
+      descriptor_);
 }
 
 void MapFieldGenerator::
 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-      "inline const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n"
+  Formatter format(printer, variables_);
+  format(
+      "inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
       "$classname$::$name$() const {\n"
       "  // @@protoc_insertion_point(field_map:$full_name$)\n"
       "  return $name$_.GetMap();\n"
       "}\n"
-      "inline ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n"
+      "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
       "$classname$::mutable_$name$() {\n"
       "  // @@protoc_insertion_point(field_mutable_map:$full_name$)\n"
       "  return $name$_.MutableMap();\n"
@@ -151,17 +148,20 @@
 
 void MapFieldGenerator::
 GenerateClearingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.Clear();\n");
+  Formatter format(printer, variables_);
+  format("$name$_.Clear();\n");
 }
 
 void MapFieldGenerator::
 GenerateMergingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+  Formatter format(printer, variables_);
+  format("$name$_.MergeFrom(from.$name$_);\n");
 }
 
 void MapFieldGenerator::
 GenerateSwappingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
+  Formatter format(printer, variables_);
+  format("$name$_.Swap(&other->$name$_);\n");
 }
 
 void MapFieldGenerator::
@@ -172,8 +172,9 @@
 
 void MapFieldGenerator::
 GenerateMergeFromCodedStream(io::Printer* printer) const {
-    const FieldDescriptor* key_field =
-        descriptor_->message_type()->FindFieldByName("key");
+  Formatter format(printer, variables_);
+  const FieldDescriptor* key_field =
+      descriptor_->message_type()->FindFieldByName("key");
   const FieldDescriptor* value_field =
       descriptor_->message_type()->FindFieldByName("value");
   bool using_entry = false;
@@ -181,17 +182,16 @@
   string value;
   if (IsProto3Field(descriptor_) ||
       value_field->type() != FieldDescriptor::TYPE_ENUM) {
-    printer->Print(
-        variables_,
-        "$map_classname$::Parser< ::google::protobuf::internal::MapField$lite$<\n"
+    format(
+        "$map_classname$::Parser< ::$proto_ns$::internal::MapField$lite$<\n"
         "    $map_classname$,\n"
         "    $key_cpp$, $val_cpp$,\n"
-        "    $key_wire_type$,\n"
-        "    $val_wire_type$,\n"
+        "    ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
+        "    ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
         "    $default_enum_value$ >,\n"
-        "  ::google::protobuf::Map< $key_cpp$, $val_cpp$ > >"
+        "  ::$proto_ns$::Map< $key_cpp$, $val_cpp$ > >"
         " parser(&$name$_);\n"
-        "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
+        "DO_(::$proto_ns$::internal::WireFormatLite::ReadMessageNoVirtual(\n"
         "    input, &parser));\n");
     key = "parser.key()";
     value = "parser.value()";
@@ -199,120 +199,121 @@
     using_entry = true;
     key = "entry->key()";
     value = "entry->value()";
-    printer->Print(variables_,
-        "::std::unique_ptr<$map_classname$> entry($name$_.NewEntry());\n");
-    printer->Print(variables_,
+    format("::std::unique_ptr<$map_classname$> entry($name$_.NewEntry());\n");
+    format(
         "{\n"
         "  ::std::string data;\n"
-        "  DO_(::google::protobuf::internal::WireFormatLite::ReadString(input, &data));\n"
+        "  DO_(::$proto_ns$::internal::WireFormatLite::ReadString(input, "
+        "&data));\n"
         "  DO_(entry->ParseFromString(data));\n"
         "  if ($val_cpp$_IsValid(*entry->mutable_value())) {\n"
         "    (*mutable_$name$())[entry->key()] =\n"
         "        static_cast< $val_cpp$ >(*entry->mutable_value());\n"
         "  } else {\n");
     if (HasDescriptorMethods(descriptor_->file(), options_)) {
-      printer->Print(variables_,
+      format(
           "    mutable_unknown_fields()"
           "->AddLengthDelimited($number$, data);\n");
     } else {
-      printer->Print(variables_,
+      format(
           "    unknown_fields_stream.WriteVarint32($tag$u);\n"
           "    unknown_fields_stream.WriteVarint32(\n"
           "        static_cast< ::google::protobuf::uint32>(data.size()));\n"
           "    unknown_fields_stream.WriteString(data);\n");
     }
 
-    printer->Print(variables_,
+    format(
         "  }\n"
         "}\n");
   }
 
   if (key_field->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
-        key_field, options_, true, variables_,
-        StrCat(key, ".data(), static_cast<int>(", key, ".length()),\n").data(),
-        printer);
+        key_field, options_, true,
+        StrCat(key, ".data(), static_cast<int>(", key, ".length()),\n")
+            .data(),
+        format);
   }
   if (value_field->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
-        value_field, options_, true, variables_,
-        StrCat(value, ".data(), static_cast<int>(", value, ".length()),\n")
+        value_field, options_, true,
+        StrCat(value, ".data(), static_cast<int>(", value,
+                     ".length()),\n")
             .data(),
-        printer);
+        format);
   }
 
   // If entry is allocated by arena, its desctructor should be avoided.
   if (using_entry && SupportsArenas(descriptor_)) {
-    printer->Print(variables_,
-        "if (entry->GetArena() != NULL) entry.release();\n");
+    format("if (entry->GetArena() != NULL) entry.release();\n");
   }
 }
 
-static void GenerateSerializationLoop(io::Printer* printer,
-                                      const std::map<string, string>& variables,
-                                      bool supports_arenas,
-                                      const string& utf8_check,
-                                      const string& loop_header,
-                                      const string& ptr,
-                                      bool loop_via_iterators) {
-  printer->Print(variables,
-      StrCat("::std::unique_ptr<$map_classname$> entry;\n",
-             loop_header, " {\n").c_str());
-  printer->Indent();
+static void GenerateSerializationLoop(const Formatter& format,
+                                      bool supports_arenas, bool string_key,
+                                      bool string_value, bool to_array,
+                                      bool is_deterministic) {
+  format("::std::unique_ptr<$map_classname$> entry;\n");
+  string ptr;
+  if (is_deterministic) {
+    format("for (size_type i = 0; i < n; i++) {\n");
+    ptr = string_key ? "items[static_cast<ptrdiff_t>(i)]"
+                     : "items[static_cast<ptrdiff_t>(i)].second";
+  } else {
+    format(
+        "for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
+        "    it = this->$name$().begin();\n"
+        "    it != this->$name$().end(); ++it) {\n");
+    ptr = "it";
+  }
+  format.Indent();
 
-  printer->Print(variables, StrCat(
-      "entry.reset($name$_.New$wrapper$(\n"
-      "    ", ptr, "->first, ", ptr, "->second));\n"
-      "$write_entry$;\n").c_str());
+  format("entry.reset($name$_.New$wrapper$($1$->first, $1$->second));\n", ptr);
+  if (to_array) {
+    format(
+        "target = ::$proto_ns$::internal::WireFormatLite::InternalWrite"
+        "$declared_type$NoVirtualToArray($number$, *entry, deterministic, "
+        "target);\n");
+  } else {
+    format(
+        "::$proto_ns$::internal::WireFormatLite::Write$stream_writer$($number$,"
+        " "
+        "*entry, output);\n");
+  }
 
   // If entry is allocated by arena, its desctructor should be avoided.
   if (supports_arenas) {
-    printer->Print(
+    format(
         "if (entry->GetArena() != NULL) {\n"
         "  entry.release();\n"
         "}\n");
   }
 
-  if (!utf8_check.empty()) {
-    // If loop_via_iterators is true then ptr is actually an iterator, and we
-    // create a pointer by prefixing it with "&*".
-    printer->Print(
-        StrCat(utf8_check, "(", (loop_via_iterators ? "&*" : ""), ptr, ");\n")
-            .c_str());
+  if (string_key || string_value) {
+    // ptr is either an actual pointer or an iterator, either way we can
+    // create a pointer by taking the address after de-referencing it.
+    format("Utf8Check::Check(&(*$1$));\n", ptr);
   }
 
-  printer->Outdent();
-  printer->Print(
-      "}\n");
+  format.Outdent();
+  format("}\n");
 }
 
 void MapFieldGenerator::
 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
-  std::map<string, string> variables(variables_);
-  variables["write_entry"] = "::google::protobuf::internal::WireFormatLite::Write" +
-                             variables["stream_writer"] + "(\n            " +
-                             variables["number"] + ", *entry, output)";
-  variables["deterministic"] = "output->IsSerializationDeterministic()";
-  GenerateSerializeWithCachedSizes(printer, variables);
+  GenerateSerializeWithCachedSizes(printer, false);
 }
 
 void MapFieldGenerator::
 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
-  std::map<string, string> variables(variables_);
-  variables["write_entry"] =
-      "target = ::google::protobuf::internal::WireFormatLite::\n"
-      "                   InternalWrite" + variables["declared_type"] +
-      "NoVirtualToArray(\n                       " + variables["number"] +
-      ", *entry, deterministic, target);\n";
-  variables["deterministic"] = "deterministic";
-  GenerateSerializeWithCachedSizes(printer, variables);
+  GenerateSerializeWithCachedSizes(printer, true);
 }
 
-void MapFieldGenerator::GenerateSerializeWithCachedSizes(
-    io::Printer* printer, const std::map<string, string>& variables) const {
-  printer->Print(variables,
-      "if (!this->$name$().empty()) {\n");
-  printer->Indent();
+void MapFieldGenerator::GenerateSerializeWithCachedSizes(io::Printer* printer,
+                                                         bool to_array) const {
+  Formatter format(printer, variables_);
+  format("if (!this->$name$().empty()) {\n");
+  format.Indent();
   const FieldDescriptor* key_field =
       descriptor_->message_type()->FindFieldByName("key");
   const FieldDescriptor* value_field =
@@ -320,114 +321,110 @@
   const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING;
   const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING;
 
-  printer->Print(variables,
-      "typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_pointer\n"
+  format(
+      "typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_pointer\n"
       "    ConstPtr;\n");
   if (string_key) {
-    printer->Print(variables,
+    format(
         "typedef ConstPtr SortItem;\n"
-        "typedef ::google::protobuf::internal::"
+        "typedef ::$proto_ns$::internal::"
         "CompareByDerefFirst<SortItem> Less;\n");
   } else {
-    printer->Print(variables,
-        "typedef ::google::protobuf::internal::SortItem< $key_cpp$, ConstPtr > "
+    format(
+        "typedef ::$proto_ns$::internal::SortItem< $key_cpp$, ConstPtr > "
         "SortItem;\n"
-        "typedef ::google::protobuf::internal::CompareByFirstField<SortItem> Less;\n");
+        "typedef ::$proto_ns$::internal::CompareByFirstField<SortItem> "
+        "Less;\n");
   }
-  string utf8_check;
-  if (string_key || string_value) {
-    printer->Print(
+  bool utf8_check = string_key || string_value;
+  if (utf8_check) {
+    format(
         "struct Utf8Check {\n"
         "  static void Check(ConstPtr p) {\n");
-    printer->Indent();
-    printer->Indent();
+    format.Indent();
+    format.Indent();
     if (string_key) {
       GenerateUtf8CheckCodeForString(
-          key_field, options_, false, variables,
-          "p->first.data(), static_cast<int>(p->first.length()),\n", printer);
+          key_field, options_, false,
+          "p->first.data(), static_cast<int>(p->first.length()),\n", format);
     }
     if (string_value) {
       GenerateUtf8CheckCodeForString(
-          value_field, options_, false, variables,
-          "p->second.data(), static_cast<int>(p->second.length()),\n", printer);
+          value_field, options_, false,
+          "p->second.data(), static_cast<int>(p->second.length()),\n", format);
     }
-    printer->Outdent();
-    printer->Outdent();
-    printer->Print(
+    format.Outdent();
+    format.Outdent();
+    format(
         "  }\n"
         "};\n");
-    utf8_check = "Utf8Check::Check";
   }
 
-  printer->Print(variables,
+  format(
       "\n"
-      "if ($deterministic$ &&\n"
+      "if ($1$ &&\n"
       "    this->$name$().size() > 1) {\n"
       "  ::std::unique_ptr<SortItem[]> items(\n"
       "      new SortItem[this->$name$().size()]);\n"
-      "  typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::size_type size_type;\n"
+      "  typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::size_type "
+      "size_type;\n"
       "  size_type n = 0;\n"
-      "  for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
+      "  for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
       "      it = this->$name$().begin();\n"
       "      it != this->$name$().end(); ++it, ++n) {\n"
       "    items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);\n"
       "  }\n"
-      "  ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());\n");
-  printer->Indent();
-  GenerateSerializationLoop(printer, variables, SupportsArenas(descriptor_),
-      utf8_check, "for (size_type i = 0; i < n; i++)",
-      string_key ? "items[static_cast<ptrdiff_t>(i)]" :
-                   "items[static_cast<ptrdiff_t>(i)].second", false);
-  printer->Outdent();
-  printer->Print(
-      "} else {\n");
-  printer->Indent();
-  GenerateSerializationLoop(
-      printer, variables, SupportsArenas(descriptor_), utf8_check,
-      "for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
-      "    it = this->$name$().begin();\n"
-      "    it != this->$name$().end(); ++it)",
-      "it", true);
-  printer->Outdent();
-  printer->Print("}\n");
-  printer->Outdent();
-  printer->Print("}\n");
+      "  ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());\n",
+      to_array ? "deterministic" : "output->IsSerializationDeterministic()");
+  format.Indent();
+  GenerateSerializationLoop(format, SupportsArenas(descriptor_), string_key,
+                            string_value, to_array, true);
+  format.Outdent();
+  format("} else {\n");
+  format.Indent();
+  GenerateSerializationLoop(format, SupportsArenas(descriptor_), string_key,
+                            string_value, to_array, false);
+  format.Outdent();
+  format("}\n");
+  format.Outdent();
+  format("}\n");
 }
 
 void MapFieldGenerator::
 GenerateByteSize(io::Printer* printer) const {
-  printer->Print(variables_,
+  Formatter format(printer, variables_);
+  format(
       "total_size += $tag_size$ *\n"
-      "    ::google::protobuf::internal::FromIntSize(this->$name$_size());\n"
+      "    ::$proto_ns$::internal::FromIntSize(this->$name$_size());\n"
       "{\n"
       "  ::std::unique_ptr<$map_classname$> entry;\n"
-      "  for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
+      "  for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
       "      it = this->$name$().begin();\n"
       "      it != this->$name$().end(); ++it) {\n");
 
   // If entry is allocated by arena, its desctructor should be avoided.
   if (SupportsArenas(descriptor_)) {
-    printer->Print(variables_,
+    format(
         "    if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
         "      entry.release();\n"
         "    }\n");
   }
 
-  printer->Print(variables_,
+  format(
       "    entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
-      "    total_size += ::google::protobuf::internal::WireFormatLite::\n"
+      "    total_size += ::$proto_ns$::internal::WireFormatLite::\n"
       "        $declared_type$SizeNoVirtual(*entry);\n"
       "  }\n");
 
   // If entry is allocated by arena, its desctructor should be avoided.
   if (SupportsArenas(descriptor_)) {
-    printer->Print(variables_,
+    format(
         "  if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
         "    entry.release();\n"
         "  }\n");
   }
 
-  printer->Print("}\n");
+  format("}\n");
 }
 
 }  // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h
index 0d54f0e..95eecc0 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h
@@ -62,11 +62,8 @@
 
  private:
   // A helper for GenerateSerializeWithCachedSizes{,ToArray}.
-  void GenerateSerializeWithCachedSizes(
-      io::Printer* printer, const std::map<string, string>& variables) const;
-
-  const FieldDescriptor* descriptor_;
-  std::map<string, string> variables_;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer,
+                                        bool to_array) const;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldGenerator);
 };
@@ -74,6 +71,6 @@
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_MAP_FIELD_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 778fc40..e219d78 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -35,9 +35,9 @@
 #include <google/protobuf/compiler/cpp/cpp_message.h>
 
 #include <algorithm>
-#include <google/protobuf/stubs/hash.h>
 #include <map>
 #include <memory>
+#include <unordered_map>
 #include <utility>
 #include <vector>
 
@@ -57,6 +57,8 @@
 #include <google/protobuf/stubs/substitute.h>
 
 
+#include <google/protobuf/stubs/hash.h>
+
 
 namespace google {
 namespace protobuf {
@@ -69,7 +71,7 @@
 namespace {
 
 template <class T>
-void PrintFieldComment(io::Printer* printer, const T* field) {
+void PrintFieldComment(const Formatter& format, const T* field) {
   // Print the field's (or oneof's) proto-syntax definition as a comment.
   // We don't want to print group bodies so we cut off after the first
   // line.
@@ -77,8 +79,25 @@
   options.elide_group_body = true;
   options.elide_oneof_body = true;
   string def = field->DebugStringWithOptions(options);
-  printer->Print("// $def$\n",
-    "def", def.substr(0, def.find_first_of('\n')));
+  format("// $1$\n", def.substr(0, def.find_first_of('\n')));
+}
+
+void PrintPresenceCheck(const Formatter& format, const FieldDescriptor* field,
+                        const std::vector<int>& has_bit_indices,
+                        io::Printer* printer, int* cached_has_bit_index) {
+  if (!field->options().weak()) {
+    int has_bit_index = has_bit_indices[field->index()];
+    if (*cached_has_bit_index != (has_bit_index / 32)) {
+      *cached_has_bit_index = (has_bit_index / 32);
+      format("cached_has_bits = _has_bits_[$1$];\n", *cached_has_bit_index);
+    }
+    const string mask =
+        StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
+    format("if (cached_has_bits & 0x$1$u) {\n", mask);
+  } else {
+    format("if (has_$1$()) {\n", FieldName(field));
+  }
+  format.Indent();
 }
 
 struct FieldOrderingByNumber {
@@ -135,9 +154,9 @@
   // Non-repeated, non-lazy message fields are simply raw pointers, so we can
   // use memset to initialize these in SharedCtor.  We cannot use this in
   // Clear, as we need to potentially delete the existing value.
-  ret = ret ||
-      (!field->is_repeated() &&
-       field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE);
+  ret = ret || (!field->is_repeated() &&
+                !IsLazy(field, options) &&
+                field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE);
   return ret;
 }
 
@@ -145,36 +164,27 @@
 // considered non-default (will be sent over the wire), for message types
 // without true field presence. Should only be called if
 // !HasFieldPresence(message_descriptor).
-bool EmitFieldNonDefaultCondition(io::Printer* printer,
-                                  const string& prefix,
+bool EmitFieldNonDefaultCondition(io::Printer* printer, const string& prefix,
                                   const FieldDescriptor* field) {
+  Formatter format(printer);
+  format.Set("prefix", prefix);
+  format.Set("name", FieldName(field));
   // Merge and serialize semantics: primitive fields are merged/serialized only
   // if non-zero (numeric) or non-empty (string).
   if (!field->is_repeated() && !field->containing_oneof()) {
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
-      printer->Print(
-          "if ($prefix$$name$().size() > 0) {\n",
-          "prefix", prefix,
-          "name", FieldName(field));
+      format("if ($prefix$$name$().size() > 0) {\n");
     } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
       // Message fields still have has_$name$() methods.
-      printer->Print(
-          "if ($prefix$has_$name$()) {\n",
-          "prefix", prefix,
-          "name", FieldName(field));
+      format("if ($prefix$has_$name$()) {\n");
     } else {
-      printer->Print(
-          "if ($prefix$$name$() != 0) {\n",
-          "prefix", prefix,
-          "name", FieldName(field));
+      format("if ($prefix$$name$() != 0) {\n");
     }
-    printer->Indent();
+    format.Indent();
     return true;
   } else if (field->containing_oneof()) {
-    printer->Print(
-        "if (has_$name$()) {\n",
-        "name", FieldName(field));
-    printer->Indent();
+    format("if (has_$name$()) {\n");
+    format.Indent();
     return true;
   }
   return false;
@@ -192,13 +202,13 @@
 }
 
 // Collects map entry message type information.
-void CollectMapInfo(const Descriptor* descriptor,
+void CollectMapInfo(const Options& options, const Descriptor* descriptor,
                     std::map<string, string>* variables) {
   GOOGLE_CHECK(IsMapEntryMessage(descriptor));
   std::map<string, string>& vars = *variables;
   const FieldDescriptor* key = descriptor->FindFieldByName("key");
   const FieldDescriptor* val = descriptor->FindFieldByName("value");
-  vars["key_cpp"] = PrimitiveTypeName(key->cpp_type());
+  vars["key_cpp"] = PrimitiveTypeName(options, key->cpp_type());
   switch (val->cpp_type()) {
     case FieldDescriptor::CPPTYPE_MESSAGE:
       vars["val_cpp"] = FieldMessageTypeName(val);
@@ -207,12 +217,12 @@
       vars["val_cpp"] = ClassName(val->enum_type(), true);
       break;
     default:
-      vars["val_cpp"] = PrimitiveTypeName(val->cpp_type());
+      vars["val_cpp"] = PrimitiveTypeName(options, val->cpp_type());
   }
-  vars["key_wire_type"] = "::google::protobuf::internal::WireFormatLite::TYPE_" +
-                          ToUpper(DeclaredTypeMethodName(key->type()));
-  vars["val_wire_type"] = "::google::protobuf::internal::WireFormatLite::TYPE_" +
-                          ToUpper(DeclaredTypeMethodName(val->type()));
+  vars["key_wire_type"] =
+      "TYPE_" + ToUpper(DeclaredTypeMethodName(key->type()));
+  vars["val_wire_type"] =
+      "TYPE_" + ToUpper(DeclaredTypeMethodName(val->type()));
   if (descriptor->file()->syntax() != FileDescriptor::SYNTAX_PROTO3 &&
       val->type() == FieldDescriptor::TYPE_ENUM) {
     const EnumValueDescriptor* default_value = val->default_value_enum();
@@ -231,9 +241,51 @@
           field->containing_oneof() != NULL);
 }
 
+// TODO(ckennelly):  Cull these exclusions if/when these protos do not have
+// their methods overriden by subclasses.
 
-bool TableDrivenParsingEnabled(
-    const Descriptor* descriptor, const Options& options) {
+bool ShouldMarkClearAsFinal(const Descriptor* descriptor,
+                            const Options& options) {
+  static std::set<string> exclusions{
+  };
+
+  const string name = ClassName(descriptor, true);
+  return exclusions.find(name) == exclusions.end() ||
+         options.opensource_runtime;
+}
+
+bool ShouldMarkIsInitializedAsFinal(const Descriptor* descriptor,
+                                    const Options& options) {
+  static std::set<string> exclusions{
+  };
+
+  const string name = ClassName(descriptor, true);
+  return exclusions.find(name) == exclusions.end() ||
+         options.opensource_runtime;
+}
+
+bool ShouldMarkMergePartialAsFinal(const Descriptor* descriptor,
+                                   const Options& options) {
+  static std::set<string> exclusions{
+  };
+
+  const string name = ClassName(descriptor, true);
+  return exclusions.find(name) == exclusions.end() ||
+         options.opensource_runtime;
+}
+
+bool ShouldMarkNewAsFinal(const Descriptor* descriptor,
+                          const Options& options) {
+  static std::set<string> exclusions{
+  };
+
+  const string name = ClassName(descriptor, true);
+  return exclusions.find(name) == exclusions.end() ||
+         options.opensource_runtime;
+}
+
+bool TableDrivenParsingEnabled(const Descriptor* descriptor,
+                               const Options& options) {
   if (!options.table_driven_parsing) {
     return false;
   }
@@ -247,14 +299,18 @@
 
   const double table_sparseness = 0.5;
   int max_field_number = 0;
-  for (int i = 0; i < descriptor->field_count(); i++) {
-    const FieldDescriptor* field = descriptor->field(i);
+  for (auto field : FieldRange(descriptor)) {
     if (max_field_number < field->number()) {
       max_field_number = field->number();
     }
 
     // - There are no weak fields.
-    if (field->options().weak()) {
+    if (IsWeak(field, options)) {
+      return false;
+    }
+
+    // - There are no lazy fields (they require the non-lite library).
+    if (IsLazy(field, options)) {
       return false;
     }
   }
@@ -282,24 +338,16 @@
 void SetUnknkownFieldsVariable(const Descriptor* descriptor,
                                const Options& options,
                                std::map<string, string>* variables) {
+  string proto_ns = ProtobufNamespace(options);
   if (UseUnknownFieldSet(descriptor->file(), options)) {
-    (*variables)["unknown_fields_type"] = "::google::protobuf::UnknownFieldSet";
+    (*variables)["unknown_fields_type"] = "::" + proto_ns + "::UnknownFieldSet";
   } else {
-    (*variables)["unknown_fields_type"] = "::std::string";
+    (*variables)["unknown_fields_type"] =
+        PrimitiveTypeName(options, FieldDescriptor::CPPTYPE_STRING);
   }
-  if (AlwaysPreserveUnknownFields(descriptor)) {
-    (*variables)["have_unknown_fields"] =
-        "_internal_metadata_.have_unknown_fields()";
-    (*variables)["unknown_fields"] = "_internal_metadata_.unknown_fields()";
-  } else {
-    (*variables)["have_unknown_fields"] =
-        "(_internal_metadata_.have_unknown_fields() && "
-        " ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())";
-    (*variables)["unknown_fields"] =
-        "(::google::protobuf::internal::GetProto3PreserveUnknownsDefault()"
-        "   ? _internal_metadata_.unknown_fields()"
-        "   : _internal_metadata_.default_instance())";
-  }
+  (*variables)["have_unknown_fields"] =
+      "_internal_metadata_.have_unknown_fields()";
+  (*variables)["unknown_fields"] = "_internal_metadata_.unknown_fields()";
   (*variables)["mutable_unknown_fields"] =
       "_internal_metadata_.mutable_unknown_fields()";
 }
@@ -393,13 +441,13 @@
 
   const FieldDescriptor* last_field = fields.front();
   std::vector<const FieldDescriptor*> chunk;
-  for (int i = 0; i < fields.size(); i++) {
-    if (!equivalent(last_field, fields[i]) && !chunk.empty()) {
+  for (auto field : fields) {
+    if (!equivalent(last_field, field) && !chunk.empty()) {
       chunks.push_back(chunk);
       chunk.clear();
     }
-    chunk.push_back(fields[i]);
-    last_field = fields[i];
+    chunk.push_back(field);
+    last_field = field;
   }
   if (!chunk.empty()) {
     chunks.push_back(chunk);
@@ -415,8 +463,7 @@
   GOOGLE_CHECK(!fields.empty());
   int first_index_offset = has_bit_indices[fields.front()->index()] / 32;
   uint32 chunk_mask = 0;
-  for (int i = 0; i < fields.size(); i++) {
-    const FieldDescriptor* field = fields[i];
+  for (auto field : fields) {
     // "index" defines where in the _has_bits_ the field appears.
     int index = has_bit_indices[field->index()];
     GOOGLE_CHECK_EQ(first_index_offset, index / 32);
@@ -426,32 +473,161 @@
   return chunk_mask;
 }
 
+// Return the number of bits set in n, a non-negative integer.
+static int popcnt(uint32 n) {
+  int result = 0;
+  while (n != 0) {
+    result += (n & 1);
+    n = n / 2;
+  }
+  return result;
+}
+
+// For a run of cold chunks, opens and closes an external if statement that
+// checks multiple has_bits words to skip bulk of cold fields.
+class ColdChunkSkipper {
+ public:
+  ColdChunkSkipper(
+      const Options& options,
+      const std::vector<std::vector<const FieldDescriptor*>>& chunks,
+      const std::vector<int>& has_bit_indices, const double cold_threshold,
+      bool has_field_presence)
+      : chunks_(chunks),
+        has_bit_indices_(has_bit_indices),
+        access_info_map_(options.access_info_map),
+        cold_threshold_(cold_threshold),
+        has_field_presence_(has_field_presence) {
+    SetCommonVars(options, &variables_);
+  }
+
+  // May open an external if check for a batch of cold fields. "from" is the
+  // prefix to _has_bits_ to allow MergeFrom to use "from._has_bits_".
+  // Otherwise, it should be "".
+  void OnStartChunk(int chunk, int cached_has_bit_index, const string& from,
+                    io::Printer* printer);
+  bool OnEndChunk(int chunk, io::Printer* printer);
+
+ private:
+  bool IsColdChunk(int chunk);
+
+  int HasbitWord(int chunk, int offset) {
+    return has_bit_indices_[chunks_[chunk][offset]->index()] / 32;
+  }
+
+  const std::vector<std::vector<const FieldDescriptor*> >& chunks_;
+  const std::vector<int>& has_bit_indices_;
+  const AccessInfoMap* access_info_map_;
+  const double cold_threshold_;
+  std::map<string, string> variables_;
+  int limit_chunk_ = -1;
+  bool has_field_presence_;
+};
+
+// Tuning parameters for ColdChunkSkipper.
+const double kColdRatio = 0.005;
+
+bool ColdChunkSkipper::IsColdChunk(int chunk) { return false; }
+
+void ColdChunkSkipper::OnStartChunk(int chunk, int cached_has_bit_index,
+                                    const string& from, io::Printer* printer) {
+  Formatter format(printer, variables_);
+  if (!access_info_map_ || !has_field_presence_) {
+    return;
+  } else if (chunk < limit_chunk_) {
+    // We are already inside a run of cold chunks.
+    return;
+  } else if (!IsColdChunk(chunk)) {
+    // We can't start a run of cold chunks.
+    return;
+  }
+
+  // Find the end of consecutive cold chunks.
+  limit_chunk_ = chunk;
+  while (limit_chunk_ < chunks_.size() && IsColdChunk(limit_chunk_)) {
+    limit_chunk_++;
+  }
+
+  if (limit_chunk_ <= chunk + 1) {
+    // Require at least two chunks to emit external has_bit checks.
+    limit_chunk_ = -1;
+    return;
+  }
+
+  // Emit has_bit check for each has_bit_dword index.
+  format("if ($GOOGLE_PROTOBUF$_PREDICT_FALSE(");
+  int first_word = HasbitWord(chunk, 0);
+  while (chunk < limit_chunk_) {
+    uint32 mask = 0;
+    int this_word = HasbitWord(chunk, 0);
+    // Generate mask for chunks on the same word.
+    for (; chunk < limit_chunk_ && HasbitWord(chunk, 0) == this_word; chunk++) {
+      for (auto field : chunks_[chunk]) {
+        int hasbit_index = has_bit_indices_[field->index()];
+        // Fields on a chunk must be in the same word.
+        GOOGLE_CHECK_EQ(this_word, hasbit_index / 32);
+        mask |= 1 << (hasbit_index % 32);
+      }
+    }
+
+    if (this_word != first_word) {
+      format(" ||\n    ");
+    }
+    format.Set("mask", strings::Hex(mask, strings::ZERO_PAD_8));
+    if (this_word == cached_has_bit_index) {
+      format("(cached_has_bits & 0x$mask$u) != 0");
+    } else {
+      format("($1$_has_bits_[$2$] & 0x$mask$u) != 0", from, this_word);
+    }
+  }
+  format(")) {\n");
+  format.Indent();
+}
+
+bool ColdChunkSkipper::OnEndChunk(int chunk, io::Printer* printer) {
+  Formatter format(printer, variables_);
+  if (chunk != limit_chunk_ - 1) {
+    return false;
+  }
+  format.Outdent();
+  format("}\n");
+  return true;
+}
+
 }  // anonymous namespace
 
 // ===================================================================
 
 MessageGenerator::MessageGenerator(const Descriptor* descriptor,
+                                   const std::map<string, string>& vars,
                                    int index_in_file_messages,
                                    const Options& options,
-                                   SCCAnalyzer* scc_analyzer)
+                                   MessageSCCAnalyzer* scc_analyzer)
     : descriptor_(descriptor),
       index_in_file_messages_(index_in_file_messages),
       classname_(ClassName(descriptor, false)),
       options_(options),
       field_generators_(descriptor, options, scc_analyzer),
       max_has_bit_index_(0),
-      enum_generators_(
-          new std::unique_ptr<EnumGenerator>[descriptor->enum_type_count()]),
-      extension_generators_(new std::unique_ptr<
-                            ExtensionGenerator>[descriptor->extension_count()]),
       num_weak_fields_(0),
-      message_layout_helper_(new PaddingOptimizer()),
-      scc_analyzer_(scc_analyzer) {
+      scc_analyzer_(scc_analyzer),
+      variables_(vars) {
+  if (!message_layout_helper_) {
+    message_layout_helper_.reset(new PaddingOptimizer());
+  }
+
+  // Variables that apply to this class
+  variables_["classname"] = classname_;
+  variables_["classtype"] = QualifiedClassName(descriptor_);
+  string scc_name =
+      ClassName(scc_analyzer_->GetSCC(descriptor_)->GetRepresentative());
+  variables_["scc_name"] = UniqueName(scc_name, descriptor_, options_);
+  variables_["full_name"] = descriptor_->full_name();
+  variables_["superclass"] = SuperClassName(descriptor_, options_);
+
   // Compute optimized field order to be used for layout and initialization
   // purposes.
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* field = descriptor_->field(i);
-    if (field->options().weak()) {
+  for (auto field : FieldRange(descriptor_)) {
+    if (IsWeak(field, options_)) {
       num_weak_fields_++;
     } else if (!field->containing_oneof()) {
       optimized_order_.push_back(field);
@@ -463,8 +639,7 @@
   if (HasFieldPresence(descriptor_->file())) {
     // We use -1 as a sentinel.
     has_bit_indices_.resize(descriptor_->field_count(), -1);
-    for (int i = 0; i < optimized_order_.size(); i++) {
-      const FieldDescriptor* field = optimized_order_[i];
+    for (auto field : optimized_order_) {
       // Skip fields that do not have has bits.
       if (field->is_repeated()) {
         continue;
@@ -472,16 +647,7 @@
 
       has_bit_indices_[field->index()] = max_has_bit_index_++;
     }
-  }
-
-  for (int i = 0; i < descriptor->enum_type_count(); i++) {
-    enum_generators_[i].reset(
-      new EnumGenerator(descriptor->enum_type(i), options));
-  }
-
-  for (int i = 0; i < descriptor->extension_count(); i++) {
-    extension_generators_[i].reset(
-      new ExtensionGenerator(descriptor->extension(i), options));
+    field_generators_.SetHasBitIndices(has_bit_indices_);
   }
 
   num_required_fields_ = 0;
@@ -492,12 +658,9 @@
   }
 
   table_driven_ = TableDrivenParsingEnabled(descriptor_, options_);
-
-  scc_name_ =
-      ClassName(scc_analyzer_->GetSCC(descriptor_)->GetRepresentative(), false);
 }
 
-MessageGenerator::~MessageGenerator() {}
+MessageGenerator::~MessageGenerator() = default;
 
 size_t MessageGenerator::HasBitsSize() const {
   size_t sizeof_has_bits = (max_has_bit_index_ + 31) / 32 * 4;
@@ -513,23 +676,22 @@
 }
 
 void MessageGenerator::AddGenerators(
-    std::vector<EnumGenerator*>* enum_generators,
-    std::vector<ExtensionGenerator*>* extension_generators) {
+    std::vector<std::unique_ptr<EnumGenerator>>* enum_generators,
+    std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators) {
   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
-    enum_generators->push_back(enum_generators_[i].get());
+    enum_generators->emplace_back(
+        new EnumGenerator(descriptor_->enum_type(i), variables_, options_));
+    enum_generators_.push_back(enum_generators->back().get());
   }
   for (int i = 0; i < descriptor_->extension_count(); i++) {
-    extension_generators->push_back(extension_generators_[i].get());
+    extension_generators->emplace_back(
+        new ExtensionGenerator(descriptor_->extension(i), options_));
+    extension_generators_.push_back(extension_generators->back().get());
   }
 }
 
-void MessageGenerator::FillMessageForwardDeclarations(
-    std::map<string, const Descriptor*>* class_names) {
-  (*class_names)[classname_] = descriptor_;
-}
-
-void MessageGenerator::
-GenerateFieldAccessorDeclarations(io::Printer* printer) {
+void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) {
+  Formatter format(printer, variables_);
   // optimized_fields_ does not contain fields where
   //    field->containing_oneof() != NULL
   // so we need to iterate over those as well.
@@ -540,77 +702,75 @@
   std::vector<const FieldDescriptor*> ordered_fields;
   ordered_fields.reserve(descriptor_->field_count());
 
-  ordered_fields.insert(
-      ordered_fields.begin(), optimized_order_.begin(), optimized_order_.end());
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* field = descriptor_->field(i);
+  ordered_fields.insert(ordered_fields.begin(), optimized_order_.begin(),
+                        optimized_order_.end());
+  for (auto field : FieldRange(descriptor_)) {
     if (field->containing_oneof() == NULL && !field->options().weak()) {
       continue;
     }
     ordered_fields.push_back(field);
   }
 
-  for (int i = 0; i < ordered_fields.size(); i++) {
-    const FieldDescriptor* field = ordered_fields[i];
+  for (auto field : ordered_fields) {
+    PrintFieldComment(format, field);
 
-    PrintFieldComment(printer, field);
+    Formatter::SaveState save(&format);
 
     std::map<string, string> vars;
     SetCommonFieldVariables(field, &vars, options_);
-    vars["constant_name"] = FieldConstantName(field);
+    format.AddMap(vars);
 
     if (field->is_repeated()) {
-      printer->Print(vars, "$deprecated_attr$int ${$$name$_size$}$() const;\n");
-      printer->Annotate("{", "}", field);
+      format("$deprecated_attr$int ${1$$name$_size$}$() const;\n", field);
     } else if (HasHasMethod(field)) {
-      printer->Print(vars, "$deprecated_attr$bool ${$has_$name$$}$() const;\n");
-      printer->Annotate("{", "}", field);
+      format("$deprecated_attr$bool ${1$has_$name$$}$() const;\n", field);
     } else if (HasPrivateHasMethod(field)) {
-      printer->Print(vars,
-                     "private:\n"
-                     "bool ${$has_$name$$}$() const;\n"
-                     "public:\n");
-      printer->Annotate("{", "}", field);
+      format(
+          "private:\n"
+          "bool ${1$has_$name$$}$() const;\n"
+          "public:\n",
+          field);
     }
 
-    printer->Print(vars, "$deprecated_attr$void ${$clear_$name$$}$();\n");
-    printer->Annotate("{", "}", field);
-    printer->Print(vars,
-                   "$deprecated_attr$static const int $constant_name$ = "
-                   "$number$;\n");
-    printer->Annotate("constant_name", field);
+    format(
+        "$deprecated_attr$void ${1$clear_$name$$}$();\n"
+        "$deprecated_attr$static const int ${1$$2$$}$ = $number$;\n",
+        field, FieldConstantName(field));
 
     // Generate type-specific accessor declarations.
     field_generators_.get(field).GenerateAccessorDeclarations(printer);
 
-    printer->Print("\n");
+    format("\n");
   }
 
   if (descriptor_->extension_range_count() > 0) {
     // Generate accessors for extensions.  We just call a macro located in
     // extension_set.h since the accessors about 80 lines of static code.
-    printer->Print(
-      "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
-      "classname", classname_);
+    format("$GOOGLE_PROTOBUF$_EXTENSION_ACCESSORS($classname$)\n");
+    // Generate MessageSet specific APIs for proto2 MessageSet.
+    // For testing purposes we don't check for bridge.MessageSet, so
+    // we don't use IsProto2MessageSet
+    if (descriptor_->options().message_set_wire_format() &&
+        !options_.opensource_runtime && !options_.lite_implicit_weak_fields) {
+      // Special-case MessageSet
+      format("GOOGLE_PROTOBUF_EXTENSION_MESSAGE_SET_ACCESSORS($classname$)\n");
+    }
   }
 
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    printer->Print(
+  for (auto oneof : OneOfRange(descriptor_)) {
+    Formatter::SaveState saver(&format);
+    format.Set("oneof_name", oneof->name());
+    format.Set("camel_oneof_name", UnderscoresToCamelCase(oneof->name(), true));
+    format(
         "void clear_$oneof_name$();\n"
-        "$camel_oneof_name$Case $oneof_name$_case() const;\n",
-        "camel_oneof_name",
-        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true),
-        "oneof_name", descriptor_->oneof_decl(i)->name());
+        "$camel_oneof_name$Case $oneof_name$_case() const;\n");
   }
 }
 
-void MessageGenerator::
-GenerateSingularFieldHasBits(const FieldDescriptor* field,
-                             std::map<string, string> vars,
-                             io::Printer* printer) {
+void MessageGenerator::GenerateSingularFieldHasBits(
+    const FieldDescriptor* field, Formatter format) {
   if (field->options().weak()) {
-    printer->Print(
-        vars,
+    format(
         "inline bool $classname$::has_$name$() const {\n"
         "  return _weak_field_map_.Has($number$);\n"
         "}\n");
@@ -622,31 +782,23 @@
     int has_bit_index = has_bit_indices_[field->index()];
     GOOGLE_CHECK_GE(has_bit_index, 0);
 
-    vars["has_array_index"] = SimpleItoa(has_bit_index / 32);
-    vars["has_mask"] = StrCat(strings::Hex(1u << (has_bit_index % 32),
-                                           strings::ZERO_PAD_8));
-    printer->Print(vars,
-      "inline bool $classname$::has_$name$() const {\n"
-      "  return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
-      "}\n"
-      "inline void $classname$::set_has_$name$() {\n"
-      "  _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n"
-      "}\n"
-      "inline void $classname$::clear_has_$name$() {\n"
-      "  _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"
-      "}\n");
+    format.Set("has_array_index", has_bit_index / 32);
+    format.Set("has_mask",
+               strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
+    format(
+        "inline bool $classname$::has_$name$() const {\n"
+        "  return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
+        "}\n");
   } else {
     // Message fields have a has_$name$() method.
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
-      bool is_lazy = false;
-      if (is_lazy) {
-        printer->Print(vars,
-          "inline bool $classname$::has_$name$() const {\n"
-          "  return !$name$_.IsCleared();\n"
-          "}\n");
+      if (IsLazy(field, options_)) {
+        format(
+            "inline bool $classname$::has_$name$() const {\n"
+            "  return !$name$_.IsCleared();\n"
+            "}\n");
       } else {
-        printer->Print(
-            vars,
+        format(
             "inline bool $classname$::has_$name$() const {\n"
             "  return this != internal_default_instance() && $name$_ != NULL;\n"
             "}\n");
@@ -655,17 +807,13 @@
   }
 }
 
-void MessageGenerator::
-GenerateOneofHasBits(io::Printer* printer) {
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    std::map<string, string> vars;
-    vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
-    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
-    vars["cap_oneof_name"] =
-        ToUpper(descriptor_->oneof_decl(i)->name());
-    vars["classname"] = classname_;
-    printer->Print(
-        vars,
+void MessageGenerator::GenerateOneofHasBits(io::Printer* printer) {
+  Formatter format(printer, variables_);
+  for (auto oneof : OneOfRange(descriptor_)) {
+    format.Set("oneof_name", oneof->name());
+    format.Set("oneof_index", oneof->index());
+    format.Set("cap_oneof_name", ToUpper(oneof->name()));
+    format(
         "inline bool $classname$::has_$oneof_name$() const {\n"
         "  return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
         "}\n"
@@ -675,168 +823,157 @@
   }
 }
 
-void MessageGenerator::
-GenerateOneofMemberHasBits(const FieldDescriptor* field,
-                           const std::map<string, string>& vars,
-                           io::Printer* printer) {
+void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field,
+                                                  const Formatter& format) {
   // Singular field in a oneof
   // N.B.: Without field presence, we do not use has-bits or generate
   // has_$name$() methods, but oneofs still have set_has_$name$().
   // Oneofs also have has_$name$() but only as a private helper
   // method, so that generated code is slightly cleaner (vs.  comparing
   // _oneof_case_[index] against a constant everywhere).
-  printer->Print(vars,
-    "inline bool $classname$::has_$name$() const {\n"
-    "  return $oneof_name$_case() == k$field_name$;\n"
-    "}\n");
-  printer->Print(vars,
-    "inline void $classname$::set_has_$name$() {\n"
-    "  _oneof_case_[$oneof_index$] = k$field_name$;\n"
-    "}\n");
+  format(
+      "inline bool $classname$::has_$name$() const {\n"
+      "  return $oneof_name$_case() == k$field_name$;\n"
+      "}\n"
+      "inline void $classname$::set_has_$name$() {\n"
+      "  _oneof_case_[$oneof_index$] = k$field_name$;\n"
+      "}\n");
 }
 
-void MessageGenerator::
-GenerateFieldClear(const FieldDescriptor* field,
-                   const std::map<string, string>& vars,
-                   bool is_inline,
-                   io::Printer* printer) {
+void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field,
+                                          bool is_inline,
+                                          Formatter format) {
   // Generate clear_$name$().
   if (is_inline) {
-    printer->Print("inline ");
+    format("inline ");
   }
-  printer->Print(vars,
-    "void $classname$::clear_$name$() {\n");
+  format("void $classname$::clear_$name$() {\n");
 
-  printer->Indent();
+  format.Indent();
 
   if (field->containing_oneof()) {
     // Clear this field only if it is the active field in this oneof,
     // otherwise ignore
-    printer->Print(vars,
-      "if (has_$name$()) {\n");
-    printer->Indent();
-    field_generators_.get(field)
-        .GenerateClearingCode(printer);
-    printer->Print(vars,
-      "clear_has_$oneof_name$();\n");
-    printer->Outdent();
-    printer->Print("}\n");
+    format("if (has_$name$()) {\n");
+    format.Indent();
+    field_generators_.get(field).GenerateClearingCode(format.printer());
+    format("clear_has_$oneof_name$();\n");
+    format.Outdent();
+    format("}\n");
   } else {
-    field_generators_.get(field)
-        .GenerateClearingCode(printer);
+    field_generators_.get(field).GenerateClearingCode(format.printer());
     if (HasFieldPresence(descriptor_->file())) {
       if (!field->is_repeated() && !field->options().weak()) {
-        printer->Print(vars, "clear_has_$name$();\n");
+        int has_bit_index = has_bit_indices_[field->index()];
+        GOOGLE_CHECK_GE(has_bit_index, 0);
+
+        format.Set("has_array_index", has_bit_index / 32);
+        format.Set("has_mask",
+                   strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
+        format("_has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n");
       }
     }
   }
 
-  printer->Outdent();
-  printer->Print("}\n");
+  format.Outdent();
+  format("}\n");
 }
 
-void MessageGenerator::
-GenerateFieldAccessorDefinitions(io::Printer* printer) {
-  printer->Print("// $classname$\n\n", "classname", classname_);
+void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) {
+  Formatter format(printer, variables_);
+  format("// $classname$\n\n");
 
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* field = descriptor_->field(i);
-
-    PrintFieldComment(printer, field);
+  for (auto field : FieldRange(descriptor_)) {
+    PrintFieldComment(format, field);
 
     std::map<string, string> vars;
     SetCommonFieldVariables(field, &vars, options_);
 
+    Formatter::SaveState saver(&format);
+    format.AddMap(vars);
+
     // Generate has_$name$() or $name$_size().
     if (field->is_repeated()) {
-      printer->Print(vars,
-        "inline int $classname$::$name$_size() const {\n"
-        "  return $name$_.size();\n"
-        "}\n");
+      format(
+          "inline int $classname$::$name$_size() const {\n"
+          "  return $name$_.size();\n"
+          "}\n");
     } else if (field->containing_oneof()) {
-      vars["field_name"] = UnderscoresToCamelCase(field->name(), true);
-      vars["oneof_name"] = field->containing_oneof()->name();
-      vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index());
-      GenerateOneofMemberHasBits(field, vars, printer);
+      format.Set("field_name", UnderscoresToCamelCase(field->name(), true));
+      format.Set("oneof_name", field->containing_oneof()->name());
+      format.Set("oneof_index",
+                 SimpleItoa(field->containing_oneof()->index()));
+      GenerateOneofMemberHasBits(field, format);
     } else {
       // Singular field.
-      GenerateSingularFieldHasBits(field, vars, printer);
+      GenerateSingularFieldHasBits(field, format);
     }
 
     if (!IsCrossFileMaybeMap(field)) {
-      GenerateFieldClear(field, vars, true, printer);
+      GenerateFieldClear(field, true, format);
     }
 
     // Generate type-specific accessors.
     field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
 
-    printer->Print("\n");
+    format("\n");
   }
 
   // Generate has_$name$() and clear_has_$name$() functions for oneofs.
   GenerateOneofHasBits(printer);
 }
 
-void MessageGenerator::
-GenerateClassDefinition(io::Printer* printer) {
+void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
+  Formatter format(printer, variables_);
   if (IsMapEntryMessage(descriptor_)) {
     std::map<string, string> vars;
-    vars["classname"] = classname_;
-    CollectMapInfo(descriptor_, &vars);
+    CollectMapInfo(options_, descriptor_, &vars);
     vars["lite"] =
         HasDescriptorMethods(descriptor_->file(), options_) ? "" : "Lite";
-    printer->Print(
-        vars,
+    format.AddMap(vars);
+    format(
         "class $classname$ : public "
-        "::google::protobuf::internal::MapEntry$lite$<$classname$, \n"
+        "::$proto_ns$::internal::MapEntry$lite$<$classname$, \n"
         "    $key_cpp$, $val_cpp$,\n"
-        "    $key_wire_type$,\n"
-        "    $val_wire_type$,\n"
+        "    ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
+        "    ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
         "    $default_enum_value$ > {\n"
         "public:\n"
-        "  typedef ::google::protobuf::internal::MapEntry$lite$<$classname$, \n"
+        "#if $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
+        "  static const char* _InternalParse(const char* begin, const char* "
+        "end, void* object, ::$proto_ns$::internal::ParseContext* ctx);\n"
+        "#endif  // $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
+        "  typedef ::$proto_ns$::internal::MapEntry$lite$<$classname$, \n"
         "    $key_cpp$, $val_cpp$,\n"
-        "    $key_wire_type$,\n"
-        "    $val_wire_type$,\n"
+        "    ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
+        "    ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
         "    $default_enum_value$ > SuperType;\n"
         "  $classname$();\n"
-        "  $classname$(::google::protobuf::Arena* arena);\n"
+        "  $classname$(::$proto_ns$::Arena* arena);\n"
         "  void MergeFrom(const $classname$& other);\n"
         "  static const $classname$* internal_default_instance() { return "
         "reinterpret_cast<const "
         "$classname$*>(&_$classname$_default_instance_); }\n");
     if (HasDescriptorMethods(descriptor_->file(), options_)) {
-      printer->Print(
-          "  void MergeFrom(const ::google::protobuf::Message& other) final;\n"
-          "  ::google::protobuf::Metadata GetMetadata() const;\n"
+      format(
+          "  void MergeFrom(const ::$proto_ns$::Message& other) final;\n"
+          "  ::$proto_ns$::Metadata GetMetadata() const;\n"
           "};\n");
     } else {
-      printer->Print("};\n");
+      format("};\n");
     }
     return;
   }
 
-  std::map<string, string> vars;
-  vars["classname"] = classname_;
-  vars["full_name"] = descriptor_->full_name();
-  vars["field_count"] = SimpleItoa(descriptor_->field_count());
-  vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count());
-  if (options_.dllexport_decl.empty()) {
-    vars["dllexport"] = "";
-  } else {
-    vars["dllexport"] = options_.dllexport_decl + " ";
-  }
-  vars["superclass"] = SuperClassName(descriptor_, options_);
-  printer->Print(vars,
-    "class $dllexport$$classname$ : public $superclass$ "
-    "/* @@protoc_insertion_point(class_definition:$full_name$) */ "
-    "{\n");
-  printer->Annotate("classname", descriptor_);
-  printer->Print(" public:\n");
-  printer->Indent();
+  format(
+      "class $dllexport_decl $${1$$classname$$}$ : public $superclass$ "
+      "/* @@protoc_insertion_point(class_definition:$full_name$) */ "
+      "{\n",
+      descriptor_);
+  format(" public:\n");
+  format.Indent();
 
-  printer->Print(
-      vars,
+  format(
       "$classname$();\n"
       "virtual ~$classname$();\n"
       "\n"
@@ -848,34 +985,36 @@
       "}\n");
 
   if (options_.table_driven_serialization) {
-    printer->Print(
-      "private:\n"
-      "const void* InternalGetTable() const;\n"
-      "public:\n"
-      "\n");
+    format(
+        "private:\n"
+        "const void* InternalGetTable() const;\n"
+        "public:\n"
+        "\n");
   }
 
   // Generate move constructor and move assignment operator.
-  printer->Print(vars,
-    "#if LANG_CXX11\n"
-    "$classname$($classname$&& from) noexcept\n"
-    "  : $classname$() {\n"
-    "  *this = ::std::move(from);\n"
-    "}\n"
-    "\n"
-    "inline $classname$& operator=($classname$&& from) noexcept {\n"
-    "  if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {\n"
-    "    if (this != &from) InternalSwap(&from);\n"
-    "  } else {\n"
-    "    CopyFrom(from);\n"
-    "  }\n"
-    "  return *this;\n"
-    "}\n"
-    "#endif\n");
+  format(
+      "#if LANG_CXX11\n"
+      "$classname$($classname$&& from) noexcept\n"
+      "  : $classname$() {\n"
+      "  *this = ::std::move(from);\n"
+      "}\n"
+      "\n"
+      "inline $classname$& operator=($classname$&& from) noexcept {\n"
+      "  if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {\n"
+      "    if (this != &from) InternalSwap(&from);\n"
+      "  } else {\n"
+      "    CopyFrom(from);\n"
+      "  }\n"
+      "  return *this;\n"
+      "}\n"
+      "#endif\n");
 
+  std::map<string, string> vars;
   SetUnknkownFieldsVariable(descriptor_, options_, &vars);
+  format.AddMap(vars);
   if (PublicUnknownFieldsAccessors(descriptor_)) {
-    printer->Print(vars,
+    format(
         "inline const $unknown_fields_type$& unknown_fields() const {\n"
         "  return $unknown_fields$;\n"
         "}\n"
@@ -889,10 +1028,10 @@
   // MessageLite's implementation which returns NULL rather than generating our
   // own method which returns NULL, in order to reduce code size.
   if (SupportsArenas(descriptor_)) {
-    // virtual method version of GetArenaNoVirtual(), required for generic dispatch given a
-    // MessageLite* (e.g., in RepeatedField::AddAllocated()).
-    printer->Print(
-        "inline ::google::protobuf::Arena* GetArena() const final {\n"
+    // virtual method version of GetArenaNoVirtual(), required for generic
+    // dispatch given a MessageLite* (e.g., in RepeatedField::AddAllocated()).
+    format(
+        "inline ::$proto_ns$::Arena* GetArena() const final {\n"
         "  return GetArenaNoVirtual();\n"
         "}\n"
         "inline void* GetMaybeArenaPointer() const final {\n"
@@ -903,229 +1042,240 @@
   // Only generate this member if it's not disabled.
   if (HasDescriptorMethods(descriptor_->file(), options_) &&
       !descriptor_->options().no_standard_descriptor_accessor()) {
-    printer->Print(vars,
-      "static const ::google::protobuf::Descriptor* descriptor();\n");
+    format(
+        "static const ::$proto_ns$::Descriptor* descriptor() {\n"
+        "  return default_instance().GetDescriptor();\n"
+        "}\n");
   }
 
-  printer->Print(vars,
-    "static const $classname$& default_instance();\n"
-    "\n");
+  format(
+      "static const $classname$& default_instance();\n"
+      "\n");
 
   // Generate enum values for every field in oneofs. One list is generated for
   // each oneof with an additional *_NOT_SET value.
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    printer->Print(
-        "enum $camel_oneof_name$Case {\n",
-        "camel_oneof_name",
-        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
-    printer->Indent();
-    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
-      printer->Print(
-          "k$field_name$ = $field_number$,\n",
-          "field_name",
-          UnderscoresToCamelCase(
-              descriptor_->oneof_decl(i)->field(j)->name(), true),
-          "field_number",
-          SimpleItoa(descriptor_->oneof_decl(i)->field(j)->number()));
+  for (auto oneof : OneOfRange(descriptor_)) {
+    format("enum $1$Case {\n", UnderscoresToCamelCase(oneof->name(), true));
+    format.Indent();
+    for (auto field : FieldRange(oneof)) {
+      string oneof_enum_case_field_name =
+          UnderscoresToCamelCase(field->name(), true);
+      format("k$1$ = $2$,\n", oneof_enum_case_field_name,  // 1
+             field->number());                             // 2
     }
-    printer->Print(
-        "$cap_oneof_name$_NOT_SET = 0,\n",
-        "cap_oneof_name",
-        ToUpper(descriptor_->oneof_decl(i)->name()));
-    printer->Outdent();
-    printer->Print(
+    format("$1$_NOT_SET = 0,\n", ToUpper(oneof->name()));
+    format.Outdent();
+    format(
         "};\n"
         "\n");
   }
 
   // TODO(gerbens) make this private, while still granting other protos access.
-  vars["message_index"] = SimpleItoa(index_in_file_messages_);
-  printer->Print(
-      vars,
+  format(
       "static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY\n"
       "static inline const $classname$* internal_default_instance() {\n"
       "  return reinterpret_cast<const $classname$*>(\n"
       "             &_$classname$_default_instance_);\n"
       "}\n"
       "static constexpr int kIndexInFileMessages =\n"
-      "  $message_index$;\n"
-      "\n");
+      "  $1$;\n"
+      "\n", index_in_file_messages_);
 
   if (SupportsArenas(descriptor_)) {
-    printer->Print(vars,
-      "void UnsafeArenaSwap($classname$* other);\n");
+    format("void UnsafeArenaSwap($classname$* other);\n");
   }
 
   if (IsAnyMessage(descriptor_)) {
-    printer->Print(vars,
-      "// implements Any -----------------------------------------------\n"
-      "\n"
-      "void PackFrom(const ::google::protobuf::Message& message);\n"
-      "void PackFrom(const ::google::protobuf::Message& message,\n"
-      "              const ::std::string& type_url_prefix);\n"
-      "bool UnpackTo(::google::protobuf::Message* message) const;\n"
-      "template<typename T> bool Is() const {\n"
-      "  return _any_metadata_.Is<T>();\n"
-      "}\n"
-      "static bool ParseAnyTypeUrl(const string& type_url,\n"
-      "                            string* full_type_name);\n"
-      "\n");
+    format(
+        "// implements Any -----------------------------------------------\n"
+        "\n"
+        "void PackFrom(const ::$proto_ns$::Message& message);\n"
+        "void PackFrom(const ::$proto_ns$::Message& message,\n"
+        "              const $string$& type_url_prefix);\n"
+        "bool UnpackTo(::$proto_ns$::Message* message) const;\n"
+        "template<typename T> bool Is() const {\n"
+        "  return _any_metadata_.Is<T>();\n"
+        "}\n"
+        "static bool ParseAnyTypeUrl(const string& type_url,\n"
+        "                            string* full_type_name);\n"
+        "static bool GetAnyFieldDescriptors(\n"
+        "    const ::$proto_ns$::Message& message,\n"
+        "    const ::$proto_ns$::FieldDescriptor** type_url_field,\n"
+        "    const ::$proto_ns$::FieldDescriptor** value_field);\n");
   }
 
-  vars["new_final"] = " final";
+  format.Set("new_final",
+             ShouldMarkNewAsFinal(descriptor_, options_) ? "final" : "");
 
-  printer->Print(vars,
-    "void Swap($classname$* other);\n"
-    "friend void swap($classname$& a, $classname$& b) {\n"
-    "  a.Swap(&b);\n"
-    "}\n"
-    "\n"
-    "// implements Message ----------------------------------------------\n"
-    "\n"
-    "inline $classname$* New() const$new_final$ {\n"
-    "  return CreateMaybeMessage<$classname$>(NULL);\n"
-    "}\n"
-    "\n"
-    "$classname$* New(::google::protobuf::Arena* arena) const$new_final$ {\n"
-    "  return CreateMaybeMessage<$classname$>(arena);\n"
-    "}\n");
+  format(
+      "void Swap($classname$* other);\n"
+      "friend void swap($classname$& a, $classname$& b) {\n"
+      "  a.Swap(&b);\n"
+      "}\n"
+      "\n"
+      "// implements Message ----------------------------------------------\n"
+      "\n"
+      "inline $classname$* New() const$ new_final$ {\n"
+      "  return CreateMaybeMessage<$classname$>(NULL);\n"
+      "}\n"
+      "\n"
+      "$classname$* New(::$proto_ns$::Arena* arena) const$ new_final$ {\n"
+      "  return CreateMaybeMessage<$classname$>(arena);\n"
+      "}\n");
 
   // For instances that derive from Message (rather than MessageLite), some
   // methods are virtual and should be marked as final.
-  string use_final = HasDescriptorMethods(descriptor_->file(), options_) ?
-      " final" : "";
+  format.Set("full_final", HasDescriptorMethods(descriptor_->file(), options_)
+                               ? "final"
+                               : "");
 
   if (HasGeneratedMethods(descriptor_->file(), options_)) {
     if (HasDescriptorMethods(descriptor_->file(), options_)) {
-      printer->Print(vars,
-        "void CopyFrom(const ::google::protobuf::Message& from) final;\n"
-        "void MergeFrom(const ::google::protobuf::Message& from) final;\n");
+      format(
+          "void CopyFrom(const ::$proto_ns$::Message& from) final;\n"
+          "void MergeFrom(const ::$proto_ns$::Message& from) final;\n");
     } else {
-      printer->Print(vars,
-        "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from)\n"
-        "  final;\n");
+      format(
+          "void CheckTypeAndMergeFrom(const ::$proto_ns$::MessageLite& from)\n"
+          "  final;\n");
     }
 
-    vars["clear_final"] = " final";
-    vars["is_initialized_final"] = " final";
-    vars["merge_partial_final"] = " final";
+    format.Set("clear_final",
+               ShouldMarkClearAsFinal(descriptor_, options_) ? "final" : "");
+    format.Set(
+        "is_initialized_final",
+        ShouldMarkIsInitializedAsFinal(descriptor_, options_) ? "final" : "");
+    format.Set(
+        "merge_partial_final",
+        ShouldMarkMergePartialAsFinal(descriptor_, options_) ? "final" : "");
 
-    printer->Print(
-        vars,
+    format(
         "void CopyFrom(const $classname$& from);\n"
         "void MergeFrom(const $classname$& from);\n"
-        "void Clear()$clear_final$;\n"
-        "bool IsInitialized() const$is_initialized_final$;\n"
+        "void Clear()$ clear_final$;\n"
+        "bool IsInitialized() const$ is_initialized_final$;\n"
         "\n"
         "size_t ByteSizeLong() const final;\n"
+        "#if $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
+        "static const char* _InternalParse(const char* begin, const char* end, "
+        "void* object, ::$proto_ns$::internal::ParseContext* ctx);\n"
+        "::$proto_ns$::internal::ParseFunc _ParseFunc() const final { return "
+        "_InternalParse; }\n"
+        "#else\n"
         "bool MergePartialFromCodedStream(\n"
-        "    ::google::protobuf::io::CodedInputStream* input)$merge_partial_final$;\n");
+        "    ::$proto_ns$::io::CodedInputStream* input)$ "
+        "merge_partial_final$;\n"
+        "#endif  // $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n");
+    if (descriptor_->options().message_set_wire_format()) {
+      format(
+          "#if $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
+          "static const char* InternalParseMessageSetItem(const char* begin, "
+          "const char* end, void* object, "
+          "::$proto_ns$::internal::ParseContext* "
+          "ctx);\n"
+          "#endif  // $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n");
+    }
+
     if (!options_.table_driven_serialization ||
         descriptor_->options().message_set_wire_format()) {
-      printer->Print(
+      format(
           "void SerializeWithCachedSizes(\n"
-          "    ::google::protobuf::io::CodedOutputStream* output) const "
-          "final;\n");
+          "    ::$proto_ns$::io::CodedOutputStream* output) const final;\n");
     }
     // DiscardUnknownFields() is implemented in message.cc using reflections. We
     // need to implement this function in generated code for messages.
     if (!UseUnknownFieldSet(descriptor_->file(), options_)) {
-      printer->Print(
-        "void DiscardUnknownFields()$final$;\n",
-        "final", use_final);
+      format("void DiscardUnknownFields()$ full_final$;\n");
     }
     if (HasFastArraySerialization(descriptor_->file(), options_)) {
-      printer->Print(
-        "::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(\n"
-        "    bool deterministic, ::google::protobuf::uint8* target) const final;\n");
+      format(
+          "$uint8$* InternalSerializeWithCachedSizesToArray(\n"
+          "    bool deterministic, $uint8$* target) const final;\n");
     }
   }
 
-  printer->Print(
+  format(
       "int GetCachedSize() const final { return _cached_size_.Get(); }"
       "\n\nprivate:\n"
       "void SharedCtor();\n"
       "void SharedDtor();\n"
-      "void SetCachedSize(int size) const$final$;\n"
-      "void InternalSwap($classname$* other);\n",
-      "classname", classname_, "final", use_final);
+      "void SetCachedSize(int size) const$ full_final$;\n"
+      "void InternalSwap($classname$* other);\n");
   if (SupportsArenas(descriptor_)) {
-    printer->Print(
-      // TODO(gerbens) Make this private! Currently people are deriving from
-      // protos to give access to this constructor, breaking the invariants
-      // we rely on.
-      "protected:\n"
-      "explicit $classname$(::google::protobuf::Arena* arena);\n"
-      "private:\n"
-      "static void ArenaDtor(void* object);\n"
-      "inline void RegisterArenaDtor(::google::protobuf::Arena* arena);\n",
-      "classname", classname_);
+    format(
+        // TODO(gerbens) Make this private! Currently people are deriving from
+        // protos to give access to this constructor, breaking the invariants
+        // we rely on.
+        "protected:\n"
+        "explicit $classname$(::$proto_ns$::Arena* arena);\n"
+        "private:\n"
+        "static void ArenaDtor(void* object);\n"
+        "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n");
   }
 
   if (SupportsArenas(descriptor_)) {
-    printer->Print(
-      "private:\n"
-      "inline ::google::protobuf::Arena* GetArenaNoVirtual() const {\n"
-      "  return _internal_metadata_.arena();\n"
-      "}\n"
-      "inline void* MaybeArenaPtr() const {\n"
-      "  return _internal_metadata_.raw_arena_ptr();\n"
-      "}\n");
+    format(
+        "private:\n"
+        "inline ::$proto_ns$::Arena* GetArenaNoVirtual() const {\n"
+        "  return _internal_metadata_.arena();\n"
+        "}\n"
+        "inline void* MaybeArenaPtr() const {\n"
+        "  return _internal_metadata_.raw_arena_ptr();\n"
+        "}\n");
   } else {
-    printer->Print(
-      "private:\n"
-      "inline ::google::protobuf::Arena* GetArenaNoVirtual() const {\n"
-      "  return NULL;\n"
-      "}\n"
-      "inline void* MaybeArenaPtr() const {\n"
-      "  return NULL;\n"
-      "}\n");
+    format(
+        "private:\n"
+        "inline ::$proto_ns$::Arena* GetArenaNoVirtual() const {\n"
+        "  return NULL;\n"
+        "}\n"
+        "inline void* MaybeArenaPtr() const {\n"
+        "  return NULL;\n"
+        "}\n");
   }
 
-  printer->Print(
+  format(
       "public:\n"
       "\n");
 
   if (HasDescriptorMethods(descriptor_->file(), options_)) {
-    printer->Print(
-      "::google::protobuf::Metadata GetMetadata() const final;\n"
-      "\n");
+    format(
+        "::$proto_ns$::Metadata GetMetadata() const final;\n"
+        "\n");
   } else {
-    printer->Print(
-      "::std::string GetTypeName() const final;\n"
-      "\n");
+    format(
+        "$string$ GetTypeName() const final;\n"
+        "\n");
   }
 
-  printer->Print(
-    "// nested types ----------------------------------------------------\n"
-    "\n");
+  format(
+      "// nested types ----------------------------------------------------\n"
+      "\n");
 
   // Import all nested message classes into this class's scope with typedefs.
   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
     const Descriptor* nested_type = descriptor_->nested_type(i);
     if (!IsMapEntryMessage(nested_type)) {
-      printer->Print("typedef $nested_full_name$ $nested_name$;\n",
-                     "nested_name", nested_type->name(),
-                     "nested_full_name", ClassName(nested_type, false));
-      printer->Annotate("nested_full_name", nested_type);
-      printer->Annotate("nested_name", nested_type);
+      format.Set("nested_full_name", ClassName(nested_type, false));
+      format.Set("nested_name", nested_type->name());
+      format("typedef ${1$$nested_full_name$$}$ ${1$$nested_name$$}$;\n",
+             nested_type);
     }
   }
 
   if (descriptor_->nested_type_count() > 0) {
-    printer->Print("\n");
+    format("\n");
   }
 
   // Import all nested enums and their values into this class's scope with
   // typedefs and constants.
   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
     enum_generators_[i]->GenerateSymbolImports(printer);
-    printer->Print("\n");
+    format("\n");
   }
 
-  printer->Print(
-    "// accessors -------------------------------------------------------\n"
-    "\n");
+  format(
+      "// accessors -------------------------------------------------------\n"
+      "\n");
 
   // Generate accessor methods for all fields.
   GenerateFieldAccessorDeclarations(printer);
@@ -1136,49 +1286,37 @@
   }
 
 
-  printer->Print(
-    "// @@protoc_insertion_point(class_scope:$full_name$)\n",
-    "full_name", descriptor_->full_name());
+  format("// @@protoc_insertion_point(class_scope:$full_name$)\n");
 
   // Generate private members.
-  printer->Outdent();
-  printer->Print(" private:\n");
-  printer->Indent();
+  format.Outdent();
+  format(" private:\n");
+  format.Indent();
+  // TODO(seongkim): Remove hack to track field access and remove this class.
+  format("class HasBitSetters;\n");
 
 
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    if (!descriptor_->field(i)->is_repeated() &&
-        !descriptor_->field(i)->options().weak()) {
-      // set_has_***() generated in all proto1/2 code and in oneofs (only) for
-      // messages without true field presence.
-      if (HasFieldPresence(descriptor_->file()) ||
-          descriptor_->field(i)->containing_oneof()) {
-        printer->Print("void set_has_$name$();\n", "name",
-                       FieldName(descriptor_->field(i)));
-      }
-      // clear_has_***() generated only for non-oneof fields
-      // in proto1/2.
-      if (!descriptor_->field(i)->containing_oneof() &&
-          HasFieldPresence(descriptor_->file())) {
-        printer->Print("void clear_has_$name$();\n", "name",
-                       FieldName(descriptor_->field(i)));
-      }
+  for (auto field : FieldRange(descriptor_)) {
+    // set_has_***() generated in all oneofs.
+    if (!field->is_repeated() && !field->options().weak() &&
+        field->containing_oneof()) {
+      format("void set_has_$1$();\n", FieldName(field));
     }
   }
-  printer->Print("\n");
+  format("\n");
 
   // Generate oneof function declarations
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    printer->Print(
-        "inline bool has_$oneof_name$() const;\n"
-        "inline void clear_has_$oneof_name$();\n\n",
-        "oneof_name", descriptor_->oneof_decl(i)->name());
+  for (auto oneof : OneOfRange(descriptor_)) {
+    format(
+        "inline bool has_$1$() const;\n"
+        "inline void clear_has_$1$();\n\n",
+        oneof->name());
   }
 
   if (HasGeneratedMethods(descriptor_->file(), options_) &&
       !descriptor_->options().message_set_wire_format() &&
       num_required_fields_ > 1) {
-    printer->Print(
+    format(
         "// helper for ByteSizeLong()\n"
         "size_t RequiredFieldsByteSizeFallback() const;\n\n");
   }
@@ -1187,14 +1325,15 @@
   // output will be determined later.
 
   bool need_to_emit_cached_size = true;
-  // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
   const string cached_size_decl =
-      "mutable ::google::protobuf::internal::CachedSize _cached_size_;\n";
+      "mutable ::$proto_ns$::internal::CachedSize _cached_size_;\n";
 
   const size_t sizeof_has_bits = HasBitsSize();
-  const string has_bits_decl = sizeof_has_bits == 0 ? "" :
-      "::google::protobuf::internal::HasBits<" + SimpleItoa(sizeof_has_bits / 4) +
-      "> _has_bits_;\n";
+  const string has_bits_decl =
+      sizeof_has_bits == 0
+          ? ""
+          : "::$proto_ns$::internal::HasBits<" +
+                SimpleItoa(sizeof_has_bits / 4) + "> _has_bits_;\n";
 
   // To minimize padding, data members are divided into three sections:
   // (1) members assumed to align to 8 bytes
@@ -1205,154 +1344,142 @@
   // Members assumed to align to 8 bytes:
 
   if (descriptor_->extension_range_count() > 0) {
-    printer->Print(
-      "::google::protobuf::internal::ExtensionSet _extensions_;\n"
-      "\n");
+    format(
+        "::$proto_ns$::internal::ExtensionSet _extensions_;\n"
+        "\n");
   }
 
   if (UseUnknownFieldSet(descriptor_->file(), options_)) {
-    printer->Print(
-      "::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;\n");
+    format(
+        "::$proto_ns$::internal::InternalMetadataWithArena "
+        "_internal_metadata_;\n");
   } else {
-    printer->Print(
-        "::google::protobuf::internal::InternalMetadataWithArenaLite "
+    format(
+        "::$proto_ns$::internal::InternalMetadataWithArenaLite "
         "_internal_metadata_;\n");
   }
 
   if (SupportsArenas(descriptor_)) {
-    printer->Print(
-      "template <typename T> friend class ::google::protobuf::Arena::InternalHelper;\n"
-      "typedef void InternalArenaConstructable_;\n"
-      "typedef void DestructorSkippable_;\n");
+    if (!options_.opensource_runtime) {
+      format(
+          "template <typename T> friend struct "
+          "::proto::internal::EmbeddedMessageHolder;\n");
+    }
+    format(
+        "template <typename T> friend class "
+        "::$proto_ns$::Arena::InternalHelper;\n"
+        "typedef void InternalArenaConstructable_;\n"
+        "typedef void DestructorSkippable_;\n");
   }
 
   if (HasFieldPresence(descriptor_->file())) {
     // _has_bits_ is frequently accessed, so to reduce code size and improve
-    // speed, it should be close to the start of the object.  But, try not to
-    // waste space:_has_bits_ by itself always makes sense if its size is a
-    // multiple of 8, but, otherwise, maybe _has_bits_ and cached_size_ together
-    // will work well.
-    printer->Print(has_bits_decl.c_str());
-    if ((sizeof_has_bits % 8) != 0) {
-      printer->Print(cached_size_decl.c_str());
-      need_to_emit_cached_size = false;
-    }
+    // speed, it should be close to the start of the object. Placing
+    // _cached_size_ together with _has_bits_ improves cache locality despite
+    // potential alignment padding.
+    format(has_bits_decl.c_str());
+    format(cached_size_decl.c_str());
+    need_to_emit_cached_size = false;
   }
 
   // Field members:
 
   // Emit some private and static members
-  for (int i = 0; i < optimized_order_.size(); ++i) {
-    const FieldDescriptor* field = optimized_order_[i];
+  for (auto field : optimized_order_) {
     const FieldGenerator& generator = field_generators_.get(field);
     generator.GenerateStaticMembers(printer);
     generator.GeneratePrivateMembers(printer);
   }
 
   // For each oneof generate a union
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    printer->Print(
-        "union $camel_oneof_name$Union {\n"
+  for (auto oneof : OneOfRange(descriptor_)) {
+    string camel_oneof_name = UnderscoresToCamelCase(oneof->name(), true);
+    format(
+        "union $1$Union {\n"
         // explicit empty constructor is needed when union contains
         // ArenaStringPtr members for string fields.
-        "  $camel_oneof_name$Union() {}\n",
-        "camel_oneof_name",
-        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
-    printer->Indent();
-    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
-      field_generators_.get(descriptor_->oneof_decl(i)->
-                            field(j)).GeneratePrivateMembers(printer);
+        "  $1$Union() {}\n",
+        camel_oneof_name);
+    format.Indent();
+    for (auto field : FieldRange(oneof)) {
+      field_generators_.get(field).GeneratePrivateMembers(printer);
     }
-    printer->Outdent();
-    printer->Print(
-        "} $oneof_name$_;\n",
-        "oneof_name", descriptor_->oneof_decl(i)->name());
-    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
-      field_generators_.get(descriptor_->oneof_decl(i)->
-                            field(j)).GenerateStaticMembers(printer);
+    format.Outdent();
+    format("} $1$_;\n", oneof->name());
+    for (auto field : FieldRange(oneof)) {
+      field_generators_.get(field).GenerateStaticMembers(printer);
     }
   }
 
   // Members assumed to align to 4 bytes:
 
   if (need_to_emit_cached_size) {
-    printer->Print(cached_size_decl.c_str());
+    format(cached_size_decl.c_str());
     need_to_emit_cached_size = false;
   }
 
   // Generate _oneof_case_.
   if (descriptor_->oneof_decl_count() > 0) {
-    printer->Print(vars,
-      "::google::protobuf::uint32 _oneof_case_[$oneof_decl_count$];\n"
-      "\n");
+    format(
+        "$uint32$ _oneof_case_[$1$];\n"
+        "\n",
+        descriptor_->oneof_decl_count());
   }
 
   if (num_weak_fields_) {
-    printer->Print(
-        "::google::protobuf::internal::WeakFieldMap _weak_field_map_;\n");
+    format("::$proto_ns$::internal::WeakFieldMap _weak_field_map_;\n");
   }
   // Generate _any_metadata_ for the Any type.
   if (IsAnyMessage(descriptor_)) {
-    printer->Print(vars,
-      "::google::protobuf::internal::AnyMetadata _any_metadata_;\n");
+    format("::$proto_ns$::internal::AnyMetadata _any_metadata_;\n");
   }
 
   // The TableStruct struct needs access to the private parts, in order to
   // construct the offsets of all members.
-  printer->Print("friend struct ::$file_namespace$::TableStruct;\n",
-                 // Vars.
-                 "scc_name", scc_name_, "file_namespace",
-                 FileLevelNamespace(descriptor_));
+  format("friend struct ::$tablename$;\n");
 
-  printer->Outdent();
-  printer->Print("};");
+  format.Outdent();
+  format("};");
   GOOGLE_DCHECK(!need_to_emit_cached_size);
 }
 
-void MessageGenerator::
-GenerateInlineMethods(io::Printer* printer) {
+void MessageGenerator::GenerateInlineMethods(io::Printer* printer) {
   if (IsMapEntryMessage(descriptor_)) return;
   GenerateFieldAccessorDefinitions(printer);
 
   // Generate oneof_case() functions.
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    std::map<string, string> vars;
-    vars["class_name"] = classname_;
-    vars["camel_oneof_name"] = UnderscoresToCamelCase(
-        descriptor_->oneof_decl(i)->name(), true);
-    vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
-    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
-    printer->Print(
-        vars,
-        "inline $class_name$::$camel_oneof_name$Case $class_name$::"
+  for (auto oneof : OneOfRange(descriptor_)) {
+    Formatter format(printer, variables_);
+    format.Set("camel_oneof_name", UnderscoresToCamelCase(oneof->name(), true));
+    format.Set("oneof_name", oneof->name());
+    format.Set("oneof_index", oneof->index());
+    format(
+        "inline $classname$::$camel_oneof_name$Case $classname$::"
         "$oneof_name$_case() const {\n"
-        "  return $class_name$::$camel_oneof_name$Case("
+        "  return $classname$::$camel_oneof_name$Case("
         "_oneof_case_[$oneof_index$]);\n"
         "}\n");
   }
 }
 
-void MessageGenerator::
-GenerateExtraDefaultFields(io::Printer* printer) {
+void MessageGenerator::GenerateExtraDefaultFields(io::Printer* printer) {
   // Generate oneof default instance and weak field instances for reflection
   // usage.
+  Formatter format(printer, variables_);
   if (descriptor_->oneof_decl_count() > 0 || num_weak_fields_ > 0) {
-    for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-      for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
-        const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+    for (auto oneof : OneOfRange(descriptor_)) {
+      for (auto field : FieldRange(oneof)) {
         if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
             (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
-             EffectiveStringCType(field) != FieldOptions::STRING)) {
-          printer->Print("const ");
+             EffectiveStringCType(field, options_) != FieldOptions::STRING)) {
+          format("const ");
         }
         field_generators_.get(field).GeneratePrivateMembers(printer);
       }
     }
-    for (int i = 0; i < descriptor_->field_count(); i++) {
-      const FieldDescriptor* field = descriptor_->field(i);
+    for (auto field : FieldRange(descriptor_)) {
       if (field->options().weak()) {
-        printer->Print(
-            "  const ::google::protobuf::Message* $name$_;\n", "name", FieldName(field));
+        format("  const ::$proto_ns$::Message* $1$_;\n", FieldName(field));
       }
     }
   }
@@ -1360,130 +1487,85 @@
 
 bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset,
                                           size_t aux_offset) {
+  Formatter format(printer, variables_);
+
   if (!table_driven_) {
-    printer->Print("{ NULL, NULL, 0, -1, -1, -1, -1, NULL, false },\n");
+    format("{ NULL, NULL, 0, -1, -1, -1, -1, NULL, false },\n");
     return false;
   }
 
-  std::map<string, string> vars;
-
-  vars["classname"] = ClassName(descriptor_);
-  vars["classtype"] = QualifiedClassName(descriptor_);
-  vars["offset"] = SimpleItoa(offset);
-  vars["aux_offset"] = SimpleItoa(aux_offset);
-
   int max_field_number = 0;
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* field = descriptor_->field(i);
+  for (auto field : FieldRange(descriptor_)) {
     if (max_field_number < field->number()) {
       max_field_number = field->number();
     }
   }
 
-  vars["max_field_number"] = SimpleItoa(max_field_number);
+  format("{\n");
+  format.Indent();
 
-  printer->Print("{\n");
-  printer->Indent();
-
-  printer->Print(vars,
-      "TableStruct::entries + $offset$,\n"
-      "TableStruct::aux + $aux_offset$,\n"
-      "$max_field_number$,\n");
+  format(
+      "$tablename$::entries + $1$,\n"
+      "$tablename$::aux + $2$,\n"
+      "$3$,\n",
+      offset, aux_offset, max_field_number);
 
   if (!HasFieldPresence(descriptor_->file())) {
     // If we don't have field presence, then _has_bits_ does not exist.
-    printer->Print(vars, "-1,\n");
+    format("-1,\n");
   } else {
-    printer->Print(vars,
-                   "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n"
-                   "  $classtype$, _has_bits_),\n");
+    format(
+        "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET(\n"
+        "  $classtype$, _has_bits_),\n");
   }
 
   if (descriptor_->oneof_decl_count() > 0) {
-    printer->Print(vars,
-                   "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n"
-                   "  $classtype$, _oneof_case_),\n");
+    format(
+        "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET(\n"
+        "  $classtype$, _oneof_case_),\n");
   } else {
-    printer->Print("-1,  // no _oneof_case_\n");
+    format("-1,  // no _oneof_case_\n");
   }
 
   if (descriptor_->extension_range_count() > 0) {
-    printer->Print(vars,
-                   "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
-                   "_extensions_),\n");
+    format(
+        "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
+        "_extensions_),\n");
   } else {
-    printer->Print("-1,  // no _extensions_\n");
+    format("-1,  // no _extensions_\n");
   }
 
   // TODO(ckennelly): Consolidate this with the calculation for
   // AuxillaryParseTableField.
-  vars["ns"] = Namespace(descriptor_);
-
-  printer->Print(vars,
-                 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n"
-                 "  $classtype$, _internal_metadata_),\n"
-                 "&$ns$::_$classname$_default_instance_,\n");
+  format(
+      "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET(\n"
+      "  $classtype$, _internal_metadata_),\n"
+      "&$package_ns$::_$classname$_default_instance_,\n");
 
   if (UseUnknownFieldSet(descriptor_->file(), options_)) {
-    printer->Print(vars, "true,\n");
+    format("true,\n");
   } else {
-    printer->Print(vars, "false,\n");
+    format("false,\n");
   }
 
-  printer->Outdent();
-  printer->Print("},\n");
+  format.Outdent();
+  format("},\n");
   return true;
 }
 
 void MessageGenerator::GenerateSchema(io::Printer* printer, int offset,
                                       int has_offset) {
-  std::map<string, string> vars;
-
-  vars["classname"] = QualifiedClassName(descriptor_);
-  vars["offset"] = SimpleItoa(offset);
-  vars["has_bits_offsets"] =
+  Formatter format(printer, variables_);
+  has_offset =
       HasFieldPresence(descriptor_->file()) || IsMapEntryMessage(descriptor_)
-          ? SimpleItoa(offset + has_offset)
-          : "-1";
+          ? offset + has_offset
+          : -1;
 
-  printer->Print(vars,
-                 "{ $offset$, $has_bits_offsets$, sizeof($classname$)},\n");
+  format("{ $1$, $2$, sizeof($classtype$)},\n", offset, has_offset);
 }
 
 namespace {
 
-// TODO(gerbens) remove this after the next sync with GitHub code base.
-// Then the opensource testing has gained the functionality to compile
-// the CalcFieldNum given the symbols defined in generated-message-util.
-#ifdef OPENSOURCE_PROTOBUF_CPP_BOOTSTRAP
-// We need a clean version of CalcFieldNum that doesn't use new functionality
-// in the runtime, because this functionality is not yet in the opensource
-// runtime
-
-uint32 CalculateType(uint32 type, uint32 type_class) {
-  return (type - 1) + type_class * 20;
-}
-
-uint32 CalcFieldNum(const FieldGenerator&, const FieldDescriptor* field,
-                    const Options& options) {
-  bool is_a_map = IsMapEntryMessage(field->containing_type());
-  int type = field->type();
-  if (field->containing_oneof()) {
-    return CalculateType(type, 4);
-  }
-  if (field->is_packed()) {
-    return CalculateType(type, 3);
-  } else if (field->is_repeated()) {
-    return CalculateType(type, 2);
-  } else if (!HasFieldPresence(field->file()) &&
-             field->containing_oneof() == NULL && !is_a_map) {
-    return CalculateType(type, 1);
-  } else {
-    return CalculateType(type, 0);
-  }
-}
-
-#else
 // We need to calculate for each field what function the table driven code
 // should use to serialize it. This returns the index in a lookup table.
 uint32 CalcFieldNum(const FieldGenerator& generator,
@@ -1495,6 +1577,12 @@
     if (generator.IsInlined()) {
       type = internal::FieldMetadata::kInlinedType;
     }
+    // string field
+    if (IsCord(field, options)) {
+      type = internal::FieldMetadata::kCordType;
+    } else if (IsStringPiece(field, options)) {
+      type = internal::FieldMetadata::kStringPieceType;
+    }
   }
   if (field->containing_oneof()) {
     return internal::FieldMetadata::CalculateType(
@@ -1515,7 +1603,6 @@
         type, internal::FieldMetadata::kPresence);
   }
 }
-#endif
 
 int FindMessageIndexInFile(const Descriptor* descriptor) {
   std::vector<const Descriptor*> flatten =
@@ -1527,12 +1614,11 @@
 }  // namespace
 
 int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
+  Formatter format(printer, variables_);
   if (!options_.table_driven_serialization) {
     return 0;
   }
 
-  string full_classname = QualifiedClassName(descriptor_);
-
   std::vector<const FieldDescriptor*> sorted = SortFieldsByNumber(descriptor_);
   if (IsMapEntryMessage(descriptor_)) {
     for (int i = 0; i < 2; i++) {
@@ -1543,36 +1629,40 @@
           field->number(), WireFormat::WireTypeForFieldType(field->type()));
 
       std::map<string, string> vars;
-      vars["classname"] = QualifiedClassName(descriptor_);
+      vars["classtype"] = QualifiedClassName(descriptor_);
       vars["field_name"] = FieldName(field);
       vars["tag"] = SimpleItoa(tag);
       vars["hasbit"] = SimpleItoa(i);
-      vars["type"] = SimpleItoa(CalcFieldNum(generator, field, options_));
+      vars["type"] =
+          SimpleItoa(CalcFieldNum(generator, field, options_));
       vars["ptr"] = "NULL";
       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
         GOOGLE_CHECK(!IsMapEntryMessage(field->message_type()));
-        {
+        if (!IsProto1(field->message_type()->file(), options_)) {
           vars["ptr"] =
-              "::" + FileLevelNamespace(field->message_type()) +
-              "::TableStruct::serialization_table + " +
-              SimpleItoa(FindMessageIndexInFile(field->message_type()));
+              "::" +
+              UniqueName("TableStruct", field->message_type(), options_) +
+              "::serialization_table + " +
+              SimpleItoa(
+                  FindMessageIndexInFile(field->message_type()));
         }
       }
-      printer->Print(vars,
-                     "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
-                     "::google::protobuf::internal::MapEntryHelper<$classname$::"
-                     "SuperType>, $field_name$_), $tag$,"
-                     "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
-                     "::google::protobuf::internal::MapEntryHelper<$classname$::"
-                     "SuperType>, _has_bits_) * 8 + $hasbit$, $type$, "
-                     "$ptr$},\n");
+      Formatter::SaveState saver(&format);
+      format.AddMap(vars);
+      format(
+          "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET("
+          "::$proto_ns$::internal::MapEntryHelper<$classtype$::"
+          "SuperType>, $field_name$_), $tag$,"
+          "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET("
+          "::$proto_ns$::internal::MapEntryHelper<$classtype$::"
+          "SuperType>, _has_bits_) * 8 + $hasbit$, $type$, "
+          "$ptr$},\n");
     }
     return 2;
   }
-  printer->Print(
-      "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
-      "_cached_size_), 0, 0, 0, NULL},\n",
-      "classname", full_classname);
+  format(
+      "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
+      "_cached_size_), 0, 0, 0, NULL},\n");
   std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
   for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
     sorted_extensions.push_back(descriptor_->extension_range(i));
@@ -1586,14 +1676,13 @@
          extension_idx++) {
       const Descriptor::ExtensionRange* range =
           sorted_extensions[extension_idx];
-      printer->Print(
-          "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
-          "_extensions_), $start$, $end$, "
-          "::google::protobuf::internal::FieldMetadata::kSpecial, "
+      format(
+          "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
+          "_extensions_), "
+          "$1$, $2$, ::$proto_ns$::internal::FieldMetadata::kSpecial, "
           "reinterpret_cast<const "
-          "void*>(::google::protobuf::internal::ExtensionSerializer)},\n",
-          "classname", full_classname, "start", SimpleItoa(range->start), "end",
-          SimpleItoa(range->end));
+          "void*>(::$proto_ns$::internal::ExtensionSerializer)},\n",
+          range->start, range->end);
     }
     if (i == sorted.size()) break;
     const FieldDescriptor* field = sorted[i];
@@ -1609,105 +1698,121 @@
     if (field->containing_oneof()) {
       classfieldname = field->containing_oneof()->name();
     }
-    std::map<string, string> vars;
-    vars["classname"] = full_classname;
-    vars["field_name"] = classfieldname;
-    vars["tag"] = SimpleItoa(tag);
-    vars["ptr"] = "NULL";
+    format.Set("field_name", classfieldname);
+    string ptr = "NULL";
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
       if (IsMapEntryMessage(field->message_type())) {
-        vars["idx"] = SimpleItoa(FindMessageIndexInFile(field->message_type()));
-        vars["fieldclassname"] = QualifiedClassName(field->message_type());
-        printer->Print(vars,
-                       "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($"
-                       "classname$, $field_name$_), $tag$, $idx$, "
-                       "::google::protobuf::internal::FieldMetadata::kSpecial, "
-                       "reinterpret_cast<const void*>(static_cast< "
-                       "::google::protobuf::internal::SpecialSerializer>("
-                       "::google::protobuf::internal::MapFieldSerializer< "
-                       "::google::protobuf::internal::MapEntryToMapField<"
-                       "$fieldclassname$>::MapFieldType, "
-                       "TableStruct::serialization_table>))},\n");
+        format(
+            "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($"
+            "classtype$, $field_name$_), $1$, $2$, "
+            "::$proto_ns$::internal::FieldMetadata::kSpecial, "
+            "reinterpret_cast<const void*>(static_cast< "
+            "::$proto_ns$::internal::SpecialSerializer>("
+            "::$proto_ns$::internal::MapFieldSerializer< "
+            "::$proto_ns$::internal::MapEntryToMapField<"
+            "$3$>::MapFieldType, "
+            "$tablename$::serialization_table>))},\n",
+            tag, FindMessageIndexInFile(field->message_type()),
+            QualifiedClassName(field->message_type()));
         continue;
-      } else {
-        vars["ptr"] =
-            "::" + FileLevelNamespace(field->message_type()) +
-            "::TableStruct::serialization_table + " +
+      } else if (!IsProto1(field->message_type()->file(), options_) &&
+                 !field->message_type()->options().message_set_wire_format()) {
+        // Proto1 or message_set don't have the usual table and we need to
+        // dispatch to generated serializer, hence ptr stays zero.
+        ptr =
+            "::" + UniqueName("TableStruct", field->message_type(), options_) +
+            "::serialization_table + " +
             SimpleItoa(FindMessageIndexInFile(field->message_type()));
       }
     }
 
     const FieldGenerator& generator = field_generators_.get(field);
-    vars["type"] = SimpleItoa(CalcFieldNum(generator, field, options_));
+    int type = CalcFieldNum(generator, field, options_);
 
+    if (IsLazy(field, options_)) {
+      type = internal::FieldMetadata::kSpecial;
+      ptr = "reinterpret_cast<const void*>(::" + variables_["proto_ns"] +
+            "::internal::LazyFieldSerializer";
+      if (field->containing_oneof()) {
+        ptr += "OneOf";
+      } else if (!HasFieldPresence(descriptor_->file()) ||
+                 has_bit_indices_[field->index()] == -1) {
+        ptr += "NoPresence";
+      }
+      ptr += ")";
+    }
 
     if (field->options().weak()) {
       // TODO(gerbens) merge weak fields into ranges
-      printer->Print(vars,
-                     "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($"
-                     "classname$, _weak_field_map_), $tag$, $tag$, "
-                     "::google::protobuf::internal::FieldMetadata::kSpecial, "
-                     "reinterpret_cast<const "
-                     "void*>(::google::protobuf::internal::WeakFieldSerializer)},\n");
+      format(
+          "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET("
+          "$classtype$, _weak_field_map_), $1$, $1$, "
+          "::$proto_ns$::internal::FieldMetadata::kSpecial, "
+          "reinterpret_cast<const "
+          "void*>(::$proto_ns$::internal::WeakFieldSerializer)},\n",
+          tag);
     } else if (field->containing_oneof()) {
-      vars["oneofoffset"] =
-          SimpleItoa(sizeof(uint32) * field->containing_oneof()->index());
-      printer->Print(vars,
-                     "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($"
-                     "classname$, $field_name$_), $tag$, "
-                     "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($"
-                     "classname$, _oneof_case_) + $oneofoffset$, "
-                     "$type$, $ptr$},\n");
+      format.Set("oneofoffset",
+                 sizeof(uint32) * field->containing_oneof()->index());
+      format(
+          "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
+          "$field_name$_), "
+          "$1$, $GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
+          "_oneof_case_) + $oneofoffset$, $2$, $3$},\n",
+          tag, type, ptr);
     } else if (HasFieldPresence(descriptor_->file()) &&
                has_bit_indices_[field->index()] != -1) {
-      vars["hasbitsoffset"] = SimpleItoa(has_bit_indices_[field->index()]);
-      printer->Print(vars,
-                     "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($"
-                     "classname$, $field_name$_), $tag$, "
-                     "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($"
-                     "classname$, _has_bits_) * 8 + $hasbitsoffset$, $type$, "
-                     "$ptr$},\n");
+      format.Set("hasbitsoffset", has_bit_indices_[field->index()]);
+      format(
+          "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
+          "$field_name$_), "
+          "$1$, $GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
+          "_has_bits_) * 8 + $hasbitsoffset$, $2$, $3$},\n",
+          tag, type, ptr);
     } else {
-      printer->Print(vars,
-                     "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($"
-                     "classname$, $field_name$_), $tag$, ~0u, $type$, "
-                     "$ptr$},\n");
+      format(
+          "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
+          "$field_name$_), "
+          "$1$, ~0u, $2$, $3$},\n",
+          tag, type, ptr);
     }
   }
   int num_field_metadata = 1 + sorted.size() + sorted_extensions.size();
   num_field_metadata++;
   string serializer = UseUnknownFieldSet(descriptor_->file(), options_)
-                          ? "::google::protobuf::internal::UnknownFieldSetSerializer"
-                          : "::google::protobuf::internal::UnknownFieldSerializerLite";
-  printer->Print(
-      "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
+                          ? "UnknownFieldSetSerializer"
+                          : "UnknownFieldSerializerLite";
+  format(
+      "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
       "_internal_metadata_), 0, ~0u, "
-      "::google::protobuf::internal::FieldMetadata::kSpecial, reinterpret_cast<const "
-      "void*>($serializer$)},\n",
-      "classname", full_classname, "serializer", serializer);
+      "::$proto_ns$::internal::FieldMetadata::kSpecial, reinterpret_cast<const "
+      "void*>(::$proto_ns$::internal::$1$)},\n",
+      serializer);
   return num_field_metadata;
 }
 
 void MessageGenerator::GenerateFieldDefaultInstances(io::Printer* printer) {
   // Construct the default instances for all fields that need one.
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    field_generators_.get(descriptor_->field(i))
-                     .GenerateDefaultInstanceAllocator(printer);
+  for (auto field : FieldRange(descriptor_)) {
+    field_generators_.get(field).GenerateDefaultInstanceAllocator(printer);
   }
 }
 
-void MessageGenerator::
-GenerateDefaultInstanceInitializer(io::Printer* printer) {
+void MessageGenerator::GenerateDefaultInstanceInitializer(
+    io::Printer* printer) {
+  Formatter format(printer, variables_);
+
   // The default instance needs all of its embedded message pointers
   // cross-linked to other default instances.  We can't do this initialization
   // in the constructor because some other default instances may not have been
   // constructed yet at that time.
   // TODO(kenton):  Maybe all message fields (even for non-default messages)
   //   should be initialized to point at default instances rather than NULL?
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* field = descriptor_->field(i);
+  for (auto field : FieldRange(descriptor_)) {
+    Formatter::SaveState saver(&format);
 
     if (!field->is_repeated() &&
+        !IsLazy(field, options_) &&
         field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
         (field->containing_oneof() == NULL ||
          HasDescriptorMethods(descriptor_->file(), options_))) {
@@ -1719,201 +1824,244 @@
             "_" + classname_ + "_default_instance_._instance.get_mutable()->";
       }
       name += FieldName(field);
-      printer->Print(
-          "$ns$::$name$_ = const_cast< $type$*>(\n"
-          "    $type$::internal_default_instance());\n",
-          // Vars.
-          "name", name, "type", FieldMessageTypeName(field), "ns",
-          Namespace(descriptor_));
+      format.Set("name", name);
+      if (IsWeak(field, options_)) {
+        const FileDescriptor* dependency = field->message_type()->file();
+        string default_instance = QualifiedFileLevelSymbol(
+            dependency->package(),
+            "_" + ClassName(field->message_type()) + "_default_instance_");
+        format(
+            "$package_ns$::$name$_ = reinterpret_cast<const "
+            "::$proto_ns$::Message*>(&$1$);\n"
+            "if ($package_ns$::$name$_ == NULL) {\n"
+            "  $package_ns$::$name$_ = "
+            "::$proto_ns$::Empty::internal_default_instance();\n"
+            "}\n",
+            default_instance);  // 1
+        continue;
+      }
+      format(
+          "$package_ns$::$name$_ = const_cast< $1$*>(\n"
+          "    $1$::internal_default_instance());\n",
+          FieldMessageTypeName(field));
     } else if (field->containing_oneof() &&
                HasDescriptorMethods(descriptor_->file(), options_)) {
-      field_generators_.get(descriptor_->field(i))
-          .GenerateConstructorCode(printer);
+      field_generators_.get(field).GenerateConstructorCode(printer);
     }
   }
 }
 
-void MessageGenerator::
-GenerateClassMethods(io::Printer* printer) {
+void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
+  Formatter format(printer, variables_);
   if (IsMapEntryMessage(descriptor_)) {
-    printer->Print(
+    format(
         "$classname$::$classname$() {}\n"
-        "$classname$::$classname$(::google::protobuf::Arena* arena) : "
-        "SuperType(arena) {}\n"
+        "$classname$::$classname$(::$proto_ns$::Arena* arena)\n"
+        "    : SuperType(arena) {}\n"
         "void $classname$::MergeFrom(const $classname$& other) {\n"
         "  MergeFromInternal(other);\n"
-        "}\n",
-        "classname", classname_);
+        "}\n");
     if (HasDescriptorMethods(descriptor_->file(), options_)) {
-      printer->Print(
-          "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
-          "  ::$file_namespace$::protobuf_AssignDescriptorsOnce();\n"
-          "  return ::$file_namespace$::file_level_metadata[$index$];\n"
-          "}\n"
+      format(
+          "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
+          "  "
+          "::$proto_ns$::internal::AssignDescriptors(&::$assign_desc_table$);\n"
+          "  return ::$file_level_metadata$[$1$];\n"
+          "}\n",
+          index_in_file_messages_);
+      format(
           "void $classname$::MergeFrom(\n"
-          "    const ::google::protobuf::Message& other) {\n"
-          "  ::google::protobuf::Message::MergeFrom(other);\n"
+          "    const ::$proto_ns$::Message& other) {\n"
+          "  ::$proto_ns$::Message::MergeFrom(other);\n"
           "}\n"
-          "\n",
-          "file_namespace", FileLevelNamespace(descriptor_),
-          "classname", classname_, "index",
-          SimpleItoa(index_in_file_messages_));
+          "\n");
     }
+    // TODO(gerbens) make maps parse :(
+    format(
+        "#if $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
+        "const char* $classname$::_InternalParse(const char* begin, const "
+        "char* end, void* object, ::$proto_ns$::internal::ParseContext* ctx) { "
+        "return end; }\n"
+        "#endif  // $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n");
+    format("\n");
     return;
   }
 
   // TODO(gerbens) Remove this function. With a little bit of cleanup and
   // refactoring this is superfluous.
-  printer->Print("void $classname$::InitAsDefaultInstance() {\n", "classname",
-                 classname_);
-  printer->Indent();
+  format("void $classname$::InitAsDefaultInstance() {\n");
+  format.Indent();
   GenerateDefaultInstanceInitializer(printer);
-  printer->Outdent();
-  printer->Print("}\n");
+  format.Outdent();
+  format("}\n");
 
   if (IsAnyMessage(descriptor_)) {
-    printer->Print(
-      "void $classname$::PackFrom(const ::google::protobuf::Message& message) {\n"
-      "  _any_metadata_.PackFrom(message);\n"
-      "}\n"
-      "\n"
-      "void $classname$::PackFrom(const ::google::protobuf::Message& message,\n"
-      "                           const ::std::string& type_url_prefix) {\n"
-      "  _any_metadata_.PackFrom(message, type_url_prefix);\n"
-      "}\n"
-      "\n"
-      "bool $classname$::UnpackTo(::google::protobuf::Message* message) const {\n"
-      "  return _any_metadata_.UnpackTo(message);\n"
-      "}\n"
-      "bool $classname$::ParseAnyTypeUrl(const string& type_url,\n"
-      "                                  string* full_type_name) {\n"
-      "  return ::google::protobuf::internal::ParseAnyTypeUrl(type_url,\n"
-      "                                             full_type_name);\n"
-      "}\n"
-      "\n",
-      "classname", classname_);
+    format(
+        "void $classname$::PackFrom(const ::$proto_ns$::Message& message) {\n"
+        "  _any_metadata_.PackFrom(message);\n"
+        "}\n"
+        "\n"
+        "void $classname$::PackFrom(const ::$proto_ns$::Message& message,\n"
+        "                           const $string$& type_url_prefix) {\n"
+        "  _any_metadata_.PackFrom(message, type_url_prefix);\n"
+        "}\n"
+        "\n"
+        "bool $classname$::UnpackTo(::$proto_ns$::Message* message) const {\n"
+        "  return _any_metadata_.UnpackTo(message);\n"
+        "}\n"
+        "bool $classname$::ParseAnyTypeUrl(const string& type_url,\n"
+        "                                  string* full_type_name) {\n"
+        "  return ::$proto_ns$::internal::ParseAnyTypeUrl(type_url,\n"
+        "                                             full_type_name);\n"
+        "}\n"
+        "bool $classname$::GetAnyFieldDescriptors(\n"
+        "    const ::$proto_ns$::Message& message,\n"
+        "    const ::$proto_ns$::FieldDescriptor** type_url_field,\n"
+        "    const ::$proto_ns$::FieldDescriptor** value_field) {\n"
+        "  return ::$proto_ns$::internal::GetAnyFieldDescriptors(\n"
+        "      message, type_url_field, value_field);\n"
+        "}\n"
+        "\n");
+  }
+
+  format(
+      "class $classname$::HasBitSetters {\n"
+      " public:\n");
+  format.Indent();
+  for (auto field : FieldRange(descriptor_)) {
+    field_generators_.get(field).GenerateInternalAccessorDeclarations(printer);
+    if (HasFieldPresence(descriptor_->file()) && !field->is_repeated() &&
+        !field->options().weak() && !field->containing_oneof()) {
+      int has_bit_index = has_bit_indices_[field->index()];
+      GOOGLE_CHECK_GE(has_bit_index, 0);
+
+      format.Set("has_array_index", has_bit_index / 32);
+      format.Set("has_mask",
+                 strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
+      format(
+          "static void set_has_$1$($classname$* msg) {\n"
+          "  msg->_has_bits_[$has_array_index$] |= 0x$has_mask$u;\n"
+          "}\n",
+          FieldName(field));
+    }
+  }
+  format.Outdent();
+  format("};\n\n");
+  for (auto field : FieldRange(descriptor_)) {
+    field_generators_.get(field).GenerateInternalAccessorDefinitions(printer);
   }
 
   // Generate non-inline field definitions.
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* field = descriptor_->field(i);
-    field_generators_.get(field)
-                     .GenerateNonInlineAccessorDefinitions(printer);
+  for (auto field : FieldRange(descriptor_)) {
+    field_generators_.get(field).GenerateNonInlineAccessorDefinitions(printer);
     if (IsCrossFileMaybeMap(field)) {
+      Formatter::SaveState saver(&format);
       std::map<string, string> vars;
       SetCommonFieldVariables(field, &vars, options_);
       if (field->containing_oneof()) {
         SetCommonOneofFieldVariables(field, &vars);
       }
-      GenerateFieldClear(field, vars, false, printer);
+      format.AddMap(vars);
+      GenerateFieldClear(field, false, format);
     }
   }
 
   // Generate field number constants.
-  printer->Print("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n");
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor *field = descriptor_->field(i);
-    printer->Print(
-      "const int $classname$::$constant_name$;\n",
-      "classname", ClassName(FieldScope(field), false),
-      "constant_name", FieldConstantName(field));
+  format("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n");
+  for (auto field : FieldRange(descriptor_)) {
+    format("const int $classname$::$1$;\n", FieldConstantName(field));
   }
-  printer->Print(
-    "#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900\n"
-    "\n");
+  format(
+      "#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900\n"
+      "\n");
 
   GenerateStructors(printer);
-  printer->Print("\n");
+  format("\n");
 
   if (descriptor_->oneof_decl_count() > 0) {
     GenerateOneofClear(printer);
-    printer->Print("\n");
+    format("\n");
   }
 
   if (HasGeneratedMethods(descriptor_->file(), options_)) {
     GenerateClear(printer);
-    printer->Print("\n");
+    format("\n");
 
     GenerateMergeFromCodedStream(printer);
-    printer->Print("\n");
+    format("\n");
 
     GenerateSerializeWithCachedSizes(printer);
-    printer->Print("\n");
+    format("\n");
 
     if (HasFastArraySerialization(descriptor_->file(), options_)) {
       GenerateSerializeWithCachedSizesToArray(printer);
-      printer->Print("\n");
+      format("\n");
     }
 
     GenerateByteSize(printer);
-    printer->Print("\n");
+    format("\n");
 
     GenerateMergeFrom(printer);
-    printer->Print("\n");
+    format("\n");
 
     GenerateCopyFrom(printer);
-    printer->Print("\n");
+    format("\n");
 
     GenerateIsInitialized(printer);
-    printer->Print("\n");
+    format("\n");
   }
 
   GenerateSwap(printer);
-  printer->Print("\n");
+  format("\n");
 
   if (options_.table_driven_serialization) {
-    printer->Print(
+    format(
         "const void* $classname$::InternalGetTable() const {\n"
-        "  return ::$file_namespace$::TableStruct::serialization_table + "
-        "$index$;\n"
+        "  return ::$tablename$::serialization_table + $1$;\n"
         "}\n"
         "\n",
-        "classname", classname_, "index", SimpleItoa(index_in_file_messages_),
-        "file_namespace", FileLevelNamespace(descriptor_));
+        index_in_file_messages_);
   }
   if (HasDescriptorMethods(descriptor_->file(), options_)) {
-    printer->Print(
-        "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
-        "  $file_namespace$::protobuf_AssignDescriptorsOnce();\n"
-        "  return ::"
-        "$file_namespace$::file_level_metadata[kIndexInFileMessages];\n"
+    format(
+        "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
+        "  ::$proto_ns$::internal::AssignDescriptors(&::$assign_desc_table$);\n"
+        "  return ::$file_level_metadata$[kIndexInFileMessages];\n"
         "}\n"
-        "\n",
-        "classname", classname_, "file_namespace",
-        FileLevelNamespace(descriptor_));
+        "\n");
   } else {
-    printer->Print(
-      "::std::string $classname$::GetTypeName() const {\n"
-      "  return \"$type_name$\";\n"
-      "}\n"
-      "\n",
-      "classname", classname_,
-      "type_name", descriptor_->full_name());
+    format(
+        "$string$ $classname$::GetTypeName() const {\n"
+        "  return \"$full_name$\";\n"
+        "}\n"
+        "\n");
   }
 
 }
 
 size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) {
+  Formatter format(printer, variables_);
+
   if (!table_driven_) {
     return 0;
   }
 
   // Field "0" is special:  We use it in our switch statement of processing
   // types to handle the successful end tag case.
-  printer->Print("{0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},\n");
+  format("{0, 0, 0, ::$proto_ns$::internal::kInvalidMask, 0, 0},\n");
   int last_field_number = 1;
 
   std::vector<const FieldDescriptor*> ordered_fields =
       SortFieldsByNumber(descriptor_);
 
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* field = ordered_fields[i];
+  for (auto field : ordered_fields) {
+    Formatter::SaveState saver(&format);
     GOOGLE_CHECK_GE(field->number(), last_field_number);
 
     for (; last_field_number < field->number(); last_field_number++) {
-      printer->Print(
-          "{ 0, 0, ::google::protobuf::internal::kInvalidMask,\n"
-          "  ::google::protobuf::internal::kInvalidMask, 0, 0 },\n");
+      format(
+          "{ 0, 0, ::$proto_ns$::internal::kInvalidMask,\n"
+          "  ::$proto_ns$::internal::kInvalidMask, 0, 0 },\n");
     }
     last_field_number++;
 
@@ -1929,30 +2077,39 @@
     processing_type = static_cast<unsigned>(field->type());
     const FieldGenerator& generator = field_generators_.get(field);
     if (field->type() == FieldDescriptor::TYPE_STRING) {
-      switch (EffectiveStringCType(field)) {
+      switch (EffectiveStringCType(field, options_)) {
         case FieldOptions::STRING:
-        default: {
           if (generator.IsInlined()) {
             processing_type = internal::TYPE_STRING_INLINED;
             break;
           }
           break;
-        }
+        case FieldOptions::CORD:
+          processing_type = internal::TYPE_STRING_CORD;
+          break;
+        case FieldOptions::STRING_PIECE:
+          processing_type = internal::TYPE_STRING_STRING_PIECE;
+          break;
       }
     } else if (field->type() == FieldDescriptor::TYPE_BYTES) {
-      switch (EffectiveStringCType(field)) {
+      switch (EffectiveStringCType(field, options_)) {
         case FieldOptions::STRING:
-        default:
           if (generator.IsInlined()) {
             processing_type = internal::TYPE_BYTES_INLINED;
             break;
           }
           break;
+        case FieldOptions::CORD:
+          processing_type = internal::TYPE_BYTES_CORD;
+          break;
+        case FieldOptions::STRING_PIECE:
+          processing_type = internal::TYPE_BYTES_STRING_PIECE;
+          break;
       }
     }
 
     processing_type |= static_cast<unsigned>(
-        field->is_repeated() ?  internal::kRepeatedMask : 0);
+        field->is_repeated() ? internal::kRepeatedMask : 0);
     processing_type |= static_cast<unsigned>(
         field->containing_oneof() ? internal::kOneofMask : 0);
 
@@ -1961,13 +2118,13 @@
     }
 
     const unsigned char tag_size =
-      WireFormat::TagSize(field->number(), field->type());
+        WireFormat::TagSize(field->number(), field->type());
 
     std::map<string, string> vars;
-    vars["classname"] = QualifiedClassName(descriptor_);
     if (field->containing_oneof() != NULL) {
       vars["name"] = field->containing_oneof()->name();
-      vars["presence"] = SimpleItoa(field->containing_oneof()->index());
+      vars["presence"] =
+          SimpleItoa(field->containing_oneof()->index());
     } else {
       vars["name"] = FieldName(field);
       vars["presence"] = SimpleItoa(has_bit_indices_[field->index()]);
@@ -1977,19 +2134,23 @@
     vars["ptype"] = SimpleItoa(processing_type);
     vars["tag_size"] = SimpleItoa(tag_size);
 
-    printer->Print(vars,
-      "{\n"
-      "  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n"
-      "    $classname$, $name$_),\n"
-      "  static_cast<::google::protobuf::uint32>($presence$),\n"
-      "  $nwtype$, $pwtype$, $ptype$, $tag_size$\n"
-      "},\n");
+    format.AddMap(vars);
+
+    format(
+        "{\n"
+        "  $GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET(\n"
+        "    $classtype$, $name$_),\n"
+        "  static_cast<$uint32$>($presence$),\n"
+        "  $nwtype$, $pwtype$, $ptype$, $tag_size$\n"
+        "},\n");
   }
 
   return last_field_number;
 }
 
 size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) {
+  Formatter format(printer, variables_);
+
   if (!table_driven_) {
     return 0;
   }
@@ -1997,74 +2158,71 @@
   std::vector<const FieldDescriptor*> ordered_fields =
       SortFieldsByNumber(descriptor_);
 
-  printer->Print("::google::protobuf::internal::AuxillaryParseTableField(),\n");
+  format("::$proto_ns$::internal::AuxillaryParseTableField(),\n");
   int last_field_number = 1;
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* field = ordered_fields[i];
+  for (auto field : ordered_fields) {
+    Formatter::SaveState saver(&format);
 
     GOOGLE_CHECK_GE(field->number(), last_field_number);
     for (; last_field_number < field->number(); last_field_number++) {
-      printer->Print("::google::protobuf::internal::AuxillaryParseTableField(),\n");
+      format("::$proto_ns$::internal::AuxillaryParseTableField(),\n");
     }
 
     std::map<string, string> vars;
     SetCommonFieldVariables(field, &vars, options_);
+    format.AddMap(vars);
 
     switch (field->cpp_type()) {
       case FieldDescriptor::CPPTYPE_ENUM:
-        vars["type"] = ClassName(field->enum_type(), true);
-        printer->Print(
-            vars,
-            "{::google::protobuf::internal::AuxillaryParseTableField::enum_aux{"
-            "$type$_IsValid}},\n");
+        format(
+            "{::$proto_ns$::internal::AuxillaryParseTableField::enum_aux{"
+            "$1$_IsValid}},\n",
+            ClassName(field->enum_type(), true));
         last_field_number++;
         break;
       case FieldDescriptor::CPPTYPE_MESSAGE: {
         if (field->is_map()) {
-          vars["classname"] = QualifiedClassName(field->message_type());
-          printer->Print(vars,
-                         "{::google::protobuf::internal::AuxillaryParseTableField::map_"
-                         "aux{&::google::protobuf::internal::ParseMap<$classname$>}},\n");
+          format(
+              "{::$proto_ns$::internal::AuxillaryParseTableField::map_"
+              "aux{&::$proto_ns$::internal::ParseMap<$1$>}},\n",
+              QualifiedClassName(field->message_type()));
           last_field_number++;
           break;
-        } else {
-          vars["classname"] = ClassName(field->message_type(), false);
         }
-        vars["ns"] = Namespace(field->message_type());
-        vars["type"] = FieldMessageTypeName(field);
-        vars["file_namespace"] =
-            FileLevelNamespace(field->message_type());
+        format.Set("field_classname", ClassName(field->message_type(), false));
+        format.Set("ns", Namespace(field->message_type()));
 
-        printer->Print(
-            vars,
-            "{::google::protobuf::internal::AuxillaryParseTableField::message_aux{\n"
-            "  &$ns$::_$classname$_default_instance_}},\n");
+        format(
+            "{::$proto_ns$::internal::AuxillaryParseTableField::message_aux{\n"
+            "  &$ns$::_$field_classname$_default_instance_}},\n");
         last_field_number++;
         break;
       }
-      case FieldDescriptor::CPPTYPE_STRING:
-        switch (EffectiveStringCType(field)) {
+      case FieldDescriptor::CPPTYPE_STRING: {
+        string default_val;
+        switch (EffectiveStringCType(field, options_)) {
           case FieldOptions::STRING:
-            vars["default"] =
-                field->default_value_string().empty()
-                    ? "&::google::protobuf::internal::fixed_address_empty_string"
-                    : "&" + Namespace(field) + " ::" + classname_ +
-                          "::" + MakeDefaultName(field);
+            default_val = field->default_value_string().empty()
+                              ? "&::" + variables_["proto_ns"] +
+                                    "::internal::fixed_address_empty_string"
+                              : "&" + Namespace(field) + " ::" + classname_ +
+                                    "::" + MakeDefaultName(field);
             break;
           case FieldOptions::CORD:
           case FieldOptions::STRING_PIECE:
-            vars["default"] =
+            default_val =
                 "\"" + CEscape(field->default_value_string()) + "\"";
             break;
         }
-        vars["full_name"] = field->full_name();
-        printer->Print(vars,
-            "{::google::protobuf::internal::AuxillaryParseTableField::string_aux{\n"
-            "  $default$,\n"
-            "  \"$full_name$\"\n"
-            "}},\n");
+        format(
+            "{::$proto_ns$::internal::AuxillaryParseTableField::string_aux{\n"
+            "  $1$,\n"
+            "  \"$2$\"\n"
+            "}},\n",
+            default_val, field->full_name());
         last_field_number++;
         break;
+      }
       default:
         break;
     }
@@ -2075,171 +2233,163 @@
 
 std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
     io::Printer* printer) {
-  std::map<string, string> variables;
-  string full_classname = QualifiedClassName(descriptor_);
-  variables["classname"] = full_classname;
+  Formatter format(printer, variables_);
 
   if (HasFieldPresence(descriptor_->file()) || IsMapEntryMessage(descriptor_)) {
-    printer->Print(
-        variables,
-        "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
+    format(
+        "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
         "_has_bits_),\n");
   } else {
-    printer->Print("~0u,  // no _has_bits_\n");
+    format("~0u,  // no _has_bits_\n");
   }
-  printer->Print(variables,
-                 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
-                 "_internal_metadata_),\n");
+  format(
+      "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
+      "_internal_metadata_),\n");
   if (descriptor_->extension_range_count() > 0) {
-    printer->Print(
-        variables,
-        "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
+    format(
+        "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
         "_extensions_),\n");
   } else {
-    printer->Print("~0u,  // no _extensions_\n");
+    format("~0u,  // no _extensions_\n");
   }
   if (descriptor_->oneof_decl_count() > 0) {
-    printer->Print(variables,
-                   "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
-                   "$classname$, _oneof_case_[0]),\n");
+    format(
+        "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET("
+        "$classtype$, _oneof_case_[0]),\n");
   } else {
-    printer->Print("~0u,  // no _oneof_case_\n");
+    format("~0u,  // no _oneof_case_\n");
   }
   if (num_weak_fields_ > 0) {
-    printer->Print(variables,
-                   "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$,"
-                   " _weak_field_map_),\n");
+    format(
+        "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$,"
+        " _weak_field_map_),\n");
   } else {
-    printer->Print("~0u,  // no _weak_field_map_\n");
+    format("~0u,  // no _weak_field_map_\n");
   }
   const int kNumGenericOffsets = 5;  // the number of fixed offsets above
-  const size_t offsets = kNumGenericOffsets +
-                         descriptor_->field_count() +
+  const size_t offsets = kNumGenericOffsets + descriptor_->field_count() +
                          descriptor_->oneof_decl_count();
   size_t entries = offsets;
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* field = descriptor_->field(i);
+  for (auto field : FieldRange(descriptor_)) {
     if (field->containing_oneof() || field->options().weak()) {
-      printer->Print("offsetof($classname$DefaultTypeInternal, $name$_)",
-                     "classname", full_classname, "name", FieldName(field));
+      format("offsetof($classtype$DefaultTypeInternal, $1$_)",
+             FieldName(field));
     } else {
-      printer->Print(
-          "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_)",
-          "classname", full_classname, "name", FieldName(field));
+      format(
+          "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, $1$_)",
+          FieldName(field));
     }
 
     uint32 tag = field_generators_.get(field).CalculateFieldTag();
     if (tag != 0) {
-      printer->Print(" | $tag$", "tag", SimpleItoa(tag));
+      format(" | $1$", tag);
     }
 
-    printer->Print(",\n");
+    format(",\n");
   }
 
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
-    printer->Print(
-        "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
-        "classname", full_classname, "name", oneof->name());
+  for (auto oneof : OneOfRange(descriptor_)) {
+    format(
+        "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, $1$_),\n",
+        oneof->name());
   }
 
   if (IsMapEntryMessage(descriptor_)) {
     entries += 2;
-    printer->Print(
+    format(
         "0,\n"
         "1,\n");
   } else if (HasFieldPresence(descriptor_->file())) {
     entries += has_bit_indices_.size();
     for (int i = 0; i < has_bit_indices_.size(); i++) {
-      const string index = has_bit_indices_[i] >= 0 ?
-        SimpleItoa(has_bit_indices_[i]) : "~0u";
-      printer->Print("$index$,\n", "index", index);
+      const string index = has_bit_indices_[i] >= 0
+                               ? SimpleItoa(has_bit_indices_[i])
+                               : "~0u";
+      format("$1$,\n", index);
     }
   }
 
   return std::make_pair(entries, offsets);
 }
 
-void MessageGenerator::
-GenerateSharedConstructorCode(io::Printer* printer) {
-  printer->Print(
-    "void $classname$::SharedCtor() {\n",
-    "classname", classname_);
-  printer->Indent();
+void MessageGenerator::GenerateSharedConstructorCode(io::Printer* printer) {
+  Formatter format(printer, variables_);
+
+  format("void $classname$::SharedCtor() {\n");
+  if (scc_analyzer_
+          ->GetSCCAnalysis(scc_analyzer_->GetSCC(descriptor_))
+          .constructor_requires_initialization) {
+    format(
+        "  ::$proto_ns$::internal::InitSCC(\n"
+        "      &scc_info_$scc_name$.base);\n");
+  }
+
+  format.Indent();
 
   std::vector<bool> processed(optimized_order_.size(), false);
   GenerateConstructorBody(printer, processed, false);
 
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    printer->Print(
-        "clear_has_$oneof_name$();\n",
-        "oneof_name", descriptor_->oneof_decl(i)->name());
+  for (auto oneof : OneOfRange(descriptor_)) {
+    format("clear_has_$1$();\n", oneof->name());
   }
 
-  printer->Outdent();
-  printer->Print("}\n\n");
+  format.Outdent();
+  format("}\n\n");
 }
 
-void MessageGenerator::
-GenerateSharedDestructorCode(io::Printer* printer) {
-  printer->Print(
-    "void $classname$::SharedDtor() {\n",
-    "classname", classname_);
-  printer->Indent();
+void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) {
+  Formatter format(printer, variables_);
+
+  format("void $classname$::SharedDtor() {\n");
+  format.Indent();
   if (SupportsArenas(descriptor_)) {
-    printer->Print(
-      "GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);\n");
+    format("$DCHK$(GetArenaNoVirtual() == NULL);\n");
   }
   // Write the destructors for each field except oneof members.
   // optimized_order_ does not contain oneof fields.
-  for (int i = 0; i < optimized_order_.size(); i++) {
-    const FieldDescriptor* field = optimized_order_[i];
+  for (auto field : optimized_order_) {
     field_generators_.get(field).GenerateDestructorCode(printer);
   }
 
   // Generate code to destruct oneofs. Clearing should do the work.
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    printer->Print(
-        "if (has_$oneof_name$()) {\n"
-        "  clear_$oneof_name$();\n"
+  for (auto oneof : OneOfRange(descriptor_)) {
+    format(
+        "if (has_$1$()) {\n"
+        "  clear_$1$();\n"
         "}\n",
-        "oneof_name", descriptor_->oneof_decl(i)->name());
+        oneof->name());
   }
 
   if (num_weak_fields_) {
-    printer->Print("_weak_field_map_.ClearAll();\n");
+    format("_weak_field_map_.ClearAll();\n");
   }
-  printer->Outdent();
-  printer->Print(
-    "}\n"
-    "\n");
+  format.Outdent();
+  format(
+      "}\n"
+      "\n");
 }
 
-void MessageGenerator::
-GenerateArenaDestructorCode(io::Printer* printer) {
+void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) {
+  Formatter format(printer, variables_);
+
   // Generate the ArenaDtor() method. Track whether any fields actually produced
   // code that needs to be called.
-  printer->Print(
-      "void $classname$::ArenaDtor(void* object) {\n",
-      "classname", classname_);
-  printer->Indent();
+  format("void $classname$::ArenaDtor(void* object) {\n");
+  format.Indent();
 
   // This code is placed inside a static method, rather than an ordinary one,
   // since that simplifies Arena's destructor list (ordinary function pointers
   // rather than member function pointers). _this is the object being
   // destructed.
-  printer->Print(
+  format(
       "$classname$* _this = reinterpret_cast< $classname$* >(object);\n"
       // avoid an "unused variable" warning in case no fields have dtor code.
-      "(void)_this;\n",
-      "classname", classname_);
+      "(void)_this;\n");
 
   bool need_registration = false;
   // Process non-oneof fields first.
-  for (int i = 0; i < optimized_order_.size(); i++) {
-    const FieldDescriptor* field = optimized_order_[i];
-    if (field_generators_.get(field)
-                         .GenerateArenaDestructorCode(printer)) {
+  for (auto field : optimized_order_) {
+    if (field_generators_.get(field).GenerateArenaDestructorCode(printer)) {
       need_registration = true;
     }
   }
@@ -2248,13 +2398,9 @@
   //
   // Note:  As of 10/5/2016, GenerateArenaDestructorCode does not emit anything
   // and returns false for oneof fields.
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
-
-    for (int j = 0; j < oneof->field_count(); j++) {
-      const FieldDescriptor* field = oneof->field(j);
-      if (field_generators_.get(field)
-                           .GenerateArenaDestructorCode(printer)) {
+  for (auto oneof : OneOfRange(descriptor_)) {
+    for (auto field : FieldRange(oneof)) {
+      if (field_generators_.get(field).GenerateArenaDestructorCode(printer)) {
         need_registration = true;
       }
     }
@@ -2262,42 +2408,40 @@
   if (num_weak_fields_) {
     // _this is the object being destructed (we are inside a static method
     // here).
-    printer->Print("_this->_weak_field_map_.ClearAll();\n");
+    format("_this->_weak_field_map_.ClearAll();\n");
     need_registration = true;
   }
 
-  printer->Outdent();
-  printer->Print(
-      "}\n");
+  format.Outdent();
+  format("}\n");
 
   if (need_registration) {
-    printer->Print(
-        "inline void $classname$::RegisterArenaDtor(::google::protobuf::Arena* arena) {\n"
+    format(
+        "inline void $classname$::RegisterArenaDtor(::$proto_ns$::Arena* "
+        "arena) {\n"
         "  if (arena != NULL) {\n"
         "    arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n"
         "  }\n"
-        "}\n",
-        "classname", classname_);
+        "}\n");
   } else {
-    printer->Print(
-        "void $classname$::RegisterArenaDtor(::google::protobuf::Arena*) {\n"
-        "}\n",
-        "classname", classname_);
+    format(
+        "void $classname$::RegisterArenaDtor(::$proto_ns$::Arena*) {\n"
+        "}\n");
   }
 }
 
 void MessageGenerator::GenerateConstructorBody(io::Printer* printer,
                                                std::vector<bool> processed,
                                                bool copy_constructor) const {
+  Formatter format(printer, variables_);
   const FieldDescriptor* last_start = NULL;
   // RunMap maps from fields that start each run to the number of fields in that
   // run.  This is optimized for the common case that there are very few runs in
   // a message and that most of the eligible fields appear together.
-  typedef hash_map<const FieldDescriptor*, size_t> RunMap;
+  typedef std::unordered_map<const FieldDescriptor*, size_t> RunMap;
   RunMap runs;
 
-  for (int i = 0; i < optimized_order_.size(); ++i) {
-    const FieldDescriptor* field = optimized_order_[i];
+  for (auto field : optimized_order_) {
     if ((copy_constructor && IsPOD(field)) ||
         (!copy_constructor && CanConstructByZeroing(field, options_))) {
       if (last_start == NULL) {
@@ -2340,9 +2484,10 @@
       const string last_field_name =
           FieldName(optimized_order_[i + run_length - 1]);
 
-      printer->Print(pod_template.c_str(),
-        "first", first_field_name,
-        "last", last_field_name);
+      format.Set("first", first_field_name);
+      format.Set("last", last_field_name);
+
+      format(pod_template.c_str());
 
       i += run_length - 1;
       // ++i at the top of the loop.
@@ -2356,8 +2501,9 @@
   }
 }
 
-void MessageGenerator::
-GenerateStructors(io::Printer* printer) {
+void MessageGenerator::GenerateStructors(io::Printer* printer) {
+  Formatter format(printer, variables_);
+
   string superclass;
   superclass = SuperClassName(descriptor_, options_);
   string initializer_with_arena = superclass + "()";
@@ -2369,13 +2515,15 @@
   initializer_with_arena += ",\n  _internal_metadata_(arena)";
 
   // Initialize member variables with arena constructor.
-  for (int i = 0; i < optimized_order_.size(); i++) {
-    const FieldDescriptor* field = optimized_order_[i];
-
+  for (auto field : optimized_order_) {
     bool has_arena_constructor = field->is_repeated();
+    if (field->containing_oneof() == NULL &&
+        (IsLazy(field, options_) || IsStringPiece(field, options_))) {
+      has_arena_constructor = true;
+    }
     if (has_arena_constructor) {
-      initializer_with_arena += string(",\n  ") +
-          FieldName(field) + string("_(arena)");
+      initializer_with_arena +=
+          string(",\n  ") + FieldName(field) + string("_(arena)");
     }
   }
 
@@ -2394,33 +2542,23 @@
     initializer_null += ", _weak_field_map_(nullptr)";
   }
 
-  printer->Print(
+  format(
       "$classname$::$classname$()\n"
-      "  : $initializer$ {\n"
-      "  ::google::protobuf::internal::InitSCC(\n"
-      "      &$file_namespace$::scc_info_$scc_name$.base);\n"
+      "  : $1$ {\n"
       "  SharedCtor();\n"
       "  // @@protoc_insertion_point(constructor:$full_name$)\n"
       "}\n",
-      "classname", classname_, "full_name", descriptor_->full_name(),
-      "scc_name", scc_name_, "initializer", initializer_null, "file_namespace",
-      FileLevelNamespace(descriptor_));
+      initializer_null);
 
   if (SupportsArenas(descriptor_)) {
-    printer->Print(
-        "$classname$::$classname$(::google::protobuf::Arena* arena)\n"
-        "  : $initializer$ {\n"
-        "  "
-        "::google::protobuf::internal::InitSCC(&$file_namespace$::scc_info_$scc_name$."
-        "base);\n"
+    format(
+        "$classname$::$classname$(::$proto_ns$::Arena* arena)\n"
+        "  : $1$ {\n"
         "  SharedCtor();\n"
         "  RegisterArenaDtor(arena);\n"
         "  // @@protoc_insertion_point(arena_constructor:$full_name$)\n"
         "}\n",
-        "initializer", initializer_with_arena, "classname", classname_,
-        "superclass", superclass, "full_name", descriptor_->full_name(),
-        "scc_name", scc_name_, "file_namespace",
-        FileLevelNamespace(descriptor_));
+        initializer_with_arena);
   }
 
   // Generate the copy constructor.
@@ -2429,117 +2567,98 @@
     // one-liner copy constructor that delegates to MergeFrom. This saves some
     // code size and also cuts down on the complexity of implicit weak fields.
     // We might eventually want to do this for all lite protos.
-    printer->Print(
-      "$classname$::$classname$(const $classname$& from)\n"
-      "  : $classname$() {\n"
-      "  MergeFrom(from);\n"
-      "}\n",
-      "classname", classname_);
+    format(
+        "$classname$::$classname$(const $classname$& from)\n"
+        "  : $classname$() {\n"
+        "  MergeFrom(from);\n"
+        "}\n");
   } else {
-    printer->Print(
-      "$classname$::$classname$(const $classname$& from)\n"
-      "  : $superclass$()",
-      "classname", classname_,
-      "superclass", superclass,
-      "full_name", descriptor_->full_name());
-    printer->Indent();
-    printer->Indent();
-    printer->Indent();
-
-    printer->Print(
-        ",\n_internal_metadata_(NULL)");
+    format(
+        "$classname$::$classname$(const $classname$& from)\n"
+        "  : $superclass$()");
+    format.Indent();
+    format.Indent();
+    format.Indent();
+    format(",\n_internal_metadata_(NULL)");
 
     if (HasFieldPresence(descriptor_->file())) {
-        printer->Print(",\n_has_bits_(from._has_bits_)");
+      if (!IsProto2MessageSet(descriptor_, options_)) {
+        format(",\n_has_bits_(from._has_bits_)");
+      }
     }
 
     std::vector<bool> processed(optimized_order_.size(), false);
-    for (int i = 0; i < optimized_order_.size(); ++i) {
-      const FieldDescriptor* field = optimized_order_[i];
-
-      if (!(field->is_repeated() && !(field->is_map()))
-          ) {
+    for (int i = 0; i < optimized_order_.size(); i++) {
+      auto field = optimized_order_[i];
+      if (!(field->is_repeated() && !(field->is_map())) &&
+          !IsCord(field, options_)) {
         continue;
       }
 
       processed[i] = true;
-      printer->Print(",\n$name$_(from.$name$_)",
-                     "name", FieldName(field));
+      format(",\n$1$_(from.$1$_)", FieldName(field));
     }
 
     if (IsAnyMessage(descriptor_)) {
-      printer->Print(",\n_any_metadata_(&type_url_, &value_)");
+      format(",\n_any_metadata_(&type_url_, &value_)");
     }
     if (num_weak_fields_ > 0) {
-      printer->Print(",\n_weak_field_map_(from._weak_field_map_)");
+      format(",\n_weak_field_map_(from._weak_field_map_)");
     }
 
-    printer->Outdent();
-    printer->Outdent();
-    printer->Print(" {\n");
+    format.Outdent();
+    format.Outdent();
+    format(" {\n");
 
-    printer->Print(
-        "_internal_metadata_.MergeFrom(from._internal_metadata_);\n");
+    format("_internal_metadata_.MergeFrom(from._internal_metadata_);\n");
 
     if (descriptor_->extension_range_count() > 0) {
-      printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
+      format("_extensions_.MergeFrom(from._extensions_);\n");
     }
 
     GenerateConstructorBody(printer, processed, true);
 
     // Copy oneof fields. Oneof field requires oneof case check.
-    for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
-      printer->Print(
-          "clear_has_$oneofname$();\n"
-          "switch (from.$oneofname$_case()) {\n",
-          "oneofname", descriptor_->oneof_decl(i)->name());
-      printer->Indent();
-      for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
-        const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
-        printer->Print(
-            "case k$field_name$: {\n",
-            "field_name", UnderscoresToCamelCase(field->name(), true));
-        printer->Indent();
+    for (auto oneof : OneOfRange(descriptor_)) {
+      format(
+          "clear_has_$1$();\n"
+          "switch (from.$1$_case()) {\n",
+          oneof->name());
+      format.Indent();
+      for (auto field : FieldRange(oneof)) {
+        format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
+        format.Indent();
         field_generators_.get(field).GenerateMergingCode(printer);
-        printer->Print(
-            "break;\n");
-        printer->Outdent();
-        printer->Print(
-            "}\n");
+        format("break;\n");
+        format.Outdent();
+        format("}\n");
       }
-      printer->Print(
-          "case $cap_oneof_name$_NOT_SET: {\n"
+      format(
+          "case $1$_NOT_SET: {\n"
           "  break;\n"
           "}\n",
-          "oneof_index",
-          SimpleItoa(descriptor_->oneof_decl(i)->index()),
-          "cap_oneof_name",
-          ToUpper(descriptor_->oneof_decl(i)->name()));
-      printer->Outdent();
-      printer->Print(
-          "}\n");
+          ToUpper(oneof->name()));
+      format.Outdent();
+      format("}\n");
     }
 
-    printer->Outdent();
-    printer->Print(
-      "  // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
-      "}\n"
-      "\n",
-      "full_name", descriptor_->full_name());
+    format.Outdent();
+    format(
+        "  // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
+        "}\n"
+        "\n");
   }
 
   // Generate the shared constructor code.
   GenerateSharedConstructorCode(printer);
 
   // Generate the destructor.
-  printer->Print(
-    "$classname$::~$classname$() {\n"
-    "  // @@protoc_insertion_point(destructor:$full_name$)\n"
-    "  SharedDtor();\n"
-    "}\n"
-    "\n",
-    "classname", classname_,
-    "full_name", descriptor_->full_name());
+  format(
+      "$classname$::~$classname$() {\n"
+      "  // @@protoc_insertion_point(destructor:$full_name$)\n"
+      "  SharedDtor();\n"
+      "}\n"
+      "\n");
 
   // Generate the shared destructor code.
   GenerateSharedDestructorCode(printer);
@@ -2550,90 +2669,60 @@
   }
 
   // Generate SetCachedSize.
-  printer->Print(
+  format(
       "void $classname$::SetCachedSize(int size) const {\n"
       "  _cached_size_.Set(size);\n"
-      "}\n",
-      "classname", classname_);
+      "}\n");
 
-  // Only generate this member if it's not disabled.
-  if (HasDescriptorMethods(descriptor_->file(), options_) &&
-      !descriptor_->options().no_standard_descriptor_accessor()) {
-    printer->Print(
-        "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
-        "  ::$file_namespace$::protobuf_AssignDescriptorsOnce();\n"
-        "  return ::"
-        "$file_namespace$::file_level_metadata[kIndexInFileMessages]."
-        "descriptor;\n"
-        "}\n"
-        "\n",
-        "classname", classname_, "file_namespace",
-        FileLevelNamespace(descriptor_));
-  }
-
-  printer->Print(
+  format(
       "const $classname$& $classname$::default_instance() {\n"
       "  "
-      "::google::protobuf::internal::InitSCC(&$file_namespace$::scc_info_$scc_name$.base)"
+      "::$proto_ns$::internal::InitSCC(&::scc_info_$scc_name$.base)"
       ";\n"
       "  return *internal_default_instance();\n"
-      "}\n\n",
-      "classname", classname_, "scc_name", scc_name_, "file_namespace",
-      FileLevelNamespace(descriptor_));
+      "}\n\n");
 }
 
 void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) {
-  printer->Print(
+  Formatter format(printer, variables_);
+  format(
       "template<> "
-      "GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE "
-      "$classname$* Arena::CreateMaybeMessage< $classname$ >(Arena* arena) {\n"
-      "  return Arena::$create_func$Internal< $classname$ >(arena);\n"
+      "$GOOGLE_PROTOBUF$_ATTRIBUTE_NOINLINE "
+      "$classtype$* Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n"
+      "  return Arena::$1$Internal< $classtype$ >(arena);\n"
       "}\n",
-      "classname", QualifiedClassName(descriptor_),
-      "create_func", MessageCreateFunction(descriptor_));
-}
-
-// Return the number of bits set in n, a non-negative integer.
-static int popcnt(uint32 n) {
-  int result = 0;
-  while (n != 0) {
-    result += (n & 1);
-    n = n / 2;
-  }
-  return result;
+      MessageCreateFunction(descriptor_));
 }
 
 bool MessageGenerator::MaybeGenerateOptionalFieldCondition(
     io::Printer* printer, const FieldDescriptor* field,
     int expected_has_bits_index) {
+  Formatter format(printer, variables_);
   int has_bit_index = has_bit_indices_[field->index()];
   if (!field->options().weak() &&
       expected_has_bits_index == has_bit_index / 32) {
     const string mask =
         StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
-    printer->Print(
-        "if (cached_has_bits & 0x$mask$u) {\n",
-        "mask", mask);
+    format("if (cached_has_bits & 0x$1$u) {\n", mask);
     return true;
   }
   return false;
 }
 
-void MessageGenerator::
-GenerateClear(io::Printer* printer) {
+void MessageGenerator::GenerateClear(io::Printer* printer) {
+  Formatter format(printer, variables_);
   // Performance tuning parameters
   const int kMaxUnconditionalPrimitiveBytesClear = 4;
 
-  printer->Print(
+  format(
       "void $classname$::Clear() {\n"
-      "// @@protoc_insertion_point(message_clear_start:$full_name$)\n",
-      "classname", classname_, "full_name", descriptor_->full_name());
-  printer->Indent();
+      "// @@protoc_insertion_point(message_clear_start:$full_name$)\n");
+  format.Indent();
 
-  printer->Print(
+  format(
       // TODO(jwb): It would be better to avoid emitting this if it is not used,
       // rather than emitting a workaround for the resulting warning.
-      "::google::protobuf::uint32 cached_has_bits = 0;\n"
+      "$uint32$ cached_has_bits = 0;\n"
       "// Prevent compiler warnings about cached_has_bits being unused\n"
       "(void) cached_has_bits;\n\n");
 
@@ -2641,7 +2730,7 @@
 
   // Step 1: Extensions
   if (descriptor_->extension_range_count() > 0) {
-    printer->Print("_extensions_.Clear();\n");
+    format("_extensions_.Clear();\n");
   }
 
   int unconditional_budget = kMaxUnconditionalPrimitiveBytesClear;
@@ -2687,6 +2776,8 @@
     }
   }
 
+  ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio,
+                                HasFieldPresence(descriptor_->file()));
   for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
     std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index];
     GOOGLE_CHECK(!chunk.empty());
@@ -2703,6 +2794,8 @@
       continue;
     }
 
+    cold_skipper.OnStartChunk(chunk_index, cached_has_bit_index, "", printer);
+
     // Step 3: Non-repeated fields that can be cleared by memset-to-0, then
     // non-repeated, non-zero initializable fields.
     int last_chunk = HasFieldPresence(descriptor_->file())
@@ -2738,12 +2831,11 @@
 
       if (cached_has_bit_index != last_chunk / 4) {
         cached_has_bit_index = last_chunk / 4;
-        printer->Print("cached_has_bits = _has_bits_[$idx$];\n", "idx",
-                       SimpleItoa(cached_has_bit_index));
+        format("cached_has_bits = _has_bits_[$1$];\n", cached_has_bit_index);
       }
-      printer->Print("if (cached_has_bits & $mask$u) {\n", "mask",
-                     SimpleItoa(last_chunk_mask));
-      printer->Indent();
+      format("if (cached_has_bits & 0x$1$u) {\n",
+             StrCat(strings::Hex(last_chunk_mask, strings::ZERO_PAD_8)));
+      format.Indent();
     }
 
     if (memset_run_start != -1) {
@@ -2756,11 +2848,11 @@
         const string first_field_name = FieldName(chunk[memset_run_start]);
         const string last_field_name = FieldName(chunk[memset_run_end]);
 
-        printer->Print(
-            "::memset(&$first$_, 0, static_cast<size_t>(\n"
-            "    reinterpret_cast<char*>(&$last$_) -\n"
-            "    reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n",
-            "first", first_field_name, "last", last_field_name);
+        format(
+            "::memset(&$1$_, 0, static_cast<size_t>(\n"
+            "    reinterpret_cast<char*>(&$2$_) -\n"
+            "    reinterpret_cast<char*>(&$1$_)) + sizeof($2$_));\n",
+            first_field_name, last_field_name);
       }
 
       // Advance last_chunk_start to skip over the fields we zeroed/memset.
@@ -2770,7 +2862,6 @@
     // Go back and emit clears for each of the fields we processed.
     for (int j = last_chunk_start; j < chunk.size(); j++) {
       const FieldDescriptor* field = chunk[j];
-      const string fieldname = FieldName(field);
       const FieldGenerator& generator = field_generators_.get(field);
 
       // It's faster to just overwrite primitive types, but we should only
@@ -2785,121 +2876,101 @@
       if (should_check_bit &&
           // If no field presence, then always clear strings/messages as well.
           HasFieldPresence(descriptor_->file())) {
-        if (!field->options().weak() &&
-            cached_has_bit_index != (has_bit_indices_[field->index()] / 32)) {
-          cached_has_bit_index = (has_bit_indices_[field->index()] / 32);
-          printer->Print("cached_has_bits = _has_bits_[$new_index$];\n",
-                         "new_index", SimpleItoa(cached_has_bit_index));
-        }
-        if (!MaybeGenerateOptionalFieldCondition(printer, field,
-                                                 cached_has_bit_index)) {
-          printer->Print("if (has_$name$()) {\n", "name", fieldname);
-        }
-        printer->Indent();
+        PrintPresenceCheck(format, field, has_bit_indices_, printer,
+                           &cached_has_bit_index);
         have_enclosing_if = true;
       }
 
       generator.GenerateMessageClearingCode(printer);
 
       if (have_enclosing_if) {
-        printer->Outdent();
-        printer->Print("}\n");
+        format.Outdent();
+        format("}\n");
       }
     }
 
     if (have_outer_if) {
-      printer->Outdent();
-      printer->Print("}\n");
+      format.Outdent();
+      format("}\n");
+    }
+
+    if (cold_skipper.OnEndChunk(chunk_index, printer)) {
+      // Reset here as it may have been updated in just closed if statement.
+      cached_has_bit_index = -1;
     }
   }
 
   // Step 4: Unions.
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    printer->Print(
-        "clear_$oneof_name$();\n",
-        "oneof_name", descriptor_->oneof_decl(i)->name());
+  for (auto oneof : OneOfRange(descriptor_)) {
+    format("clear_$1$();\n", oneof->name());
   }
 
   if (num_weak_fields_) {
-    printer->Print("_weak_field_map_.ClearAll();\n");
+    format("_weak_field_map_.ClearAll();\n");
   }
 
   if (HasFieldPresence(descriptor_->file())) {
     // Step 5: Everything else.
-    printer->Print("_has_bits_.Clear();\n");
+    format("_has_bits_.Clear();\n");
   }
 
-  printer->Print("_internal_metadata_.Clear();\n");
+  format("_internal_metadata_.Clear();\n");
 
-  printer->Outdent();
-  printer->Print("}\n");
+  format.Outdent();
+  format("}\n");
 }
 
-void MessageGenerator::
-GenerateOneofClear(io::Printer* printer) {
+void MessageGenerator::GenerateOneofClear(io::Printer* printer) {
   // Generated function clears the active field and union case (e.g. foo_case_).
   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    std::map<string, string> oneof_vars;
-    oneof_vars["classname"] = classname_;
-    oneof_vars["oneofname"] = descriptor_->oneof_decl(i)->name();
-    oneof_vars["full_name"] = descriptor_->full_name();
-    string message_class;
+    auto oneof = descriptor_->oneof_decl(i);
+    Formatter format(printer, variables_);
+    format.Set("oneofname", oneof->name());
 
-    printer->Print(oneof_vars,
-                   "void $classname$::clear_$oneofname$() {\n"
-                   "// @@protoc_insertion_point(one_of_clear_start:"
-                   "$full_name$)\n");
-    printer->Indent();
-    printer->Print(oneof_vars,
-        "switch ($oneofname$_case()) {\n");
-    printer->Indent();
-    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
-      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
-      printer->Print(
-          "case k$field_name$: {\n",
-          "field_name", UnderscoresToCamelCase(field->name(), true));
-      printer->Indent();
+    format(
+        "void $classname$::clear_$oneofname$() {\n"
+        "// @@protoc_insertion_point(one_of_clear_start:$full_name$)\n");
+    format.Indent();
+    format("switch ($oneofname$_case()) {\n");
+    format.Indent();
+    for (auto field : FieldRange(oneof)) {
+      format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
+      format.Indent();
       // We clear only allocated objects in oneofs
       if (!IsStringOrMessage(field)) {
-        printer->Print(
-            "// No need to clear\n");
+        format("// No need to clear\n");
       } else {
         field_generators_.get(field).GenerateClearingCode(printer);
       }
-      printer->Print(
-          "break;\n");
-      printer->Outdent();
-      printer->Print(
-          "}\n");
+      format("break;\n");
+      format.Outdent();
+      format("}\n");
     }
-    printer->Print(
-        "case $cap_oneof_name$_NOT_SET: {\n"
+    format(
+        "case $1$_NOT_SET: {\n"
         "  break;\n"
         "}\n",
-        "cap_oneof_name",
-        ToUpper(descriptor_->oneof_decl(i)->name()));
-    printer->Outdent();
-    printer->Print(
+        ToUpper(oneof->name()));
+    format.Outdent();
+    format(
         "}\n"
-        "_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n",
-        "oneof_index", SimpleItoa(i),
-        "cap_oneof_name",
-        ToUpper(descriptor_->oneof_decl(i)->name()));
-    printer->Outdent();
-    printer->Print(
+        "_oneof_case_[$1$] = $2$_NOT_SET;\n",
+        i, ToUpper(oneof->name()));
+    format.Outdent();
+    format(
         "}\n"
         "\n");
   }
 }
 
-void MessageGenerator::
-GenerateSwap(io::Printer* printer) {
+void MessageGenerator::GenerateSwap(io::Printer* printer) {
+  Formatter format(printer, variables_);
   if (SupportsArenas(descriptor_)) {
     // Generate the Swap member function. This is a lightweight wrapper around
     // UnsafeArenaSwap() / MergeFrom() with temporaries, depending on the memory
     // ownership situation: swapping across arenas or between an arena and a
     // heap requires copying.
-    printer->Print(
+    format(
         "void $classname$::Swap($classname$* other) {\n"
         "  if (other == this) return;\n"
         "  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {\n"
@@ -2916,26 +2987,35 @@
         "}\n"
         "void $classname$::UnsafeArenaSwap($classname$* other) {\n"
         "  if (other == this) return;\n"
-        "  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());\n"
+        "  $DCHK$(GetArenaNoVirtual() == other->GetArenaNoVirtual());\n"
         "  InternalSwap(other);\n"
-        "}\n",
-        "classname", classname_);
+        "}\n");
   } else {
-    printer->Print(
+    format(
         "void $classname$::Swap($classname$* other) {\n"
         "  if (other == this) return;\n"
         "  InternalSwap(other);\n"
-        "}\n",
-        "classname", classname_);
+        "}\n");
   }
 
   // Generate the UnsafeArenaSwap member function.
-  printer->Print("void $classname$::InternalSwap($classname$* other) {\n",
-                 "classname", classname_);
-  printer->Indent();
-  printer->Print("using std::swap;\n");
+  format("void $classname$::InternalSwap($classname$* other) {\n");
+  format.Indent();
+  format("using std::swap;\n");
 
   if (HasGeneratedMethods(descriptor_->file(), options_)) {
+    if (descriptor_->extension_range_count() > 0) {
+      format("_extensions_.Swap(&other->_extensions_);\n");
+    }
+
+    format("_internal_metadata_.Swap(&other->_internal_metadata_);\n");
+
+    if (HasFieldPresence(descriptor_->file())) {
+      for (int i = 0; i < HasBitsSize() / 4; ++i) {
+        format("swap(_has_bits_[$1$], other->_has_bits_[$1$]);\n", i);
+      }
+    }
+
     for (int i = 0; i < optimized_order_.size(); i++) {
       // optimized_order_ does not contain oneof fields, but the field
       // generators for these fields do not emit swapping code on their own.
@@ -2943,163 +3023,125 @@
       field_generators_.get(field).GenerateSwappingCode(printer);
     }
 
+    for (auto oneof : OneOfRange(descriptor_)) {
+      format("swap($1$_, other->$1$_);\n", oneof->name());
+    }
+
     for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-      printer->Print(
-        "swap($oneof_name$_, other->$oneof_name$_);\n"
-        "swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n",
-        "oneof_name", descriptor_->oneof_decl(i)->name(),
-        "i", SimpleItoa(i));
+      format(
+          "swap(_oneof_case_[$1$], other->_oneof_case_[$1$]);\n", i);
     }
 
-    if (HasFieldPresence(descriptor_->file())) {
-      for (int i = 0; i < HasBitsSize() / 4; ++i) {
-        printer->Print("swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
-                       "i", SimpleItoa(i));
-      }
-    }
-
-    printer->Print("_internal_metadata_.Swap(&other->_internal_metadata_);\n");
-
-    if (descriptor_->extension_range_count() > 0) {
-      printer->Print("_extensions_.Swap(&other->_extensions_);\n");
-    }
     if (num_weak_fields_) {
-      printer->Print(
-          "_weak_field_map_.UnsafeArenaSwap(&other->_weak_field_map_);\n");
+      format("_weak_field_map_.UnsafeArenaSwap(&other->_weak_field_map_);\n");
     }
   } else {
-    printer->Print("GetReflection()->Swap(this, other);");
+    format("GetReflection()->Swap(this, other);");
   }
 
-  printer->Outdent();
-  printer->Print("}\n");
+  format.Outdent();
+  format("}\n");
 }
 
-void MessageGenerator::
-GenerateMergeFrom(io::Printer* printer) {
+void MessageGenerator::GenerateMergeFrom(io::Printer* printer) {
+  Formatter format(printer, variables_);
   if (HasDescriptorMethods(descriptor_->file(), options_)) {
     // Generate the generalized MergeFrom (aka that which takes in the Message
     // base class as a parameter).
-    printer->Print(
-        "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
+    format(
+        "void $classname$::MergeFrom(const ::$proto_ns$::Message& from) {\n"
         "// @@protoc_insertion_point(generalized_merge_from_start:"
         "$full_name$)\n"
-        "  GOOGLE_DCHECK_NE(&from, this);\n",
-        "classname", classname_, "full_name", descriptor_->full_name());
-    printer->Indent();
+        "  $DCHK$_NE(&from, this);\n");
+    format.Indent();
 
     // Cast the message to the proper type. If we find that the message is
     // *not* of the proper type, we can still call Merge via the reflection
     // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
     // for each message.
-    printer->Print(
-      "const $classname$* source =\n"
-      "    ::google::protobuf::internal::DynamicCastToGenerated<const $classname$>(\n"
-      "        &from);\n"
-      "if (source == NULL) {\n"
-      "// @@protoc_insertion_point(generalized_merge_from_cast_fail:"
-      "$full_name$)\n"
-      "  ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
-      "} else {\n"
-      "// @@protoc_insertion_point(generalized_merge_from_cast_success:"
-      "$full_name$)\n"
-      "  MergeFrom(*source);\n"
-      "}\n",
-      "classname", classname_, "full_name", descriptor_->full_name());
+    format(
+        "const $classname$* source =\n"
+        "    ::$proto_ns$::DynamicCastToGenerated<$classname$>(\n"
+        "        &from);\n"
+        "if (source == NULL) {\n"
+        "// @@protoc_insertion_point(generalized_merge_from_cast_fail:"
+        "$full_name$)\n"
+        "  ::$proto_ns$::internal::ReflectionOps::Merge(from, this);\n"
+        "} else {\n"
+        "// @@protoc_insertion_point(generalized_merge_from_cast_success:"
+        "$full_name$)\n"
+        "  MergeFrom(*source);\n"
+        "}\n");
 
-    printer->Outdent();
-    printer->Print("}\n\n");
+    format.Outdent();
+    format("}\n\n");
   } else {
     // Generate CheckTypeAndMergeFrom().
-    printer->Print(
-      "void $classname$::CheckTypeAndMergeFrom(\n"
-      "    const ::google::protobuf::MessageLite& from) {\n"
-      "  MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
-      "}\n"
-      "\n",
-      "classname", classname_);
+    format(
+        "void $classname$::CheckTypeAndMergeFrom(\n"
+        "    const ::$proto_ns$::MessageLite& from) {\n"
+        "  MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
+        "}\n"
+        "\n");
   }
 
   // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
-  printer->Print(
+  format(
       "void $classname$::MergeFrom(const $classname$& from) {\n"
       "// @@protoc_insertion_point(class_specific_merge_from_start:"
       "$full_name$)\n"
-      "  GOOGLE_DCHECK_NE(&from, this);\n",
-      "classname", classname_, "full_name", descriptor_->full_name());
-  printer->Indent();
+      "  $DCHK$_NE(&from, this);\n");
+  format.Indent();
 
   if (descriptor_->extension_range_count() > 0) {
-    printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
+    format("_extensions_.MergeFrom(from._extensions_);\n");
   }
 
-  printer->Print(
-    "_internal_metadata_.MergeFrom(from._internal_metadata_);\n"
-    "::google::protobuf::uint32 cached_has_bits = 0;\n"
-    "(void) cached_has_bits;\n\n");
+  format(
+      "_internal_metadata_.MergeFrom(from._internal_metadata_);\n"
+      "$uint32$ cached_has_bits = 0;\n"
+      "(void) cached_has_bits;\n\n");
 
-  // cached_has_bit_index maintains that:
-  //   cached_has_bits = from._has_bits_[cached_has_bit_index]
-  // for cached_has_bit_index >= 0
-  int cached_has_bit_index = -1;
+  if (HasFieldPresence(descriptor_->file())) {
+    std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields(
+        optimized_order_, MatchRepeatedAndHasByte(&has_bit_indices_, true));
 
-  int last_i = -1;
-  for (int i = 0; i < optimized_order_.size(); ) {
-    // Detect infinite loops.
-    GOOGLE_CHECK_NE(i, last_i);
-    last_i = i;
+    ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_,
+                                  kColdRatio, true);
 
-    // Merge Repeated fields. These fields do not require a
-    // check as we can simply iterate over them.
-    for (; i < optimized_order_.size(); i++) {
-      const FieldDescriptor* field = optimized_order_[i];
-      if (!field->is_repeated()) {
-        break;
+    // cached_has_bit_index maintains that:
+    //   cached_has_bits = from._has_bits_[cached_has_bit_index]
+    // for cached_has_bit_index >= 0
+    int cached_has_bit_index = -1;
+
+    for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
+      const std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index];
+      GOOGLE_CHECK(!chunk.empty());
+
+      // Merge Repeated fields. These fields do not require a
+      // check as we can simply iterate over them.
+      if (chunk.front()->is_repeated()) {
+        for (int i = 0; i < chunk.size(); i++) {
+          const FieldDescriptor* field = chunk[i];
+
+          const FieldGenerator& generator = field_generators_.get(field);
+          generator.GenerateMergingCode(printer);
+        }
+        continue;
       }
 
-      const FieldGenerator& generator = field_generators_.get(field);
-      generator.GenerateMergingCode(printer);
-    }
+      // Merge Optional and Required fields (after a _has_bit_ check).
+      cold_skipper.OnStartChunk(chunk_index, cached_has_bit_index, "from.",
+                                printer);
 
-    // Merge Optional and Required fields (after a _has_bit_ check).
-    int last_chunk = -1;
-    int last_chunk_start = -1;
-    int last_chunk_end = -1;
-    uint32 last_chunk_mask = 0;
-    for (; i < optimized_order_.size(); i++) {
-      const FieldDescriptor* field = optimized_order_[i];
-      if (field->is_repeated()) {
-        break;
-      }
+      int last_chunk = has_bit_indices_[chunk.front()->index()] / 8;
+      GOOGLE_DCHECK_NE(-1, last_chunk);
 
-      // "index" defines where in the _has_bits_ the field appears.
-      // "i" is our loop counter within optimized_order_.
-      int index = HasFieldPresence(descriptor_->file()) ?
-          has_bit_indices_[field->index()] : 0;
-      int chunk = index / 8;
-
-      if (last_chunk == -1) {
-        last_chunk = chunk;
-        last_chunk_start = i;
-      } else if (chunk != last_chunk) {
-        // Emit the fields for this chunk so far.
-        break;
-      }
-
-      last_chunk_end = i;
-      last_chunk_mask |= static_cast<uint32>(1) << (index % 32);
-    }
-
-    if (last_chunk != -1) {
-      GOOGLE_DCHECK_NE(-1, last_chunk_start);
-      GOOGLE_DCHECK_NE(-1, last_chunk_end);
-      GOOGLE_DCHECK_NE(0, last_chunk_mask);
-
-      const int count = popcnt(last_chunk_mask);
-      const bool have_outer_if = HasFieldPresence(descriptor_->file()) &&
-          (last_chunk_start != last_chunk_end);
-
+      const bool have_outer_if = chunk.size() > 1;
       if (have_outer_if) {
+        uint32 last_chunk_mask = GenChunkMask(chunk, has_bit_indices_);
+        const int count = popcnt(last_chunk_mask);
+
         // Check (up to) 8 has_bits at a time if we have more than one field in
         // this chunk.  Due to field layout ordering, we may check
         // _has_bits_[last_chunk * 8 / 32] multiple times.
@@ -3107,50 +3149,32 @@
         GOOGLE_DCHECK_GE(8, count);
 
         if (cached_has_bit_index != last_chunk / 4) {
-          int new_index = last_chunk / 4;
-          printer->Print("cached_has_bits = from._has_bits_[$new_index$];\n",
-                         "new_index", SimpleItoa(new_index));
-          cached_has_bit_index = new_index;
+          cached_has_bit_index = last_chunk / 4;
+          format("cached_has_bits = from._has_bits_[$1$];\n",
+                 cached_has_bit_index);
         }
-
-        printer->Print(
-          "if (cached_has_bits & $mask$u) {\n",
-          "mask", SimpleItoa(last_chunk_mask));
-        printer->Indent();
+        format("if (cached_has_bits & 0x$1$u) {\n",
+               StrCat(strings::Hex(last_chunk_mask, strings::ZERO_PAD_8)));
+        format.Indent();
       }
 
-      // Go back and emit clears for each of the fields we processed.
+      // Go back and emit merging code for each of the fields we processed.
       bool deferred_has_bit_changes = false;
-      for (int j = last_chunk_start; j <= last_chunk_end; j++) {
-        const FieldDescriptor* field = optimized_order_[j];
+      for (const auto field : chunk) {
         const FieldGenerator& generator = field_generators_.get(field);
 
-        bool have_enclosing_if = false;
-        if (HasFieldPresence(descriptor_->file())) {
-          // Attempt to use the state of cached_has_bits, if possible.
-          int has_bit_index = has_bit_indices_[field->index()];
-          if (!field->options().weak() &&
-              cached_has_bit_index == has_bit_index / 32) {
-            const string mask = StrCat(
-                strings::Hex(1u << (has_bit_index % 32),
-                strings::ZERO_PAD_8));
+        // Attempt to use the state of cached_has_bits, if possible.
+        int has_bit_index = has_bit_indices_[field->index()];
+        if (!field->options().weak() &&
+            cached_has_bit_index == has_bit_index / 32) {
+          const string mask = StrCat(
+              strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
 
-            printer->Print(
-                "if (cached_has_bits & 0x$mask$u) {\n", "mask", mask);
-          } else {
-            printer->Print(
-              "if (from.has_$name$()) {\n",
-              "name", FieldName(field));
-          }
-
-          printer->Indent();
-          have_enclosing_if = true;
+          format("if (cached_has_bits & 0x$1$u) {\n", mask);
         } else {
-          // Merge semantics without true field presence: primitive fields are
-          // merged only if non-zero (numeric) or non-empty (string).
-          have_enclosing_if = EmitFieldNonDefaultCondition(
-              printer, "from.", field);
+          format("if (from.has_$1$()) {\n", FieldName(field));
         }
+        format.Indent();
 
         if (have_outer_if && IsPOD(field)) {
           // GenerateCopyConstructorCode for enum and primitive scalar fields
@@ -3164,181 +3188,233 @@
           generator.GenerateMergingCode(printer);
         }
 
-        if (have_enclosing_if) {
-          printer->Outdent();
-          printer->Print("}\n");
-        }
+        format.Outdent();
+        format("}\n");
       }
 
       if (have_outer_if) {
         if (deferred_has_bit_changes) {
           // Flush the has bits for the primitives we deferred.
           GOOGLE_CHECK_LE(0, cached_has_bit_index);
-          printer->Print(
-              "_has_bits_[$index$] |= cached_has_bits;\n",
-              "index", SimpleItoa(cached_has_bit_index));
+          format("_has_bits_[$1$] |= cached_has_bits;\n", cached_has_bit_index);
         }
 
-        printer->Outdent();
-        printer->Print("}\n");
+        format.Outdent();
+        format("}\n");
+      }
+
+      if (cold_skipper.OnEndChunk(chunk_index, printer)) {
+        // Reset here as it may have been updated in just closed if statement.
+        cached_has_bit_index = -1;
+      }
+    }
+  } else {
+    // proto3
+    for (const auto field : optimized_order_) {
+      const FieldGenerator& generator = field_generators_.get(field);
+      // Merge semantics without true field presence: primitive fields are
+      // merged only if non-zero (numeric) or non-empty (string).
+      bool have_enclosing_if =
+          EmitFieldNonDefaultCondition(printer, "from.", field);
+
+      generator.GenerateMergingCode(printer);
+
+      if (have_enclosing_if) {
+        format.Outdent();
+        format("}\n");
       }
     }
   }
 
   // Merge oneof fields. Oneof field requires oneof case check.
-  for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
-    printer->Print(
-        "switch (from.$oneofname$_case()) {\n",
-        "oneofname", descriptor_->oneof_decl(i)->name());
-    printer->Indent();
-    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
-      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
-      printer->Print(
-          "case k$field_name$: {\n",
-          "field_name", UnderscoresToCamelCase(field->name(), true));
-      printer->Indent();
+  for (auto oneof : OneOfRange(descriptor_)) {
+    format("switch (from.$1$_case()) {\n", oneof->name());
+    format.Indent();
+    for (auto field : FieldRange(oneof)) {
+      format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
+      format.Indent();
       field_generators_.get(field).GenerateMergingCode(printer);
-      printer->Print(
-          "break;\n");
-      printer->Outdent();
-      printer->Print(
-          "}\n");
+      format("break;\n");
+      format.Outdent();
+      format("}\n");
     }
-    printer->Print(
-        "case $cap_oneof_name$_NOT_SET: {\n"
+    format(
+        "case $1$_NOT_SET: {\n"
         "  break;\n"
         "}\n",
-        "cap_oneof_name",
-        ToUpper(descriptor_->oneof_decl(i)->name()));
-    printer->Outdent();
-    printer->Print(
-        "}\n");
+        ToUpper(oneof->name()));
+    format.Outdent();
+    format("}\n");
   }
   if (num_weak_fields_) {
-    printer->Print("_weak_field_map_.MergeFrom(from._weak_field_map_);\n");
+    format("_weak_field_map_.MergeFrom(from._weak_field_map_);\n");
   }
 
-  printer->Outdent();
-  printer->Print("}\n");
+  format.Outdent();
+  format("}\n");
 }
 
-void MessageGenerator::
-GenerateCopyFrom(io::Printer* printer) {
+void MessageGenerator::GenerateCopyFrom(io::Printer* printer) {
+  Formatter format(printer, variables_);
   if (HasDescriptorMethods(descriptor_->file(), options_)) {
     // Generate the generalized CopyFrom (aka that which takes in the Message
     // base class as a parameter).
-    printer->Print(
-        "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n"
+    format(
+        "void $classname$::CopyFrom(const ::$proto_ns$::Message& from) {\n"
         "// @@protoc_insertion_point(generalized_copy_from_start:"
-        "$full_name$)\n",
-        "classname", classname_, "full_name", descriptor_->full_name());
-    printer->Indent();
+        "$full_name$)\n");
+    format.Indent();
 
-    printer->Print(
-      "if (&from == this) return;\n"
-      "Clear();\n"
-      "MergeFrom(from);\n");
+    format("if (&from == this) return;\n");
 
-    printer->Outdent();
-    printer->Print("}\n\n");
+    if (!options_.opensource_runtime) {
+      // This check is disabled in the opensource release because we're
+      // concerned that many users do not define NDEBUG in their release
+      // builds.
+      format(
+          "#ifndef NDEBUG\n"
+          "size_t from_size = from.ByteSizeLong();\n"
+          "#endif\n"
+          "Clear();\n"
+          "#ifndef NDEBUG\n"
+          "$CHK$_EQ(from_size, from.ByteSizeLong())\n"
+          "  << \"Source of CopyFrom changed when clearing target.  Either \"\n"
+          "  << \"source is a nested message in target (not allowed), or \"\n"
+          "  << \"another thread is modifying the source.\";\n"
+          "#endif\n");
+    } else {
+      format("Clear();\n");
+    }
+    format("MergeFrom(from);\n");
+
+    format.Outdent();
+    format("}\n\n");
   }
 
   // Generate the class-specific CopyFrom.
-  printer->Print(
+  format(
       "void $classname$::CopyFrom(const $classname$& from) {\n"
       "// @@protoc_insertion_point(class_specific_copy_from_start:"
-      "$full_name$)\n",
-      "classname", classname_, "full_name", descriptor_->full_name());
-  printer->Indent();
+      "$full_name$)\n");
+  format.Indent();
 
-  printer->Print(
-    "if (&from == this) return;\n"
-    "Clear();\n"
-    "MergeFrom(from);\n");
+  format("if (&from == this) return;\n");
 
-  printer->Outdent();
-  printer->Print("}\n");
+  if (!options_.opensource_runtime) {
+    // This check is disabled in the opensource release because we're
+    // concerned that many users do not define NDEBUG in their release builds.
+    format(
+        "#ifndef NDEBUG\n"
+        "size_t from_size = from.ByteSizeLong();\n"
+        "#endif\n"
+        "Clear();\n"
+        "#ifndef NDEBUG\n"
+        "$CHK$_EQ(from_size, from.ByteSizeLong())\n"
+        "  << \"Source of CopyFrom changed when clearing target.  Either \"\n"
+        "  << \"source is a nested message in target (not allowed), or \"\n"
+        "  << \"another thread is modifying the source.\";\n"
+        "#endif\n");
+  } else {
+    format("Clear();\n");
+  }
+  format("MergeFrom(from);\n");
+
+  format.Outdent();
+  format("}\n");
 }
 
-void MessageGenerator::
-GenerateMergeFromCodedStream(io::Printer* printer) {
-  std::map<string, string> vars;
+void MessageGenerator::GenerateMergeFromCodedStream(io::Printer* printer) {
+  std::map<string, string> vars = variables_;
   SetUnknkownFieldsVariable(descriptor_, options_, &vars);
+  Formatter format(printer, vars);
   if (descriptor_->options().message_set_wire_format()) {
     // Special-case MessageSet.
-    vars["classname"] = classname_;
-    printer->Print(vars,
-      "bool $classname$::MergePartialFromCodedStream(\n"
-      "    ::google::protobuf::io::CodedInputStream* input) {\n"
-      "  return _extensions_.ParseMessageSet(input,\n"
-      "      internal_default_instance(), $mutable_unknown_fields$);\n"
-      "}\n");
+    format(
+        "#if $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
+        "const char* $classname$::_InternalParse(const char* begin, const "
+        "char* end, void* object,\n"
+        "                  ::$proto_ns$::internal::ParseContext* ctx) {\n"
+        "  return ::$proto_ns$::internal::ParseMessageSet(begin, end, "
+        "static_cast<$classname$*>(object), ctx);\n"
+        "}\n"
+        "const char* $classname$::InternalParseMessageSetItem(const char* "
+        "begin, const char* end, void* object,\n"
+        "                  ::$proto_ns$::internal::ParseContext* ctx) {\n"
+        "  auto msg = static_cast<$classname$*>(object);\n"
+        "  return "
+        "msg->_extensions_.ParseMessageSetItem({InternalParseMessageSetItem, "
+        "msg}, begin, end, internal_default_instance(), "
+        "&msg->_internal_metadata_, ctx);\n"
+        "}\n"
+        "#else\n"
+        "bool $classname$::MergePartialFromCodedStream(\n"
+        "    ::$proto_ns$::io::CodedInputStream* input) {\n"
+        "  return _extensions_.ParseMessageSet(input,\n"
+        "      internal_default_instance(), $mutable_unknown_fields$);\n"
+        "}\n"
+        "#endif  // $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n");
     return;
   }
+  format("#if $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n");
+  GenerateParserLoop(descriptor_, options_, scc_analyzer_, printer);
+  format("#else  // $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n");
   std::vector<const FieldDescriptor*> ordered_fields =
       SortFieldsByNumber(descriptor_);
 
-  printer->Print(
-    "bool $classname$::MergePartialFromCodedStream(\n"
-    "    ::google::protobuf::io::CodedInputStream* input) {\n",
-    "classname", classname_);
+  format(
+      "bool $classname$::MergePartialFromCodedStream(\n"
+      "    ::$proto_ns$::io::CodedInputStream* input) {\n");
 
   if (table_driven_) {
-    printer->Indent();
+    format.Indent();
 
-    const string lite = UseUnknownFieldSet(descriptor_->file(), options_) ?
-        "" : "Lite";
+    const string lite =
+        UseUnknownFieldSet(descriptor_->file(), options_) ? "" : "Lite";
 
-    printer->Print(
-        "return ::google::protobuf::internal::MergePartialFromCodedStream$lite$(\n"
-        "    this,\n"
-        "    ::$file_namespace$::TableStruct::schema[\n"
-        "      $classname$::kIndexInFileMessages],\n"
-        "    input);\n",
-        "classname", classname_, "file_namespace",
-        FileLevelNamespace(descriptor_), "lite", lite);
+    format(
+        "return ::$proto_ns$::internal::MergePartialFromCodedStream$1$(\n"
+        "    this, ::$tablename$::schema[\n"
+        "      $classname$::kIndexInFileMessages], input);\n",
+        lite);
 
-    printer->Outdent();
+    format.Outdent();
 
-    printer->Print("}\n");
+    format("}\n");
+    format("#endif  // $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n");
     return;
   }
 
   if (SupportsArenas(descriptor_)) {
-    for (int i = 0; i < ordered_fields.size(); i++) {
-      const FieldDescriptor* field = ordered_fields[i];
+    for (auto field : ordered_fields) {
       const FieldGenerator& field_generator = field_generators_.get(field);
       if (field_generator.MergeFromCodedStreamNeedsArena()) {
-        printer->Print(
-          "  ::google::protobuf::Arena* arena = GetArenaNoVirtual();\n");
+        format("  ::$proto_ns$::Arena* arena = GetArenaNoVirtual();\n");
         break;
       }
     }
   }
 
-  printer->Print(
-      "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto "
-      "failure\n"
-      "  ::google::protobuf::uint32 tag;\n");
+  format(
+      "#define DO_(EXPRESSION) if "
+      "(!$GOOGLE_PROTOBUF$_PREDICT_TRUE(EXPRESSION)) goto failure\n"
+      "  $uint32$ tag;\n");
 
   if (!UseUnknownFieldSet(descriptor_->file(), options_)) {
-    printer->Print(
-        "  ::google::protobuf::internal::LiteUnknownFieldSetter unknown_fields_setter(\n"
+    format(
+        "  ::$proto_ns$::internal::LiteUnknownFieldSetter "
+        "unknown_fields_setter(\n"
         "      &_internal_metadata_);\n"
-        "  ::google::protobuf::io::StringOutputStream unknown_fields_output(\n"
+        "  ::$proto_ns$::io::StringOutputStream unknown_fields_output(\n"
         "      unknown_fields_setter.buffer());\n"
-        "  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
-        "      &unknown_fields_output, false);\n",
-        "classname", classname_);
+        "  ::$proto_ns$::io::CodedOutputStream unknown_fields_stream(\n"
+        "      &unknown_fields_output, false);\n");
   }
 
-  printer->Print(
-    "  // @@protoc_insertion_point(parse_start:$full_name$)\n",
-    "full_name", descriptor_->full_name());
+  format("  // @@protoc_insertion_point(parse_start:$full_name$)\n");
 
-  printer->Indent();
-  printer->Print("for (;;) {\n");
-  printer->Indent();
+  format.Indent();
+  format("for (;;) {\n");
+  format.Indent();
 
   // To calculate the maximum tag to expect, we look at the highest-numbered
   // field. We need to be prepared to handle more than one wire type if that
@@ -3355,8 +3431,7 @@
   bool capture_last_tag = false;
   const Descriptor* parent = descriptor_->containing_type();
   if (parent) {
-    for (int i = 0; i < parent->field_count(); i++) {
-      const FieldDescriptor* field = parent->field(i);
+    for (auto field : FieldRange(parent)) {
       if (field->type() == FieldDescriptor::TYPE_GROUP &&
           field->message_type() == descriptor_) {
         capture_last_tag = true;
@@ -3383,13 +3458,12 @@
     }
   }
 
-  printer->Print("::std::pair<::google::protobuf::uint32, bool> p = "
-                 "input->ReadTagWithCutoffNoLastTag($max$u);\n"
-                 "tag = p.first;\n"
-                 "if (!p.second) goto handle_unusual;\n",
-                 "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 :
-                                   (maxtag <= kCutoff1 ? kCutoff1 :
-                                    maxtag)));
+  format(
+      "::std::pair<$uint32$, bool> p = "
+      "input->ReadTagWithCutoffNoLastTag($1$u);\n"
+      "tag = p.first;\n"
+      "if (!p.second) goto handle_unusual;\n",
+      maxtag <= kCutoff0 ? kCutoff0 : (maxtag <= kCutoff1 ? kCutoff1 : maxtag));
 
   if (descriptor_->field_count() > 0) {
     // We don't even want to print the switch() if we have no fields because
@@ -3407,182 +3481,189 @@
     // inserts branches that may fail (especially for real world protos that
     // interleave--in field number order--hot and cold fields).  Loadtests
     // confirmed that removing this optimization is performance neutral.
-    printer->Print("switch (::google::protobuf::internal::WireFormatLite::"
-                   "GetTagFieldNumber(tag)) {\n");
+    if (num_weak_fields_ > 0) {
+      format("uint32 weak_offset;\n");
+    }
+    format(
+        "switch (::$proto_ns$::internal::WireFormatLite::"
+        "GetTagFieldNumber(tag)) {\n");
 
-    printer->Indent();
+    format.Indent();
 
-    for (int i = 0; i < ordered_fields.size(); i++) {
-      const FieldDescriptor* field = ordered_fields[i];
+    for (auto field : ordered_fields) {
+      PrintFieldComment(format, field);
+      if (IsWeak(field, options_)) {
+        format(
+            "case $1$:\n"
+            "  weak_offset = offsetof($classname$DefaultTypeInternal, $2$_);\n"
+            "  goto handle_weak_field_map;\n",
+            field->number(), FieldName(field));
+        continue;
+      }
 
-      PrintFieldComment(printer, field);
-
-      printer->Print(
-        "case $number$: {\n",
-        "number", SimpleItoa(field->number()));
-      printer->Indent();
+      format("case $1$: {\n", field->number());
+      format.Indent();
       const FieldGenerator& field_generator = field_generators_.get(field);
 
       // Emit code to parse the common, expected case.
-      printer->Print(
-        "if (static_cast< ::google::protobuf::uint8>(tag) ==\n"
-        "    static_cast< ::google::protobuf::uint8>($truncated$u /* $full$ & 0xFF */)) {\n",
-        "truncated", SimpleItoa(WireFormat::MakeTag(field) & 0xFF),
-        "full", SimpleItoa(WireFormat::MakeTag(field)));
+      // MSVC is warning about truncating constant in the static_cast so
+      // we truncate the tag explicitly.
+      format(
+          "if (static_cast< $uint8$>(tag) == ($1$ & 0xFF)) {\n",
+          WireFormat::MakeTag(field));
 
-      printer->Indent();
+      format.Indent();
       if (field->is_packed()) {
         field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
       } else {
         field_generator.GenerateMergeFromCodedStream(printer);
       }
-      printer->Outdent();
+      format.Outdent();
 
       // Emit code to parse unexpectedly packed or unpacked values.
       if (field->is_packed()) {
         internal::WireFormatLite::WireType wiretype =
             WireFormat::WireTypeForFieldType(field->type());
-        const uint32 tag = internal::WireFormatLite::MakeTag(
-            field->number(), wiretype);
-        printer->Print(
-            "} else if (\n"
-            "    static_cast< ::google::protobuf::uint8>(tag) ==\n"
-            "    static_cast< ::google::protobuf::uint8>($truncated$u /* $full$ & 0xFF */)) {\n",
-            "truncated", SimpleItoa(tag & 0xFF),
-            "full", SimpleItoa(tag));
+        const uint32 tag =
+            internal::WireFormatLite::MakeTag(field->number(), wiretype);
+        format(
+            "} else if (static_cast< $uint8$>(tag) == ($1$ & 0xFF)) {\n",
+            tag);
 
-        printer->Indent();
+        format.Indent();
         field_generator.GenerateMergeFromCodedStream(printer);
-        printer->Outdent();
+        format.Outdent();
       } else if (field->is_packable() && !field->is_packed()) {
         internal::WireFormatLite::WireType wiretype =
             internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
-         const uint32 tag = internal::WireFormatLite::MakeTag(
-            field->number(), wiretype);
-
-        printer->Print(
-            "} else if (\n"
-            "    static_cast< ::google::protobuf::uint8>(tag) ==\n"
-            "    static_cast< ::google::protobuf::uint8>($truncated$u /* $full$ & 0xFF */)) {\n",
-            "truncated", SimpleItoa(tag & 0xFF),
-            "full", SimpleItoa(tag));
-        printer->Indent();
+        const uint32 tag =
+            internal::WireFormatLite::MakeTag(field->number(), wiretype);
+        format(
+            "} else if (static_cast< $uint8$>(tag) == ($1$ & 0xFF)) {\n",
+            tag);
+        format.Indent();
         field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
-        printer->Outdent();
+        format.Outdent();
       }
 
-      printer->Print(
-        "} else {\n"
-        "  goto handle_unusual;\n"
-        "}\n");
+      format(
+          "} else {\n"
+          "  goto handle_unusual;\n"
+          "}\n");
 
-      printer->Print(
-        "break;\n");
+      format("break;\n");
 
-      printer->Outdent();
-      printer->Print("}\n\n");
+      format.Outdent();
+      format("}\n\n");
     }
-    printer->Print("default: {\n");
-    printer->Indent();
+    if (num_weak_fields_ > 0) {
+      format("handle_weak_field_map: {\n");
+      format.Indent();
+
+      format(
+          "if ((tag & 0x7) != 2) goto handle_unusual;\n"
+          "DO_(_weak_field_map_.ReadMessage(input, tag >> 3,\n"
+          "    &_$classname$_default_instance_, weak_offset));\n");
+      format("break;\n");
+      format.Outdent();
+      format("}\n\n");
+    }
+    format("default: {\n");
+    format.Indent();
   }
 
-  printer->Outdent();
-  printer->Print("handle_unusual:\n");
-  printer->Indent();
+  format.Outdent();
+  format("handle_unusual:\n");
+  format.Indent();
   // If tag is 0 or an end-group tag then this must be the end of the message.
   if (capture_last_tag) {
-    printer->Print(
-      "if (tag == 0 ||\n"
-      "    ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
-      "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
-      "  input->SetLastTag(tag);\n"
-      "  goto success;\n"
-      "}\n");
+    format(
+        "if (tag == 0 ||\n"
+        "    ::$proto_ns$::internal::WireFormatLite::GetTagWireType(tag) ==\n"
+        "    ::$proto_ns$::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
+        "  input->SetLastTag(tag);\n"
+        "  goto success;\n"
+        "}\n");
   } else {
-    printer->Print(
-      "if (tag == 0) {\n"
-      "  goto success;\n"
-      "}\n");
+    format(
+        "if (tag == 0) {\n"
+        "  goto success;\n"
+        "}\n");
   }
 
   // Handle extension ranges.
   if (descriptor_->extension_range_count() > 0) {
-    printer->Print(
-      "if (");
+    format("if (");
     for (int i = 0; i < descriptor_->extension_range_count(); i++) {
-      const Descriptor::ExtensionRange* range =
-        descriptor_->extension_range(i);
-      if (i > 0) printer->Print(" ||\n    ");
+      const Descriptor::ExtensionRange* range = descriptor_->extension_range(i);
+      if (i > 0) format(" ||\n    ");
 
       uint32 start_tag = WireFormatLite::MakeTag(
-        range->start, static_cast<WireFormatLite::WireType>(0));
+          range->start, static_cast<WireFormatLite::WireType>(0));
       uint32 end_tag = WireFormatLite::MakeTag(
-        range->end, static_cast<WireFormatLite::WireType>(0));
+          range->end, static_cast<WireFormatLite::WireType>(0));
 
       if (range->end > FieldDescriptor::kMaxNumber) {
-        printer->Print(
-          "($start$u <= tag)",
-          "start", SimpleItoa(start_tag));
+        format("($1$u <= tag)", start_tag);
       } else {
-        printer->Print(
-          "($start$u <= tag && tag < $end$u)",
-          "start", SimpleItoa(start_tag),
-          "end", SimpleItoa(end_tag));
+        format("($1$u <= tag && tag < $2$u)", start_tag, end_tag);
       }
     }
-    printer->Print(") {\n");
+    format(") {\n");
     if (UseUnknownFieldSet(descriptor_->file(), options_)) {
-      printer->Print(vars,
-        "  DO_(_extensions_.ParseField(tag, input,\n"
-        "      internal_default_instance(),\n"
-        "      $mutable_unknown_fields$));\n");
+      format(
+          "  DO_(_extensions_.ParseField(tag, input,\n"
+          "      internal_default_instance(),\n"
+          "      $mutable_unknown_fields$));\n");
     } else {
-      printer->Print(
-        "  DO_(_extensions_.ParseField(tag, input,\n"
-        "      internal_default_instance(),\n"
-        "      &unknown_fields_stream));\n");
+      format(
+          "  DO_(_extensions_.ParseField(tag, input,\n"
+          "      internal_default_instance(),\n"
+          "      &unknown_fields_stream));\n");
     }
-    printer->Print(
-      "  continue;\n"
-      "}\n");
+    format(
+        "  continue;\n"
+        "}\n");
   }
 
   // We really don't recognize this tag.  Skip it.
   if (UseUnknownFieldSet(descriptor_->file(), options_)) {
-    printer->Print(vars,
-        "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
+    format(
+        "DO_(::$proto_ns$::internal::WireFormat::SkipField(\n"
         "      input, tag, $mutable_unknown_fields$));\n");
   } else {
-    printer->Print(
-        "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n"
+    format(
+        "DO_(::$proto_ns$::internal::WireFormatLite::SkipField(\n"
         "    input, tag, &unknown_fields_stream));\n");
   }
 
   if (descriptor_->field_count() > 0) {
-    printer->Print("break;\n");
-    printer->Outdent();
-    printer->Print("}\n");    // default:
-    printer->Outdent();
-    printer->Print("}\n");    // switch
+    format("break;\n");
+    format.Outdent();
+    format("}\n");  // default:
+    format.Outdent();
+    format("}\n");  // switch
   }
 
-  printer->Outdent();
-  printer->Outdent();
-  printer->Print(
-    "  }\n"                   // for (;;)
-    "success:\n"
-    "  // @@protoc_insertion_point(parse_success:$full_name$)\n"
-    "  return true;\n"
-    "failure:\n"
-    "  // @@protoc_insertion_point(parse_failure:$full_name$)\n"
-    "  return false;\n"
-    "#undef DO_\n"
-    "}\n", "full_name", descriptor_->full_name());
+  format.Outdent();
+  format.Outdent();
+  format(
+      "  }\n"  // for (;;)
+      "success:\n"
+      "  // @@protoc_insertion_point(parse_success:$full_name$)\n"
+      "  return true;\n"
+      "failure:\n"
+      "  // @@protoc_insertion_point(parse_failure:$full_name$)\n"
+      "  return false;\n"
+      "#undef DO_\n"
+      "}\n");
+  format("#endif  // $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n");
 }
 
 void MessageGenerator::GenerateSerializeOneofFields(
     io::Printer* printer, const std::vector<const FieldDescriptor*>& fields,
     bool to_array) {
+  Formatter format(printer, variables_);
   GOOGLE_CHECK(!fields.empty());
   if (fields.size() == 1) {
     GenerateSerializeOneField(printer, fields[0], to_array, -1);
@@ -3590,39 +3671,35 @@
   }
   // We have multiple mutually exclusive choices.  Emit a switch statement.
   const OneofDescriptor* oneof = fields[0]->containing_oneof();
-  printer->Print(
-    "switch ($oneofname$_case()) {\n",
-    "oneofname", oneof->name());
-  printer->Indent();
-  for (int i = 0; i < fields.size(); i++) {
-    const FieldDescriptor* field = fields[i];
-    printer->Print(
-      "case k$field_name$:\n",
-      "field_name", UnderscoresToCamelCase(field->name(), true));
-    printer->Indent();
+  format("switch ($1$_case()) {\n", oneof->name());
+  format.Indent();
+  for (auto field : fields) {
+    format("case k$1$:\n", UnderscoresToCamelCase(field->name(), true));
+    format.Indent();
     if (to_array) {
       field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
           printer);
     } else {
       field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
     }
-    printer->Print(
-      "break;\n");
-    printer->Outdent();
+    format("break;\n");
+    format.Outdent();
   }
-  printer->Outdent();
+  format.Outdent();
   // Doing nothing is an option.
-  printer->Print(
-    "  default: ;\n"
-    "}\n");
+  format(
+      "  default: ;\n"
+      "}\n");
 }
 
-void MessageGenerator::GenerateSerializeOneField(
-    io::Printer* printer, const FieldDescriptor* field, bool to_array,
-    int cached_has_bits_index) {
+void MessageGenerator::GenerateSerializeOneField(io::Printer* printer,
+                                                 const FieldDescriptor* field,
+                                                 bool to_array,
+                                                 int cached_has_bits_index) {
+  Formatter format(printer, variables_);
   if (!field->options().weak()) {
     // For weakfields, PrintFieldComment is called during iteration.
-    PrintFieldComment(printer, field);
+    PrintFieldComment(format, field);
   }
 
   bool have_enclosing_if = false;
@@ -3631,19 +3708,15 @@
     // Attempt to use the state of cached_has_bits, if possible.
     int has_bit_index = has_bit_indices_[field->index()];
     if (cached_has_bits_index == has_bit_index / 32) {
-      const string mask = StrCat(
-          strings::Hex(1u << (has_bit_index % 32),
-          strings::ZERO_PAD_8));
+      const string mask =
+          StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
 
-      printer->Print(
-          "if (cached_has_bits & 0x$mask$u) {\n", "mask", mask);
+      format("if (cached_has_bits & 0x$1$u) {\n", mask);
     } else {
-      printer->Print(
-        "if (has_$name$()) {\n",
-        "name", FieldName(field));
+      format("if (has_$1$()) {\n", FieldName(field));
     }
 
-    printer->Indent();
+    format.Indent();
     have_enclosing_if = true;
   } else if (!HasFieldPresence(descriptor_->file())) {
     have_enclosing_if = EmitFieldNonDefaultCondition(printer, "this->", field);
@@ -3657,10 +3730,10 @@
   }
 
   if (have_enclosing_if) {
-    printer->Outdent();
-    printer->Print("}\n");
+    format.Outdent();
+    format("}\n");
   }
-  printer->Print("\n");
+  format("\n");
 }
 
 void MessageGenerator::GenerateSerializeOneExtensionRange(
@@ -3669,110 +3742,99 @@
   std::map<string, string> vars;
   vars["start"] = SimpleItoa(range->start);
   vars["end"] = SimpleItoa(range->end);
-  printer->Print(vars,
-    "// Extension range [$start$, $end$)\n");
+  Formatter format(printer, vars);
+  format("// Extension range [$start$, $end$)\n");
   if (to_array) {
-    printer->Print(vars,
-      "target = _extensions_.InternalSerializeWithCachedSizesToArray(\n"
-      "    $start$, $end$, deterministic, target);\n\n");
+    format(
+        "target = _extensions_.InternalSerializeWithCachedSizesToArray(\n"
+        "    $start$, $end$, deterministic, target);\n\n");
   } else {
-    printer->Print(vars,
-      "_extensions_.SerializeWithCachedSizes(\n"
-      "    $start$, $end$, output);\n\n");
+    format(
+        "_extensions_.SerializeWithCachedSizes($start$, $end$, output);\n"
+        "\n");
   }
 }
 
-void MessageGenerator::
-GenerateSerializeWithCachedSizes(io::Printer* printer) {
+void MessageGenerator::GenerateSerializeWithCachedSizes(io::Printer* printer) {
+  Formatter format(printer, variables_);
   if (descriptor_->options().message_set_wire_format()) {
     // Special-case MessageSet.
-    printer->Print(
-      "void $classname$::SerializeWithCachedSizes(\n"
-      "    ::google::protobuf::io::CodedOutputStream* output) const {\n"
-      "  _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
-      "classname", classname_);
-    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
+    format(
+        "void $classname$::SerializeWithCachedSizes(\n"
+        "    ::$proto_ns$::io::CodedOutputStream* output) const {\n"
+        "  _extensions_.SerializeMessageSetWithCachedSizes(output);\n");
     std::map<string, string> vars;
     SetUnknkownFieldsVariable(descriptor_, options_, &vars);
-    printer->Print(vars,
-      "  ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
-      "      $unknown_fields$, output);\n");
-    printer->Print(
-      "}\n");
+    format.AddMap(vars);
+    format(
+        "  "
+        "::$proto_ns$::internal::SerializeUnknownMessageSetItems(\n"
+        "      $unknown_fields$, output);\n");
+    format("}\n");
     return;
   }
   if (options_.table_driven_serialization) return;
 
-  printer->Print(
-    "void $classname$::SerializeWithCachedSizes(\n"
-    "    ::google::protobuf::io::CodedOutputStream* output) const {\n",
-    "classname", classname_);
-  printer->Indent();
+  format(
+      "void $classname$::SerializeWithCachedSizes(\n"
+      "    ::$proto_ns$::io::CodedOutputStream* output) const {\n");
+  format.Indent();
 
-  printer->Print(
-    "// @@protoc_insertion_point(serialize_start:$full_name$)\n",
-    "full_name", descriptor_->full_name());
+  format("// @@protoc_insertion_point(serialize_start:$full_name$)\n");
 
   GenerateSerializeWithCachedSizesBody(printer, false);
 
-  printer->Print(
-    "// @@protoc_insertion_point(serialize_end:$full_name$)\n",
-    "full_name", descriptor_->full_name());
+  format("// @@protoc_insertion_point(serialize_end:$full_name$)\n");
 
-  printer->Outdent();
-  printer->Print(
-    "}\n");
+  format.Outdent();
+  format("}\n");
 }
 
-void MessageGenerator::
-GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
+void MessageGenerator::GenerateSerializeWithCachedSizesToArray(
+    io::Printer* printer) {
+  Formatter format(printer, variables_);
   if (descriptor_->options().message_set_wire_format()) {
     // Special-case MessageSet.
-    printer->Print(
-      "::google::protobuf::uint8* $classname$::InternalSerializeWithCachedSizesToArray(\n"
-      "    bool deterministic, ::google::protobuf::uint8* target) const {\n"
-      "  target = _extensions_."
-      "InternalSerializeMessageSetWithCachedSizesToArray(\n"
-      "               deterministic, target);\n",
-      "classname", classname_);
-    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
+    format(
+        "$uint8$* $classname$::InternalSerializeWithCachedSizesToArray(\n"
+        "    bool deterministic, $uint8$* target) const {\n"
+        "  target = _extensions_."
+        "InternalSerializeMessageSetWithCachedSizesToArray(\n"
+        "               deterministic, target);\n");
     std::map<string, string> vars;
     SetUnknkownFieldsVariable(descriptor_, options_, &vars);
-    printer->Print(vars,
-      "  target = ::google::protobuf::internal::WireFormat::\n"
-      "             SerializeUnknownMessageSetItemsToArray(\n"
-      "               $unknown_fields$, target);\n");
-    printer->Print(
-      "  return target;\n"
-      "}\n");
+    format.AddMap(vars);
+    format(
+        "  target = ::$proto_ns$::internal::\n"
+        "             SerializeUnknownMessageSetItemsToArray(\n"
+        "               $unknown_fields$, target);\n");
+    format(
+        "  return target;\n"
+        "}\n");
     return;
   }
 
-  printer->Print(
-    "::google::protobuf::uint8* $classname$::InternalSerializeWithCachedSizesToArray(\n"
-    "    bool deterministic, ::google::protobuf::uint8* target) const {\n",
-    "classname", classname_);
-  printer->Indent();
+  format(
+      "$uint8$* $classname$::InternalSerializeWithCachedSizesToArray(\n"
+      "    bool deterministic, $uint8$* target) const {\n");
+  format.Indent();
 
-  printer->Print("(void)deterministic; // Unused\n");
-  printer->Print(
-    "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n",
-    "full_name", descriptor_->full_name());
+  format("(void)deterministic; // Unused\n");
+  format("// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n");
 
   GenerateSerializeWithCachedSizesBody(printer, true);
 
-  printer->Print(
-    "// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n",
-    "full_name", descriptor_->full_name());
+  format("// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n");
 
-  printer->Outdent();
-  printer->Print(
-    "  return target;\n"
-    "}\n");
+  format.Outdent();
+  format(
+      "  return target;\n"
+      "}\n");
 }
 
-void MessageGenerator::
-GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
+void MessageGenerator::GenerateSerializeWithCachedSizesBody(
+    io::Printer* printer, bool to_array) {
+  Formatter format(printer, variables_);
   // If there are multiple fields in a row from the same oneof then we
   // coalesce them and emit a switch statement.  This is more efficient
   // because it lets the C++ compiler know this is a "at most one can happen"
@@ -3783,7 +3845,7 @@
     LazySerializerEmitter(MessageGenerator* mg, io::Printer* printer,
                           bool to_array)
         : mg_(mg),
-          printer_(printer),
+          format_(printer),
           to_array_(to_array),
           eager_(!HasFieldPresence(mg->descriptor_->file())),
           cached_has_bit_index_(-1) {}
@@ -3808,16 +3870,14 @@
             // Reload.
             int new_index = has_bit_index / 32;
 
-            printer_->Print(
-                "cached_has_bits = _has_bits_[$new_index$];\n",
-                "new_index", SimpleItoa(new_index));
+            format_("cached_has_bits = _has_bits_[$1$];\n", new_index);
 
             cached_has_bit_index_ = new_index;
           }
         }
 
-        mg_->GenerateSerializeOneField(
-            printer_, field, to_array_, cached_has_bit_index_);
+        mg_->GenerateSerializeOneField(format_.printer(), field, to_array_,
+                                       cached_has_bit_index_);
       } else {
         v_.push_back(field);
       }
@@ -3825,7 +3885,7 @@
 
     void Flush() {
       if (!v_.empty()) {
-        mg_->GenerateSerializeOneofFields(printer_, v_, to_array_);
+        mg_->GenerateSerializeOneofFields(format_.printer(), v_, to_array_);
         v_.clear();
       }
     }
@@ -3839,7 +3899,7 @@
     }
 
     MessageGenerator* mg_;
-    io::Printer* printer_;
+    Formatter format_;
     const bool to_array_;
     const bool eager_;
     std::vector<const FieldDescriptor*> v_;
@@ -3860,13 +3920,13 @@
   std::sort(sorted_extensions.begin(), sorted_extensions.end(),
             ExtensionRangeSorter());
   if (num_weak_fields_) {
-    printer->Print(
-        "::google::protobuf::internal::WeakFieldMap::FieldWriter field_writer("
+    format(
+        "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer("
         "_weak_field_map_);\n");
   }
 
-  printer->Print(
-      "::google::protobuf::uint32 cached_has_bits = 0;\n"
+  format(
+      "$uint32$ cached_has_bits = 0;\n"
       "(void) cached_has_bits;\n\n");
 
   // Merge the fields and the extension ranges, both sorted by field number.
@@ -3882,7 +3942,7 @@
         const FieldDescriptor* field = ordered_fields[i++];
         if (field->options().weak()) {
           last_weak_field = field;
-          PrintFieldComment(printer, field);
+          PrintFieldComment(format, field);
         } else {
           if (last_weak_field != nullptr) {
             e.Emit(last_weak_field);
@@ -3890,14 +3950,13 @@
           }
           e.Emit(field);
         }
-      } else  {
+      } else {
         if (last_weak_field != nullptr) {
           e.Emit(last_weak_field);
           last_weak_field = nullptr;
         }
         e.Flush();
-        GenerateSerializeOneExtensionRange(printer,
-                                           sorted_extensions[j++],
+        GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++],
                                            to_array);
       }
     }
@@ -3908,27 +3967,27 @@
 
   std::map<string, string> vars;
   SetUnknkownFieldsVariable(descriptor_, options_, &vars);
+  format.AddMap(vars);
   if (UseUnknownFieldSet(descriptor_->file(), options_)) {
-    printer->Print(vars,
-      "if ($have_unknown_fields$) {\n");
-    printer->Indent();
+    format("if ($have_unknown_fields$) {\n");
+    format.Indent();
     if (to_array) {
-      printer->Print(vars,
-        "target = "
-        "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
-        "    $unknown_fields$, target);\n");
+      format(
+          "target = "
+          "::$proto_ns$::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
+          "    $unknown_fields$, target);\n");
     } else {
-      printer->Print(vars,
-        "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
-        "    $unknown_fields$, output);\n");
+      format(
+          "::$proto_ns$::internal::WireFormat::SerializeUnknownFields(\n"
+          "    $unknown_fields$, output);\n");
     }
-    printer->Outdent();
+    format.Outdent();
 
-    printer->Print("}\n");
+    format("}\n");
   } else {
-    printer->Print(vars,
-      "output->WriteRaw($unknown_fields$.data(),\n"
-      "                 static_cast<int>($unknown_fields$.size()));\n");
+    format(
+        "output->WriteRaw($unknown_fields$.data(),\n"
+        "                 static_cast<int>($unknown_fields$.size()));\n");
   }
 }
 
@@ -3936,15 +3995,13 @@
   const int array_size = HasBitsSize();
   std::vector<uint32> masks(array_size, 0);
 
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* field = descriptor_->field(i);
+  for (auto field : FieldRange(descriptor_)) {
     if (!field->is_required()) {
       continue;
     }
 
     const int has_bit_index = has_bit_indices_[field->index()];
-    masks[has_bit_index / 32] |=
-        static_cast<uint32>(1) << (has_bit_index % 32);
+    masks[has_bit_index / 32] |= static_cast<uint32>(1) << (has_bit_index % 32);
   }
   return masks;
 }
@@ -3959,35 +4016,36 @@
     if (masks[i] == 0) continue;
     string m = StrCat("0x", strings::Hex(masks[i], strings::ZERO_PAD_8));
     // Each xor evaluates to 0 if the expected bits are present.
-    parts.push_back(StrCat("((_has_bits_[", i, "] & ", m, ") ^ ", m, ")"));
+    parts.push_back(
+        StrCat("((_has_bits_[", i, "] & ", m, ") ^ ", m, ")"));
   }
   GOOGLE_CHECK(!parts.empty());
   // If we have multiple parts, each expected to be 0, then bitwise-or them.
-  string result = parts.size() == 1
-                      ? parts[0]
-                      : StrCat("(", Join(parts, "\n       | "), ")");
+  string result =
+      parts.size() == 1
+          ? parts[0]
+          : StrCat("(", Join(parts, "\n       | "), ")");
   return result + " == 0";
 }
 
-void MessageGenerator::
-GenerateByteSize(io::Printer* printer) {
+void MessageGenerator::GenerateByteSize(io::Printer* printer) {
+  Formatter format(printer, variables_);
+
   if (descriptor_->options().message_set_wire_format()) {
     // Special-case MessageSet.
-    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
     std::map<string, string> vars;
     SetUnknkownFieldsVariable(descriptor_, options_, &vars);
-    vars["classname"] = classname_;
-    vars["full_name"] = descriptor_->full_name();
-    printer->Print(
-        vars,
+    format.AddMap(vars);
+    format(
         "size_t $classname$::ByteSizeLong() const {\n"
         "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n"
         "  size_t total_size = _extensions_.MessageSetByteSize();\n"
         "  if ($have_unknown_fields$) {\n"
-        "    total_size += ::google::protobuf::internal::WireFormat::\n"
+        "    total_size += ::$proto_ns$::internal::\n"
         "        ComputeUnknownMessageSetItemsSize($unknown_fields$);\n"
         "  }\n"
-        "  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);\n"
+        "  int cached_size = "
+        "::$proto_ns$::internal::ToCachedSize(total_size);\n"
         "  SetCachedSize(cached_size);\n"
         "  return total_size;\n"
         "}\n");
@@ -3997,60 +4055,60 @@
   if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) {
     // Emit a function (rarely used, we hope) that handles the required fields
     // by checking for each one individually.
-    printer->Print(
+    format(
         "size_t $classname$::RequiredFieldsByteSizeFallback() const {\n"
         "// @@protoc_insertion_point(required_fields_byte_size_fallback_start:"
-        "$full_name$)\n",
-        "classname", classname_, "full_name", descriptor_->full_name());
-    printer->Indent();
-    printer->Print("size_t total_size = 0;\n");
-    for (int i = 0; i < optimized_order_.size(); i++) {
-      const FieldDescriptor* field = optimized_order_[i];
+        "$full_name$)\n");
+    format.Indent();
+    format("size_t total_size = 0;\n");
+    for (auto field : optimized_order_) {
       if (field->is_required()) {
-        printer->Print("\n"
-                       "if (has_$name$()) {\n",
-                       "name", FieldName(field));
-        printer->Indent();
-        PrintFieldComment(printer, field);
+        format(
+            "\n"
+            "if (has_$1$()) {\n",
+            FieldName(field));
+        format.Indent();
+        PrintFieldComment(format, field);
         field_generators_.get(field).GenerateByteSize(printer);
-        printer->Outdent();
-        printer->Print("}\n");
+        format.Outdent();
+        format("}\n");
       }
     }
-    printer->Print("\n"
-                   "return total_size;\n");
-    printer->Outdent();
-    printer->Print("}\n");
+    format(
+        "\n"
+        "return total_size;\n");
+    format.Outdent();
+    format("}\n");
   }
 
-  printer->Print(
+  format(
       "size_t $classname$::ByteSizeLong() const {\n"
-      "// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n",
-      "classname", classname_, "full_name", descriptor_->full_name());
-  printer->Indent();
-  printer->Print(
-    "size_t total_size = 0;\n"
-    "\n");
+      "// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n");
+  format.Indent();
+  format(
+      "size_t total_size = 0;\n"
+      "\n");
 
   if (descriptor_->extension_range_count() > 0) {
-    printer->Print(
-      "total_size += _extensions_.ByteSize();\n"
-      "\n");
+    format(
+        "total_size += _extensions_.ByteSize();\n"
+        "\n");
   }
 
   std::map<string, string> vars;
   SetUnknkownFieldsVariable(descriptor_, options_, &vars);
+  format.AddMap(vars);
   if (UseUnknownFieldSet(descriptor_->file(), options_)) {
-    printer->Print(vars,
-      "if ($have_unknown_fields$) {\n"
-      "  total_size +=\n"
-      "    ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
-      "      $unknown_fields$);\n"
-      "}\n");
+    format(
+        "if ($have_unknown_fields$) {\n"
+        "  total_size +=\n"
+        "    ::$proto_ns$::internal::WireFormat::ComputeUnknownFieldsSize(\n"
+        "      $unknown_fields$);\n"
+        "}\n");
   } else {
-    printer->Print(vars,
-      "total_size += $unknown_fields$.size();\n"
-      "\n");
+    format(
+        "total_size += $unknown_fields$.size();\n"
+        "\n");
   }
 
   // Handle required fields (if any).  We expect all of them to be
@@ -4059,35 +4117,32 @@
   if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) {
     // The fast path works if all required fields are present.
     const std::vector<uint32> masks_for_has_bits = RequiredFieldsBitMask();
-    printer->Print((string("if (") +
-                    ConditionalToCheckBitmasks(masks_for_has_bits) +
-                    ") {  // All required fields are present.\n").c_str());
-    printer->Indent();
+    format("if ($1$) {  // All required fields are present.\n",
+           ConditionalToCheckBitmasks(masks_for_has_bits));
+    format.Indent();
     // Oneof fields cannot be required, so optimized_order_ contains all of the
     // fields that we need to potentially emit.
-    for (int i = 0; i < optimized_order_.size(); i++) {
-      const FieldDescriptor* field = optimized_order_[i];
+    for (auto field : optimized_order_) {
       if (!field->is_required()) continue;
-      PrintFieldComment(printer, field);
+      PrintFieldComment(format, field);
       field_generators_.get(field).GenerateByteSize(printer);
-      printer->Print("\n");
+      format("\n");
     }
-    printer->Outdent();
-    printer->Print("} else {\n"  // the slow path
-                   "  total_size += RequiredFieldsByteSizeFallback();\n"
-                   "}\n");
+    format.Outdent();
+    format(
+        "} else {\n"  // the slow path
+        "  total_size += RequiredFieldsByteSizeFallback();\n"
+        "}\n");
   } else {
     // num_required_fields_ <= 1: no need to be tricky
-    for (int i = 0; i < optimized_order_.size(); i++) {
-      const FieldDescriptor* field = optimized_order_[i];
+    for (auto field : optimized_order_) {
       if (!field->is_required()) continue;
-      PrintFieldComment(printer, field);
-      printer->Print("if (has_$name$()) {\n",
-                     "name", FieldName(field));
-      printer->Indent();
+      PrintFieldComment(format, field);
+      format("if (has_$1$()) {\n", FieldName(field));
+      format.Indent();
       field_generators_.get(field).GenerateByteSize(printer);
-      printer->Outdent();
-      printer->Print("}\n");
+      format.Outdent();
+      format("}\n");
     }
   }
 
@@ -4100,6 +4155,16 @@
   chunks.erase(std::remove_if(chunks.begin(), chunks.end(), IsRequired),
                chunks.end());
 
+  ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio,
+                                HasFieldPresence(descriptor_->file()));
+
+  format(
+      "$uint32$ cached_has_bits = 0;\n"
+      "// Prevent compiler warnings about cached_has_bits being unused\n"
+      "(void) cached_has_bits;\n\n");
+
+  int cached_has_bit_index = -1;
+
   for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
     const std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index];
     GOOGLE_CHECK(!chunk.empty());
@@ -4109,14 +4174,16 @@
       for (int i = 0; i < chunk.size(); i++) {
         const FieldDescriptor* field = chunk[i];
 
-        PrintFieldComment(printer, field);
+        PrintFieldComment(format, field);
         const FieldGenerator& generator = field_generators_.get(field);
         generator.GenerateByteSize(printer);
-        printer->Print("\n");
+        format("\n");
       }
       continue;
     }
 
+    cold_skipper.OnStartChunk(chunk_index, cached_has_bit_index, "", printer);
+
     // Handle optional (non-repeated/oneof) fields.
     //
     // These are handled in chunks of 8.  The first chunk is
@@ -4144,10 +4211,13 @@
       GOOGLE_DCHECK_LE(2, count);
       GOOGLE_DCHECK_GE(8, count);
 
-      printer->Print("if (_has_bits_[$index$ / 32] & $mask$u) {\n", "index",
-                     SimpleItoa(last_chunk * 8), "mask",
-                     SimpleItoa(last_chunk_mask));
-      printer->Indent();
+      if (cached_has_bit_index != last_chunk / 4) {
+        cached_has_bit_index = last_chunk / 4;
+        format("cached_has_bits = _has_bits_[$1$];\n", cached_has_bit_index);
+      }
+      format("if (cached_has_bits & 0x$1$u) {\n",
+             StrCat(strings::Hex(last_chunk_mask, strings::ZERO_PAD_8)));
+      format.Indent();
     }
 
     // Go back and emit checks for each of the fields we processed.
@@ -4155,12 +4225,12 @@
       const FieldDescriptor* field = chunk[j];
       const FieldGenerator& generator = field_generators_.get(field);
 
-      PrintFieldComment(printer, field);
+      PrintFieldComment(format, field);
 
       bool have_enclosing_if = false;
       if (HasFieldPresence(descriptor_->file())) {
-        printer->Print("if (has_$name$()) {\n", "name", FieldName(field));
-        printer->Indent();
+        PrintPresenceCheck(format, field, has_bit_indices_, printer,
+                           &cached_has_bit_index);
         have_enclosing_if = true;
       } else {
         // Without field presence: field is serialized only if it has a
@@ -4172,54 +4242,50 @@
       generator.GenerateByteSize(printer);
 
       if (have_enclosing_if) {
-        printer->Outdent();
-        printer->Print(
+        format.Outdent();
+        format(
             "}\n"
             "\n");
       }
     }
 
     if (have_outer_if) {
-      printer->Outdent();
-      printer->Print("}\n");
+      format.Outdent();
+      format("}\n");
+    }
+
+    if (cold_skipper.OnEndChunk(chunk_index, printer)) {
+      // Reset here as it may have been updated in just closed if statement.
+      cached_has_bit_index = -1;
     }
   }
 
   // Fields inside a oneof don't use _has_bits_ so we count them in a separate
   // pass.
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    printer->Print(
-        "switch ($oneofname$_case()) {\n",
-        "oneofname", descriptor_->oneof_decl(i)->name());
-    printer->Indent();
-    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
-      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
-      PrintFieldComment(printer, field);
-      printer->Print(
-          "case k$field_name$: {\n",
-          "field_name", UnderscoresToCamelCase(field->name(), true));
-      printer->Indent();
+  for (auto oneof : OneOfRange(descriptor_)) {
+    format("switch ($1$_case()) {\n", oneof->name());
+    format.Indent();
+    for (auto field : FieldRange(oneof)) {
+      PrintFieldComment(format, field);
+      format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
+      format.Indent();
       field_generators_.get(field).GenerateByteSize(printer);
-      printer->Print(
-          "break;\n");
-      printer->Outdent();
-      printer->Print(
-          "}\n");
+      format("break;\n");
+      format.Outdent();
+      format("}\n");
     }
-    printer->Print(
-        "case $cap_oneof_name$_NOT_SET: {\n"
+    format(
+        "case $1$_NOT_SET: {\n"
         "  break;\n"
         "}\n",
-        "cap_oneof_name",
-        ToUpper(descriptor_->oneof_decl(i)->name()));
-    printer->Outdent();
-    printer->Print(
-        "}\n");
+        ToUpper(oneof->name()));
+    format.Outdent();
+    format("}\n");
   }
 
   if (num_weak_fields_) {
     // TagSize + MessageSize
-    printer->Print("total_size += _weak_field_map_.ByteSizeLong();\n");
+    format("total_size += _weak_field_map_.ByteSizeLong();\n");
   }
 
   // We update _cached_size_ even though this is a const method.  Because
@@ -4230,27 +4296,25 @@
   // the underlying atomic. This makes it easier on platforms where even relaxed
   // memory order might have perf impact to replace it with ordinary loads and
   // stores.
-  printer->Print(
-      "int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);\n"
+  format(
+      "int cached_size = ::$proto_ns$::internal::ToCachedSize(total_size);\n"
       "SetCachedSize(cached_size);\n"
       "return total_size;\n");
 
-  printer->Outdent();
-  printer->Print("}\n");
+  format.Outdent();
+  format("}\n");
 }
 
-void MessageGenerator::
-GenerateIsInitialized(io::Printer* printer) {
-  printer->Print(
-    "bool $classname$::IsInitialized() const {\n",
-    "classname", classname_);
-  printer->Indent();
+void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
+  Formatter format(printer, variables_);
+  format("bool $classname$::IsInitialized() const {\n");
+  format.Indent();
 
   if (descriptor_->extension_range_count() > 0) {
-    printer->Print(
-      "if (!_extensions_.IsInitialized()) {\n"
-      "  return false;\n"
-      "}\n\n");
+    format(
+        "if (!_extensions_.IsInitialized()) {\n"
+        "  return false;\n"
+        "}\n\n");
   }
 
   if (HasFieldPresence(descriptor_->file())) {
@@ -4267,57 +4331,51 @@
       // TODO(ckennelly): Consider doing something similar to ByteSizeLong(),
       // where we check all of the required fields in a single branch (assuming
       // that we aren't going to benefit from early termination).
-      printer->Print(
-        "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
-        "i", SimpleItoa(i),
-        "mask", StrCat(strings::Hex(mask, strings::ZERO_PAD_8)));
+      format("if ((_has_bits_[$1$] & 0x$2$) != 0x$2$) return false;\n",
+             i,                                                 // 1
+             StrCat(strings::Hex(mask, strings::ZERO_PAD_8)));  // 2
     }
   }
 
   // Now check that all non-oneof embedded messages are initialized.
-  for (int i = 0; i < optimized_order_.size(); i++) {
-    const FieldDescriptor* field = optimized_order_[i];
+  for (auto field : optimized_order_) {
     // TODO(ckennelly): Push this down into a generator?
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
         !ShouldIgnoreRequiredFieldCheck(field, options_) &&
         scc_analyzer_->HasRequiredFields(field->message_type())) {
       if (field->is_repeated()) {
         if (IsImplicitWeakField(field, options_, scc_analyzer_)) {
-          printer->Print(
-            "if (!::google::protobuf::internal::AllAreInitializedWeak(this->$name$_))"
-            " return false;\n",
-            "name", FieldName(field));
+          format(
+              "if (!::$proto_ns$::internal::AllAreInitializedWeak(this->$1$_))"
+              " return false;\n",
+              FieldName(field));
         } else {
-          printer->Print(
-            "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))"
-            " return false;\n",
-            "name", FieldName(field));
+          format(
+              "if (!::$proto_ns$::internal::AllAreInitialized(this->$1$()))"
+              " return false;\n",
+              FieldName(field));
         }
       } else if (field->options().weak()) {
         continue;
       } else {
         GOOGLE_CHECK(!field->containing_oneof());
-        printer->Print(
-            "if (has_$name$()) {\n"
-            "  if (!this->$name$_->IsInitialized()) return false;\n"
+        format(
+            "if (has_$1$()) {\n"
+            "  if (!this->$1$_->IsInitialized()) return false;\n"
             "}\n",
-            "name", FieldName(field));
+            FieldName(field));
       }
     }
   }
   if (num_weak_fields_) {
     // For Weak fields.
-    printer->Print("if (!_weak_field_map_.IsInitialized()) return false;\n");
+    format("if (!_weak_field_map_.IsInitialized()) return false;\n");
   }
   // Go through the oneof fields, emitting a switch if any might have required
   // fields.
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
-
+  for (auto oneof : OneOfRange(descriptor_)) {
     bool has_required_fields = false;
-    for (int j = 0; j < oneof->field_count(); j++) {
-      const FieldDescriptor* field = oneof->field(j);
-
+    for (auto field : FieldRange(oneof)) {
       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
           !ShouldIgnoreRequiredFieldCheck(field, options_) &&
           scc_analyzer_->HasRequiredFields(field->message_type())) {
@@ -4330,16 +4388,11 @@
       continue;
     }
 
-    printer->Print(
-        "switch ($oneofname$_case()) {\n",
-        "oneofname", oneof->name());
-    printer->Indent();
-    for (int j = 0; j < oneof->field_count(); j++) {
-      const FieldDescriptor* field = oneof->field(j);
-      printer->Print(
-          "case k$field_name$: {\n",
-          "field_name", UnderscoresToCamelCase(field->name(), true));
-      printer->Indent();
+    format("switch ($1$_case()) {\n", oneof->name());
+    format.Indent();
+    for (auto field : FieldRange(oneof)) {
+      format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
+      format.Indent();
 
       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
           !ShouldIgnoreRequiredFieldCheck(field, options_) &&
@@ -4348,35 +4401,31 @@
         if (field->options().weak()) {
           // Just skip.
         } else {
-          printer->Print(
-            "if (has_$name$()) {\n"
-            "  if (!this->$name$().IsInitialized()) return false;\n"
-            "}\n",
-            "name", FieldName(field));
+          format(
+              "if (has_$1$()) {\n"
+              "  if (!this->$1$().IsInitialized()) return false;\n"
+              "}\n",
+              FieldName(field));
         }
       }
 
-      printer->Print(
-          "break;\n");
-      printer->Outdent();
-      printer->Print(
-          "}\n");
+      format("break;\n");
+      format.Outdent();
+      format("}\n");
     }
-    printer->Print(
-        "case $cap_oneof_name$_NOT_SET: {\n"
+    format(
+        "case $1$_NOT_SET: {\n"
         "  break;\n"
         "}\n",
-        "cap_oneof_name",
         ToUpper(oneof->name()));
-    printer->Outdent();
-    printer->Print(
-        "}\n");
+    format.Outdent();
+    format("}\n");
   }
 
-  printer->Outdent();
-  printer->Print(
-    "  return true;\n"
-    "}\n");
+  format.Outdent();
+  format(
+      "  return true;\n"
+      "}\n");
 }
 
 }  // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h
index ca2ca2c..170a70c 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -45,37 +45,33 @@
 
 namespace google {
 namespace protobuf {
-  namespace io {
-    class Printer;             // printer.h
-  }
+namespace io {
+class Printer;  // printer.h
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace cpp {
 
-class EnumGenerator;           // enum.h
-class ExtensionGenerator;      // extension.h
+class EnumGenerator;       // enum.h
+class ExtensionGenerator;  // extension.h
 
 class MessageGenerator {
  public:
   // See generator.cc for the meaning of dllexport_decl.
-  MessageGenerator(const Descriptor* descriptor, int index_in_file_messages,
-                   const Options& options, SCCAnalyzer* scc_analyzer);
+  MessageGenerator(const Descriptor* descriptor,
+                   const std::map<string, string>& vars,
+                   int index_in_file_messages, const Options& options,
+                   MessageSCCAnalyzer* scc_analyzer);
   ~MessageGenerator();
 
   // Append the two types of nested generators to the corresponding vector.
-  void AddGenerators(std::vector<EnumGenerator*>* enum_generators,
-                     std::vector<ExtensionGenerator*>* extension_generators);
-
-  // Header stuff.
-
-  // Return names for forward declarations of this class and all its nested
-  // types. A given key in {class,enum}_names will map from a class name to the
-  // descriptor that was responsible for its inclusion in the map. This can be
-  // used to associate the descriptor with the code generated for it.
-  void FillMessageForwardDeclarations(
-      std::map<string, const Descriptor*>* class_names);
+  void AddGenerators(
+      std::vector<std::unique_ptr<EnumGenerator>>* enum_generators,
+      std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators);
 
   // Generate definitions for this class and all its nested types.
   void GenerateClassDefinition(io::Printer* printer);
@@ -112,8 +108,8 @@
   // generated.
   size_t GenerateParseOffsets(io::Printer* printer);
   size_t GenerateParseAuxTable(io::Printer* printer);
-  // Generates a ParseTable entry.  Returns whether the proto uses table-driven
-  // parsing.
+  // Generates a ParseTable entry.  Returns whether the proto uses
+  // table-driven parsing.
   bool GenerateParseTable(io::Printer* printer, size_t offset,
                           size_t aux_offset);
 
@@ -140,8 +136,8 @@
   void GenerateArenaDestructorCode(io::Printer* printer);
 
   // Helper for GenerateClear and others.  Optionally emits a condition that
-  // assumes the existence of the cached_has_bits variable, and returns true if
-  // the condition was printed.
+  // assumes the existence of the cached_has_bits variable, and returns true
+  // if the condition was printed.
   bool MaybeGenerateOptionalFieldCondition(io::Printer* printer,
                                            const FieldDescriptor* field,
                                            int expected_has_bits_index);
@@ -166,8 +162,7 @@
   //   cached_has_bits = _has_bits_[cached_has_bit_index]
   // for cached_has_bit_index >= 0
   void GenerateSerializeOneField(io::Printer* printer,
-                                 const FieldDescriptor* field,
-                                 bool unbounded,
+                                 const FieldDescriptor* field, bool unbounded,
                                  int cached_has_bits_index);
   // Generate a switch statement to serialize 2+ fields from the same oneof.
   // Or, if fields.size() == 1, just call GenerateSerializeOneField().
@@ -180,19 +175,15 @@
 
   // Generates has_foo() functions and variables for singular field has-bits.
   void GenerateSingularFieldHasBits(const FieldDescriptor* field,
-                                    std::map<string, string> vars,
-                                    io::Printer* printer);
+                                    Formatter format);
   // Generates has_foo() functions and variables for oneof field has-bits.
   void GenerateOneofHasBits(io::Printer* printer);
   // Generates has_foo_bar() functions for oneof members.
   void GenerateOneofMemberHasBits(const FieldDescriptor* field,
-                                  const std::map<string, string>& vars,
-                                  io::Printer* printer);
+                                  const Formatter& format);
   // Generates the clear_foo() method for a field.
-  void GenerateFieldClear(const FieldDescriptor* field,
-                          const std::map<string, string>& vars,
-                          bool is_inline,
-                          io::Printer* printer);
+  void GenerateFieldClear(const FieldDescriptor* field, bool is_inline,
+                          Formatter format);
 
   void GenerateConstructorBody(io::Printer* printer,
                                std::vector<bool> already_processed,
@@ -206,15 +197,16 @@
   string classname_;
   Options options_;
   FieldGeneratorMap field_generators_;
-  // optimized_order_ is the order we layout the message's fields in the class.
-  // This is reused to initialize the fields in-order for cache efficiency.
+  // optimized_order_ is the order we layout the message's fields in the
+  // class. This is reused to initialize the fields in-order for cache
+  // efficiency.
   //
   // optimized_order_ excludes oneof fields and weak fields.
-  std::vector<const FieldDescriptor *> optimized_order_;
+  std::vector<const FieldDescriptor*> optimized_order_;
   std::vector<int> has_bit_indices_;
   int max_has_bit_index_;
-  std::unique_ptr<std::unique_ptr<EnumGenerator> []> enum_generators_;
-  std::unique_ptr<std::unique_ptr<ExtensionGenerator> []> extension_generators_;
+  std::vector<const EnumGenerator*> enum_generators_;
+  std::vector<const ExtensionGenerator*> extension_generators_;
   int num_required_fields_;
   int num_weak_fields_;
   // table_driven_ indicates the generated message uses table-driven parsing.
@@ -222,8 +214,9 @@
 
   std::unique_ptr<MessageLayoutHelper> message_layout_helper_;
 
-  SCCAnalyzer* scc_analyzer_;
-  string scc_name_;
+  MessageSCCAnalyzer* scc_analyzer_;
+
+  std::map<string, string> variables_;
 
   friend class FileGenerator;
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
@@ -232,6 +225,6 @@
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index c1e15c5..afb2727 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -101,9 +101,8 @@
 
 MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
                                              const Options& options,
-                                             SCCAnalyzer* scc_analyzer)
-    : FieldGenerator(options),
-      descriptor_(descriptor),
+                                             MessageSCCAnalyzer* scc_analyzer)
+    : FieldGenerator(descriptor, options),
       implicit_weak_field_(
           IsImplicitWeakField(descriptor, options, scc_analyzer)) {
   SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
@@ -113,364 +112,388 @@
 
 void MessageFieldGenerator::
 GeneratePrivateMembers(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (implicit_weak_field_) {
-    printer->Print(variables_, "::google::protobuf::MessageLite* $name$_;\n");
+    format("::$proto_ns$::MessageLite* $name$_;\n");
   } else {
-    printer->Print(variables_, "$type$* $name$_;\n");
+    format("$type$* $name$_;\n");
   }
 }
 
 void MessageFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
-  if (implicit_weak_field_) {
-    // These private accessors are used by MergeFrom and
-    // MergePartialFromCodedStream, and their purpose is to provide access to
-    // the field without creating a strong dependency on the message type.
-    printer->Print(variables_,
-       "private:\n"
-       "const ::google::protobuf::MessageLite& _internal_$name$() const;\n"
-       "::google::protobuf::MessageLite* _internal_mutable_$name$();\n"
-       "public:\n");
-  } else {
-    // This inline accessor directly returns member field and is used in
-    // Serialize such that AFDO profile correctly captures access information to
-    // message fields under serialize.
-    printer->Print(variables_,
-       "private:\n"
-       "const $type$& _internal_$name$() const;\n"
-       "public:\n");
-  }
-  printer->Print(variables_,
-      "$deprecated_attr$const $type$& $name$() const;\n");
-  printer->Annotate("name", descriptor_);
-  printer->Print(variables_, "$deprecated_attr$$type$* $release_name$();\n");
-  printer->Annotate("release_name", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$$type$* ${$mutable_$name$$}$();\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$void ${$set_allocated_$name$$}$"
-                 "($type$* $name$);\n");
-  printer->Annotate("{", "}", descriptor_);
+  Formatter format(printer, variables_);
+  format(
+      "$deprecated_attr$const $type$& ${1$$name$$}$() const;\n"
+      "$deprecated_attr$$type$* ${1$$release_name$$}$();\n"
+      "$deprecated_attr$$type$* ${1$mutable_$name$$}$();\n"
+      "$deprecated_attr$void ${1$set_allocated_$name$$}$"
+      "($type$* $name$);\n",
+      descriptor_);
   if (SupportsArenas(descriptor_)) {
-    printer->Print(variables_,
-                   "$deprecated_attr$void "
-                   "${$unsafe_arena_set_allocated_$name$$}$(\n"
-                   "    $type$* $name$);\n");
-    printer->Annotate("{", "}", descriptor_);
-    printer->Print(
-        variables_,
-        "$deprecated_attr$$type$* ${$unsafe_arena_release_$name$$}$();\n");
-    printer->Annotate("{", "}", descriptor_);
+    format(
+        "$deprecated_attr$void "
+        "${1$unsafe_arena_set_allocated_$name$$}$(\n"
+        "    $type$* $name$);\n"
+        "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n",
+        descriptor_);
   }
 }
 
 void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
     io::Printer* printer) const {
-  if (implicit_weak_field_) {
-    printer->Print(variables_,
-      "const ::google::protobuf::MessageLite& $classname$::_internal_$name$() const {\n"
-      "  if ($name$_ != NULL) {\n"
-      "    return *$name$_;\n"
-      "  } else if (&$type_default_instance$ != NULL) {\n"
-      "    return *reinterpret_cast<const ::google::protobuf::MessageLite*>(\n"
-      "        &$type_default_instance$);\n"
-      "  } else {\n"
-      "    return "
-      "*::google::protobuf::internal::ImplicitWeakMessage::default_instance();\n"
-      "  }\n"
-      "}\n");
-  }
+  Formatter format(printer, variables_);
   if (SupportsArenas(descriptor_)) {
-    if (implicit_weak_field_) {
-      printer->Print(variables_,
-        "::google::protobuf::MessageLite* $classname$::_internal_mutable_$name$() {\n"
-        "  $set_hasbit$\n"
-        "  if ($name$_ == NULL) {\n"
-        "    if (&$type_default_instance$ == NULL) {\n"
-        "      $name$_ = ::google::protobuf::Arena::CreateMessage<\n"
-        "          ::google::protobuf::internal::ImplicitWeakMessage>(\n"
-        "              GetArenaNoVirtual());\n"
-        "    } else {\n"
-        "      $name$_ = reinterpret_cast<const ::google::protobuf::MessageLite*>(\n"
-        "          &$type_default_instance$)->New(GetArenaNoVirtual());\n"
-        "    }\n"
+    format(
+        "void $classname$::unsafe_arena_set_allocated_$name$(\n"
+        "    $type$* $name$) {\n"
+        // If we're not on an arena, free whatever we were holding before.
+        // (If we are on arena, we can just forget the earlier pointer.)
+        "  if (GetArenaNoVirtual() == NULL) {\n"
+        "    delete $name$_;\n"
         "  }\n"
-        "  return $name$_;\n"
-        "}\n");
-    }
-
-    printer->Print(variables_,
-      "void $classname$::unsafe_arena_set_allocated_$name$(\n"
-      "    $type$* $name$) {\n"
-      // If we're not on an arena, free whatever we were holding before.
-      // (If we are on arena, we can just forget the earlier pointer.)
-      "  if (GetArenaNoVirtual() == NULL) {\n"
-      "    delete $name$_;\n"
-      "  }\n"
-      "  $name$_ = $name$;\n"
-      "  if ($name$) {\n"
-      "    $set_hasbit$\n"
-      "  } else {\n"
-      "    $clear_hasbit$\n"
-      "  }\n"
-      "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
-      ":$full_name$)\n"
-      "}\n");
-  } else if (implicit_weak_field_) {
-    printer->Print(variables_,
-        "::google::protobuf::MessageLite* $classname$::_internal_mutable_$name$() {\n"
-        "  $set_hasbit$\n"
-        "  if ($name$_ == NULL) {\n"
-        "    if (&$type_default_instance$ == NULL) {\n"
-        "      $name$_ = new ::google::protobuf::internal::ImplicitWeakMessage;\n"
-        "    } else {\n"
-        "      $name$_ = reinterpret_cast<const ::google::protobuf::MessageLite*>(\n"
-        "          &$type_default_instance$)->New();\n"
-        "    }\n"
+        "  $name$_ = $name$;\n"
+        "  if ($name$) {\n"
+        "    $set_hasbit$\n"
+        "  } else {\n"
+        "    $clear_hasbit$\n"
         "  }\n"
-        "  return $name$_;\n"
+        "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
+        ":$full_name$)\n"
         "}\n");
   }
 }
 
 void MessageFieldGenerator::
 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  if (!implicit_weak_field_) {
-    printer->Print(variables_,
-      "inline const $type$& $classname$::_internal_$name$() const {\n"
-      "  return *$field_member$;\n"
+  Formatter format(printer, variables_);
+  format(
+      "inline const $type$& $classname$::$name$() const {\n"
+      "  const $type$* p = $casted_member$;\n"
+      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+      "  return p != NULL ? *p : *reinterpret_cast<const $type$*>(\n"
+      "      &$type_default_instance$);\n"
       "}\n");
-  }
-  printer->Print(variables_,
-    "inline const $type$& $classname$::$name$() const {\n"
-    "  const $type$* p = $casted_member$;\n"
-    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
-    "  return p != NULL ? *p : *reinterpret_cast<const $type$*>(\n"
-    "      &$type_default_instance$);\n"
-    "}\n");
 
-  printer->Print(variables_,
-    "inline $type$* $classname$::$release_name$() {\n"
-    "  // @@protoc_insertion_point(field_release:$full_name$)\n"
-    "$type_reference_function$"
-    "  $clear_hasbit$\n"
-    "  $type$* temp = $casted_member$;\n");
-  if (SupportsArenas(descriptor_)) {
-    printer->Print(variables_,
-      "  if (GetArenaNoVirtual() != NULL) {\n"
-      "    temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);\n"
-      "  }\n");
-  }
-  printer->Print(variables_,
-    "  $name$_ = NULL;\n"
-    "  return temp;\n"
-    "}\n");
-
-  if (SupportsArenas(descriptor_)) {
-    printer->Print(variables_,
-      "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
-      "  // @@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
+  format(
+      "inline $type$* $classname$::$release_name$() {\n"
+      "  // @@protoc_insertion_point(field_release:$full_name$)\n"
       "$type_reference_function$"
       "  $clear_hasbit$\n"
-      "  $type$* temp = $casted_member$;\n"
+      "  $type$* temp = $casted_member$;\n");
+  if (SupportsArenas(descriptor_)) {
+    format(
+        "  if (GetArenaNoVirtual() != NULL) {\n"
+        "    temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
+        "  }\n");
+  }
+  format(
       "  $name$_ = NULL;\n"
       "  return temp;\n"
       "}\n");
+
+  if (SupportsArenas(descriptor_)) {
+    format(
+        "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
+        "  // "
+        "@@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
+        "$type_reference_function$"
+        "  $clear_hasbit$\n"
+        "  $type$* temp = $casted_member$;\n"
+        "  $name$_ = NULL;\n"
+        "  return temp;\n"
+        "}\n");
   }
 
-  printer->Print(variables_,
-    "inline $type$* $classname$::mutable_$name$() {\n"
-    "  $set_hasbit$\n"
-    "  if ($name$_ == NULL) {\n"
-    "    auto* p = CreateMaybeMessage<$type$>(GetArenaNoVirtual());\n");
+  format(
+      "inline $type$* $classname$::mutable_$name$() {\n"
+      "  $set_hasbit$\n"
+      "  if ($name$_ == NULL) {\n"
+      "    auto* p = CreateMaybeMessage<$type$>(GetArenaNoVirtual());\n");
   if (implicit_weak_field_) {
-    printer->Print(variables_,
-      "    $name$_ = reinterpret_cast<::google::protobuf::MessageLite*>(p);\n");
+    format("    $name$_ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n");
   } else {
-    printer->Print(variables_,
-      "    $name$_ = p;\n");
+    format("    $name$_ = p;\n");
   }
-  printer->Print(variables_,
-    "  }\n"
-    "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
-    "  return $casted_member$;\n"
-    "}\n");
+  format(
+      "  }\n"
+      "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+      "  return $casted_member$;\n"
+      "}\n");
 
   // We handle the most common case inline, and delegate less common cases to
   // the slow fallback function.
-  printer->Print(variables_,
-    "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
-    "  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();\n");
-  printer->Print(variables_,
-    "  if (message_arena == NULL) {\n");
+  format(
+      "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
+      "  ::$proto_ns$::Arena* message_arena = GetArenaNoVirtual();\n");
+  format("  if (message_arena == NULL) {\n");
   if (IsCrossFileMessage(descriptor_)) {
-    printer->Print(variables_,
-      "    delete reinterpret_cast< ::google::protobuf::MessageLite*>($name$_);\n");
+    format(
+        "    delete reinterpret_cast< ::$proto_ns$::MessageLite*>($name$_);\n");
   } else {
-    printer->Print(variables_,
-      "    delete $name$_;\n");
+    format("    delete $name$_;\n");
   }
-  printer->Print(variables_,
-    "  }\n"
-    "  if ($name$) {\n");
+  format(
+      "  }\n"
+      "  if ($name$) {\n");
   if (SupportsArenas(descriptor_->message_type()) &&
       IsCrossFileMessage(descriptor_)) {
     // We have to read the arena through the virtual method, because the type
     // isn't defined in this file.
-    printer->Print(variables_,
-      "    ::google::protobuf::Arena* submessage_arena =\n"
-      "      reinterpret_cast<::google::protobuf::MessageLite*>($name$)->GetArena();\n");
+    format(
+        "    ::$proto_ns$::Arena* submessage_arena =\n"
+        "      "
+        "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n");
   } else if (!SupportsArenas(descriptor_->message_type())) {
-    printer->Print(variables_,
-      "    ::google::protobuf::Arena* submessage_arena = NULL;\n");
+    format("    ::$proto_ns$::Arena* submessage_arena = NULL;\n");
   } else {
-    printer->Print(variables_,
-      "    ::google::protobuf::Arena* submessage_arena =\n"
-      "      ::google::protobuf::Arena::GetArena($name$);\n");
+    format(
+        "    ::$proto_ns$::Arena* submessage_arena =\n"
+        "      ::$proto_ns$::Arena::GetArena($name$);\n");
   }
-  printer->Print(variables_,
-    "    if (message_arena != submessage_arena) {\n"
-    "      $name$ = ::google::protobuf::internal::GetOwnedMessage(\n"
-    "          message_arena, $name$, submessage_arena);\n"
-    "    }\n"
-    "    $set_hasbit$\n"
-    "  } else {\n"
-    "    $clear_hasbit$\n"
-    "  }\n");
+  format(
+      "    if (message_arena != submessage_arena) {\n"
+      "      $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
+      "          message_arena, $name$, submessage_arena);\n"
+      "    }\n"
+      "    $set_hasbit$\n"
+      "  } else {\n"
+      "    $clear_hasbit$\n"
+      "  }\n");
   if (implicit_weak_field_) {
-    printer->Print(variables_,
-      "  $name$_ = reinterpret_cast<MessageLite*>($name$);\n");
+    format("  $name$_ = reinterpret_cast<MessageLite*>($name$);\n");
   } else {
-    printer->Print(variables_,
-      "  $name$_ = $name$;\n");
+    format("  $name$_ = $name$;\n");
   }
-  printer->Print(variables_,
-    "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
-    "}\n");
+  format(
+      "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+      "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateInternalAccessorDeclarations(io::Printer* printer) const {
+  Formatter format(printer, variables_);
+  if (implicit_weak_field_) {
+    format(
+        "static const ::$proto_ns$::MessageLite& $name$("
+        "const $classname$* msg);\n"
+        "static ::$proto_ns$::MessageLite* mutable_$name$("
+        "$classname$* msg);\n");
+  } else {
+    format("static const $type$& $name$(const $classname$* msg);\n");
+  }
+}
+
+void MessageFieldGenerator::
+GenerateInternalAccessorDefinitions(io::Printer* printer) const {
+  // In theory, these accessors could be inline in HasBitSetters. However, in
+  // practice, the linker is then not able to throw them out making implicit
+  // weak dependencies not work at all.
+  Formatter format(printer, variables_);
+  if (implicit_weak_field_) {
+    // These private accessors are used by MergeFrom and
+    // MergePartialFromCodedStream, and their purpose is to provide access to
+    // the field without creating a strong dependency on the message type.
+    format(
+        "const ::$proto_ns$::MessageLite& $classname$::HasBitSetters::$name$(\n"
+        "    const $classname$* msg) {\n"
+        "  if (msg->$name$_ != NULL) {\n"
+        "    return *msg->$name$_;\n"
+        "  } else if (&$type_default_instance$ != NULL) {\n"
+        "    return *reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
+        "        &$type_default_instance$);\n"
+        "  } else {\n"
+        "    return "
+        "*::$proto_ns$::internal::ImplicitWeakMessage::default_instance();\n"
+        "  }\n"
+        "}\n");
+    if (SupportsArenas(descriptor_)) {
+      format(
+          "::$proto_ns$::MessageLite*\n"
+          "$classname$::HasBitSetters::mutable_$name$($classname$* msg) {\n");
+      if (HasFieldPresence(descriptor_->file())) {
+        format("  msg->$set_hasbit$\n");
+      }
+      format(
+          "  if (msg->$name$_ == NULL) {\n"
+          "    if (&$type_default_instance$ == NULL) {\n"
+          "      msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n"
+          "          ::$proto_ns$::internal::ImplicitWeakMessage>(\n"
+          "              msg->GetArenaNoVirtual());\n"
+          "    } else {\n"
+          "      msg->$name$_ = reinterpret_cast<const "
+          "::$proto_ns$::MessageLite*>(\n"
+          "          &$type_default_instance$)->New("
+          "msg->GetArenaNoVirtual());\n"
+          "    }\n"
+          "  }\n"
+          "  return msg->$name$_;\n"
+          "}\n");
+    } else {
+      format(
+          "::$proto_ns$::MessageLite*\n"
+          "$classname$::HasBitSetters::mutable_$name$($classname$* msg) {\n");
+      if (HasFieldPresence(descriptor_->file())) {
+        format("  msg->$set_hasbit$\n");
+      }
+      format(
+          "  if (msg->$name$_ == NULL) {\n"
+          "    if (&$type_default_instance$ == NULL) {\n"
+          "      msg->$name$_ = "
+          "new ::$proto_ns$::internal::ImplicitWeakMessage;\n"
+          "    } else {\n"
+          "      msg->$name$_ = "
+          "reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
+          "          &$type_default_instance$)->New();\n"
+          "    }\n"
+          "  }\n"
+          "  return msg->$name$_;\n"
+          "}\n");
+    }
+  } else {
+    // This inline accessor directly returns member field and is used in
+    // Serialize such that AFDO profile correctly captures access information to
+    // message fields under serialize.
+    format(
+        "const $type$&\n"
+        "$classname$::HasBitSetters::$name$(const $classname$* msg) {\n"
+        "  return *msg->$field_member$;\n"
+        "}\n");
+  }
 }
 
 void MessageFieldGenerator::
 GenerateClearingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (!HasFieldPresence(descriptor_->file())) {
     // If we don't have has-bits, message presence is indicated only by ptr !=
     // NULL. Thus on clear, we need to delete the object.
-    printer->Print(variables_,
-      "if (GetArenaNoVirtual() == NULL && $name$_ != NULL) {\n"
-      "  delete $name$_;\n"
-      "}\n"
-      "$name$_ = NULL;\n");
+    format(
+        "if (GetArenaNoVirtual() == NULL && $name$_ != NULL) {\n"
+        "  delete $name$_;\n"
+        "}\n"
+        "$name$_ = NULL;\n");
   } else {
-    printer->Print(variables_,
-      "if ($name$_ != NULL) $name$_->Clear();\n");
+    format("if ($name$_ != NULL) $name$_->Clear();\n");
   }
 }
 
 void MessageFieldGenerator::
 GenerateMessageClearingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (!HasFieldPresence(descriptor_->file())) {
     // If we don't have has-bits, message presence is indicated only by ptr !=
     // NULL. Thus on clear, we need to delete the object.
-    printer->Print(variables_,
-      "if (GetArenaNoVirtual() == NULL && $name$_ != NULL) {\n"
-      "  delete $name$_;\n"
-      "}\n"
-      "$name$_ = NULL;\n");
+    format(
+        "if (GetArenaNoVirtual() == NULL && $name$_ != NULL) {\n"
+        "  delete $name$_;\n"
+        "}\n"
+        "$name$_ = NULL;\n");
   } else {
-    printer->Print(variables_,
-      "GOOGLE_DCHECK($name$_ != NULL);\n"
-      "$name$_->Clear();\n");
+    format(
+        "$DCHK$($name$_ != NULL);\n"
+        "$name$_->Clear();\n");
   }
 }
 
 void MessageFieldGenerator::
 GenerateMergingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (implicit_weak_field_) {
-    printer->Print(variables_,
-      "_internal_mutable_$name$()->CheckTypeAndMergeFrom(\n"
-      "    from._internal_$name$());\n");
+    format(
+        "HasBitSetters::mutable_$name$(this)->CheckTypeAndMergeFrom(\n"
+        "    HasBitSetters::$name$(&from));\n");
   } else {
-    printer->Print(variables_,
-      "mutable_$name$()->$type$::MergeFrom(from.$name$());\n");
+    format("mutable_$name$()->$type$::MergeFrom(from.$name$());\n");
   }
 }
 
 void MessageFieldGenerator::
 GenerateSwappingCode(io::Printer* printer) const {
-  printer->Print(variables_, "swap($name$_, other->$name$_);\n");
+  Formatter format(printer, variables_);
+  format("swap($name$_, other->$name$_);\n");
 }
 
 void MessageFieldGenerator::
 GenerateDestructorCode(io::Printer* printer) const {
-  // TODO(gerbens) Remove this when we don't need to destruct default instances.
-  // In google3 a default instance will never get deleted so we don't need to
-  // worry about that but in opensource protobuf default instances are deleted
-  // in shutdown process and we need to take special care when handling them.
-  printer->Print(variables_,
-    "if (this != internal_default_instance()) ");
-  printer->Print(variables_, "delete $name$_;\n");
+  Formatter format(printer, variables_);
+  if (options_.opensource_runtime) {
+    // TODO(gerbens) Remove this when we don't need to destruct default
+    // instances.  In google3 a default instance will never get deleted so we
+    // don't need to worry about that but in opensource protobuf default
+    // instances are deleted in shutdown process and we need to take special
+    // care when handling them.
+    format("if (this != internal_default_instance()) ");
+  }
+  format("delete $name$_;\n");
 }
 
 void MessageFieldGenerator::
 GenerateConstructorCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_ = NULL;\n");
+  Formatter format(printer, variables_);
+  format("$name$_ = NULL;\n");
 }
 
 void MessageFieldGenerator::
 GenerateCopyConstructorCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "if (from.has_$name$()) {\n"
-    "  $name$_ = new $type$(*from.$name$_);\n"
-    "} else {\n"
-    "  $name$_ = NULL;\n"
-    "}\n");
+  Formatter format(printer, variables_);
+  format(
+      "if (from.has_$name$()) {\n"
+      "  $name$_ = new $type$(*from.$name$_);\n"
+      "} else {\n"
+      "  $name$_ = NULL;\n"
+      "}\n");
 }
 
 void MessageFieldGenerator::
 GenerateMergeFromCodedStream(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (implicit_weak_field_) {
-    printer->Print(variables_,
-      "DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(\n"
-      "     input, _internal_mutable_$name$()));\n");
+    format(
+        "DO_(::$proto_ns$::internal::WireFormatLite::ReadMessage(\n"
+        "     input, HasBitSetters::mutable_$name$(this)));\n");
   } else if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
-    printer->Print(variables_,
-      "DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(\n"
-      "     input, mutable_$name$()));\n");
+    format(
+        "DO_(::$proto_ns$::internal::WireFormatLite::ReadMessage(\n"
+        "     input, mutable_$name$()));\n");
   } else {
-    printer->Print(variables_,
-      "DO_(::google::protobuf::internal::WireFormatLite::ReadGroup(\n"
-      "      $number$, input, mutable_$name$()));\n");
+    format(
+        "DO_(::$proto_ns$::internal::WireFormatLite::ReadGroup(\n"
+        "      $number$, input, mutable_$name$()));\n");
   }
 }
 
 void MessageFieldGenerator::
 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
-  printer->Print(variables_,
-    "::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
-    "  $number$, this->_internal_$name$(), output);\n");
+  Formatter format(printer, variables_);
+  format(
+      "::$proto_ns$::internal::WireFormatLite::Write$stream_writer$(\n"
+      "  $number$, HasBitSetters::$name$(this), output);\n");
 }
 
 void MessageFieldGenerator::
 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
-  printer->Print(variables_,
-    "target = ::google::protobuf::internal::WireFormatLite::\n"
-    "  InternalWrite$declared_type$ToArray(\n"
-    "    $number$, this->_internal_$name$(), deterministic, target);\n");
+  Formatter format(printer, variables_);
+  format(
+      "target = ::$proto_ns$::internal::WireFormatLite::\n"
+      "  InternalWrite$declared_type$ToArray(\n"
+      "    $number$, HasBitSetters::$name$(this), deterministic, target);\n");
 }
 
 void MessageFieldGenerator::
 GenerateByteSize(io::Printer* printer) const {
-  printer->Print(variables_,
-    "total_size += $tag_size$ +\n"
-    "  ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
-    "    *$field_member$);\n");
+  Formatter format(printer, variables_);
+  format(
+      "total_size += $tag_size$ +\n"
+      "  ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
+      "    *$field_member$);\n");
 }
 
 // ===================================================================
 
 MessageOneofFieldGenerator::MessageOneofFieldGenerator(
     const FieldDescriptor* descriptor, const Options& options,
-    SCCAnalyzer* scc_analyzer)
+    MessageSCCAnalyzer* scc_analyzer)
     : MessageFieldGenerator(descriptor, options, scc_analyzer) {
   SetCommonOneofFieldVariables(descriptor, &variables_);
 }
@@ -479,126 +502,122 @@
 
 void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
     io::Printer* printer) const {
-  printer->Print(variables_,
-    "void $classname$::set_allocated_$name$($type$* $name$) {\n"
-    "  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();\n"
-    "  clear_$oneof_name$();\n"
-    "  if ($name$) {\n");
+  Formatter format(printer, variables_);
+  format(
+      "void $classname$::set_allocated_$name$($type$* $name$) {\n"
+      "  ::$proto_ns$::Arena* message_arena = GetArenaNoVirtual();\n"
+      "  clear_$oneof_name$();\n"
+      "  if ($name$) {\n");
   if (SupportsArenas(descriptor_->message_type()) &&
       descriptor_->file() != descriptor_->message_type()->file()) {
     // We have to read the arena through the virtual method, because the type
     // isn't defined in this file.
-    printer->Print(variables_,
-      "    ::google::protobuf::Arena* submessage_arena =\n"
-      "      reinterpret_cast<::google::protobuf::MessageLite*>($name$)->GetArena();\n");
+    format(
+        "    ::$proto_ns$::Arena* submessage_arena =\n"
+        "      "
+        "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n");
   } else if (!SupportsArenas(descriptor_->message_type())) {
-    printer->Print(variables_,
-      "    ::google::protobuf::Arena* submessage_arena = NULL;\n");
+    format("    ::$proto_ns$::Arena* submessage_arena = NULL;\n");
   } else {
-    printer->Print(variables_,
-      "    ::google::protobuf::Arena* submessage_arena =\n"
-      "      ::google::protobuf::Arena::GetArena($name$);\n");
+    format(
+        "    ::$proto_ns$::Arena* submessage_arena =\n"
+        "      ::$proto_ns$::Arena::GetArena($name$);\n");
   }
-  printer->Print(variables_,
-    "    if (message_arena != submessage_arena) {\n"
-    "      $name$ = ::google::protobuf::internal::GetOwnedMessage(\n"
-    "          message_arena, $name$, submessage_arena);\n"
-    "    }\n"
-    "    set_has_$name$();\n"
-    "    $field_member$ = $name$;\n"
-    "  }\n"
-    "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
-    "}\n");
+  format(
+      "    if (message_arena != submessage_arena) {\n"
+      "      $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
+      "          message_arena, $name$, submessage_arena);\n"
+      "    }\n"
+      "    set_has_$name$();\n"
+      "    $field_member$ = $name$;\n"
+      "  }\n"
+      "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+      "}\n");
 }
 
 void MessageOneofFieldGenerator::
 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  if (!implicit_weak_field_) {
-    printer->Print(variables_,
-      "inline const $type$& $classname$::_internal_$name$() const {\n"
-      "  return *$field_member$;\n"
-      "}\n");
-  }
-  printer->Print(variables_,
-    "inline $type$* $classname$::$release_name$() {\n"
-    "  // @@protoc_insertion_point(field_release:$full_name$)\n"
-    "  if (has_$name$()) {\n"
-    "    clear_has_$oneof_name$();\n"
-    "      $type$* temp = $field_member$;\n");
-  if (SupportsArenas(descriptor_)) {
-    printer->Print(variables_,
-      "    if (GetArenaNoVirtual() != NULL) {\n"
-      "      temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);\n"
-      "    }\n");
-  }
-  printer->Print(variables_,
-    "    $field_member$ = NULL;\n"
-    "    return temp;\n"
-    "  } else {\n"
-    "    return NULL;\n"
-    "  }\n"
-    "}\n");
-
-  printer->Print(variables_,
-    "inline const $type$& $classname$::$name$() const {\n"
-    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
-    "  return has_$name$()\n"
-    "      ? *$field_member$\n"
-    "      : *reinterpret_cast< $type$*>(&$type_default_instance$);\n"
-    "}\n");
-
-  if (SupportsArenas(descriptor_)) {
-    printer->Print(variables_,
-      "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
-      "  // @@protoc_insertion_point(field_unsafe_arena_release"
-      ":$full_name$)\n"
+  Formatter format(printer, variables_);
+  format(
+      "inline $type$* $classname$::$release_name$() {\n"
+      "  // @@protoc_insertion_point(field_release:$full_name$)\n"
       "  if (has_$name$()) {\n"
       "    clear_has_$oneof_name$();\n"
-      "    $type$* temp = $field_member$;\n"
+      "      $type$* temp = $field_member$;\n");
+  if (SupportsArenas(descriptor_)) {
+    format(
+        "    if (GetArenaNoVirtual() != NULL) {\n"
+        "      temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
+        "    }\n");
+  }
+  format(
       "    $field_member$ = NULL;\n"
       "    return temp;\n"
       "  } else {\n"
       "    return NULL;\n"
       "  }\n"
-      "}\n"
-      "inline void $classname$::unsafe_arena_set_allocated_$name$"
-      "($type$* $name$) {\n"
-      // We rely on the oneof clear method to free the earlier contents of this
-      // oneof. We can directly use the pointer we're given to set the new
-      // value.
-      "  clear_$oneof_name$();\n"
-      "  if ($name$) {\n"
-      "    set_has_$name$();\n"
-      "    $field_member$ = $name$;\n"
-      "  }\n"
-      "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
-      "$full_name$)\n"
       "}\n");
+
+  format(
+      "inline const $type$& $classname$::$name$() const {\n"
+      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+      "  return has_$name$()\n"
+      "      ? *$field_member$\n"
+      "      : *reinterpret_cast< $type$*>(&$type_default_instance$);\n"
+      "}\n");
+
+  if (SupportsArenas(descriptor_)) {
+    format(
+        "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
+        "  // @@protoc_insertion_point(field_unsafe_arena_release"
+        ":$full_name$)\n"
+        "  if (has_$name$()) {\n"
+        "    clear_has_$oneof_name$();\n"
+        "    $type$* temp = $field_member$;\n"
+        "    $field_member$ = NULL;\n"
+        "    return temp;\n"
+        "  } else {\n"
+        "    return NULL;\n"
+        "  }\n"
+        "}\n"
+        "inline void $classname$::unsafe_arena_set_allocated_$name$"
+        "($type$* $name$) {\n"
+        // We rely on the oneof clear method to free the earlier contents of
+        // this oneof. We can directly use the pointer we're given to set the
+        // new value.
+        "  clear_$oneof_name$();\n"
+        "  if ($name$) {\n"
+        "    set_has_$name$();\n"
+        "    $field_member$ = $name$;\n"
+        "  }\n"
+        "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
+        "$full_name$)\n"
+        "}\n");
   }
 
-  printer->Print(variables_,
-    "inline $type$* $classname$::mutable_$name$() {\n"
-    "  if (!has_$name$()) {\n"
-    "    clear_$oneof_name$();\n"
-    "    set_has_$name$();\n"
-    "    $field_member$ = CreateMaybeMessage< $type$ >(\n"
-    "        GetArenaNoVirtual());\n"
-    "  }\n"
-    "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
-    "  return $field_member$;\n"
-    "}\n");
+  format(
+      "inline $type$* $classname$::mutable_$name$() {\n"
+      "  if (!has_$name$()) {\n"
+      "    clear_$oneof_name$();\n"
+      "    set_has_$name$();\n"
+      "    $field_member$ = CreateMaybeMessage< $type$ >(\n"
+      "        GetArenaNoVirtual());\n"
+      "  }\n"
+      "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+      "  return $field_member$;\n"
+      "}\n");
 }
 
 void MessageOneofFieldGenerator::
 GenerateClearingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (SupportsArenas(descriptor_)) {
-    printer->Print(variables_,
-      "if (GetArenaNoVirtual() == NULL) {\n"
-      "  delete $field_member$;\n"
-      "}\n");
+    format(
+        "if (GetArenaNoVirtual() == NULL) {\n"
+        "  delete $field_member$;\n"
+        "}\n");
   } else {
-    printer->Print(variables_,
-      "delete $field_member$;\n");
+    format("delete $field_member$;\n");
   }
 }
 
@@ -628,9 +647,8 @@
 
 RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
     const FieldDescriptor* descriptor, const Options& options,
-    SCCAnalyzer* scc_analyzer)
-    : FieldGenerator(options),
-      descriptor_(descriptor),
+    MessageSCCAnalyzer* scc_analyzer)
+    : FieldGenerator(descriptor, options),
       implicit_weak_field_(
           IsImplicitWeakField(descriptor, options, scc_analyzer)) {
   SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
@@ -640,108 +658,101 @@
 
 void RepeatedMessageFieldGenerator::
 GeneratePrivateMembers(io::Printer* printer) const {
-  printer->Print(variables_,
-    "::google::protobuf::RepeatedPtrField< $type$ > $name$_;\n");
+  Formatter format(printer, variables_);
+  format("::$proto_ns$::RepeatedPtrField< $type$ > $name$_;\n");
 }
 
 void RepeatedMessageFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
-  printer->Print(variables_,
-                 "$deprecated_attr$$type$* ${$mutable_$name$$}$(int index);\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$::google::protobuf::RepeatedPtrField< $type$ >*\n"
-                 "    ${$mutable_$name$$}$();\n");
-  printer->Annotate("{", "}", descriptor_);
-
-  printer->Print(variables_,
-    "$deprecated_attr$const $type$& $name$(int index) const;\n");
-  printer->Annotate("name", descriptor_);
-  printer->Print(variables_, "$deprecated_attr$$type$* ${$add_$name$$}$();\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-    "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
-    "    $name$() const;\n");
-  printer->Annotate("name", descriptor_);
+  Formatter format(printer, variables_);
+  format(
+      "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index);\n"
+      "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
+      "    ${1$mutable_$name$$}$();\n"
+      "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const;\n"
+      "$deprecated_attr$$type$* ${1$add_$name$$}$();\n"
+      "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
+      "    ${1$$name$$}$() const;\n",
+      descriptor_);
 }
 
 void RepeatedMessageFieldGenerator::
 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline $type$* $classname$::mutable_$name$(int index) {\n"
-    // TODO(dlj): move insertion points
-    "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
-    "$type_reference_function$"
-    "  return $name$_.Mutable(index);\n"
-    "}\n"
-    "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
-    "$classname$::mutable_$name$() {\n"
-    "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
-    "$type_reference_function$"
-    "  return &$name$_;\n"
-    "}\n");
+  Formatter format(printer, variables_);
+  format(
+      "inline $type$* $classname$::mutable_$name$(int index) {\n"
+      // TODO(dlj): move insertion points
+      "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+      "$type_reference_function$"
+      "  return $name$_.Mutable(index);\n"
+      "}\n"
+      "inline ::$proto_ns$::RepeatedPtrField< $type$ >*\n"
+      "$classname$::mutable_$name$() {\n"
+      "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+      "$type_reference_function$"
+      "  return &$name$_;\n"
+      "}\n");
 
   if (options_.safe_boundary_check) {
-    printer->Print(variables_,
-      "inline const $type$& $classname$::$name$(int index) const {\n"
-      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
-      "  return $name$_.InternalCheckedGet(index,\n"
-      "      *reinterpret_cast<const $type$*>(&$type_default_instance$));\n"
-      "}\n");
+    format(
+        "inline const $type$& $classname$::$name$(int index) const {\n"
+        "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+        "  return $name$_.InternalCheckedGet(index,\n"
+        "      *reinterpret_cast<const $type$*>(&$type_default_instance$));\n"
+        "}\n");
   } else {
-    printer->Print(variables_,
-      "inline const $type$& $classname$::$name$(int index) const {\n"
-      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
-      "$type_reference_function$"
-      "  return $name$_.Get(index);\n"
-      "}\n");
+    format(
+        "inline const $type$& $classname$::$name$(int index) const {\n"
+        "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+        "$type_reference_function$"
+        "  return $name$_.Get(index);\n"
+        "}\n");
   }
 
-  printer->Print(variables_,
-    "inline $type$* $classname$::add_$name$() {\n"
-    "  // @@protoc_insertion_point(field_add:$full_name$)\n"
-    "  return $name$_.Add();\n"
-    "}\n");
+  format(
+      "inline $type$* $classname$::add_$name$() {\n"
+      "  // @@protoc_insertion_point(field_add:$full_name$)\n"
+      "  return $name$_.Add();\n"
+      "}\n");
 
-  printer->Print(variables_,
-    "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
-    "$classname$::$name$() const {\n"
-    "  // @@protoc_insertion_point(field_list:$full_name$)\n"
-    "$type_reference_function$"
-    "  return $name$_;\n"
-    "}\n");
+  format(
+      "inline const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
+      "$classname$::$name$() const {\n"
+      "  // @@protoc_insertion_point(field_list:$full_name$)\n"
+      "$type_reference_function$"
+      "  return $name$_;\n"
+      "}\n");
 }
 
 void RepeatedMessageFieldGenerator::
 GenerateClearingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (implicit_weak_field_) {
-    printer->Print(
-        variables_,
+    format(
         "CastToBase(&$name$_)->Clear<"
-        "::google::protobuf::internal::ImplicitWeakTypeHandler<$type$>>();\n");
+        "::$proto_ns$::internal::ImplicitWeakTypeHandler<$type$>>();\n");
   } else {
-    printer->Print(variables_, "$name$_.Clear();\n");
+    format("$name$_.Clear();\n");
   }
 }
 
 void RepeatedMessageFieldGenerator::
 GenerateMergingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (implicit_weak_field_) {
-    printer->Print(
-        variables_,
+    format(
         "CastToBase(&$name$_)->MergeFrom<"
-        "::google::protobuf::internal::ImplicitWeakTypeHandler<$type$>>(CastToBase("
+        "::$proto_ns$::internal::ImplicitWeakTypeHandler<$type$>>(CastToBase("
         "from.$name$_));\n");
   } else {
-    printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+    format("$name$_.MergeFrom(from.$name$_);\n");
   }
 }
 
 void RepeatedMessageFieldGenerator::
 GenerateSwappingCode(io::Printer* printer) const {
-  printer->Print(
-      variables_,
-      "CastToBase(&$name$_)->InternalSwap(CastToBase(&other->$name$_));\n");
+  Formatter format(printer, variables_);
+  format("CastToBase(&$name$_)->InternalSwap(CastToBase(&other->$name$_));\n");
 }
 
 void RepeatedMessageFieldGenerator::
@@ -751,83 +762,85 @@
 
 void RepeatedMessageFieldGenerator::
 GenerateMergeFromCodedStream(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
     if (implicit_weak_field_) {
-      printer->Print(variables_,
-        "DO_(::google::protobuf::internal::WireFormatLite::"
-        "ReadMessage(input, CastToBase(&$name$_)->AddWeak(\n"
-        "    reinterpret_cast<const ::google::protobuf::MessageLite*>(\n"
-        "        &$type_default_instance$))));\n");
+      format(
+          "DO_(::$proto_ns$::internal::WireFormatLite::"
+          "ReadMessage(input, CastToBase(&$name$_)->AddWeak(\n"
+          "    reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
+          "        &$type_default_instance$))));\n");
     } else {
-      printer->Print(variables_,
-        "DO_(::google::protobuf::internal::WireFormatLite::"
-        "ReadMessage(\n"
-        "      input, add_$name$()));\n");
+      format(
+          "DO_(::$proto_ns$::internal::WireFormatLite::"
+          "ReadMessage(\n"
+          "      input, add_$name$()));\n");
     }
   } else {
-    printer->Print(variables_,
-      "DO_(::google::protobuf::internal::WireFormatLite::"
-      "ReadGroup($number$, input, add_$name$()));\n");
+    format(
+        "DO_(::$proto_ns$::internal::WireFormatLite::"
+        "ReadGroup($number$, input, add_$name$()));\n");
   }
 }
 
 void RepeatedMessageFieldGenerator::
 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
-  printer->Print(variables_,
-    "for (unsigned int i = 0,\n"
-    "    n = static_cast<unsigned int>(this->$name$_size()); i < n; i++) {\n"
-    "  ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
-    "    $number$,\n");
+  Formatter format(printer, variables_);
+  format(
+      "for (unsigned int i = 0,\n"
+      "    n = static_cast<unsigned int>(this->$name$_size()); i < n; i++) {\n"
+      "  ::$proto_ns$::internal::WireFormatLite::Write$stream_writer$(\n"
+      "    $number$,\n");
   if (implicit_weak_field_) {
-    printer->Print(
-        variables_,
+    format(
         "    CastToBase($name$_).Get<"
-        "::google::protobuf::internal::ImplicitWeakTypeHandler<$type$>>("
+        "::$proto_ns$::internal::ImplicitWeakTypeHandler<$type$>>("
         "static_cast<int>(i)),\n");
   } else {
-    printer->Print(variables_,
-      "    this->$name$(static_cast<int>(i)),\n");
+    format("    this->$name$(static_cast<int>(i)),\n");
   }
-  printer->Print(variables_,
-    "    output);\n"
-    "}\n");
+  format(
+      "    output);\n"
+      "}\n");
 }
 
 void RepeatedMessageFieldGenerator::
 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
-  printer->Print(variables_,
-    "for (unsigned int i = 0,\n"
-    "    n = static_cast<unsigned int>(this->$name$_size()); i < n; i++) {\n"
-    "  target = ::google::protobuf::internal::WireFormatLite::\n"
-    "    InternalWrite$declared_type$ToArray(\n"
-    "      $number$, this->$name$(static_cast<int>(i)), deterministic, target);\n"
-    "}\n");
+  Formatter format(printer, variables_);
+  format(
+      "for (unsigned int i = 0,\n"
+      "    n = static_cast<unsigned int>(this->$name$_size()); i < n; i++) {\n"
+      "  target = ::$proto_ns$::internal::WireFormatLite::\n"
+      "    InternalWrite$declared_type$ToArray(\n"
+      "      $number$, this->$name$(static_cast<int>(i)), deterministic, "
+      "target);\n"
+      "}\n");
 }
 
 void RepeatedMessageFieldGenerator::
 GenerateByteSize(io::Printer* printer) const {
-  printer->Print(variables_,
-    "{\n"
-    "  unsigned int count = static_cast<unsigned int>(this->$name$_size());\n");
-  printer->Indent();
-  printer->Print(variables_,
-    "total_size += $tag_size$UL * count;\n"
-    "for (unsigned int i = 0; i < count; i++) {\n"
-    "  total_size +=\n"
-    "    ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n");
+  Formatter format(printer, variables_);
+  format(
+      "{\n"
+      "  unsigned int count = static_cast<unsigned "
+      "int>(this->$name$_size());\n");
+  format.Indent();
+  format(
+      "total_size += $tag_size$UL * count;\n"
+      "for (unsigned int i = 0; i < count; i++) {\n"
+      "  total_size +=\n"
+      "    ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n");
   if (implicit_weak_field_) {
-    printer->Print(
-        variables_,
+    format(
         "      CastToBase($name$_).Get<"
-        "::google::protobuf::internal::ImplicitWeakTypeHandler<$type$>>("
+        "::$proto_ns$::internal::ImplicitWeakTypeHandler<$type$>>("
         "static_cast<int>(i)));\n");
   } else {
-    printer->Print(variables_,
-        "      this->$name$(static_cast<int>(i)));\n");
+    format("      this->$name$(static_cast<int>(i)));\n");
   }
-  printer->Print(variables_, "}\n");
-  printer->Outdent();
-  printer->Print("}\n");
+  format("}\n");
+  format.Outdent();
+  format("}\n");
 }
 
 }  // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h
index 6879539..eed8e4f 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h
@@ -48,7 +48,8 @@
 class MessageFieldGenerator : public FieldGenerator {
  public:
   MessageFieldGenerator(const FieldDescriptor* descriptor,
-                        const Options& options, SCCAnalyzer* scc_analyzer);
+                        const Options& options,
+                        MessageSCCAnalyzer* scc_analyzer);
   ~MessageFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
@@ -56,6 +57,8 @@
   void GenerateAccessorDeclarations(io::Printer* printer) const;
   void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
   void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateInternalAccessorDeclarations(io::Printer* printer) const;
+  void GenerateInternalAccessorDefinitions(io::Printer* printer) const;
   void GenerateClearingCode(io::Printer* printer) const;
   void GenerateMessageClearingCode(io::Printer* printer) const;
   void GenerateMergingCode(io::Printer* printer) const;
@@ -69,9 +72,7 @@
   void GenerateByteSize(io::Printer* printer) const;
 
  protected:
-  const FieldDescriptor* descriptor_;
   const bool implicit_weak_field_;
-  std::map<string, string> variables_;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
@@ -80,7 +81,8 @@
 class MessageOneofFieldGenerator : public MessageFieldGenerator {
  public:
   MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
-                             const Options& options, SCCAnalyzer* scc_analyzer);
+                             const Options& options,
+                             MessageSCCAnalyzer* scc_analyzer);
   ~MessageOneofFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
@@ -103,7 +105,7 @@
  public:
   RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
                                 const Options& options,
-                                SCCAnalyzer* scc_analyzer);
+                                MessageSCCAnalyzer* scc_analyzer);
   ~RepeatedMessageFieldGenerator();
 
   // implements FieldGenerator ---------------------------------------
@@ -121,9 +123,7 @@
   void GenerateByteSize(io::Printer* printer) const;
 
  private:
-  const FieldDescriptor* descriptor_;
   const bool implicit_weak_field_;
-  std::map<string, string> variables_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
 };
@@ -131,6 +131,6 @@
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h b/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h
index d502a6f..67eeff0 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h
@@ -56,6 +56,6 @@
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h
index f09885b..6a364de 100644
--- a/src/google/protobuf/compiler/cpp/cpp_options.h
+++ b/src/google/protobuf/compiler/cpp/cpp_options.h
@@ -45,39 +45,28 @@
 
 // Generator options (see generator.cc for a description of each):
 struct Options {
-  Options()
-      : safe_boundary_check(false),
-        proto_h(false),
-        transitive_pb_h(true),
-        annotate_headers(false),
-        enforce_lite(false),
-        table_driven_parsing(false),
-        table_driven_serialization(false),
-        lite_implicit_weak_fields(false),
-        bootstrap(false),
-        num_cc_files(0),
-        access_info_map(NULL) {}
-
   string dllexport_decl;
-  bool safe_boundary_check;
-  bool proto_h;
-  bool transitive_pb_h;
-  bool annotate_headers;
-  bool enforce_lite;
-  bool table_driven_parsing;
-  bool table_driven_serialization;
-  bool lite_implicit_weak_fields;
-  bool bootstrap;
-  int num_cc_files;
+  bool safe_boundary_check = false;
+  bool proto_h = false;
+  bool transitive_pb_h = true;
+  bool annotate_headers = false;
+  bool enforce_lite = false;
+  bool table_driven_parsing = false;
+  bool table_driven_serialization = false;
+  bool lite_implicit_weak_fields = false;
+  bool bootstrap = false;
+  bool opensource_runtime = false;
+  bool opensource_include_paths = false;
+  int num_cc_files = 0;
   string annotation_pragma_name;
   string annotation_guard_name;
-  const AccessInfoMap* access_info_map;
+  const AccessInfoMap* access_info_map = nullptr;
 };
 
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
-
 }  // namespace google
+
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc
index e930386..2f78bda 100644
--- a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc
@@ -106,6 +106,8 @@
 // STRING is grouped next, as our Clear/SharedCtor/SharedDtor walks it and
 // calls ArenaStringPtr::Destroy on each.
 //
+// LAZY_MESSAGE is grouped next, as it interferes with the ability to memset
+// non-repeated fields otherwise.
 //
 // MESSAGE is grouped next, as our Clear/SharedDtor code walks it and calls
 // delete on each.  We initialize these fields with a NULL pointer (see
@@ -122,6 +124,9 @@
   enum Family {
     REPEATED = 0,
     STRING = 1,
+    // Laying out LAZY_MESSAGE before MESSAGE allows a single memset to zero
+    // MESSAGE and ZERO_INITIALIZABLE fields together.
+    LAZY_MESSAGE = 2,
     MESSAGE = 3,
     ZERO_INITIALIZABLE = 4,
     OTHER = 5,
@@ -142,7 +147,9 @@
       f = STRING;
     } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
       f = MESSAGE;
-
+      if (IsLazy(field, options)) {
+        f = LAZY_MESSAGE;
+      }
     } else if (CanInitializeByZeroing(field)) {
       f = ZERO_INITIALIZABLE;
     }
diff --git a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h
index 42a3b5c..2382081 100644
--- a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h
+++ b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h
@@ -59,6 +59,6 @@
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
index ff6ba0f..4f8a23e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
@@ -219,7 +219,7 @@
                              "}\n",
                              true));
 
-  google::protobuf::compiler::CommandLineInterface cli;
+  CommandLineInterface cli;
   cli.SetInputsAreProtoPathRelative(true);
 
   CppGenerator cpp_generator;
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
index 701f9d2..2f6a050 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -83,16 +83,16 @@
                            std::map<string, string>* variables,
                            const Options& options) {
   SetCommonFieldVariables(descriptor, variables, options);
-  (*variables)["type"] = PrimitiveTypeName(descriptor->cpp_type());
-  (*variables)["default"] = DefaultValue(descriptor);
-  (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
+  (*variables)["type"] = PrimitiveTypeName(options, descriptor->cpp_type());
+  (*variables)["default"] = DefaultValue(options, descriptor);
+  (*variables)["tag"] =
+      SimpleItoa(internal::WireFormat::MakeTag(descriptor));
   int fixed_size = FixedSize(descriptor->type());
   if (fixed_size != -1) {
     (*variables)["fixed_size"] = SimpleItoa(fixed_size);
   }
-  (*variables)["wire_format_field_type"] =
-      "::google::protobuf::internal::WireFormatLite::" + FieldDescriptorProto_Type_Name(
-          static_cast<FieldDescriptorProto_Type>(descriptor->type()));
+  (*variables)["wire_format_field_type"] = FieldDescriptorProto_Type_Name(
+      static_cast<FieldDescriptorProto_Type>(descriptor->type()));
   (*variables)["full_name"] = descriptor->full_name();
 }
 
@@ -102,7 +102,7 @@
 
 PrimitiveFieldGenerator::PrimitiveFieldGenerator(
     const FieldDescriptor* descriptor, const Options& options)
-    : FieldGenerator(options), descriptor_(descriptor) {
+    : FieldGenerator(descriptor, options) {
   SetPrimitiveVariables(descriptor, &variables_, options);
 }
 
@@ -110,91 +110,103 @@
 
 void PrimitiveFieldGenerator::
 GeneratePrivateMembers(io::Printer* printer) const {
-  printer->Print(variables_, "$type$ $name$_;\n");
+  Formatter format(printer, variables_);
+  format("$type$ $name$_;\n");
 }
 
 void PrimitiveFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
-  printer->Print(variables_, "$deprecated_attr$$type$ $name$() const;\n");
-  printer->Annotate("name", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$void ${$set_$name$$}$($type$ value);\n");
-  printer->Annotate("{", "}", descriptor_);
+  Formatter format(printer, variables_);
+  format(
+      "$deprecated_attr$$type$ ${1$$name$$}$() const;\n"
+      "$deprecated_attr$void ${1$set_$name$$}$($type$ value);\n",
+      descriptor_);
 }
 
 void PrimitiveFieldGenerator::
 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline $type$ $classname$::$name$() const {\n"
-    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
-    "  return $name$_;\n"
-    "}\n"
-    "inline void $classname$::set_$name$($type$ value) {\n"
-    "  $set_hasbit$\n"
-    "  $name$_ = value;\n"
-    "  // @@protoc_insertion_point(field_set:$full_name$)\n"
-    "}\n");
+  Formatter format(printer, variables_);
+  format(
+      "inline $type$ $classname$::$name$() const {\n"
+      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+      "  return $name$_;\n"
+      "}\n"
+      "inline void $classname$::set_$name$($type$ value) {\n"
+      "  $set_hasbit$\n"
+      "  $name$_ = value;\n"
+      "  // @@protoc_insertion_point(field_set:$full_name$)\n"
+      "}\n");
 }
 
 void PrimitiveFieldGenerator::
 GenerateClearingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_ = $default$;\n");
+  Formatter format(printer, variables_);
+  format("$name$_ = $default$;\n");
 }
 
 void PrimitiveFieldGenerator::
 GenerateMergingCode(io::Printer* printer) const {
-  printer->Print(variables_, "set_$name$(from.$name$());\n");
+  Formatter format(printer, variables_);
+  format("set_$name$(from.$name$());\n");
 }
 
 void PrimitiveFieldGenerator::
 GenerateSwappingCode(io::Printer* printer) const {
-  printer->Print(variables_, "swap($name$_, other->$name$_);\n");
+  Formatter format(printer, variables_);
+  format("swap($name$_, other->$name$_);\n");
 }
 
 void PrimitiveFieldGenerator::
 GenerateConstructorCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_ = $default$;\n");
+  Formatter format(printer, variables_);
+  format("$name$_ = $default$;\n");
 }
 
 void PrimitiveFieldGenerator::
 GenerateCopyConstructorCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_ = from.$name$_;\n");
+  Formatter format(printer, variables_);
+  format("$name$_ = from.$name$_;\n");
 }
 
 void PrimitiveFieldGenerator::
 GenerateMergeFromCodedStream(io::Printer* printer) const {
-  printer->Print(variables_,
-    "$set_hasbit$\n"
-    "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
-    "         $type$, $wire_format_field_type$>(\n"
-    "       input, &$name$_)));\n");
+  Formatter format(printer, variables_);
+  format(
+      "$set_hasbit_io$\n"
+      "DO_((::$proto_ns$::internal::WireFormatLite::ReadPrimitive<\n"
+      "         $type$, "
+      "::$proto_ns$::internal::WireFormatLite::$wire_format_field_type$>(\n"
+      "       input, &$name$_)));\n");
 }
 
 void PrimitiveFieldGenerator::
 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
-  printer->Print(variables_,
-    "::google::protobuf::internal::WireFormatLite::Write$declared_type$("
+  Formatter format(printer, variables_);
+  format(
+      "::$proto_ns$::internal::WireFormatLite::Write$declared_type$("
       "$number$, this->$name$(), output);\n");
 }
 
 void PrimitiveFieldGenerator::
 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
-  printer->Print(variables_,
-    "target = ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray("
+  Formatter format(printer, variables_);
+  format(
+      "target = "
+      "::$proto_ns$::internal::WireFormatLite::Write$declared_type$ToArray("
       "$number$, this->$name$(), target);\n");
 }
 
 void PrimitiveFieldGenerator::
 GenerateByteSize(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   int fixed_size = FixedSize(descriptor_->type());
   if (fixed_size == -1) {
-    printer->Print(variables_,
-      "total_size += $tag_size$ +\n"
-      "  ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
-      "    this->$name$());\n");
+    format(
+        "total_size += $tag_size$ +\n"
+        "  ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
+        "    this->$name$());\n");
   } else {
-    printer->Print(variables_,
-      "total_size += $tag_size$ + $fixed_size$;\n");
+    format("total_size += $tag_size$ + $fixed_size$;\n");
   }
 }
 
@@ -211,27 +223,29 @@
 
 void PrimitiveOneofFieldGenerator::
 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline $type$ $classname$::$name$() const {\n"
-    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
-    "  if (has_$name$()) {\n"
-    "    return $field_member$;\n"
-    "  }\n"
-    "  return $default$;\n"
-    "}\n"
-    "inline void $classname$::set_$name$($type$ value) {\n"
-    "  if (!has_$name$()) {\n"
-    "    clear_$oneof_name$();\n"
-    "    set_has_$name$();\n"
-    "  }\n"
-    "  $field_member$ = value;\n"
-    "  // @@protoc_insertion_point(field_set:$full_name$)\n"
-    "}\n");
+  Formatter format(printer, variables_);
+  format(
+      "inline $type$ $classname$::$name$() const {\n"
+      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+      "  if (has_$name$()) {\n"
+      "    return $field_member$;\n"
+      "  }\n"
+      "  return $default$;\n"
+      "}\n"
+      "inline void $classname$::set_$name$($type$ value) {\n"
+      "  if (!has_$name$()) {\n"
+      "    clear_$oneof_name$();\n"
+      "    set_has_$name$();\n"
+      "  }\n"
+      "  $field_member$ = value;\n"
+      "  // @@protoc_insertion_point(field_set:$full_name$)\n"
+      "}\n");
 }
 
 void PrimitiveOneofFieldGenerator::
 GenerateClearingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$field_member$ = $default$;\n");
+  Formatter format(printer, variables_);
+  format("$field_member$ = $default$;\n");
 }
 
 void PrimitiveOneofFieldGenerator::
@@ -241,25 +255,27 @@
 
 void PrimitiveOneofFieldGenerator::
 GenerateConstructorCode(io::Printer* printer) const {
-  printer->Print(variables_,
-                 "$ns$::_$classname$_default_instance_.$name$_ = $default$;\n");
+  Formatter format(printer, variables_);
+  format("$ns$::_$classname$_default_instance_.$name$_ = $default$;\n");
 }
 
 void PrimitiveOneofFieldGenerator::
 GenerateMergeFromCodedStream(io::Printer* printer) const {
-  printer->Print(variables_,
-    "clear_$oneof_name$();\n"
-    "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
-    "         $type$, $wire_format_field_type$>(\n"
-    "       input, &$field_member$)));\n"
-    "set_has_$name$();\n");
+  Formatter format(printer, variables_);
+  format(
+      "clear_$oneof_name$();\n"
+      "DO_((::$proto_ns$::internal::WireFormatLite::ReadPrimitive<\n"
+      "         $type$, "
+      "::$proto_ns$::internal::WireFormatLite::$wire_format_field_type$>(\n"
+      "       input, &$field_member$)));\n"
+      "set_has_$name$();\n");
 }
 
 // ===================================================================
 
 RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
     const FieldDescriptor* descriptor, const Options& options)
-    : FieldGenerator(options), descriptor_(descriptor) {
+    : FieldGenerator(descriptor, options) {
   SetPrimitiveVariables(descriptor, &variables_, options);
 
   if (descriptor->is_packed()) {
@@ -275,77 +291,72 @@
 
 void RepeatedPrimitiveFieldGenerator::
 GeneratePrivateMembers(io::Printer* printer) const {
-  printer->Print(variables_,
-    "::google::protobuf::RepeatedField< $type$ > $name$_;\n");
+  Formatter format(printer, variables_);
+  format("::$proto_ns$::RepeatedField< $type$ > $name$_;\n");
   if (descriptor_->is_packed() &&
       HasGeneratedMethods(descriptor_->file(), options_)) {
-    printer->Print(variables_,
-      "mutable int _$name$_cached_byte_size_;\n");
+    format("mutable std::atomic<int> _$name$_cached_byte_size_;\n");
   }
 }
 
 void RepeatedPrimitiveFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
-  printer->Print(variables_,
-                 "$deprecated_attr$$type$ $name$(int index) const;\n");
-  printer->Annotate("name", descriptor_);
-  printer->Print(
-      variables_,
-      "$deprecated_attr$void ${$set_$name$$}$(int index, $type$ value);\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$void ${$add_$name$$}$($type$ value);\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$const ::google::protobuf::RepeatedField< $type$ >&\n"
-                 "    $name$() const;\n");
-  printer->Annotate("name", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$::google::protobuf::RepeatedField< $type$ >*\n"
-                 "    ${$mutable_$name$$}$();\n");
-  printer->Annotate("{", "}", descriptor_);
+  Formatter format(printer, variables_);
+  format(
+      "$deprecated_attr$$type$ ${1$$name$$}$(int index) const;\n"
+      "$deprecated_attr$void ${1$set_$name$$}$(int index, $type$ value);\n"
+      "$deprecated_attr$void ${1$add_$name$$}$($type$ value);\n"
+      "$deprecated_attr$const ::$proto_ns$::RepeatedField< $type$ >&\n"
+      "    ${1$$name$$}$() const;\n"
+      "$deprecated_attr$::$proto_ns$::RepeatedField< $type$ >*\n"
+      "    ${1$mutable_$name$$}$();\n",
+      descriptor_);
 }
 
 void RepeatedPrimitiveFieldGenerator::
 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
-  printer->Print(variables_,
-    "inline $type$ $classname$::$name$(int index) const {\n"
-    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
-    "  return $name$_.Get(index);\n"
-    "}\n"
-    "inline void $classname$::set_$name$(int index, $type$ value) {\n"
-    "  $name$_.Set(index, value);\n"
-    "  // @@protoc_insertion_point(field_set:$full_name$)\n"
-    "}\n"
-    "inline void $classname$::add_$name$($type$ value) {\n"
-    "  $name$_.Add(value);\n"
-    "  // @@protoc_insertion_point(field_add:$full_name$)\n"
-    "}\n"
-    "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
-    "$classname$::$name$() const {\n"
-    "  // @@protoc_insertion_point(field_list:$full_name$)\n"
-    "  return $name$_;\n"
-    "}\n"
-    "inline ::google::protobuf::RepeatedField< $type$ >*\n"
-    "$classname$::mutable_$name$() {\n"
-    "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
-    "  return &$name$_;\n"
-    "}\n");
+  Formatter format(printer, variables_);
+  format(
+      "inline $type$ $classname$::$name$(int index) const {\n"
+      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+      "  return $name$_.Get(index);\n"
+      "}\n"
+      "inline void $classname$::set_$name$(int index, $type$ value) {\n"
+      "  $name$_.Set(index, value);\n"
+      "  // @@protoc_insertion_point(field_set:$full_name$)\n"
+      "}\n"
+      "inline void $classname$::add_$name$($type$ value) {\n"
+      "  $name$_.Add(value);\n"
+      "  // @@protoc_insertion_point(field_add:$full_name$)\n"
+      "}\n"
+      "inline const ::$proto_ns$::RepeatedField< $type$ >&\n"
+      "$classname$::$name$() const {\n"
+      "  // @@protoc_insertion_point(field_list:$full_name$)\n"
+      "  return $name$_;\n"
+      "}\n"
+      "inline ::$proto_ns$::RepeatedField< $type$ >*\n"
+      "$classname$::mutable_$name$() {\n"
+      "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+      "  return &$name$_;\n"
+      "}\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::
 GenerateClearingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.Clear();\n");
+  Formatter format(printer, variables_);
+  format("$name$_.Clear();\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::
 GenerateMergingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+  Formatter format(printer, variables_);
+  format("$name$_.MergeFrom(from.$name$_);\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::
 GenerateSwappingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.InternalSwap(&other->$name$_);\n");
+  Formatter format(printer, variables_);
+  format("$name$_.InternalSwap(&other->$name$_);\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::
@@ -355,124 +366,135 @@
 
 void RepeatedPrimitiveFieldGenerator::
 GenerateCopyConstructorCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.CopyFrom(from.$name$_);\n");
+  Formatter format(printer, variables_);
+  format("$name$_.CopyFrom(from.$name$_);\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::
 GenerateMergeFromCodedStream(io::Printer* printer) const {
-  printer->Print(variables_,
-    "DO_((::google::protobuf::internal::WireFormatLite::$repeated_reader$<\n"
-    "         $type$, $wire_format_field_type$>(\n"
-    "       $tag_size$, $tag$u, input, this->mutable_$name$())));\n");
+  Formatter format(printer, variables_);
+  format(
+      "DO_((::$proto_ns$::internal::WireFormatLite::$repeated_reader$<\n"
+      "         $type$, "
+      "::$proto_ns$::internal::WireFormatLite::$wire_format_field_type$>(\n"
+      "       $tag_size$, $tag$u, input, this->mutable_$name$())));\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::
 GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
-  printer->Print(variables_,
-    "DO_((::google::protobuf::internal::WireFormatLite::$packed_reader$<\n"
-    "         $type$, $wire_format_field_type$>(\n"
-    "       input, this->mutable_$name$())));\n");
+  Formatter format(printer, variables_);
+  format(
+      "DO_((::$proto_ns$::internal::WireFormatLite::$packed_reader$<\n"
+      "         $type$, "
+      "::$proto_ns$::internal::WireFormatLite::$wire_format_field_type$>(\n"
+      "       input, this->mutable_$name$())));\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::
 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   bool array_written = false;
   if (descriptor_->is_packed()) {
     // Write the tag and the size.
-    printer->Print(variables_,
-      "if (this->$name$_size() > 0) {\n"
-      "  ::google::protobuf::internal::WireFormatLite::WriteTag("
-          "$number$, "
-          "::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, "
-          "output);\n"
-      "  output->WriteVarint32(static_cast< ::google::protobuf::uint32>(\n"
-      "      _$name$_cached_byte_size_));\n");
+    format(
+        "if (this->$name$_size() > 0) {\n"
+        "  ::$proto_ns$::internal::WireFormatLite::WriteTag("
+        "$number$, "
+        "::$proto_ns$::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, "
+        "output);\n"
+        "  output->WriteVarint32(_$name$_cached_byte_size_.load(\n"
+        "      std::memory_order_relaxed));\n");
 
     if (FixedSize(descriptor_->type()) > 0) {
       // TODO(ckennelly): Use RepeatedField<T>::unsafe_data() via
       // WireFormatLite to access the contents of this->$name$_ to save a branch
       // here.
-      printer->Print(variables_,
-        "  ::google::protobuf::internal::WireFormatLite::Write$declared_type$Array(\n"
-        "    this->$name$().data(), this->$name$_size(), output);\n");
+      format(
+          "  "
+          "::$proto_ns$::internal::WireFormatLite::Write$declared_type$Array(\n"
+          "    this->$name$().data(), this->$name$_size(), output);\n");
       array_written = true;  // Wrote array all at once
     }
-    printer->Print(variables_, "}\n");
+    format("}\n");
   }
   if (!array_written) {
-    printer->Print(variables_,
-        "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
+    format("for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
     if (descriptor_->is_packed()) {
-      printer->Print(variables_,
-        "  ::google::protobuf::internal::WireFormatLite::Write$declared_type$NoTag(\n"
-        "    this->$name$(i), output);\n");
+      format(
+          "  "
+          "::$proto_ns$::internal::WireFormatLite::Write$declared_type$NoTag(\n"
+          "    this->$name$(i), output);\n");
     } else {
-      printer->Print(variables_,
-        "  ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
-        "    $number$, this->$name$(i), output);\n");
+      format(
+          "  ::$proto_ns$::internal::WireFormatLite::Write$declared_type$(\n"
+          "    $number$, this->$name$(i), output);\n");
     }
-    printer->Print("}\n");
+    format("}\n");
   }
 }
 
 void RepeatedPrimitiveFieldGenerator::
 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (descriptor_->is_packed()) {
     // Write the tag and the size.
-    printer->Print(variables_,
-      "if (this->$name$_size() > 0) {\n"
-      "  target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n"
-      "    $number$,\n"
-      "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
-      "    target);\n"
-      "  target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(\n"
-      "      static_cast< ::google::protobuf::int32>(\n"
-      "          _$name$_cached_byte_size_), target);\n"
-      "  target = ::google::protobuf::internal::WireFormatLite::\n"
-      "    Write$declared_type$NoTagToArray(this->$name$_, target);\n"
-      "}\n");
+    format(
+        "if (this->$name$_size() > 0) {\n"
+        "  target = ::$proto_ns$::internal::WireFormatLite::WriteTagToArray(\n"
+        "    $number$,\n"
+        "    "
+        "::$proto_ns$::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+        "    target);\n"
+        "  target = "
+        "::$proto_ns$::io::CodedOutputStream::WriteVarint32ToArray(\n"
+        "      _$name$_cached_byte_size_.load(std::memory_order_relaxed),\n"
+        "       target);\n"
+        "  target = ::$proto_ns$::internal::WireFormatLite::\n"
+        "    Write$declared_type$NoTagToArray(this->$name$_, target);\n"
+        "}\n");
   } else {
-    printer->Print(variables_,
-      "target = ::google::protobuf::internal::WireFormatLite::\n"
-      "  Write$declared_type$ToArray($number$, this->$name$_, target);\n");
+    format(
+        "target = ::$proto_ns$::internal::WireFormatLite::\n"
+        "  Write$declared_type$ToArray($number$, this->$name$_, target);\n");
   }
 }
 
 void RepeatedPrimitiveFieldGenerator::
 GenerateByteSize(io::Printer* printer) const {
-  printer->Print(variables_, "{\n");
-  printer->Indent();
+  Formatter format(printer, variables_);
+  format("{\n");
+  format.Indent();
   int fixed_size = FixedSize(descriptor_->type());
   if (fixed_size == -1) {
-    printer->Print(variables_,
-      "size_t data_size = ::google::protobuf::internal::WireFormatLite::\n"
-      "  $declared_type$Size(this->$name$_);\n");
+    format(
+        "size_t data_size = ::$proto_ns$::internal::WireFormatLite::\n"
+        "  $declared_type$Size(this->$name$_);\n");
   } else {
-    printer->Print(variables_,
-      "unsigned int count = static_cast<unsigned int>(this->$name$_size());\n"
-      "size_t data_size = $fixed_size$UL * count;\n");
+    format(
+        "unsigned int count = static_cast<unsigned int>(this->$name$_size());\n"
+        "size_t data_size = $fixed_size$UL * count;\n");
   }
 
   if (descriptor_->is_packed()) {
-    printer->Print(variables_,
-      "if (data_size > 0) {\n"
-      "  total_size += $tag_size$ +\n"
-      "    ::google::protobuf::internal::WireFormatLite::Int32Size(\n"
-      "        static_cast< ::google::protobuf::int32>(data_size));\n"
-      "}\n"
-      "int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);\n"
-      "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
-      "_$name$_cached_byte_size_ = cached_size;\n"
-      "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
-      "total_size += data_size;\n");
+    format(
+        "if (data_size > 0) {\n"
+        "  total_size += $tag_size$ +\n"
+        "    ::$proto_ns$::internal::WireFormatLite::Int32Size(\n"
+        "        static_cast<$int32$>(data_size));\n"
+        "}\n"
+        "int cached_size = ::$proto_ns$::internal::ToCachedSize(data_size);\n"
+        "_$name$_cached_byte_size_.store(cached_size,\n"
+        "                                std::memory_order_relaxed);\n"
+        "total_size += data_size;\n");
   } else {
-    printer->Print(variables_,
-      "total_size += $tag_size$ *\n"
-      "              ::google::protobuf::internal::FromIntSize(this->$name$_size());\n"
-      "total_size += data_size;\n");
+    format(
+        "total_size += $tag_size$ *\n"
+        "              "
+        "::$proto_ns$::internal::FromIntSize(this->$name$_size());\n"
+        "total_size += data_size;\n");
   }
-  printer->Outdent();
-  printer->Print("}\n");
+  format.Outdent();
+  format("}\n");
 }
 
 }  // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
index d52228e..77389aa 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
@@ -64,10 +64,6 @@
   void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
   void GenerateByteSize(io::Printer* printer) const;
 
- protected:
-  const FieldDescriptor* descriptor_;
-  std::map<string, string> variables_;
-
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
 };
@@ -111,15 +107,12 @@
   void GenerateByteSize(io::Printer* printer) const;
 
  private:
-  const FieldDescriptor* descriptor_;
-  std::map<string, string> variables_;
-
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
 };
 
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_service.cc b/src/google/protobuf/compiler/cpp/cpp_service.cc
index 95357d9..677b737 100644
--- a/src/google/protobuf/compiler/cpp/cpp_service.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_service.cc
@@ -42,151 +42,153 @@
 namespace compiler {
 namespace cpp {
 
+namespace {
+
+void InitMethodVariables(const MethodDescriptor* method, Formatter* format) {
+  format->Set("name", method->name());
+  format->Set("input_type", QualifiedClassName(method->input_type()));
+  format->Set("output_type", QualifiedClassName(method->output_type()));
+}
+
+}  // namespace
+
 ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor,
+                                   const std::map<string, string>& vars,
                                    const Options& options)
-  : descriptor_(descriptor) {
+    : descriptor_(descriptor), vars_(vars) {
   vars_["classname"] = descriptor_->name();
-  vars_["file_namespace"] = FileLevelNamespace(descriptor_->file()->name());
   vars_["full_name"] = descriptor_->full_name();
-  if (options.dllexport_decl.empty()) {
-    vars_["dllexport"] = "";
-  } else {
-    vars_["dllexport"] = options.dllexport_decl + " ";
-  }
 }
 
 ServiceGenerator::~ServiceGenerator() {}
 
 void ServiceGenerator::GenerateDeclarations(io::Printer* printer) {
+  Formatter format(printer, vars_);
   // Forward-declare the stub type.
-  printer->Print(vars_,
-    "class $classname$_Stub;\n"
-    "\n");
+  format(
+      "class $classname$_Stub;\n"
+      "\n");
 
   GenerateInterface(printer);
   GenerateStubDefinition(printer);
 }
 
 void ServiceGenerator::GenerateInterface(io::Printer* printer) {
-  printer->Print(vars_,
-    "class $dllexport$$classname$ : public ::google::protobuf::Service {\n"
-    " protected:\n"
-    "  // This class should be treated as an abstract interface.\n"
-    "  inline $classname$() {};\n"
-    " public:\n"
-    "  virtual ~$classname$();\n");
+  Formatter format(printer, vars_);
+  format(
+      "class $dllexport_decl $$classname$ : public ::$proto_ns$::Service {\n"
+      " protected:\n"
+      "  // This class should be treated as an abstract interface.\n"
+      "  inline $classname$() {};\n"
+      " public:\n"
+      "  virtual ~$classname$();\n");
   printer->Indent();
 
-  printer->Print(vars_,
-    "\n"
-    "typedef $classname$_Stub Stub;\n"
-    "\n"
-    "static const ::google::protobuf::ServiceDescriptor* descriptor();\n"
-    "\n");
+  format(
+      "\n"
+      "typedef $classname$_Stub Stub;\n"
+      "\n"
+      "static const ::$proto_ns$::ServiceDescriptor* descriptor();\n"
+      "\n");
 
   GenerateMethodSignatures(VIRTUAL, printer);
 
-  printer->Print(
-    "\n"
-    "// implements Service ----------------------------------------------\n"
-    "\n"
-    "const ::google::protobuf::ServiceDescriptor* GetDescriptor();\n"
-    "void CallMethod(const ::google::protobuf::MethodDescriptor* method,\n"
-    "                ::google::protobuf::RpcController* controller,\n"
-    "                const ::google::protobuf::Message* request,\n"
-    "                ::google::protobuf::Message* response,\n"
-    "                ::google::protobuf::Closure* done);\n"
-    "const ::google::protobuf::Message& GetRequestPrototype(\n"
-    "  const ::google::protobuf::MethodDescriptor* method) const;\n"
-    "const ::google::protobuf::Message& GetResponsePrototype(\n"
-    "  const ::google::protobuf::MethodDescriptor* method) const;\n");
+  format(
+      "\n"
+      "// implements Service ----------------------------------------------\n"
+      "\n"
+      "const ::$proto_ns$::ServiceDescriptor* GetDescriptor();\n"
+      "void CallMethod(const ::$proto_ns$::MethodDescriptor* method,\n"
+      "                ::$proto_ns$::RpcController* controller,\n"
+      "                const ::$proto_ns$::Message* request,\n"
+      "                ::$proto_ns$::Message* response,\n"
+      "                ::google::protobuf::Closure* done);\n"
+      "const ::$proto_ns$::Message& GetRequestPrototype(\n"
+      "  const ::$proto_ns$::MethodDescriptor* method) const;\n"
+      "const ::$proto_ns$::Message& GetResponsePrototype(\n"
+      "  const ::$proto_ns$::MethodDescriptor* method) const;\n");
 
   printer->Outdent();
-  printer->Print(vars_,
-    "\n"
-    " private:\n"
-    "  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$);\n"
-    "};\n"
-    "\n");
+  format(
+      "\n"
+      " private:\n"
+      "  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$);\n"
+      "};\n"
+      "\n");
 }
 
 void ServiceGenerator::GenerateStubDefinition(io::Printer* printer) {
-  printer->Print(vars_,
-    "class $dllexport$$classname$_Stub : public $classname$ {\n"
-    " public:\n");
+  Formatter format(printer, vars_);
+  format(
+      "class $dllexport_decl $$classname$_Stub : public $classname$ {\n"
+      " public:\n");
 
   printer->Indent();
 
-  printer->Print(vars_,
-    "$classname$_Stub(::google::protobuf::RpcChannel* channel);\n"
-    "$classname$_Stub(::google::protobuf::RpcChannel* channel,\n"
-    "                 ::google::protobuf::Service::ChannelOwnership ownership);\n"
-    "~$classname$_Stub();\n"
-    "\n"
-    "inline ::google::protobuf::RpcChannel* channel() { return channel_; }\n"
-    "\n"
-    "// implements $classname$ ------------------------------------------\n"
-    "\n");
+  format(
+      "$classname$_Stub(::$proto_ns$::RpcChannel* channel);\n"
+      "$classname$_Stub(::$proto_ns$::RpcChannel* channel,\n"
+      "                 ::$proto_ns$::Service::ChannelOwnership ownership);\n"
+      "~$classname$_Stub();\n"
+      "\n"
+      "inline ::$proto_ns$::RpcChannel* channel() { return channel_; }\n"
+      "\n"
+      "// implements $classname$ ------------------------------------------\n"
+      "\n");
 
   GenerateMethodSignatures(NON_VIRTUAL, printer);
 
   printer->Outdent();
-  printer->Print(vars_,
-    " private:\n"
-    "  ::google::protobuf::RpcChannel* channel_;\n"
-    "  bool owns_channel_;\n"
-    "  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$_Stub);\n"
-    "};\n"
-    "\n");
+  format(
+      " private:\n"
+      "  ::$proto_ns$::RpcChannel* channel_;\n"
+      "  bool owns_channel_;\n"
+      "  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$_Stub);\n"
+      "};\n"
+      "\n");
 }
 
-void ServiceGenerator::GenerateMethodSignatures(
-    VirtualOrNon virtual_or_non, io::Printer* printer) {
+void ServiceGenerator::GenerateMethodSignatures(VirtualOrNon virtual_or_non,
+                                                io::Printer* printer) {
   for (int i = 0; i < descriptor_->method_count(); i++) {
     const MethodDescriptor* method = descriptor_->method(i);
-    std::map<string, string> sub_vars;
-    sub_vars["name"] = method->name();
-    sub_vars["input_type"] = ClassName(method->input_type(), true);
-    sub_vars["output_type"] = ClassName(method->output_type(), true);
-    sub_vars["virtual"] = virtual_or_non == VIRTUAL ? "virtual " : "";
-
-    printer->Print(sub_vars,
-      "$virtual$void $name$(::google::protobuf::RpcController* controller,\n"
-      "                     const $input_type$* request,\n"
-      "                     $output_type$* response,\n"
-      "                     ::google::protobuf::Closure* done);\n");
+    Formatter format(printer, vars_);
+    InitMethodVariables(method, &format);
+    format.Set("virtual", virtual_or_non == VIRTUAL ? "virtual " : "");
+    format(
+        "$virtual$void $name$(::$proto_ns$::RpcController* controller,\n"
+        "                     const $input_type$* request,\n"
+        "                     $output_type$* response,\n"
+        "                     ::google::protobuf::Closure* done);\n");
   }
 }
 
 // ===================================================================
 
-void ServiceGenerator::GenerateDescriptorInitializer(
-    io::Printer* printer, int index) {
-  std::map<string, string> vars;
-  vars["classname"] = descriptor_->name();
-  vars["index"] = SimpleItoa(index);
-
-  printer->Print(vars,
-    "$classname$_descriptor_ = file->service($index$);\n");
+void ServiceGenerator::GenerateDescriptorInitializer(io::Printer* printer,
+                                                     int index) {
+  Formatter format(printer, vars_);
+  format("$classname$_descriptor_ = file->service($1$);\n", index);
 }
 
 // ===================================================================
 
 void ServiceGenerator::GenerateImplementation(io::Printer* printer) {
-  vars_["index"] = SimpleItoa(index_in_metadata_);
-  printer->Print(
-      vars_,
+  Formatter format(printer, vars_);
+  format(
       "$classname$::~$classname$() {}\n"
       "\n"
-      "const ::google::protobuf::ServiceDescriptor* $classname$::descriptor() {\n"
-      "  $file_namespace$::protobuf_AssignDescriptorsOnce();\n"
-      "  return $file_namespace$::file_level_service_descriptors[$index$];\n"
+      "const ::$proto_ns$::ServiceDescriptor* $classname$::descriptor() {\n"
+      "  "
+      "::$proto_ns$::internal::AssignDescriptors(&$assign_desc_table$);\n"
+      "  return $file_level_service_descriptors$[$1$];\n"
       "}\n"
       "\n"
-      "const ::google::protobuf::ServiceDescriptor* $classname$::GetDescriptor() {\n"
+      "const ::$proto_ns$::ServiceDescriptor* $classname$::GetDescriptor() {\n"
       "  return descriptor();\n"
       "}\n"
-      "\n");
+      "\n",
+      index_in_metadata_);
 
   // Generate methods of the interface.
   GenerateNotImplementedMethods(printer);
@@ -195,18 +197,20 @@
   GenerateGetPrototype(RESPONSE, printer);
 
   // Generate stub implementation.
-  printer->Print(vars_,
-    "$classname$_Stub::$classname$_Stub(::google::protobuf::RpcChannel* channel)\n"
-    "  : channel_(channel), owns_channel_(false) {}\n"
-    "$classname$_Stub::$classname$_Stub(\n"
-    "    ::google::protobuf::RpcChannel* channel,\n"
-    "    ::google::protobuf::Service::ChannelOwnership ownership)\n"
-    "  : channel_(channel),\n"
-    "    owns_channel_(ownership == ::google::protobuf::Service::STUB_OWNS_CHANNEL) {}\n"
-    "$classname$_Stub::~$classname$_Stub() {\n"
-    "  if (owns_channel_) delete channel_;\n"
-    "}\n"
-    "\n");
+  format(
+      "$classname$_Stub::$classname$_Stub(::$proto_ns$::RpcChannel* channel)\n"
+      "  : channel_(channel), owns_channel_(false) {}\n"
+      "$classname$_Stub::$classname$_Stub(\n"
+      "    ::$proto_ns$::RpcChannel* channel,\n"
+      "    ::$proto_ns$::Service::ChannelOwnership ownership)\n"
+      "  : channel_(channel),\n"
+      "    owns_channel_(ownership == "
+      "::$proto_ns$::Service::STUB_OWNS_CHANNEL) "
+      "{}\n"
+      "$classname$_Stub::~$classname$_Stub() {\n"
+      "  if (owns_channel_) delete channel_;\n"
+      "}\n"
+      "\n");
 
   GenerateStubMethods(printer);
 }
@@ -214,123 +218,110 @@
 void ServiceGenerator::GenerateNotImplementedMethods(io::Printer* printer) {
   for (int i = 0; i < descriptor_->method_count(); i++) {
     const MethodDescriptor* method = descriptor_->method(i);
-    std::map<string, string> sub_vars;
-    sub_vars["classname"] = descriptor_->name();
-    sub_vars["name"] = method->name();
-    sub_vars["index"] = SimpleItoa(i);
-    sub_vars["input_type"] = ClassName(method->input_type(), true);
-    sub_vars["output_type"] = ClassName(method->output_type(), true);
-
-    printer->Print(sub_vars,
-      "void $classname$::$name$(::google::protobuf::RpcController* controller,\n"
-      "                         const $input_type$*,\n"
-      "                         $output_type$*,\n"
-      "                         ::google::protobuf::Closure* done) {\n"
-      "  controller->SetFailed(\"Method $name$() not implemented.\");\n"
-      "  done->Run();\n"
-      "}\n"
-      "\n");
+    Formatter format(printer, vars_);
+    InitMethodVariables(method, &format);
+    format(
+        "void $classname$::$name$(::$proto_ns$::RpcController* controller,\n"
+        "                         const $input_type$*,\n"
+        "                         $output_type$*,\n"
+        "                         ::google::protobuf::Closure* done) {\n"
+        "  controller->SetFailed(\"Method $name$() not implemented.\");\n"
+        "  done->Run();\n"
+        "}\n"
+        "\n");
   }
 }
 
 void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
-  printer->Print(
-      vars_,
-      "void $classname$::CallMethod(const ::google::protobuf::MethodDescriptor* method,\n"
-      "                             ::google::protobuf::RpcController* controller,\n"
-      "                             const ::google::protobuf::Message* request,\n"
-      "                             ::google::protobuf::Message* response,\n"
+  Formatter format(printer, vars_);
+  format(
+      "void $classname$::CallMethod(const ::$proto_ns$::MethodDescriptor* "
+      "method,\n"
+      "                             ::$proto_ns$::RpcController* controller,\n"
+      "                             const ::$proto_ns$::Message* request,\n"
+      "                             ::$proto_ns$::Message* response,\n"
       "                             ::google::protobuf::Closure* done) {\n"
-      "  GOOGLE_DCHECK_EQ(method->service(), "
-      "$file_namespace$::file_level_service_descriptors[$index$]);\n"
-      "  switch(method->index()) {\n");
+      "  GOOGLE_DCHECK_EQ(method->service(), $file_level_service_descriptors$[$1$]);\n"
+      "  switch(method->index()) {\n",
+      index_in_metadata_);
 
   for (int i = 0; i < descriptor_->method_count(); i++) {
     const MethodDescriptor* method = descriptor_->method(i);
-    std::map<string, string> sub_vars;
-    sub_vars["name"] = method->name();
-    sub_vars["index"] = SimpleItoa(i);
-    sub_vars["input_type"] = ClassName(method->input_type(), true);
-    sub_vars["output_type"] = ClassName(method->output_type(), true);
+    Formatter format(printer, vars_);
+    InitMethodVariables(method, &format);
 
     // Note:  down_cast does not work here because it only works on pointers,
     //   not references.
-    printer->Print(sub_vars,
-      "    case $index$:\n"
-      "      $name$(controller,\n"
-      "             ::google::protobuf::down_cast<const $input_type$*>(request),\n"
-      "             ::google::protobuf::down_cast< $output_type$*>(response),\n"
-      "             done);\n"
-      "      break;\n");
+    format(
+        "    case $1$:\n"
+        "      $name$(controller,\n"
+        "             ::google::protobuf::down_cast<const $input_type$*>(request),\n"
+        "             ::google::protobuf::down_cast< $output_type$*>(response),\n"
+        "             done);\n"
+        "      break;\n",
+        i);
   }
 
-  printer->Print(vars_,
-    "    default:\n"
-    "      GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
-    "      break;\n"
-    "  }\n"
-    "}\n"
-    "\n");
+  format(
+      "    default:\n"
+      "      GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
+      "      break;\n"
+      "  }\n"
+      "}\n"
+      "\n");
 }
 
 void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
                                             io::Printer* printer) {
+  Formatter format(printer, vars_);
   if (which == REQUEST) {
-    printer->Print(vars_,
-      "const ::google::protobuf::Message& $classname$::GetRequestPrototype(\n");
+    format("const ::$proto_ns$::Message& $classname$::GetRequestPrototype(\n");
   } else {
-    printer->Print(vars_,
-      "const ::google::protobuf::Message& $classname$::GetResponsePrototype(\n");
+    format("const ::$proto_ns$::Message& $classname$::GetResponsePrototype(\n");
   }
 
-  printer->Print(vars_,
-    "    const ::google::protobuf::MethodDescriptor* method) const {\n"
-    "  GOOGLE_DCHECK_EQ(method->service(), descriptor());\n"
-    "  switch(method->index()) {\n");
+  format(
+      "    const ::$proto_ns$::MethodDescriptor* method) const {\n"
+      "  GOOGLE_DCHECK_EQ(method->service(), descriptor());\n"
+      "  switch(method->index()) {\n");
 
   for (int i = 0; i < descriptor_->method_count(); i++) {
     const MethodDescriptor* method = descriptor_->method(i);
     const Descriptor* type =
-      (which == REQUEST) ? method->input_type() : method->output_type();
+        (which == REQUEST) ? method->input_type() : method->output_type();
 
-    std::map<string, string> sub_vars;
-    sub_vars["index"] = SimpleItoa(i);
-    sub_vars["type"] = ClassName(type, true);
-
-    printer->Print(sub_vars,
-      "    case $index$:\n"
-      "      return $type$::default_instance();\n");
+    format(
+        "    case $1$:\n"
+        "      return $2$::default_instance();\n",
+        i, QualifiedClassName(type));
   }
 
-  printer->Print(
-    "    default:\n"
-    "      GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
-    "      return *::google::protobuf::MessageFactory::generated_factory()\n"
-    "          ->GetPrototype(method->$input_or_output$_type());\n"
-    "  }\n"
-    "}\n"
-    "\n",
-    "input_or_output", which == REQUEST ? "input" : "output");
+  format(
+      "    default:\n"
+      "      GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
+      "      return *::$proto_ns$::MessageFactory::generated_factory()\n"
+      "          ->GetPrototype(method->$1$_type());\n"
+      "  }\n"
+      "}\n"
+      "\n",
+      which == REQUEST ? "input" : "output");
 }
 
 void ServiceGenerator::GenerateStubMethods(io::Printer* printer) {
   for (int i = 0; i < descriptor_->method_count(); i++) {
     const MethodDescriptor* method = descriptor_->method(i);
-    std::map<string, string> sub_vars;
-    sub_vars["classname"] = descriptor_->name();
-    sub_vars["name"] = method->name();
-    sub_vars["index"] = SimpleItoa(i);
-    sub_vars["input_type"] = ClassName(method->input_type(), true);
-    sub_vars["output_type"] = ClassName(method->output_type(), true);
-
-    printer->Print(sub_vars,
-      "void $classname$_Stub::$name$(::google::protobuf::RpcController* controller,\n"
-      "                              const $input_type$* request,\n"
-      "                              $output_type$* response,\n"
-      "                              ::google::protobuf::Closure* done) {\n"
-      "  channel_->CallMethod(descriptor()->method($index$),\n"
-      "                       controller, request, response, done);\n"
-      "}\n");
+    Formatter format(printer, vars_);
+    InitMethodVariables(method, &format);
+    format(
+        "void $classname$_Stub::$name$(::$proto_ns$::RpcController* "
+        "controller,\n"
+        "                              const $input_type$* request,\n"
+        "                              $output_type$* response,\n"
+        "                              ::google::protobuf::Closure* done) {\n"
+        "  channel_->CallMethod(descriptor()->method($1$),\n"
+        "                       controller, request, response, done);\n"
+        "}\n",
+        i);
   }
 }
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_service.h b/src/google/protobuf/compiler/cpp/cpp_service.h
index 33c0254..3acbe63 100644
--- a/src/google/protobuf/compiler/cpp/cpp_service.h
+++ b/src/google/protobuf/compiler/cpp/cpp_service.h
@@ -42,11 +42,13 @@
 
 namespace google {
 namespace protobuf {
-  namespace io {
-    class Printer;             // printer.h
-  }
+namespace io {
+class Printer;  // printer.h
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace cpp {
@@ -55,6 +57,7 @@
  public:
   // See generator.cc for the meaning of dllexport_decl.
   explicit ServiceGenerator(const ServiceDescriptor* descriptor,
+                            const std::map<string, string>& vars,
                             const Options& options);
   ~ServiceGenerator();
 
@@ -70,7 +73,8 @@
   // descriptor.
   void GenerateDescriptorInitializer(io::Printer* printer, int index);
 
-  // Generate implementations of everything declared by GenerateDeclarations().
+  // Generate implementations of everything declared by
+  // GenerateDeclarations().
   void GenerateImplementation(io::Printer* printer);
 
  private:
@@ -116,6 +120,6 @@
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index cf6c4b3..ecfabe6 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -36,9 +36,9 @@
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/io/printer.h>
-
 #include <google/protobuf/stubs/strutil.h>
 
+
 namespace google {
 namespace protobuf {
 namespace compiler {
@@ -50,19 +50,20 @@
                         std::map<string, string>* variables,
                         const Options& options) {
   SetCommonFieldVariables(descriptor, variables, options);
-  (*variables)["default"] = DefaultValue(descriptor);
+  (*variables)["default"] = DefaultValue(options, descriptor);
   (*variables)["default_length"] =
       SimpleItoa(descriptor->default_value_string().length());
   string default_variable_string = MakeDefaultName(descriptor);
   (*variables)["default_variable_name"] = default_variable_string;
   (*variables)["default_variable"] =
       descriptor->default_value_string().empty()
-          ? "&::google::protobuf::internal::GetEmptyStringAlreadyInited()"
+          ? "&::" + (*variables)["proto_ns"] +
+                "::internal::GetEmptyStringAlreadyInited()"
           : "&" + Namespace(descriptor) + "::" + (*variables)["classname"] +
                 "::" + default_variable_string + ".get()";
   (*variables)["pointer_type"] =
       descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
-  (*variables)["null_check"] = "GOOGLE_DCHECK(value != NULL);\n";
+  (*variables)["null_check"] = (*variables)["DCHK"] + "(value != NULL);\n";
   // NOTE: Escaped here to unblock proto1->proto2 migration.
   // TODO(liujisi): Extend this to apply for other conflicting methods.
   (*variables)["release_name"] =
@@ -70,7 +71,11 @@
                        descriptor, "release_");
   (*variables)["full_name"] = descriptor->full_name();
 
-  (*variables)["string_piece"] = "::std::string";
+  if (options.opensource_runtime) {
+    (*variables)["string_piece"] = "::std::string";
+  } else {
+    (*variables)["string_piece"] = "::StringPiece";
+  }
 
   (*variables)["lite"] =
       HasDescriptorMethods(descriptor->file(), options) ? "" : "Lite";
@@ -82,8 +87,7 @@
 
 StringFieldGenerator::StringFieldGenerator(const FieldDescriptor* descriptor,
                                            const Options& options)
-    : FieldGenerator(options),
-      descriptor_(descriptor),
+    : FieldGenerator(descriptor, options),
       lite_(!HasDescriptorMethods(descriptor->file(), options)),
       inlined_(false) {
 
@@ -107,9 +111,9 @@
 
 void StringFieldGenerator::
 GeneratePrivateMembers(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (inlined_) {
-    printer->Print(variables_,
-                   "::google::protobuf::internal::InlinedStringField $name$_;\n");
+    format("::$proto_ns$::internal::InlinedStringField $name$_;\n");
   } else {
     // N.B. that we continue to use |ArenaStringPtr| instead of |string*| for
     // string fields, even when SupportArenas(descriptor_) == false. Why?  The
@@ -123,25 +127,27 @@
     // conditionals. It's simpler to stick with this but use lightweight
     // accessors that assume arena == NULL.  There should be very little
     // overhead anyway because it's just a tagged pointer in-memory.
-    printer->Print(variables_, "::google::protobuf::internal::ArenaStringPtr $name$_;\n");
+    format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n");
   }
 }
 
 void StringFieldGenerator::
 GenerateStaticMembers(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (!descriptor_->default_value_string().empty()) {
     // We make the default instance public, so it can be initialized by
     // non-friend code.
-    printer->Print(variables_,
-                   "public:\n"
-                   "static ::google::protobuf::internal::ExplicitlyConstructed< ::std::string>"
-                   " $default_variable_name$;\n"
-                   "private:\n");
+    format(
+        "public:\n"
+        "static ::$proto_ns$::internal::ExplicitlyConstructed<$string$>"
+        " $default_variable_name$;\n"
+        "private:\n");
   }
 }
 
 void StringFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   // If we're using StringFieldGenerator for a field with a ctype, it's
   // because that ctype isn't actually implemented.  In particular, this is
   // true of ctype=CORD and ctype=STRING_PIECE in the open source release.
@@ -159,90 +165,82 @@
   // reflection interface since the reflection interface is independent of
   // the string's underlying representation.
 
-  bool unknown_ctype =
-      descriptor_->options().ctype() != EffectiveStringCType(descriptor_);
+  bool unknown_ctype = descriptor_->options().ctype() !=
+                       EffectiveStringCType(descriptor_, options_);
 
   if (unknown_ctype) {
-    printer->Outdent();
-    printer->Print(
-      " private:\n"
-      "  // Hidden due to unknown ctype option.\n");
-    printer->Indent();
+    format.Outdent();
+    format(
+        " private:\n"
+        "  // Hidden due to unknown ctype option.\n");
+    format.Indent();
   }
 
-  printer->Print(variables_,
-                 "$deprecated_attr$const ::std::string& $name$() const;\n");
-  printer->Annotate("name", descriptor_);
-  printer->Print(
-      variables_,
-      "$deprecated_attr$void ${$set_$name$$}$(const ::std::string& value);\n");
-  printer->Annotate("{", "}", descriptor_);
-
-  printer->Print(variables_,
-                 "#if LANG_CXX11\n"
-                 "$deprecated_attr$void ${$set_$name$$}$(::std::string&& value);\n"
-                 "#endif\n");
-  printer->Annotate("{", "}", descriptor_);
-
-  printer->Print(
-      variables_,
-      "$deprecated_attr$void ${$set_$name$$}$(const char* value);\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$void ${$set_$name$$}$(const $pointer_type$* "
-                 "value, size_t size)"
-                 ";\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$::std::string* ${$mutable_$name$$}$();\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_, "$deprecated_attr$::std::string* $release_name$();\n");
-  printer->Annotate("release_name", descriptor_);
-  printer->Print(
-      variables_,
-      "$deprecated_attr$void ${$set_allocated_$name$$}$(::std::string* $name$);\n");
-  printer->Annotate("{", "}", descriptor_);
-  if (SupportsArenas(descriptor_)) {
-    printer->Print(
-        variables_,
-        "PROTOBUF_RUNTIME_DEPRECATED(\"The unsafe_arena_ accessors for\"\n"
-        "\"    string fields are deprecated and will be removed in a\"\n"
-        "\"    future release.\")\n"
-        "::std::string* ${$unsafe_arena_release_$name$$}$();\n");
-    printer->Annotate("{", "}", descriptor_);
-    printer->Print(
-        variables_,
-        "PROTOBUF_RUNTIME_DEPRECATED(\"The unsafe_arena_ accessors for\"\n"
-        "\"    string fields are deprecated and will be removed in a\"\n"
-        "\"    future release.\")\n"
-        "void ${$unsafe_arena_set_allocated_$name$$}$(\n"
-        "    ::std::string* $name$);\n");
-    printer->Annotate("{", "}", descriptor_);
+  format(
+      "$deprecated_attr$const $string$& ${1$$name$$}$() const;\n"
+      "$deprecated_attr$void ${1$set_$name$$}$(const $string$& value);\n"
+      "#if LANG_CXX11\n"
+      "$deprecated_attr$void ${1$set_$name$$}$($string$&& value);\n"
+      "#endif\n"
+      "$deprecated_attr$void ${1$set_$name$$}$(const char* value);\n",
+      descriptor_);
+  if (!options_.opensource_runtime) {
+    format(
+        "$deprecated_attr$void ${1$set_$name$$}$(::StringPiece value);\n"
+        "#ifdef HAS_GLOBAL_STRING\n"
+        "$deprecated_attr$void ${1$set_$name$$}$(const ::std::string& value);\n"
+        "#endif\n",
+        descriptor_);
+  }
+  format(
+      "$deprecated_attr$void ${1$set_$name$$}$(const $pointer_type$* "
+      "value, size_t size)"
+      ";\n"
+      "$deprecated_attr$$string$* ${1$mutable_$name$$}$();\n"
+      "$deprecated_attr$$string$* ${1$$release_name$$}$();\n"
+      "$deprecated_attr$void ${1$set_allocated_$name$$}$($string$* $name$);\n",
+      descriptor_);
+  if (options_.opensource_runtime) {
+    if (SupportsArenas(descriptor_)) {
+      format(
+          "$GOOGLE_PROTOBUF$_RUNTIME_DEPRECATED(\"The unsafe_arena_ accessors "
+          "for\"\n"
+          "\"    string fields are deprecated and will be removed in a\"\n"
+          "\"    future release.\")\n"
+          "$string$* ${1$unsafe_arena_release_$name$$}$();\n"
+          "$GOOGLE_PROTOBUF$_RUNTIME_DEPRECATED(\"The unsafe_arena_ accessors "
+          "for\"\n"
+          "\"    string fields are deprecated and will be removed in a\"\n"
+          "\"    future release.\")\n"
+          "void ${1$unsafe_arena_set_allocated_$name$$}$(\n"
+          "    $string$* $name$);\n",
+          descriptor_);
+    }
   }
 
   if (unknown_ctype) {
-    printer->Outdent();
-    printer->Print(" public:\n");
-    printer->Indent();
+    format.Outdent();
+    format(" public:\n");
+    format.Indent();
   }
 }
 
 void StringFieldGenerator::
 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (SupportsArenas(descriptor_)) {
-    printer->Print(
-        variables_,
-        "inline const ::std::string& $classname$::$name$() const {\n"
+    format(
+        "inline const $string$& $classname$::$name$() const {\n"
         "  // @@protoc_insertion_point(field_get:$full_name$)\n"
         "  return $name$_.Get();\n"
         "}\n"
-        "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+        "inline void $classname$::set_$name$(const $string$& value) {\n"
         "  $set_hasbit$\n"
         "  $name$_.Set$lite$($default_variable$, value, GetArenaNoVirtual());\n"
         "  // @@protoc_insertion_point(field_set:$full_name$)\n"
         "}\n"
         "#if LANG_CXX11\n"
-        "inline void $classname$::set_$name$(::std::string&& value) {\n"
+        "inline void $classname$::set_$name$($string$&& value) {\n"
         "  $set_hasbit$\n"
         "  $name$_.Set$lite$(\n"
         "    $default_variable$, ::std::move(value), GetArenaNoVirtual());\n"
@@ -255,7 +253,26 @@
         "  $name$_.Set$lite$($default_variable$, $string_piece$(value),\n"
         "              GetArenaNoVirtual());\n"
         "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
-        "}\n"
+        "}\n");
+    if (!options_.opensource_runtime) {
+      format(
+          "inline void $classname$::set_$name$(::StringPiece value) {\n"
+          "  $set_hasbit$\n"
+          "  $name$_.Set$lite$($default_variable$, value, "
+          "GetArenaNoVirtual());\n"
+          "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
+          "}\n"
+          "#ifdef HAS_GLOBAL_STRING\n"
+          "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+          "  $set_hasbit$\n"
+          "  $name$_.Set$lite$($default_variable$, "
+          "::StringPiece(value.data(),\n"
+          "      value.size()), GetArenaNoVirtual());\n"
+          "  // @@protoc_insertion_point(field_set_std_string:$full_name$)\n"
+          "}\n"
+          "#endif\n");
+    }
+    format(
         "inline "
         "void $classname$::set_$name$(const $pointer_type$* value,\n"
         "    size_t size) {\n"
@@ -265,31 +282,32 @@
         "GetArenaNoVirtual());\n"
         "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
         "}\n"
-        "inline ::std::string* $classname$::mutable_$name$() {\n"
+        "inline $string$* $classname$::mutable_$name$() {\n"
         "  $set_hasbit$\n"
         "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
         "  return $name$_.Mutable($default_variable$, GetArenaNoVirtual());\n"
         "}\n"
-        "inline ::std::string* $classname$::$release_name$() {\n"
+        "inline $string$* $classname$::$release_name$() {\n"
         "  // @@protoc_insertion_point(field_release:$full_name$)\n");
 
     if (HasFieldPresence(descriptor_->file())) {
-      printer->Print(variables_,
-        "  if (!has_$name$()) {\n"
-        "    return NULL;\n"
-        "  }\n"
-        "  $clear_hasbit$\n"
-        "  return $name$_.ReleaseNonDefault("
-        "$default_variable$, GetArenaNoVirtual());\n");
+      format(
+          "  if (!has_$name$()) {\n"
+          "    return NULL;\n"
+          "  }\n"
+          "  $clear_hasbit$\n"
+          "  return $name$_.ReleaseNonDefault("
+          "$default_variable$, GetArenaNoVirtual());\n");
     } else {
-      printer->Print(variables_,
-        "  $clear_hasbit$\n"
-        "  return $name$_.Release($default_variable$, GetArenaNoVirtual());\n");
+      format(
+          "  $clear_hasbit$\n"
+          "  return $name$_.Release($default_variable$, "
+          "GetArenaNoVirtual());\n");
     }
 
-    printer->Print(variables_,
+    format(
         "}\n"
-        "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
+        "inline void $classname$::set_allocated_$name$($string$* $name$) {\n"
         "  if ($name$ != NULL) {\n"
         "    $set_hasbit$\n"
         "  } else {\n"
@@ -298,43 +316,45 @@
         "  $name$_.SetAllocated($default_variable$, $name$,\n"
         "      GetArenaNoVirtual());\n"
         "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
-        "}\n"
-        "inline ::std::string* $classname$::unsafe_arena_release_$name$() {\n"
-        "  // "
-        "@@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
-        "  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
-        "  $clear_hasbit$\n"
-        "  return $name$_.UnsafeArenaRelease($default_variable$,\n"
-        "      GetArenaNoVirtual());\n"
-        "}\n"
-        "inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
-        "    ::std::string* $name$) {\n"
-        "  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
-        "  if ($name$ != NULL) {\n"
-        "    $set_hasbit$\n"
-        "  } else {\n"
-        "    $clear_hasbit$\n"
-        "  }\n"
-        "  $name$_.UnsafeArenaSetAllocated($default_variable$,\n"
-        "      $name$, GetArenaNoVirtual());\n"
-        "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
-        "$full_name$)\n"
         "}\n");
+    if (options_.opensource_runtime) {
+      format(
+          "inline $string$* $classname$::unsafe_arena_release_$name$() {\n"
+          "  // "
+          "@@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
+          "  $DCHK$(GetArenaNoVirtual() != NULL);\n"
+          "  $clear_hasbit$\n"
+          "  return $name$_.UnsafeArenaRelease($default_variable$,\n"
+          "      GetArenaNoVirtual());\n"
+          "}\n"
+          "inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
+          "    $string$* $name$) {\n"
+          "  $DCHK$(GetArenaNoVirtual() != NULL);\n"
+          "  if ($name$ != NULL) {\n"
+          "    $set_hasbit$\n"
+          "  } else {\n"
+          "    $clear_hasbit$\n"
+          "  }\n"
+          "  $name$_.UnsafeArenaSetAllocated($default_variable$,\n"
+          "      $name$, GetArenaNoVirtual());\n"
+          "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
+          "$full_name$)\n"
+          "}\n");
+    }
   } else {
     // No-arena case.
-    printer->Print(
-        variables_,
-        "inline const ::std::string& $classname$::$name$() const {\n"
+    format(
+        "inline const $string$& $classname$::$name$() const {\n"
         "  // @@protoc_insertion_point(field_get:$full_name$)\n"
         "  return $name$_.GetNoArena();\n"
         "}\n"
-        "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+        "inline void $classname$::set_$name$(const $string$& value) {\n"
         "  $set_hasbit$\n"
         "  $name$_.SetNoArena($default_variable$, value);\n"
         "  // @@protoc_insertion_point(field_set:$full_name$)\n"
         "}\n"
         "#if LANG_CXX11\n"
-        "inline void $classname$::set_$name$(::std::string&& value) {\n"
+        "inline void $classname$::set_$name$($string$&& value) {\n"
         "  $set_hasbit$\n"
         "  $name$_.SetNoArena(\n"
         "    $default_variable$, ::std::move(value));\n"
@@ -346,7 +366,24 @@
         "  $set_hasbit$\n"
         "  $name$_.SetNoArena($default_variable$, $string_piece$(value));\n"
         "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
-        "}\n"
+        "}\n");
+    if (!options_.opensource_runtime) {
+      format(
+          "inline void $classname$::set_$name$(::StringPiece value) {\n"
+          "  $set_hasbit$\n"
+          "  $name$_.SetNoArena($default_variable$, value);\n"
+          "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
+          "}\n"
+          "#ifdef HAS_GLOBAL_STRING\n"
+          "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+          "  $set_hasbit$\n"
+          "  $name$_.SetNoArena($default_variable$,\n"
+          "      ::StringPiece(value.data(), value.size()));\n"
+          "  // @@protoc_insertion_point(field_set_std_string:$full_name$)\n"
+          "}\n"
+          "#endif\n");
+    }
+    format(
         "inline "
         "void $classname$::set_$name$(const $pointer_type$* value, "
         "size_t size) {\n"
@@ -355,30 +392,30 @@
         "      $string_piece$(reinterpret_cast<const char*>(value), size));\n"
         "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
         "}\n"
-        "inline ::std::string* $classname$::mutable_$name$() {\n"
+        "inline $string$* $classname$::mutable_$name$() {\n"
         "  $set_hasbit$\n"
         "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
         "  return $name$_.MutableNoArena($default_variable$);\n"
         "}\n"
-        "inline ::std::string* $classname$::$release_name$() {\n"
+        "inline $string$* $classname$::$release_name$() {\n"
         "  // @@protoc_insertion_point(field_release:$full_name$)\n");
 
     if (HasFieldPresence(descriptor_->file())) {
-      printer->Print(variables_,
-        "  if (!has_$name$()) {\n"
-        "    return NULL;\n"
-        "  }\n"
-        "  $clear_hasbit$\n"
-        "  return $name$_.ReleaseNonDefaultNoArena($default_variable$);\n");
+      format(
+          "  if (!has_$name$()) {\n"
+          "    return NULL;\n"
+          "  }\n"
+          "  $clear_hasbit$\n"
+          "  return $name$_.ReleaseNonDefaultNoArena($default_variable$);\n");
     } else {
-      printer->Print(variables_,
-        "  $clear_hasbit$\n"
-        "  return $name$_.ReleaseNoArena($default_variable$);\n");
+      format(
+          "  $clear_hasbit$\n"
+          "  return $name$_.ReleaseNoArena($default_variable$);\n");
     }
 
-    printer->Print(variables_,
+    format(
         "}\n"
-        "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
+        "inline void $classname$::set_allocated_$name$($string$* $name$) {\n"
         "  if ($name$ != NULL) {\n"
         "    $set_hasbit$\n"
         "  } else {\n"
@@ -392,41 +429,42 @@
 
 void StringFieldGenerator::
 GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (!descriptor_->default_value_string().empty()) {
     // Initialized in GenerateDefaultInstanceAllocator.
-    printer->Print(variables_,
-                   "::google::protobuf::internal::ExplicitlyConstructed<::std::string> "
-                   "$classname$::$default_variable_name$;\n");
+    format(
+        "::$proto_ns$::internal::ExplicitlyConstructed<$string$> "
+        "$classname$::$default_variable_name$;\n");
   }
 }
 
 void StringFieldGenerator::
 GenerateClearingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   // Two-dimension specialization here: supporting arenas or not, and default
   // value is the empty string or not. Complexity here ensures the minimal
   // number of branches / amount of extraneous code at runtime (given that the
   // below methods are inlined one-liners)!
   if (SupportsArenas(descriptor_)) {
     if (descriptor_->default_value_string().empty()) {
-      printer->Print(variables_,
-        "$name$_.ClearToEmpty($default_variable$, GetArenaNoVirtual());\n");
+      format(
+          "$name$_.ClearToEmpty($default_variable$, GetArenaNoVirtual());\n");
     } else {
-      printer->Print(variables_,
-        "$name$_.ClearToDefault($default_variable$, GetArenaNoVirtual());\n");
+      format(
+          "$name$_.ClearToDefault($default_variable$, GetArenaNoVirtual());\n");
     }
   } else {
     if (descriptor_->default_value_string().empty()) {
-      printer->Print(variables_,
-        "$name$_.ClearToEmptyNoArena($default_variable$);\n");
+      format("$name$_.ClearToEmptyNoArena($default_variable$);\n");
     } else {
-      printer->Print(variables_,
-        "$name$_.ClearToDefaultNoArena($default_variable$);\n");
+      format("$name$_.ClearToDefaultNoArena($default_variable$);\n");
     }
   }
 }
 
 void StringFieldGenerator::
 GenerateMessageClearingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   // Two-dimension specialization here: supporting arenas, field presence, or
   // not, and default value is the empty string or not. Complexity here ensures
   // the minimal number of branches / amount of extraneous code at runtime
@@ -447,67 +485,60 @@
     //
     // For non-inlined strings, we distinguish from non-default by comparing
     // instances, rather than contents.
-    printer->Print(variables_,
-      "GOOGLE_DCHECK(!$name$_.IsDefault($default_variable$));\n");
+    format("$DCHK$(!$name$_.IsDefault($default_variable$));\n");
   }
 
   if (SupportsArenas(descriptor_)) {
     if (descriptor_->default_value_string().empty()) {
       if (must_be_present) {
-        printer->Print(variables_,
-          "$name$_.ClearNonDefaultToEmpty();\n");
+        format("$name$_.ClearNonDefaultToEmpty();\n");
       } else {
-        printer->Print(variables_,
-          "$name$_.ClearToEmpty($default_variable$, GetArenaNoVirtual());\n");
+        format(
+            "$name$_.ClearToEmpty($default_variable$, GetArenaNoVirtual());\n");
       }
     } else {
       // Clear to a non-empty default is more involved, as we try to use the
       // Arena if one is present and may need to reallocate the string.
-      printer->Print(variables_,
-        "$name$_.ClearToDefault($default_variable$, GetArenaNoVirtual());\n");
+      format(
+          "$name$_.ClearToDefault($default_variable$, GetArenaNoVirtual());\n");
     }
   } else if (must_be_present) {
     // When Arenas are disabled and field presence has been checked, we can
     // safely treat the ArenaStringPtr as a string*.
     if (descriptor_->default_value_string().empty()) {
-      printer->Print(variables_, "$name$_.ClearNonDefaultToEmptyNoArena();\n");
+      format("$name$_.ClearNonDefaultToEmptyNoArena();\n");
     } else {
-      printer->Print(
-          variables_,
-          "$name$_.UnsafeMutablePointer()->assign(*$default_variable$);\n");
+      format("$name$_.UnsafeMutablePointer()->assign(*$default_variable$);\n");
     }
   } else {
     if (descriptor_->default_value_string().empty()) {
-      printer->Print(variables_,
-        "$name$_.ClearToEmptyNoArena($default_variable$);\n");
+      format("$name$_.ClearToEmptyNoArena($default_variable$);\n");
     } else {
-      printer->Print(variables_,
-        "$name$_.ClearToDefaultNoArena($default_variable$);\n");
+      format("$name$_.ClearToDefaultNoArena($default_variable$);\n");
     }
   }
 }
 
 void StringFieldGenerator::
 GenerateMergingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (SupportsArenas(descriptor_) || descriptor_->containing_oneof() != NULL) {
     // TODO(gpike): improve this
-    printer->Print(variables_, "set_$name$(from.$name$());\n");
+    format("set_$name$(from.$name$());\n");
   } else {
-    printer->Print(variables_,
-      "$set_hasbit$\n"
-      "$name$_.AssignWithDefault($default_variable$, from.$name$_);\n");
+    format(
+        "$set_hasbit$\n"
+        "$name$_.AssignWithDefault($default_variable$, from.$name$_);\n");
   }
 }
 
 void StringFieldGenerator::
 GenerateSwappingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (inlined_) {
-    printer->Print(
-        variables_,
-        "$name$_.Swap(&other->$name$_);\n");
+    format("$name$_.Swap(&other->$name$_);\n");
   } else {
-    printer->Print(
-        variables_,
+    format(
         "$name$_.Swap(&other->$name$_, $default_variable$,\n"
         "  GetArenaNoVirtual());\n");
   }
@@ -515,6 +546,7 @@
 
 void StringFieldGenerator::
 GenerateConstructorCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   // TODO(ckennelly): Construct non-empty strings as part of the initializer
   // list.
   if (inlined_ && descriptor_->default_value_string().empty()) {
@@ -522,125 +554,149 @@
     return;
   }
 
-  printer->Print(variables_,
-                 "$name$_.UnsafeSetDefault($default_variable$);\n");
+  format("$name$_.UnsafeSetDefault($default_variable$);\n");
 }
 
 void StringFieldGenerator::
 GenerateCopyConstructorCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   GenerateConstructorCode(printer);
 
   if (HasFieldPresence(descriptor_->file())) {
-    printer->Print(variables_,
-        "if (from.has_$name$()) {\n");
+    format("if (from.has_$name$()) {\n");
   } else {
-    printer->Print(variables_,
-        "if (from.$name$().size() > 0) {\n");
+    format("if (from.$name$().size() > 0) {\n");
   }
 
-  printer->Indent();
+  format.Indent();
 
   if (SupportsArenas(descriptor_) || descriptor_->containing_oneof() != NULL) {
     // TODO(gpike): improve this
-    printer->Print(variables_,
-      "$name$_.Set$lite$($default_variable$, from.$name$(),\n"
-      "  GetArenaNoVirtual());\n");
+    format(
+        "$name$_.Set$lite$($default_variable$, from.$name$(),\n"
+        "  GetArenaNoVirtual());\n");
   } else {
-    printer->Print(variables_,
-      "$name$_.AssignWithDefault($default_variable$, from.$name$_);\n");
+    format("$name$_.AssignWithDefault($default_variable$, from.$name$_);\n");
   }
 
-  printer->Outdent();
-  printer->Print("}\n");
+  format.Outdent();
+  format("}\n");
 }
 
 void StringFieldGenerator::
 GenerateDestructorCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (inlined_) {
     // The destructor is automatically invoked.
     return;
   }
 
-  printer->Print(variables_, "$name$_.DestroyNoArena($default_variable$);\n");
+  format("$name$_.DestroyNoArena($default_variable$);\n");
 }
 
 bool StringFieldGenerator::GenerateArenaDestructorCode(
     io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (!inlined_) {
     return false;
   }
 
-  printer->Print(variables_,
-                 "_this->$name$_.DestroyNoArena($default_variable$);\n");
+  format("_this->$name$_.DestroyNoArena($default_variable$);\n");
   return true;
 }
 
 void StringFieldGenerator::
 GenerateDefaultInstanceAllocator(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (!descriptor_->default_value_string().empty()) {
-    printer->Print(
-        variables_,
+    format(
         "$ns$::$classname$::$default_variable_name$.DefaultConstruct();\n"
         "*$ns$::$classname$::$default_variable_name$.get_mutable() = "
-        "::std::string($default$, $default_length$);\n"
-        "::google::protobuf::internal::OnShutdownDestroyString(\n"
-        "    $ns$::$classname$::$default_variable_name$.get_mutable());\n"
-    );
+        "$string$($default$, $default_length$);\n"
+        "::$proto_ns$::internal::OnShutdownDestroyString(\n"
+        "    $ns$::$classname$::$default_variable_name$.get_mutable());\n");
   }
 }
 
 void StringFieldGenerator::
 GenerateMergeFromCodedStream(io::Printer* printer) const {
-  printer->Print(variables_,
-    "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
-    "      input, this->mutable_$name$()));\n");
+  Formatter format(printer, variables_);
+  // The google3 version of proto2 has ArenaStrings and parses into them
+  // directly, but for the open-source release, we always parse into ::std::string
+  // instances. Note that for lite, we do similarly to the open source release
+  // and use ::std::string, not ArenaString.
+  if (!options_.opensource_runtime && !inlined_ &&
+      SupportsArenas(descriptor_) && !lite_) {
+    // If arena != NULL, the current string is either an ArenaString (no
+    // destructor necessary) or a materialized ::std::string (and is on the Arena's
+    // destructor list).  No call to ArenaStringPtr::Destroy is needed.
+    format(
+        "if (arena != NULL) {\n"
+        "  ::$proto_ns$::internal::TaggedPtr<$string$> str =\n"
+        "    ::$proto_ns$::internal::ReadArenaString(input, arena);\n"
+        "  DO_(!str.IsNull());\n"
+        "  $set_hasbit_io$\n"
+        "  $name$_.UnsafeSetTaggedPointer(str);\n"
+        "} else {\n"
+        "  DO_(::$proto_ns$::internal::WireFormatLite::Read$declared_type$(\n"
+        "        input, this->mutable_$name$()));\n"
+        "}\n");
+  } else {
+    format(
+        "DO_(::$proto_ns$::internal::WireFormatLite::Read$declared_type$(\n"
+        "      input, this->mutable_$name$()));\n");
+  }
 
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
-        descriptor_, options_, true, variables_,
+        descriptor_, options_, true,
         "this->$name$().data(), static_cast<int>(this->$name$().length()),\n",
-        printer);
+        format);
   }
 }
 
 bool StringFieldGenerator::
 MergeFromCodedStreamNeedsArena() const {
-  return false;
+  return !lite_ && !inlined_ && !options_.opensource_runtime;
 }
 
 void StringFieldGenerator::
 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
-        descriptor_, options_, false, variables_,
+        descriptor_, options_, false,
         "this->$name$().data(), static_cast<int>(this->$name$().length()),\n",
-        printer);
+        format);
   }
-  printer->Print(variables_,
-    "::google::protobuf::internal::WireFormatLite::Write$declared_type$MaybeAliased(\n"
-    "  $number$, this->$name$(), output);\n");
+  format(
+      "::$proto_ns$::internal::WireFormatLite::Write$declared_type$"
+      "MaybeAliased(\n"
+      "  $number$, this->$name$(), output);\n");
 }
 
 void StringFieldGenerator::
 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
-        descriptor_, options_, false, variables_,
+        descriptor_, options_, false,
         "this->$name$().data(), static_cast<int>(this->$name$().length()),\n",
-        printer);
+        format);
   }
-  printer->Print(variables_,
-    "target =\n"
-    "  ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray(\n"
-    "    $number$, this->$name$(), target);\n");
+  format(
+      "target =\n"
+      "  ::$proto_ns$::internal::WireFormatLite::Write$declared_type$ToArray(\n"
+      "    $number$, this->$name$(), target);\n");
 }
 
 void StringFieldGenerator::
 GenerateByteSize(io::Printer* printer) const {
-  printer->Print(variables_,
-    "total_size += $tag_size$ +\n"
-    "  ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
-    "    this->$name$());\n");
+  Formatter format(printer, variables_);
+  format(
+      "total_size += $tag_size$ +\n"
+      "  ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
+      "    this->$name$());\n");
 }
 
 uint32 StringFieldGenerator::CalculateFieldTag() const {
@@ -661,17 +717,17 @@
 
 void StringOneofFieldGenerator::
 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (SupportsArenas(descriptor_)) {
-    printer->Print(
-        variables_,
-        "inline const ::std::string& $classname$::$name$() const {\n"
+    format(
+        "inline const $string$& $classname$::$name$() const {\n"
         "  // @@protoc_insertion_point(field_get:$full_name$)\n"
         "  if (has_$name$()) {\n"
         "    return $field_member$.Get();\n"
         "  }\n"
         "  return *$default_variable$;\n"
         "}\n"
-        "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+        "inline void $classname$::set_$name$(const $string$& value) {\n"
         "  if (!has_$name$()) {\n"
         "    clear_$oneof_name$();\n"
         "    set_has_$name$();\n"
@@ -682,7 +738,7 @@
         "  // @@protoc_insertion_point(field_set:$full_name$)\n"
         "}\n"
         "#if LANG_CXX11\n"
-        "inline void $classname$::set_$name$(::std::string&& value) {\n"
+        "inline void $classname$::set_$name$($string$&& value) {\n"
         "  // @@protoc_insertion_point(field_set:$full_name$)\n"
         "  if (!has_$name$()) {\n"
         "    clear_$oneof_name$();\n"
@@ -704,7 +760,34 @@
         "  $field_member$.Set$lite$($default_variable$,\n"
         "      $string_piece$(value), GetArenaNoVirtual());\n"
         "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
-        "}\n"
+        "}\n");
+    if (!options_.opensource_runtime) {
+      format(
+          "inline void $classname$::set_$name$(::StringPiece value) {\n"
+          "  if (!has_$name$()) {\n"
+          "    clear_$oneof_name$();\n"
+          "    set_has_$name$();\n"
+          "    $field_member$.UnsafeSetDefault($default_variable$);\n"
+          "  }\n"
+          "  $field_member$.Set$lite$($default_variable$, value,\n"
+          "      GetArenaNoVirtual());\n"
+          "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
+          "}\n"
+          "#ifdef HAS_GLOBAL_STRING\n"
+          "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+          "  if (!has_$name$()) {\n"
+          "    clear_$oneof_name$();\n"
+          "    set_has_$name$();\n"
+          "    $field_member$.UnsafeSetDefault($default_variable$);\n"
+          "  }\n"
+          "  $field_member$.Set$lite$($default_variable$,\n"
+          "      ::StringPiece(value.data(), value.size()), "
+          "GetArenaNoVirtual());\n"
+          "  // @@protoc_insertion_point(field_set_std_string:$full_name$)\n"
+          "}\n"
+          "#endif\n");
+    }
+    format(
         "inline "
         "void $classname$::set_$name$(const $pointer_type$* value,\n"
         "                             size_t size) {\n"
@@ -719,7 +802,7 @@
         "      GetArenaNoVirtual());\n"
         "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
         "}\n"
-        "inline ::std::string* $classname$::mutable_$name$() {\n"
+        "inline $string$* $classname$::mutable_$name$() {\n"
         "  if (!has_$name$()) {\n"
         "    clear_$oneof_name$();\n"
         "    set_has_$name$();\n"
@@ -729,7 +812,7 @@
         "      GetArenaNoVirtual());\n"
         "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
         "}\n"
-        "inline ::std::string* $classname$::$release_name$() {\n"
+        "inline $string$* $classname$::$release_name$() {\n"
         "  // @@protoc_insertion_point(field_release:$full_name$)\n"
         "  if (has_$name$()) {\n"
         "    clear_has_$oneof_name$();\n"
@@ -739,57 +822,57 @@
         "    return NULL;\n"
         "  }\n"
         "}\n"
-        "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
-        "  if (!has_$name$()) {\n"
-        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
+        "inline void $classname$::set_allocated_$name$($string$* $name$) {\n"
+        "  if (has_$oneof_name$()) {\n"
+        "    clear_$oneof_name$();\n"
         "  }\n"
-        "  clear_$oneof_name$();\n"
         "  if ($name$ != NULL) {\n"
         "    set_has_$name$();\n"
-        "    $field_member$.SetAllocated($default_variable$, $name$,\n"
-        "        GetArenaNoVirtual());\n"
+        "    $field_member$.UnsafeSetDefault($name$);\n"
         "  }\n"
         "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
-        "}\n"
-        "inline ::std::string* $classname$::unsafe_arena_release_$name$() {\n"
-        "  // "
-        "@@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
-        "  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
-        "  if (has_$name$()) {\n"
-        "    clear_has_$oneof_name$();\n"
-        "    return $field_member$.UnsafeArenaRelease(\n"
-        "        $default_variable$, GetArenaNoVirtual());\n"
-        "  } else {\n"
-        "    return NULL;\n"
-        "  }\n"
-        "}\n"
-        "inline void $classname$::unsafe_arena_set_allocated_$name$("
-        "::std::string* $name$) {\n"
-        "  GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
-        "  if (!has_$name$()) {\n"
-        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
-        "  }\n"
-        "  clear_$oneof_name$();\n"
-        "  if ($name$) {\n"
-        "    set_has_$name$();\n"
-        "    $field_member$.UnsafeArenaSetAllocated($default_variable$, "
-        "$name$, GetArenaNoVirtual());\n"
-        "  }\n"
-        "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
-        "$full_name$)\n"
         "}\n");
+    if (options_.opensource_runtime) {
+      format(
+          "inline $string$* $classname$::unsafe_arena_release_$name$() {\n"
+          "  // "
+          "@@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
+          "  $DCHK$(GetArenaNoVirtual() != NULL);\n"
+          "  if (has_$name$()) {\n"
+          "    clear_has_$oneof_name$();\n"
+          "    return $field_member$.UnsafeArenaRelease(\n"
+          "        $default_variable$, GetArenaNoVirtual());\n"
+          "  } else {\n"
+          "    return NULL;\n"
+          "  }\n"
+          "}\n"
+          "inline void $classname$::unsafe_arena_set_allocated_$name$("
+          "$string$* $name$) {\n"
+          "  $DCHK$(GetArenaNoVirtual() != NULL);\n"
+          "  if (!has_$name$()) {\n"
+          "    $field_member$.UnsafeSetDefault($default_variable$);\n"
+          "  }\n"
+          "  clear_$oneof_name$();\n"
+          "  if ($name$) {\n"
+          "    set_has_$name$();\n"
+          "    $field_member$.UnsafeArenaSetAllocated($default_variable$, "
+          "$name$, GetArenaNoVirtual());\n"
+          "  }\n"
+          "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
+          "$full_name$)\n"
+          "}\n");
+    }
   } else {
     // No-arena case.
-    printer->Print(
-        variables_,
-        "inline const ::std::string& $classname$::$name$() const {\n"
+    format(
+        "inline const $string$& $classname$::$name$() const {\n"
         "  // @@protoc_insertion_point(field_get:$full_name$)\n"
         "  if (has_$name$()) {\n"
         "    return $field_member$.GetNoArena();\n"
         "  }\n"
         "  return *$default_variable$;\n"
         "}\n"
-        "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+        "inline void $classname$::set_$name$(const $string$& value) {\n"
         "  // @@protoc_insertion_point(field_set:$full_name$)\n"
         "  if (!has_$name$()) {\n"
         "    clear_$oneof_name$();\n"
@@ -800,7 +883,7 @@
         "  // @@protoc_insertion_point(field_set:$full_name$)\n"
         "}\n"
         "#if LANG_CXX11\n"
-        "inline void $classname$::set_$name$(::std::string&& value) {\n"
+        "inline void $classname$::set_$name$($string$&& value) {\n"
         "  // @@protoc_insertion_point(field_set:$full_name$)\n"
         "  if (!has_$name$()) {\n"
         "    clear_$oneof_name$();\n"
@@ -821,7 +904,32 @@
         "  $field_member$.SetNoArena($default_variable$,\n"
         "      $string_piece$(value));\n"
         "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
-        "}\n"
+        "}\n");
+    if (!options_.opensource_runtime) {
+      format(
+          "inline void $classname$::set_$name$(::StringPiece value) {\n"
+          "  if (!has_$name$()) {\n"
+          "    clear_$oneof_name$();\n"
+          "    set_has_$name$();\n"
+          "    $field_member$.UnsafeSetDefault($default_variable$);\n"
+          "  }\n"
+          "  $field_member$.SetNoArena($default_variable$, value);\n"
+          "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
+          "}\n"
+          "#ifdef HAS_GLOBAL_STRING\n"
+          "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+          "  if (!has_$name$()) {\n"
+          "    clear_$oneof_name$();\n"
+          "    set_has_$name$();\n"
+          "    $field_member$.UnsafeSetDefault($default_variable$);\n"
+          "  }\n"
+          "  $field_member$.SetNoArena($default_variable$,\n"
+          "      ::StringPiece(value.data(), value.size()));\n"
+          "  // @@protoc_insertion_point(field_set_std_string:$full_name$)\n"
+          "}\n"
+          "#endif\n");
+    }
+    format(
         "inline "
         "void $classname$::set_$name$(const $pointer_type$* value, size_t "
         "size) {\n"
@@ -834,7 +942,7 @@
         "      reinterpret_cast<const char*>(value), size));\n"
         "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
         "}\n"
-        "inline ::std::string* $classname$::mutable_$name$() {\n"
+        "inline $string$* $classname$::mutable_$name$() {\n"
         "  if (!has_$name$()) {\n"
         "    clear_$oneof_name$();\n"
         "    set_has_$name$();\n"
@@ -843,7 +951,7 @@
         "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
         "  return $field_member$.MutableNoArena($default_variable$);\n"
         "}\n"
-        "inline ::std::string* $classname$::$release_name$() {\n"
+        "inline $string$* $classname$::$release_name$() {\n"
         "  // @@protoc_insertion_point(field_release:$full_name$)\n"
         "  if (has_$name$()) {\n"
         "    clear_has_$oneof_name$();\n"
@@ -852,14 +960,13 @@
         "    return NULL;\n"
         "  }\n"
         "}\n"
-        "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
-        "  if (!has_$name$()) {\n"
-        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
+        "inline void $classname$::set_allocated_$name$($string$* $name$) {\n"
+        "  if (has_$oneof_name$()) {\n"
+        "    clear_$oneof_name$();\n"
         "  }\n"
-        "  clear_$oneof_name$();\n"
         "  if ($name$ != NULL) {\n"
         "    set_has_$name$();\n"
-        "    $field_member$.SetAllocatedNoArena($default_variable$, $name$);\n"
+        "    $field_member$.UnsafeSetDefault($name$);\n"
         "  }\n"
         "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
         "}\n");
@@ -868,13 +975,13 @@
 
 void StringOneofFieldGenerator::
 GenerateClearingCode(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (SupportsArenas(descriptor_)) {
-    printer->Print(variables_,
-      "$field_member$.Destroy($default_variable$,\n"
-      "    GetArenaNoVirtual());\n");
+    format(
+        "$field_member$.Destroy($default_variable$,\n"
+        "    GetArenaNoVirtual());\n");
   } else {
-    printer->Print(variables_,
-      "$field_member$.DestroyNoArena($default_variable$);\n");
+    format("$field_member$.DestroyNoArena($default_variable$);\n");
   }
 }
 
@@ -890,31 +997,55 @@
 
 void StringOneofFieldGenerator::
 GenerateConstructorCode(io::Printer* printer) const {
-  printer->Print(
-      variables_,
+  Formatter format(printer, variables_);
+  format(
       "$ns$::_$classname$_default_instance_.$name$_.UnsafeSetDefault(\n"
       "    $default_variable$);\n");
 }
 
 void StringOneofFieldGenerator::
 GenerateDestructorCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "if (has_$name$()) {\n"
-    "  $field_member$.DestroyNoArena($default_variable$);\n"
-    "}\n");
+  Formatter format(printer, variables_);
+  format(
+      "if (has_$name$()) {\n"
+      "  $field_member$.DestroyNoArena($default_variable$);\n"
+      "}\n");
 }
 
 void StringOneofFieldGenerator::
 GenerateMergeFromCodedStream(io::Printer* printer) const {
-    printer->Print(variables_,
-      "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
-      "      input, this->mutable_$name$()));\n");
+  Formatter format(printer, variables_);
+  // See above: ArenaString is not included in the open-source release.
+  if (!options_.opensource_runtime && SupportsArenas(descriptor_) && !lite_) {
+    // If has_$name$(), then the current string is either an ArenaString (no
+    // destructor necessary) or a materialized ::std::string (and is on the Arena's
+    // destructor list).  No call to ArenaStringPtr::Destroy is needed.
+    format(
+        "if (arena != NULL) {\n"
+        "  clear_$oneof_name$();\n"
+        "  if (!has_$name$()) {\n"
+        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
+        "    set_has_$name$();\n"
+        "  }\n"
+        "  ::$proto_ns$::internal::TaggedPtr<$string$> new_value =\n"
+        "    ::$proto_ns$::internal::ReadArenaString(input, arena);\n"
+        "  DO_(!new_value.IsNull());\n"
+        "  $field_member$.UnsafeSetTaggedPointer(new_value);\n"
+        "} else {\n"
+        "  DO_(::$proto_ns$::internal::WireFormatLite::Read$declared_type$(\n"
+        "        input, this->mutable_$name$()));\n"
+        "}\n");
+  } else {
+    format(
+        "DO_(::$proto_ns$::internal::WireFormatLite::Read$declared_type$(\n"
+        "      input, this->mutable_$name$()));\n");
+  }
 
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
-        descriptor_, options_, true, variables_,
+        descriptor_, options_, true,
         "this->$name$().data(), static_cast<int>(this->$name$().length()),\n",
-        printer);
+        format);
   }
 }
 
@@ -923,7 +1054,7 @@
 
 RepeatedStringFieldGenerator::RepeatedStringFieldGenerator(
     const FieldDescriptor* descriptor, const Options& options)
-    : FieldGenerator(options), descriptor_(descriptor) {
+    : FieldGenerator(descriptor, options) {
   SetStringVariables(descriptor, &variables_, options);
 }
 
@@ -931,182 +1062,210 @@
 
 void RepeatedStringFieldGenerator::
 GeneratePrivateMembers(io::Printer* printer) const {
-  printer->Print(variables_,
-    "::google::protobuf::RepeatedPtrField< ::std::string> $name$_;\n");
+  Formatter format(printer, variables_);
+  format("::$proto_ns$::RepeatedPtrField<$string$> $name$_;\n");
 }
 
 void RepeatedStringFieldGenerator::
 GenerateAccessorDeclarations(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   // See comment above about unknown ctypes.
-  bool unknown_ctype =
-      descriptor_->options().ctype() != EffectiveStringCType(descriptor_);
+  bool unknown_ctype = descriptor_->options().ctype() !=
+                       EffectiveStringCType(descriptor_, options_);
 
   if (unknown_ctype) {
-    printer->Outdent();
-    printer->Print(
-      " private:\n"
-      "  // Hidden due to unknown ctype option.\n");
-    printer->Indent();
+    format.Outdent();
+    format(
+        " private:\n"
+        "  // Hidden due to unknown ctype option.\n");
+    format.Indent();
   }
 
-  printer->Print(variables_,
-                 "$deprecated_attr$const ::std::string& $name$(int index) const;\n");
-  printer->Annotate("name", descriptor_);
-  printer->Print(
-      variables_,
-      "$deprecated_attr$::std::string* ${$mutable_$name$$}$(int index);\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$void ${$set_$name$$}$(int index, const "
-                 "::std::string& value);\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(
-      variables_,
+  format(
+      "$deprecated_attr$const $string$& ${1$$name$$}$(int index) const;\n"
+      "$deprecated_attr$$string$* ${1$mutable_$name$$}$(int index);\n"
+      "$deprecated_attr$void ${1$set_$name$$}$(int index, const "
+      "$string$& value);\n"
       "#if LANG_CXX11\n"
-      "$deprecated_attr$void ${$set_$name$$}$(int index, ::std::string&& value);\n"
-      "#endif\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$void ${$set_$name$$}$(int index, const "
-                 "char* value);\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-                 ""
-                 "$deprecated_attr$void ${$set_$name$$}$("
-                 "int index, const $pointer_type$* value, size_t size);\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$::std::string* ${$add_$name$$}$();\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(
-      variables_,
-      "$deprecated_attr$void ${$add_$name$$}$(const ::std::string& value);\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-                 "#if LANG_CXX11\n"
-                 "$deprecated_attr$void ${$add_$name$$}$(::std::string&& value);\n"
-                 "#endif\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(
-      variables_,
-      "$deprecated_attr$void ${$add_$name$$}$(const char* value);\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$void ${$add_$name$$}$(const $pointer_type$* "
-                 "value, size_t size)"
-                 ";\n");
-  printer->Annotate("{", "}", descriptor_);
-  printer->Print(
-      variables_,
-      "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() "
-      "const;\n");
-  printer->Annotate("name", descriptor_);
-  printer->Print(variables_,
-                 "$deprecated_attr$::google::protobuf::RepeatedPtrField< ::std::string>* "
-                 "${$mutable_$name$$}$()"
-                 ";\n");
-  printer->Annotate("{", "}", descriptor_);
+      "$deprecated_attr$void ${1$set_$name$$}$(int index, $string$&& value);\n"
+      "#endif\n"
+      "$deprecated_attr$void ${1$set_$name$$}$(int index, const "
+      "char* value);\n",
+      descriptor_);
+  if (!options_.opensource_runtime) {
+    format(
+        "$deprecated_attr$void ${1$set_$name$$}$(int index, "
+        "StringPiece value);\n"
+        "#ifdef HAS_GLOBAL_STRING\n"
+        "$deprecated_attr$void ${1$set_$name$$}$(int index, const "
+        "::std::string& value);\n"
+        "#endif\n",
+        descriptor_);
+  }
+  format(
+      "$deprecated_attr$void ${1$set_$name$$}$("
+      "int index, const $pointer_type$* value, size_t size);\n"
+      "$deprecated_attr$$string$* ${1$add_$name$$}$();\n"
+      "$deprecated_attr$void ${1$add_$name$$}$(const $string$& value);\n"
+      "#if LANG_CXX11\n"
+      "$deprecated_attr$void ${1$add_$name$$}$($string$&& value);\n"
+      "#endif\n"
+      "$deprecated_attr$void ${1$add_$name$$}$(const char* value);\n",
+      descriptor_);
+  if (!options_.opensource_runtime) {
+    format(
+        "$deprecated_attr$void ${1$add_$name$$}$(StringPiece value);\n"
+        "#ifdef HAS_GLOBAL_STRING\n"
+        "$deprecated_attr$void ${1$add_$name$$}$(const ::std::string& value);\n"
+        "#endif\n",
+        descriptor_);
+  }
+  format(
+      "$deprecated_attr$void ${1$add_$name$$}$(const $pointer_type$* "
+      "value, size_t size)"
+      ";\n"
+      "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField<$string$>& "
+      "${1$$name$$}$() "
+      "const;\n"
+      "$deprecated_attr$::$proto_ns$::RepeatedPtrField<$string$>* "
+      "${1$mutable_$name$$}$()"
+      ";\n",
+      descriptor_);
 
   if (unknown_ctype) {
-    printer->Outdent();
-    printer->Print(" public:\n");
-    printer->Indent();
+    format.Outdent();
+    format(" public:\n");
+    format.Indent();
   }
 }
 
 void RepeatedStringFieldGenerator::
 GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  Formatter format(printer, variables_);
   if (options_.safe_boundary_check) {
-    printer->Print(variables_,
-      "inline const ::std::string& $classname$::$name$(int index) const {\n"
-      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
-      "  return $name$_.InternalCheckedGet(\n"
-      "      index, ::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
-      "}\n");
+    format(
+        "inline const $string$& $classname$::$name$(int index) const {\n"
+        "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+        "  return $name$_.InternalCheckedGet(\n"
+        "      index, ::$proto_ns$::internal::GetEmptyStringAlreadyInited());\n"
+        "}\n");
   } else {
-    printer->Print(variables_,
-      "inline const ::std::string& $classname$::$name$(int index) const {\n"
-      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
-      "  return $name$_.Get(index);\n"
-      "}\n");
+    format(
+        "inline const $string$& $classname$::$name$(int index) const {\n"
+        "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+        "  return $name$_.Get(index);\n"
+        "}\n");
   }
-  printer->Print(variables_,
-    "inline ::std::string* $classname$::mutable_$name$(int index) {\n"
-    "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
-    "  return $name$_.Mutable(index);\n"
-    "}\n"
-    "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
-    "  // @@protoc_insertion_point(field_set:$full_name$)\n"
-    "  $name$_.Mutable(index)->assign(value);\n"
-    "}\n"
-    "#if LANG_CXX11\n"
-    "inline void $classname$::set_$name$(int index, ::std::string&& value) {\n"
-    "  // @@protoc_insertion_point(field_set:$full_name$)\n"
-    "  $name$_.Mutable(index)->assign(std::move(value));\n"
-    "}\n"
-    "#endif\n"
-    "inline void $classname$::set_$name$(int index, const char* value) {\n"
-    "  $null_check$"
-    "  $name$_.Mutable(index)->assign(value);\n"
-    "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
-    "}\n"
-    "inline void "
-    "$classname$::set_$name$"
-    "(int index, const $pointer_type$* value, size_t size) {\n"
-    "  $name$_.Mutable(index)->assign(\n"
-    "    reinterpret_cast<const char*>(value), size);\n"
-    "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
-    "}\n"
-    "inline ::std::string* $classname$::add_$name$() {\n"
-    "  // @@protoc_insertion_point(field_add_mutable:$full_name$)\n"
-    "  return $name$_.Add();\n"
-    "}\n"
-    "inline void $classname$::add_$name$(const ::std::string& value) {\n"
-    "  $name$_.Add()->assign(value);\n"
-    "  // @@protoc_insertion_point(field_add:$full_name$)\n"
-    "}\n"
-    "#if LANG_CXX11\n"
-    "inline void $classname$::add_$name$(::std::string&& value) {\n"
-    "  $name$_.Add(std::move(value));\n"
-    "  // @@protoc_insertion_point(field_add:$full_name$)\n"
-    "}\n"
-    "#endif\n"
-    "inline void $classname$::add_$name$(const char* value) {\n"
-    "  $null_check$"
-    "  $name$_.Add()->assign(value);\n"
-    "  // @@protoc_insertion_point(field_add_char:$full_name$)\n"
-    "}\n"
-    "inline void "
-    "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
-    "  $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
-    "  // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
-    "}\n"
-    "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n"
-    "$classname$::$name$() const {\n"
-    "  // @@protoc_insertion_point(field_list:$full_name$)\n"
-    "  return $name$_;\n"
-    "}\n"
-    "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n"
-    "$classname$::mutable_$name$() {\n"
-    "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
-    "  return &$name$_;\n"
-    "}\n");
+  format(
+      "inline $string$* $classname$::mutable_$name$(int index) {\n"
+      "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+      "  return $name$_.Mutable(index);\n"
+      "}\n"
+      "inline void $classname$::set_$name$(int index, const $string$& value) "
+      "{\n"
+      "  // @@protoc_insertion_point(field_set:$full_name$)\n"
+      "  $name$_.Mutable(index)->assign(value);\n"
+      "}\n"
+      "#if LANG_CXX11\n"
+      "inline void $classname$::set_$name$(int index, $string$&& value) {\n"
+      "  // @@protoc_insertion_point(field_set:$full_name$)\n"
+      "  $name$_.Mutable(index)->assign(std::move(value));\n"
+      "}\n"
+      "#endif\n"
+      "inline void $classname$::set_$name$(int index, const char* value) {\n"
+      "  $null_check$"
+      "  $name$_.Mutable(index)->assign(value);\n"
+      "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
+      "}\n");
+  if (!options_.opensource_runtime) {
+    format(
+        "inline void "
+        "$classname$::set_$name$(int index, StringPiece value) {\n"
+        "  $name$_.Mutable(index)->assign(value.data(), value.size());\n"
+        "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
+        "}\n"
+        "#ifdef HAS_GLOBAL_STRING\n"
+        "inline void "
+        "$classname$::set_$name$(int index, const std::string& value) {\n"
+        "  $name$_.Mutable(index)->assign(value.data(), value.size());\n"
+        "  // @@protoc_insertion_point(field_set_std_string:$full_name$)\n"
+        "}\n"
+        "#endif\n");
+  }
+  format(
+      "inline void "
+      "$classname$::set_$name$"
+      "(int index, const $pointer_type$* value, size_t size) {\n"
+      "  $name$_.Mutable(index)->assign(\n"
+      "    reinterpret_cast<const char*>(value), size);\n"
+      "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
+      "}\n"
+      "inline $string$* $classname$::add_$name$() {\n"
+      "  // @@protoc_insertion_point(field_add_mutable:$full_name$)\n"
+      "  return $name$_.Add();\n"
+      "}\n"
+      "inline void $classname$::add_$name$(const $string$& value) {\n"
+      "  $name$_.Add()->assign(value);\n"
+      "  // @@protoc_insertion_point(field_add:$full_name$)\n"
+      "}\n"
+      "#if LANG_CXX11\n"
+      "inline void $classname$::add_$name$($string$&& value) {\n"
+      "  $name$_.Add(std::move(value));\n"
+      "  // @@protoc_insertion_point(field_add:$full_name$)\n"
+      "}\n"
+      "#endif\n"
+      "inline void $classname$::add_$name$(const char* value) {\n"
+      "  $null_check$"
+      "  $name$_.Add()->assign(value);\n"
+      "  // @@protoc_insertion_point(field_add_char:$full_name$)\n"
+      "}\n");
+  if (!options_.opensource_runtime) {
+    format(
+        "inline void $classname$::add_$name$(StringPiece value) {\n"
+        "  $name$_.Add()->assign(value.data(), value.size());\n"
+        "  // @@protoc_insertion_point(field_add_string_piece:$full_name$)\n"
+        "}\n"
+        "#ifdef HAS_GLOBAL_STRING\n"
+        "inline void $classname$::add_$name$(const ::std::string& value) {\n"
+        "  $name$_.Add()->assign(value.data(), value.size());\n"
+        "  // @@protoc_insertion_point(field_add_std_string:$full_name$)\n"
+        "}\n"
+        "#endif\n");
+  }
+  format(
+      "inline void "
+      "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
+      "  $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
+      "  // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
+      "}\n"
+      "inline const ::$proto_ns$::RepeatedPtrField<$string$>&\n"
+      "$classname$::$name$() const {\n"
+      "  // @@protoc_insertion_point(field_list:$full_name$)\n"
+      "  return $name$_;\n"
+      "}\n"
+      "inline ::$proto_ns$::RepeatedPtrField<$string$>*\n"
+      "$classname$::mutable_$name$() {\n"
+      "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+      "  return &$name$_;\n"
+      "}\n");
 }
 
 void RepeatedStringFieldGenerator::
 GenerateClearingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.Clear();\n");
+  Formatter format(printer, variables_);
+  format("$name$_.Clear();\n");
 }
 
 void RepeatedStringFieldGenerator::
 GenerateMergingCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+  Formatter format(printer, variables_);
+  format("$name$_.MergeFrom(from.$name$_);\n");
 }
 
 void RepeatedStringFieldGenerator::
 GenerateSwappingCode(io::Printer* printer) const {
-  printer->Print(variables_,
-                 "$name$_.InternalSwap(CastToBase(&other->$name$_));\n");
+  Formatter format(printer, variables_);
+  format("$name$_.InternalSwap(CastToBase(&other->$name$_));\n");
 }
 
 void RepeatedStringFieldGenerator::
@@ -1116,68 +1275,72 @@
 
 void RepeatedStringFieldGenerator::
 GenerateCopyConstructorCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.CopyFrom(from.$name$_);");
+  Formatter format(printer, variables_);
+  format("$name$_.CopyFrom(from.$name$_);");
 }
 
 void RepeatedStringFieldGenerator::
 GenerateMergeFromCodedStream(io::Printer* printer) const {
-  printer->Print(variables_,
-    "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
-    "      input, this->add_$name$()));\n");
+  Formatter format(printer, variables_);
+  format(
+      "DO_(::$proto_ns$::internal::WireFormatLite::Read$declared_type$(\n"
+      "      input, this->add_$name$()));\n");
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
-        descriptor_, options_, true, variables_,
+        descriptor_, options_, true,
         "this->$name$(this->$name$_size() - 1).data(),\n"
         "static_cast<int>(this->$name$(this->$name$_size() - 1).length()),\n",
-        printer);
+        format);
   }
 }
 
 void RepeatedStringFieldGenerator::
 GenerateSerializeWithCachedSizes(io::Printer* printer) const {
-  printer->Print(variables_,
-        "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
-  printer->Indent();
+  Formatter format(printer, variables_);
+  format("for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
+  format.Indent();
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
-        descriptor_, options_, false, variables_,
+        descriptor_, options_, false,
         "this->$name$(i).data(), static_cast<int>(this->$name$(i).length()),\n",
-        printer);
+        format);
   }
-  printer->Outdent();
-  printer->Print(variables_,
-    "  ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
-    "    $number$, this->$name$(i), output);\n"
-    "}\n");
+  format.Outdent();
+  format(
+      "  ::$proto_ns$::internal::WireFormatLite::Write$declared_type$(\n"
+      "    $number$, this->$name$(i), output);\n"
+      "}\n");
 }
 
 void RepeatedStringFieldGenerator::
 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
-  printer->Print(variables_,
-    "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
-  printer->Indent();
+  Formatter format(printer, variables_);
+  format("for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
+  format.Indent();
   if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
     GenerateUtf8CheckCodeForString(
-        descriptor_, options_, false, variables_,
+        descriptor_, options_, false,
         "this->$name$(i).data(), static_cast<int>(this->$name$(i).length()),\n",
-        printer);
+        format);
   }
-  printer->Outdent();
-  printer->Print(variables_,
-    "  target = ::google::protobuf::internal::WireFormatLite::\n"
-    "    Write$declared_type$ToArray($number$, this->$name$(i), target);\n"
-    "}\n");
+  format.Outdent();
+  format(
+      "  target = ::$proto_ns$::internal::WireFormatLite::\n"
+      "    Write$declared_type$ToArray($number$, this->$name$(i), target);\n"
+      "}\n");
 }
 
 void RepeatedStringFieldGenerator::
 GenerateByteSize(io::Printer* printer) const {
-  printer->Print(variables_,
-    "total_size += $tag_size$ *\n"
-    "    ::google::protobuf::internal::FromIntSize(this->$name$_size());\n"
-    "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n"
-    "  total_size += ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
-    "    this->$name$(i));\n"
-    "}\n");
+  Formatter format(printer, variables_);
+  format(
+      "total_size += $tag_size$ *\n"
+      "    ::$proto_ns$::internal::FromIntSize(this->$name$_size());\n"
+      "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n"
+      "  total_size += "
+      "::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
+      "    this->$name$(i));\n"
+      "}\n");
 }
 
 }  // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h
index 6cbf722..3a1de55 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h
@@ -75,8 +75,6 @@
   bool MergeFromCodedStreamNeedsArena() const;
 
  protected:
-  const FieldDescriptor* descriptor_;
-  std::map<string, string> variables_;
   const bool lite_;
   bool inlined_;
 
@@ -127,15 +125,12 @@
   void GenerateByteSize(io::Printer* printer) const;
 
  private:
-  const FieldDescriptor* descriptor_;
-  std::map<string, string> variables_;
-
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator);
 };
 
 }  // namespace cpp
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index 22b759a..2cf030e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -33,7 +33,7 @@
 //  Sanjay Ghemawat, Jeff Dean, and others.
 //
 // To test the code generator, we actually use it to generate code for
-// google/protobuf/unittest.proto, then test that.  This means that we
+// net/proto2/internal/unittest.proto, then test that.  This means that we
 // are actually testing the parser and other parts of the system at the same
 // time, and that problems in the generator may show up as compile-time errors
 // rather than unittest failures, which may be surprising.  However, testing
@@ -60,7 +60,7 @@
 #define HELPERS_TEST_NAME HelpersTest
 #define DESCRIPTOR_INIT_TEST_NAME DescriptorInitializationTest
 
-#define UNITTEST_PROTO_PATH "google/protobuf/unittest.proto"
+#define UNITTEST_PROTO_PATH "net/proto2/internal/unittest.proto"
 #define UNITTEST ::protobuf_unittest
 #define UNITTEST_IMPORT ::protobuf_unittest_import
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.h b/src/google/protobuf/compiler/cpp/cpp_unittest.h
index 69c8f44..c5dc767 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.h
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.h
@@ -46,6 +46,6 @@
 namespace protobuf {
 namespace protobuf_unittest {}
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.inc b/src/google/protobuf/compiler/cpp/cpp_unittest.inc
index ff6354f..0604731 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.inc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.inc
@@ -33,7 +33,7 @@
 //  Sanjay Ghemawat, Jeff Dean, and others.
 //
 // To test the code generator, we actually use it to generate code for
-// google/protobuf/unittest.proto, then test that.  This means that we
+// net/proto2/internal/unittest.proto, then test that.  This means that we
 // are actually testing the parser and other parts of the system at the same
 // time, and that problems in the generator may show up as compile-time errors
 // rather than unittest failures, which may be surprising.  However, testing
@@ -50,6 +50,7 @@
 #include <vector>
 
 #include <google/protobuf/unittest_no_arena.pb.h>
+
 #if !defined(GOOGLE_PROTOBUF_CMAKE_BUILD) && !defined(_MSC_VER)
 // We exclude this large proto from cmake build because it's too large for
 // visual studio to compile (report internal errors).
@@ -57,7 +58,9 @@
 #endif
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h>
+#include <google/protobuf/compiler/scc.h>
 #include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/test_util2.h>
 #include <google/protobuf/unittest_no_generic_services.pb.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
@@ -72,6 +75,7 @@
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
+#include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/stl_util.h>
 
 namespace google {
@@ -110,12 +114,12 @@
   // Set up the Importer.
   MockErrorCollector error_collector;
   DiskSourceTree source_tree;
-  source_tree.MapPath("", TestSourceDir());
+  source_tree.MapPath("", TestUtil::TestSourceDir());
   Importer importer(&source_tree, &error_collector);
 
   // Import (parse) unittest.proto.
   const FileDescriptor* parsed_descriptor =
-    importer.Import(UNITTEST_PROTO_PATH);
+      importer.Import(TestUtil::MaybeTranslatePath(UNITTEST_PROTO_PATH));
   EXPECT_EQ("", error_collector.text_);
   ASSERT_TRUE(parsed_descriptor != NULL);
 
@@ -165,21 +169,6 @@
             &message.optional_import_message());
 }
 
-#ifndef PROTOBUF_USE_DLLS
-TEST(GENERATED_MESSAGE_TEST_NAME, Int32StringConversion) {
-  EXPECT_EQ("971", Int32ToString(971));
-  EXPECT_EQ("(~0x7fffffff)", Int32ToString(kint32min));
-  EXPECT_EQ("2147483647", Int32ToString(kint32max));
-}
-
-TEST(GENERATED_MESSAGE_TEST_NAME, Int64StringConversion) {
-  EXPECT_EQ("GOOGLE_LONGLONG(971)", Int64ToString(971));
-  EXPECT_EQ("GOOGLE_LONGLONG(-2147483648)", Int64ToString(kint32min));
-  EXPECT_EQ("GOOGLE_LONGLONG(~0x7fffffffffffffff)", Int64ToString(kint64min));
-  EXPECT_EQ("GOOGLE_LONGLONG(9223372036854775807)", Int64ToString(kint64max));
-}
-#endif  // !PROTOBUF_USE_DLLS
-
 TEST(GENERATED_MESSAGE_TEST_NAME, FloatingPointDefaults) {
   const UNITTEST::TestExtremeDefaultValues& extreme_default =
       UNITTEST::TestExtremeDefaultValues::default_instance();
@@ -667,8 +656,7 @@
   TestUtil::ExpectAllFieldsSet(message2);
 }
 
-#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || \
-    !defined(GOOGLE_PROTOBUF_NO_RTTI)
+#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || GOOGLE_PROTOBUF_RTTI
 TEST(GENERATED_MESSAGE_TEST_NAME, UpcastCopyFrom) {
   // Test the CopyFrom method that takes in the generic const Message&
   // parameter.
@@ -676,7 +664,7 @@
 
   TestUtil::SetAllFields(&message1);
 
-  const Message* source = implicit_cast<const Message*>(&message1);
+  const Message* source = ::google::protobuf::implicit_cast<const Message*>(&message1);
   message2.CopyFrom(*source);
 
   TestUtil::ExpectAllFieldsSet(message2);
@@ -709,7 +697,7 @@
 
 TEST(GENERATED_MESSAGE_TEST_NAME, NonEmptyMergeFrom) {
   // Test merging with a non-empty message. Code is a modified form
-  // of that found in google/protobuf/reflection_ops_unittest.cc.
+  // of that found in net/proto2/internal/reflection_ops_unittest.cc.
   UNITTEST::TestAllTypes message1, message2;
 
   TestUtil::SetAllFields(&message1);
@@ -741,7 +729,7 @@
   TestUtil::SetAllFields(&message1);
   int size = message1.ByteSizeLong();
   data.resize(size);
-  uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+  uint8* start = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
   uint8* end = message1.SerializeWithCachedSizesToArray(start);
   EXPECT_EQ(size, end - start);
   EXPECT_TRUE(message2.ParseFromString(data));
@@ -755,7 +743,7 @@
   TestUtil::SetPackedFields(&packed_message1);
   int packed_size = packed_message1.ByteSizeLong();
   packed_data.resize(packed_size);
-  uint8* start = reinterpret_cast<uint8*>(string_as_array(&packed_data));
+  uint8* start = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&packed_data));
   uint8* end = packed_message1.SerializeWithCachedSizesToArray(start);
   EXPECT_EQ(packed_size, end - start);
   EXPECT_TRUE(packed_message2.ParseFromString(packed_data));
@@ -772,7 +760,7 @@
   data.resize(size);
   {
     // Allow the output stream to buffer only one byte at a time.
-    io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+    io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
     io::CodedOutputStream output_stream(&array_stream);
     message1.SerializeWithCachedSizes(&output_stream);
     EXPECT_FALSE(output_stream.HadError());
@@ -791,7 +779,7 @@
   data.resize(size);
   {
     // Allow the output stream to buffer only one byte at a time.
-    io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+    io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
     io::CodedOutputStream output_stream(&array_stream);
     message1.SerializeWithCachedSizes(&output_stream);
     EXPECT_FALSE(output_stream.HadError());
@@ -1872,7 +1860,7 @@
   EXPECT_EQ(message2.foo_message().qux_int(), 123);
 
   // Make sure that self-assignment does something sane.
-  message2 = message2;
+  message2 = *&message2;  // Avoid -Wself-assign.
   EXPECT_EQ(message2.foo_message().qux_int(), 123);
 }
 
@@ -1883,7 +1871,7 @@
   message1.mutable_foogroup()->set_a(123);
   EXPECT_TRUE(message1.has_foogroup());
 
-  const Message* source = implicit_cast<const Message*>(&message1);
+  const Message* source = ::google::protobuf::implicit_cast<const Message*>(&message1);
   message2.CopyFrom(*source);
 
   EXPECT_TRUE(message2.has_foogroup());
@@ -1902,7 +1890,7 @@
     message1.set_foo_int(123);
     int size = message1.ByteSizeLong();
     data.resize(size);
-    uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+    uint8* start = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
     uint8* end = message1.SerializeWithCachedSizesToArray(start);
     EXPECT_EQ(size, end - start);
     EXPECT_TRUE(message2.ParseFromString(data));
@@ -1916,7 +1904,7 @@
     message1.set_foo_string("foo");
     int size = message1.ByteSizeLong();
     data.resize(size);
-    uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+    uint8* start = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
     uint8* end = message1.SerializeWithCachedSizesToArray(start);
     EXPECT_EQ(size, end - start);
     EXPECT_TRUE(message2.ParseFromString(data));
@@ -1931,7 +1919,7 @@
     message1.set_foo_bytes("qux");
     int size = message1.ByteSizeLong();
     data.resize(size);
-    uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+    uint8* start = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
     uint8* end = message1.SerializeWithCachedSizesToArray(start);
     EXPECT_EQ(size, end - start);
     EXPECT_TRUE(message2.ParseFromString(data));
@@ -1945,7 +1933,7 @@
     message1.set_foo_enum(UNITTEST::TestOneof2::FOO);
     int size = message1.ByteSizeLong();
     data.resize(size);
-    uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+    uint8* start = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
     uint8* end = message1.SerializeWithCachedSizesToArray(start);
     EXPECT_EQ(size, end - start);
     EXPECT_TRUE(message2.ParseFromString(data));
@@ -1959,7 +1947,7 @@
     message1.mutable_foo_message()->set_qux_int(234);
     int size = message1.ByteSizeLong();
     data.resize(size);
-    uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+    uint8* start = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
     uint8* end = message1.SerializeWithCachedSizesToArray(start);
     EXPECT_EQ(size, end - start);
     EXPECT_TRUE(message2.ParseFromString(data));
@@ -1973,7 +1961,7 @@
     message1.mutable_foogroup()->set_a(345);
     int size = message1.ByteSizeLong();
     data.resize(size);
-    uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+    uint8* start = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
     uint8* end = message1.SerializeWithCachedSizesToArray(start);
     EXPECT_EQ(size, end - start);
     EXPECT_TRUE(message2.ParseFromString(data));
@@ -1998,7 +1986,7 @@
 
     {
       // Allow the output stream to buffer only one byte at a time.
-      io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+      io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
       io::CodedOutputStream output_stream(&array_stream);
       message1.SerializeWithCachedSizes(&output_stream);
       EXPECT_FALSE(output_stream.HadError());
@@ -2019,7 +2007,7 @@
 
     {
       // Allow the output stream to buffer only one byte at a time.
-      io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+      io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
       io::CodedOutputStream output_stream(&array_stream);
       message1.SerializeWithCachedSizes(&output_stream);
       EXPECT_FALSE(output_stream.HadError());
@@ -2041,7 +2029,7 @@
 
     {
       // Allow the output stream to buffer only one byte at a time.
-      io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+      io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
       io::CodedOutputStream output_stream(&array_stream);
       message1.SerializeWithCachedSizes(&output_stream);
       EXPECT_FALSE(output_stream.HadError());
@@ -2062,7 +2050,7 @@
 
     {
       // Allow the output stream to buffer only one byte at a time.
-      io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+      io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
       io::CodedOutputStream output_stream(&array_stream);
       message1.SerializeWithCachedSizes(&output_stream);
       EXPECT_FALSE(output_stream.HadError());
@@ -2083,7 +2071,7 @@
 
     {
       // Allow the output stream to buffer only one byte at a time.
-      io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+      io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
       io::CodedOutputStream output_stream(&array_stream);
       message1.SerializeWithCachedSizes(&output_stream);
       EXPECT_FALSE(output_stream.HadError());
@@ -2104,7 +2092,7 @@
 
     {
       // Allow the output stream to buffer only one byte at a time.
-      io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+      io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
       io::CodedOutputStream output_stream(&array_stream);
       message1.SerializeWithCachedSizes(&output_stream);
       EXPECT_FALSE(output_stream.HadError());
@@ -2161,7 +2149,7 @@
 
 TEST(HELPERS_TEST_NAME, TestSCC) {
   UNITTEST::TestMutualRecursionA a;
-  SCCAnalyzer scc_analyzer((Options()));
+  MessageSCCAnalyzer scc_analyzer((Options()));
   const SCC* scc = scc_analyzer.GetSCC(a.GetDescriptor());
   std::vector<string> names;
   for (int i = 0; i < scc->descriptors.size(); i++) {
@@ -2185,7 +2173,7 @@
 TEST(HELPERS_TEST_NAME, TestSCCAnalysis) {
   {
     UNITTEST::TestRecursiveMessage msg;
-    SCCAnalyzer scc_analyzer((Options()));
+    MessageSCCAnalyzer scc_analyzer((Options()));
     const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor());
     MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc);
     EXPECT_EQ(result.is_recursive, true);
@@ -2195,7 +2183,7 @@
   }
   {
     UNITTEST::TestAllExtensions msg;
-    SCCAnalyzer scc_analyzer((Options()));
+    MessageSCCAnalyzer scc_analyzer((Options()));
     const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor());
     MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc);
     EXPECT_EQ(result.is_recursive, false);
@@ -2205,7 +2193,7 @@
   }
   {
     UNITTEST::TestRequired msg;
-    SCCAnalyzer scc_analyzer((Options()));
+    MessageSCCAnalyzer scc_analyzer((Options()));
     const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor());
     MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc);
     EXPECT_EQ(result.is_recursive, false);
@@ -2269,8 +2257,8 @@
 #endif
 
   EXPECT_EQ(should_have_descriptors,
-    DescriptorPool::generated_pool()->InternalIsFileLoaded(
-      UNITTEST_PROTO_PATH));
+            DescriptorPool::generated_pool()->InternalIsFileLoaded(
+                TestUtil::MaybeTranslatePath(UNITTEST_PROTO_PATH)));
 }
 
 }  // namespace cpp_unittest
diff --git a/src/google/protobuf/compiler/cpp/metadata_test.cc b/src/google/protobuf/compiler/cpp/metadata_test.cc
index 2ad4edd..77636fe 100644
--- a/src/google/protobuf/compiler/cpp/metadata_test.cc
+++ b/src/google/protobuf/compiler/cpp/metadata_test.cc
@@ -42,11 +42,12 @@
 #include <gtest/gtest.h>
 
 namespace google {
-namespace atu = ::google::protobuf::compiler::annotation_test_util;
-
 namespace protobuf {
 namespace compiler {
 namespace cpp {
+
+namespace atu = annotation_test_util;
+
 namespace {
 
 class CppMetadataTest : public ::testing::Test {
@@ -59,7 +60,7 @@
                        string* pb_h, GeneratedCodeInfo* pb_h_info,
                        string* proto_h, GeneratedCodeInfo* proto_h_info,
                        string* pb_cc) {
-    google::protobuf::compiler::CommandLineInterface cli;
+    CommandLineInterface cli;
     CppGenerator cpp_generator;
     cli.RegisterGenerator("--cpp_out", &cpp_generator, "");
     string cpp_out =
diff --git a/src/google/protobuf/compiler/csharp/csharp_enum.h b/src/google/protobuf/compiler/csharp/csharp_enum.h
index 8925cdf..5170d83 100644
--- a/src/google/protobuf/compiler/csharp/csharp_enum.h
+++ b/src/google/protobuf/compiler/csharp/csharp_enum.h
@@ -35,6 +35,8 @@
 
 #include <google/protobuf/compiler/code_generator.h>
 #include <google/protobuf/compiler/csharp/csharp_source_generator_base.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/printer.h>
 
 namespace google {
 namespace protobuf {
diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h
index df26853..62c2551 100644
--- a/src/google/protobuf/compiler/csharp/csharp_field_base.h
+++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h
@@ -36,6 +36,8 @@
 
 #include <google/protobuf/compiler/code_generator.h>
 #include <google/protobuf/compiler/csharp/csharp_source_generator_base.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/printer.h>
 
 namespace google {
 namespace protobuf {
diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.h b/src/google/protobuf/compiler/csharp/csharp_helpers.h
index c317ad0..8dd265b 100644
--- a/src/google/protobuf/compiler/csharp/csharp_helpers.h
+++ b/src/google/protobuf/compiler/csharp/csharp_helpers.h
@@ -96,7 +96,7 @@
 
 // Note that we wouldn't normally want to export this (we're not expecting
 // it to be used outside libprotoc itself) but this exposes it for testing.
-std::string LIBPROTOBUF_EXPORT GetEnumValueName(const std::string& enum_name, const std::string& enum_value_name);
+std::string LIBPROTOC_EXPORT GetEnumValueName(const std::string& enum_name, const std::string& enum_value_name);
 
 // TODO(jtattermusch): perhaps we could move this to strutil
 std::string StringToBase64(const std::string& input);
diff --git a/src/google/protobuf/compiler/csharp/csharp_reflection_class.h b/src/google/protobuf/compiler/csharp/csharp_reflection_class.h
index e0c69f3..3291d65 100644
--- a/src/google/protobuf/compiler/csharp/csharp_reflection_class.h
+++ b/src/google/protobuf/compiler/csharp/csharp_reflection_class.h
@@ -35,6 +35,8 @@
 
 #include <google/protobuf/compiler/code_generator.h>
 #include <google/protobuf/compiler/csharp/csharp_source_generator_base.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/printer.h>
 
 namespace google {
 namespace protobuf {
diff --git a/src/google/protobuf/compiler/csharp/csharp_source_generator_base.h b/src/google/protobuf/compiler/csharp/csharp_source_generator_base.h
index c741080..790fb1b 100644
--- a/src/google/protobuf/compiler/csharp/csharp_source_generator_base.h
+++ b/src/google/protobuf/compiler/csharp/csharp_source_generator_base.h
@@ -34,6 +34,7 @@
 #include <string>
 
 #include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/io/printer.h>
 
 namespace google {
 namespace protobuf {
diff --git a/src/google/protobuf/compiler/importer.h b/src/google/protobuf/compiler/importer.h
index bf6d3de..5f27907 100644
--- a/src/google/protobuf/compiler/importer.h
+++ b/src/google/protobuf/compiler/importer.h
@@ -99,7 +99,7 @@
   bool FindFileByName(const string& filename,
                       FileDescriptorProto* output) override;
   bool FindFileContainingSymbol(const string& symbol_name,
-                                FileDescriptorProto*output) override;
+                                FileDescriptorProto* output) override;
   bool FindFileContainingExtension(const string& containing_type,
                                    int field_number,
                                    FileDescriptorProto* output) override;
@@ -116,17 +116,13 @@
     ~ValidationErrorCollector();
 
     // implements ErrorCollector ---------------------------------------
-    void AddError(const string& filename,
-                  const string& element_name,
-                  const Message* descriptor,
-                  ErrorLocation location,
+    void AddError(const string& filename, const string& element_name,
+                  const Message* descriptor, ErrorLocation location,
                   const string& message) override;
 
-    virtual void AddWarning(const string& filename,
-                            const string& element_name,
-                            const Message* descriptor,
-                            ErrorLocation location,
-                            const string& message) override;
+    void AddWarning(const string& filename, const string& element_name,
+                    const Message* descriptor, ErrorLocation location,
+                    const string& message) override;
 
    private:
     SourceTreeDescriptorDatabase* owner_;
@@ -294,9 +290,9 @@
   bool VirtualFileToDiskFile(const string& virtual_file, string* disk_file);
 
   // implements SourceTree -------------------------------------------
-  virtual io::ZeroCopyInputStream* Open(const string& filename) override;
+  io::ZeroCopyInputStream* Open(const string& filename) override;
 
-  virtual string GetLastErrorMessage() override;
+  string GetLastErrorMessage() override;
 
  private:
   struct Mapping {
@@ -323,6 +319,6 @@
 
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc
index 73bef3f..5108809 100644
--- a/src/google/protobuf/compiler/importer_unittest.cc
+++ b/src/google/protobuf/compiler/importer_unittest.cc
@@ -34,8 +34,8 @@
 
 #include <google/protobuf/compiler/importer.h>
 
-#include <google/protobuf/stubs/hash.h>
 #include <memory>
+#include <unordered_map>
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
@@ -112,7 +112,7 @@
   }
 
  private:
-  hash_map<string, const char*> files_;
+  std::unordered_map<string, const char*> files_;
 };
 
 // ===================================================================
diff --git a/src/google/protobuf/compiler/java/java_context.h b/src/google/protobuf/compiler/java/java_context.h
index 9de7415..fd41a27 100644
--- a/src/google/protobuf/compiler/java/java_context.h
+++ b/src/google/protobuf/compiler/java/java_context.h
@@ -51,7 +51,9 @@
     }
   }
 }  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -106,6 +108,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_CONTEXT_H__
diff --git a/src/google/protobuf/compiler/java/java_doc_comment.h b/src/google/protobuf/compiler/java/java_doc_comment.h
index 7d9535c..112c3bc 100644
--- a/src/google/protobuf/compiler/java/java_doc_comment.h
+++ b/src/google/protobuf/compiler/java/java_doc_comment.h
@@ -39,11 +39,13 @@
 
 namespace google {
 namespace protobuf {
-  namespace io {
-    class Printer;             // printer.h
-  }
+namespace io {
+class Printer;  // printer.h
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -64,6 +66,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__
diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc
index bef69f1..1ca7ba9 100644
--- a/src/google/protobuf/compiler/java/java_enum.cc
+++ b/src/google/protobuf/compiler/java/java_enum.cc
@@ -190,10 +190,9 @@
   printer->Indent();
 
   for (int i = 0; i < canonical_values_.size(); i++) {
-    printer->Print(
-      "case $number$: return $name$;\n",
-      "name", canonical_values_[i]->name(),
-      "number", SimpleItoa(canonical_values_[i]->number()));
+    printer->Print("case $number$: return $name$;\n", "name",
+                   canonical_values_[i]->name(), "number",
+                   SimpleItoa(canonical_values_[i]->number()));
   }
 
   printer->Outdent();
@@ -242,19 +241,22 @@
       // extensions in both the mutable and immutable cases. (In the mutable api
       // this is accomplished by attempting to load the immutable outer class).
       printer->Print(
-        "  return $file$.getDescriptor().getEnumTypes().get($index$);\n",
-        "file", name_resolver_->GetClassName(descriptor_->file(),
-                                             immutable_api_),
-        "index", SimpleItoa(descriptor_->index()));
+          "  return $file$.getDescriptor().getEnumTypes().get($index$);\n",
+          "file",
+          name_resolver_->GetClassName(descriptor_->file(), immutable_api_),
+          "index", SimpleItoa(descriptor_->index()));
     } else {
       printer->Print(
           "  return $parent$.$descriptor$.getEnumTypes().get($index$);\n",
-          "parent", name_resolver_->GetClassName(descriptor_->containing_type(),
-                                                 immutable_api_),
-          "descriptor", descriptor_->containing_type()->options()
-                        .no_standard_descriptor_accessor()
-                        ? "getDefaultInstance().getDescriptorForType()"
-                        : "getDescriptor()",
+          "parent",
+          name_resolver_->GetClassName(descriptor_->containing_type(),
+                                       immutable_api_),
+          "descriptor",
+          descriptor_->containing_type()
+                  ->options()
+                  .no_standard_descriptor_accessor()
+              ? "getDefaultInstance().getDescriptorForType()"
+              : "getDescriptor()",
           "index", SimpleItoa(descriptor_->index()));
     }
 
diff --git a/src/google/protobuf/compiler/java/java_enum.h b/src/google/protobuf/compiler/java/java_enum.h
index 13dfc32..d650924 100644
--- a/src/google/protobuf/compiler/java/java_enum.h
+++ b/src/google/protobuf/compiler/java/java_enum.h
@@ -41,17 +41,19 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;           // context.h
-      class ClassNameResolver; // name_resolver.h
-    }
-  }
-  namespace io {
-    class Printer;             // printer.h
+namespace compiler {
+  namespace java {
+    class Context;           // context.h
+    class ClassNameResolver; // name_resolver.h
   }
 }
+namespace io {
+  class Printer;             // printer.h
+}
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -67,9 +69,9 @@
  private:
   const EnumDescriptor* descriptor_;
 
-  // The proto language allows multiple enum constants to have the same numeric
-  // value.  Java, however, does not allow multiple enum constants to be
-  // considered equivalent.  We treat the first defined constant for any
+  // The proto language allows multiple enum constants to have the same
+  // numeric value.  Java, however, does not allow multiple enum constants to
+  // be considered equivalent.  We treat the first defined constant for any
   // given numeric value as "canonical" and the rest as aliases of that
   // canonical value.
   std::vector<const EnumValueDescriptor*> canonical_values_;
@@ -93,6 +95,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__
diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc
index ef64d88..9d0bcd2 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field.cc
@@ -66,10 +66,10 @@
   (*variables)["mutable_type"] =
       name_resolver->GetMutableClassName(descriptor->enum_type());
   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
-  (*variables)["default_number"] = SimpleItoa(
-      descriptor->default_value_enum()->number());
-  (*variables)["tag"] =
-      SimpleItoa(static_cast<int32>(internal::WireFormat::MakeTag(descriptor)));
+  (*variables)["default_number"] =
+      SimpleItoa(descriptor->default_value_enum()->number());
+  (*variables)["tag"] = SimpleItoa(
+      static_cast<int32>(internal::WireFormat::MakeTag(descriptor)));
   (*variables)["tag_size"] = SimpleItoa(
       internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
@@ -305,15 +305,11 @@
   if (SupportFieldPresence(descriptor_->file())) {
     printer->Print(variables_,
       "if ($get_has_field_bit_from_local$) {\n"
-      "  result.$name$_ = $name$_;\n"
       "  $set_has_field_bit_to_local$;\n"
-      "} else {\n"
-      "  result.$name$_ = $default_number$;\n"
       "}\n");
-  } else {
-    printer->Print(variables_,
-      "result.$name$_ = $name$_;\n");
   }
+  printer->Print(variables_,
+    "result.$name$_ = $name$_;\n");
 }
 
 void ImmutableEnumFieldGenerator::
diff --git a/src/google/protobuf/compiler/java/java_enum_field.h b/src/google/protobuf/compiler/java/java_enum_field.h
index 924ff28..842da59 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.h
+++ b/src/google/protobuf/compiler/java/java_enum_field.h
@@ -41,26 +41,29 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;            // context.h
-      class ClassNameResolver;  // name_resolver.h
-    }
-  }
-}
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
 
 class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator {
  public:
-  explicit ImmutableEnumFieldGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  explicit ImmutableEnumFieldGenerator(const FieldDescriptor* descriptor,
+                                       int messageBitIndex, int builderBitIndex,
+                                       Context* context);
   ~ImmutableEnumFieldGenerator();
 
-  // implements ImmutableFieldGenerator ---------------------------------------
+  // implements ImmutableFieldGenerator
+  // ---------------------------------------
   int GetNumBitsForMessage() const;
   int GetNumBitsForBuilder() const;
   void GenerateInterfaceMembers(io::Printer* printer) const;
@@ -94,9 +97,9 @@
 
 class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator {
  public:
-  ImmutableEnumOneofFieldGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  ImmutableEnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+                                   int messageBitIndex, int builderBitIndex,
+                                   Context* context);
   ~ImmutableEnumOneofFieldGenerator();
 
   void GenerateMembers(io::Printer* printer) const;
@@ -155,6 +158,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__
diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
index f1fe71b..353a2f6 100644
--- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
@@ -66,10 +66,10 @@
   (*variables)["mutable_type"] =
       name_resolver->GetMutableClassName(descriptor->enum_type());
   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
-  (*variables)["default_number"] = SimpleItoa(
-      descriptor->default_value_enum()->number());
-  (*variables)["tag"] =
-      SimpleItoa(static_cast<int32>(internal::WireFormat::MakeTag(descriptor)));
+  (*variables)["default_number"] =
+      SimpleItoa(descriptor->default_value_enum()->number());
+  (*variables)["tag"] = SimpleItoa(
+      static_cast<int32>(internal::WireFormat::MakeTag(descriptor)));
   (*variables)["tag_size"] = SimpleItoa(
       internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
@@ -120,14 +120,12 @@
 ImmutableEnumFieldLiteGenerator::
 ImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
                             int messageBitIndex,
-                            int builderBitIndex,
                             Context* context)
   : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
-    builderBitIndex_(builderBitIndex),
-    name_resolver_(context->GetNameResolver()) {
-  SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
-                   context->GetFieldGeneratorInfo(descriptor),
-                   name_resolver_, &variables_);
+    context_(context), name_resolver_(context->GetNameResolver()) {
+  SetEnumVariables(descriptor, messageBitIndex, 0,
+                   context->GetFieldGeneratorInfo(descriptor), name_resolver_,
+                   &variables_);
 }
 
 ImmutableEnumFieldLiteGenerator::~ImmutableEnumFieldLiteGenerator() {}
@@ -136,10 +134,6 @@
   return 1;
 }
 
-int ImmutableEnumFieldLiteGenerator::GetNumBitsForBuilder() const {
-  return 0;
-}
-
 void ImmutableEnumFieldLiteGenerator::
 GenerateInterfaceMembers(io::Printer* printer) const {
   if (SupportFieldPresence(descriptor_->file())) {
@@ -363,13 +357,9 @@
 
 // ===================================================================
 
-ImmutableEnumOneofFieldLiteGenerator::
-ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
-                                 int messageBitIndex,
-                                 int builderBitIndex,
-                                 Context* context)
-    : ImmutableEnumFieldLiteGenerator(
-          descriptor, messageBitIndex, builderBitIndex, context) {
+ImmutableEnumOneofFieldLiteGenerator::ImmutableEnumOneofFieldLiteGenerator(
+    const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
+    : ImmutableEnumFieldLiteGenerator(descriptor, messageBitIndex, context) {
   const OneofGeneratorInfo* info =
       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
   SetCommonOneofVariables(descriptor, info, &variables_);
@@ -570,16 +560,16 @@
 // ===================================================================
 
 RepeatedImmutableEnumFieldLiteGenerator::
-RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
-                                    int messageBitIndex,
-                                    int builderBitIndex,
-                                    Context* context)
-  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
-    builderBitIndex_(builderBitIndex), context_(context),
-    name_resolver_(context->GetNameResolver()) {
-  SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
-                   context->GetFieldGeneratorInfo(descriptor),
-                   name_resolver_, &variables_);
+    RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
+                                            int messageBitIndex,
+                                            Context* context)
+    : descriptor_(descriptor),
+      messageBitIndex_(messageBitIndex),
+      context_(context),
+      name_resolver_(context->GetNameResolver()) {
+  SetEnumVariables(descriptor, messageBitIndex, 0,
+                   context->GetFieldGeneratorInfo(descriptor), name_resolver_,
+                   &variables_);
 }
 
 RepeatedImmutableEnumFieldLiteGenerator::
@@ -589,10 +579,6 @@
   return 0;
 }
 
-int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForBuilder() const {
-  return 0;
-}
-
 void RepeatedImmutableEnumFieldLiteGenerator::
 GenerateInterfaceMembers(io::Printer* printer) const {
   WriteFieldDocComment(printer, descriptor_);
diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.h b/src/google/protobuf/compiler/java/java_enum_field_lite.h
index fa00472..6bda426 100644
--- a/src/google/protobuf/compiler/java/java_enum_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_enum_field_lite.h
@@ -41,28 +41,30 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;            // context.h
-      class ClassNameResolver;  // name_resolver.h
-    }
-  }
-}
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
 
 class ImmutableEnumFieldLiteGenerator : public ImmutableFieldLiteGenerator {
  public:
-  explicit ImmutableEnumFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  explicit ImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
+                                           int messageBitIndex,
+                                           Context* context);
   ~ImmutableEnumFieldLiteGenerator();
 
-  // implements ImmutableFieldLiteGenerator ------------------------------------
+  // implements ImmutableFieldLiteGenerator
+  // ------------------------------------
   int GetNumBitsForMessage() const;
-  int GetNumBitsForBuilder() const;
   void GenerateInterfaceMembers(io::Printer* printer) const;
   void GenerateMembers(io::Printer* printer) const;
   void GenerateBuilderMembers(io::Printer* printer) const;
@@ -83,7 +85,6 @@
   const FieldDescriptor* descriptor_;
   std::map<string, string> variables_;
   const int messageBitIndex_;
-  const int builderBitIndex_;
   Context* context_;
   ClassNameResolver* name_resolver_;
 
@@ -94,9 +95,8 @@
 class ImmutableEnumOneofFieldLiteGenerator
     : public ImmutableEnumFieldLiteGenerator {
  public:
-  ImmutableEnumOneofFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
+                                       int messageBitIndex, Context* context);
   ~ImmutableEnumOneofFieldLiteGenerator();
 
   void GenerateMembers(io::Printer* printer) const;
@@ -116,13 +116,11 @@
     : public ImmutableFieldLiteGenerator {
  public:
   explicit RepeatedImmutableEnumFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+      const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
   ~RepeatedImmutableEnumFieldLiteGenerator();
 
   // implements ImmutableFieldLiteGenerator ------------------------------------
   int GetNumBitsForMessage() const;
-  int GetNumBitsForBuilder() const;
   void GenerateInterfaceMembers(io::Printer* printer) const;
   void GenerateMembers(io::Printer* printer) const;
   void GenerateBuilderMembers(io::Printer* printer) const;
@@ -144,7 +142,6 @@
   const FieldDescriptor* descriptor_;
   std::map<string, string> variables_;
   const int messageBitIndex_;
-  const int builderBitIndex_;
   Context* context_;
   ClassNameResolver* name_resolver_;
 
@@ -154,6 +151,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_LITE_H__
diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc
index 806008e..deebe52 100644
--- a/src/google/protobuf/compiler/java/java_enum_lite.cc
+++ b/src/google/protobuf/compiler/java/java_enum_lite.cc
@@ -43,6 +43,7 @@
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/map_util.h>
 
 namespace google {
 namespace protobuf {
@@ -163,33 +164,47 @@
   printer->Indent();
 
   for (int i = 0; i < canonical_values_.size(); i++) {
-    printer->Print(
-      "case $number$: return $name$;\n",
-      "name", canonical_values_[i]->name(),
-      "number", SimpleItoa(canonical_values_[i]->number()));
+    printer->Print("case $number$: return $name$;\n", "name",
+                   canonical_values_[i]->name(), "number",
+                   SimpleItoa(canonical_values_[i]->number()));
   }
 
   printer->Outdent();
   printer->Outdent();
   printer->Print(
-    "    default: return null;\n"
-    "  }\n"
-    "}\n"
-    "\n"
-    "public static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
-    "    internalGetValueMap() {\n"
-    "  return internalValueMap;\n"
-    "}\n"
-    "private static final com.google.protobuf.Internal.EnumLiteMap<\n"
-    "    $classname$> internalValueMap =\n"
-    "      new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n"
-    "        @java.lang.Override\n"
-    "        public $classname$ findValueByNumber(int number) {\n"
-    "          return $classname$.forNumber(number);\n"
-    "        }\n"
-    "      };\n"
-    "\n",
-    "classname", descriptor_->name());
+      "    default: return null;\n"
+      "  }\n"
+      "}\n"
+      "\n"
+      "public static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
+      "    internalGetValueMap() {\n"
+      "  return internalValueMap;\n"
+      "}\n"
+      "private static final com.google.protobuf.Internal.EnumLiteMap<\n"
+      "    $classname$> internalValueMap =\n"
+      "      new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n"
+      "        @java.lang.Override\n"
+      "        public $classname$ findValueByNumber(int number) {\n"
+      "          return $classname$.forNumber(number);\n"
+      "        }\n"
+      "      };\n"
+      "\n"
+      "public static com.google.protobuf.Internal.EnumVerifier \n"
+      "    internalGetVerifier() {\n"
+      "  return $classname$Verifier.INSTANCE;\n"
+      "}\n"
+      "\n"
+      "private static final class $classname$Verifier implements \n"
+      "     com.google.protobuf.Internal.EnumVerifier { \n"
+      "        static final com.google.protobuf.Internal.EnumVerifier "
+      "          INSTANCE = new $classname$Verifier();\n"
+      "        @java.lang.Override\n"
+      "        public boolean isInRange(int number) {\n"
+      "          return $classname$.forNumber(number) != null;\n"
+      "        }\n"
+      "      };\n"
+      "\n",
+      "classname", descriptor_->name());
 
   printer->Print(
     "private final int value;\n\n"
diff --git a/src/google/protobuf/compiler/java/java_enum_lite.h b/src/google/protobuf/compiler/java/java_enum_lite.h
index b7be912..9e20e6f 100644
--- a/src/google/protobuf/compiler/java/java_enum_lite.h
+++ b/src/google/protobuf/compiler/java/java_enum_lite.h
@@ -41,17 +41,19 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;           // context.h
-      class ClassNameResolver; // name_resolver.h
-    }
-  }
-  namespace io {
-    class Printer;             // printer.h
+namespace compiler {
+  namespace java {
+    class Context;           // context.h
+    class ClassNameResolver; // name_resolver.h
   }
 }
+namespace io {
+  class Printer;             // printer.h
+}
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -67,9 +69,9 @@
  private:
   const EnumDescriptor* descriptor_;
 
-  // The proto language allows multiple enum constants to have the same numeric
-  // value.  Java, however, does not allow multiple enum constants to be
-  // considered equivalent.  We treat the first defined constant for any
+  // The proto language allows multiple enum constants to have the same
+  // numeric value.  Java, however, does not allow multiple enum constants to
+  // be considered equivalent.  We treat the first defined constant for any
   // given numeric value as "canonical" and the rest as aliases of that
   // canonical value.
   std::vector<const EnumValueDescriptor*> canonical_values_;
@@ -93,6 +95,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_LITE_H__
diff --git a/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc
index 3eb1370..1ee9771 100644
--- a/src/google/protobuf/compiler/java/java_extension.cc
+++ b/src/google/protobuf/compiler/java/java_extension.cc
@@ -151,8 +151,8 @@
     // Only applies to non-nested extensions.
     printer->Print(
         "$name$.internalInit(descriptor.getExtensions().get($index$));\n",
-        "name", UnderscoresToCamelCase(descriptor_),
-        "index", SimpleItoa(descriptor_->index()));
+        "name", UnderscoresToCamelCase(descriptor_), "index",
+        SimpleItoa(descriptor_->index()));
     bytecode_estimate += 21;
   }
   return bytecode_estimate;
diff --git a/src/google/protobuf/compiler/java/java_extension.h b/src/google/protobuf/compiler/java/java_extension.h
index fb8d520..7a58373 100644
--- a/src/google/protobuf/compiler/java/java_extension.h
+++ b/src/google/protobuf/compiler/java/java_extension.h
@@ -42,18 +42,20 @@
 
 namespace google {
 namespace protobuf {
-  class FieldDescriptor;       // descriptor.h
-  namespace compiler {
-    namespace java {
-      class Context;           // context.h
-      class ClassNameResolver; // name_resolver.h
-    }
-  }
-  namespace io {
-    class Printer;             // printer.h
-  }
+class FieldDescriptor;  // descriptor.h
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+namespace io {
+class Printer;  // printer.h
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -68,16 +70,17 @@
 
   virtual void Generate(io::Printer* printer) = 0;
 
-  // Returns an estimate of the number of bytes the printed code will compile to
+  // Returns an estimate of the number of bytes the printed code will compile
+  // to
   virtual int GenerateNonNestedInitializationCode(io::Printer* printer) = 0;
 
-  // Returns an estimate of the number of bytes the printed code will compile to
+  // Returns an estimate of the number of bytes the printed code will compile
+  // to
   virtual int GenerateRegistrationCode(io::Printer* printer) = 0;
 
  protected:
   static void InitTemplateVars(const FieldDescriptor* descriptor,
-                               const string& scope,
-                               bool immutable,
+                               const string& scope, bool immutable,
                                ClassNameResolver* name_resolver,
                                std::map<string, string>* vars_pointer);
 
@@ -108,6 +111,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__
diff --git a/src/google/protobuf/compiler/java/java_extension_lite.h b/src/google/protobuf/compiler/java/java_extension_lite.h
index 4cd49bd..34716f9 100644
--- a/src/google/protobuf/compiler/java/java_extension_lite.h
+++ b/src/google/protobuf/compiler/java/java_extension_lite.h
@@ -71,6 +71,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_LITE_H__
diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc
index 93de022..fec20a7 100644
--- a/src/google/protobuf/compiler/java/java_field.cc
+++ b/src/google/protobuf/compiler/java/java_field.cc
@@ -121,58 +121,57 @@
 }
 
 ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator(
-    const FieldDescriptor* field, int messageBitIndex, int builderBitIndex,
-    Context* context) {
+    const FieldDescriptor* field, int messageBitIndex, Context* context) {
   if (field->is_repeated()) {
     switch (GetJavaType(field)) {
       case JAVATYPE_MESSAGE:
         if (IsMapEntry(field->message_type())) {
-          return new ImmutableMapFieldLiteGenerator(
-              field, messageBitIndex, builderBitIndex, context);
+          return new ImmutableMapFieldLiteGenerator(field, messageBitIndex,
+                                                    context);
         } else {
           return new RepeatedImmutableMessageFieldLiteGenerator(
-              field, messageBitIndex, builderBitIndex, context);
+              field, messageBitIndex, context);
         }
       case JAVATYPE_ENUM:
         return new RepeatedImmutableEnumFieldLiteGenerator(
-            field, messageBitIndex, builderBitIndex, context);
+            field, messageBitIndex, context);
       case JAVATYPE_STRING:
         return new RepeatedImmutableStringFieldLiteGenerator(
-            field, messageBitIndex, builderBitIndex, context);
+            field, messageBitIndex, context);
       default:
         return new RepeatedImmutablePrimitiveFieldLiteGenerator(
-            field, messageBitIndex, builderBitIndex, context);
+            field, messageBitIndex, context);
     }
   } else {
     if (field->containing_oneof()) {
       switch (GetJavaType(field)) {
         case JAVATYPE_MESSAGE:
           return new ImmutableMessageOneofFieldLiteGenerator(
-              field, messageBitIndex, builderBitIndex, context);
+              field, messageBitIndex, context);
         case JAVATYPE_ENUM:
           return new ImmutableEnumOneofFieldLiteGenerator(
-              field, messageBitIndex, builderBitIndex, context);
+              field, messageBitIndex, context);
         case JAVATYPE_STRING:
           return new ImmutableStringOneofFieldLiteGenerator(
-              field, messageBitIndex, builderBitIndex, context);
+              field, messageBitIndex, context);
         default:
           return new ImmutablePrimitiveOneofFieldLiteGenerator(
-              field, messageBitIndex, builderBitIndex, context);
+              field, messageBitIndex, context);
       }
     } else {
       switch (GetJavaType(field)) {
         case JAVATYPE_MESSAGE:
-          return new ImmutableMessageFieldLiteGenerator(
-              field, messageBitIndex, builderBitIndex, context);
+          return new ImmutableMessageFieldLiteGenerator(field, messageBitIndex,
+                                                        context);
         case JAVATYPE_ENUM:
-          return new ImmutableEnumFieldLiteGenerator(
-              field, messageBitIndex, builderBitIndex, context);
+          return new ImmutableEnumFieldLiteGenerator(field, messageBitIndex,
+                                                     context);
         case JAVATYPE_STRING:
-          return new ImmutableStringFieldLiteGenerator(
-              field, messageBitIndex, builderBitIndex, context);
+          return new ImmutableStringFieldLiteGenerator(field, messageBitIndex,
+                                                       context);
         default:
           return new ImmutablePrimitiveFieldLiteGenerator(
-              field, messageBitIndex, builderBitIndex, context);
+              field, messageBitIndex, context);
       }
     }
   }
@@ -210,9 +209,7 @@
 template <>
 FieldGeneratorMap<ImmutableFieldGenerator>::FieldGeneratorMap(
     const Descriptor* descriptor, Context* context)
-    : descriptor_(descriptor),
-      field_generators_(descriptor->field_count()) {
-
+    : descriptor_(descriptor), field_generators_(descriptor->field_count()) {
   // Construct all the FieldGenerators and assign them bit indices for their
   // bit fields.
   int messageBitIndex = 0;
@@ -232,18 +229,15 @@
 template <>
 FieldGeneratorMap<ImmutableFieldLiteGenerator>::FieldGeneratorMap(
     const Descriptor* descriptor, Context* context)
-    : descriptor_(descriptor),
-      field_generators_(descriptor->field_count()) {
+    : descriptor_(descriptor), field_generators_(descriptor->field_count()) {
   // Construct all the FieldGenerators and assign them bit indices for their
   // bit fields.
   int messageBitIndex = 0;
-  int builderBitIndex = 0;
   for (int i = 0; i < descriptor->field_count(); i++) {
     ImmutableFieldLiteGenerator* generator = MakeImmutableLiteGenerator(
-        descriptor->field(i), messageBitIndex, builderBitIndex, context);
+        descriptor->field(i), messageBitIndex, context);
     field_generators_[i].reset(generator);
     messageBitIndex += generator->GetNumBitsForMessage();
-    builderBitIndex += generator->GetNumBitsForBuilder();
   }
 }
 
@@ -276,12 +270,12 @@
   (*variables)["oneof_capitalized_name"] = info->capitalized_name;
   (*variables)["oneof_index"] =
       SimpleItoa(descriptor->containing_oneof()->index());
-  (*variables)["set_oneof_case_message"] = info->name +
-      "Case_ = " + SimpleItoa(descriptor->number());
+  (*variables)["set_oneof_case_message"] =
+      info->name + "Case_ = " + SimpleItoa(descriptor->number());
   (*variables)["clear_oneof_case_message"] = info->name +
       "Case_ = 0";
-  (*variables)["has_oneof_case_message"] = info->name +
-      "Case_ == " + SimpleItoa(descriptor->number());
+  (*variables)["has_oneof_case_message"] =
+      info->name + "Case_ == " + SimpleItoa(descriptor->number());
 }
 
 void PrintExtraFieldInfo(const std::map<string, string>& variables,
diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h
index 7275c09..881427d 100644
--- a/src/google/protobuf/compiler/java/java_field.h
+++ b/src/google/protobuf/compiler/java/java_field.h
@@ -45,17 +45,19 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;                // context.h
-      class ClassNameResolver;      // name_resolver.h
-    }
-  }
-  namespace io {
-    class Printer;                  // printer.h
-  }
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+namespace io {
+class Printer;  // printer.h
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -79,8 +81,8 @@
   virtual void GenerateParsingDoneCode(io::Printer* printer) const = 0;
   virtual void GenerateSerializationCode(io::Printer* printer) const = 0;
   virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0;
-  virtual void GenerateFieldBuilderInitializationCode(io::Printer* printer)
-      const = 0;
+  virtual void GenerateFieldBuilderInitializationCode(
+      io::Printer* printer) const = 0;
 
   virtual void GenerateEqualsCode(io::Printer* printer) const = 0;
   virtual void GenerateHashCode(io::Printer* printer) const = 0;
@@ -97,7 +99,6 @@
   virtual ~ImmutableFieldLiteGenerator();
 
   virtual int GetNumBitsForMessage() const = 0;
-  virtual int GetNumBitsForBuilder() const = 0;
   virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0;
   virtual void GenerateMembers(io::Printer* printer) const = 0;
   virtual void GenerateBuilderMembers(io::Printer* printer) const = 0;
@@ -198,6 +199,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc
index 5583b77..bb48a3b 100644
--- a/src/google/protobuf/compiler/java/java_file.cc
+++ b/src/google/protobuf/compiler/java/java_file.cc
@@ -172,7 +172,8 @@
 
   if ((*bytecode_estimate) > bytesPerMethod) {
     ++(*method_num);
-    printer->Print(chain_statement, "method_num", SimpleItoa(*method_num));
+    printer->Print(chain_statement, "method_num",
+                   SimpleItoa(*method_num));
     printer->Outdent();
     printer->Print("}\n");
     printer->Print(method_decl, "method_num", SimpleItoa(*method_num));
@@ -545,11 +546,13 @@
             "      $scope$.getExtensions().get($index$),\n"
             "      (com.google.protobuf.Message) defaultExtensionInstance);\n"
             "}\n",
-            "scope", scope, "index", SimpleItoa(field->index()), "class",
+            "scope", scope, "index", SimpleItoa(field->index()),
+            "class",
             name_resolver_->GetImmutableClassName(field->message_type()));
       } else {
         printer->Print("registry.add($scope$.getExtensions().get($index$));\n",
-                       "scope", scope, "index", SimpleItoa(field->index()));
+                       "scope", scope, "index",
+                       SimpleItoa(field->index()));
       }
     }
     printer->Print(
diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h
index 78833a4..4158d48 100644
--- a/src/google/protobuf/compiler/java/java_file.h
+++ b/src/google/protobuf/compiler/java/java_file.h
@@ -43,22 +43,24 @@
 
 namespace google {
 namespace protobuf {
-  class FileDescriptor;          // descriptor.h
-  namespace io {
-    class Printer;               // printer.h
-  }
-  namespace compiler {
-    class GeneratorContext;      // code_generator.h
-    namespace java {
-      class Context;             // context.h
-      class MessageGenerator;    // message.h
-      class GeneratorFactory;    // generator_factory.h
-      class ExtensionGenerator;  // extension.h
-      class ClassNameResolver;   // name_resolver.h
-    }
+class FileDescriptor;          // descriptor.h
+namespace io {
+  class Printer;               // printer.h
+}
+namespace compiler {
+  class GeneratorContext;      // code_generator.h
+  namespace java {
+    class Context;             // context.h
+    class MessageGenerator;    // message.h
+    class GeneratorFactory;    // generator_factory.h
+    class ExtensionGenerator;  // extension.h
+    class ClassNameResolver;   // name_resolver.h
   }
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -85,7 +87,7 @@
                         std::vector<string>* annotation_list);
 
   const string& java_package() { return java_package_; }
-  const string& classname()    { return classname_;    }
+  const string& classname() { return classname_; }
 
  private:
   void GenerateDescriptorInitializationCodeForImmutable(io::Printer* printer);
@@ -112,6 +114,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc
index a5b2e78..fd2591d 100644
--- a/src/google/protobuf/compiler/java/java_generator.cc
+++ b/src/google/protobuf/compiler/java/java_generator.cc
@@ -34,6 +34,7 @@
 
 #include <google/protobuf/compiler/java/java_generator.h>
 
+
 #include <memory>
 
 #include <google/protobuf/compiler/java/java_file.h>
@@ -117,6 +118,7 @@
     file_generators.push_back(new FileGenerator(file, file_options,
                                                 /* mutable = */ false));
   }
+
   for (int i = 0; i < file_generators.size(); ++i) {
     if (!file_generators[i]->Validate(error)) {
       for (int j = 0; j < file_generators.size(); ++j) {
@@ -163,6 +165,7 @@
     }
   }
 
+
   for (int i = 0; i < file_generators.size(); ++i) {
     delete file_generators[i];
   }
diff --git a/src/google/protobuf/compiler/java/java_generator.h b/src/google/protobuf/compiler/java/java_generator.h
index 47f76be..6eefdd8 100644
--- a/src/google/protobuf/compiler/java/java_generator.h
+++ b/src/google/protobuf/compiler/java/java_generator.h
@@ -67,6 +67,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
diff --git a/src/google/protobuf/compiler/java/java_generator_factory.h b/src/google/protobuf/compiler/java/java_generator_factory.h
index 55365a9..505cd3a 100644
--- a/src/google/protobuf/compiler/java/java_generator_factory.h
+++ b/src/google/protobuf/compiler/java/java_generator_factory.h
@@ -37,19 +37,21 @@
 
 namespace google {
 namespace protobuf {
-  class FieldDescriptor;         // descriptor.h
-  class Descriptor;              // descriptor.h
-  class ServiceDescriptor;       // descriptor.h
-  namespace compiler {
-    namespace java {
-      class MessageGenerator;    // message.h
-      class ExtensionGenerator;  // extension.h
-      class ServiceGenerator;    // service.h
-      class Context;             // context.h
-    }
+class FieldDescriptor;         // descriptor.h
+class Descriptor;              // descriptor.h
+class ServiceDescriptor;       // descriptor.h
+namespace compiler {
+  namespace java {
+    class MessageGenerator;    // message.h
+    class ExtensionGenerator;  // extension.h
+    class ServiceGenerator;    // service.h
+    class Context;             // context.h
   }
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -96,6 +98,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_FACTORY_H__
diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc
index 957076c..dbd1604 100644
--- a/src/google/protobuf/compiler/java/java_helpers.cc
+++ b/src/google/protobuf/compiler/java/java_helpers.cc
@@ -33,8 +33,8 @@
 //  Sanjay Ghemawat, Jeff Dean, and others.
 
 #include <algorithm>
-#include <google/protobuf/stubs/hash.h>
 #include <limits>
+#include <unordered_set>
 #include <vector>
 
 #include <google/protobuf/stubs/stringprintf.h>
@@ -135,6 +135,29 @@
   printer->Print(ptemplate.c_str(), "annotation_file", annotation_file);
 }
 
+void PrintEnumVerifierLogic(io::Printer* printer,
+                            const FieldDescriptor* descriptor,
+                            const std::map<string, string>& variables,
+                            const char* var_name,
+                            const char* terminating_string,
+                            bool enforce_lite) {
+  std::string enum_verifier_string =
+      (descriptor->enum_type()->file()->options().optimize_for() ==
+       FileOptions::LITE_RUNTIME) || enforce_lite
+          ? StrCat(var_name, ".internalGetVerifier()")
+          : StrCat(
+              "new com.google.protobuf.Internal.EnumVerifier() {\n"
+              "        @java.lang.Override\n"
+              "        public boolean isInRange(int number) {\n"
+              "          return ", var_name, ".forNumber(number) != null;\n"
+              "        }\n"
+              "      }"
+      );
+  printer->Print(
+      variables,
+      StrCat(enum_verifier_string, terminating_string).c_str());
+}
+
 string UnderscoresToCamelCase(const string& input, bool cap_next_letter) {
   string result;
   // Note:  I distrust ctype.h due to locales.
@@ -178,6 +201,10 @@
   return UnderscoresToCamelCase(FieldName(field), true);
 }
 
+string CapitalizedFieldName(const FieldDescriptor* field) {
+  return UnderscoresToCapitalizedCamelCase(field);
+}
+
 string UnderscoresToCamelCase(const MethodDescriptor* method) {
   return UnderscoresToCamelCase(method->name(), false);
 }
@@ -223,6 +250,10 @@
   return result;
 }
 
+string FileJavaPackage(const FileDescriptor* file) {
+  return FileJavaPackage(file, true /* immutable */);
+}
+
 string JavaPackageToDir(string package_name) {
   string package_dir =
     StringReplace(package_name, ".", "/", true);
@@ -369,6 +400,10 @@
   return NULL;
 }
 
+const char* PrimitiveTypeName(const FieldDescriptor* descriptor) {
+  return PrimitiveTypeName(GetJavaType(descriptor));
+}
+
 const char* BoxedPrimitiveTypeName(JavaType type) {
   switch (type) {
     case JAVATYPE_INT    : return "java.lang.Integer";
@@ -389,6 +424,10 @@
   return NULL;
 }
 
+const char* BoxedPrimitiveTypeName(const FieldDescriptor* descriptor) {
+  return BoxedPrimitiveTypeName(GetJavaType(descriptor));
+}
+
 
 const char* FieldTypeName(FieldDescriptor::Type field_type) {
   switch (field_type) {
@@ -437,11 +476,13 @@
       return SimpleItoa(field->default_value_int32());
     case FieldDescriptor::CPPTYPE_UINT32:
       // Need to print as a signed int since Java has no unsigned.
-      return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
+      return SimpleItoa(
+          static_cast<int32>(field->default_value_uint32()));
     case FieldDescriptor::CPPTYPE_INT64:
       return SimpleItoa(field->default_value_int64()) + "L";
     case FieldDescriptor::CPPTYPE_UINT64:
-      return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
+      return SimpleItoa(
+                 static_cast<int64>(field->default_value_uint64())) +
              "L";
     case FieldDescriptor::CPPTYPE_DOUBLE: {
       double value = field->default_value_double();
@@ -749,9 +790,8 @@
 //
 // already_seen is used to avoid checking the same type multiple times
 // (and also to protect against recursion).
-bool HasRequiredFields(
-    const Descriptor* type,
-    hash_set<const Descriptor*>* already_seen) {
+bool HasRequiredFields(const Descriptor* type,
+                       std::unordered_set<const Descriptor*>* already_seen) {
   if (already_seen->count(type) > 0) {
     // The type is already in cache.  This means that either:
     // a. The type has no required fields.
@@ -786,7 +826,7 @@
 }
 
 bool HasRequiredFields(const Descriptor* type) {
-  hash_set<const Descriptor*> already_seen;
+  std::unordered_set<const Descriptor*> already_seen;
   return HasRequiredFields(type, &already_seen);
 }
 
@@ -932,22 +972,6 @@
   }
 }
 
-std::pair<int, int> GetTableDrivenNumberOfEntriesAndLookUpStartFieldNumber(
-    const FieldDescriptor** fields, int count) {
-  GOOGLE_CHECK_GT(count, 0);
-  int table_driven_number_of_entries = count;
-  int look_up_start_field_number = 0;
-  for (int i = 0; i < count; i++) {
-    const int field_number = fields[i]->number();
-    if (ShouldUseTable(fields[0]->number(), field_number, i + 1)) {
-      table_driven_number_of_entries =
-          field_number - fields[0]->number() + 1 + count - i - 1;
-      look_up_start_field_number = field_number + 1;
-    }
-  }
-  return std::make_pair(
-      table_driven_number_of_entries, look_up_start_field_number);
-}
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h
index dd9b65b..375bd67 100644
--- a/src/google/protobuf/compiler/java/java_helpers.h
+++ b/src/google/protobuf/compiler/java/java_helpers.h
@@ -62,6 +62,15 @@
 void PrintGeneratedAnnotation(io::Printer* printer, char delimiter = '$',
                               const string& annotation_file = "");
 
+// If a GeneratedMessageLite contains non-lite enums, then its verifier
+// must be instantiated inline, rather than retrieved from the enum class.
+void PrintEnumVerifierLogic(io::Printer* printer,
+                            const FieldDescriptor* descriptor,
+                            const std::map<string, string>& variables,
+                            const char* var_name,
+                            const char* terminating_string,
+                            bool enforce_lite);
+
 // Converts a name to camel-case. If cap_first_letter is true, capitalize the
 // first letter.
 string UnderscoresToCamelCase(const string& name, bool cap_first_letter);
@@ -93,7 +102,8 @@
 string FileClassName(const FileDescriptor* file, bool immutable = true);
 
 // Returns the file's Java package name.
-string FileJavaPackage(const FileDescriptor* file, bool immutable = true);
+string FileJavaPackage(const FileDescriptor* file);
+string FileJavaPackage(const FileDescriptor* file, bool immutable);
 
 // Returns output directory for the given package name.
 string JavaPackageToDir(string package_name);
@@ -107,7 +117,7 @@
                   const FileDescriptor* file);
 
 // TODO(xiaofeng): the following methods are kept for they are exposed
-// publicly in //google/protobuf/compiler/java/names.h. They return
+// publicly in //net/proto2/compiler/java/public/names.h. They return
 // immutable names only and should be removed after mutable API is
 // integrated into google3.
 string ClassName(const Descriptor* descriptor);
@@ -140,7 +150,8 @@
 // cannot currently use the new runtime with core protos since there is a
 // bootstrapping problem with obtaining their descriptors.
 inline bool IsDescriptorProto(const Descriptor* descriptor) {
-  return descriptor->file()->name() == "google/protobuf/descriptor.proto";
+  return descriptor->file()->name() == "net/proto2/proto/descriptor.proto" ||
+         descriptor->file()->name() == "google/protobuf/descriptor.proto";
 }
 
 
@@ -391,10 +402,6 @@
   return "V3";
 }
 
-inline bool EnableExperimentalRuntime(Context* context) {
-  return false;
-}
-
 void WriteUInt32ToUtf16CharSequence(uint32 number, std::vector<uint16>* output);
 
 inline void WriteIntToUtf16CharSequence(int value,
@@ -422,6 +429,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
diff --git a/src/google/protobuf/compiler/java/java_map_field.h b/src/google/protobuf/compiler/java/java_map_field.h
index 4702174..90c90eb 100644
--- a/src/google/protobuf/compiler/java/java_map_field.h
+++ b/src/google/protobuf/compiler/java/java_map_field.h
@@ -75,6 +75,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_H__
diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.cc b/src/google/protobuf/compiler/java/java_map_field_lite.cc
index e2e6807..569c38d 100644
--- a/src/google/protobuf/compiler/java/java_map_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc
@@ -142,12 +142,12 @@
 ImmutableMapFieldLiteGenerator::
 ImmutableMapFieldLiteGenerator(const FieldDescriptor* descriptor,
                                        int messageBitIndex,
-                                       int builderBitIndex,
                                        Context* context)
-  : descriptor_(descriptor), name_resolver_(context->GetNameResolver())  {
-  SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
-                      context->GetFieldGeneratorInfo(descriptor),
-                      context, &variables_);
+  : descriptor_(descriptor), context_(context),
+    name_resolver_(context->GetNameResolver()){
+  SetMessageVariables(descriptor, messageBitIndex, 0,
+                      context->GetFieldGeneratorInfo(descriptor), context,
+                      &variables_);
 }
 
 ImmutableMapFieldLiteGenerator::
@@ -157,10 +157,6 @@
   return 0;
 }
 
-int ImmutableMapFieldLiteGenerator::GetNumBitsForBuilder() const {
-  return 0;
-}
-
 void ImmutableMapFieldLiteGenerator::
 GenerateInterfaceMembers(io::Printer* printer) const {
   WriteFieldDocComment(printer, descriptor_);
diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.h b/src/google/protobuf/compiler/java/java_map_field_lite.h
index 94aa481..710617a 100644
--- a/src/google/protobuf/compiler/java/java_map_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_map_field_lite.h
@@ -40,14 +40,13 @@
 
 class ImmutableMapFieldLiteGenerator : public ImmutableFieldLiteGenerator {
  public:
-  explicit ImmutableMapFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  explicit ImmutableMapFieldLiteGenerator(const FieldDescriptor* descriptor,
+                                          int messageBitIndex,
+                                          Context* context);
   ~ImmutableMapFieldLiteGenerator();
 
   // implements ImmutableFieldLiteGenerator ------------------------------------
   int GetNumBitsForMessage() const;
-  int GetNumBitsForBuilder() const;
   void GenerateInterfaceMembers(io::Printer* printer) const;
   void GenerateMembers(io::Printer* printer) const;
   void GenerateBuilderMembers(io::Printer* printer) const;
@@ -68,12 +67,13 @@
  private:
   const FieldDescriptor* descriptor_;
   std::map<string, string> variables_;
+  Context* context_;
   ClassNameResolver* name_resolver_;
 };
 
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_LITE_H__
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index 209c0b2..151422310 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -35,7 +35,6 @@
 #include <google/protobuf/compiler/java/java_message.h>
 
 #include <algorithm>
-#include <google/protobuf/stubs/hash.h>
 #include <map>
 #include <memory>
 #include <vector>
@@ -53,8 +52,8 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/wire_format.h>
-#include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
 
 
 namespace google {
@@ -377,10 +376,7 @@
     "}\n");
 
   if (context_->HasGeneratedMethods(descriptor_)) {
-    if (!EnableExperimentalRuntime(context_) ||
-        IsDescriptorProto(descriptor_)) {
-      GenerateParsingConstructor(printer);
-    }
+    GenerateParsingConstructor(printer);
   }
 
   GenerateDescriptorMethods(printer);
@@ -421,7 +417,8 @@
         descriptor_->oneof_decl(i))->name;
     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
         descriptor_->oneof_decl(i))->capitalized_name;
-    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
+    vars["oneof_index"] =
+        SimpleItoa(descriptor_->oneof_decl(i)->index());
     // oneofCase_ and oneof_
     printer->Print(vars,
       "private int $oneof_name$Case_ = 0;\n"
@@ -434,11 +431,10 @@
     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
       printer->Print(
-        "$deprecation$$field_name$($field_number$),\n",
-        "deprecation",
-        field->options().deprecated() ? "@java.lang.Deprecated " : "",
-        "field_name", ToUpper(field->name()),
-        "field_number", SimpleItoa(field->number()));
+          "$deprecation$$field_name$($field_number$),\n", "deprecation",
+          field->options().deprecated() ? "@java.lang.Deprecated " : "",
+          "field_name", ToUpper(field->name()), "field_number",
+          SimpleItoa(field->number()));
     }
     printer->Print(
       "$cap_oneof_name$_NOT_SET(0);\n",
@@ -462,12 +458,9 @@
       "  switch (value) {\n");
     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
-      printer->Print(
-        "    case $field_number$: return $field_name$;\n",
-        "field_number",
-        SimpleItoa(field->number()),
-        "field_name",
-        ToUpper(field->name()));
+      printer->Print("    case $field_number$: return $field_name$;\n",
+                     "field_number", SimpleItoa(field->number()),
+                     "field_name", ToUpper(field->name()));
     }
     printer->Print(
       "    case 0: return $cap_oneof_name$_NOT_SET;\n"
@@ -497,8 +490,9 @@
   // Fields
   for (int i = 0; i < descriptor_->field_count(); i++) {
     printer->Print("public static final int $constant_name$ = $number$;\n",
-      "constant_name", FieldConstantName(descriptor_->field(i)),
-      "number", SimpleItoa(descriptor_->field(i)->number()));
+                   "constant_name", FieldConstantName(descriptor_->field(i)),
+                   "number",
+                   SimpleItoa(descriptor_->field(i)->number()));
     field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
     printer->Print("\n");
   }
@@ -591,58 +585,54 @@
     "                    throws java.io.IOException {\n");
   printer->Indent();
 
-  if (EnableExperimentalRuntime(context_) && !IsDescriptorProto(descriptor_)) {
-    printer->Print("writeToInternal(output);\n");
-  } else {
-    if (HasPackedFields(descriptor_)) {
-      // writeTo(CodedOutputStream output) might be invoked without
-      // getSerializedSize() ever being called, but we need the memoized
-      // sizes in case this message has packed fields. Rather than emit checks
-      // for each packed field, just call getSerializedSize() up front. In most
-      // cases, getSerializedSize() will have already been called anyway by one
-      // of the wrapper writeTo() methods, making this call cheap.
-      printer->Print("getSerializedSize();\n");
-    }
+  if (HasPackedFields(descriptor_)) {
+    // writeTo(CodedOutputStream output) might be invoked without
+    // getSerializedSize() ever being called, but we need the memoized
+    // sizes in case this message has packed fields. Rather than emit checks
+    // for each packed field, just call getSerializedSize() up front. In most
+    // cases, getSerializedSize() will have already been called anyway by one
+    // of the wrapper writeTo() methods, making this call cheap.
+    printer->Print("getSerializedSize();\n");
+  }
 
-    if (descriptor_->extension_range_count() > 0) {
-      if (descriptor_->options().message_set_wire_format()) {
-        printer->Print(
-            "com.google.protobuf.GeneratedMessage$ver$\n"
-            "  .ExtendableMessage<$classname$>.ExtensionWriter\n"
-            "    extensionWriter = newMessageSetExtensionWriter();\n",
-            "classname", name_resolver_->GetImmutableClassName(descriptor_),
-            "ver", GeneratedCodeVersionSuffix());
-      } else {
-        printer->Print(
-            "com.google.protobuf.GeneratedMessage$ver$\n"
-            "  .ExtendableMessage<$classname$>.ExtensionWriter\n"
-            "    extensionWriter = newExtensionWriter();\n",
-            "classname", name_resolver_->GetImmutableClassName(descriptor_),
-            "ver", GeneratedCodeVersionSuffix());
-      }
-    }
-
-    // Merge the fields and the extension ranges, both sorted by field number.
-    for (int i = 0, j = 0;
-         i < descriptor_->field_count() || j < sorted_extensions.size();) {
-      if (i == descriptor_->field_count()) {
-        GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
-      } else if (j == sorted_extensions.size()) {
-        GenerateSerializeOneField(printer, sorted_fields[i++]);
-      } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
-        GenerateSerializeOneField(printer, sorted_fields[i++]);
-      } else {
-        GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
-      }
-    }
-
+  if (descriptor_->extension_range_count() > 0) {
     if (descriptor_->options().message_set_wire_format()) {
-      printer->Print("unknownFields.writeAsMessageSetTo(output);\n");
+      printer->Print(
+          "com.google.protobuf.GeneratedMessage$ver$\n"
+          "  .ExtendableMessage<$classname$>.ExtensionWriter\n"
+          "    extensionWriter = newMessageSetExtensionWriter();\n",
+          "classname", name_resolver_->GetImmutableClassName(descriptor_),
+          "ver", GeneratedCodeVersionSuffix());
     } else {
-      printer->Print("unknownFields.writeTo(output);\n");
+      printer->Print(
+          "com.google.protobuf.GeneratedMessage$ver$\n"
+          "  .ExtendableMessage<$classname$>.ExtensionWriter\n"
+          "    extensionWriter = newExtensionWriter();\n",
+          "classname", name_resolver_->GetImmutableClassName(descriptor_),
+          "ver", GeneratedCodeVersionSuffix());
     }
   }
 
+  // Merge the fields and the extension ranges, both sorted by field number.
+  for (int i = 0, j = 0;
+       i < descriptor_->field_count() || j < sorted_extensions.size();) {
+    if (i == descriptor_->field_count()) {
+      GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
+    } else if (j == sorted_extensions.size()) {
+      GenerateSerializeOneField(printer, sorted_fields[i++]);
+    } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
+      GenerateSerializeOneField(printer, sorted_fields[i++]);
+    } else {
+      GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
+    }
+  }
+
+  if (descriptor_->options().message_set_wire_format()) {
+    printer->Print("unknownFields.writeAsMessageSetTo(output);\n");
+  } else {
+    printer->Print("unknownFields.writeTo(output);\n");
+  }
+
   printer->Outdent();
   printer->Print(
       "}\n"
@@ -653,39 +643,33 @@
       "  if (size != -1) return size;\n"
       "\n");
   printer->Indent();
-  if (EnableExperimentalRuntime(context_) && !IsDescriptorProto(descriptor_)) {
-    printer->Print(
-        "memoizedSize = getSerializedSizeInternal();\n"
-        "return memoizedSize;\n");
-  } else {
 
-    printer->Print("size = 0;\n");
+  printer->Print("size = 0;\n");
 
-    for (int i = 0; i < descriptor_->field_count(); i++) {
-      field_generators_.get(sorted_fields[i])
-          .GenerateSerializedSizeCode(printer);
-    }
-
-    if (descriptor_->extension_range_count() > 0) {
-      if (descriptor_->options().message_set_wire_format()) {
-        printer->Print("size += extensionsSerializedSizeAsMessageSet();\n");
-      } else {
-        printer->Print("size += extensionsSerializedSize();\n");
-      }
-    }
-
-    if (descriptor_->options().message_set_wire_format()) {
-      printer->Print(
-          "size += unknownFields.getSerializedSizeAsMessageSet();\n");
-    } else {
-      printer->Print("size += unknownFields.getSerializedSize();\n");
-    }
-
-    printer->Print(
-        "memoizedSize = size;\n"
-        "return size;\n");
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(sorted_fields[i])
+        .GenerateSerializedSizeCode(printer);
   }
 
+  if (descriptor_->extension_range_count() > 0) {
+    if (descriptor_->options().message_set_wire_format()) {
+      printer->Print("size += extensionsSerializedSizeAsMessageSet();\n");
+    } else {
+      printer->Print("size += extensionsSerializedSize();\n");
+    }
+  }
+
+  if (descriptor_->options().message_set_wire_format()) {
+    printer->Print(
+        "size += unknownFields.getSerializedSizeAsMessageSet();\n");
+  } else {
+    printer->Print("size += unknownFields.getSerializedSize();\n");
+  }
+
+  printer->Print(
+      "memoizedSize = size;\n"
+      "return size;\n");
+
   printer->Outdent();
   printer->Print(
     "}\n"
@@ -779,9 +763,8 @@
 
 void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange(
     io::Printer* printer, const Descriptor::ExtensionRange* range) {
-  printer->Print(
-    "extensionWriter.writeUntil($end$, output);\n",
-    "end", SimpleItoa(range->end));
+  printer->Print("extensionWriter.writeUntil($end$, output);\n", "end",
+                 SimpleItoa(range->end));
 }
 
 // ===================================================================
@@ -853,10 +836,10 @@
       const FieldDescriptor* field = map_fields[i];
       const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
       printer->Print(
-        "case $number$:\n"
-        "  return internalGet$capitalized_name$();\n",
-        "number", SimpleItoa(field->number()),
-        "capitalized_name", info->capitalized_name);
+          "case $number$:\n"
+          "  return internalGet$capitalized_name$();\n",
+          "number", SimpleItoa(field->number()), "capitalized_name",
+          info->capitalized_name);
     }
     printer->Print(
         "default:\n"
@@ -944,10 +927,9 @@
             const OneofDescriptor* oneof = field->containing_oneof();
             const OneofGeneratorInfo* oneof_info =
                 context_->GetOneofGeneratorInfo(oneof);
-            printer->Print(
-              "if ($oneof_name$Case_ == $field_number$) {\n",
-              "oneof_name", oneof_info->name,
-              "field_number", SimpleItoa(field->number()));
+            printer->Print("if ($oneof_name$Case_ == $field_number$) {\n",
+                           "oneof_name", oneof_info->name, "field_number",
+                           SimpleItoa(field->number()));
           } else {
             printer->Print(
               "if (has$name$()) {\n",
@@ -1080,10 +1062,8 @@
     printer->Indent();
     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
-      printer->Print(
-        "case $field_number$:\n",
-        "field_number",
-        SimpleItoa(field->number()));
+      printer->Print("case $field_number$:\n", "field_number",
+                     SimpleItoa(field->number()));
       printer->Indent();
       field_generators_.get(field).GenerateEqualsCode(printer);
       printer->Print("break;\n");
@@ -1164,10 +1144,8 @@
     printer->Indent();
     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
-      printer->Print(
-        "case $field_number$:\n",
-        "field_number",
-        SimpleItoa(field->number()));
+      printer->Print("case $field_number$:\n", "field_number",
+                     SimpleItoa(field->number()));
       printer->Indent();
       field_generators_.get(field).GenerateHashCode(printer);
       printer->Print("break;\n");
@@ -1273,9 +1251,8 @@
     uint32 tag = WireFormatLite::MakeTag(field->number(),
       WireFormat::WireTypeForFieldType(field->type()));
 
-    printer->Print(
-      "case $tag$: {\n",
-      "tag", SimpleItoa(static_cast<int32>(tag)));
+    printer->Print("case $tag$: {\n", "tag",
+                   SimpleItoa(static_cast<int32>(tag)));
     printer->Indent();
 
     field_generators_.get(field).GenerateParsingCode(printer);
@@ -1290,9 +1267,8 @@
       // packed version of this field regardless of field->options().packed().
       uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
         WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
-      printer->Print(
-        "case $tag$: {\n",
-        "tag", SimpleItoa(static_cast<int32>(packed_tag)));
+      printer->Print("case $tag$: {\n", "tag",
+                     SimpleItoa(static_cast<int32>(packed_tag)));
       printer->Indent();
 
       field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
@@ -1306,15 +1282,12 @@
 
   printer->Print(
       "default: {\n"
-      "  if (!parseUnknownField$suffix$(\n"
+      "  if (!parseUnknownField(\n"
       "      input, unknownFields, extensionRegistry, tag)) {\n"
       "    done = true;\n"  // it's an endgroup tag
       "  }\n"
       "  break;\n"
-      "}\n",
-      "suffix",
-      descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ? "Proto3"
-                                                                     : "");
+      "}\n");
 
   printer->Outdent();
   printer->Outdent();
@@ -1369,16 +1342,7 @@
       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
       "    throws com.google.protobuf.InvalidProtocolBufferException {\n",
       "classname", descriptor_->name());
-  if (EnableExperimentalRuntime(context_) && !IsDescriptorProto(descriptor_)) {
-    printer->Indent();
-    printer->Print(
-        "$classname$ msg = new $classname$();\n"
-        "msg.mergeFromInternal(input, extensionRegistry);\n"
-        "msg.makeImmutableInternal();\n"
-        "return msg;\n",
-        "classname", descriptor_->name());
-    printer->Outdent();
-  } else if (context_->HasGeneratedMethods(descriptor_)) {
+  if (context_->HasGeneratedMethods(descriptor_)) {
     printer->Print("  return new $classname$(input, extensionRegistry);\n",
                    "classname", descriptor_->name());
   } else {
diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h
index da1447c..ac0c765 100644
--- a/src/google/protobuf/compiler/java/java_message.h
+++ b/src/google/protobuf/compiler/java/java_message.h
@@ -41,17 +41,19 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;           // context.h
-      class ClassNameResolver; // name_resolver.h
-    }
-  }
-  namespace io {
-    class Printer;             // printer.h
-  }
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+namespace io {
+class Printer;  // printer.h
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -66,8 +68,8 @@
   // All static variables have to be declared at the top-level of the file
   // so that we can control initialization order, which is important for
   // DescriptorProto bootstrapping to work.
-  virtual void GenerateStaticVariables(
-      io::Printer* printer, int* bytecode_estimate) = 0;
+  virtual void GenerateStaticVariables(io::Printer* printer,
+                                       int* bytecode_estimate) = 0;
 
   // Output code which initializes the static variables generated by
   // GenerateStaticVariables(). Returns an estimate of bytecode size.
@@ -76,7 +78,8 @@
   // Generate the class itself.
   virtual void Generate(io::Printer* printer) = 0;
 
-  // Generates the base interface that both the class and its builder implement
+  // Generates the base interface that both the class and its builder
+  // implement
   virtual void GenerateInterface(io::Printer* printer) = 0;
 
   // Generate code to register all contained extensions with an
@@ -137,6 +140,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
diff --git a/src/google/protobuf/compiler/java/java_message_builder.cc b/src/google/protobuf/compiler/java/java_message_builder.cc
index 4c67e80..0b9db22 100644
--- a/src/google/protobuf/compiler/java/java_message_builder.cc
+++ b/src/google/protobuf/compiler/java/java_message_builder.cc
@@ -35,7 +35,6 @@
 #include <google/protobuf/compiler/java/java_message_builder.h>
 
 #include <algorithm>
-#include <google/protobuf/stubs/hash.h>
 #include <map>
 #include <memory>
 #include <vector>
@@ -51,8 +50,8 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/wire_format.h>
-#include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
 
 
 namespace google {
@@ -126,7 +125,8 @@
         descriptor_->oneof_decl(i))->name;
     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
         descriptor_->oneof_decl(i))->capitalized_name;
-    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
+    vars["oneof_index"] =
+        SimpleItoa(descriptor_->oneof_decl(i)->index());
     // oneofCase_ and oneof_
     printer->Print(vars,
       "private int $oneof_name$Case_ = 0;\n"
@@ -169,8 +169,6 @@
                      .GenerateBuilderMembers(printer);
   }
 
-  bool is_proto3 =
-      descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
     // Override methods declared in GeneratedMessage to return the concrete
     // generated type so callsites won't depend on GeneratedMessage. This
     // is needed to keep binary compatibility when we change generated code
@@ -180,7 +178,7 @@
     "@java.lang.Override\n"
     "public final Builder setUnknownFields(\n"
     "    final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
-    "  return super.setUnknownFields$suffix$(unknownFields);\n"
+    "  return super.setUnknownFields(unknownFields);\n"
     "}\n"
     "\n"
     "@java.lang.Override\n"
@@ -188,8 +186,7 @@
     "    final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
     "  return super.mergeUnknownFields(unknownFields);\n"
     "}\n"
-    "\n",
-    "suffix", is_proto3 ? "Proto3" : "");
+    "\n");
 
   printer->Print(
     "\n"
@@ -234,10 +231,10 @@
       const FieldDescriptor* field = map_fields[i];
       const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
       printer->Print(
-        "case $number$:\n"
-        "  return internalGet$capitalized_name$();\n",
-        "number", SimpleItoa(field->number()),
-        "capitalized_name", info->capitalized_name);
+          "case $number$:\n"
+          "  return internalGet$capitalized_name$();\n",
+          "number", SimpleItoa(field->number()), "capitalized_name",
+          info->capitalized_name);
     }
     printer->Print(
         "default:\n"
@@ -260,10 +257,10 @@
       const FieldGeneratorInfo* info =
           context_->GetFieldGeneratorInfo(field);
       printer->Print(
-        "case $number$:\n"
-        "  return internalGetMutable$capitalized_name$();\n",
-        "number", SimpleItoa(field->number()),
-        "capitalized_name", info->capitalized_name);
+          "case $number$:\n"
+          "  return internalGetMutable$capitalized_name$();\n",
+          "number", SimpleItoa(field->number()), "capitalized_name",
+          info->capitalized_name);
     }
     printer->Print(
         "default:\n"
@@ -686,10 +683,9 @@
             const OneofDescriptor* oneof = field->containing_oneof();
             const OneofGeneratorInfo* oneof_info =
                 context_->GetOneofGeneratorInfo(oneof);
-            printer->Print(
-              "if ($oneof_name$Case_ == $field_number$) {\n",
-              "oneof_name", oneof_info->name,
-              "field_number", SimpleItoa(field->number()));
+            printer->Print("if ($oneof_name$Case_ == $field_number$) {\n",
+                           "oneof_name", oneof_info->name, "field_number",
+                           SimpleItoa(field->number()));
           } else {
             printer->Print(
               "if (has$name$()) {\n",
diff --git a/src/google/protobuf/compiler/java/java_message_builder.h b/src/google/protobuf/compiler/java/java_message_builder.h
index 015ea06..d67a9c9 100644
--- a/src/google/protobuf/compiler/java/java_message_builder.h
+++ b/src/google/protobuf/compiler/java/java_message_builder.h
@@ -41,17 +41,19 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;           // context.h
-      class ClassNameResolver; // name_resolver.h
-    }
-  }
-  namespace io {
-    class Printer;             // printer.h
-  }
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+namespace io {
+class Printer;  // printer.h
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -81,6 +83,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_H__
diff --git a/src/google/protobuf/compiler/java/java_message_builder_lite.cc b/src/google/protobuf/compiler/java/java_message_builder_lite.cc
index f04d394..b9a12d4 100644
--- a/src/google/protobuf/compiler/java/java_message_builder_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_builder_lite.cc
@@ -35,7 +35,6 @@
 #include <google/protobuf/compiler/java/java_message_builder_lite.h>
 
 #include <algorithm>
-#include <google/protobuf/stubs/hash.h>
 #include <map>
 #include <memory>
 #include <vector>
@@ -51,8 +50,8 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/wire_format.h>
-#include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
 
 namespace google {
 namespace protobuf {
@@ -102,7 +101,8 @@
         descriptor_->oneof_decl(i))->name;
     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
         descriptor_->oneof_decl(i))->capitalized_name;
-    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
+    vars["oneof_index"] =
+        SimpleItoa(descriptor_->oneof_decl(i)->index());
 
     // oneofCase() and clearOneof()
     printer->Print(vars,
@@ -120,20 +120,6 @@
       "\n");
   }
 
-  if (GenerateHasBits(descriptor_)) {
-    // Integers for bit fields.
-    int totalBits = 0;
-    for (int i = 0; i < descriptor_->field_count(); i++) {
-      totalBits += field_generators_.get(descriptor_->field(i))
-          .GetNumBitsForBuilder();
-    }
-    int totalInts = (totalBits + 31) / 32;
-    for (int i = 0; i < totalInts; i++) {
-      printer->Print("private int $bit_field_name$;\n",
-        "bit_field_name", GetBitFieldName(i));
-    }
-  }
-
   for (int i = 0; i < descriptor_->field_count(); i++) {
     printer->Print("\n");
     field_generators_.get(descriptor_->field(i))
diff --git a/src/google/protobuf/compiler/java/java_message_builder_lite.h b/src/google/protobuf/compiler/java/java_message_builder_lite.h
index 8597b2e..079d86a 100644
--- a/src/google/protobuf/compiler/java/java_message_builder_lite.h
+++ b/src/google/protobuf/compiler/java/java_message_builder_lite.h
@@ -41,17 +41,19 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;           // context.h
-      class ClassNameResolver; // name_resolver.h
-    }
-  }
-  namespace io {
-    class Printer;             // printer.h
-  }
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+namespace io {
+class Printer;  // printer.h
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -59,7 +61,7 @@
 class MessageBuilderLiteGenerator {
  public:
   explicit MessageBuilderLiteGenerator(const Descriptor* descriptor,
-                                   Context* context);
+                                       Context* context);
   virtual ~MessageBuilderLiteGenerator();
 
   virtual void Generate(io::Printer* printer);
@@ -78,6 +80,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_LITE_H__
diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc
index bda4fcc..92425d0 100644
--- a/src/google/protobuf/compiler/java/java_message_field.cc
+++ b/src/google/protobuf/compiler/java/java_message_field.cc
@@ -254,8 +254,7 @@
 
   bool support_field_presence = SupportFieldPresence(descriptor_->file());
 
-  printer->Print(variables_,
-    "private $type$ $name$_;\n");
+  printer->Print(variables_, "private $type$ $name$_;\n");
 
   printer->Print(variables_,
       // If this builder is non-null, it is used and the other fields are
@@ -443,20 +442,17 @@
 void ImmutableMessageFieldGenerator::
 GenerateBuildingCode(io::Printer* printer) const {
   if (SupportFieldPresence(descriptor_->file())) {
-    printer->Print(variables_,
-      "if ($get_has_field_bit_from_local$) {\n");
+    printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n");
     printer->Indent();
-    PrintNestedBuilderCondition(printer,
-      "result.$name$_ = $name$_;\n",
-      "result.$name$_ = $name$Builder_.build();\n");
+    PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n",
+                                "result.$name$_ = $name$Builder_.build();\n");
     printer->Outdent();
     printer->Print(variables_,
-      "  $set_has_field_bit_to_local$;\n"
-      "}\n");
+                   "  $set_has_field_bit_to_local$;\n"
+                   "}\n");
   } else {
-    PrintNestedBuilderCondition(printer,
-      "result.$name$_ = $name$_;\n",
-      "result.$name$_ = $name$Builder_.build();\n");
+    PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n",
+                                "result.$name$_ = $name$Builder_.build();\n");
   }
 }
 
diff --git a/src/google/protobuf/compiler/java/java_message_field.h b/src/google/protobuf/compiler/java/java_message_field.h
index 7ee0edb..d70d827 100644
--- a/src/google/protobuf/compiler/java/java_message_field.h
+++ b/src/google/protobuf/compiler/java/java_message_field.h
@@ -41,26 +41,30 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;           // context.h
-      class ClassNameResolver; // name_resolver.h
-    }
-  }
-}
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
 
 class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator {
  public:
-  explicit ImmutableMessageFieldGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  explicit ImmutableMessageFieldGenerator(const FieldDescriptor* descriptor,
+                                          int messageBitIndex,
+                                          int builderBitIndex,
+                                          Context* context);
   ~ImmutableMessageFieldGenerator();
 
-  // implements ImmutableFieldGenerator ---------------------------------------
+  // implements ImmutableFieldGenerator
+  // ---------------------------------------
   int GetNumBitsForMessage() const;
   int GetNumBitsForBuilder() const;
   void GenerateInterfaceMembers(io::Printer* printer) const;
@@ -89,11 +93,13 @@
   ClassNameResolver* name_resolver_;
 
   void PrintNestedBuilderCondition(io::Printer* printer,
-      const char* regular_case, const char* nested_builder_case) const;
+                                   const char* regular_case,
+                                   const char* nested_builder_case) const;
   void PrintNestedBuilderFunction(io::Printer* printer,
-      const char* method_prototype, const char* regular_case,
-      const char* nested_builder_case,
-      const char* trailing_code) const;
+                                  const char* method_prototype,
+                                  const char* regular_case,
+                                  const char* nested_builder_case,
+                                  const char* trailing_code) const;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldGenerator);
@@ -102,9 +108,9 @@
 class ImmutableMessageOneofFieldGenerator
     : public ImmutableMessageFieldGenerator {
  public:
-  ImmutableMessageOneofFieldGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  ImmutableMessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+                                      int messageBitIndex, int builderBitIndex,
+                                      Context* context);
   ~ImmutableMessageOneofFieldGenerator();
 
   void GenerateMembers(io::Printer* printer) const;
@@ -155,11 +161,13 @@
   ClassNameResolver* name_resolver_;
 
   void PrintNestedBuilderCondition(io::Printer* printer,
-      const char* regular_case, const char* nested_builder_case) const;
+                                   const char* regular_case,
+                                   const char* nested_builder_case) const;
   void PrintNestedBuilderFunction(io::Printer* printer,
-      const char* method_prototype, const char* regular_case,
-      const char* nested_builder_case,
-      const char* trailing_code) const;
+                                  const char* method_prototype,
+                                  const char* regular_case,
+                                  const char* nested_builder_case,
+                                  const char* trailing_code) const;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableMessageFieldGenerator);
@@ -168,6 +176,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.cc b/src/google/protobuf/compiler/java/java_message_field_lite.cc
index 9cf6f36..7bf6426 100644
--- a/src/google/protobuf/compiler/java/java_message_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc
@@ -104,17 +104,15 @@
 
 // ===================================================================
 
-ImmutableMessageFieldLiteGenerator::
-ImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor,
-                      int messageBitIndex,
-                      int builderBitIndex,
-                      Context* context)
-  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
-    builderBitIndex_(builderBitIndex), context_(context),
-    name_resolver_(context->GetNameResolver()) {
-    SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
-                        context->GetFieldGeneratorInfo(descriptor),
-                        name_resolver_, &variables_);
+ImmutableMessageFieldLiteGenerator::ImmutableMessageFieldLiteGenerator(
+    const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
+    : descriptor_(descriptor),
+      messageBitIndex_(messageBitIndex),
+      context_(context),
+      name_resolver_(context->GetNameResolver()) {
+  SetMessageVariables(descriptor, messageBitIndex, 0,
+                      context->GetFieldGeneratorInfo(descriptor),
+                      name_resolver_, &variables_);
 }
 
 ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {}
@@ -123,10 +121,6 @@
   return 1;
 }
 
-int ImmutableMessageFieldLiteGenerator::GetNumBitsForBuilder() const {
-  return 0;
-}
-
 void ImmutableMessageFieldLiteGenerator::
 GenerateInterfaceMembers(io::Printer* printer) const {
   WriteFieldDocComment(printer, descriptor_);
@@ -387,12 +381,10 @@
 // ===================================================================
 
 ImmutableMessageOneofFieldLiteGenerator::
-ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
-                                 int messageBitIndex,
-                                 int builderBitIndex,
-                                 Context* context)
-    : ImmutableMessageFieldLiteGenerator(
-          descriptor, messageBitIndex, builderBitIndex, context) {
+    ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
+                                            int messageBitIndex,
+                                            Context* context)
+    : ImmutableMessageFieldLiteGenerator(descriptor, messageBitIndex, context) {
   const OneofGeneratorInfo* info =
       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
   SetCommonOneofVariables(descriptor, info, &variables_);
@@ -593,14 +585,14 @@
 // ===================================================================
 
 RepeatedImmutableMessageFieldLiteGenerator::
-RepeatedImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor,
-                                       int messageBitIndex,
-                                       int builderBitIndex,
-                                       Context* context)
-  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
-    builderBitIndex_(builderBitIndex), context_(context),
-    name_resolver_(context->GetNameResolver())  {
-  SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
+    RepeatedImmutableMessageFieldLiteGenerator(
+        const FieldDescriptor* descriptor, int messageBitIndex,
+        Context* context)
+    : descriptor_(descriptor),
+      messageBitIndex_(messageBitIndex),
+      context_(context),
+      name_resolver_(context->GetNameResolver()) {
+  SetMessageVariables(descriptor, messageBitIndex, 0,
                       context->GetFieldGeneratorInfo(descriptor),
                       name_resolver_, &variables_);
 }
@@ -612,10 +604,6 @@
   return 0;
 }
 
-int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForBuilder() const {
-  return 0;
-}
-
 void RepeatedImmutableMessageFieldLiteGenerator::
 GenerateInterfaceMembers(io::Printer* printer) const {
   // TODO(jonp): In the future, consider having methods specific to the
diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.h b/src/google/protobuf/compiler/java/java_message_field_lite.h
index 7c814c6..c9eb30b 100644
--- a/src/google/protobuf/compiler/java/java_message_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_message_field_lite.h
@@ -41,28 +41,30 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;           // context.h
-      class ClassNameResolver; // name_resolver.h
-    }
-  }
-}
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
 
 class ImmutableMessageFieldLiteGenerator : public ImmutableFieldLiteGenerator {
  public:
-  explicit ImmutableMessageFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  explicit ImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor,
+                                              int messageBitIndex,
+                                              Context* context);
   ~ImmutableMessageFieldLiteGenerator();
 
-  // implements ImmutableFieldLiteGenerator ------------------------------------
+  // implements ImmutableFieldLiteGenerator
+  // ------------------------------------
   int GetNumBitsForMessage() const;
-  int GetNumBitsForBuilder() const;
   void GenerateInterfaceMembers(io::Printer* printer) const;
   void GenerateMembers(io::Printer* printer) const;
   void GenerateBuilderMembers(io::Printer* printer) const;
@@ -83,7 +85,6 @@
   const FieldDescriptor* descriptor_;
   std::map<string, string> variables_;
   const int messageBitIndex_;
-  const int builderBitIndex_;
   Context* context_;
   ClassNameResolver* name_resolver_;
 
@@ -94,9 +95,9 @@
 class ImmutableMessageOneofFieldLiteGenerator
     : public ImmutableMessageFieldLiteGenerator {
  public:
-  ImmutableMessageOneofFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
+                                          int messageBitIndex,
+                                          Context* context);
   ~ImmutableMessageOneofFieldLiteGenerator();
 
   void GenerateMembers(io::Printer* printer) const;
@@ -115,13 +116,11 @@
     : public ImmutableFieldLiteGenerator {
  public:
   explicit RepeatedImmutableMessageFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+      const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
   ~RepeatedImmutableMessageFieldLiteGenerator();
 
   // implements ImmutableFieldLiteGenerator ------------------------------------
   int GetNumBitsForMessage() const;
-  int GetNumBitsForBuilder() const;
   void GenerateInterfaceMembers(io::Printer* printer) const;
   void GenerateMembers(io::Printer* printer) const;
   void GenerateBuilderMembers(io::Printer* printer) const;
@@ -143,7 +142,6 @@
   const FieldDescriptor* descriptor_;
   std::map<string, string> variables_;
   const int messageBitIndex_;
-  const int builderBitIndex_;
   Context* context_;
   ClassNameResolver* name_resolver_;
 
@@ -154,6 +152,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_LITE_H__
diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc
index 3a512e8..85a7453 100644
--- a/src/google/protobuf/compiler/java/java_message_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_lite.cc
@@ -35,7 +35,6 @@
 #include <google/protobuf/compiler/java/java_message_lite.h>
 
 #include <algorithm>
-#include <google/protobuf/stubs/hash.h>
 #include <map>
 #include <memory>
 #include <vector>
@@ -53,8 +52,8 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/wire_format.h>
-#include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
 
 
 namespace google {
@@ -266,12 +265,9 @@
     printer->Indent();
     for (int j = 0; j < oneof->field_count(); j++) {
       const FieldDescriptor* field = oneof->field(j);
-      printer->Print(
-        "$field_name$($field_number$),\n",
-        "field_name",
-        ToUpper(field->name()),
-        "field_number",
-        SimpleItoa(field->number()));
+      printer->Print("$field_name$($field_number$),\n", "field_name",
+                     ToUpper(field->name()), "field_number",
+                     SimpleItoa(field->number()));
     }
     printer->Print(
       "$cap_oneof_name$_NOT_SET(0);\n",
@@ -295,12 +291,9 @@
       "  switch (value) {\n");
     for (int j = 0; j < oneof->field_count(); j++) {
       const FieldDescriptor* field = oneof->field(j);
-      printer->Print(
-        "    case $field_number$: return $field_name$;\n",
-        "field_number",
-        SimpleItoa(field->number()),
-        "field_name",
-        ToUpper(field->name()));
+      printer->Print("    case $field_number$: return $field_name$;\n",
+                     "field_number", SimpleItoa(field->number()),
+                     "field_name", ToUpper(field->name()));
     }
     printer->Print(
       "    case 0: return $cap_oneof_name$_NOT_SET;\n"
@@ -333,16 +326,14 @@
   // Fields
   for (int i = 0; i < descriptor_->field_count(); i++) {
     printer->Print("public static final int $constant_name$ = $number$;\n",
-      "constant_name", FieldConstantName(descriptor_->field(i)),
-      "number", SimpleItoa(descriptor_->field(i)->number()));
+                   "constant_name", FieldConstantName(descriptor_->field(i)),
+                   "number",
+                   SimpleItoa(descriptor_->field(i)->number()));
     field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
     printer->Print("\n");
   }
 
-  if (!EnableExperimentalRuntime(context_)) {
-    GenerateMessageSerializationMethods(printer);
-  }
-
+  GenerateMessageSerializationMethods(printer);
   GenerateParseFromMethods(printer);
   GenerateBuilder(printer);
 
@@ -737,9 +728,8 @@
 
 void ImmutableMessageLiteGenerator::GenerateSerializeOneExtensionRange(
     io::Printer* printer, const Descriptor::ExtensionRange* range) {
-  printer->Print(
-    "extensionWriter.writeUntil($end$, output);\n",
-    "end", SimpleItoa(range->end));
+  printer->Print("extensionWriter.writeUntil($end$, output);\n", "end",
+                 SimpleItoa(range->end));
 }
 
 // ===================================================================
@@ -818,10 +808,9 @@
             const OneofDescriptor* oneof = field->containing_oneof();
             const OneofGeneratorInfo* oneof_info =
                 context_->GetOneofGeneratorInfo(oneof);
-            printer->Print(
-              "if ($oneof_name$Case_ == $field_number$) {\n",
-              "oneof_name", oneof_info->name,
-              "field_number", SimpleItoa(field->number()));
+            printer->Print("if ($oneof_name$Case_ == $field_number$) {\n",
+                           "oneof_name", oneof_info->name, "field_number",
+                           SimpleItoa(field->number()));
           } else {
             printer->Print(
               "if (has$name$()) {\n",
@@ -1002,102 +991,96 @@
   printer->Print(
       "try {\n");
   printer->Indent();
-  if (EnableExperimentalRuntime(context_)) {
-    printer->Print(
-        "mergeFromInternal(input, extensionRegistry);\n"
-        "return DEFAULT_INSTANCE;\n");
-  } else {
-    printer->Print(
-        "boolean done = false;\n"
-        "while (!done) {\n");
+  printer->Print(
+      "boolean done = false;\n"
+      "while (!done) {\n");
+  printer->Indent();
+
+  printer->Print(
+      "int tag = input.readTag();\n"
+      "switch (tag) {\n");
+  printer->Indent();
+
+  printer->Print(
+      "case 0:\n"  // zero signals EOF / limit reached
+      "  done = true;\n"
+      "  break;\n");
+
+  std::unique_ptr<const FieldDescriptor* []> sorted_fields(
+      SortFieldsByNumber(descriptor_));
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = sorted_fields[i];
+    uint32 tag = WireFormatLite::MakeTag(
+        field->number(), WireFormat::WireTypeForFieldType(field->type()));
+
+    printer->Print("case $tag$: {\n", "tag",
+                   SimpleItoa(static_cast<int32>(tag)));
     printer->Indent();
 
+    field_generators_.get(field).GenerateParsingCode(printer);
+
+    printer->Outdent();
     printer->Print(
-        "int tag = input.readTag();\n"
-        "switch (tag) {\n");
-    printer->Indent();
+      "  break;\n"
+      "}\n");
 
-    printer->Print(
-        "case 0:\n"  // zero signals EOF / limit reached
-        "  done = true;\n"
-        "  break;\n");
-
-    std::unique_ptr<const FieldDescriptor* []> sorted_fields(
-        SortFieldsByNumber(descriptor_));
-    for (int i = 0; i < descriptor_->field_count(); i++) {
-      const FieldDescriptor* field = sorted_fields[i];
-      uint32 tag = WireFormatLite::MakeTag(
-          field->number(), WireFormat::WireTypeForFieldType(field->type()));
-
+    if (field->is_packable()) {
+      // To make packed = true wire compatible, we generate parsing code from
+      // a packed version of this field regardless of
+      // field->options().packed().
+      uint32 packed_tag = WireFormatLite::MakeTag(
+          field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
       printer->Print("case $tag$: {\n", "tag",
-                     SimpleItoa(static_cast<int32>(tag)));
+                     SimpleItoa(static_cast<int32>(packed_tag)));
       printer->Indent();
 
-      field_generators_.get(field).GenerateParsingCode(printer);
+      field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
 
       printer->Outdent();
       printer->Print(
-        "  break;\n"
-        "}\n");
-
-      if (field->is_packable()) {
-        // To make packed = true wire compatible, we generate parsing code from
-        // a packed version of this field regardless of
-        // field->options().packed().
-        uint32 packed_tag = WireFormatLite::MakeTag(
-            field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
-        printer->Print("case $tag$: {\n", "tag",
-                       SimpleItoa(static_cast<int32>(packed_tag)));
-        printer->Indent();
-
-        field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
-
-        printer->Outdent();
-        printer->Print(
-            "  break;\n"
-            "}\n");
-      }
+          "  break;\n"
+          "}\n");
     }
+  }
 
-    if (descriptor_->extension_range_count() > 0) {
-      if (descriptor_->options().message_set_wire_format()) {
-        printer->Print(
-            "default: {\n"
-            "  if (!parseUnknownFieldAsMessageSet(\n"
-            "      getDefaultInstanceForType(), input, extensionRegistry,\n"
-            "      tag)) {\n"
-            "    done = true;\n"  // it's an endgroup tag
-            "  }\n"
-            "  break;\n"
-            "}\n");
-      } else {
-        printer->Print(
-            "default: {\n"
-            "  if (!parseUnknownField(getDefaultInstanceForType(),\n"
-            "      input, extensionRegistry, tag)) {\n"
-            "    done = true;\n"  // it's an endgroup tag
-            "  }\n"
-            "  break;\n"
-            "}\n");
-      }
+  if (descriptor_->extension_range_count() > 0) {
+    if (descriptor_->options().message_set_wire_format()) {
+      printer->Print(
+          "default: {\n"
+          "  if (!parseUnknownFieldAsMessageSet(\n"
+          "      getDefaultInstanceForType(), input, extensionRegistry,\n"
+          "      tag)) {\n"
+          "    done = true;\n"  // it's an endgroup tag
+          "  }\n"
+          "  break;\n"
+          "}\n");
     } else {
       printer->Print(
           "default: {\n"
-          "  if (!parseUnknownField(tag, input)) {\n"
+          "  if (!parseUnknownField(getDefaultInstanceForType(),\n"
+          "      input, extensionRegistry, tag)) {\n"
           "    done = true;\n"  // it's an endgroup tag
           "  }\n"
           "  break;\n"
           "}\n");
     }
-
-    printer->Outdent();
-    printer->Outdent();
+  } else {
     printer->Print(
-        "  }\n"  // switch (tag)
-        "}\n");  // while (!done)
+        "default: {\n"
+        "  if (!parseUnknownField(tag, input)) {\n"
+        "    done = true;\n"  // it's an endgroup tag
+        "  }\n"
+        "  break;\n"
+        "}\n");
   }
 
   printer->Outdent();
+  printer->Outdent();
+  printer->Print(
+      "  }\n"  // switch (tag)
+      "}\n");  // while (!done)
+
+  printer->Outdent();
   printer->Print(
       "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
       "  throw new RuntimeException(e.setUnfinishedMessage(this));\n"
diff --git a/src/google/protobuf/compiler/java/java_message_lite.h b/src/google/protobuf/compiler/java/java_message_lite.h
index 1e319c6..d38c54a 100644
--- a/src/google/protobuf/compiler/java/java_message_lite.h
+++ b/src/google/protobuf/compiler/java/java_message_lite.h
@@ -87,6 +87,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_LITE_H__
diff --git a/src/google/protobuf/compiler/java/java_name_resolver.h b/src/google/protobuf/compiler/java/java_name_resolver.h
index 28b049d..90684da 100644
--- a/src/google/protobuf/compiler/java/java_name_resolver.h
+++ b/src/google/protobuf/compiler/java/java_name_resolver.h
@@ -120,6 +120,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_NAME_RESOLVER_H__
diff --git a/src/google/protobuf/compiler/java/java_names.h b/src/google/protobuf/compiler/java/java_names.h
index 0d61433..39e8c51 100644
--- a/src/google/protobuf/compiler/java/java_names.h
+++ b/src/google/protobuf/compiler/java/java_names.h
@@ -46,6 +46,7 @@
 class Descriptor;
 class EnumDescriptor;
 class FileDescriptor;
+class FieldDescriptor;
 class ServiceDescriptor;
 
 namespace compiler {
@@ -79,9 +80,33 @@
 //   The fully-qualified Java class name.
 string ClassName(const ServiceDescriptor* descriptor);
 
+// Requires:
+//   descriptor != NULL
+//
+// Returns:
+//   Java package name.
+string FileJavaPackage(const FileDescriptor* descriptor);
+
+// Requires:
+//   descriptor != NULL
+// Returns:
+//   Captialized camel case name field name.
+string CapitalizedFieldName(const FieldDescriptor* descriptor);
+
+// Requires:
+//   descriptor != NULL
+// Returns:
+//   Primitive Java type name for the field.
+const char* PrimitiveTypeName(const FieldDescriptor* descriptor);
+
+// Requires:
+//   descriptor != NULL
+// Returns:
+//   Boes primitive Java type name for the field.
+const char* BoxedPrimitiveTypeName(const FieldDescriptor* descriptor);
+
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
 }  // namespace google
-
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__
diff --git a/src/google/protobuf/compiler/java/java_options.h b/src/google/protobuf/compiler/java/java_options.h
index e4e7d5e..6c29be1 100644
--- a/src/google/protobuf/compiler/java/java_options.h
+++ b/src/google/protobuf/compiler/java/java_options.h
@@ -68,6 +68,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_OPTIONS_H__
diff --git a/src/google/protobuf/compiler/java/java_plugin_unittest.cc b/src/google/protobuf/compiler/java/java_plugin_unittest.cc
index 87f687d..644d068 100644
--- a/src/google/protobuf/compiler/java/java_plugin_unittest.cc
+++ b/src/google/protobuf/compiler/java/java_plugin_unittest.cc
@@ -95,7 +95,7 @@
                              "enum Qux { BLAH = 1; }\n",
                              true));
 
-  google::protobuf::compiler::CommandLineInterface cli;
+  CommandLineInterface cli;
   cli.SetInputsAreProtoPathRelative(true);
 
   JavaGenerator java_generator;
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc
index e6ce69c..c98c8b3 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -56,6 +56,14 @@
 
 namespace {
 
+bool EnableJavaPrimitiveExperiment() {
+#ifdef PROTOBUF_JAVA_PRIMITIVE_EXPERIMENT
+  return PROTOBUF_JAVA_PRIMITIVE_EXPERIMENT;
+#else   // PROTOBUF_JAVA_PRIMITIVE_EXPERIMENT
+  return false;
+#endif  // !PROTOBUF_JAVA_PRIMITIVE_EXPERIMENT
+}
+
 void SetPrimitiveVariables(const FieldDescriptor* descriptor,
                            int messageBitIndex,
                            int builderBitIndex,
@@ -63,13 +71,51 @@
                            ClassNameResolver* name_resolver,
                            std::map<string, string>* variables) {
   SetCommonFieldVariables(descriptor, info, variables);
+  JavaType javaType = GetJavaType(descriptor);
 
-  (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
-  (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
+  (*variables)["type"] = PrimitiveTypeName(javaType);
+  (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType);
   (*variables)["field_type"] = (*variables)["type"];
-  (*variables)["field_list_type"] = "java.util.List<" +
-      (*variables)["boxed_type"] + ">";
-  (*variables)["empty_list"] = "java.util.Collections.emptyList()";
+
+  if (EnableJavaPrimitiveExperiment() &&
+      (javaType == JAVATYPE_BOOLEAN ||
+       javaType == JAVATYPE_DOUBLE ||
+       javaType == JAVATYPE_FLOAT ||
+       javaType == JAVATYPE_INT ||
+       javaType == JAVATYPE_LONG)) {
+    string capitalized_type = UnderscoresToCamelCase(
+        PrimitiveTypeName(javaType), /*cap_first_letter=*/true);
+    (*variables)["field_list_type"] =
+        "com.google.protobuf.Internal." + capitalized_type + "List";
+    (*variables)["empty_list"] = "empty" + capitalized_type + "List()";
+    (*variables)["create_list"] = "new" + capitalized_type + "List()";
+    (*variables)["mutable_copy_list"] =
+        "mutableCopy(" + (*variables)["name"] + "_)";
+    (*variables)["name_make_immutable"] =
+        (*variables)["name"] + "_.makeImmutable()";
+    (*variables)["repeated_get"] =
+        (*variables)["name"] + "_.get" + capitalized_type;
+    (*variables)["repeated_add"] =
+        (*variables)["name"] + "_.add" + capitalized_type;
+    (*variables)["repeated_set"] =
+        (*variables)["name"] + "_.set" + capitalized_type;
+  } else {
+    (*variables)["field_list_type"] =
+        "java.util.List<" + (*variables)["boxed_type"] + ">";
+    (*variables)["create_list"] =
+        "new java.util.ArrayList<" + (*variables)["boxed_type"] + ">()";
+    (*variables)["mutable_copy_list"] = "new java.util.ArrayList<" +
+                                        (*variables)["boxed_type"] + ">(" +
+                                        (*variables)["name"] + "_)";
+    (*variables)["empty_list"] = "java.util.Collections.emptyList()";
+    (*variables)["name_make_immutable"] =
+        (*variables)["name"] + "_ = java.util.Collections.unmodifiableList(" +
+        (*variables)["name"] + "_)";
+    (*variables)["repeated_get"] = (*variables)["name"] + "_.get";
+    (*variables)["repeated_add"] = (*variables)["name"] + "_.add";
+    (*variables)["repeated_set"] = (*variables)["name"] + "_.set";
+  }
+
   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
   (*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ?
       "" : ("= " + ImmutableDefaultValue(descriptor, name_resolver));
@@ -294,22 +340,21 @@
 void ImmutablePrimitiveFieldGenerator::
 GenerateBuildingCode(io::Printer* printer) const {
   if (SupportFieldPresence(descriptor_->file())) {
-    printer->Print(variables_,
-      "if ($get_has_field_bit_from_local$) {\n"
-      "  result.$name$_ = $name$_;\n"
-      "  $set_has_field_bit_to_local$;\n");
     if (IsDefaultValueJavaDefault(descriptor_)) {
       printer->Print(variables_,
-        "}\n");
+                     "if ($get_has_field_bit_from_local$) {\n"
+                     "  result.$name$_ = $name$_;\n"
+                     "  $set_has_field_bit_to_local$;\n"
+                     "}\n");
     } else {
       printer->Print(variables_,
-        "} else {\n"
-        "  result.$name$_ = $default$;\n"
-        "}\n");
+                     "if ($get_has_field_bit_from_local$) {\n"
+                     "  $set_has_field_bit_to_local$;\n"
+                     "}\n"
+                     "result.$name$_ = $name$_;\n");
     }
   } else {
-    printer->Print(variables_,
-      "result.$name$_ = $name$_;\n");
+    printer->Print(variables_, "result.$name$_ = $name$_;\n");
   }
 }
 
@@ -641,7 +686,7 @@
   WriteFieldDocComment(printer, descriptor_);
   printer->Print(variables_,
     "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
-    "  return $name$_.get(index);\n"
+    "  return $repeated_get$(index);\n"
     "}\n");
   printer->Annotate("{", "}", descriptor_);
 
@@ -668,7 +713,7 @@
   printer->Print(variables_,
     "private void ensure$capitalized_name$IsMutable() {\n"
     "  if (!$get_mutable_bit_builder$) {\n"
-    "    $name$_ = new java.util.ArrayList<$boxed_type$>($name$_);\n"
+    "    $name$_ = $mutable_copy_list$;\n"
     "    $set_mutable_bit_builder$;\n"
     "   }\n"
     "}\n");
@@ -681,7 +726,8 @@
   printer->Print(variables_,
     "$deprecation$public java.util.List<$boxed_type$>\n"
     "    ${$get$capitalized_name$List$}$() {\n"
-    "  return java.util.Collections.unmodifiableList($name$_);\n"
+    "  return $get_mutable_bit_builder$ ?\n"
+    "           java.util.Collections.unmodifiableList($name$_) : $name$_;\n"
     "}\n");
   printer->Annotate("{", "}", descriptor_);
   WriteFieldDocComment(printer, descriptor_);
@@ -693,7 +739,7 @@
   WriteFieldDocComment(printer, descriptor_);
   printer->Print(variables_,
     "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
-    "  return $name$_.get(index);\n"
+    "  return $repeated_get$(index);\n"
     "}\n");
   printer->Annotate("{", "}", descriptor_);
   WriteFieldDocComment(printer, descriptor_);
@@ -702,7 +748,7 @@
     "    int index, $type$ value) {\n"
     "$null_check$"
     "  ensure$capitalized_name$IsMutable();\n"
-    "  $name$_.set(index, value);\n"
+    "  $repeated_set$(index, value);\n"
     "  $on_changed$\n"
     "  return this;\n"
     "}\n");
@@ -712,7 +758,7 @@
     "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value) {\n"
     "$null_check$"
     "  ensure$capitalized_name$IsMutable();\n"
-    "  $name$_.add(value);\n"
+    "  $repeated_add$(value);\n"
     "  $on_changed$\n"
     "  return this;\n"
     "}\n");
@@ -782,7 +828,7 @@
   // list is immutable, we can just reuse it. If not, we make it immutable.
   printer->Print(variables_,
     "if ($get_mutable_bit_builder$) {\n"
-    "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+    "  $name_make_immutable$;\n"
     "  $clear_mutable_bit_builder$;\n"
     "}\n"
     "result.$name$_ = $name$_;\n");
@@ -792,10 +838,10 @@
 GenerateParsingCode(io::Printer* printer) const {
   printer->Print(variables_,
     "if (!$get_mutable_bit_parser$) {\n"
-    "  $name$_ = new java.util.ArrayList<$boxed_type$>();\n"
+    "  $name$_ = $create_list$;\n"
     "  $set_mutable_bit_parser$;\n"
     "}\n"
-    "$name$_.add(input.read$capitalized_type$());\n");
+    "$repeated_add$(input.read$capitalized_type$());\n");
 }
 
 void RepeatedImmutablePrimitiveFieldGenerator::
@@ -804,11 +850,11 @@
     "int length = input.readRawVarint32();\n"
     "int limit = input.pushLimit(length);\n"
     "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n"
-    "  $name$_ = new java.util.ArrayList<$boxed_type$>();\n"
+    "  $name$_ = $create_list$;\n"
     "  $set_mutable_bit_parser$;\n"
     "}\n"
     "while (input.getBytesUntilLimit() > 0) {\n"
-    "  $name$_.add(input.read$capitalized_type$());\n"
+    "  $repeated_add$(input.read$capitalized_type$());\n"
     "}\n"
     "input.popLimit(limit);\n");
 }
@@ -817,7 +863,7 @@
 GenerateParsingDoneCode(io::Printer* printer) const {
   printer->Print(variables_,
     "if ($get_mutable_bit_parser$) {\n"
-    "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+    "  $name_make_immutable$; // C\n"
     "}\n");
 }
 
@@ -833,12 +879,12 @@
       "  output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"
       "}\n"
       "for (int i = 0; i < $name$_.size(); i++) {\n"
-      "  output.write$capitalized_type$NoTag($name$_.get(i));\n"
+      "  output.write$capitalized_type$NoTag($repeated_get$(i));\n"
       "}\n");
   } else {
     printer->Print(variables_,
       "for (int i = 0; i < $name$_.size(); i++) {\n"
-      "  output.write$capitalized_type$($number$, $name$_.get(i));\n"
+      "  output.write$capitalized_type$($number$, $repeated_get$(i));\n"
       "}\n");
   }
 }
@@ -854,7 +900,7 @@
     printer->Print(variables_,
       "for (int i = 0; i < $name$_.size(); i++) {\n"
       "  dataSize += com.google.protobuf.CodedOutputStream\n"
-      "    .compute$capitalized_type$SizeNoTag($name$_.get(i));\n"
+      "    .compute$capitalized_type$SizeNoTag($repeated_get$(i));\n"
       "}\n");
   } else {
     printer->Print(variables_,
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.h b/src/google/protobuf/compiler/java/java_primitive_field.h
index 7ac9bbf..a136805 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.h
+++ b/src/google/protobuf/compiler/java/java_primitive_field.h
@@ -41,26 +41,30 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;           // context.h
-      class ClassNameResolver; // name_resolver.h
-    }
-  }
-}
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
 
 class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator {
  public:
-  explicit ImmutablePrimitiveFieldGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  explicit ImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+                                            int messageBitIndex,
+                                            int builderBitIndex,
+                                            Context* context);
   ~ImmutablePrimitiveFieldGenerator();
 
-  // implements ImmutableFieldGenerator ---------------------------------------
+  // implements ImmutableFieldGenerator
+  // ---------------------------------------
   int GetNumBitsForMessage() const;
   int GetNumBitsForBuilder() const;
   void GenerateInterfaceMembers(io::Printer* printer) const;
@@ -95,9 +99,9 @@
 class ImmutablePrimitiveOneofFieldGenerator
     : public ImmutablePrimitiveFieldGenerator {
  public:
-  ImmutablePrimitiveOneofFieldGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  ImmutablePrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+                                        int messageBitIndex,
+                                        int builderBitIndex, Context* context);
   ~ImmutablePrimitiveOneofFieldGenerator();
 
   void GenerateMembers(io::Printer* printer) const;
@@ -155,6 +159,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__
diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
index d2ebc56..034a086 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
@@ -172,15 +172,13 @@
 
 // ===================================================================
 
-ImmutablePrimitiveFieldLiteGenerator::
-ImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor* descriptor,
-                                 int messageBitIndex,
-                                 int builderBitIndex,
-                                 Context* context)
-  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
-    builderBitIndex_(builderBitIndex), context_(context),
-    name_resolver_(context->GetNameResolver()) {
-  SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ImmutablePrimitiveFieldLiteGenerator::ImmutablePrimitiveFieldLiteGenerator(
+    const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
+    : descriptor_(descriptor),
+      messageBitIndex_(messageBitIndex),
+      context_(context),
+      name_resolver_(context->GetNameResolver()) {
+  SetPrimitiveVariables(descriptor, messageBitIndex, 0,
                         context->GetFieldGeneratorInfo(descriptor),
                         name_resolver_, &variables_);
 }
@@ -191,10 +189,6 @@
   return 1;
 }
 
-int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForBuilder() const {
-  return 0;
-}
-
 void ImmutablePrimitiveFieldLiteGenerator::
 GenerateInterfaceMembers(io::Printer* printer) const {
   if (SupportFieldPresence(descriptor_->file())) {
@@ -472,12 +466,11 @@
 // ===================================================================
 
 ImmutablePrimitiveOneofFieldLiteGenerator::
-ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
-                                 int messageBitIndex,
-                                 int builderBitIndex,
-                                 Context* context)
-    : ImmutablePrimitiveFieldLiteGenerator(
-          descriptor, messageBitIndex, builderBitIndex, context) {
+    ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
+                                              int messageBitIndex,
+                                              Context* context)
+    : ImmutablePrimitiveFieldLiteGenerator(descriptor, messageBitIndex,
+                                           context) {
   const OneofGeneratorInfo* info =
       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
   SetCommonOneofVariables(descriptor, info, &variables_);
@@ -609,14 +602,14 @@
 // ===================================================================
 
 RepeatedImmutablePrimitiveFieldLiteGenerator::
-RepeatedImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor* descriptor,
-                                         int messageBitIndex,
-                                         int builderBitIndex,
-                                         Context* context)
-  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
-    builderBitIndex_(builderBitIndex), context_(context),
-    name_resolver_(context->GetNameResolver()) {
-  SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+    RepeatedImmutablePrimitiveFieldLiteGenerator(
+        const FieldDescriptor* descriptor, int messageBitIndex,
+        Context* context)
+    : descriptor_(descriptor),
+      messageBitIndex_(messageBitIndex),
+      context_(context),
+      name_resolver_(context->GetNameResolver()) {
+  SetPrimitiveVariables(descriptor, messageBitIndex, 0,
                         context->GetFieldGeneratorInfo(descriptor),
                         name_resolver_, &variables_);
 }
@@ -628,10 +621,6 @@
   return 0;
 }
 
-int RepeatedImmutablePrimitiveFieldLiteGenerator::GetNumBitsForBuilder() const {
-  return 0;
-}
-
 void RepeatedImmutablePrimitiveFieldLiteGenerator::
 GenerateInterfaceMembers(io::Printer* printer) const {
   WriteFieldDocComment(printer, descriptor_);
diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.h b/src/google/protobuf/compiler/java/java_primitive_field_lite.h
index 93416f0..c12e458 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.h
@@ -41,14 +41,16 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;           // context.h
-      class ClassNameResolver; // name_resolver.h
-    }
-  }
-}
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -57,13 +59,12 @@
     : public ImmutableFieldLiteGenerator {
  public:
   explicit ImmutablePrimitiveFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+      const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
   ~ImmutablePrimitiveFieldLiteGenerator();
 
-  // implements ImmutableFieldLiteGenerator ------------------------------------
+  // implements ImmutableFieldLiteGenerator
+  // ------------------------------------
   int GetNumBitsForMessage() const;
-  int GetNumBitsForBuilder() const;
   void GenerateInterfaceMembers(io::Printer* printer) const;
   void GenerateMembers(io::Printer* printer) const;
   void GenerateBuilderMembers(io::Printer* printer) const;
@@ -87,7 +88,6 @@
   const FieldDescriptor* descriptor_;
   std::map<string, string> variables_;
   const int messageBitIndex_;
-  const int builderBitIndex_;
   Context* context_;
   ClassNameResolver* name_resolver_;
 
@@ -98,9 +98,9 @@
 class ImmutablePrimitiveOneofFieldLiteGenerator
     : public ImmutablePrimitiveFieldLiteGenerator {
  public:
-  ImmutablePrimitiveOneofFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
+                                            int messageBitIndex,
+                                            Context* context);
   ~ImmutablePrimitiveOneofFieldLiteGenerator();
 
   void GenerateMembers(io::Printer* printer) const;
@@ -120,13 +120,11 @@
     : public ImmutableFieldLiteGenerator {
  public:
   explicit RepeatedImmutablePrimitiveFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+      const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
   virtual ~RepeatedImmutablePrimitiveFieldLiteGenerator();
 
   // implements ImmutableFieldLiteGenerator ------------------------------------
   int GetNumBitsForMessage() const;
-  int GetNumBitsForBuilder() const;
   void GenerateInterfaceMembers(io::Printer* printer) const;
   void GenerateMembers(io::Printer* printer) const;
   void GenerateBuilderMembers(io::Printer* printer) const;
@@ -151,7 +149,6 @@
   const FieldDescriptor* descriptor_;
   std::map<string, string> variables_;
   const int messageBitIndex_;
-  const int builderBitIndex_;
   Context* context_;
   ClassNameResolver* name_resolver_;
 
@@ -161,6 +158,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_LITE_H__
diff --git a/src/google/protobuf/compiler/java/java_service.cc b/src/google/protobuf/compiler/java/java_service.cc
index 988e194..53a9017 100644
--- a/src/google/protobuf/compiler/java/java_service.cc
+++ b/src/google/protobuf/compiler/java/java_service.cc
@@ -84,13 +84,13 @@
 
   // Generate getDescriptor() and getDescriptorForType().
   printer->Print(
-    "public static final\n"
-    "    com.google.protobuf.Descriptors.ServiceDescriptor\n"
-    "    getDescriptor() {\n"
-    "  return $file$.getDescriptor().getServices().get($index$);\n"
-    "}\n",
-    "file", name_resolver_->GetImmutableClassName(descriptor_->file()),
-    "index", SimpleItoa(descriptor_->index()));
+      "public static final\n"
+      "    com.google.protobuf.Descriptors.ServiceDescriptor\n"
+      "    getDescriptor() {\n"
+      "  return $file$.getDescriptor().getServices().get($index$);\n"
+      "}\n",
+      "file", name_resolver_->GetImmutableClassName(descriptor_->file()),
+      "index", SimpleItoa(descriptor_->index()));
   GenerateGetDescriptorForType(printer);
 
   // Generate more stuff.
diff --git a/src/google/protobuf/compiler/java/java_service.h b/src/google/protobuf/compiler/java/java_service.h
index 12b3f94..f34cd79 100644
--- a/src/google/protobuf/compiler/java/java_service.h
+++ b/src/google/protobuf/compiler/java/java_service.h
@@ -40,17 +40,19 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;            // context.h
-      class ClassNameResolver;  // name_resolver.h
-    }
-  }
-  namespace io {
-    class Printer;              // printer.h
-  }
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+namespace io {
+class Printer;  // printer.h
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -133,6 +135,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
+}  // namespace google
 
 #endif  // NET_PROTO2_COMPILER_JAVA_SERVICE_H__
-}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_shared_code_generator.h b/src/google/protobuf/compiler/java/java_shared_code_generator.h
index 58a31f5..1eb6fea 100644
--- a/src/google/protobuf/compiler/java/java_shared_code_generator.h
+++ b/src/google/protobuf/compiler/java/java_shared_code_generator.h
@@ -44,18 +44,20 @@
 
 namespace google {
 namespace protobuf {
-  class FileDescriptor;        // descriptor.h
-  namespace compiler {
-    class GeneratorContext;    // code_generator.h
-    namespace java {
-      class ClassNameResolver;       // name_resolver.h
-    }
-  }
-  namespace io {
-    class Printer;             // printer.h
-  }
+class FileDescriptor;  // descriptor.h
+namespace compiler {
+class GeneratorContext;  // code_generator.h
+namespace java {
+class ClassNameResolver;  // name_resolver.h
 }
+}  // namespace compiler
+namespace io {
+class Printer;  // printer.h
+}
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
@@ -84,6 +86,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__
diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc
index b08febc..2b6e938 100644
--- a/src/google/protobuf/compiler/java/java_string_field.cc
+++ b/src/google/protobuf/compiler/java/java_string_field.cc
@@ -405,15 +405,11 @@
   if (SupportFieldPresence(descriptor_->file())) {
     printer->Print(variables_,
       "if ($get_has_field_bit_from_local$) {\n"
-      "  result.$name$_ = $name$_;\n"
       "  $set_has_field_bit_to_local$;\n"
-      "} else {\n"
-      "  result.$name$_ = $default$;\n"
       "}\n");
-  } else {
-    printer->Print(variables_,
-      "result.$name$_ = $name$_;\n");
   }
+  printer->Print(variables_,
+    "result.$name$_ = $name$_;\n");
 }
 
 void ImmutableStringFieldGenerator::
diff --git a/src/google/protobuf/compiler/java/java_string_field.h b/src/google/protobuf/compiler/java/java_string_field.h
index 0f7c705..7f9fa0e 100644
--- a/src/google/protobuf/compiler/java/java_string_field.h
+++ b/src/google/protobuf/compiler/java/java_string_field.h
@@ -42,26 +42,29 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;           // context.h
-      class ClassNameResolver; // name_resolver.h
-    }
-  }
-}
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
 
 class ImmutableStringFieldGenerator : public ImmutableFieldGenerator {
  public:
-  explicit ImmutableStringFieldGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  explicit ImmutableStringFieldGenerator(const FieldDescriptor* descriptor,
+                                         int messageBitIndex,
+                                         int builderBitIndex, Context* context);
   ~ImmutableStringFieldGenerator();
 
-  // implements ImmutableFieldGenerator ---------------------------------------
+  // implements ImmutableFieldGenerator
+  // ---------------------------------------
   int GetNumBitsForMessage() const;
   int GetNumBitsForBuilder() const;
   void GenerateInterfaceMembers(io::Printer* printer) const;
@@ -96,9 +99,9 @@
 class ImmutableStringOneofFieldGenerator
     : public ImmutableStringFieldGenerator {
  public:
-  ImmutableStringOneofFieldGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  ImmutableStringOneofFieldGenerator(const FieldDescriptor* descriptor,
+                                     int messageBitIndex, int builderBitIndex,
+                                     Context* context);
   ~ImmutableStringOneofFieldGenerator();
 
  private:
@@ -154,6 +157,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.cc b/src/google/protobuf/compiler/java/java_string_field_lite.cc
index a238c67..5ce3151 100644
--- a/src/google/protobuf/compiler/java/java_string_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc
@@ -119,15 +119,13 @@
 
 // ===================================================================
 
-ImmutableStringFieldLiteGenerator::
-ImmutableStringFieldLiteGenerator(const FieldDescriptor* descriptor,
-                              int messageBitIndex,
-                              int builderBitIndex,
-                              Context* context)
-  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
-    builderBitIndex_(builderBitIndex), context_(context),
-    name_resolver_(context->GetNameResolver()) {
-  SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ImmutableStringFieldLiteGenerator::ImmutableStringFieldLiteGenerator(
+    const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
+    : descriptor_(descriptor),
+      messageBitIndex_(messageBitIndex),
+      context_(context),
+      name_resolver_(context->GetNameResolver()) {
+  SetPrimitiveVariables(descriptor, messageBitIndex, 0,
                         context->GetFieldGeneratorInfo(descriptor),
                         name_resolver_, &variables_);
 }
@@ -138,10 +136,6 @@
   return 1;
 }
 
-int ImmutableStringFieldLiteGenerator::GetNumBitsForBuilder() const {
-  return 0;
-}
-
 // A note about how strings are handled. In the SPEED and CODE_SIZE runtimes,
 // strings are not stored as java.lang.String in the Message because of two
 // issues:
@@ -403,13 +397,9 @@
 
 // ===================================================================
 
-ImmutableStringOneofFieldLiteGenerator::
-ImmutableStringOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
-                                   int messageBitIndex,
-                                   int builderBitIndex,
-                                   Context* context)
-    : ImmutableStringFieldLiteGenerator(
-          descriptor, messageBitIndex, builderBitIndex, context) {
+ImmutableStringOneofFieldLiteGenerator::ImmutableStringOneofFieldLiteGenerator(
+    const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
+    : ImmutableStringFieldLiteGenerator(descriptor, messageBitIndex, context) {
   const OneofGeneratorInfo* info =
       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
   SetCommonOneofVariables(descriptor, info, &variables_);
@@ -603,14 +593,14 @@
 // ===================================================================
 
 RepeatedImmutableStringFieldLiteGenerator::
-RepeatedImmutableStringFieldLiteGenerator(const FieldDescriptor* descriptor,
-                                      int messageBitIndex,
-                                      int builderBitIndex,
-                                      Context* context)
-  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
-    builderBitIndex_(builderBitIndex), context_(context),
-    name_resolver_(context->GetNameResolver()) {
-  SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+    RepeatedImmutableStringFieldLiteGenerator(const FieldDescriptor* descriptor,
+                                              int messageBitIndex,
+                                              Context* context)
+    : descriptor_(descriptor),
+      messageBitIndex_(messageBitIndex),
+      context_(context),
+      name_resolver_(context->GetNameResolver()) {
+  SetPrimitiveVariables(descriptor, messageBitIndex, 0,
                         context->GetFieldGeneratorInfo(descriptor),
                         name_resolver_, &variables_);
 }
@@ -622,10 +612,6 @@
   return 0;
 }
 
-int RepeatedImmutableStringFieldLiteGenerator::GetNumBitsForBuilder() const {
-  return 0;
-}
-
 void RepeatedImmutableStringFieldLiteGenerator::
 GenerateInterfaceMembers(io::Printer* printer) const {
   WriteFieldDocComment(printer, descriptor_);
diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.h b/src/google/protobuf/compiler/java/java_string_field_lite.h
index b7fb640..684d3b0 100644
--- a/src/google/protobuf/compiler/java/java_string_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_string_field_lite.h
@@ -42,28 +42,30 @@
 
 namespace google {
 namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;           // context.h
-      class ClassNameResolver; // name_resolver.h
-    }
-  }
-}
+namespace compiler {
+namespace java {
+class Context;            // context.h
+class ClassNameResolver;  // name_resolver.h
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 namespace java {
 
 class ImmutableStringFieldLiteGenerator : public ImmutableFieldLiteGenerator {
  public:
-  explicit ImmutableStringFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  explicit ImmutableStringFieldLiteGenerator(const FieldDescriptor* descriptor,
+                                             int messageBitIndex,
+                                             Context* context);
   ~ImmutableStringFieldLiteGenerator();
 
-  // implements ImmutableFieldLiteGenerator ------------------------------------
+  // implements ImmutableFieldLiteGenerator
+  // ------------------------------------
   int GetNumBitsForMessage() const;
-  int GetNumBitsForBuilder() const;
   void GenerateInterfaceMembers(io::Printer* printer) const;
   void GenerateMembers(io::Printer* printer) const;
   void GenerateBuilderMembers(io::Printer* printer) const;
@@ -85,7 +87,6 @@
   const FieldDescriptor* descriptor_;
   std::map<string, string> variables_;
   const int messageBitIndex_;
-  const int builderBitIndex_;
   Context* context_;
   ClassNameResolver* name_resolver_;
 
@@ -96,9 +97,8 @@
 class ImmutableStringOneofFieldLiteGenerator
     : public ImmutableStringFieldLiteGenerator {
  public:
-  ImmutableStringOneofFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+  ImmutableStringOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
+                                         int messageBitIndex, Context* context);
   ~ImmutableStringOneofFieldLiteGenerator();
 
  private:
@@ -117,13 +117,11 @@
     : public ImmutableFieldLiteGenerator {
  public:
   explicit RepeatedImmutableStringFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
+      const FieldDescriptor* descriptor, int messageBitIndex, Context* context);
   ~RepeatedImmutableStringFieldLiteGenerator();
 
   // implements ImmutableFieldLiteGenerator ------------------------------------
   int GetNumBitsForMessage() const;
-  int GetNumBitsForBuilder() const;
   void GenerateInterfaceMembers(io::Printer* printer) const;
   void GenerateMembers(io::Printer* printer) const;
   void GenerateBuilderMembers(io::Printer* printer) const;
@@ -145,7 +143,6 @@
   const FieldDescriptor* descriptor_;
   std::map<string, string> variables_;
   const int messageBitIndex_;
-  const int builderBitIndex_;
   Context* context_;
   ClassNameResolver* name_resolver_;
 
@@ -155,6 +152,6 @@
 }  // namespace java
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_LITE_H__
diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc
index 45b906f..5779d5e 100644
--- a/src/google/protobuf/compiler/js/js_generator.cc
+++ b/src/google/protobuf/compiler/js/js_generator.cc
@@ -42,12 +42,12 @@
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/compiler/js/well_known_types_embed.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/descriptor.h>
-#include <google/protobuf/stubs/strutil.h>
 
 
 namespace google {
@@ -220,8 +220,8 @@
   if (descriptor == NULL) {
     return "";
   }
-  string result =
-      StripPrefixString(descriptor->full_name(), descriptor->file()->package());
+  string result = StripPrefixString(descriptor->full_name(),
+                                             descriptor->file()->package());
   // Add a leading dot if one is not already present.
   if (!result.empty() && result[0] != '.') {
     result = "." + result;
@@ -439,9 +439,10 @@
 bool IgnoreExtensionField(const FieldDescriptor* field) {
   // Exclude descriptor extensions from output "to avoid clutter" (from original
   // codegen).
-  return field->is_extension() &&
-         field->containing_type()->file()->name() ==
-             "google/protobuf/descriptor.proto";
+  if (!field->is_extension()) return false;
+  const FileDescriptor* file = field->containing_type()->file();
+  return file->name() == "net/proto2/proto/descriptor.proto" ||
+         file->name() == "google/protobuf/descriptor.proto";
 }
 
 
@@ -453,19 +454,9 @@
 }
 
 
-// Used inside Google only -- do not remove.
-bool ShouldTreatMapsAsRepeatedFields(const FileDescriptor& descriptor) {
-  return false;
-}
-
 // Do we ignore this message type?
-bool IgnoreMessage(const GeneratorOptions& options, const Descriptor* d) {
-  return d->options().map_entry() &&
-         !ShouldTreatMapsAsRepeatedFields(*d->file());
-}
-
-bool IsMap(const GeneratorOptions& options, const FieldDescriptor* field) {
-  return field->is_map() && !ShouldTreatMapsAsRepeatedFields(*field->file());
+bool IgnoreMessage(const Descriptor* d) {
+  return d->options().map_entry();
 }
 
 // Does JSPB ignore this entire oneof? True only if all fields are ignored.
@@ -490,7 +481,7 @@
         ToUpperCamel(ParseLowerUnderscore(field->name())) :
         ToLowerCamel(ParseLowerUnderscore(field->name()));
   }
-  if (is_map || IsMap(options, field)) {
+  if (is_map || field->is_map()) {
     // JSPB-style or proto3-style map.
     result += "Map";
   } else if (!drop_list && field->is_repeated()) {
@@ -569,7 +560,8 @@
     for (int i = 0; i < parent_type->field_count(); i++) {
       if (parent_type->field(i)->type() == FieldDescriptor::TYPE_GROUP &&
           parent_type->field(i)->message_type() == containing_type) {
-        return SimpleItoa(field->number() - parent_type->field(i)->number());
+        return SimpleItoa(field->number() -
+                                   parent_type->field(i)->number());
       }
     }
   }
@@ -781,7 +773,7 @@
     case FieldDescriptor::CPPTYPE_UINT64:
       // The default value of JSType is JS_NORMAL, which behaves the same as
       // JS_NUMBER.
-      return field->options().jstype() == google::protobuf::FieldOptions::JS_STRING;
+      return field->options().jstype() == FieldOptions::JS_STRING;
     default:
       return false;
   }
@@ -804,15 +796,15 @@
       // The original codegen is in Java, and Java protobufs store unsigned
       // integer values as signed integer values. In order to exactly match the
       // output, we need to reinterpret as base-2 signed. Ugh.
-      return MaybeNumberString(
-          field, SimpleItoa(static_cast<int32>(field->default_value_uint32())));
+      return MaybeNumberString(field, SimpleItoa(static_cast<int32>(
+                                          field->default_value_uint32())));
     case FieldDescriptor::CPPTYPE_INT64:
       return MaybeNumberString(
           field, SimpleItoa(field->default_value_int64()));
     case FieldDescriptor::CPPTYPE_UINT64:
       // See above note for uint32 -- reinterpreting as signed.
-      return MaybeNumberString(
-          field, SimpleItoa(static_cast<int64>(field->default_value_uint64())));
+      return MaybeNumberString(field, SimpleItoa(static_cast<int64>(
+                                          field->default_value_uint64())));
     case FieldDescriptor::CPPTYPE_ENUM:
       return SimpleItoa(field->default_value_enum()->number());
     case FieldDescriptor::CPPTYPE_BOOL:
@@ -1014,11 +1006,11 @@
                              bool is_setter_argument,
                              bool force_present,
                              bool singular_if_not_packed,
-                             BytesMode bytes_mode = BYTES_DEFAULT) {
-  GOOGLE_CHECK(!(is_setter_argument && force_present));
+                             BytesMode bytes_mode = BYTES_DEFAULT,
+                             bool force_singular = false) {
   string jstype = JSTypeName(options, field, bytes_mode);
 
-  if (field->is_repeated() &&
+  if (!force_singular && field->is_repeated() &&
       (field->is_packed() || !singular_if_not_packed)) {
     if (field->type() == FieldDescriptor::TYPE_BYTES &&
         bytes_mode == BYTES_DEFAULT) {
@@ -1136,7 +1128,7 @@
 bool HasRepeatedFields(const GeneratorOptions& options,
                        const Descriptor* desc) {
   for (int i = 0; i < desc->field_count(); i++) {
-    if (desc->field(i)->is_repeated() && !IsMap(options, desc->field(i))) {
+    if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) {
       return true;
     }
   }
@@ -1174,7 +1166,7 @@
                                const Descriptor* desc) {
   std::vector<string> numbers;
   for (int i = 0; i < desc->field_count(); i++) {
-    if (desc->field(i)->is_repeated() && !IsMap(options, desc->field(i))) {
+    if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) {
       numbers.push_back(JSFieldIndex(desc->field(i)));
     }
   }
@@ -1260,7 +1252,7 @@
 
 string FieldDefinition(const GeneratorOptions& options,
                        const FieldDescriptor* field) {
-  if (IsMap(options, field)) {
+  if (field->is_map()) {
     const FieldDescriptor* key_field = MapFieldKey(field);
     const FieldDescriptor* value_field = MapFieldValue(field);
     string key_type = ProtoTypeName(options, key_field);
@@ -1352,7 +1344,7 @@
 
 bool HasMap(const GeneratorOptions& options, const Descriptor* desc) {
   for (int i = 0; i < desc->field_count(); i++) {
-    if (IsMap(options, desc->field(i))) {
+    if (desc->field(i)->is_map()) {
       return true;
     }
   }
@@ -1618,7 +1610,7 @@
     io::Printer* printer,
     const Descriptor* desc,
     std::set<string>* provided) const {
-  if (IgnoreMessage(options, desc)) {
+  if (IgnoreMessage(desc)) {
     return;
   }
 
@@ -1681,13 +1673,13 @@
       if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
         string namespaceObject = *it;
         // Remove "proto." from the namespace object
-        GOOGLE_CHECK(namespaceObject.compare(0, 6, "proto.") == 0);
+        GOOGLE_CHECK_EQ(0, namespaceObject.compare(0, 6, "proto."));
         namespaceObject.erase(0, 6);
         printer->Print("goog.exportSymbol('$name$', null, proto);\n", "name",
-                namespaceObject);
+                       namespaceObject);
       } else {
         printer->Print("goog.exportSymbol('$name$', null, global);\n", "name",
-                *it);
+                       *it);
       }
     }
   }
@@ -1724,7 +1716,7 @@
   for (int i = 0; i < files.size(); i++) {
     for (int j = 0; j < files[i]->message_type_count(); j++) {
       const Descriptor* desc = files[i]->message_type(j);
-      if (!IgnoreMessage(options, desc)) {
+      if (!IgnoreMessage(desc)) {
         FindRequiresForMessage(options, desc, &required, &forwards,
                                &have_message);
       }
@@ -1869,7 +1861,7 @@
         forwards->insert(GetEnumPath(options, field->enum_type()));
       }
     } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
-      if (!IgnoreMessage(options, field->message_type())) {
+      if (!IgnoreMessage(field->message_type())) {
         required->insert(GetMessagePath(options, field->message_type()));
       }
     }
@@ -1907,7 +1899,7 @@
 void Generator::GenerateClass(const GeneratorOptions& options,
                               io::Printer* printer,
                               const Descriptor* desc) const {
-  if (IgnoreMessage(options, desc)) {
+  if (IgnoreMessage(desc)) {
     return;
   }
 
@@ -2229,7 +2221,7 @@
   printer->Print("$fieldname$: ",
                  "fieldname", JSObjectFieldName(options, field));
 
-  if (IsMap(options, field)) {
+  if (field->is_map()) {
     const FieldDescriptor* value_field = MapFieldValue(field);
     // If the map values are of a message type, we must provide their static
     // toObject() method; otherwise we pass undefined for that argument.
@@ -2297,7 +2289,7 @@
       " * @return {!$classname$}\n"
       " */\n"
       "$classname$.fromObject = function(obj) {\n"
-      "  var f, msg = new $classname$();\n",
+      "  var msg = new $classname$();\n",
       "classname", GetMessagePath(options, desc));
 
   for (int i = 0; i < desc->field_count(); i++) {
@@ -2315,7 +2307,7 @@
     const GeneratorOptions& options,
     io::Printer* printer,
     const FieldDescriptor* field) const {
-  if (IsMap(options, field)) {
+  if (field->is_map()) {
     const FieldDescriptor* value_field = MapFieldValue(field);
     if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
       // Since the map values are of message type, we have to do some extra work
@@ -2427,7 +2419,7 @@
 void Generator::GenerateClassField(const GeneratorOptions& options,
                                    io::Printer* printer,
                                    const FieldDescriptor* field) const {
-  if (IsMap(options, field)) {
+  if (field->is_map()) {
     const FieldDescriptor* key_field = MapFieldKey(field);
     const FieldDescriptor* value_field = MapFieldValue(field);
     // Map field: special handling to instantiate the map object on demand.
@@ -2707,7 +2699,7 @@
 
   // Generate clearFoo() method for map fields, repeated fields, and other
   // fields with presence.
-  if (IsMap(options, field)) {
+  if (field->is_map()) {
     printer->Print(
         "$class$.prototype.$clearername$ = function() {\n"
         "  this.$gettername$().clear();$returnvalue$\n"
@@ -2762,7 +2754,7 @@
     printer->Print(
         "/**\n"
         " * Returns whether this field is set.\n"
-        " * @return {!boolean}\n"
+        " * @return {boolean}\n"
         " */\n"
         "$class$.prototype.$hasername$ = function() {\n"
         "  return jspb.Message.getField(this, $index$) != null;\n"
@@ -2782,7 +2774,7 @@
   // clang-format off
   printer->Print(
       "/**\n"
-      " * @param {!$optionaltype$} value\n"
+      " * @param {$optionaltype$} value\n"
       " * @param {number=} opt_index$returndoc$\n"
       " */\n"
       "$class$.prototype.$addername$ = function(value, opt_index) {\n"
@@ -2790,7 +2782,14 @@
       "class", GetMessagePath(options, field->containing_type()), "addername",
       "add" + JSGetterName(options, field, BYTES_DEFAULT,
                            /* drop_list = */ true),
-      "optionaltype", JSTypeName(options, field, BYTES_DEFAULT),
+      "optionaltype",
+          JSFieldTypeAnnotation(
+                                options, field,
+                                /* is_setter_argument = */ false,
+                                /* force_present = */ true,
+                                /* singular_if_not_packed = */ false,
+                                BYTES_DEFAULT,
+                                /* force_singular = */ true),
       "index", JSFieldIndex(field),
       "returndoc", JSReturnDoc(options, field));
   printer->Annotate("addername", field);
@@ -2954,11 +2953,10 @@
     const GeneratorOptions& options,
     io::Printer* printer,
     const FieldDescriptor* field) const {
+  printer->Print("    case $num$:\n", "num",
+                 SimpleItoa(field->number()));
 
-  printer->Print("    case $num$:\n",
-                 "num", SimpleItoa(field->number()));
-
-  if (IsMap(options, field)) {
+  if (field->is_map()) {
     const FieldDescriptor* key_field = MapFieldKey(field);
     const FieldDescriptor* value_field = MapFieldValue(field);
     printer->Print(
@@ -2988,11 +2986,12 @@
           "      var value = new $fieldclass$;\n"
           "      reader.read$msgOrGroup$($grpfield$value,"
           "$fieldclass$.deserializeBinaryFromReader);\n",
-        "fieldclass", SubmessageTypeRef(options, field),
-          "msgOrGroup", (field->type() == FieldDescriptor::TYPE_GROUP) ?
-                        "Group" : "Message",
-          "grpfield", (field->type() == FieldDescriptor::TYPE_GROUP) ?
-                      (SimpleItoa(field->number()) + ", ") : "");
+          "fieldclass", SubmessageTypeRef(options, field), "msgOrGroup",
+          (field->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message",
+          "grpfield",
+          (field->type() == FieldDescriptor::TYPE_GROUP)
+              ? (SimpleItoa(field->number()) + ", ")
+              : "");
     } else {
       printer->Print(
           "      var value = /** @type {$fieldtype$} */ "
@@ -3090,12 +3089,12 @@
         "  f = message.get$name$($nolazy$);\n",
         "name", JSGetterName(options, field, BYTES_U8),
         // No lazy creation for maps containers -- fastpath the empty case.
-        "nolazy", IsMap(options, field) ? "true" : "");
+        "nolazy", field->is_map() ? "true" : "");
   }
 
   // Print an `if (condition)` statement that evaluates to true if the field
   // goes on the wire.
-  if (IsMap(options, field)) {
+  if (field->is_map()) {
     printer->Print(
         "  if (f && f.getLength() > 0) {\n");
   } else if (field->is_repeated()) {
@@ -3148,15 +3147,15 @@
   }
 
   // Write the field on the wire.
-  if (IsMap(options, field)) {
+  if (field->is_map()) {
     const FieldDescriptor* key_field = MapFieldKey(field);
     const FieldDescriptor* value_field = MapFieldValue(field);
     printer->Print(
         "    f.serializeBinary($index$, writer, "
-                              "$keyWriterFn$, $valueWriterFn$",
-        "index", SimpleItoa(field->number()),
-        "keyWriterFn", JSBinaryWriterMethodName(options, key_field),
-        "valueWriterFn", JSBinaryWriterMethodName(options, value_field));
+        "$keyWriterFn$, $valueWriterFn$",
+        "index", SimpleItoa(field->number()), "keyWriterFn",
+        JSBinaryWriterMethodName(options, key_field), "valueWriterFn",
+        JSBinaryWriterMethodName(options, value_field));
 
     if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
       printer->Print(", $messageType$.serializeBinaryToWriter",
@@ -3173,7 +3172,7 @@
         "index", SimpleItoa(field->number()));
 
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
-        !IsMap(options, field)) {
+        !field->is_map()) {
       printer->Print(
           ",\n"
           "      $submsg$.serializeBinaryToWriter\n",
@@ -3205,11 +3204,10 @@
 
   for (int i = 0; i < enumdesc->value_count(); i++) {
     const EnumValueDescriptor* value = enumdesc->value(i);
-    printer->Print(
-        "  $name$: $value$$comma$\n",
-        "name", ToEnumCase(value->name()),
-        "value", SimpleItoa(value->number()),
-        "comma", (i == enumdesc->value_count() - 1) ? "" : ",");
+    printer->Print("  $name$: $value$$comma$\n", "name",
+                   ToEnumCase(value->name()), "value",
+                   SimpleItoa(value->number()), "comma",
+                   (i == enumdesc->value_count() - 1) ? "" : ",");
     printer->Annotate("name", value);
   }
 
@@ -3252,13 +3250,15 @@
       "!Object} */ (\n"
       "         $toObject$),\n"
       "    $repeated$);\n",
-      "index", SimpleItoa(field->number()),
-      "name", extension_object_name,
-      "ctor", (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ?
-               SubmessageTypeRef(options, field) : string("null")),
-      "toObject", (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ?
-                   (SubmessageTypeRef(options, field) + ".toObject") :
-                   string("null")),
+      "index", SimpleItoa(field->number()), "name",
+      extension_object_name, "ctor",
+      (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
+           ? SubmessageTypeRef(options, field)
+           : string("null")),
+      "toObject",
+      (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
+           ? (SubmessageTypeRef(options, field) + ".toObject")
+           : string("null")),
       "repeated", (field->is_repeated() ? "1" : "0"));
 
   printer->Print(
@@ -3271,8 +3271,8 @@
       "    $binaryMessageDeserializeFn$,\n",
       "extendName",
       JSExtensionsObjectName(options, field->file(), field->containing_type()),
-      "index", SimpleItoa(field->number()), "class", extension_scope, "name",
-      extension_object_name, "binaryReaderFn",
+      "index", SimpleItoa(field->number()), "class", extension_scope,
+      "name", extension_object_name, "binaryReaderFn",
       JSBinaryReaderMethodName(options, field), "binaryWriterFn",
       JSBinaryWriterMethodName(options, field), "binaryMessageSerializeFn",
       (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
@@ -3291,10 +3291,9 @@
       "// toObject() will function correctly.\n"
       "$extendName$[$index$] = $class$.$name$;\n"
       "\n",
-      "extendName", JSExtensionsObjectName(options, field->file(),
-                                           field->containing_type()),
-      "index", SimpleItoa(field->number()),
-      "class", extension_scope,
+      "extendName",
+      JSExtensionsObjectName(options, field->file(), field->containing_type()),
+      "index", SimpleItoa(field->number()), "class", extension_scope,
       "name", extension_object_name);
 }
 
@@ -3465,8 +3464,7 @@
       printer->Print(
           "var $alias$ = require('$file$');\n"
           "goog.object.extend(proto, $alias$);\n",
-          "alias", ModuleAlias(name),
-          "file",
+          "alias", ModuleAlias(name), "file",
           GetRootPath(file->name(), name) + GetJSFilename(options, name));
     }
   }
@@ -3504,12 +3502,13 @@
   }
 
   // if provided is empty, do not export anything
-  if (options.import_style == GeneratorOptions::kImportCommonJs && !provided.empty()) {
+  if (options.import_style == GeneratorOptions::kImportCommonJs &&
+      !provided.empty()) {
     printer->Print("goog.object.extend(exports, $package$);\n",
                    "package", GetFilePath(options, file));
-  } else if(options.import_style == GeneratorOptions::kImportCommonJsStrict) {
-    printer->Print("goog.object.extend(exports, proto);\n",
-                   "package", GetFilePath(options, file));
+  } else if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
+    printer->Print("goog.object.extend(exports, proto);\n", "package",
+                   GetFilePath(options, file));
   }
 
   // Emit well-known type methods.
@@ -3667,7 +3666,7 @@
     // Generate one output file per input (.proto) file.
 
     for (int i = 0; i < files.size(); i++) {
-      const google::protobuf::FileDescriptor* file = files[i];
+      const FileDescriptor* file = files[i];
 
       string filename =
           options.output_dir + "/" + GetJSFilename(options, file->name());
diff --git a/src/google/protobuf/compiler/js/js_generator.h b/src/google/protobuf/compiler/js/js_generator.h
index b50ef7f..21e03bc 100644
--- a/src/google/protobuf/compiler/js/js_generator.h
+++ b/src/google/protobuf/compiler/js/js_generator.h
@@ -329,6 +329,6 @@
 }  // namespace js
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
diff --git a/src/google/protobuf/compiler/js/well_known_types_embed.cc b/src/google/protobuf/compiler/js/well_known_types_embed.cc
index e5ee551..c00c60c 100644
--- a/src/google/protobuf/compiler/js/well_known_types_embed.cc
+++ b/src/google/protobuf/compiler/js/well_known_types_embed.cc
@@ -1,3 +1,33 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
 #include <google/protobuf/compiler/js/well_known_types_embed.h>
 
 struct FileToc well_known_types_js[] = {
diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc
index 1db3544..8be2652 100644
--- a/src/google/protobuf/compiler/main.cc
+++ b/src/google/protobuf/compiler/main.cc
@@ -30,71 +30,80 @@
 
 // Author: kenton@google.com (Kenton Varda)
 
-#include <google/protobuf/compiler/command_line_interface.h>
 #include <google/protobuf/compiler/cpp/cpp_generator.h>
-
-#ifndef OPENSOURCE_PROTOBUF_CPP_BOOTSTRAP
-#include <google/protobuf/compiler/python/python_generator.h>
 #include <google/protobuf/compiler/java/java_generator.h>
-#endif  // ! OPENSOURCE_PROTOBUF_CPP_BOOTSTRAP
+#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/compiler/python/python_generator.h>
 
-#ifndef OPENSOURCE_PROTOBUF_CPP_BOOTSTRAP
 #include <google/protobuf/compiler/csharp/csharp_generator.h>
 #include <google/protobuf/compiler/js/js_generator.h>
 #include <google/protobuf/compiler/objectivec/objectivec_generator.h>
 #include <google/protobuf/compiler/php/php_generator.h>
 #include <google/protobuf/compiler/ruby/ruby_generator.h>
-#endif  // ! OPENSOURCE_PROTOBUF_CPP_BOOTSTRAP
 
-int main(int argc, char* argv[]) {
+namespace google {
+namespace protobuf {
+namespace compiler {
 
-  google::protobuf::compiler::CommandLineInterface cli;
+int ProtobufMain(int argc, char* argv[]) {
+
+  CommandLineInterface cli;
   cli.AllowPlugins("protoc-");
 
   // Proto2 C++
-  google::protobuf::compiler::cpp::CppGenerator cpp_generator;
+  cpp::CppGenerator cpp_generator;
   cli.RegisterGenerator("--cpp_out", "--cpp_opt", &cpp_generator,
                         "Generate C++ header and source.");
 
-#ifndef OPENSOURCE_PROTOBUF_CPP_BOOTSTRAP
+#ifdef GOOGLE_PROTOBUF_USE_OPENSOURCE_GOOGLE3_RUNTIME
+  cpp_generator.set_runtime(cpp::CppGenerator::Runtime::kOpensourceGoogle3);
+#elif defined(GOOGLE_PROTOBUF_USE_OPENSOURCE_RUNTIME)
+  cpp_generator.set_runtime(cpp::CppGenerator::Runtime::kOpensource);
+#endif
+
   // Proto2 Java
-  google::protobuf::compiler::java::JavaGenerator java_generator;
+  java::JavaGenerator java_generator;
   cli.RegisterGenerator("--java_out", "--java_opt", &java_generator,
                         "Generate Java source file.");
-#endif  // !OPENSOURCE_PROTOBUF_CPP_BOOTSTRAP
 
 
-#ifndef OPENSOURCE_PROTOBUF_CPP_BOOTSTRAP
   // Proto2 Python
-  google::protobuf::compiler::python::Generator py_generator;
+  python::Generator py_generator;
   cli.RegisterGenerator("--python_out", &py_generator,
                         "Generate Python source file.");
 
   // PHP
-  google::protobuf::compiler::php::Generator php_generator;
+  php::Generator php_generator;
   cli.RegisterGenerator("--php_out", &php_generator,
                         "Generate PHP source file.");
 
   // Ruby
-  google::protobuf::compiler::ruby::Generator rb_generator;
+  ruby::Generator rb_generator;
   cli.RegisterGenerator("--ruby_out", &rb_generator,
                         "Generate Ruby source file.");
 
   // CSharp
-  google::protobuf::compiler::csharp::Generator csharp_generator;
+  csharp::Generator csharp_generator;
   cli.RegisterGenerator("--csharp_out", "--csharp_opt", &csharp_generator,
                         "Generate C# source file.");
 
   // Objective C
-  google::protobuf::compiler::objectivec::ObjectiveCGenerator objc_generator;
+  objectivec::ObjectiveCGenerator objc_generator;
   cli.RegisterGenerator("--objc_out", "--objc_opt", &objc_generator,
                         "Generate Objective C header and source.");
 
   // JavaScript
-  google::protobuf::compiler::js::Generator js_generator;
+  js::Generator js_generator;
   cli.RegisterGenerator("--js_out", &js_generator,
                         "Generate JavaScript source.");
-#endif  // !OPENSOURCE_PROTOBUF_CPP_BOOTSTRAP
 
   return cli.Run(argc, argv);
 }
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
+
+int main(int argc, char* argv[]) {
+  return google::protobuf::compiler::ProtobufMain(argc, argv);
+}
diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc
index e150f97..4bb1d87 100644
--- a/src/google/protobuf/compiler/mock_code_generator.cc
+++ b/src/google/protobuf/compiler/mock_code_generator.cc
@@ -36,10 +36,10 @@
 #include <iostream>
 #include <memory>
 #include <vector>
-
-
 #include <google/protobuf/stubs/strutil.h>
 
+
+
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/testing/file.h>
@@ -179,7 +179,7 @@
   for (int i = 0; i < file->message_type_count(); i++) {
     if (HasPrefixString(file->message_type(i)->name(), "MockCodeGenerator_")) {
       string command = StripPrefixString(file->message_type(i)->name(),
-                                         "MockCodeGenerator_");
+                                                  "MockCodeGenerator_");
       if (command == "Error") {
         *error = "Saw message type MockCodeGenerator_Error.";
         return false;
@@ -223,8 +223,8 @@
 
   if (HasPrefixString(parameter, "insert=")) {
     std::vector<string> insert_into;
-    SplitStringUsing(StripPrefixString(parameter, "insert="),
-                     ",", &insert_into);
+    SplitStringUsing(StripPrefixString(parameter, "insert="), ",",
+                     &insert_into);
 
     for (size_t i = 0; i < insert_into.size(); i++) {
       {
diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h
index cdd9138..3b59bc4 100644
--- a/src/google/protobuf/compiler/mock_code_generator.h
+++ b/src/google/protobuf/compiler/mock_code_generator.h
@@ -41,7 +41,9 @@
 namespace protobuf {
 class FileDescriptor;
 }  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace compiler {
 
@@ -125,6 +127,6 @@
 
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
index df71c8b..0afa6fb 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
@@ -38,6 +38,7 @@
 #include <iostream>
 #include <sstream>
 #include <stdlib.h>
+#include <unordered_set>
 #include <vector>
 
 #include <google/protobuf/stubs/hash.h>
@@ -79,8 +80,8 @@
 
 namespace {
 
-hash_set<string> MakeWordsMap(const char* const words[], size_t num_words) {
-  hash_set<string> result;
+std::unordered_set<string> MakeWordsMap(const char* const words[], size_t num_words) {
+  std::unordered_set<string> result;
   for (int i = 0; i < num_words; i++) {
     result.insert(words[i]);
   }
@@ -89,7 +90,7 @@
 
 const char* const kUpperSegmentsList[] = {"url", "http", "https"};
 
-hash_set<string> kUpperSegments =
+std::unordered_set<string> kUpperSegments =
     MakeWordsMap(kUpperSegmentsList, GOOGLE_ARRAYSIZE(kUpperSegmentsList));
 
 bool ascii_isnewline(char c) {
@@ -217,7 +218,7 @@
     "StyleParameter", "StyleField", "TimeScale", "TimeBase", "TimeRecord",
 };
 
-hash_set<string> kReservedWords =
+std::unordered_set<string> kReservedWords =
     MakeWordsMap(kReservedWordList, GOOGLE_ARRAYSIZE(kReservedWordList));
 
 string SanitizeNameForObjC(const string& input,
diff --git a/src/google/protobuf/compiler/package_info.h b/src/google/protobuf/compiler/package_info.h
index fb6b473..105ef60 100644
--- a/src/google/protobuf/compiler/package_info.h
+++ b/src/google/protobuf/compiler/package_info.h
@@ -37,7 +37,6 @@
 // documentation generator.
 
 namespace google {
-
 namespace protobuf {
 
 // Implementation of the Protocol Buffer compiler.
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index 5c7047a..0cec293 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -35,9 +35,10 @@
 // Recursive descent FTW.
 
 #include <float.h>
-#include <google/protobuf/stubs/hash.h>
 #include <limits>
+#include <unordered_map>
 
+#include <google/protobuf/stubs/hash.h>
 
 #include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/logging.h>
@@ -58,7 +59,7 @@
 
 namespace {
 
-typedef hash_map<string, FieldDescriptorProto::Type> TypeNameMap;
+typedef std::unordered_map<string, FieldDescriptorProto::Type> TypeNameMap;
 
 TypeNameMap MakeTypeNameTable() {
   TypeNameMap result;
@@ -336,9 +337,9 @@
 // -------------------------------------------------------------------
 
 Parser::LocationRecorder::LocationRecorder(Parser* parser)
-  : parser_(parser),
-    source_code_info_(parser->source_code_info_),
-    location_(parser_->source_code_info_->add_location()) {
+    : parser_(parser),
+      source_code_info_(parser->source_code_info_),
+      location_(parser_->source_code_info_->add_location()) {
   location_->add_span(parser_->input_->current().line);
   location_->add_span(parser_->input_->current().column);
 }
@@ -1511,7 +1512,6 @@
     range->set_end(end);
   } while (TryConsume(","));
 
-
   if (LookingAt("[")) {
     int range_number_index = extensions_location.CurrentPathSize();
     SourceCodeInfo info;
@@ -1525,8 +1525,7 @@
           extensions_location, 0 /* we fill this in w/ actual index below */,
           &info);
       LocationRecorder location(
-          index_location,
-          DescriptorProto::ExtensionRange::kOptionsFieldNumber);
+          index_location, DescriptorProto::ExtensionRange::kOptionsFieldNumber);
       DO(Consume("["));
 
       do {
@@ -1546,12 +1545,12 @@
     for (int i = old_range_size; i < message->extension_range_size(); i++) {
       for (int j = 0; j < info.location_size(); j++) {
         if (info.location(j).path_size() == range_number_index + 1) {
-          // this location's path is up to the extension range index, but doesn't
-          // include options; so it's redundant with location above
+          // this location's path is up to the extension range index, but
+          // doesn't include options; so it's redundant with location above
           continue;
         }
         SourceCodeInfo_Location* dest = source_code_info_->add_location();
-        dest->CopyFrom(info.location(j));
+        *dest = info.location(j);
         dest->set_path(range_number_index, i);
       }
     }
@@ -2277,5 +2276,4 @@
 
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h
index 5d98e5e..b55750c 100644
--- a/src/google/protobuf/compiler/parser.h
+++ b/src/google/protobuf/compiler/parser.h
@@ -46,9 +46,10 @@
 #include <google/protobuf/repeated_field.h>
 
 namespace google {
-namespace protobuf { class Message; }
-
 namespace protobuf {
+
+class Message;
+
 namespace compiler {
 
 // Defined in this file.
@@ -226,7 +227,7 @@
 
     // Creates a recorder that generates locations into given source code info.
     LocationRecorder(const LocationRecorder& parent, int path1,
-                    SourceCodeInfo* source_code_info);
+                     SourceCodeInfo* source_code_info);
 
     ~LocationRecorder();
 
@@ -578,6 +579,6 @@
 
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_PARSER_H__
diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc
index 0725a68..008d97d 100644
--- a/src/google/protobuf/compiler/parser_unittest.cc
+++ b/src/google/protobuf/compiler/parser_unittest.cc
@@ -39,6 +39,7 @@
 
 #include <google/protobuf/compiler/parser.h>
 
+#include <google/protobuf/test_util2.h>
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/unittest_custom_options.pb.h>
 #include <google/protobuf/io/tokenizer.h>
@@ -1746,7 +1747,8 @@
 TEST_F(ParserValidationErrorTest, FileOptionNameError) {
   ExpectHasValidationErrors(
     "option foo = 5;",
-    "0:7: Option \"foo\" unknown.\n");
+    "0:7: Option \"foo\" unknown. Ensure that your proto definition file "
+    "imports the proto which defines the option.\n");
 }
 
 TEST_F(ParserValidationErrorTest, FileOptionValueError) {
@@ -1761,7 +1763,8 @@
     "message Foo {\n"
     "  optional bool bar = 1 [foo=1];\n"
     "}\n",
-    "1:25: Option \"foo\" unknown.\n");
+    "1:25: Option \"foo\" unknown. Ensure that your proto definition file "
+    "imports the proto which defines the option.\n");
 }
 
 TEST_F(ParserValidationErrorTest, FieldOptionValueError) {
@@ -1866,7 +1869,7 @@
 
   // base2.proto:
   //   package baz
-  //   import google/protobuf/descriptor.proto
+  //   import net/proto2/proto/descriptor.proto
   //   message Bar { optional int32 foo = 1; }
   //   extend FileOptions { optional Bar bar = 7672757; }
   FileDescriptorProto other_file;
@@ -1992,7 +1995,8 @@
   // We now have a FileDescriptorProto, but to compare with the expected we
   // need to link to a FileDecriptor, then output back to a proto. We'll
   // also need to give it the same name as the original.
-  parsed.set_name("google/protobuf/unittest.proto");
+  parsed.set_name(
+      TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto"));
   // We need the imported dependency before we can build our parsed proto
   const FileDescriptor* public_import =
       protobuf_unittest_import::PublicImportMessage::descriptor()->file();
diff --git a/src/google/protobuf/compiler/plugin.h b/src/google/protobuf/compiler/plugin.h
index d2793a9..c664917 100644
--- a/src/google/protobuf/compiler/plugin.h
+++ b/src/google/protobuf/compiler/plugin.h
@@ -85,6 +85,6 @@
 
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index 20aa82c..7569f27 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -6,8 +6,8 @@
 #include <algorithm>
 
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
@@ -18,42 +18,34 @@
 #include "third_party/protobuf/version.h"
 #endif
 // @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
 
-namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto {
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_CodeGeneratorResponse_File;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Version;
-}  // namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto
-namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto {
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<6> scc_info_FileDescriptorProto;
-}  // namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<6> scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto;
 namespace google {
 namespace protobuf {
 namespace compiler {
 class VersionDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Version>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Version> _instance;
 } _Version_default_instance_;
 class CodeGeneratorRequestDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorRequest>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorRequest> _instance;
 } _CodeGeneratorRequest_default_instance_;
 class CodeGeneratorResponse_FileDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorResponse_File>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorResponse_File> _instance;
 } _CodeGeneratorResponse_File_default_instance_;
 class CodeGeneratorResponseDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorResponse>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorResponse> _instance;
 } _CodeGeneratorResponse_default_instance_;
 }  // namespace compiler
 }  // namespace protobuf
 }  // namespace google
-namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto {
-static void InitDefaultsVersion() {
+static void InitDefaultsVersion_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -64,10 +56,10 @@
   ::google::protobuf::compiler::Version::InitAsDefaultInstance();
 }
 
-LIBPROTOC_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Version =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsVersion}, {}};
+LIBPROTOC_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsVersion_google_2fprotobuf_2fcompiler_2fplugin_2eproto}, {}};
 
-static void InitDefaultsCodeGeneratorRequest() {
+static void InitDefaultsCodeGeneratorRequest_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -78,12 +70,12 @@
   ::google::protobuf::compiler::CodeGeneratorRequest::InitAsDefaultInstance();
 }
 
-LIBPROTOC_EXPORT ::google::protobuf::internal::SCCInfo<2> scc_info_CodeGeneratorRequest =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsCodeGeneratorRequest}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorProto.base,
-      &protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_Version.base,}};
+LIBPROTOC_EXPORT ::google::protobuf::internal::SCCInfo<2> scc_info_CodeGeneratorRequest_google_2fprotobuf_2fcompiler_2fplugin_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsCodeGeneratorRequest_google_2fprotobuf_2fcompiler_2fplugin_2eproto}, {
+      &scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base,}};
 
-static void InitDefaultsCodeGeneratorResponse_File() {
+static void InitDefaultsCodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -94,10 +86,10 @@
   ::google::protobuf::compiler::CodeGeneratorResponse_File::InitAsDefaultInstance();
 }
 
-LIBPROTOC_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_CodeGeneratorResponse_File =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsCodeGeneratorResponse_File}, {}};
+LIBPROTOC_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsCodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto}, {}};
 
-static void InitDefaultsCodeGeneratorResponse() {
+static void InitDefaultsCodeGeneratorResponse_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -108,20 +100,22 @@
   ::google::protobuf::compiler::CodeGeneratorResponse::InitAsDefaultInstance();
 }
 
-LIBPROTOC_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_CodeGeneratorResponse =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsCodeGeneratorResponse}, {
-      &protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorResponse_File.base,}};
+LIBPROTOC_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_CodeGeneratorResponse_google_2fprotobuf_2fcompiler_2fplugin_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsCodeGeneratorResponse_google_2fprotobuf_2fcompiler_2fplugin_2eproto}, {
+      &scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base,}};
 
-void InitDefaults() {
-  ::google::protobuf::internal::InitSCC(&scc_info_Version.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_CodeGeneratorRequest.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_CodeGeneratorResponse_File.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_CodeGeneratorResponse.base);
+void InitDefaults_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_CodeGeneratorRequest_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_CodeGeneratorResponse_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata[4];
+::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[4];
+constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr;
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr;
 
-const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::Version, _has_bits_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::Version, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -183,62 +177,44 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::compiler::_CodeGeneratorResponse_default_instance_),
 };
 
-static void protobuf_AssignDescriptors() {
-  AddDescriptors();
-  AssignDescriptors(
-      "google/protobuf/compiler/plugin.proto", schemas, file_default_instances, TableStruct::offsets,
-      file_level_metadata, NULL, NULL);
-}
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = {
+  {}, AddDescriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto", schemas,
+  file_default_instances, TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets,
+  file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto, 4, file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto,
+};
 
-static void protobuf_AssignDescriptorsOnce() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
-}
+::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = {
+  false, InitDefaults_google_2fprotobuf_2fcompiler_2fplugin_2eproto, 
+  "\n%google/protobuf/compiler/plugin.proto\022"
+  "\030google.protobuf.compiler\032 google/protob"
+  "uf/descriptor.proto\"F\n\007Version\022\r\n\005major\030"
+  "\001 \001(\005\022\r\n\005minor\030\002 \001(\005\022\r\n\005patch\030\003 \001(\005\022\016\n\006s"
+  "uffix\030\004 \001(\t\"\272\001\n\024CodeGeneratorRequest\022\030\n\020"
+  "file_to_generate\030\001 \003(\t\022\021\n\tparameter\030\002 \001("
+  "\t\0228\n\nproto_file\030\017 \003(\0132$.google.protobuf."
+  "FileDescriptorProto\022;\n\020compiler_version\030"
+  "\003 \001(\0132!.google.protobuf.compiler.Version"
+  "\"\252\001\n\025CodeGeneratorResponse\022\r\n\005error\030\001 \001("
+  "\t\022B\n\004file\030\017 \003(\01324.google.protobuf.compil"
+  "er.CodeGeneratorResponse.File\032>\n\004File\022\014\n"
+  "\004name\030\001 \001(\t\022\027\n\017insertion_point\030\002 \001(\t\022\017\n\007"
+  "content\030\017 \001(\tBg\n\034com.google.protobuf.com"
+  "pilerB\014PluginProtosZ9github.com/golang/p"
+  "rotobuf/protoc-gen-go/plugin;plugin_go"
+,
+  "google/protobuf/compiler/plugin.proto", &assign_descriptors_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto, 638,
+};
 
-void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
-void protobuf_RegisterTypes(const ::std::string&) {
-  protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 4);
-}
-
-static void AddDescriptorsImpl() {
-  InitDefaults();
-  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
-      "\n%google/protobuf/compiler/plugin.proto\022"
-      "\030google.protobuf.compiler\032 google/protob"
-      "uf/descriptor.proto\"F\n\007Version\022\r\n\005major\030"
-      "\001 \001(\005\022\r\n\005minor\030\002 \001(\005\022\r\n\005patch\030\003 \001(\005\022\016\n\006s"
-      "uffix\030\004 \001(\t\"\272\001\n\024CodeGeneratorRequest\022\030\n\020"
-      "file_to_generate\030\001 \003(\t\022\021\n\tparameter\030\002 \001("
-      "\t\0228\n\nproto_file\030\017 \003(\0132$.google.protobuf."
-      "FileDescriptorProto\022;\n\020compiler_version\030"
-      "\003 \001(\0132!.google.protobuf.compiler.Version"
-      "\"\252\001\n\025CodeGeneratorResponse\022\r\n\005error\030\001 \001("
-      "\t\022B\n\004file\030\017 \003(\01324.google.protobuf.compil"
-      "er.CodeGeneratorResponse.File\032>\n\004File\022\014\n"
-      "\004name\030\001 \001(\t\022\027\n\017insertion_point\030\002 \001(\t\022\017\n\007"
-      "content\030\017 \001(\tBg\n\034com.google.protobuf.com"
-      "pilerB\014PluginProtosZ9github.com/golang/p"
-      "rotobuf/protoc-gen-go/plugin;plugin_go"
+void AddDescriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
+    ::AddDescriptors_google_2fprotobuf_2fdescriptor_2eproto,
   };
-  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 638);
-  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
-    "google/protobuf/compiler/plugin.proto", &protobuf_RegisterTypes);
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::AddDescriptors();
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto, deps, 1);
 }
 
-void AddDescriptors() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
-}
-// Force AddDescriptors() to be called at dynamic initialization time.
-struct StaticDescriptorInitializer {
-  StaticDescriptorInitializer() {
-    AddDescriptors();
-  }
-} static_descriptor_initializer;
-}  // namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fplugin_2eproto = []() { AddDescriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); return true; }();
 namespace google {
 namespace protobuf {
 namespace compiler {
@@ -247,6 +223,22 @@
 
 void Version::InitAsDefaultInstance() {
 }
+class Version::HasBitSetters {
+ public:
+  static void set_has_major(Version* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+  static void set_has_minor(Version* msg) {
+    msg->_has_bits_[0] |= 0x00000004u;
+  }
+  static void set_has_patch(Version* msg) {
+    msg->_has_bits_[0] |= 0x00000008u;
+  }
+  static void set_has_suffix(Version* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Version::kMajorFieldNumber;
 const int Version::kMinorFieldNumber;
@@ -256,8 +248,6 @@
 
 Version::Version()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_Version.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.compiler.Version)
 }
@@ -277,6 +267,8 @@
 }
 
 void Version::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base);
   suffix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   ::memset(&major_, 0, static_cast<size_t>(
       reinterpret_cast<char*>(&patch_) -
@@ -295,13 +287,8 @@
 void Version::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Version::descriptor() {
-  ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Version& Version::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_Version.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -316,7 +303,7 @@
   if (cached_has_bits & 0x00000001u) {
     suffix_.ClearNonDefaultToEmptyNoArena();
   }
-  if (cached_has_bits & 14u) {
+  if (cached_has_bits & 0x0000000eu) {
     ::memset(&major_, 0, static_cast<size_t>(
         reinterpret_cast<char*>(&patch_) -
         reinterpret_cast<char*>(&major_)) + sizeof(patch_));
@@ -325,9 +312,94 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Version::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Version*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional int32 major = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_major(value);
+        break;
+      }
+      // optional int32 minor = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_minor(value);
+        break;
+      }
+      // optional int32 patch = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_patch(value);
+        break;
+      }
+      // optional string suffix = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.Version.suffix");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_suffix();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Version::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.compiler.Version)
   for (;;) {
@@ -337,9 +409,8 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional int32 major = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
-          set_has_major();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          HasBitSetters::set_has_major(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &major_)));
@@ -351,9 +422,8 @@
 
       // optional int32 minor = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
-          set_has_minor();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          HasBitSetters::set_has_minor(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &minor_)));
@@ -365,9 +435,8 @@
 
       // optional int32 patch = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
-          set_has_patch();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          HasBitSetters::set_has_patch(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &patch_)));
@@ -379,8 +448,7 @@
 
       // optional string suffix = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_suffix()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -412,6 +480,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Version::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -503,30 +572,35 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
-  if (_has_bits_[0 / 32] & 15u) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x0000000fu) {
     // optional string suffix = 4;
-    if (has_suffix()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->suffix());
     }
 
     // optional int32 major = 1;
-    if (has_major()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->major());
     }
 
     // optional int32 minor = 2;
-    if (has_minor()) {
+    if (cached_has_bits & 0x00000004u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->minor());
     }
 
     // optional int32 patch = 3;
-    if (has_patch()) {
+    if (cached_has_bits & 0x00000008u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->patch());
@@ -542,7 +616,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.Version)
   GOOGLE_DCHECK_NE(&from, this);
   const Version* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Version>(
+      ::google::protobuf::DynamicCastToGenerated<Version>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.Version)
@@ -561,9 +635,9 @@
   (void) cached_has_bits;
 
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 15u) {
+  if (cached_has_bits & 0x0000000fu) {
     if (cached_has_bits & 0x00000001u) {
-      set_has_suffix();
+      _has_bits_[0] |= 0x00000001u;
       suffix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.suffix_);
     }
     if (cached_has_bits & 0x00000002u) {
@@ -603,18 +677,18 @@
 }
 void Version::InternalSwap(Version* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   suffix_.Swap(&other->suffix_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   swap(major_, other->major_);
   swap(minor_, other->minor_);
   swap(patch_, other->patch_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata Version::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[kIndexInFileMessages];
 }
 
 
@@ -624,6 +698,21 @@
   ::google::protobuf::compiler::_CodeGeneratorRequest_default_instance_._instance.get_mutable()->compiler_version_ = const_cast< ::google::protobuf::compiler::Version*>(
       ::google::protobuf::compiler::Version::internal_default_instance());
 }
+class CodeGeneratorRequest::HasBitSetters {
+ public:
+  static void set_has_parameter(CodeGeneratorRequest* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static const ::google::protobuf::compiler::Version& compiler_version(const CodeGeneratorRequest* msg);
+  static void set_has_compiler_version(CodeGeneratorRequest* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+};
+
+const ::google::protobuf::compiler::Version&
+CodeGeneratorRequest::HasBitSetters::compiler_version(const CodeGeneratorRequest* msg) {
+  return *msg->compiler_version_;
+}
 void CodeGeneratorRequest::clear_proto_file() {
   proto_file_.Clear();
 }
@@ -636,8 +725,6 @@
 
 CodeGeneratorRequest::CodeGeneratorRequest()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorRequest.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorRequest)
 }
@@ -661,6 +748,8 @@
 }
 
 void CodeGeneratorRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_CodeGeneratorRequest_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base);
   parameter_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   compiler_version_ = NULL;
 }
@@ -678,13 +767,8 @@
 void CodeGeneratorRequest::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() {
-  ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorRequest.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_CodeGeneratorRequest_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -698,7 +782,7 @@
   file_to_generate_.Clear();
   proto_file_.Clear();
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       parameter_.ClearNonDefaultToEmptyNoArena();
     }
@@ -711,9 +795,112 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* CodeGeneratorRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<CodeGeneratorRequest*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // repeated string file_to_generate = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
+          parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+          ::std::string* str = msg->add_file_to_generate();
+          str->clear();
+          object = str;
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 10 && (ptr += 1));
+        break;
+      }
+      // optional string parameter = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorRequest.parameter");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_parameter();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional .google.protobuf.compiler.Version compiler_version = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::compiler::Version::_InternalParse;
+        object = msg->mutable_compiler_version();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+      case 15: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 122) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::FileDescriptorProto::_InternalParse;
+          object = msg->add_proto_file();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 122 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool CodeGeneratorRequest::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorRequest)
   for (;;) {
@@ -723,8 +910,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // repeated string file_to_generate = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->add_file_to_generate()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -740,8 +926,7 @@
 
       // optional string parameter = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_parameter()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -756,8 +941,7 @@
 
       // optional .google.protobuf.compiler.Version compiler_version = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_compiler_version()));
         } else {
@@ -768,8 +952,7 @@
 
       // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
       case 15: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(122u /* 122 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (122 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_proto_file()));
         } else {
@@ -797,6 +980,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void CodeGeneratorRequest::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -828,7 +1012,7 @@
   // optional .google.protobuf.compiler.Version compiler_version = 3;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      3, this->_internal_compiler_version(), output);
+      3, HasBitSetters::compiler_version(this), output);
   }
 
   // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
@@ -880,7 +1064,7 @@
   if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        3, this->_internal_compiler_version(), deterministic, target);
+        3, HasBitSetters::compiler_version(this), deterministic, target);
   }
 
   // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
@@ -908,6 +1092,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated string file_to_generate = 1;
   total_size += 1 *
       ::google::protobuf::internal::FromIntSize(this->file_to_generate_size());
@@ -927,16 +1115,17 @@
     }
   }
 
-  if (_has_bits_[0 / 32] & 3u) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000003u) {
     // optional string parameter = 2;
-    if (has_parameter()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->parameter());
     }
 
     // optional .google.protobuf.compiler.Version compiler_version = 3;
-    if (has_compiler_version()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::MessageSize(
           *compiler_version_);
@@ -952,7 +1141,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest)
   GOOGLE_DCHECK_NE(&from, this);
   const CodeGeneratorRequest* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const CodeGeneratorRequest>(
+      ::google::protobuf::DynamicCastToGenerated<CodeGeneratorRequest>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.CodeGeneratorRequest)
@@ -973,9 +1162,9 @@
   file_to_generate_.MergeFrom(from.file_to_generate_);
   proto_file_.MergeFrom(from.proto_file_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
-      set_has_parameter();
+      _has_bits_[0] |= 0x00000001u;
       parameter_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.parameter_);
     }
     if (cached_has_bits & 0x00000002u) {
@@ -1009,18 +1198,18 @@
 }
 void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   file_to_generate_.InternalSwap(CastToBase(&other->file_to_generate_));
   CastToBase(&proto_file_)->InternalSwap(CastToBase(&other->proto_file_));
   parameter_.Swap(&other->parameter_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   swap(compiler_version_, other->compiler_version_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[kIndexInFileMessages];
 }
 
 
@@ -1028,6 +1217,19 @@
 
 void CodeGeneratorResponse_File::InitAsDefaultInstance() {
 }
+class CodeGeneratorResponse_File::HasBitSetters {
+ public:
+  static void set_has_name(CodeGeneratorResponse_File* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_insertion_point(CodeGeneratorResponse_File* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+  static void set_has_content(CodeGeneratorResponse_File* msg) {
+    msg->_has_bits_[0] |= 0x00000004u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int CodeGeneratorResponse_File::kNameFieldNumber;
 const int CodeGeneratorResponse_File::kInsertionPointFieldNumber;
@@ -1036,8 +1238,6 @@
 
 CodeGeneratorResponse_File::CodeGeneratorResponse_File()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorResponse_File.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
 }
@@ -1062,6 +1262,8 @@
 }
 
 void CodeGeneratorResponse_File::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   insertion_point_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   content_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -1081,13 +1283,8 @@
 void CodeGeneratorResponse_File::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() {
-  ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorResponse_File.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -1099,7 +1296,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 7u) {
+  if (cached_has_bits & 0x00000007u) {
     if (cached_has_bits & 0x00000001u) {
       name_.ClearNonDefaultToEmptyNoArena();
     }
@@ -1114,9 +1311,96 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* CodeGeneratorResponse_File::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<CodeGeneratorResponse_File*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.File.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string insertion_point = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_insertion_point();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string content = 15;
+      case 15: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 122) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.File.content");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_content();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool CodeGeneratorResponse_File::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorResponse.File)
   for (;;) {
@@ -1126,8 +1410,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -1142,8 +1425,7 @@
 
       // optional string insertion_point = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_insertion_point()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -1158,8 +1440,7 @@
 
       // optional string content = 15;
       case 15: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(122u /* 122 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (122 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_content()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -1191,6 +1472,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void CodeGeneratorResponse_File::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -1294,23 +1576,28 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
-  if (_has_bits_[0 / 32] & 7u) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000007u) {
     // optional string name = 1;
-    if (has_name()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->name());
     }
 
     // optional string insertion_point = 2;
-    if (has_insertion_point()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->insertion_point());
     }
 
     // optional string content = 15;
-    if (has_content()) {
+    if (cached_has_bits & 0x00000004u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->content());
@@ -1326,7 +1613,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
   GOOGLE_DCHECK_NE(&from, this);
   const CodeGeneratorResponse_File* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const CodeGeneratorResponse_File>(
+      ::google::protobuf::DynamicCastToGenerated<CodeGeneratorResponse_File>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.CodeGeneratorResponse.File)
@@ -1345,17 +1632,17 @@
   (void) cached_has_bits;
 
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 7u) {
+  if (cached_has_bits & 0x00000007u) {
     if (cached_has_bits & 0x00000001u) {
-      set_has_name();
+      _has_bits_[0] |= 0x00000001u;
       name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
     }
     if (cached_has_bits & 0x00000002u) {
-      set_has_insertion_point();
+      _has_bits_[0] |= 0x00000002u;
       insertion_point_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.insertion_point_);
     }
     if (cached_has_bits & 0x00000004u) {
-      set_has_content();
+      _has_bits_[0] |= 0x00000004u;
       content_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.content_);
     }
   }
@@ -1385,19 +1672,19 @@
 }
 void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   insertion_point_.Swap(&other->insertion_point_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   content_.Swap(&other->content_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[kIndexInFileMessages];
 }
 
 
@@ -1405,6 +1692,13 @@
 
 void CodeGeneratorResponse::InitAsDefaultInstance() {
 }
+class CodeGeneratorResponse::HasBitSetters {
+ public:
+  static void set_has_error(CodeGeneratorResponse* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int CodeGeneratorResponse::kErrorFieldNumber;
 const int CodeGeneratorResponse::kFileFieldNumber;
@@ -1412,8 +1706,6 @@
 
 CodeGeneratorResponse::CodeGeneratorResponse()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorResponse.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse)
 }
@@ -1431,6 +1723,8 @@
 }
 
 void CodeGeneratorResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_CodeGeneratorResponse_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base);
   error_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 
@@ -1446,13 +1740,8 @@
 void CodeGeneratorResponse::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() {
-  ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorResponse.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_CodeGeneratorResponse_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -1472,9 +1761,80 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* CodeGeneratorResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<CodeGeneratorResponse*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional string error = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.error");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_error();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+      case 15: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 122) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::compiler::CodeGeneratorResponse_File::_InternalParse;
+          object = msg->add_file();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 122 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool CodeGeneratorResponse::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorResponse)
   for (;;) {
@@ -1484,8 +1844,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional string error = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_error()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -1500,8 +1859,7 @@
 
       // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
       case 15: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(122u /* 122 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (122 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_file()));
         } else {
@@ -1529,6 +1887,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void CodeGeneratorResponse::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -1607,6 +1966,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
   {
     unsigned int count = static_cast<unsigned int>(this->file_size());
@@ -1619,7 +1982,8 @@
   }
 
   // optional string error = 1;
-  if (has_error()) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000001u) {
     total_size += 1 +
       ::google::protobuf::internal::WireFormatLite::StringSize(
         this->error());
@@ -1634,7 +1998,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse)
   GOOGLE_DCHECK_NE(&from, this);
   const CodeGeneratorResponse* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const CodeGeneratorResponse>(
+      ::google::protobuf::DynamicCastToGenerated<CodeGeneratorResponse>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.CodeGeneratorResponse)
@@ -1654,7 +2018,7 @@
 
   file_.MergeFrom(from.file_);
   if (from.has_error()) {
-    set_has_error();
+    _has_bits_[0] |= 0x00000001u;
     error_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.error_);
   }
 }
@@ -1683,16 +2047,16 @@
 }
 void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   CastToBase(&file_)->InternalSwap(CastToBase(&other->file_));
   error_.Swap(&other->error_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[kIndexInFileMessages];
 }
 
 
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index 78d3bba..4b7527e 100644
--- a/src/google/protobuf/compiler/plugin.pb.h
+++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -4,18 +4,18 @@
 #ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto
 #define PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto
 
+#include <limits>
 #include <string>
 
 #include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 3006001
+#if GOOGLE_PROTOBUF_VERSION < 3006000
 #error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please update
+#error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
 #if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
 #error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please
+#error incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.
 #endif
 
@@ -32,7 +32,8 @@
 #include <google/protobuf/unknown_field_set.h>
 #include <google/protobuf/descriptor.pb.h>
 // @@protoc_insertion_point(includes)
-#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto LIBPROTOC_EXPORT
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto LIBPROTOC_EXPORT
 #ifdef major
 #undef major
 #endif
@@ -40,18 +41,19 @@
 #undef minor
 #endif
 
-namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto {
 // Internal implementation detail -- do not use these members.
-struct LIBPROTOC_EXPORT TableStruct {
-  static const ::google::protobuf::internal::ParseTableField entries[];
-  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
-  static const ::google::protobuf::internal::ParseTable schema[4];
+struct LIBPROTOC_EXPORT TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[4]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
   static const ::google::protobuf::uint32 offsets[];
 };
-void LIBPROTOC_EXPORT AddDescriptors();
-}  // namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto
+void LIBPROTOC_EXPORT AddDescriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
 namespace google {
 namespace protobuf {
 namespace compiler {
@@ -68,10 +70,6 @@
 class VersionDefaultTypeInternal;
 LIBPROTOC_EXPORT extern VersionDefaultTypeInternal _Version_default_instance_;
 }  // namespace compiler
-}  // namespace protobuf
-}  // namespace google
-namespace google {
-namespace protobuf {
 template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorRequest* Arena::CreateMaybeMessage<::google::protobuf::compiler::CodeGeneratorRequest>(Arena*);
 template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorResponse* Arena::CreateMaybeMessage<::google::protobuf::compiler::CodeGeneratorResponse>(Arena*);
 template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorResponse_File* Arena::CreateMaybeMessage<::google::protobuf::compiler::CodeGeneratorResponse_File>(Arena*);
@@ -117,7 +115,9 @@
     return _internal_metadata_.mutable_unknown_fields();
   }
 
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Version& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -150,8 +150,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -216,14 +221,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.compiler.Version)
  private:
-  void set_has_major();
-  void clear_has_major();
-  void set_has_minor();
-  void clear_has_minor();
-  void set_has_patch();
-  void clear_has_patch();
-  void set_has_suffix();
-  void clear_has_suffix();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::internal::HasBits<1> _has_bits_;
@@ -232,7 +230,7 @@
   ::google::protobuf::int32 major_;
   ::google::protobuf::int32 minor_;
   ::google::protobuf::int32 patch_;
-  friend struct ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -269,7 +267,9 @@
     return _internal_metadata_.mutable_unknown_fields();
   }
 
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const CodeGeneratorRequest& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -302,8 +302,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -349,8 +354,8 @@
   #endif
   void add_file_to_generate(const char* value);
   void add_file_to_generate(const char* value, size_t size);
-  const ::google::protobuf::RepeatedPtrField< ::std::string>& file_to_generate() const;
-  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_to_generate();
+  const ::google::protobuf::RepeatedPtrField<::std::string>& file_to_generate() const;
+  ::google::protobuf::RepeatedPtrField<::std::string>* mutable_file_to_generate();
 
   // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
   int proto_file_size() const;
@@ -383,9 +388,6 @@
   bool has_compiler_version() const;
   void clear_compiler_version();
   static const int kCompilerVersionFieldNumber = 3;
-  private:
-  const ::google::protobuf::compiler::Version& _internal_compiler_version() const;
-  public:
   const ::google::protobuf::compiler::Version& compiler_version() const;
   ::google::protobuf::compiler::Version* release_compiler_version();
   ::google::protobuf::compiler::Version* mutable_compiler_version();
@@ -393,19 +395,16 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
  private:
-  void set_has_parameter();
-  void clear_has_parameter();
-  void set_has_compiler_version();
-  void clear_has_compiler_version();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  ::google::protobuf::RepeatedPtrField< ::std::string> file_to_generate_;
+  ::google::protobuf::RepeatedPtrField<::std::string> file_to_generate_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_;
   ::google::protobuf::internal::ArenaStringPtr parameter_;
   ::google::protobuf::compiler::Version* compiler_version_;
-  friend struct ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -442,7 +441,9 @@
     return _internal_metadata_.mutable_unknown_fields();
   }
 
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const CodeGeneratorResponse_File& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -475,8 +476,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -550,12 +556,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
  private:
-  void set_has_name();
-  void clear_has_name();
-  void set_has_insertion_point();
-  void clear_has_insertion_point();
-  void set_has_content();
-  void clear_has_content();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::internal::HasBits<1> _has_bits_;
@@ -563,7 +564,7 @@
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::internal::ArenaStringPtr insertion_point_;
   ::google::protobuf::internal::ArenaStringPtr content_;
-  friend struct ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -600,7 +601,9 @@
     return _internal_metadata_.mutable_unknown_fields();
   }
 
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const CodeGeneratorResponse& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -633,8 +636,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -692,15 +700,14 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
  private:
-  void set_has_error();
-  void clear_has_error();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_;
   ::google::protobuf::internal::ArenaStringPtr error_;
-  friend struct ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
 };
 // ===================================================================
 
@@ -717,22 +724,16 @@
 inline bool Version::has_major() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void Version::set_has_major() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void Version::clear_has_major() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void Version::clear_major() {
   major_ = 0;
-  clear_has_major();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline ::google::protobuf::int32 Version::major() const {
   // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.major)
   return major_;
 }
 inline void Version::set_major(::google::protobuf::int32 value) {
-  set_has_major();
+  _has_bits_[0] |= 0x00000002u;
   major_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.major)
 }
@@ -741,22 +742,16 @@
 inline bool Version::has_minor() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
-inline void Version::set_has_minor() {
-  _has_bits_[0] |= 0x00000004u;
-}
-inline void Version::clear_has_minor() {
-  _has_bits_[0] &= ~0x00000004u;
-}
 inline void Version::clear_minor() {
   minor_ = 0;
-  clear_has_minor();
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline ::google::protobuf::int32 Version::minor() const {
   // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.minor)
   return minor_;
 }
 inline void Version::set_minor(::google::protobuf::int32 value) {
-  set_has_minor();
+  _has_bits_[0] |= 0x00000004u;
   minor_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.minor)
 }
@@ -765,22 +760,16 @@
 inline bool Version::has_patch() const {
   return (_has_bits_[0] & 0x00000008u) != 0;
 }
-inline void Version::set_has_patch() {
-  _has_bits_[0] |= 0x00000008u;
-}
-inline void Version::clear_has_patch() {
-  _has_bits_[0] &= ~0x00000008u;
-}
 inline void Version::clear_patch() {
   patch_ = 0;
-  clear_has_patch();
+  _has_bits_[0] &= ~0x00000008u;
 }
 inline ::google::protobuf::int32 Version::patch() const {
   // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.patch)
   return patch_;
 }
 inline void Version::set_patch(::google::protobuf::int32 value) {
-  set_has_patch();
+  _has_bits_[0] |= 0x00000008u;
   patch_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.patch)
 }
@@ -789,28 +778,22 @@
 inline bool Version::has_suffix() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void Version::set_has_suffix() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void Version::clear_has_suffix() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void Version::clear_suffix() {
   suffix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  clear_has_suffix();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& Version::suffix() const {
   // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.suffix)
   return suffix_.GetNoArena();
 }
 inline void Version::set_suffix(const ::std::string& value) {
-  set_has_suffix();
+  _has_bits_[0] |= 0x00000001u;
   suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
   // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.suffix)
 }
 #if LANG_CXX11
 inline void Version::set_suffix(::std::string&& value) {
-  set_has_suffix();
+  _has_bits_[0] |= 0x00000001u;
   suffix_.SetNoArena(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.Version.suffix)
@@ -818,18 +801,18 @@
 #endif
 inline void Version::set_suffix(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_suffix();
+  _has_bits_[0] |= 0x00000001u;
   suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.Version.suffix)
 }
 inline void Version::set_suffix(const char* value, size_t size) {
-  set_has_suffix();
+  _has_bits_[0] |= 0x00000001u;
   suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       ::std::string(reinterpret_cast<const char*>(value), size));
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.Version.suffix)
 }
 inline ::std::string* Version::mutable_suffix() {
-  set_has_suffix();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.Version.suffix)
   return suffix_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
@@ -838,14 +821,14 @@
   if (!has_suffix()) {
     return NULL;
   }
-  clear_has_suffix();
+  _has_bits_[0] &= ~0x00000001u;
   return suffix_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline void Version::set_allocated_suffix(::std::string* suffix) {
   if (suffix != NULL) {
-    set_has_suffix();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_suffix();
+    _has_bits_[0] &= ~0x00000001u;
   }
   suffix_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), suffix);
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.Version.suffix)
@@ -913,12 +896,12 @@
   file_to_generate_.Add()->assign(reinterpret_cast<const char*>(value), size);
   // @@protoc_insertion_point(field_add_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
 }
-inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+inline const ::google::protobuf::RepeatedPtrField<::std::string>&
 CodeGeneratorRequest::file_to_generate() const {
   // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
   return file_to_generate_;
 }
-inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+inline ::google::protobuf::RepeatedPtrField<::std::string>*
 CodeGeneratorRequest::mutable_file_to_generate() {
   // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
   return &file_to_generate_;
@@ -928,28 +911,22 @@
 inline bool CodeGeneratorRequest::has_parameter() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void CodeGeneratorRequest::set_has_parameter() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void CodeGeneratorRequest::clear_has_parameter() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void CodeGeneratorRequest::clear_parameter() {
   parameter_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  clear_has_parameter();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& CodeGeneratorRequest::parameter() const {
   // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.parameter)
   return parameter_.GetNoArena();
 }
 inline void CodeGeneratorRequest::set_parameter(const ::std::string& value) {
-  set_has_parameter();
+  _has_bits_[0] |= 0x00000001u;
   parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
   // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter)
 }
 #if LANG_CXX11
 inline void CodeGeneratorRequest::set_parameter(::std::string&& value) {
-  set_has_parameter();
+  _has_bits_[0] |= 0x00000001u;
   parameter_.SetNoArena(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorRequest.parameter)
@@ -957,18 +934,18 @@
 #endif
 inline void CodeGeneratorRequest::set_parameter(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_parameter();
+  _has_bits_[0] |= 0x00000001u;
   parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.parameter)
 }
 inline void CodeGeneratorRequest::set_parameter(const char* value, size_t size) {
-  set_has_parameter();
+  _has_bits_[0] |= 0x00000001u;
   parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       ::std::string(reinterpret_cast<const char*>(value), size));
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.parameter)
 }
 inline ::std::string* CodeGeneratorRequest::mutable_parameter() {
-  set_has_parameter();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.parameter)
   return parameter_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
@@ -977,14 +954,14 @@
   if (!has_parameter()) {
     return NULL;
   }
-  clear_has_parameter();
+  _has_bits_[0] &= ~0x00000001u;
   return parameter_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline void CodeGeneratorRequest::set_allocated_parameter(::std::string* parameter) {
   if (parameter != NULL) {
-    set_has_parameter();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_parameter();
+    _has_bits_[0] &= ~0x00000001u;
   }
   parameter_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), parameter);
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter)
@@ -1021,18 +998,9 @@
 inline bool CodeGeneratorRequest::has_compiler_version() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void CodeGeneratorRequest::set_has_compiler_version() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void CodeGeneratorRequest::clear_has_compiler_version() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void CodeGeneratorRequest::clear_compiler_version() {
   if (compiler_version_ != NULL) compiler_version_->Clear();
-  clear_has_compiler_version();
-}
-inline const ::google::protobuf::compiler::Version& CodeGeneratorRequest::_internal_compiler_version() const {
-  return *compiler_version_;
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::google::protobuf::compiler::Version& CodeGeneratorRequest::compiler_version() const {
   const ::google::protobuf::compiler::Version* p = compiler_version_;
@@ -1042,13 +1010,13 @@
 }
 inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::release_compiler_version() {
   // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
-  clear_has_compiler_version();
+  _has_bits_[0] &= ~0x00000002u;
   ::google::protobuf::compiler::Version* temp = compiler_version_;
   compiler_version_ = NULL;
   return temp;
 }
 inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() {
-  set_has_compiler_version();
+  _has_bits_[0] |= 0x00000002u;
   if (compiler_version_ == NULL) {
     auto* p = CreateMaybeMessage<::google::protobuf::compiler::Version>(GetArenaNoVirtual());
     compiler_version_ = p;
@@ -1067,9 +1035,9 @@
       compiler_version = ::google::protobuf::internal::GetOwnedMessage(
           message_arena, compiler_version, submessage_arena);
     }
-    set_has_compiler_version();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_compiler_version();
+    _has_bits_[0] &= ~0x00000002u;
   }
   compiler_version_ = compiler_version;
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
@@ -1083,28 +1051,22 @@
 inline bool CodeGeneratorResponse_File::has_name() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void CodeGeneratorResponse_File::set_has_name() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void CodeGeneratorResponse_File::clear_has_name() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void CodeGeneratorResponse_File::clear_name() {
   name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& CodeGeneratorResponse_File::name() const {
   // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.name)
   return name_.GetNoArena();
 }
 inline void CodeGeneratorResponse_File::set_name(const ::std::string& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
   // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name)
 }
 #if LANG_CXX11
 inline void CodeGeneratorResponse_File::set_name(::std::string&& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.SetNoArena(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.File.name)
@@ -1112,18 +1074,18 @@
 #endif
 inline void CodeGeneratorResponse_File::set_name(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.name)
 }
 inline void CodeGeneratorResponse_File::set_name(const char* value, size_t size) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       ::std::string(reinterpret_cast<const char*>(value), size));
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.name)
 }
 inline ::std::string* CodeGeneratorResponse_File::mutable_name() {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.name)
   return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
@@ -1132,14 +1094,14 @@
   if (!has_name()) {
     return NULL;
   }
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline void CodeGeneratorResponse_File::set_allocated_name(::std::string* name) {
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name)
@@ -1149,28 +1111,22 @@
 inline bool CodeGeneratorResponse_File::has_insertion_point() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void CodeGeneratorResponse_File::set_has_insertion_point() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void CodeGeneratorResponse_File::clear_has_insertion_point() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void CodeGeneratorResponse_File::clear_insertion_point() {
   insertion_point_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  clear_has_insertion_point();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::std::string& CodeGeneratorResponse_File::insertion_point() const {
   // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
   return insertion_point_.GetNoArena();
 }
 inline void CodeGeneratorResponse_File::set_insertion_point(const ::std::string& value) {
-  set_has_insertion_point();
+  _has_bits_[0] |= 0x00000002u;
   insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
   // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
 }
 #if LANG_CXX11
 inline void CodeGeneratorResponse_File::set_insertion_point(::std::string&& value) {
-  set_has_insertion_point();
+  _has_bits_[0] |= 0x00000002u;
   insertion_point_.SetNoArena(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
@@ -1178,18 +1134,18 @@
 #endif
 inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_insertion_point();
+  _has_bits_[0] |= 0x00000002u;
   insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
 }
 inline void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) {
-  set_has_insertion_point();
+  _has_bits_[0] |= 0x00000002u;
   insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       ::std::string(reinterpret_cast<const char*>(value), size));
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
 }
 inline ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() {
-  set_has_insertion_point();
+  _has_bits_[0] |= 0x00000002u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
   return insertion_point_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
@@ -1198,14 +1154,14 @@
   if (!has_insertion_point()) {
     return NULL;
   }
-  clear_has_insertion_point();
+  _has_bits_[0] &= ~0x00000002u;
   return insertion_point_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline void CodeGeneratorResponse_File::set_allocated_insertion_point(::std::string* insertion_point) {
   if (insertion_point != NULL) {
-    set_has_insertion_point();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_insertion_point();
+    _has_bits_[0] &= ~0x00000002u;
   }
   insertion_point_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), insertion_point);
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
@@ -1215,28 +1171,22 @@
 inline bool CodeGeneratorResponse_File::has_content() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
-inline void CodeGeneratorResponse_File::set_has_content() {
-  _has_bits_[0] |= 0x00000004u;
-}
-inline void CodeGeneratorResponse_File::clear_has_content() {
-  _has_bits_[0] &= ~0x00000004u;
-}
 inline void CodeGeneratorResponse_File::clear_content() {
   content_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  clear_has_content();
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline const ::std::string& CodeGeneratorResponse_File::content() const {
   // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.content)
   return content_.GetNoArena();
 }
 inline void CodeGeneratorResponse_File::set_content(const ::std::string& value) {
-  set_has_content();
+  _has_bits_[0] |= 0x00000004u;
   content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
   // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content)
 }
 #if LANG_CXX11
 inline void CodeGeneratorResponse_File::set_content(::std::string&& value) {
-  set_has_content();
+  _has_bits_[0] |= 0x00000004u;
   content_.SetNoArena(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.File.content)
@@ -1244,18 +1194,18 @@
 #endif
 inline void CodeGeneratorResponse_File::set_content(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_content();
+  _has_bits_[0] |= 0x00000004u;
   content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.content)
 }
 inline void CodeGeneratorResponse_File::set_content(const char* value, size_t size) {
-  set_has_content();
+  _has_bits_[0] |= 0x00000004u;
   content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       ::std::string(reinterpret_cast<const char*>(value), size));
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.content)
 }
 inline ::std::string* CodeGeneratorResponse_File::mutable_content() {
-  set_has_content();
+  _has_bits_[0] |= 0x00000004u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.content)
   return content_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
@@ -1264,14 +1214,14 @@
   if (!has_content()) {
     return NULL;
   }
-  clear_has_content();
+  _has_bits_[0] &= ~0x00000004u;
   return content_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline void CodeGeneratorResponse_File::set_allocated_content(::std::string* content) {
   if (content != NULL) {
-    set_has_content();
+    _has_bits_[0] |= 0x00000004u;
   } else {
-    clear_has_content();
+    _has_bits_[0] &= ~0x00000004u;
   }
   content_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), content);
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content)
@@ -1285,28 +1235,22 @@
 inline bool CodeGeneratorResponse::has_error() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void CodeGeneratorResponse::set_has_error() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void CodeGeneratorResponse::clear_has_error() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void CodeGeneratorResponse::clear_error() {
   error_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  clear_has_error();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& CodeGeneratorResponse::error() const {
   // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.error)
   return error_.GetNoArena();
 }
 inline void CodeGeneratorResponse::set_error(const ::std::string& value) {
-  set_has_error();
+  _has_bits_[0] |= 0x00000001u;
   error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
   // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error)
 }
 #if LANG_CXX11
 inline void CodeGeneratorResponse::set_error(::std::string&& value) {
-  set_has_error();
+  _has_bits_[0] |= 0x00000001u;
   error_.SetNoArena(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.error)
@@ -1314,18 +1258,18 @@
 #endif
 inline void CodeGeneratorResponse::set_error(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_error();
+  _has_bits_[0] |= 0x00000001u;
   error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.error)
 }
 inline void CodeGeneratorResponse::set_error(const char* value, size_t size) {
-  set_has_error();
+  _has_bits_[0] |= 0x00000001u;
   error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       ::std::string(reinterpret_cast<const char*>(value), size));
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.error)
 }
 inline ::std::string* CodeGeneratorResponse::mutable_error() {
-  set_has_error();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.error)
   return error_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
@@ -1334,14 +1278,14 @@
   if (!has_error()) {
     return NULL;
   }
-  clear_has_error();
+  _has_bits_[0] &= ~0x00000001u;
   return error_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline void CodeGeneratorResponse::set_allocated_error(::std::string* error) {
   if (error != NULL) {
-    set_has_error();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_error();
+    _has_bits_[0] &= ~0x00000001u;
   }
   error_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), error);
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error)
@@ -1395,4 +1339,5 @@
 
 // @@protoc_insertion_point(global_scope)
 
+#include <google/protobuf/port_undef.inc>
 #endif  // PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto
diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc
index 01f28b3..6dc61ec 100644
--- a/src/google/protobuf/compiler/python/python_generator.cc
+++ b/src/google/protobuf/compiler/python/python_generator.cc
@@ -45,7 +45,6 @@
 // directly.
 
 #include <algorithm>
-#include <google/protobuf/stubs/hash.h>
 #include <limits>
 #include <map>
 #include <memory>
@@ -73,11 +72,6 @@
 
 namespace {
 
-// Reimplemented here because we can't bring in
-// absl/strings/string_view_utils.h because it needs C++11.
-bool StrStartsWith(StringPiece sp, StringPiece x) {
-  return sp.size() >= x.size() && sp.substr(0, x.size()) == x;
-}
 bool StrEndsWith(StringPiece sp, StringPiece x) {
   return sp.size() >= x.size() && sp.substr(sp.size() - x.size()) == x;
 }
@@ -103,7 +97,7 @@
 
 // Returns the alias we assign to the module of the given .proto filename
 // when importing. See testPackageInitializationImport in
-// google/protobuf/python/reflection_test.py
+// net/proto2/python/internal/reflection_test.py
 // to see why we need the alias.
 string ModuleAlias(const string& filename) {
   string module_name = ModuleName(filename);
@@ -424,7 +418,7 @@
   printer_->Print(m, file_descriptor_template);
   printer_->Indent();
   printer_->Print(
-//##!PY25      "serialized_pb=b'$value$'\n",
+      //##!PY25      "serialized_pb=b'$value$'\n",
       "serialized_pb=_b('$value$')\n",  //##PY25
       "value", strings::CHexEscape(file_descriptor_serialized_));
   if (file_->dependency_count() != 0) {
@@ -476,9 +470,9 @@
   }
 
   for (int i = 0; i < top_level_enum_values.size(); ++i) {
-    printer_->Print("$name$ = $value$\n",
-                    "name", top_level_enum_values[i].first,
-                    "value", SimpleItoa(top_level_enum_values[i].second));
+    printer_->Print("$name$ = $value$\n", "name",
+                    top_level_enum_values[i].first, "value",
+                    SimpleItoa(top_level_enum_values[i].second));
   }
   printer_->Print("\n");
 }
@@ -550,9 +544,9 @@
     const FieldDescriptor& extension_field = *file_->extension(i);
     string constant_name = extension_field.name() + "_FIELD_NUMBER";
     UpperString(&constant_name);
-    printer_->Print("$constant_name$ = $number$\n",
-      "constant_name", constant_name,
-      "number", SimpleItoa(extension_field.number()));
+    printer_->Print("$constant_name$ = $number$\n", "constant_name",
+                    constant_name, "number",
+                    SimpleItoa(extension_field.number()));
     printer_->Print("$name$ = ", "name", extension_field.name());
     PrintFieldDescriptor(extension_field, is_extension);
     printer_->Print("\n");
@@ -745,9 +739,9 @@
   for (int i = 0; i < message_descriptor.extension_range_count(); ++i) {
     const Descriptor::ExtensionRange* range =
         message_descriptor.extension_range(i);
-    printer_->Print("($start$, $end$), ",
-                    "start", SimpleItoa(range->start),
-                    "end", SimpleItoa(range->end));
+    printer_->Print("($start$, $end$), ", "start",
+                    SimpleItoa(range->start), "end",
+                    SimpleItoa(range->end));
   }
   printer_->Print("],\n");
   printer_->Print("oneofs=[\n");
@@ -1184,7 +1178,8 @@
 }
 
 bool Generator::GeneratingDescriptorProto() const {
-  return file_->name() == "google/protobuf/descriptor.proto";
+  return file_->name() == "net/proto2/proto/descriptor.proto" ||
+         file_->name() == "google/protobuf/descriptor.proto";
 }
 
 // Returns the unique Python module-level identifier given to a descriptor.
@@ -1260,10 +1255,11 @@
   int offset = file_descriptor_serialized_.find(sp);
   GOOGLE_CHECK_GE(offset, 0);
 
-  printer_->Print("serialized_start=$serialized_start$,\n"
-                  "serialized_end=$serialized_end$,\n",
-                  "serialized_start", SimpleItoa(offset),
-                  "serialized_end", SimpleItoa(offset + sp.size()));
+  printer_->Print(
+      "serialized_start=$serialized_start$,\n"
+      "serialized_end=$serialized_end$,\n",
+      "serialized_start", SimpleItoa(offset), "serialized_end",
+      SimpleItoa(offset + sp.size()));
 }
 
 namespace {
diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h
index 8e4050d..99a7383 100644
--- a/src/google/protobuf/compiler/python/python_generator.h
+++ b/src/google/protobuf/compiler/python/python_generator.h
@@ -38,8 +38,6 @@
 #include <string>
 
 #include <google/protobuf/compiler/code_generator.h>
-#include <google/protobuf/stubs/mutex.h>
-#include <google/protobuf/stubs/common.h>
 
 namespace google {
 namespace protobuf {
@@ -170,6 +168,6 @@
 }  // namespace python
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
diff --git a/src/google/protobuf/compiler/python/python_plugin_unittest.cc b/src/google/protobuf/compiler/python/python_plugin_unittest.cc
index 2f09680..d19d11f 100644
--- a/src/google/protobuf/compiler/python/python_plugin_unittest.cc
+++ b/src/google/protobuf/compiler/python/python_plugin_unittest.cc
@@ -90,7 +90,7 @@
                              "}\n",
                              true));
 
-  google::protobuf::compiler::CommandLineInterface cli;
+  compiler::CommandLineInterface cli;
   cli.SetInputsAreProtoPathRelative(true);
 
   python::Generator python_generator;
@@ -133,7 +133,7 @@
                              "message Message2 {}\n",
                              true));
 
-  google::protobuf::compiler::CommandLineInterface cli;
+  compiler::CommandLineInterface cli;
   cli.SetInputsAreProtoPathRelative(true);
   python::Generator python_generator;
   cli.RegisterGenerator("--python_out", &python_generator, "");
diff --git a/src/google/protobuf/compiler/scc.cc b/src/google/protobuf/compiler/scc.cc
new file mode 100644
index 0000000..bbdabbf
--- /dev/null
+++ b/src/google/protobuf/compiler/scc.cc
@@ -0,0 +1,111 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/compiler/scc.h>
+
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+SCCAnalyzer::NodeData SCCAnalyzer::DFS(const Descriptor* descriptor) {
+  // Must not have visited already.
+  GOOGLE_DCHECK_EQ(cache_.count(descriptor), 0);
+
+  // Mark visited by inserting in map.
+  NodeData& result = cache_[descriptor];
+  // Initialize data structures.
+  result.index = result.lowlink = index_++;
+  stack_.push_back(descriptor);
+
+  // Recurse the fields / nodes in graph
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    const Descriptor* child = descriptor->field(i)->message_type();
+    if (child) {
+      if (cache_.count(child) == 0) {
+        // unexplored node
+        NodeData child_data = DFS(child);
+        result.lowlink = std::min(result.lowlink, child_data.lowlink);
+      } else {
+        NodeData child_data = cache_[child];
+        if (child_data.scc == nullptr) {
+          // Still in the stack_ so we found a back edge
+          result.lowlink = std::min(result.lowlink, child_data.index);
+        }
+      }
+    }
+  }
+  if (result.index == result.lowlink) {
+    // This is the root of a strongly connected component
+    SCC* scc = CreateSCC();
+    while (true) {
+      const Descriptor* scc_desc = stack_.back();
+      scc->descriptors.push_back(scc_desc);
+      // Remove from stack
+      stack_.pop_back();
+      cache_[scc_desc].scc = scc;
+
+      if (scc_desc == descriptor) break;
+    }
+
+    // The order of descriptors is random and depends how this SCC was
+    // discovered. In-order to ensure maximum stability we sort it by name.
+    std::sort(scc->descriptors.begin(), scc->descriptors.end(),
+              [](const Descriptor* a, const Descriptor* b) {
+                return a->full_name() < b->full_name();
+              });
+    AddChildren(scc);
+  }
+  return result;
+}
+
+void SCCAnalyzer::AddChildren(SCC* scc) {
+  std::set<const SCC*> seen;
+  for (int i = 0; i < scc->descriptors.size(); i++) {
+    const Descriptor* descriptor = scc->descriptors[i];
+    for (int j = 0; j < descriptor->field_count(); j++) {
+      const Descriptor* child_msg = descriptor->field(j)->message_type();
+      if (child_msg) {
+        const SCC* child = GetSCC(child_msg);
+        if (child == scc) continue;
+        if (seen.insert(child).second) {
+          scc->children.push_back(child);
+        }
+      }
+    }
+  }
+}
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/compiler/scc.h b/src/google/protobuf/compiler/scc.h
new file mode 100644
index 0000000..69a47f1
--- /dev/null
+++ b/src/google/protobuf/compiler/scc.h
@@ -0,0 +1,95 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_SCC_H__
+#define GOOGLE_PROTOBUF_COMPILER_SCC_H__
+
+#include <map>
+
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+// Description of each strongly connected component. Note that the order
+// of both the descriptors in this SCC and the order of children is
+// deterministic.
+struct SCC {
+  std::vector<const Descriptor*> descriptors;
+  std::vector<const SCC*> children;
+
+  const Descriptor* GetRepresentative() const { return descriptors[0]; }
+};
+
+// This class is used for analyzing the SCC for each message, to ensure linear
+// instead of quadratic performance, if we do this per message we would get
+// O(V*(V+E)).
+class LIBPROTOC_EXPORT SCCAnalyzer {
+ public:
+  explicit SCCAnalyzer() : index_(0) {}
+
+  const SCC* GetSCC(const Descriptor* descriptor) {
+    if (cache_.count(descriptor)) return cache_[descriptor].scc;
+    return DFS(descriptor).scc;
+  }
+
+ private:
+  struct NodeData {
+    const SCC* scc;  // if null it means its still on the stack
+    int index;
+    int lowlink;
+  };
+
+  std::map<const Descriptor*, NodeData> cache_;
+  std::vector<const Descriptor*> stack_;
+  int index_;
+  std::vector<std::unique_ptr<SCC>> garbage_bin_;
+
+  SCC* CreateSCC() {
+    garbage_bin_.emplace_back(new SCC());
+    return garbage_bin_.back().get();
+  }
+
+  // Tarjan's Strongly Connected Components algo
+  NodeData DFS(const Descriptor* descriptor);
+
+  // Add the SCC's that are children of this SCC to its children.
+  void AddChildren(SCC* scc);
+
+  // This is necessary for compiler bug in msvc2015.
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SCCAnalyzer);
+};
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_COMPILER_SCC_H__
diff --git a/src/google/protobuf/compiler/subprocess.h b/src/google/protobuf/compiler/subprocess.h
index 9d980b0..dad5dab 100644
--- a/src/google/protobuf/compiler/subprocess.h
+++ b/src/google/protobuf/compiler/subprocess.h
@@ -102,6 +102,6 @@
 
 }  // namespace compiler
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__
diff --git a/src/google/protobuf/compiler/test_plugin.cc b/src/google/protobuf/compiler/test_plugin.cc
index c676ce8..4b75876 100644
--- a/src/google/protobuf/compiler/test_plugin.cc
+++ b/src/google/protobuf/compiler/test_plugin.cc
@@ -38,13 +38,24 @@
 #include <google/protobuf/compiler/plugin.h>
 #include <google/protobuf/compiler/mock_code_generator.h>
 
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+int ProtobufMain(int argc, char* argv[]) {
+  MockCodeGenerator generator("test_plugin");
+  return PluginMain(argc, argv, &generator);
+}
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
+
 int main(int argc, char* argv[]) {
 #ifdef _MSC_VER
   // Don't print a silly message or stick a modal dialog box in my face,
   // please.
   _set_abort_behavior(0, ~0);
 #endif  // !_MSC_VER
-
-  google::protobuf::compiler::MockCodeGenerator generator("test_plugin");
-  return google::protobuf::compiler::PluginMain(argc, argv, &generator);
+  return google::protobuf::compiler::ProtobufMain(argc, argv);
 }
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index fd00399..5486ab9 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -34,19 +34,17 @@
 
 #include <algorithm>
 #include <functional>
-#include <google/protobuf/stubs/hash.h>
 #include <limits>
 #include <map>
 #include <memory>
 #include <set>
 #include <string>
+#include <unordered_map>
+#include <unordered_set>
 #include <vector>
 
-#include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/mutex.h>
-#include <google/protobuf/stubs/once.h>
 #include <google/protobuf/stubs/stringprintf.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/descriptor.pb.h>
@@ -62,15 +60,17 @@
 #include <google/protobuf/unknown_field_set.h>
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/casts.h>
 
 
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/stl_util.h>
+#include <google/protobuf/stubs/hash.h>
 
 #undef PACKAGE  // autoheader #defines this.  :(
 
-namespace google {
 
+namespace google {
 namespace protobuf {
 
 struct Symbol {
@@ -399,8 +399,8 @@
 typedef std::pair<const Descriptor*, int> DescriptorIntPair;
 typedef std::pair<const EnumDescriptor*, int> EnumIntPair;
 
-#define HASH_MAP hash_map
-#define HASH_SET hash_set
+#define HASH_MAP std::unordered_map
+#define HASH_SET std::unordered_set
 #define HASH_FXN hash
 
 template<typename PairType>
@@ -489,7 +489,7 @@
     // both so the opensource protocol compiler can also compile internal
     // proto3 files with custom options. See: b/27567912
     allowed_proto3_extendees->insert(string("google.protobuf.") +
-                                      kOptionNames[i]);
+                                     kOptionNames[i]);
     // Split the word to trick the opensource processing scripts so they
     // will keep the origial package name.
     allowed_proto3_extendees->insert(string("proto") + "2." + kOptionNames[i]);
@@ -626,9 +626,9 @@
   // The string is initialized to the given value for convenience.
   string* AllocateString(const string& value);
 
-  // Allocate a GoogleOnceDynamic which will be destroyed when the pool is
+  // Allocate a internal::call_once which will be destroyed when the pool is
   // destroyed.
-  GoogleOnceDynamic* AllocateOnceDynamic();
+  internal::once_flag* AllocateOnceDynamic();
 
   // Allocate a protocol message object.  Some older versions of GCC have
   // trouble understanding explicit template instantiations in some cases, so
@@ -642,8 +642,8 @@
  private:
   std::vector<string*> strings_;    // All strings in the pool.
   std::vector<Message*> messages_;  // All messages in the pool.
-  std::vector<GoogleOnceDynamic*>
-      once_dynamics_;  // All GoogleOnceDynamics in the pool.
+  std::vector<internal::once_flag*>
+      once_dynamics_;  // All internal::call_onces in the pool.
   std::vector<FileDescriptorTables*>
       file_tables_;                 // All file tables in the pool.
   std::vector<void*> allocations_;  // All other memory allocated in the pool.
@@ -742,7 +742,7 @@
   void AddFieldByStylizedNames(const FieldDescriptor* field);
 
   // Populates p->first->locations_by_path_ from p->second.
-  // Unusual signature dictated by GoogleOnceDynamic.
+  // Unusual signature dictated by internal::call_once.
   static void BuildLocationsByPath(
       std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p);
 
@@ -769,22 +769,22 @@
   SymbolsByParentMap symbols_by_parent_;
   mutable FieldsByNameMap fields_by_lowercase_name_;
   std::unique_ptr<FieldsByNameMap> fields_by_lowercase_name_tmp_;
-  mutable GoogleOnceDynamic fields_by_lowercase_name_once_;
+  mutable internal::once_flag fields_by_lowercase_name_once_;
   mutable FieldsByNameMap fields_by_camelcase_name_;
   std::unique_ptr<FieldsByNameMap> fields_by_camelcase_name_tmp_;
-  mutable GoogleOnceDynamic fields_by_camelcase_name_once_;
+  mutable internal::once_flag fields_by_camelcase_name_once_;
   FieldsByNumberMap fields_by_number_;  // Not including extensions.
   EnumValuesByNumberMap enum_values_by_number_;
   mutable EnumValuesByNumberMap unknown_enum_values_by_number_
       GOOGLE_GUARDED_BY(unknown_enum_values_mu_);
 
   // Populated on first request to save space, hence constness games.
-  mutable GoogleOnceDynamic locations_by_path_once_;
+  mutable internal::once_flag locations_by_path_once_;
   mutable LocationsByPathMap locations_by_path_;
 
   // Mutex to protect the unknown-enum-value map due to dynamic
   // EnumValueDescriptor creation on unknown values.
-  mutable Mutex unknown_enum_values_mu_;
+  mutable internal::WrappedMutex unknown_enum_values_mu_;
 };
 
 DescriptorPool::Tables::Tables()
@@ -908,8 +908,8 @@
 
 inline Symbol FileDescriptorTables::FindNestedSymbol(
     const void* parent, const string& name) const {
-  const Symbol* result =
-    FindOrNull(symbols_by_parent_, PointerStringPair(parent, name.c_str()));
+  const Symbol* result = FindOrNull(
+      symbols_by_parent_, PointerStringPair(parent, name.c_str()));
   if (result == NULL) {
     return kNullSymbol;
   } else {
@@ -982,16 +982,18 @@
        it != fields_by_number_.end(); it++) {
     PointerStringPair lowercase_key(FindParentForFieldsByMap(it->second),
                                     it->second->lowercase_name().c_str());
-    InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, it->second);
+    InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key,
+                            it->second);
   }
 }
 
 inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName(
     const void* parent, const string& lowercase_name) const {
-  fields_by_lowercase_name_once_.Init(
+  internal::call_once(
+      fields_by_lowercase_name_once_,
       &FileDescriptorTables::FieldsByLowercaseNamesLazyInitStatic, this);
   return FindPtrOrNull(fields_by_lowercase_name_,
-                       PointerStringPair(parent, lowercase_name.c_str()));
+                            PointerStringPair(parent, lowercase_name.c_str()));
 }
 
 void FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic(
@@ -1004,21 +1006,24 @@
        it != fields_by_number_.end(); it++) {
     PointerStringPair camelcase_key(FindParentForFieldsByMap(it->second),
                                     it->second->camelcase_name().c_str());
-    InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, it->second);
+    InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key,
+                            it->second);
   }
 }
 
 inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName(
     const void* parent, const string& camelcase_name) const {
-  fields_by_camelcase_name_once_.Init(
-      &FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic, this);
+  internal::call_once(
+      fields_by_camelcase_name_once_,
+      FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic, this);
   return FindPtrOrNull(fields_by_camelcase_name_,
-                       PointerStringPair(parent, camelcase_name.c_str()));
+                            PointerStringPair(parent, camelcase_name.c_str()));
 }
 
 inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber(
     const EnumDescriptor* parent, int number) const {
-  return FindPtrOrNull(enum_values_by_number_, std::make_pair(parent, number));
+  return FindPtrOrNull(enum_values_by_number_,
+                            std::make_pair(parent, number));
 }
 
 inline const EnumValueDescriptor*
@@ -1026,8 +1031,8 @@
     const EnumDescriptor* parent, int number) const {
   // First try, with map of compiled-in values.
   {
-    const EnumValueDescriptor* desc =
-        FindPtrOrNull(enum_values_by_number_, std::make_pair(parent, number));
+    const EnumValueDescriptor* desc = FindPtrOrNull(
+        enum_values_by_number_, std::make_pair(parent, number));
     if (desc != NULL) {
       return desc;
     }
@@ -1068,7 +1073,7 @@
     result->type_ = parent;
     result->options_ = &EnumValueOptions::default_instance();
     InsertIfNotPresent(&unknown_enum_values_by_number_,
-                       std::make_pair(parent, number), result);
+                            std::make_pair(parent, number), result);
     return result;
   }
 }
@@ -1134,16 +1139,16 @@
   // entries from fields_by_number_.
 
   PointerStringPair lowercase_key(parent, field->lowercase_name().c_str());
-  if (!InsertIfNotPresent(fields_by_lowercase_name_tmp_.get(), lowercase_key,
-                          field)) {
+  if (!InsertIfNotPresent(fields_by_lowercase_name_tmp_.get(),
+                               lowercase_key, field)) {
     InsertIfNotPresent(
         &fields_by_lowercase_name_, lowercase_key,
         FindPtrOrNull(*fields_by_lowercase_name_tmp_, lowercase_key));
   }
 
   PointerStringPair camelcase_key(parent, field->camelcase_name().c_str());
-  if (!InsertIfNotPresent(fields_by_camelcase_name_tmp_.get(), camelcase_key,
-                          field)) {
+  if (!InsertIfNotPresent(fields_by_camelcase_name_tmp_.get(),
+                               camelcase_key, field)) {
     InsertIfNotPresent(
         &fields_by_camelcase_name_, camelcase_key,
         FindPtrOrNull(*fields_by_camelcase_name_tmp_, camelcase_key));
@@ -1189,8 +1194,8 @@
   return result;
 }
 
-GoogleOnceDynamic* DescriptorPool::Tables::AllocateOnceDynamic() {
-  GoogleOnceDynamic* result = new GoogleOnceDynamic();
+internal::once_flag* DescriptorPool::Tables::AllocateOnceDynamic() {
+  internal::once_flag* result = new internal::once_flag();
   once_dynamics_.push_back(result);
   return result;
 }
@@ -1232,7 +1237,8 @@
     const std::vector<int>& path, const SourceCodeInfo* info) const {
   std::pair<const FileDescriptorTables*, const SourceCodeInfo*> p(
       std::make_pair(this, info));
-  locations_by_path_once_.Init(&FileDescriptorTables::BuildLocationsByPath, &p);
+  internal::call_once(locations_by_path_once_,
+                      FileDescriptorTables::BuildLocationsByPath, &p);
   return FindPtrOrNull(locations_by_path_, Join(path, ","));
 }
 
@@ -1255,7 +1261,7 @@
 
 DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database,
                                ErrorCollector* error_collector)
-  : mutex_(new Mutex),
+  : mutex_(new internal::WrappedMutex),
     fallback_database_(fallback_database),
     default_error_collector_(error_collector),
     underlay_(NULL),
@@ -1307,6 +1313,7 @@
 
 namespace {
 
+
 EncodedDescriptorDatabase* GeneratedDatabase() {
   static auto generated_database =
       internal::OnShutdownDelete(new EncodedDescriptorDatabase());
@@ -1331,6 +1338,8 @@
   return internal_generated_pool();
 }
 
+
+
 void DescriptorPool::InternalAddGeneratedFile(
     const void* encoded_file_descriptor, int size) {
   // So, this function is called in the process of initializing the
@@ -1760,7 +1769,7 @@
     DescriptorProto_ExtensionRange* proto) const {
   proto->set_start(this->start);
   proto->set_end(this->end);
-  if (options_ != &google::protobuf::ExtensionRangeOptions::default_instance()) {
+  if (options_ != &ExtensionRangeOptions::default_instance()) {
     *proto->mutable_options() = *options_;
   }
 }
@@ -2079,9 +2088,9 @@
   // Some compilers do not allow static_cast directly between two enum types,
   // so we must cast to int first.
   proto->set_label(static_cast<FieldDescriptorProto::Label>(
-                     implicit_cast<int>(label())));
+      ::google::protobuf::implicit_cast<int>(label())));
   proto->set_type(static_cast<FieldDescriptorProto::Type>(
-                    implicit_cast<int>(type())));
+      ::google::protobuf::implicit_cast<int>(type())));
 
   if (is_extension()) {
     if (!containing_type()->is_unqualified_placeholder_) {
@@ -2257,9 +2266,8 @@
     const Descriptor* option_descriptor =
         pool->FindMessageTypeByName(options.GetDescriptor()->full_name());
     if (option_descriptor == NULL) {
-      // google/protobuf/descriptor.proto is not in the pool. This means no
-      // custom options are used so we are safe to proceed with the compiled
-      // options message type.
+      // descriptor.proto is not in the pool. This means no custom options are
+      // used so we are safe to proceed with the compiled options message type.
       return RetrieveOptionsAssumingRightPool(depth, options, option_entries);
     }
     DynamicMessageFactory factory;
@@ -2919,7 +2927,7 @@
 
 bool FileDescriptor::GetSourceLocation(const std::vector<int>& path,
                                        SourceLocation* out_location) const {
-  GOOGLE_CHECK_NOTNULL(out_location);
+  GOOGLE_CHECK(out_location != nullptr);
   if (source_code_info_) {
     if (const SourceCodeInfo_Location* loc =
         tables_->GetSourceLocation(path, source_code_info_)) {
@@ -3071,17 +3079,14 @@
 // pointers in the original options, not the mutable copy). The Message must be
 // one of the Options messages in descriptor.proto.
 struct OptionsToInterpret {
-  OptionsToInterpret(const string& ns,
-                     const string& el,
-                     std::vector<int>& path,
-                     const Message* orig_opt,
+  OptionsToInterpret(const string& ns, const string& el,
+                     const std::vector<int>& path, const Message* orig_opt,
                      Message* opt)
       : name_scope(ns),
         element_name(el),
         element_path(path),
         original_options(orig_opt),
-        options(opt) {
-  }
+        options(opt) {}
   string name_scope;
   string element_name;
   std::vector<int> element_path;
@@ -3249,20 +3254,19 @@
   // descriptor. Remembers its uninterpreted options, to be interpreted
   // later. DescriptorT must be one of the Descriptor messages from
   // descriptor.proto.
-  template<class DescriptorT> void AllocateOptions(
-      const typename DescriptorT::OptionsType& orig_options,
-      DescriptorT* descriptor, int options_field_tag);
+  template <class DescriptorT>
+  void AllocateOptions(const typename DescriptorT::OptionsType& orig_options,
+                       DescriptorT* descriptor, int options_field_tag);
   // Specialization for FileOptions.
   void AllocateOptions(const FileOptions& orig_options,
                        FileDescriptor* descriptor);
 
   // Implementation for AllocateOptions(). Don't call this directly.
-  template<class DescriptorT> void AllocateOptionsImpl(
-      const string& name_scope,
-      const string& element_name,
+  template <class DescriptorT>
+  void AllocateOptionsImpl(
+      const string& name_scope, const string& element_name,
       const typename DescriptorT::OptionsType& orig_options,
-      DescriptorT* descriptor,
-      std::vector<int>& options_path);
+      DescriptorT* descriptor, const std::vector<int>& options_path);
 
   // These methods all have the same signature for the sake of the BUILD_ARRAY
   // macro, below.
@@ -3364,8 +3368,9 @@
     // location path to the uninterpreted option, and options_path is the
     // source location path to the options message. The location paths are
     // recorded and then used in UpdateSourceCodeInfo.
-    bool InterpretSingleOption(Message* options, std::vector<int>& src_path,
-                               std::vector<int>& options_path);
+    bool InterpretSingleOption(Message* options,
+                               const std::vector<int>& src_path,
+                               const std::vector<int>& options_path);
 
     // Adds the uninterpreted_option to the given options message verbatim.
     // Used when AllowUnknownDependencies() is in effect and we can't find
@@ -4065,7 +4070,8 @@
 
 // This generic implementation is good for all descriptors except
 // FileDescriptor.
-template<class DescriptorT> void DescriptorBuilder::AllocateOptions(
+template <class DescriptorT>
+void DescriptorBuilder::AllocateOptions(
     const typename DescriptorT::OptionsType& orig_options,
     DescriptorT* descriptor, int options_field_tag) {
   std::vector<int> options_path;
@@ -4085,18 +4091,25 @@
                       orig_options, descriptor, options_path);
 }
 
-template<class DescriptorT> void DescriptorBuilder::AllocateOptionsImpl(
-    const string& name_scope,
-    const string& element_name,
+template <class DescriptorT>
+void DescriptorBuilder::AllocateOptionsImpl(
+    const string& name_scope, const string& element_name,
     const typename DescriptorT::OptionsType& orig_options,
-    DescriptorT* descriptor,
-    std::vector<int>& options_path) {
+    DescriptorT* descriptor, const std::vector<int>& options_path) {
   // We need to use a dummy pointer to work around a bug in older versions of
   // GCC.  Otherwise, the following two lines could be replaced with:
   //   typename DescriptorT::OptionsType* options =
   //       tables_->AllocateMessage<typename DescriptorT::OptionsType>();
   typename DescriptorT::OptionsType* const dummy = NULL;
   typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy);
+
+  if (!orig_options.IsInitialized()) {
+    AddError(name_scope + "." + element_name, orig_options,
+             DescriptorPool::ErrorCollector::OPTION_NAME,
+             "Uninterpreted option is missing name or value.");
+    return;
+  }
+
   // Avoid using MergeFrom()/CopyFrom() in this class to make it -fno-rtti
   // friendly. Without RTTI, MergeFrom() and CopyFrom() will fallback to the
   // reflection based method, which requires the Descriptor. However, we are in
@@ -4112,13 +4125,11 @@
   // OptionsType::GetDescriptor() to be called which may then deadlock since
   // we're still trying to build it.
   if (options->uninterpreted_option_size() > 0) {
-    options_to_interpret_.push_back(
-        OptionsToInterpret(name_scope, element_name, options_path,
-            &orig_options, options));
+    options_to_interpret_.push_back(OptionsToInterpret(
+        name_scope, element_name, options_path, &orig_options, options));
   }
 }
 
-
 // A common pattern:  We want to convert a repeated field in the descriptor
 // to an array of values, calling some method to build each value.
 #define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT)             \
@@ -4252,7 +4263,7 @@
 
   result->is_placeholder_ = false;
   result->finished_building_ = false;
-  SourceCodeInfo *info = NULL;
+  SourceCodeInfo* info = nullptr;
   if (proto.has_source_code_info()) {
     info = tables_->AllocateMessage<SourceCodeInfo>();
     info->CopyFrom(proto.source_code_info());
@@ -4452,8 +4463,7 @@
       option_interpreter.InterpretOptions(&(*iter));
     }
     options_to_interpret_.clear();
-
-    if (info != NULL) {
+    if (info != nullptr) {
       option_interpreter.UpdateSourceCodeInfo(info);
     }
   }
@@ -4528,7 +4538,7 @@
     result->options_ = NULL;  // Will set to default_instance later.
   } else {
     AllocateOptions(proto.options(), result,
-        DescriptorProto::kOptionsFieldNumber);
+                    DescriptorProto::kOptionsFieldNumber);
   }
 
   AddSymbol(result->full_name(), parent, result->name(),
@@ -4669,10 +4679,10 @@
 
   // Some compilers do not allow static_cast directly between two enum types,
   // so we must cast to int first.
-  result->type_  = static_cast<FieldDescriptor::Type>(
-                     implicit_cast<int>(proto.type()));
+  result->type_ = static_cast<FieldDescriptor::Type>(
+      ::google::protobuf::implicit_cast<int>(proto.type()));
   result->label_ = static_cast<FieldDescriptor::Label>(
-                     implicit_cast<int>(proto.label()));
+      ::google::protobuf::implicit_cast<int>(proto.label()));
 
   // An extension cannot have a required field (b/13365836).
   if (result->is_extension_ &&
@@ -4909,7 +4919,7 @@
     result->options_ = NULL;  // Will set to default_instance later.
   } else {
     AllocateOptions(proto.options(), result,
-        FieldDescriptorProto::kOptionsFieldNumber);
+                    FieldDescriptorProto::kOptionsFieldNumber);
   }
 
 
@@ -4948,7 +4958,8 @@
     options_path.push_back(DescriptorProto::kExtensionRangeFieldNumber);
     // find index of this extension range in order to compute path
     int index;
-    for (index = 0; parent->extension_ranges_ + index != result; index++);
+    for (index = 0; parent->extension_ranges_ + index != result; index++) {
+    }
     options_path.push_back(index);
     options_path.push_back(DescriptorProto_ExtensionRange::kOptionsFieldNumber);
     AllocateOptionsImpl(parent->full_name(), parent->full_name(),
@@ -5005,7 +5016,7 @@
     result->options_ = NULL;  // Will set to default_instance later.
   } else {
     AllocateOptions(proto.options(), result,
-        OneofDescriptorProto::kOptionsFieldNumber);
+                    OneofDescriptorProto::kOptionsFieldNumber);
   }
 
   AddSymbol(result->full_name(), parent, result->name(),
@@ -5041,13 +5052,12 @@
   //     NAME_TYPE_LAST_NAME = 2,
   //   }
   PrefixRemover remover(result->name());
-  std::map<string, const google::protobuf::EnumValueDescriptor*> values;
+  std::map<string, const EnumValueDescriptor*> values;
   for (int i = 0; i < result->value_count(); i++) {
-    const google::protobuf::EnumValueDescriptor* value = result->value(i);
+    const EnumValueDescriptor* value = result->value(i);
     string stripped =
         EnumValueToPascalCase(remover.MaybeRemove(value->name()));
-    std::pair<std::map<string, const google::protobuf::EnumValueDescriptor*>::iterator,
-              bool>
+    std::pair<std::map<string, const EnumValueDescriptor*>::iterator, bool>
         insert_result = values.insert(std::make_pair(stripped, value));
     bool inserted = insert_result.second;
 
@@ -5123,7 +5133,7 @@
     result->options_ = NULL;  // Will set to default_instance later.
   } else {
     AllocateOptions(proto.options(), result,
-        EnumDescriptorProto::kOptionsFieldNumber);
+                    EnumDescriptorProto::kOptionsFieldNumber);
   }
 
   AddSymbol(result->full_name(), parent, result->name(),
@@ -5201,7 +5211,7 @@
     result->options_ = NULL;  // Will set to default_instance later.
   } else {
     AllocateOptions(proto.options(), result,
-        EnumValueDescriptorProto::kOptionsFieldNumber);
+                    EnumValueDescriptorProto::kOptionsFieldNumber);
   }
 
   // Again, enum values are weird because we makes them appear as siblings
@@ -5269,7 +5279,7 @@
     result->options_ = NULL;  // Will set to default_instance later.
   } else {
     AllocateOptions(proto.options(), result,
-        ServiceDescriptorProto::kOptionsFieldNumber);
+                    ServiceDescriptorProto::kOptionsFieldNumber);
   }
 
   AddSymbol(result->full_name(), NULL, result->name(),
@@ -5298,7 +5308,7 @@
     result->options_ = NULL;  // Will set to default_instance later.
   } else {
     AllocateOptions(proto.options(), result,
-        MethodDescriptorProto::kOptionsFieldNumber);
+                    MethodDescriptorProto::kOptionsFieldNumber);
   }
 
   result->client_streaming_ = proto.client_streaming();
@@ -6017,6 +6027,23 @@
 
   ValidateJSType(field, proto);
 
+  // json_name option is not allowed on extension fields. Note that the
+  // json_name field in FieldDescriptorProto is always populated by protoc
+  // when it sends descriptor data to plugins (caculated from field name if
+  // the option is not explicitly set) so we can't rely on its presence to
+  // determine whether the json_name option is set on the field. Here we
+  // compare it against the default calculated json_name value and consider
+  // the option set if they are different. This won't catch the case when
+  // an user explicitly sets json_name to the default value, but should be
+  // good enough to catch common misuses.
+  if (field->is_extension() &&
+      (field->has_json_name() &&
+       field->json_name() != ToJsonName(field->name()))) {
+    AddError(field->full_name(), proto,
+             DescriptorPool::ErrorCollector::OPTION_NAME,
+             "option json_name is not allowed on extension fields.");
+  }
+
 }
 
 void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm,
@@ -6308,25 +6335,31 @@
     // If they are not known, that's OK too. They will get reparsed into the
     // UnknownFieldSet and wait there until the message is parsed by something
     // that does know about the options.
+
+    // Keep the unparsed options around in case the reparsing fails.
+    std::unique_ptr<Message> unparsed_options(options->New());
+    options->GetReflection()->Swap(unparsed_options.get(), options);
+
     string buf;
-    GOOGLE_CHECK(options->AppendPartialToString(&buf))
-        << "Protocol message could not be serialized.";
-    GOOGLE_CHECK(options->ParsePartialFromString(buf))
-        << "Protocol message serialized itself in invalid fashion.";
-    if (!options->IsInitialized()) {
-      builder_->AddWarning(
+    if (!unparsed_options->AppendToString(&buf) ||
+        !options->ParseFromString(buf)) {
+      builder_->AddError(
           options_to_interpret->element_name, *original_options,
           DescriptorPool::ErrorCollector::OTHER,
-          "Options could not be fully parsed using the proto descriptors "
-          "compiled into this binary. Missing required fields: " +
-          options->InitializationErrorString());
+          "Some options could not be correctly parsed using the proto "
+          "descriptors compiled into this binary.\n"
+          "Unparsed options: " + unparsed_options->ShortDebugString() + "\n"
+          "Parsing attempt:  " + options->ShortDebugString());
+      // Restore the unparsed options.
+      options->GetReflection()->Swap(unparsed_options.get(), options);
     }
   }
   return !failed;
 }
 
 bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
-    Message* options, std::vector<int>& src_path, std::vector<int>& opts_path) {
+    Message* options, const std::vector<int>& src_path,
+    const std::vector<int>& options_path) {
   // First do some basic validation.
   if (uninterpreted_option_->name_size() == 0) {
     // This should never happen unless the parser has gone seriously awry or
@@ -6340,9 +6373,9 @@
 
   const Descriptor* options_descriptor = NULL;
   // Get the options message's descriptor from the builder's pool, so that we
-  // get the version that knows about any extension options declared in the
-  // file we're currently building. The descriptor should be there as long as
-  // the file we're building imported "google/protobuf/descriptors.proto".
+  // get the version that knows about any extension options declared in the file
+  // we're currently building. The descriptor should be there as long as the
+  // file we're building imported descriptor.proto.
 
   // Note that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not
   // DescriptorPool::FindMessageTypeByName() because we're already holding the
@@ -6372,7 +6405,7 @@
   std::vector<const FieldDescriptor*> intermediate_fields;
   string debug_msg_name = "";
 
-  std::vector<int> dest_path = opts_path;
+  std::vector<int> dest_path = options_path;
 
   for (int i = 0; i < uninterpreted_option_->name_size(); ++i) {
     const string& name_part = uninterpreted_option_->name(i).name_part();
@@ -6417,7 +6450,9 @@
             debug_msg_name.substr(1) +
             "\") to start from the outermost scope.");
       } else {
-        return AddNameError("Option \"" + debug_msg_name + "\" unknown.");
+        return AddNameError(
+          "Option \"" + debug_msg_name + "\" unknown. Ensure that your proto" +
+          " definition file imports the proto which defines the option.");
       }
     } else if (field->containing_type() != descriptor) {
       if (get_is_placeholder(field->containing_type())) {
@@ -6442,7 +6477,7 @@
 
       if (i < uninterpreted_option_->name_size() - 1) {
         if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
-          return AddNameError("Option \"" +  debug_msg_name +
+          return AddNameError("Option \"" + debug_msg_name +
                               "\" is an atomic type, not a message.");
         } else if (field->is_repeated()) {
           return AddNameError("Option field \"" + debug_msg_name +
@@ -6531,7 +6566,6 @@
 
 void DescriptorBuilder::OptionInterpreter::UpdateSourceCodeInfo(
     SourceCodeInfo* info) {
-
   if (interpreted_paths_.empty()) {
     // nothing to do!
     return;
@@ -6556,7 +6590,6 @@
 
   for (RepeatedPtrField<SourceCodeInfo_Location>::iterator loc = locs->begin();
        loc != locs->end(); loc++) {
-
     if (matched) {
       // see if this location is in the range to remove
       bool loc_matches = true;
@@ -6590,7 +6623,7 @@
     if (entry == interpreted_paths_.end()) {
       // not a match
       if (copying) {
-        new_locs.Add()->CopyFrom(*loc);
+        *new_locs.Add() = *loc;
       }
       continue;
     }
@@ -6602,14 +6635,15 @@
       copying = true;
       new_locs.Reserve(locs->size());
       for (RepeatedPtrField<SourceCodeInfo_Location>::iterator it =
-           locs->begin(); it != loc; it++) {
-        new_locs.Add()->CopyFrom(*it);
+               locs->begin();
+           it != loc; it++) {
+        *new_locs.Add() = *it;
       }
     }
 
     // add replacement and update its path
     SourceCodeInfo_Location* replacement = new_locs.Add();
-    replacement->CopyFrom(*loc);
+    *replacement = *loc;
     replacement->clear_path();
     for (std::vector<int>::iterator rit = entry->second.begin();
          rit != entry->second.end(); rit++) {
@@ -6789,7 +6823,7 @@
                              option_field->full_name() + "\".");
       }
       unknown_fields->AddFixed32(option_field->number(),
-          google::protobuf::internal::WireFormatLite::EncodeFloat(value));
+                                 internal::WireFormatLite::EncodeFloat(value));
       break;
     }
 
@@ -6806,7 +6840,7 @@
                              option_field->full_name() + "\".");
       }
       unknown_fields->AddFixed64(option_field->number(),
-          google::protobuf::internal::WireFormatLite::EncodeDouble(value));
+                                 internal::WireFormatLite::EncodeDouble(value));
       break;
     }
 
@@ -6905,8 +6939,8 @@
  public:
   DescriptorBuilder* builder_;
 
-  virtual const FieldDescriptor* FindExtension(
-      Message* message, const string& name) const override {
+  const FieldDescriptor* FindExtension(Message* message,
+                                       const string& name) const override {
     assert_mutex_held(builder_->pool_);
     const Descriptor* descriptor = message->GetDescriptor();
     Symbol result = builder_->LookupSymbolNoPlaceholder(
@@ -6943,7 +6977,7 @@
  public:
   string error_;
 
-  virtual void AddError(int /* line */, int /* column */,
+  void AddError(int /* line */, int /* column */,
                 const string& message) override {
     if (!error_.empty()) {
       error_ += "; ";
@@ -6951,12 +6985,12 @@
     error_ += message;
   }
 
-  virtual void AddWarning(int /* line */, int /* column */,
+  void AddWarning(int /* line */, int /* column */,
                   const string& /* message */) override {
     // Ignore warnings
   }
 };
-}
+}  // namespace
 
 // We construct a dynamic message of the type corresponding to
 // option_field, parse the supplied text-format string into this
@@ -7017,8 +7051,8 @@
       break;
 
     case FieldDescriptor::TYPE_SINT32:
-      unknown_fields->AddVarint(number,
-          google::protobuf::internal::WireFormatLite::ZigZagEncode32(value));
+      unknown_fields->AddVarint(
+          number, internal::WireFormatLite::ZigZagEncode32(value));
       break;
 
     default:
@@ -7039,8 +7073,8 @@
       break;
 
     case FieldDescriptor::TYPE_SINT64:
-      unknown_fields->AddVarint(number,
-          google::protobuf::internal::WireFormatLite::ZigZagEncode64(value));
+      unknown_fields->AddVarint(
+          number, internal::WireFormatLite::ZigZagEncode64(value));
       break;
 
     default:
@@ -7177,25 +7211,25 @@
 }
 
 // message_type(), enum_type(), default_value_enum(), and type()
-// all share the same GoogleOnceDynamic init path to do lazy
+// all share the same internal::call_once init path to do lazy
 // import building and cross linking of a field of a message.
 const Descriptor* FieldDescriptor::message_type() const {
   if (type_once_) {
-    type_once_->Init(&FieldDescriptor::TypeOnceInit, this);
+    internal::call_once(*type_once_, FieldDescriptor::TypeOnceInit, this);
   }
   return message_type_;
 }
 
 const EnumDescriptor* FieldDescriptor::enum_type() const {
   if (type_once_) {
-    type_once_->Init(&FieldDescriptor::TypeOnceInit, this);
+    internal::call_once(*type_once_, FieldDescriptor::TypeOnceInit, this);
   }
   return enum_type_;
 }
 
 const EnumValueDescriptor* FieldDescriptor::default_value_enum() const {
   if (type_once_) {
-    type_once_->Init(&FieldDescriptor::TypeOnceInit, this);
+    internal::call_once(*type_once_, FieldDescriptor::TypeOnceInit, this);
   }
   return default_value_enum_;
 }
@@ -7216,8 +7250,9 @@
 const FileDescriptor* FileDescriptor::dependency(int index) const {
   if (dependencies_once_) {
     // Do once init for all indicies, as it's unlikely only a single index would
-    // be called, and saves on GoogleOnceDynamic allocations.
-    dependencies_once_->Init(&FileDescriptor::DependenciesOnceInit, this);
+    // be called, and saves on internal::call_once allocations.
+    internal::call_once(*dependencies_once_,
+                        FileDescriptor::DependenciesOnceInit, this);
   }
   return dependencies_[index];
 }
@@ -7255,7 +7290,7 @@
 
 void LazyDescriptor::Once() {
   if (once_) {
-    once_->Init(&LazyDescriptor::OnceStatic, this);
+    internal::call_once(*once_, LazyDescriptor::OnceStatic, this);
   }
 }
 
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h
index 115d4dd..08caab2 100644
--- a/src/google/protobuf/descriptor.h
+++ b/src/google/protobuf/descriptor.h
@@ -123,6 +123,10 @@
 // Defined in command_line_interface.cc
 namespace compiler {
 class CommandLineInterface;
+namespace cpp {
+// Defined in helpers.h
+class Formatter;
+}  // namespace cpp
 }  // namespace compiler
 
 namespace descriptor_unittest {
@@ -210,7 +214,7 @@
 
   const Descriptor* descriptor_;
   const string* name_;
-  GoogleOnceDynamic* once_;
+  internal::once_flag* once_;
   const FileDescriptor* file_;
 };
 }  // namespace internal
@@ -245,9 +249,8 @@
 
   // Get options for this message type.  These are specified in the .proto file
   // by placing lines like "option foo = 1234;" in the message definition.
-  // Allowed options are defined by MessageOptions in
-  // google/protobuf/descriptor.proto, and any available extensions of that
-  // message.
+  // Allowed options are defined by MessageOptions in descriptor.proto, and any
+  // available extensions of that message.
   const MessageOptions& options() const;
 
   // Write the contents of this Descriptor into the given DescriptorProto.
@@ -420,10 +423,11 @@
   typedef MessageOptions OptionsType;
 
   // Allows tests to test CopyTo(proto, true).
-  friend class ::google::protobuf::descriptor_unittest::DescriptorTest;
+  friend class descriptor_unittest::DescriptorTest;
 
   // Allows access to GetLocationPath for annotations.
-  friend class ::google::protobuf::io::Printer;
+  friend class io::Printer;
+  friend class compiler::cpp::Formatter;
 
   // Fill the json_name field of FieldDescriptorProto.
   void CopyJsonNameTo(DescriptorProto* proto) const;
@@ -683,9 +687,8 @@
   // Get the FieldOptions for this field.  This includes things listed in
   // square brackets after the field definition.  E.g., the field:
   //   optional string text = 1 [ctype=CORD];
-  // has the "ctype" option set.  Allowed options are defined by FieldOptions
-  // in google/protobuf/descriptor.proto, and any available extensions of that
-  // message.
+  // has the "ctype" option set.  Allowed options are defined by FieldOptions in
+  // descriptor.proto, and any available extensions of that message.
   const FieldOptions& options() const;
 
   // See Descriptor::CopyTo().
@@ -720,7 +723,8 @@
   typedef FieldOptions OptionsType;
 
   // Allows access to GetLocationPath for annotations.
-  friend class ::google::protobuf::io::Printer;
+  friend class io::Printer;
+  friend class compiler::cpp::Formatter;
 
   // Fill the json_name field of FieldDescriptorProto.
   void CopyJsonNameTo(FieldDescriptorProto* proto) const;
@@ -753,7 +757,7 @@
   // Otherwise, it has the same value as camelcase_name_.
   const string* json_name_;
   const FileDescriptor* file_;
-  GoogleOnceDynamic* type_once_;
+  internal::once_flag* type_once_;
   static void TypeOnceInit(const FieldDescriptor* to_init);
   void InternalTypeOnceInit() const;
   mutable Type type_;
@@ -850,7 +854,8 @@
   typedef OneofOptions OptionsType;
 
   // Allows access to GetLocationPath for annotations.
-  friend class ::google::protobuf::io::Printer;
+  friend class io::Printer;
+  friend class compiler::cpp::Formatter;
 
   // See Descriptor::DebugString().
   void DebugString(int depth, string* contents,
@@ -915,8 +920,8 @@
 
   // Get options for this enum type.  These are specified in the .proto file by
   // placing lines like "option foo = 1234;" in the enum definition.  Allowed
-  // options are defined by EnumOptions in google/protobuf/descriptor.proto,
-  // and any available extensions of that message.
+  // options are defined by EnumOptions in descriptor.proto, and any available
+  // extensions of that message.
   const EnumOptions& options() const;
 
   // See Descriptor::CopyTo().
@@ -975,7 +980,8 @@
   typedef EnumOptions OptionsType;
 
   // Allows access to GetLocationPath for annotations.
-  friend class ::google::protobuf::io::Printer;
+  friend class io::Printer;
+  friend class compiler::cpp::Formatter;
 
   // Looks up a value by number.  If the value does not exist, dynamically
   // creates a new EnumValueDescriptor for that value, assuming that it was
@@ -1055,11 +1061,10 @@
   // The type of this value.  Never NULL.
   const EnumDescriptor* type() const;
 
-  // Get options for this enum value.  These are specified in the .proto file
-  // by adding text like "[foo = 1234]" after an enum value definition.
-  // Allowed options are defined by EnumValueOptions in
-  // google/protobuf/descriptor.proto, and any available extensions of that
-  // message.
+  // Get options for this enum value.  These are specified in the .proto file by
+  // adding text like "[foo = 1234]" after an enum value definition.  Allowed
+  // options are defined by EnumValueOptions in descriptor.proto, and any
+  // available extensions of that message.
   const EnumValueOptions& options() const;
 
   // See Descriptor::CopyTo().
@@ -1083,7 +1088,8 @@
   typedef EnumValueOptions OptionsType;
 
   // Allows access to GetLocationPath for annotations.
-  friend class ::google::protobuf::io::Printer;
+  friend class io::Printer;
+  friend class compiler::cpp::Formatter;
 
   // See Descriptor::DebugString().
   void DebugString(int depth, string *contents,
@@ -1129,9 +1135,8 @@
 
   // Get options for this service type.  These are specified in the .proto file
   // by placing lines like "option foo = 1234;" in the service definition.
-  // Allowed options are defined by ServiceOptions in
-  // google/protobuf/descriptor.proto, and any available extensions of that
-  // message.
+  // Allowed options are defined by ServiceOptions in descriptor.proto, and any
+  // available extensions of that message.
   const ServiceOptions& options() const;
 
   // The number of methods this service defines.
@@ -1163,7 +1168,8 @@
   typedef ServiceOptions OptionsType;
 
   // Allows access to GetLocationPath for annotations.
-  friend class ::google::protobuf::io::Printer;
+  friend class io::Printer;
+  friend class compiler::cpp::Formatter;
 
   // See Descriptor::DebugString().
   void DebugString(string *contents, const DebugStringOptions& options) const;
@@ -1222,8 +1228,7 @@
   // Get options for this method.  These are specified in the .proto file by
   // placing lines like "option foo = 1234;" in curly-braces after a method
   // declaration.  Allowed options are defined by MethodOptions in
-  // google/protobuf/descriptor.proto, and any available extensions of that
-  // message.
+  // descriptor.proto, and any available extensions of that message.
   const MethodOptions& options() const;
 
   // See Descriptor::CopyTo().
@@ -1247,7 +1252,8 @@
   typedef MethodOptions OptionsType;
 
   // Allows access to GetLocationPath for annotations.
-  friend class ::google::protobuf::io::Printer;
+  friend class io::Printer;
+  friend class compiler::cpp::Formatter;
 
   // See Descriptor::DebugString().
   void DebugString(int depth, string *contents,
@@ -1283,7 +1289,7 @@
 class LIBPROTOBUF_EXPORT FileDescriptor {
  public:
   // The filename, relative to the source tree.
-  // e.g. "google/protobuf/descriptor.proto"
+  // e.g. "foo/bar/baz.proto"
   const string& name() const;
 
   // The package, e.g. "google.protobuf.compiler".
@@ -1345,8 +1351,7 @@
   // Get options for this file.  These are specified in the .proto file by
   // placing lines like "option foo = 1234;" at the top level, outside of any
   // other definitions.  Allowed options are defined by FileOptions in
-  // google/protobuf/descriptor.proto, and any available extensions of that
-  // message.
+  // descriptor.proto, and any available extensions of that message.
   const FileOptions& options() const;
 
   // Syntax of this file.
@@ -1417,7 +1422,7 @@
   const string* name_;
   const string* package_;
   const DescriptorPool* pool_;
-  GoogleOnceDynamic* dependencies_once_;
+  internal::once_flag* dependencies_once_;
   static void DependenciesOnceInit(const FileDescriptor* to_init);
   void InternalDependenciesOnceInit() const;
 
@@ -1793,7 +1798,7 @@
 
   // If fallback_database_ is NULL, this is NULL.  Otherwise, this is a mutex
   // which must be locked while accessing tables_.
-  Mutex* mutex_;
+  internal::WrappedMutex* mutex_;
 
   // See constructor.
   DescriptorDatabase* fallback_database_;
@@ -2000,7 +2005,7 @@
 
 inline FieldDescriptor::Type FieldDescriptor::type() const {
   if (type_once_) {
-    type_once_->Init(&FieldDescriptor::TypeOnceInit, this);
+    internal::call_once(*type_once_, &FieldDescriptor::TypeOnceInit, this);
   }
   return type_;
 }
@@ -2133,6 +2138,6 @@
 }
 
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_DESCRIPTOR_H__
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index f3522ec..01accf9 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -6,8 +6,8 @@
 #include <algorithm>
 
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
@@ -18,175 +18,146 @@
 #include "third_party/protobuf/version.h"
 #endif
 // @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
 
-namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto {
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_DescriptorProto_ReservedRange;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_EnumDescriptorProto_EnumReservedRange;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_GeneratedCodeInfo_Annotation;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_SourceCodeInfo_Location;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_UninterpretedOption_NamePart;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_DescriptorProto_ExtensionRange;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EnumOptions;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValueDescriptorProto;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValueOptions;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_ExtensionRangeOptions;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_FieldDescriptorProto;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_FieldOptions;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_FileOptions;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_MessageOptions;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_MethodDescriptorProto;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_MethodOptions;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_OneofDescriptorProto;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_OneofOptions;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_ServiceOptions;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_SourceCodeInfo;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_UninterpretedOption;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_ServiceDescriptorProto;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<3> scc_info_EnumDescriptorProto;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<6> scc_info_DescriptorProto;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<6> scc_info_FileDescriptorProto;
-}  // namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_DescriptorProto_ReservedRange_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_EnumDescriptorProto_EnumReservedRange_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_GeneratedCodeInfo_Annotation_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_SourceCodeInfo_Location_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_UninterpretedOption_NamePart_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_DescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EnumOptions_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValueDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValueOptions_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_ExtensionRangeOptions_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_FieldDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_FieldOptions_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_FileOptions_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_MessageOptions_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_MethodDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_MethodOptions_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_OneofDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_OneofOptions_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_ServiceOptions_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_SourceCodeInfo_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_ServiceDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<3> scc_info_EnumDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<6> scc_info_DescriptorProto_google_2fprotobuf_2fdescriptor_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<6> scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto;
 namespace google {
 namespace protobuf {
 class FileDescriptorSetDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<FileDescriptorSet>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<FileDescriptorSet> _instance;
 } _FileDescriptorSet_default_instance_;
 class FileDescriptorProtoDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<FileDescriptorProto>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<FileDescriptorProto> _instance;
 } _FileDescriptorProto_default_instance_;
 class DescriptorProto_ExtensionRangeDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto_ExtensionRange>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto_ExtensionRange> _instance;
 } _DescriptorProto_ExtensionRange_default_instance_;
 class DescriptorProto_ReservedRangeDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto_ReservedRange>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto_ReservedRange> _instance;
 } _DescriptorProto_ReservedRange_default_instance_;
 class DescriptorProtoDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<DescriptorProto> _instance;
 } _DescriptorProto_default_instance_;
 class ExtensionRangeOptionsDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<ExtensionRangeOptions>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<ExtensionRangeOptions> _instance;
 } _ExtensionRangeOptions_default_instance_;
 class FieldDescriptorProtoDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<FieldDescriptorProto>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<FieldDescriptorProto> _instance;
 } _FieldDescriptorProto_default_instance_;
 class OneofDescriptorProtoDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<OneofDescriptorProto>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<OneofDescriptorProto> _instance;
 } _OneofDescriptorProto_default_instance_;
 class EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<EnumDescriptorProto_EnumReservedRange>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<EnumDescriptorProto_EnumReservedRange> _instance;
 } _EnumDescriptorProto_EnumReservedRange_default_instance_;
 class EnumDescriptorProtoDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<EnumDescriptorProto>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<EnumDescriptorProto> _instance;
 } _EnumDescriptorProto_default_instance_;
 class EnumValueDescriptorProtoDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<EnumValueDescriptorProto>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<EnumValueDescriptorProto> _instance;
 } _EnumValueDescriptorProto_default_instance_;
 class ServiceDescriptorProtoDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<ServiceDescriptorProto>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<ServiceDescriptorProto> _instance;
 } _ServiceDescriptorProto_default_instance_;
 class MethodDescriptorProtoDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<MethodDescriptorProto>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<MethodDescriptorProto> _instance;
 } _MethodDescriptorProto_default_instance_;
 class FileOptionsDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<FileOptions>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<FileOptions> _instance;
 } _FileOptions_default_instance_;
 class MessageOptionsDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<MessageOptions>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<MessageOptions> _instance;
 } _MessageOptions_default_instance_;
 class FieldOptionsDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<FieldOptions>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<FieldOptions> _instance;
 } _FieldOptions_default_instance_;
 class OneofOptionsDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<OneofOptions>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<OneofOptions> _instance;
 } _OneofOptions_default_instance_;
 class EnumOptionsDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<EnumOptions>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<EnumOptions> _instance;
 } _EnumOptions_default_instance_;
 class EnumValueOptionsDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<EnumValueOptions>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<EnumValueOptions> _instance;
 } _EnumValueOptions_default_instance_;
 class ServiceOptionsDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<ServiceOptions>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<ServiceOptions> _instance;
 } _ServiceOptions_default_instance_;
 class MethodOptionsDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<MethodOptions>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<MethodOptions> _instance;
 } _MethodOptions_default_instance_;
 class UninterpretedOption_NamePartDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<UninterpretedOption_NamePart>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<UninterpretedOption_NamePart> _instance;
 } _UninterpretedOption_NamePart_default_instance_;
 class UninterpretedOptionDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<UninterpretedOption>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<UninterpretedOption> _instance;
 } _UninterpretedOption_default_instance_;
 class SourceCodeInfo_LocationDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<SourceCodeInfo_Location>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<SourceCodeInfo_Location> _instance;
 } _SourceCodeInfo_Location_default_instance_;
 class SourceCodeInfoDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<SourceCodeInfo>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<SourceCodeInfo> _instance;
 } _SourceCodeInfo_default_instance_;
 class GeneratedCodeInfo_AnnotationDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<GeneratedCodeInfo_Annotation>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<GeneratedCodeInfo_Annotation> _instance;
 } _GeneratedCodeInfo_Annotation_default_instance_;
 class GeneratedCodeInfoDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<GeneratedCodeInfo>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<GeneratedCodeInfo> _instance;
 } _GeneratedCodeInfo_default_instance_;
 }  // namespace protobuf
 }  // namespace google
-namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto {
-static void InitDefaultsFileDescriptorSet() {
+static void InitDefaultsFileDescriptorSet_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -197,11 +168,11 @@
   ::google::protobuf::FileDescriptorSet::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_FileDescriptorSet =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsFileDescriptorSet}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorProto.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_FileDescriptorSet_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsFileDescriptorSet_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsFileDescriptorProto() {
+static void InitDefaultsFileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -212,16 +183,16 @@
   ::google::protobuf::FileDescriptorProto::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<6> scc_info_FileDescriptorProto =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 6, InitDefaultsFileDescriptorProto}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto.base,
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto.base,
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceDescriptorProto.base,
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldDescriptorProto.base,
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileOptions.base,
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<6> scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 6, InitDefaultsFileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_DescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_EnumDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_ServiceDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_FieldDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_FileOptions_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_SourceCodeInfo_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsDescriptorProto_ExtensionRange() {
+static void InitDefaultsDescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -232,11 +203,11 @@
   ::google::protobuf::DescriptorProto_ExtensionRange::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_DescriptorProto_ExtensionRange =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsDescriptorProto_ExtensionRange}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ExtensionRangeOptions.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_DescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsDescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_ExtensionRangeOptions_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsDescriptorProto_ReservedRange() {
+static void InitDefaultsDescriptorProto_ReservedRange_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -247,10 +218,10 @@
   ::google::protobuf::DescriptorProto_ReservedRange::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_DescriptorProto_ReservedRange =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsDescriptorProto_ReservedRange}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_DescriptorProto_ReservedRange_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsDescriptorProto_ReservedRange_google_2fprotobuf_2fdescriptor_2eproto}, {}};
 
-static void InitDefaultsDescriptorProto() {
+static void InitDefaultsDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -261,16 +232,16 @@
   ::google::protobuf::DescriptorProto::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<6> scc_info_DescriptorProto =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 6, InitDefaultsDescriptorProto}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldDescriptorProto.base,
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto.base,
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ExtensionRange.base,
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofDescriptorProto.base,
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MessageOptions.base,
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ReservedRange.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<6> scc_info_DescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 6, InitDefaultsDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_FieldDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_EnumDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_DescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_OneofDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_MessageOptions_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_DescriptorProto_ReservedRange_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsExtensionRangeOptions() {
+static void InitDefaultsExtensionRangeOptions_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -281,11 +252,11 @@
   ::google::protobuf::ExtensionRangeOptions::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_ExtensionRangeOptions =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsExtensionRangeOptions}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_ExtensionRangeOptions_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsExtensionRangeOptions_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsFieldDescriptorProto() {
+static void InitDefaultsFieldDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -296,11 +267,11 @@
   ::google::protobuf::FieldDescriptorProto::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_FieldDescriptorProto =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsFieldDescriptorProto}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldOptions.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_FieldDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsFieldDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_FieldOptions_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsOneofDescriptorProto() {
+static void InitDefaultsOneofDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -311,11 +282,11 @@
   ::google::protobuf::OneofDescriptorProto::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_OneofDescriptorProto =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsOneofDescriptorProto}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofOptions.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_OneofDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsOneofDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_OneofOptions_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsEnumDescriptorProto_EnumReservedRange() {
+static void InitDefaultsEnumDescriptorProto_EnumReservedRange_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -326,10 +297,10 @@
   ::google::protobuf::EnumDescriptorProto_EnumReservedRange::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_EnumDescriptorProto_EnumReservedRange =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsEnumDescriptorProto_EnumReservedRange}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_EnumDescriptorProto_EnumReservedRange_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsEnumDescriptorProto_EnumReservedRange_google_2fprotobuf_2fdescriptor_2eproto}, {}};
 
-static void InitDefaultsEnumDescriptorProto() {
+static void InitDefaultsEnumDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -340,13 +311,13 @@
   ::google::protobuf::EnumDescriptorProto::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<3> scc_info_EnumDescriptorProto =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 3, InitDefaultsEnumDescriptorProto}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueDescriptorProto.base,
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumOptions.base,
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto_EnumReservedRange.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<3> scc_info_EnumDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 3, InitDefaultsEnumDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_EnumValueDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_EnumOptions_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_EnumDescriptorProto_EnumReservedRange_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsEnumValueDescriptorProto() {
+static void InitDefaultsEnumValueDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -357,11 +328,11 @@
   ::google::protobuf::EnumValueDescriptorProto::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValueDescriptorProto =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEnumValueDescriptorProto}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueOptions.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValueDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEnumValueDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_EnumValueOptions_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsServiceDescriptorProto() {
+static void InitDefaultsServiceDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -372,12 +343,12 @@
   ::google::protobuf::ServiceDescriptorProto::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<2> scc_info_ServiceDescriptorProto =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsServiceDescriptorProto}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodDescriptorProto.base,
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceOptions.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<2> scc_info_ServiceDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsServiceDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_MethodDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base,
+      &scc_info_ServiceOptions_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsMethodDescriptorProto() {
+static void InitDefaultsMethodDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -388,11 +359,11 @@
   ::google::protobuf::MethodDescriptorProto::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_MethodDescriptorProto =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMethodDescriptorProto}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodOptions.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_MethodDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMethodDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_MethodOptions_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsFileOptions() {
+static void InitDefaultsFileOptions_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -403,11 +374,11 @@
   ::google::protobuf::FileOptions::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_FileOptions =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsFileOptions}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_FileOptions_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsFileOptions_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsMessageOptions() {
+static void InitDefaultsMessageOptions_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -418,11 +389,11 @@
   ::google::protobuf::MessageOptions::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_MessageOptions =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMessageOptions}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_MessageOptions_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMessageOptions_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsFieldOptions() {
+static void InitDefaultsFieldOptions_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -433,11 +404,11 @@
   ::google::protobuf::FieldOptions::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_FieldOptions =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsFieldOptions}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_FieldOptions_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsFieldOptions_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsOneofOptions() {
+static void InitDefaultsOneofOptions_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -448,11 +419,11 @@
   ::google::protobuf::OneofOptions::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_OneofOptions =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsOneofOptions}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_OneofOptions_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsOneofOptions_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsEnumOptions() {
+static void InitDefaultsEnumOptions_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -463,11 +434,11 @@
   ::google::protobuf::EnumOptions::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_EnumOptions =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEnumOptions}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_EnumOptions_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEnumOptions_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsEnumValueOptions() {
+static void InitDefaultsEnumValueOptions_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -478,11 +449,11 @@
   ::google::protobuf::EnumValueOptions::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValueOptions =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEnumValueOptions}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValueOptions_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEnumValueOptions_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsServiceOptions() {
+static void InitDefaultsServiceOptions_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -493,11 +464,11 @@
   ::google::protobuf::ServiceOptions::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_ServiceOptions =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsServiceOptions}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_ServiceOptions_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsServiceOptions_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsMethodOptions() {
+static void InitDefaultsMethodOptions_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -508,11 +479,11 @@
   ::google::protobuf::MethodOptions::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_MethodOptions =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMethodOptions}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_MethodOptions_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMethodOptions_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsUninterpretedOption_NamePart() {
+static void InitDefaultsUninterpretedOption_NamePart_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -523,10 +494,10 @@
   ::google::protobuf::UninterpretedOption_NamePart::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_UninterpretedOption_NamePart =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUninterpretedOption_NamePart}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_UninterpretedOption_NamePart_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUninterpretedOption_NamePart_google_2fprotobuf_2fdescriptor_2eproto}, {}};
 
-static void InitDefaultsUninterpretedOption() {
+static void InitDefaultsUninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -537,11 +508,11 @@
   ::google::protobuf::UninterpretedOption::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_UninterpretedOption =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsUninterpretedOption}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption_NamePart.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsUninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_UninterpretedOption_NamePart_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsSourceCodeInfo_Location() {
+static void InitDefaultsSourceCodeInfo_Location_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -552,10 +523,10 @@
   ::google::protobuf::SourceCodeInfo_Location::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_SourceCodeInfo_Location =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsSourceCodeInfo_Location}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_SourceCodeInfo_Location_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsSourceCodeInfo_Location_google_2fprotobuf_2fdescriptor_2eproto}, {}};
 
-static void InitDefaultsSourceCodeInfo() {
+static void InitDefaultsSourceCodeInfo_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -566,11 +537,11 @@
   ::google::protobuf::SourceCodeInfo::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_SourceCodeInfo =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsSourceCodeInfo}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo_Location.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_SourceCodeInfo_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsSourceCodeInfo_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_SourceCodeInfo_Location_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-static void InitDefaultsGeneratedCodeInfo_Annotation() {
+static void InitDefaultsGeneratedCodeInfo_Annotation_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -581,10 +552,10 @@
   ::google::protobuf::GeneratedCodeInfo_Annotation::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_GeneratedCodeInfo_Annotation =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsGeneratedCodeInfo_Annotation}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_GeneratedCodeInfo_Annotation_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsGeneratedCodeInfo_Annotation_google_2fprotobuf_2fdescriptor_2eproto}, {}};
 
-static void InitDefaultsGeneratedCodeInfo() {
+static void InitDefaultsGeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -595,44 +566,45 @@
   ::google::protobuf::GeneratedCodeInfo::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_GeneratedCodeInfo =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsGeneratedCodeInfo}, {
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo_Annotation.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsGeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto}, {
+      &scc_info_GeneratedCodeInfo_Annotation_google_2fprotobuf_2fdescriptor_2eproto.base,}};
 
-void InitDefaults() {
-  ::google::protobuf::internal::InitSCC(&scc_info_FileDescriptorSet.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_FileDescriptorProto.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_DescriptorProto_ExtensionRange.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_DescriptorProto_ReservedRange.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_DescriptorProto.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_ExtensionRangeOptions.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_FieldDescriptorProto.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_OneofDescriptorProto.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_EnumDescriptorProto_EnumReservedRange.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_EnumDescriptorProto.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_EnumValueDescriptorProto.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_ServiceDescriptorProto.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_MethodDescriptorProto.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_FileOptions.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_MessageOptions.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_FieldOptions.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_OneofOptions.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_EnumOptions.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_EnumValueOptions.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_ServiceOptions.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_MethodOptions.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_UninterpretedOption_NamePart.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_UninterpretedOption.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_SourceCodeInfo_Location.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_SourceCodeInfo.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_GeneratedCodeInfo_Annotation.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_GeneratedCodeInfo.base);
+void InitDefaults_google_2fprotobuf_2fdescriptor_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_FileDescriptorSet_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_DescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_DescriptorProto_ReservedRange_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_DescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ExtensionRangeOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_FieldDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_OneofDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EnumDescriptorProto_EnumReservedRange_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EnumDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EnumValueDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ServiceDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_MethodDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_FileOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_MessageOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_FieldOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_OneofOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EnumOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EnumValueOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ServiceOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_MethodOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_UninterpretedOption_NamePart_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_SourceCodeInfo_Location_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_SourceCodeInfo_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_GeneratedCodeInfo_Annotation_google_2fprotobuf_2fdescriptor_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata[27];
-const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[6];
+::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[27];
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[6];
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto = nullptr;
 
-const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorSet, _has_bits_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FileDescriptorSet, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -1077,201 +1049,183 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_GeneratedCodeInfo_default_instance_),
 };
 
-static void protobuf_AssignDescriptors() {
-  AddDescriptors();
-  AssignDescriptors(
-      "google/protobuf/descriptor.proto", schemas, file_default_instances, TableStruct::offsets,
-      file_level_metadata, file_level_enum_descriptors, NULL);
-}
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto = {
+  {}, AddDescriptors_google_2fprotobuf_2fdescriptor_2eproto, "google/protobuf/descriptor.proto", schemas,
+  file_default_instances, TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets,
+  file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto, 27, file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto, file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto,
+};
 
-static void protobuf_AssignDescriptorsOnce() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
-}
+::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto = {
+  false, InitDefaults_google_2fprotobuf_2fdescriptor_2eproto, 
+  "\n google/protobuf/descriptor.proto\022\017goog"
+  "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
+  "\030\001 \003(\0132$.google.protobuf.FileDescriptorP"
+  "roto\"\333\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
+  "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022"
+  "\031\n\021public_dependency\030\n \003(\005\022\027\n\017weak_depen"
+  "dency\030\013 \003(\005\0226\n\014message_type\030\004 \003(\0132 .goog"
+  "le.protobuf.DescriptorProto\0227\n\tenum_type"
+  "\030\005 \003(\0132$.google.protobuf.EnumDescriptorP"
+  "roto\0228\n\007service\030\006 \003(\0132\'.google.protobuf."
+  "ServiceDescriptorProto\0228\n\textension\030\007 \003("
+  "\0132%.google.protobuf.FieldDescriptorProto"
+  "\022-\n\007options\030\010 \001(\0132\034.google.protobuf.File"
+  "Options\0229\n\020source_code_info\030\t \001(\0132\037.goog"
+  "le.protobuf.SourceCodeInfo\022\016\n\006syntax\030\014 \001"
+  "(\t\"\251\005\n\017DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005"
+  "field\030\002 \003(\0132%.google.protobuf.FieldDescr"
+  "iptorProto\0228\n\textension\030\006 \003(\0132%.google.p"
+  "rotobuf.FieldDescriptorProto\0225\n\013nested_t"
+  "ype\030\003 \003(\0132 .google.protobuf.DescriptorPr"
+  "oto\0227\n\tenum_type\030\004 \003(\0132$.google.protobuf"
+  ".EnumDescriptorProto\022H\n\017extension_range\030"
+  "\005 \003(\0132/.google.protobuf.DescriptorProto."
+  "ExtensionRange\0229\n\noneof_decl\030\010 \003(\0132%.goo"
+  "gle.protobuf.OneofDescriptorProto\0220\n\007opt"
+  "ions\030\007 \001(\0132\037.google.protobuf.MessageOpti"
+  "ons\022F\n\016reserved_range\030\t \003(\0132..google.pro"
+  "tobuf.DescriptorProto.ReservedRange\022\025\n\rr"
+  "eserved_name\030\n \003(\t\032e\n\016ExtensionRange\022\r\n\005"
+  "start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\0227\n\007options\030\003 \001("
+  "\0132&.google.protobuf.ExtensionRangeOption"
+  "s\032+\n\rReservedRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end"
+  "\030\002 \001(\005\"g\n\025ExtensionRangeOptions\022C\n\024unint"
+  "erpreted_option\030\347\007 \003(\0132$.google.protobuf"
+  ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\274\005\n\024Fiel"
+  "dDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number"
+  "\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.google.protobuf."
+  "FieldDescriptorProto.Label\0228\n\004type\030\005 \001(\016"
+  "2*.google.protobuf.FieldDescriptorProto."
+  "Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001("
+  "\t\022\025\n\rdefault_value\030\007 \001(\t\022\023\n\013oneof_index\030"
+  "\t \001(\005\022\021\n\tjson_name\030\n \001(\t\022.\n\007options\030\010 \001("
+  "\0132\035.google.protobuf.FieldOptions\"\266\002\n\004Typ"
+  "e\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTY"
+  "PE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT3"
+  "2\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022"
+  "\r\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_"
+  "GROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020"
+  "\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYP"
+  "E_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_"
+  "SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LA"
+  "BEL_OPTIONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LA"
+  "BEL_REPEATED\020\003\"T\n\024OneofDescriptorProto\022\014"
+  "\n\004name\030\001 \001(\t\022.\n\007options\030\002 \001(\0132\035.google.p"
+  "rotobuf.OneofOptions\"\244\002\n\023EnumDescriptorP"
+  "roto\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132).goog"
+  "le.protobuf.EnumValueDescriptorProto\022-\n\007"
+  "options\030\003 \001(\0132\034.google.protobuf.EnumOpti"
+  "ons\022N\n\016reserved_range\030\004 \003(\01326.google.pro"
+  "tobuf.EnumDescriptorProto.EnumReservedRa"
+  "nge\022\025\n\rreserved_name\030\005 \003(\t\032/\n\021EnumReserv"
+  "edRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"l\n\030E"
+  "numValueDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n"
+  "\006number\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.google."
+  "protobuf.EnumValueOptions\"\220\001\n\026ServiceDes"
+  "criptorProto\022\014\n\004name\030\001 \001(\t\0226\n\006method\030\002 \003"
+  "(\0132&.google.protobuf.MethodDescriptorPro"
+  "to\0220\n\007options\030\003 \001(\0132\037.google.protobuf.Se"
+  "rviceOptions\"\301\001\n\025MethodDescriptorProto\022\014"
+  "\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023\n\013outp"
+  "ut_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google."
+  "protobuf.MethodOptions\022\037\n\020client_streami"
+  "ng\030\005 \001(\010:\005false\022\037\n\020server_streaming\030\006 \001("
+  "\010:\005false\"\246\006\n\013FileOptions\022\024\n\014java_package"
+  "\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023"
+  "java_multiple_files\030\n \001(\010:\005false\022)\n\035java"
+  "_generate_equals_and_hash\030\024 \001(\010B\002\030\001\022%\n\026j"
+  "ava_string_check_utf8\030\033 \001(\010:\005false\022F\n\014op"
+  "timize_for\030\t \001(\0162).google.protobuf.FileO"
+  "ptions.OptimizeMode:\005SPEED\022\022\n\ngo_package"
+  "\030\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(\010:\005fal"
+  "se\022$\n\025java_generic_services\030\021 \001(\010:\005false"
+  "\022\"\n\023py_generic_services\030\022 \001(\010:\005false\022#\n\024"
+  "php_generic_services\030* \001(\010:\005false\022\031\n\ndep"
+  "recated\030\027 \001(\010:\005false\022\037\n\020cc_enable_arenas"
+  "\030\037 \001(\010:\005false\022\031\n\021objc_class_prefix\030$ \001(\t"
+  "\022\030\n\020csharp_namespace\030% \001(\t\022\024\n\014swift_pref"
+  "ix\030\' \001(\t\022\030\n\020php_class_prefix\030( \001(\t\022\025\n\rph"
+  "p_namespace\030) \001(\t\022\036\n\026php_metadata_namesp"
+  "ace\030, \001(\t\022\024\n\014ruby_package\030- \001(\t\022C\n\024unint"
+  "erpreted_option\030\347\007 \003(\0132$.google.protobuf"
+  ".UninterpretedOption\":\n\014OptimizeMode\022\t\n\005"
+  "SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003"
+  "*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\362\001\n\016MessageOptions\022&\n\027"
+  "message_set_wire_format\030\001 \001(\010:\005false\022.\n\037"
+  "no_standard_descriptor_accessor\030\002 \001(\010:\005f"
+  "alse\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\021\n\tmap_e"
+  "ntry\030\007 \001(\010\022C\n\024uninterpreted_option\030\347\007 \003("
+  "\0132$.google.protobuf.UninterpretedOption*"
+  "\t\010\350\007\020\200\200\200\200\002J\004\010\010\020\tJ\004\010\t\020\n\"\236\003\n\014FieldOptions\022"
+  ":\n\005ctype\030\001 \001(\0162#.google.protobuf.FieldOp"
+  "tions.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\?\n\006j"
+  "stype\030\006 \001(\0162$.google.protobuf.FieldOptio"
+  "ns.JSType:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010:\005fals"
+  "e\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n \001"
+  "(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003(\013"
+  "2$.google.protobuf.UninterpretedOption\"/"
+  "\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_"
+  "PIECE\020\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS_S"
+  "TRING\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020\005\""
+  "^\n\014OneofOptions\022C\n\024uninterpreted_option\030"
+  "\347\007 \003(\0132$.google.protobuf.UninterpretedOp"
+  "tion*\t\010\350\007\020\200\200\200\200\002\"\223\001\n\013EnumOptions\022\023\n\013allow"
+  "_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022"
+  "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google."
+  "protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002J"
+  "\004\010\005\020\006\"}\n\020EnumValueOptions\022\031\n\ndeprecated\030"
+  "\001 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 "
+  "\003(\0132$.google.protobuf.UninterpretedOptio"
+  "n*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprec"
+  "ated\030! \001(\010:\005false\022C\n\024uninterpreted_optio"
+  "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted"
+  "Option*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n\nd"
+  "eprecated\030! \001(\010:\005false\022_\n\021idempotency_le"
+  "vel\030\" \001(\0162/.google.protobuf.MethodOption"
+  "s.IdempotencyLevel:\023IDEMPOTENCY_UNKNOWN\022"
+  "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google."
+  "protobuf.UninterpretedOption\"P\n\020Idempote"
+  "ncyLevel\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017NO_"
+  "SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200"
+  "\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\0132"
+  "-.google.protobuf.UninterpretedOption.Na"
+  "mePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022posi"
+  "tive_int_value\030\004 \001(\004\022\032\n\022negative_int_val"
+  "ue\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string"
+  "_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n"
+  "\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_exten"
+  "sion\030\002 \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010locatio"
+  "n\030\001 \003(\0132(.google.protobuf.SourceCodeInfo"
+  ".Location\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001"
+  "\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003"
+  " \001(\t\022\031\n\021trailing_comments\030\004 \001(\t\022!\n\031leadi"
+  "ng_detached_comments\030\006 \003(\t\"\247\001\n\021Generated"
+  "CodeInfo\022A\n\nannotation\030\001 \003(\0132-.google.pr"
+  "otobuf.GeneratedCodeInfo.Annotation\032O\n\nA"
+  "nnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_fi"
+  "le\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B\217\001\n"
+  "\023com.google.protobufB\020DescriptorProtosH\001"
+  "Z>github.com/golang/protobuf/protoc-gen-"
+  "go/descriptor;descriptor\370\001\001\242\002\003GPB\252\002\032Goog"
+  "le.Protobuf.Reflection"
+,
+  "google/protobuf/descriptor.proto", &assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto, 6022,
+};
 
-void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
-void protobuf_RegisterTypes(const ::std::string&) {
-  protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 27);
-}
-
-static void AddDescriptorsImpl() {
-  InitDefaults();
-  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
-      "\n google/protobuf/descriptor.proto\022\017goog"
-      "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
-      "\030\001 \003(\0132$.google.protobuf.FileDescriptorP"
-      "roto\"\333\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
-      "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022"
-      "\031\n\021public_dependency\030\n \003(\005\022\027\n\017weak_depen"
-      "dency\030\013 \003(\005\0226\n\014message_type\030\004 \003(\0132 .goog"
-      "le.protobuf.DescriptorProto\0227\n\tenum_type"
-      "\030\005 \003(\0132$.google.protobuf.EnumDescriptorP"
-      "roto\0228\n\007service\030\006 \003(\0132\'.google.protobuf."
-      "ServiceDescriptorProto\0228\n\textension\030\007 \003("
-      "\0132%.google.protobuf.FieldDescriptorProto"
-      "\022-\n\007options\030\010 \001(\0132\034.google.protobuf.File"
-      "Options\0229\n\020source_code_info\030\t \001(\0132\037.goog"
-      "le.protobuf.SourceCodeInfo\022\016\n\006syntax\030\014 \001"
-      "(\t\"\251\005\n\017DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005"
-      "field\030\002 \003(\0132%.google.protobuf.FieldDescr"
-      "iptorProto\0228\n\textension\030\006 \003(\0132%.google.p"
-      "rotobuf.FieldDescriptorProto\0225\n\013nested_t"
-      "ype\030\003 \003(\0132 .google.protobuf.DescriptorPr"
-      "oto\0227\n\tenum_type\030\004 \003(\0132$.google.protobuf"
-      ".EnumDescriptorProto\022H\n\017extension_range\030"
-      "\005 \003(\0132/.google.protobuf.DescriptorProto."
-      "ExtensionRange\0229\n\noneof_decl\030\010 \003(\0132%.goo"
-      "gle.protobuf.OneofDescriptorProto\0220\n\007opt"
-      "ions\030\007 \001(\0132\037.google.protobuf.MessageOpti"
-      "ons\022F\n\016reserved_range\030\t \003(\0132..google.pro"
-      "tobuf.DescriptorProto.ReservedRange\022\025\n\rr"
-      "eserved_name\030\n \003(\t\032e\n\016ExtensionRange\022\r\n\005"
-      "start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\0227\n\007options\030\003 \001("
-      "\0132&.google.protobuf.ExtensionRangeOption"
-      "s\032+\n\rReservedRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end"
-      "\030\002 \001(\005\"g\n\025ExtensionRangeOptions\022C\n\024unint"
-      "erpreted_option\030\347\007 \003(\0132$.google.protobuf"
-      ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\274\005\n\024Fiel"
-      "dDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number"
-      "\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.google.protobuf."
-      "FieldDescriptorProto.Label\0228\n\004type\030\005 \001(\016"
-      "2*.google.protobuf.FieldDescriptorProto."
-      "Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001("
-      "\t\022\025\n\rdefault_value\030\007 \001(\t\022\023\n\013oneof_index\030"
-      "\t \001(\005\022\021\n\tjson_name\030\n \001(\t\022.\n\007options\030\010 \001("
-      "\0132\035.google.protobuf.FieldOptions\"\266\002\n\004Typ"
-      "e\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTY"
-      "PE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT3"
-      "2\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022"
-      "\r\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_"
-      "GROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020"
-      "\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYP"
-      "E_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_"
-      "SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LA"
-      "BEL_OPTIONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LA"
-      "BEL_REPEATED\020\003\"T\n\024OneofDescriptorProto\022\014"
-      "\n\004name\030\001 \001(\t\022.\n\007options\030\002 \001(\0132\035.google.p"
-      "rotobuf.OneofOptions\"\244\002\n\023EnumDescriptorP"
-      "roto\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132).goog"
-      "le.protobuf.EnumValueDescriptorProto\022-\n\007"
-      "options\030\003 \001(\0132\034.google.protobuf.EnumOpti"
-      "ons\022N\n\016reserved_range\030\004 \003(\01326.google.pro"
-      "tobuf.EnumDescriptorProto.EnumReservedRa"
-      "nge\022\025\n\rreserved_name\030\005 \003(\t\032/\n\021EnumReserv"
-      "edRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"l\n\030E"
-      "numValueDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n"
-      "\006number\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.google."
-      "protobuf.EnumValueOptions\"\220\001\n\026ServiceDes"
-      "criptorProto\022\014\n\004name\030\001 \001(\t\0226\n\006method\030\002 \003"
-      "(\0132&.google.protobuf.MethodDescriptorPro"
-      "to\0220\n\007options\030\003 \001(\0132\037.google.protobuf.Se"
-      "rviceOptions\"\301\001\n\025MethodDescriptorProto\022\014"
-      "\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023\n\013outp"
-      "ut_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google."
-      "protobuf.MethodOptions\022\037\n\020client_streami"
-      "ng\030\005 \001(\010:\005false\022\037\n\020server_streaming\030\006 \001("
-      "\010:\005false\"\246\006\n\013FileOptions\022\024\n\014java_package"
-      "\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023"
-      "java_multiple_files\030\n \001(\010:\005false\022)\n\035java"
-      "_generate_equals_and_hash\030\024 \001(\010B\002\030\001\022%\n\026j"
-      "ava_string_check_utf8\030\033 \001(\010:\005false\022F\n\014op"
-      "timize_for\030\t \001(\0162).google.protobuf.FileO"
-      "ptions.OptimizeMode:\005SPEED\022\022\n\ngo_package"
-      "\030\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(\010:\005fal"
-      "se\022$\n\025java_generic_services\030\021 \001(\010:\005false"
-      "\022\"\n\023py_generic_services\030\022 \001(\010:\005false\022#\n\024"
-      "php_generic_services\030* \001(\010:\005false\022\031\n\ndep"
-      "recated\030\027 \001(\010:\005false\022\037\n\020cc_enable_arenas"
-      "\030\037 \001(\010:\005false\022\031\n\021objc_class_prefix\030$ \001(\t"
-      "\022\030\n\020csharp_namespace\030% \001(\t\022\024\n\014swift_pref"
-      "ix\030\' \001(\t\022\030\n\020php_class_prefix\030( \001(\t\022\025\n\rph"
-      "p_namespace\030) \001(\t\022\036\n\026php_metadata_namesp"
-      "ace\030, \001(\t\022\024\n\014ruby_package\030- \001(\t\022C\n\024unint"
-      "erpreted_option\030\347\007 \003(\0132$.google.protobuf"
-      ".UninterpretedOption\":\n\014OptimizeMode\022\t\n\005"
-      "SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003"
-      "*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\362\001\n\016MessageOptions\022&\n\027"
-      "message_set_wire_format\030\001 \001(\010:\005false\022.\n\037"
-      "no_standard_descriptor_accessor\030\002 \001(\010:\005f"
-      "alse\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\021\n\tmap_e"
-      "ntry\030\007 \001(\010\022C\n\024uninterpreted_option\030\347\007 \003("
-      "\0132$.google.protobuf.UninterpretedOption*"
-      "\t\010\350\007\020\200\200\200\200\002J\004\010\010\020\tJ\004\010\t\020\n\"\236\003\n\014FieldOptions\022"
-      ":\n\005ctype\030\001 \001(\0162#.google.protobuf.FieldOp"
-      "tions.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\?\n\006j"
-      "stype\030\006 \001(\0162$.google.protobuf.FieldOptio"
-      "ns.JSType:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010:\005fals"
-      "e\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n \001"
-      "(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003(\013"
-      "2$.google.protobuf.UninterpretedOption\"/"
-      "\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_"
-      "PIECE\020\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS_S"
-      "TRING\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020\005\""
-      "^\n\014OneofOptions\022C\n\024uninterpreted_option\030"
-      "\347\007 \003(\0132$.google.protobuf.UninterpretedOp"
-      "tion*\t\010\350\007\020\200\200\200\200\002\"\223\001\n\013EnumOptions\022\023\n\013allow"
-      "_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022"
-      "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google."
-      "protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002J"
-      "\004\010\005\020\006\"}\n\020EnumValueOptions\022\031\n\ndeprecated\030"
-      "\001 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 "
-      "\003(\0132$.google.protobuf.UninterpretedOptio"
-      "n*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprec"
-      "ated\030! \001(\010:\005false\022C\n\024uninterpreted_optio"
-      "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted"
-      "Option*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n\nd"
-      "eprecated\030! \001(\010:\005false\022_\n\021idempotency_le"
-      "vel\030\" \001(\0162/.google.protobuf.MethodOption"
-      "s.IdempotencyLevel:\023IDEMPOTENCY_UNKNOWN\022"
-      "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google."
-      "protobuf.UninterpretedOption\"P\n\020Idempote"
-      "ncyLevel\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017NO_"
-      "SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200"
-      "\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\0132"
-      "-.google.protobuf.UninterpretedOption.Na"
-      "mePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022posi"
-      "tive_int_value\030\004 \001(\004\022\032\n\022negative_int_val"
-      "ue\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string"
-      "_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n"
-      "\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_exten"
-      "sion\030\002 \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010locatio"
-      "n\030\001 \003(\0132(.google.protobuf.SourceCodeInfo"
-      ".Location\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001"
-      "\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003"
-      " \001(\t\022\031\n\021trailing_comments\030\004 \001(\t\022!\n\031leadi"
-      "ng_detached_comments\030\006 \003(\t\"\247\001\n\021Generated"
-      "CodeInfo\022A\n\nannotation\030\001 \003(\0132-.google.pr"
-      "otobuf.GeneratedCodeInfo.Annotation\032O\n\nA"
-      "nnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_fi"
-      "le\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B\217\001\n"
-      "\023com.google.protobufB\020DescriptorProtosH\001"
-      "Z>github.com/golang/protobuf/protoc-gen-"
-      "go/descriptor;descriptor\370\001\001\242\002\003GPB\252\002\032Goog"
-      "le.Protobuf.Reflection"
+void AddDescriptors_google_2fprotobuf_2fdescriptor_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
   };
-  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 6022);
-  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
-    "google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, deps, 0);
 }
 
-void AddDescriptors() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
-}
-// Force AddDescriptors() to be called at dynamic initialization time.
-struct StaticDescriptorInitializer {
-  StaticDescriptorInitializer() {
-    AddDescriptors();
-  }
-} static_descriptor_initializer;
-}  // namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_google_2fprotobuf_2fdescriptor_2eproto = []() { AddDescriptors_google_2fprotobuf_2fdescriptor_2eproto(); return true; }();
 namespace google {
 namespace protobuf {
 const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor() {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_enum_descriptors[0];
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[0];
 }
 bool FieldDescriptorProto_Type_IsValid(int value) {
   switch (value) {
@@ -1323,8 +1277,8 @@
 const int FieldDescriptorProto::Type_ARRAYSIZE;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor() {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_enum_descriptors[1];
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[1];
 }
 bool FieldDescriptorProto_Label_IsValid(int value) {
   switch (value) {
@@ -1346,8 +1300,8 @@
 const int FieldDescriptorProto::Label_ARRAYSIZE;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor() {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_enum_descriptors[2];
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[2];
 }
 bool FileOptions_OptimizeMode_IsValid(int value) {
   switch (value) {
@@ -1369,8 +1323,8 @@
 const int FileOptions::OptimizeMode_ARRAYSIZE;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor() {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_enum_descriptors[3];
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[3];
 }
 bool FieldOptions_CType_IsValid(int value) {
   switch (value) {
@@ -1392,8 +1346,8 @@
 const int FieldOptions::CType_ARRAYSIZE;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 const ::google::protobuf::EnumDescriptor* FieldOptions_JSType_descriptor() {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_enum_descriptors[4];
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[4];
 }
 bool FieldOptions_JSType_IsValid(int value) {
   switch (value) {
@@ -1415,8 +1369,8 @@
 const int FieldOptions::JSType_ARRAYSIZE;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 const ::google::protobuf::EnumDescriptor* MethodOptions_IdempotencyLevel_descriptor() {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_enum_descriptors[5];
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[5];
 }
 bool MethodOptions_IdempotencyLevel_IsValid(int value) {
   switch (value) {
@@ -1442,14 +1396,16 @@
 
 void FileDescriptorSet::InitAsDefaultInstance() {
 }
+class FileDescriptorSet::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int FileDescriptorSet::kFileFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 FileDescriptorSet::FileDescriptorSet()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorSet.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorSet)
 }
@@ -1457,7 +1413,6 @@
   : ::google::protobuf::Message(),
   _internal_metadata_(arena),
   file_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorSet.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorSet)
@@ -1472,6 +1427,8 @@
 }
 
 void FileDescriptorSet::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_FileDescriptorSet_google_2fprotobuf_2fdescriptor_2eproto.base);
 }
 
 FileDescriptorSet::~FileDescriptorSet() {
@@ -1492,13 +1449,8 @@
 void FileDescriptorSet::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const FileDescriptorSet& FileDescriptorSet::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorSet.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_FileDescriptorSet_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -1514,9 +1466,64 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* FileDescriptorSet::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<FileDescriptorSet*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // repeated .google.protobuf.FileDescriptorProto file = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::FileDescriptorProto::_InternalParse;
+          object = msg->add_file();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 10 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool FileDescriptorSet::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.FileDescriptorSet)
   for (;;) {
@@ -1526,8 +1533,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // repeated .google.protobuf.FileDescriptorProto file = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_file()));
         } else {
@@ -1555,6 +1561,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void FileDescriptorSet::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -1610,6 +1617,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.FileDescriptorProto file = 1;
   {
     unsigned int count = static_cast<unsigned int>(this->file_size());
@@ -1630,7 +1641,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FileDescriptorSet)
   GOOGLE_DCHECK_NE(&from, this);
   const FileDescriptorSet* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const FileDescriptorSet>(
+      ::google::protobuf::DynamicCastToGenerated<FileDescriptorSet>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FileDescriptorSet)
@@ -1691,14 +1702,14 @@
 }
 void FileDescriptorSet::InternalSwap(FileDescriptorSet* other) {
   using std::swap;
-  CastToBase(&file_)->InternalSwap(CastToBase(&other->file_));
-  swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
+  CastToBase(&file_)->InternalSwap(CastToBase(&other->file_));
 }
 
 ::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -1710,6 +1721,35 @@
   ::google::protobuf::_FileDescriptorProto_default_instance_._instance.get_mutable()->source_code_info_ = const_cast< ::google::protobuf::SourceCodeInfo*>(
       ::google::protobuf::SourceCodeInfo::internal_default_instance());
 }
+class FileDescriptorProto::HasBitSetters {
+ public:
+  static void set_has_name(FileDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_package(FileDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+  static const ::google::protobuf::FileOptions& options(const FileDescriptorProto* msg);
+  static void set_has_options(FileDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000008u;
+  }
+  static const ::google::protobuf::SourceCodeInfo& source_code_info(const FileDescriptorProto* msg);
+  static void set_has_source_code_info(FileDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000010u;
+  }
+  static void set_has_syntax(FileDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000004u;
+  }
+};
+
+const ::google::protobuf::FileOptions&
+FileDescriptorProto::HasBitSetters::options(const FileDescriptorProto* msg) {
+  return *msg->options_;
+}
+const ::google::protobuf::SourceCodeInfo&
+FileDescriptorProto::HasBitSetters::source_code_info(const FileDescriptorProto* msg) {
+  return *msg->source_code_info_;
+}
 void FileDescriptorProto::unsafe_arena_set_allocated_options(
     ::google::protobuf::FileOptions* options) {
   if (GetArenaNoVirtual() == NULL) {
@@ -1717,9 +1757,9 @@
   }
   options_ = options;
   if (options) {
-    set_has_options();
+    _has_bits_[0] |= 0x00000008u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000008u;
   }
   // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.options)
 }
@@ -1730,9 +1770,9 @@
   }
   source_code_info_ = source_code_info;
   if (source_code_info) {
-    set_has_source_code_info();
+    _has_bits_[0] |= 0x00000010u;
   } else {
-    clear_has_source_code_info();
+    _has_bits_[0] &= ~0x00000010u;
   }
   // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.source_code_info)
 }
@@ -1753,8 +1793,6 @@
 
 FileDescriptorProto::FileDescriptorProto()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorProto.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorProto)
 }
@@ -1768,7 +1806,6 @@
   extension_(arena),
   public_dependency_(arena),
   weak_dependency_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorProto.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorProto)
@@ -1814,6 +1851,8 @@
 }
 
 void FileDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   package_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   syntax_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -1845,13 +1884,8 @@
 void FileDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const FileDescriptorProto& FileDescriptorProto::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorProto.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -1870,7 +1904,7 @@
   public_dependency_.Clear();
   weak_dependency_.Clear();
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 31u) {
+  if (cached_has_bits & 0x0000001fu) {
     if (cached_has_bits & 0x00000001u) {
       name_.ClearNonDefaultToEmpty();
     }
@@ -1893,9 +1927,251 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* FileDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<FileDescriptorProto*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FileDescriptorProto.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string package = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FileDescriptorProto.package");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_package();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated string dependency = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          ctx->extra_parse_data().SetFieldName("google.protobuf.FileDescriptorProto.dependency");
+          parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+          ::std::string* str = msg->add_dependency();
+          str->clear();
+          object = str;
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 26 && (ptr += 1));
+        break;
+      }
+      // repeated .google.protobuf.DescriptorProto message_type = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::DescriptorProto::_InternalParse;
+          object = msg->add_message_type();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 34 && (ptr += 1));
+        break;
+      }
+      // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::EnumDescriptorProto::_InternalParse;
+          object = msg->add_enum_type();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 42 && (ptr += 1));
+        break;
+      }
+      // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::ServiceDescriptorProto::_InternalParse;
+          object = msg->add_service();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 50 && (ptr += 1));
+        break;
+      }
+      // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::FieldDescriptorProto::_InternalParse;
+          object = msg->add_extension();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 58 && (ptr += 1));
+        break;
+      }
+      // optional .google.protobuf.FileOptions options = 8;
+      case 8: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::FileOptions::_InternalParse;
+        object = msg->mutable_options();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+      case 9: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 74) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::SourceCodeInfo::_InternalParse;
+        object = msg->mutable_source_code_info();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated int32 public_dependency = 10;
+      case 10: {
+        if (static_cast<::google::protobuf::uint8>(tag) == 80) {
+          do {
+            ::google::protobuf::uint64 val;
+            ptr = Varint::Parse64(ptr, &val);
+            if (!ptr) goto error;
+            ::google::protobuf::int32 value = val;
+            msg->add_public_dependency(value);
+            if (ptr >= end) break;
+          } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 80 && (ptr += 1));
+          break;
+        } else if (static_cast<::google::protobuf::uint8>(tag) != 82) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::internal::PackedInt32Parser;
+        object = msg->mutable_public_dependency();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated int32 weak_dependency = 11;
+      case 11: {
+        if (static_cast<::google::protobuf::uint8>(tag) == 88) {
+          do {
+            ::google::protobuf::uint64 val;
+            ptr = Varint::Parse64(ptr, &val);
+            if (!ptr) goto error;
+            ::google::protobuf::int32 value = val;
+            msg->add_weak_dependency(value);
+            if (ptr >= end) break;
+          } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 88 && (ptr += 1));
+          break;
+        } else if (static_cast<::google::protobuf::uint8>(tag) != 90) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::internal::PackedInt32Parser;
+        object = msg->mutable_weak_dependency();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string syntax = 12;
+      case 12: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 98) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FileDescriptorProto.syntax");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_syntax();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool FileDescriptorProto::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.FileDescriptorProto)
   for (;;) {
@@ -1905,8 +2181,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -1921,8 +2196,7 @@
 
       // optional string package = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_package()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -1937,8 +2211,7 @@
 
       // repeated string dependency = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->add_dependency()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -1954,8 +2227,7 @@
 
       // repeated .google.protobuf.DescriptorProto message_type = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_message_type()));
         } else {
@@ -1966,8 +2238,7 @@
 
       // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
       case 5: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_enum_type()));
         } else {
@@ -1978,8 +2249,7 @@
 
       // repeated .google.protobuf.ServiceDescriptorProto service = 6;
       case 6: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_service()));
         } else {
@@ -1990,8 +2260,7 @@
 
       // repeated .google.protobuf.FieldDescriptorProto extension = 7;
       case 7: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (58 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_extension()));
         } else {
@@ -2002,8 +2271,7 @@
 
       // optional .google.protobuf.FileOptions options = 8;
       case 8: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (66 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_options()));
         } else {
@@ -2014,8 +2282,7 @@
 
       // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
       case 9: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(74u /* 74 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (74 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_source_code_info()));
         } else {
@@ -2026,14 +2293,11 @@
 
       // repeated int32 public_dependency = 10;
       case 10: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(80u /* 80 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (80 & 0xFF)) {
           DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  1, 80u, input, this->mutable_public_dependency())));
-        } else if (
-            static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(82u /* 82 & 0xFF */)) {
+        } else if (static_cast< ::google::protobuf::uint8>(tag) == (82 & 0xFF)) {
           DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, this->mutable_public_dependency())));
@@ -2045,14 +2309,11 @@
 
       // repeated int32 weak_dependency = 11;
       case 11: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(88u /* 88 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (88 & 0xFF)) {
           DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  1, 88u, input, this->mutable_weak_dependency())));
-        } else if (
-            static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(90u /* 90 & 0xFF */)) {
+        } else if (static_cast< ::google::protobuf::uint8>(tag) == (90 & 0xFF)) {
           DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, this->mutable_weak_dependency())));
@@ -2064,8 +2325,7 @@
 
       // optional string syntax = 12;
       case 12: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(98u /* 98 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (98 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_syntax()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -2097,6 +2357,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void FileDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -2174,13 +2435,13 @@
   // optional .google.protobuf.FileOptions options = 8;
   if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      8, this->_internal_options(), output);
+      8, HasBitSetters::options(this), output);
   }
 
   // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
   if (cached_has_bits & 0x00000010u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      9, this->_internal_source_code_info(), output);
+      9, HasBitSetters::source_code_info(this), output);
   }
 
   // repeated int32 public_dependency = 10;
@@ -2288,14 +2549,14 @@
   if (cached_has_bits & 0x00000008u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        8, this->_internal_options(), deterministic, target);
+        8, HasBitSetters::options(this), deterministic, target);
   }
 
   // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
   if (cached_has_bits & 0x00000010u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        9, this->_internal_source_code_info(), deterministic, target);
+        9, HasBitSetters::source_code_info(this), deterministic, target);
   }
 
   // repeated int32 public_dependency = 10;
@@ -2334,6 +2595,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated string dependency = 3;
   total_size += 1 *
       ::google::protobuf::internal::FromIntSize(this->dependency_size());
@@ -2404,37 +2669,38 @@
     total_size += data_size;
   }
 
-  if (_has_bits_[0 / 32] & 31u) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x0000001fu) {
     // optional string name = 1;
-    if (has_name()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->name());
     }
 
     // optional string package = 2;
-    if (has_package()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->package());
     }
 
     // optional string syntax = 12;
-    if (has_syntax()) {
+    if (cached_has_bits & 0x00000004u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->syntax());
     }
 
     // optional .google.protobuf.FileOptions options = 8;
-    if (has_options()) {
+    if (cached_has_bits & 0x00000008u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::MessageSize(
           *options_);
     }
 
     // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
-    if (has_source_code_info()) {
+    if (cached_has_bits & 0x00000010u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::MessageSize(
           *source_code_info_);
@@ -2450,7 +2716,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FileDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   const FileDescriptorProto* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const FileDescriptorProto>(
+      ::google::protobuf::DynamicCastToGenerated<FileDescriptorProto>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FileDescriptorProto)
@@ -2476,7 +2742,7 @@
   public_dependency_.MergeFrom(from.public_dependency_);
   weak_dependency_.MergeFrom(from.weak_dependency_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 31u) {
+  if (cached_has_bits & 0x0000001fu) {
     if (cached_has_bits & 0x00000001u) {
       set_name(from.name());
     }
@@ -2541,6 +2807,8 @@
 }
 void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   dependency_.InternalSwap(CastToBase(&other->dependency_));
   CastToBase(&message_type_)->InternalSwap(CastToBase(&other->message_type_));
   CastToBase(&enum_type_)->InternalSwap(CastToBase(&other->enum_type_));
@@ -2556,13 +2824,11 @@
     GetArenaNoVirtual());
   swap(options_, other->options_);
   swap(source_code_info_, other->source_code_info_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -2572,6 +2838,24 @@
   ::google::protobuf::_DescriptorProto_ExtensionRange_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::ExtensionRangeOptions*>(
       ::google::protobuf::ExtensionRangeOptions::internal_default_instance());
 }
+class DescriptorProto_ExtensionRange::HasBitSetters {
+ public:
+  static void set_has_start(DescriptorProto_ExtensionRange* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+  static void set_has_end(DescriptorProto_ExtensionRange* msg) {
+    msg->_has_bits_[0] |= 0x00000004u;
+  }
+  static const ::google::protobuf::ExtensionRangeOptions& options(const DescriptorProto_ExtensionRange* msg);
+  static void set_has_options(DescriptorProto_ExtensionRange* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+};
+
+const ::google::protobuf::ExtensionRangeOptions&
+DescriptorProto_ExtensionRange::HasBitSetters::options(const DescriptorProto_ExtensionRange* msg) {
+  return *msg->options_;
+}
 void DescriptorProto_ExtensionRange::unsafe_arena_set_allocated_options(
     ::google::protobuf::ExtensionRangeOptions* options) {
   if (GetArenaNoVirtual() == NULL) {
@@ -2579,9 +2863,9 @@
   }
   options_ = options;
   if (options) {
-    set_has_options();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000001u;
   }
   // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.ExtensionRange.options)
 }
@@ -2593,15 +2877,12 @@
 
 DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ExtensionRange.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto.ExtensionRange)
 }
 DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ExtensionRange.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ExtensionRange)
@@ -2623,6 +2904,8 @@
 }
 
 void DescriptorProto_ExtensionRange::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_DescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto.base);
   ::memset(&options_, 0, static_cast<size_t>(
       reinterpret_cast<char*>(&end_) -
       reinterpret_cast<char*>(&options_)) + sizeof(end_));
@@ -2647,13 +2930,8 @@
 void DescriptorProto_ExtensionRange::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const DescriptorProto_ExtensionRange& DescriptorProto_ExtensionRange::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ExtensionRange.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_DescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -2669,7 +2947,7 @@
     GOOGLE_DCHECK(options_ != NULL);
     options_->Clear();
   }
-  if (cached_has_bits & 6u) {
+  if (cached_has_bits & 0x00000006u) {
     ::memset(&start_, 0, static_cast<size_t>(
         reinterpret_cast<char*>(&end_) -
         reinterpret_cast<char*>(&start_)) + sizeof(end_));
@@ -2678,9 +2956,81 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* DescriptorProto_ExtensionRange::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<DescriptorProto_ExtensionRange*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional int32 start = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_start(value);
+        break;
+      }
+      // optional int32 end = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_end(value);
+        break;
+      }
+      // optional .google.protobuf.ExtensionRangeOptions options = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::ExtensionRangeOptions::_InternalParse;
+        object = msg->mutable_options();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.DescriptorProto.ExtensionRange)
   for (;;) {
@@ -2690,9 +3040,8 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional int32 start = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
-          set_has_start();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          HasBitSetters::set_has_start(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &start_)));
@@ -2704,9 +3053,8 @@
 
       // optional int32 end = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
-          set_has_end();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          HasBitSetters::set_has_end(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &end_)));
@@ -2718,8 +3066,7 @@
 
       // optional .google.protobuf.ExtensionRangeOptions options = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_options()));
         } else {
@@ -2747,6 +3094,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void DescriptorProto_ExtensionRange::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -2768,7 +3116,7 @@
   // optional .google.protobuf.ExtensionRangeOptions options = 3;
   if (cached_has_bits & 0x00000001u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      3, this->_internal_options(), output);
+      3, HasBitSetters::options(this), output);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -2800,7 +3148,7 @@
   if (cached_has_bits & 0x00000001u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        3, this->_internal_options(), deterministic, target);
+        3, HasBitSetters::options(this), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -2820,23 +3168,28 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
-  if (_has_bits_[0 / 32] & 7u) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000007u) {
     // optional .google.protobuf.ExtensionRangeOptions options = 3;
-    if (has_options()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::MessageSize(
           *options_);
     }
 
     // optional int32 start = 1;
-    if (has_start()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->start());
     }
 
     // optional int32 end = 2;
-    if (has_end()) {
+    if (cached_has_bits & 0x00000004u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->end());
@@ -2852,7 +3205,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange)
   GOOGLE_DCHECK_NE(&from, this);
   const DescriptorProto_ExtensionRange* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto_ExtensionRange>(
+      ::google::protobuf::DynamicCastToGenerated<DescriptorProto_ExtensionRange>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.DescriptorProto.ExtensionRange)
@@ -2871,7 +3224,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 7u) {
+  if (cached_has_bits & 0x00000007u) {
     if (cached_has_bits & 0x00000001u) {
       mutable_options()->::google::protobuf::ExtensionRangeOptions::MergeFrom(from.options());
     }
@@ -2927,16 +3280,16 @@
 }
 void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   swap(options_, other->options_);
   swap(start_, other->start_);
   swap(end_, other->end_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -2944,6 +3297,16 @@
 
 void DescriptorProto_ReservedRange::InitAsDefaultInstance() {
 }
+class DescriptorProto_ReservedRange::HasBitSetters {
+ public:
+  static void set_has_start(DescriptorProto_ReservedRange* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_end(DescriptorProto_ReservedRange* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int DescriptorProto_ReservedRange::kStartFieldNumber;
 const int DescriptorProto_ReservedRange::kEndFieldNumber;
@@ -2951,15 +3314,12 @@
 
 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ReservedRange.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto.ReservedRange)
 }
 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ReservedRange.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ReservedRange)
@@ -2999,13 +3359,8 @@
 void DescriptorProto_ReservedRange::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* DescriptorProto_ReservedRange::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto_ReservedRange.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_DescriptorProto_ReservedRange_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -3017,7 +3372,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     ::memset(&start_, 0, static_cast<size_t>(
         reinterpret_cast<char*>(&end_) -
         reinterpret_cast<char*>(&start_)) + sizeof(end_));
@@ -3026,9 +3381,68 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* DescriptorProto_ReservedRange::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<DescriptorProto_ReservedRange*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional int32 start = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_start(value);
+        break;
+      }
+      // optional int32 end = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_end(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool DescriptorProto_ReservedRange::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.DescriptorProto.ReservedRange)
   for (;;) {
@@ -3038,9 +3452,8 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional int32 start = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
-          set_has_start();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          HasBitSetters::set_has_start(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &start_)));
@@ -3052,9 +3465,8 @@
 
       // optional int32 end = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
-          set_has_end();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          HasBitSetters::set_has_end(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &end_)));
@@ -3083,6 +3495,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void DescriptorProto_ReservedRange::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -3143,16 +3556,21 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
-  if (_has_bits_[0 / 32] & 3u) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000003u) {
     // optional int32 start = 1;
-    if (has_start()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->start());
     }
 
     // optional int32 end = 2;
-    if (has_end()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->end());
@@ -3168,7 +3586,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DescriptorProto.ReservedRange)
   GOOGLE_DCHECK_NE(&from, this);
   const DescriptorProto_ReservedRange* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto_ReservedRange>(
+      ::google::protobuf::DynamicCastToGenerated<DescriptorProto_ReservedRange>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.DescriptorProto.ReservedRange)
@@ -3187,7 +3605,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       start_ = from.start_;
     }
@@ -3237,15 +3655,15 @@
 }
 void DescriptorProto_ReservedRange::InternalSwap(DescriptorProto_ReservedRange* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   swap(start_, other->start_);
   swap(end_, other->end_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata DescriptorProto_ReservedRange::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -3255,6 +3673,21 @@
   ::google::protobuf::_DescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::MessageOptions*>(
       ::google::protobuf::MessageOptions::internal_default_instance());
 }
+class DescriptorProto::HasBitSetters {
+ public:
+  static void set_has_name(DescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static const ::google::protobuf::MessageOptions& options(const DescriptorProto* msg);
+  static void set_has_options(DescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+};
+
+const ::google::protobuf::MessageOptions&
+DescriptorProto::HasBitSetters::options(const DescriptorProto* msg) {
+  return *msg->options_;
+}
 void DescriptorProto::unsafe_arena_set_allocated_options(
     ::google::protobuf::MessageOptions* options) {
   if (GetArenaNoVirtual() == NULL) {
@@ -3262,9 +3695,9 @@
   }
   options_ = options;
   if (options) {
-    set_has_options();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000002u;
   }
   // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.options)
 }
@@ -3283,8 +3716,6 @@
 
 DescriptorProto::DescriptorProto()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto)
 }
@@ -3299,7 +3730,6 @@
   oneof_decl_(arena),
   reserved_range_(arena),
   reserved_name_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto)
@@ -3331,6 +3761,8 @@
 }
 
 void DescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_DescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   options_ = NULL;
 }
@@ -3355,13 +3787,8 @@
 void DescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* DescriptorProto::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const DescriptorProto& DescriptorProto::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_DescriptorProto.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_DescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -3381,7 +3808,7 @@
   reserved_range_.Clear();
   reserved_name_.Clear();
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       name_.ClearNonDefaultToEmpty();
     }
@@ -3394,9 +3821,208 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* DescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<DescriptorProto*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.DescriptorProto.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated .google.protobuf.FieldDescriptorProto field = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::FieldDescriptorProto::_InternalParse;
+          object = msg->add_field();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 18 && (ptr += 1));
+        break;
+      }
+      // repeated .google.protobuf.DescriptorProto nested_type = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::DescriptorProto::_InternalParse;
+          object = msg->add_nested_type();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 26 && (ptr += 1));
+        break;
+      }
+      // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::EnumDescriptorProto::_InternalParse;
+          object = msg->add_enum_type();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 34 && (ptr += 1));
+        break;
+      }
+      // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::DescriptorProto_ExtensionRange::_InternalParse;
+          object = msg->add_extension_range();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 42 && (ptr += 1));
+        break;
+      }
+      // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::FieldDescriptorProto::_InternalParse;
+          object = msg->add_extension();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 50 && (ptr += 1));
+        break;
+      }
+      // optional .google.protobuf.MessageOptions options = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::MessageOptions::_InternalParse;
+        object = msg->mutable_options();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+      case 8: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::OneofDescriptorProto::_InternalParse;
+          object = msg->add_oneof_decl();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 66 && (ptr += 1));
+        break;
+      }
+      // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
+      case 9: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 74) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::DescriptorProto_ReservedRange::_InternalParse;
+          object = msg->add_reserved_range();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 74 && (ptr += 1));
+        break;
+      }
+      // repeated string reserved_name = 10;
+      case 10: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 82) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          ctx->extra_parse_data().SetFieldName("google.protobuf.DescriptorProto.reserved_name");
+          parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+          ::std::string* str = msg->add_reserved_name();
+          str->clear();
+          object = str;
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 82 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool DescriptorProto::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.DescriptorProto)
   for (;;) {
@@ -3406,8 +4032,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -3422,8 +4047,7 @@
 
       // repeated .google.protobuf.FieldDescriptorProto field = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_field()));
         } else {
@@ -3434,8 +4058,7 @@
 
       // repeated .google.protobuf.DescriptorProto nested_type = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_nested_type()));
         } else {
@@ -3446,8 +4069,7 @@
 
       // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_enum_type()));
         } else {
@@ -3458,8 +4080,7 @@
 
       // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
       case 5: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_extension_range()));
         } else {
@@ -3470,8 +4091,7 @@
 
       // repeated .google.protobuf.FieldDescriptorProto extension = 6;
       case 6: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_extension()));
         } else {
@@ -3482,8 +4102,7 @@
 
       // optional .google.protobuf.MessageOptions options = 7;
       case 7: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (58 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_options()));
         } else {
@@ -3494,8 +4113,7 @@
 
       // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
       case 8: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (66 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_oneof_decl()));
         } else {
@@ -3506,8 +4124,7 @@
 
       // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
       case 9: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(74u /* 74 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (74 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_reserved_range()));
         } else {
@@ -3518,8 +4135,7 @@
 
       // repeated string reserved_name = 10;
       case 10: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(82u /* 82 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (82 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->add_reserved_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -3552,6 +4168,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void DescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -3618,7 +4235,7 @@
   // optional .google.protobuf.MessageOptions options = 7;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      7, this->_internal_options(), output);
+      7, HasBitSetters::options(this), output);
   }
 
   // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
@@ -3719,7 +4336,7 @@
   if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        7, this->_internal_options(), deterministic, target);
+        7, HasBitSetters::options(this), deterministic, target);
   }
 
   // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
@@ -3765,6 +4382,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.FieldDescriptorProto field = 2;
   {
     unsigned int count = static_cast<unsigned int>(this->field_size());
@@ -3850,16 +4471,17 @@
       this->reserved_name(i));
   }
 
-  if (_has_bits_[0 / 32] & 3u) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000003u) {
     // optional string name = 1;
-    if (has_name()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->name());
     }
 
     // optional .google.protobuf.MessageOptions options = 7;
-    if (has_options()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::MessageSize(
           *options_);
@@ -3875,7 +4497,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   const DescriptorProto* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto>(
+      ::google::protobuf::DynamicCastToGenerated<DescriptorProto>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.DescriptorProto)
@@ -3902,7 +4524,7 @@
   reserved_range_.MergeFrom(from.reserved_range_);
   reserved_name_.MergeFrom(from.reserved_name_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       set_name(from.name());
     }
@@ -3960,6 +4582,8 @@
 }
 void DescriptorProto::InternalSwap(DescriptorProto* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   CastToBase(&field_)->InternalSwap(CastToBase(&other->field_));
   CastToBase(&nested_type_)->InternalSwap(CastToBase(&other->nested_type_));
   CastToBase(&enum_type_)->InternalSwap(CastToBase(&other->enum_type_));
@@ -3971,13 +4595,11 @@
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   swap(options_, other->options_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata DescriptorProto::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -3985,14 +4607,16 @@
 
 void ExtensionRangeOptions::InitAsDefaultInstance() {
 }
+class ExtensionRangeOptions::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int ExtensionRangeOptions::kUninterpretedOptionFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 ExtensionRangeOptions::ExtensionRangeOptions()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ExtensionRangeOptions.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.ExtensionRangeOptions)
 }
@@ -4001,7 +4625,6 @@
   _extensions_(arena),
   _internal_metadata_(arena),
   uninterpreted_option_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ExtensionRangeOptions.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.ExtensionRangeOptions)
@@ -4017,6 +4640,8 @@
 }
 
 void ExtensionRangeOptions::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ExtensionRangeOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
 }
 
 ExtensionRangeOptions::~ExtensionRangeOptions() {
@@ -4037,13 +4662,8 @@
 void ExtensionRangeOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* ExtensionRangeOptions::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const ExtensionRangeOptions& ExtensionRangeOptions::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ExtensionRangeOptions.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_ExtensionRangeOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -4060,9 +4680,71 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ExtensionRangeOptions::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ExtensionRangeOptions*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
+          object = msg->add_uninterpreted_option();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 65535) == 16058 && (ptr += 2));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+      if ((8000u <= tag)) {
+        auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
+            internal_default_instance(), &msg->_internal_metadata_, ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+        continue;
+      }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool ExtensionRangeOptions::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.ExtensionRangeOptions)
   for (;;) {
@@ -4072,8 +4754,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
       case 999: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (7994 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_uninterpreted_option()));
         } else {
@@ -4107,6 +4788,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void ExtensionRangeOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -4124,8 +4806,7 @@
   }
 
   // Extension range [1000, 536870912)
-  _extensions_.SerializeWithCachedSizes(
-      1000, 536870912, output);
+  _extensions_.SerializeWithCachedSizes(1000, 536870912, output);
 
   if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
@@ -4172,6 +4853,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
     unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
@@ -4192,7 +4877,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ExtensionRangeOptions)
   GOOGLE_DCHECK_NE(&from, this);
   const ExtensionRangeOptions* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const ExtensionRangeOptions>(
+      ::google::protobuf::DynamicCastToGenerated<ExtensionRangeOptions>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.ExtensionRangeOptions)
@@ -4258,15 +4943,15 @@
 }
 void ExtensionRangeOptions::InternalSwap(ExtensionRangeOptions* other) {
   using std::swap;
-  CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
   _extensions_.Swap(&other->_extensions_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
+  CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
 }
 
 ::google::protobuf::Metadata ExtensionRangeOptions::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -4276,6 +4961,45 @@
   ::google::protobuf::_FieldDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::FieldOptions*>(
       ::google::protobuf::FieldOptions::internal_default_instance());
 }
+class FieldDescriptorProto::HasBitSetters {
+ public:
+  static void set_has_name(FieldDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_number(FieldDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000040u;
+  }
+  static void set_has_label(FieldDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000100u;
+  }
+  static void set_has_type(FieldDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000200u;
+  }
+  static void set_has_type_name(FieldDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000004u;
+  }
+  static void set_has_extendee(FieldDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+  static void set_has_default_value(FieldDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000008u;
+  }
+  static void set_has_oneof_index(FieldDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000080u;
+  }
+  static void set_has_json_name(FieldDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000010u;
+  }
+  static const ::google::protobuf::FieldOptions& options(const FieldDescriptorProto* msg);
+  static void set_has_options(FieldDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000020u;
+  }
+};
+
+const ::google::protobuf::FieldOptions&
+FieldDescriptorProto::HasBitSetters::options(const FieldDescriptorProto* msg) {
+  return *msg->options_;
+}
 void FieldDescriptorProto::unsafe_arena_set_allocated_options(
     ::google::protobuf::FieldOptions* options) {
   if (GetArenaNoVirtual() == NULL) {
@@ -4283,9 +5007,9 @@
   }
   options_ = options;
   if (options) {
-    set_has_options();
+    _has_bits_[0] |= 0x00000020u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000020u;
   }
   // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.options)
 }
@@ -4304,15 +5028,12 @@
 
 FieldDescriptorProto::FieldDescriptorProto()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldDescriptorProto.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.FieldDescriptorProto)
 }
 FieldDescriptorProto::FieldDescriptorProto(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldDescriptorProto.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldDescriptorProto)
@@ -4359,6 +5080,8 @@
 }
 
 void FieldDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_FieldDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   extendee_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   type_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -4395,13 +5118,8 @@
 void FieldDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const FieldDescriptorProto& FieldDescriptorProto::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldDescriptorProto.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_FieldDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -4413,7 +5131,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 63u) {
+  if (cached_has_bits & 0x0000003fu) {
     if (cached_has_bits & 0x00000001u) {
       name_.ClearNonDefaultToEmpty();
     }
@@ -4434,12 +5152,12 @@
       options_->Clear();
     }
   }
-  if (cached_has_bits & 192u) {
+  if (cached_has_bits & 0x000000c0u) {
     ::memset(&number_, 0, static_cast<size_t>(
         reinterpret_cast<char*>(&oneof_index_) -
         reinterpret_cast<char*>(&number_)) + sizeof(oneof_index_));
   }
-  if (cached_has_bits & 768u) {
+  if (cached_has_bits & 0x00000300u) {
     label_ = 1;
     type_ = 1;
   }
@@ -4447,9 +5165,189 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* FieldDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<FieldDescriptorProto*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FieldDescriptorProto.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string extendee = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FieldDescriptorProto.extendee");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_extendee();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional int32 number = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_number(value);
+        break;
+      }
+      // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        if (!::google::protobuf::FieldDescriptorProto_Label_IsValid(val)) {
+          ::google::protobuf::internal::WriteVarint(4, val, msg->mutable_unknown_fields());
+          break;
+        }
+        ::google::protobuf::FieldDescriptorProto_Label value = static_cast<::google::protobuf::FieldDescriptorProto_Label>(val);
+        msg->set_label(value);
+        break;
+      }
+      // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        if (!::google::protobuf::FieldDescriptorProto_Type_IsValid(val)) {
+          ::google::protobuf::internal::WriteVarint(5, val, msg->mutable_unknown_fields());
+          break;
+        }
+        ::google::protobuf::FieldDescriptorProto_Type value = static_cast<::google::protobuf::FieldDescriptorProto_Type>(val);
+        msg->set_type(value);
+        break;
+      }
+      // optional string type_name = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FieldDescriptorProto.type_name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_type_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string default_value = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FieldDescriptorProto.default_value");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_default_value();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional .google.protobuf.FieldOptions options = 8;
+      case 8: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::FieldOptions::_InternalParse;
+        object = msg->mutable_options();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional int32 oneof_index = 9;
+      case 9: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 72) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_oneof_index(value);
+        break;
+      }
+      // optional string json_name = 10;
+      case 10: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 82) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FieldDescriptorProto.json_name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_json_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool FieldDescriptorProto::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.FieldDescriptorProto)
   for (;;) {
@@ -4459,8 +5357,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -4475,8 +5372,7 @@
 
       // optional string extendee = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_extendee()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -4491,9 +5387,8 @@
 
       // optional int32 number = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
-          set_has_number();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          HasBitSetters::set_has_number(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &number_)));
@@ -4505,8 +5400,7 @@
 
       // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
           int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -4515,7 +5409,7 @@
             set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value));
           } else {
             mutable_unknown_fields()->AddVarint(
-                4, static_cast< ::google::protobuf::uint64>(value));
+                4, static_cast<::google::protobuf::uint64>(value));
           }
         } else {
           goto handle_unusual;
@@ -4525,8 +5419,7 @@
 
       // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
       case 5: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
           int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -4535,7 +5428,7 @@
             set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value));
           } else {
             mutable_unknown_fields()->AddVarint(
-                5, static_cast< ::google::protobuf::uint64>(value));
+                5, static_cast<::google::protobuf::uint64>(value));
           }
         } else {
           goto handle_unusual;
@@ -4545,8 +5438,7 @@
 
       // optional string type_name = 6;
       case 6: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_type_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -4561,8 +5453,7 @@
 
       // optional string default_value = 7;
       case 7: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (58 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_default_value()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -4577,8 +5468,7 @@
 
       // optional .google.protobuf.FieldOptions options = 8;
       case 8: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (66 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_options()));
         } else {
@@ -4589,9 +5479,8 @@
 
       // optional int32 oneof_index = 9;
       case 9: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(72u /* 72 & 0xFF */)) {
-          set_has_oneof_index();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (72 & 0xFF)) {
+          HasBitSetters::set_has_oneof_index(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &oneof_index_)));
@@ -4603,8 +5492,7 @@
 
       // optional string json_name = 10;
       case 10: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(82u /* 82 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (82 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_json_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -4636,6 +5524,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void FieldDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -4704,7 +5593,7 @@
   // optional .google.protobuf.FieldOptions options = 8;
   if (cached_has_bits & 0x00000020u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      8, this->_internal_options(), output);
+      8, HasBitSetters::options(this), output);
   }
 
   // optional int32 oneof_index = 9;
@@ -4802,7 +5691,7 @@
   if (cached_has_bits & 0x00000020u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        8, this->_internal_options(), deterministic, target);
+        8, HasBitSetters::options(this), deterministic, target);
   }
 
   // optional int32 oneof_index = 9;
@@ -4838,73 +5727,78 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
-  if (_has_bits_[0 / 32] & 255u) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x000000ffu) {
     // optional string name = 1;
-    if (has_name()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->name());
     }
 
     // optional string extendee = 2;
-    if (has_extendee()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->extendee());
     }
 
     // optional string type_name = 6;
-    if (has_type_name()) {
+    if (cached_has_bits & 0x00000004u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->type_name());
     }
 
     // optional string default_value = 7;
-    if (has_default_value()) {
+    if (cached_has_bits & 0x00000008u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->default_value());
     }
 
     // optional string json_name = 10;
-    if (has_json_name()) {
+    if (cached_has_bits & 0x00000010u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->json_name());
     }
 
     // optional .google.protobuf.FieldOptions options = 8;
-    if (has_options()) {
+    if (cached_has_bits & 0x00000020u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::MessageSize(
           *options_);
     }
 
     // optional int32 number = 3;
-    if (has_number()) {
+    if (cached_has_bits & 0x00000040u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->number());
     }
 
     // optional int32 oneof_index = 9;
-    if (has_oneof_index()) {
+    if (cached_has_bits & 0x00000080u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->oneof_index());
     }
 
   }
-  if (_has_bits_[8 / 32] & 768u) {
+  if (cached_has_bits & 0x00000300u) {
     // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
-    if (has_label()) {
+    if (cached_has_bits & 0x00000100u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::EnumSize(this->label());
     }
 
     // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
-    if (has_type()) {
+    if (cached_has_bits & 0x00000200u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
     }
@@ -4919,7 +5813,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   const FieldDescriptorProto* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const FieldDescriptorProto>(
+      ::google::protobuf::DynamicCastToGenerated<FieldDescriptorProto>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FieldDescriptorProto)
@@ -4938,7 +5832,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 255u) {
+  if (cached_has_bits & 0x000000ffu) {
     if (cached_has_bits & 0x00000001u) {
       set_name(from.name());
     }
@@ -4965,7 +5859,7 @@
     }
     _has_bits_[0] |= cached_has_bits;
   }
-  if (cached_has_bits & 768u) {
+  if (cached_has_bits & 0x00000300u) {
     if (cached_has_bits & 0x00000100u) {
       label_ = from.label_;
     }
@@ -5018,6 +5912,8 @@
 }
 void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   extendee_.Swap(&other->extendee_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
@@ -5033,13 +5929,11 @@
   swap(oneof_index_, other->oneof_index_);
   swap(label_, other->label_);
   swap(type_, other->type_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -5049,6 +5943,21 @@
   ::google::protobuf::_OneofDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::OneofOptions*>(
       ::google::protobuf::OneofOptions::internal_default_instance());
 }
+class OneofDescriptorProto::HasBitSetters {
+ public:
+  static void set_has_name(OneofDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static const ::google::protobuf::OneofOptions& options(const OneofDescriptorProto* msg);
+  static void set_has_options(OneofDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+};
+
+const ::google::protobuf::OneofOptions&
+OneofDescriptorProto::HasBitSetters::options(const OneofDescriptorProto* msg) {
+  return *msg->options_;
+}
 void OneofDescriptorProto::unsafe_arena_set_allocated_options(
     ::google::protobuf::OneofOptions* options) {
   if (GetArenaNoVirtual() == NULL) {
@@ -5056,9 +5965,9 @@
   }
   options_ = options;
   if (options) {
-    set_has_options();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000002u;
   }
   // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.OneofDescriptorProto.options)
 }
@@ -5069,15 +5978,12 @@
 
 OneofDescriptorProto::OneofDescriptorProto()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofDescriptorProto.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.OneofDescriptorProto)
 }
 OneofDescriptorProto::OneofDescriptorProto(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofDescriptorProto.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofDescriptorProto)
@@ -5101,6 +6007,8 @@
 }
 
 void OneofDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_OneofDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   options_ = NULL;
 }
@@ -5125,13 +6033,8 @@
 void OneofDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* OneofDescriptorProto::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const OneofDescriptorProto& OneofDescriptorProto::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofDescriptorProto.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_OneofDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -5143,7 +6046,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       name_.ClearNonDefaultToEmpty();
     }
@@ -5156,9 +6059,77 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* OneofDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<OneofDescriptorProto*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.OneofDescriptorProto.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional .google.protobuf.OneofOptions options = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::OneofOptions::_InternalParse;
+        object = msg->mutable_options();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool OneofDescriptorProto::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.OneofDescriptorProto)
   for (;;) {
@@ -5168,8 +6139,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -5184,8 +6154,7 @@
 
       // optional .google.protobuf.OneofOptions options = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_options()));
         } else {
@@ -5213,6 +6182,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void OneofDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -5234,7 +6204,7 @@
   // optional .google.protobuf.OneofOptions options = 2;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      2, this->_internal_options(), output);
+      2, HasBitSetters::options(this), output);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -5267,7 +6237,7 @@
   if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        2, this->_internal_options(), deterministic, target);
+        2, HasBitSetters::options(this), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -5287,16 +6257,21 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
-  if (_has_bits_[0 / 32] & 3u) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000003u) {
     // optional string name = 1;
-    if (has_name()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->name());
     }
 
     // optional .google.protobuf.OneofOptions options = 2;
-    if (has_options()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::MessageSize(
           *options_);
@@ -5312,7 +6287,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.OneofDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   const OneofDescriptorProto* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const OneofDescriptorProto>(
+      ::google::protobuf::DynamicCastToGenerated<OneofDescriptorProto>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.OneofDescriptorProto)
@@ -5331,7 +6306,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       set_name(from.name());
     }
@@ -5383,16 +6358,16 @@
 }
 void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   swap(options_, other->options_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata OneofDescriptorProto::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -5400,6 +6375,16 @@
 
 void EnumDescriptorProto_EnumReservedRange::InitAsDefaultInstance() {
 }
+class EnumDescriptorProto_EnumReservedRange::HasBitSetters {
+ public:
+  static void set_has_start(EnumDescriptorProto_EnumReservedRange* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_end(EnumDescriptorProto_EnumReservedRange* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int EnumDescriptorProto_EnumReservedRange::kStartFieldNumber;
 const int EnumDescriptorProto_EnumReservedRange::kEndFieldNumber;
@@ -5407,15 +6392,12 @@
 
 EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto_EnumReservedRange.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
 }
 EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto_EnumReservedRange.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange)
@@ -5455,13 +6437,8 @@
 void EnumDescriptorProto_EnumReservedRange::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* EnumDescriptorProto_EnumReservedRange::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const EnumDescriptorProto_EnumReservedRange& EnumDescriptorProto_EnumReservedRange::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto_EnumReservedRange.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_EnumDescriptorProto_EnumReservedRange_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -5473,7 +6450,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     ::memset(&start_, 0, static_cast<size_t>(
         reinterpret_cast<char*>(&end_) -
         reinterpret_cast<char*>(&start_)) + sizeof(end_));
@@ -5482,9 +6459,68 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EnumDescriptorProto_EnumReservedRange::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EnumDescriptorProto_EnumReservedRange*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional int32 start = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_start(value);
+        break;
+      }
+      // optional int32 end = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_end(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool EnumDescriptorProto_EnumReservedRange::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
   for (;;) {
@@ -5494,9 +6530,8 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional int32 start = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
-          set_has_start();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          HasBitSetters::set_has_start(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &start_)));
@@ -5508,9 +6543,8 @@
 
       // optional int32 end = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
-          set_has_end();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          HasBitSetters::set_has_end(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &end_)));
@@ -5539,6 +6573,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void EnumDescriptorProto_EnumReservedRange::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -5599,16 +6634,21 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
-  if (_has_bits_[0 / 32] & 3u) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000003u) {
     // optional int32 start = 1;
-    if (has_start()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->start());
     }
 
     // optional int32 end = 2;
-    if (has_end()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->end());
@@ -5624,7 +6664,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumDescriptorProto.EnumReservedRange)
   GOOGLE_DCHECK_NE(&from, this);
   const EnumDescriptorProto_EnumReservedRange* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const EnumDescriptorProto_EnumReservedRange>(
+      ::google::protobuf::DynamicCastToGenerated<EnumDescriptorProto_EnumReservedRange>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.EnumDescriptorProto.EnumReservedRange)
@@ -5643,7 +6683,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       start_ = from.start_;
     }
@@ -5693,15 +6733,15 @@
 }
 void EnumDescriptorProto_EnumReservedRange::InternalSwap(EnumDescriptorProto_EnumReservedRange* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   swap(start_, other->start_);
   swap(end_, other->end_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata EnumDescriptorProto_EnumReservedRange::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -5711,6 +6751,21 @@
   ::google::protobuf::_EnumDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::EnumOptions*>(
       ::google::protobuf::EnumOptions::internal_default_instance());
 }
+class EnumDescriptorProto::HasBitSetters {
+ public:
+  static void set_has_name(EnumDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static const ::google::protobuf::EnumOptions& options(const EnumDescriptorProto* msg);
+  static void set_has_options(EnumDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+};
+
+const ::google::protobuf::EnumOptions&
+EnumDescriptorProto::HasBitSetters::options(const EnumDescriptorProto* msg) {
+  return *msg->options_;
+}
 void EnumDescriptorProto::unsafe_arena_set_allocated_options(
     ::google::protobuf::EnumOptions* options) {
   if (GetArenaNoVirtual() == NULL) {
@@ -5718,9 +6773,9 @@
   }
   options_ = options;
   if (options) {
-    set_has_options();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000002u;
   }
   // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumDescriptorProto.options)
 }
@@ -5734,8 +6789,6 @@
 
 EnumDescriptorProto::EnumDescriptorProto()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.EnumDescriptorProto)
 }
@@ -5745,7 +6798,6 @@
   value_(arena),
   reserved_range_(arena),
   reserved_name_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto)
@@ -5772,6 +6824,8 @@
 }
 
 void EnumDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_EnumDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   options_ = NULL;
 }
@@ -5796,13 +6850,8 @@
 void EnumDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const EnumDescriptorProto& EnumDescriptorProto::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumDescriptorProto.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_EnumDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -5817,7 +6866,7 @@
   reserved_range_.Clear();
   reserved_name_.Clear();
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       name_.ClearNonDefaultToEmpty();
     }
@@ -5830,9 +6879,128 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EnumDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EnumDescriptorProto*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.EnumDescriptorProto.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::EnumValueDescriptorProto::_InternalParse;
+          object = msg->add_value();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 18 && (ptr += 1));
+        break;
+      }
+      // optional .google.protobuf.EnumOptions options = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::EnumOptions::_InternalParse;
+        object = msg->mutable_options();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::EnumDescriptorProto_EnumReservedRange::_InternalParse;
+          object = msg->add_reserved_range();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 34 && (ptr += 1));
+        break;
+      }
+      // repeated string reserved_name = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          ctx->extra_parse_data().SetFieldName("google.protobuf.EnumDescriptorProto.reserved_name");
+          parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+          ::std::string* str = msg->add_reserved_name();
+          str->clear();
+          object = str;
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 42 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool EnumDescriptorProto::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.EnumDescriptorProto)
   for (;;) {
@@ -5842,8 +7010,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -5858,8 +7025,7 @@
 
       // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_value()));
         } else {
@@ -5870,8 +7036,7 @@
 
       // optional .google.protobuf.EnumOptions options = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_options()));
         } else {
@@ -5882,8 +7047,7 @@
 
       // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_reserved_range()));
         } else {
@@ -5894,8 +7058,7 @@
 
       // repeated string reserved_name = 5;
       case 5: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->add_reserved_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -5928,6 +7091,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void EnumDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -5958,7 +7122,7 @@
   // optional .google.protobuf.EnumOptions options = 3;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      3, this->_internal_options(), output);
+      3, HasBitSetters::options(this), output);
   }
 
   // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
@@ -6018,7 +7182,7 @@
   if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        3, this->_internal_options(), deterministic, target);
+        3, HasBitSetters::options(this), deterministic, target);
   }
 
   // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4;
@@ -6056,6 +7220,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
   {
     unsigned int count = static_cast<unsigned int>(this->value_size());
@@ -6086,16 +7254,17 @@
       this->reserved_name(i));
   }
 
-  if (_has_bits_[0 / 32] & 3u) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000003u) {
     // optional string name = 1;
-    if (has_name()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->name());
     }
 
     // optional .google.protobuf.EnumOptions options = 3;
-    if (has_options()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::MessageSize(
           *options_);
@@ -6111,7 +7280,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   const EnumDescriptorProto* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const EnumDescriptorProto>(
+      ::google::protobuf::DynamicCastToGenerated<EnumDescriptorProto>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.EnumDescriptorProto)
@@ -6133,7 +7302,7 @@
   reserved_range_.MergeFrom(from.reserved_range_);
   reserved_name_.MergeFrom(from.reserved_name_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       set_name(from.name());
     }
@@ -6186,19 +7355,19 @@
 }
 void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   CastToBase(&value_)->InternalSwap(CastToBase(&other->value_));
   CastToBase(&reserved_range_)->InternalSwap(CastToBase(&other->reserved_range_));
   reserved_name_.InternalSwap(CastToBase(&other->reserved_name_));
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   swap(options_, other->options_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -6208,6 +7377,24 @@
   ::google::protobuf::_EnumValueDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::EnumValueOptions*>(
       ::google::protobuf::EnumValueOptions::internal_default_instance());
 }
+class EnumValueDescriptorProto::HasBitSetters {
+ public:
+  static void set_has_name(EnumValueDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_number(EnumValueDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000004u;
+  }
+  static const ::google::protobuf::EnumValueOptions& options(const EnumValueDescriptorProto* msg);
+  static void set_has_options(EnumValueDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+};
+
+const ::google::protobuf::EnumValueOptions&
+EnumValueDescriptorProto::HasBitSetters::options(const EnumValueDescriptorProto* msg) {
+  return *msg->options_;
+}
 void EnumValueDescriptorProto::unsafe_arena_set_allocated_options(
     ::google::protobuf::EnumValueOptions* options) {
   if (GetArenaNoVirtual() == NULL) {
@@ -6215,9 +7402,9 @@
   }
   options_ = options;
   if (options) {
-    set_has_options();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000002u;
   }
   // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
 }
@@ -6229,15 +7416,12 @@
 
 EnumValueDescriptorProto::EnumValueDescriptorProto()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueDescriptorProto.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.EnumValueDescriptorProto)
 }
 EnumValueDescriptorProto::EnumValueDescriptorProto(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueDescriptorProto.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueDescriptorProto)
@@ -6262,6 +7446,8 @@
 }
 
 void EnumValueDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_EnumValueDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   ::memset(&options_, 0, static_cast<size_t>(
       reinterpret_cast<char*>(&number_) -
@@ -6288,13 +7474,8 @@
 void EnumValueDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const EnumValueDescriptorProto& EnumValueDescriptorProto::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueDescriptorProto.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_EnumValueDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -6306,7 +7487,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       name_.ClearNonDefaultToEmpty();
     }
@@ -6320,9 +7501,87 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EnumValueDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EnumValueDescriptorProto*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.EnumValueDescriptorProto.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional int32 number = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_number(value);
+        break;
+      }
+      // optional .google.protobuf.EnumValueOptions options = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::EnumValueOptions::_InternalParse;
+        object = msg->mutable_options();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool EnumValueDescriptorProto::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.EnumValueDescriptorProto)
   for (;;) {
@@ -6332,8 +7591,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -6348,9 +7606,8 @@
 
       // optional int32 number = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
-          set_has_number();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          HasBitSetters::set_has_number(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &number_)));
@@ -6362,8 +7619,7 @@
 
       // optional .google.protobuf.EnumValueOptions options = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_options()));
         } else {
@@ -6391,6 +7647,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void EnumValueDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -6417,7 +7674,7 @@
   // optional .google.protobuf.EnumValueOptions options = 3;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      3, this->_internal_options(), output);
+      3, HasBitSetters::options(this), output);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -6455,7 +7712,7 @@
   if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        3, this->_internal_options(), deterministic, target);
+        3, HasBitSetters::options(this), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -6475,23 +7732,28 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
-  if (_has_bits_[0 / 32] & 7u) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000007u) {
     // optional string name = 1;
-    if (has_name()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->name());
     }
 
     // optional .google.protobuf.EnumValueOptions options = 3;
-    if (has_options()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::MessageSize(
           *options_);
     }
 
     // optional int32 number = 2;
-    if (has_number()) {
+    if (cached_has_bits & 0x00000004u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->number());
@@ -6507,7 +7769,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumValueDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   const EnumValueDescriptorProto* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const EnumValueDescriptorProto>(
+      ::google::protobuf::DynamicCastToGenerated<EnumValueDescriptorProto>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.EnumValueDescriptorProto)
@@ -6526,7 +7788,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 7u) {
+  if (cached_has_bits & 0x00000007u) {
     if (cached_has_bits & 0x00000001u) {
       set_name(from.name());
     }
@@ -6582,17 +7844,17 @@
 }
 void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   swap(options_, other->options_);
   swap(number_, other->number_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -6602,6 +7864,21 @@
   ::google::protobuf::_ServiceDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::ServiceOptions*>(
       ::google::protobuf::ServiceOptions::internal_default_instance());
 }
+class ServiceDescriptorProto::HasBitSetters {
+ public:
+  static void set_has_name(ServiceDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static const ::google::protobuf::ServiceOptions& options(const ServiceDescriptorProto* msg);
+  static void set_has_options(ServiceDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+};
+
+const ::google::protobuf::ServiceOptions&
+ServiceDescriptorProto::HasBitSetters::options(const ServiceDescriptorProto* msg) {
+  return *msg->options_;
+}
 void ServiceDescriptorProto::unsafe_arena_set_allocated_options(
     ::google::protobuf::ServiceOptions* options) {
   if (GetArenaNoVirtual() == NULL) {
@@ -6609,9 +7886,9 @@
   }
   options_ = options;
   if (options) {
-    set_has_options();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000002u;
   }
   // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.ServiceDescriptorProto.options)
 }
@@ -6623,8 +7900,6 @@
 
 ServiceDescriptorProto::ServiceDescriptorProto()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceDescriptorProto.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.ServiceDescriptorProto)
 }
@@ -6632,7 +7907,6 @@
   : ::google::protobuf::Message(),
   _internal_metadata_(arena),
   method_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceDescriptorProto.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceDescriptorProto)
@@ -6657,6 +7931,8 @@
 }
 
 void ServiceDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ServiceDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   options_ = NULL;
 }
@@ -6681,13 +7957,8 @@
 void ServiceDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const ServiceDescriptorProto& ServiceDescriptorProto::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceDescriptorProto.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_ServiceDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -6700,7 +7971,7 @@
 
   method_.Clear();
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       name_.ClearNonDefaultToEmpty();
     }
@@ -6713,9 +7984,93 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ServiceDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ServiceDescriptorProto*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.ServiceDescriptorProto.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated .google.protobuf.MethodDescriptorProto method = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::MethodDescriptorProto::_InternalParse;
+          object = msg->add_method();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 18 && (ptr += 1));
+        break;
+      }
+      // optional .google.protobuf.ServiceOptions options = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::ServiceOptions::_InternalParse;
+        object = msg->mutable_options();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool ServiceDescriptorProto::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.ServiceDescriptorProto)
   for (;;) {
@@ -6725,8 +8080,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -6741,8 +8095,7 @@
 
       // repeated .google.protobuf.MethodDescriptorProto method = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_method()));
         } else {
@@ -6753,8 +8106,7 @@
 
       // optional .google.protobuf.ServiceOptions options = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_options()));
         } else {
@@ -6782,6 +8134,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void ServiceDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -6812,7 +8165,7 @@
   // optional .google.protobuf.ServiceOptions options = 3;
   if (cached_has_bits & 0x00000002u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      3, this->_internal_options(), output);
+      3, HasBitSetters::options(this), output);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -6853,7 +8206,7 @@
   if (cached_has_bits & 0x00000002u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        3, this->_internal_options(), deterministic, target);
+        3, HasBitSetters::options(this), deterministic, target);
   }
 
   if (_internal_metadata_.have_unknown_fields()) {
@@ -6873,6 +8226,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.MethodDescriptorProto method = 2;
   {
     unsigned int count = static_cast<unsigned int>(this->method_size());
@@ -6884,16 +8241,17 @@
     }
   }
 
-  if (_has_bits_[0 / 32] & 3u) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000003u) {
     // optional string name = 1;
-    if (has_name()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->name());
     }
 
     // optional .google.protobuf.ServiceOptions options = 3;
-    if (has_options()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::MessageSize(
           *options_);
@@ -6909,7 +8267,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ServiceDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   const ServiceDescriptorProto* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const ServiceDescriptorProto>(
+      ::google::protobuf::DynamicCastToGenerated<ServiceDescriptorProto>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.ServiceDescriptorProto)
@@ -6929,7 +8287,7 @@
 
   method_.MergeFrom(from.method_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       set_name(from.name());
     }
@@ -6982,17 +8340,17 @@
 }
 void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   CastToBase(&method_)->InternalSwap(CastToBase(&other->method_));
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   swap(options_, other->options_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -7002,6 +8360,33 @@
   ::google::protobuf::_MethodDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< ::google::protobuf::MethodOptions*>(
       ::google::protobuf::MethodOptions::internal_default_instance());
 }
+class MethodDescriptorProto::HasBitSetters {
+ public:
+  static void set_has_name(MethodDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_input_type(MethodDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+  static void set_has_output_type(MethodDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000004u;
+  }
+  static const ::google::protobuf::MethodOptions& options(const MethodDescriptorProto* msg);
+  static void set_has_options(MethodDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000008u;
+  }
+  static void set_has_client_streaming(MethodDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000010u;
+  }
+  static void set_has_server_streaming(MethodDescriptorProto* msg) {
+    msg->_has_bits_[0] |= 0x00000020u;
+  }
+};
+
+const ::google::protobuf::MethodOptions&
+MethodDescriptorProto::HasBitSetters::options(const MethodDescriptorProto* msg) {
+  return *msg->options_;
+}
 void MethodDescriptorProto::unsafe_arena_set_allocated_options(
     ::google::protobuf::MethodOptions* options) {
   if (GetArenaNoVirtual() == NULL) {
@@ -7009,9 +8394,9 @@
   }
   options_ = options;
   if (options) {
-    set_has_options();
+    _has_bits_[0] |= 0x00000008u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000008u;
   }
   // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MethodDescriptorProto.options)
 }
@@ -7026,15 +8411,12 @@
 
 MethodDescriptorProto::MethodDescriptorProto()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodDescriptorProto.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.MethodDescriptorProto)
 }
 MethodDescriptorProto::MethodDescriptorProto(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodDescriptorProto.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodDescriptorProto)
@@ -7071,6 +8453,8 @@
 }
 
 void MethodDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_MethodDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   input_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   output_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -7101,13 +8485,8 @@
 void MethodDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const MethodDescriptorProto& MethodDescriptorProto::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodDescriptorProto.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_MethodDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -7119,7 +8498,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 15u) {
+  if (cached_has_bits & 0x0000000fu) {
     if (cached_has_bits & 0x00000001u) {
       name_.ClearNonDefaultToEmpty();
     }
@@ -7141,9 +8520,129 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* MethodDescriptorProto::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<MethodDescriptorProto*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.MethodDescriptorProto.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string input_type = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.MethodDescriptorProto.input_type");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_input_type();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string output_type = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.MethodDescriptorProto.output_type");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_output_type();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional .google.protobuf.MethodOptions options = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::MethodOptions::_InternalParse;
+        object = msg->mutable_options();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional bool client_streaming = 5 [default = false];
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_client_streaming(value);
+        break;
+      }
+      // optional bool server_streaming = 6 [default = false];
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 48) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_server_streaming(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool MethodDescriptorProto::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.MethodDescriptorProto)
   for (;;) {
@@ -7153,8 +8652,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -7169,8 +8667,7 @@
 
       // optional string input_type = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_input_type()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -7185,8 +8682,7 @@
 
       // optional string output_type = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_output_type()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -7201,8 +8697,7 @@
 
       // optional .google.protobuf.MethodOptions options = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_options()));
         } else {
@@ -7213,9 +8708,8 @@
 
       // optional bool client_streaming = 5 [default = false];
       case 5: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
-          set_has_client_streaming();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
+          HasBitSetters::set_has_client_streaming(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &client_streaming_)));
@@ -7227,9 +8721,8 @@
 
       // optional bool server_streaming = 6 [default = false];
       case 6: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) {
-          set_has_server_streaming();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (48 & 0xFF)) {
+          HasBitSetters::set_has_server_streaming(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &server_streaming_)));
@@ -7258,6 +8751,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void MethodDescriptorProto::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -7299,7 +8793,7 @@
   // optional .google.protobuf.MethodOptions options = 4;
   if (cached_has_bits & 0x00000008u) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      4, this->_internal_options(), output);
+      4, HasBitSetters::options(this), output);
   }
 
   // optional bool client_streaming = 5 [default = false];
@@ -7364,7 +8858,7 @@
   if (cached_has_bits & 0x00000008u) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        4, this->_internal_options(), deterministic, target);
+        4, HasBitSetters::options(this), deterministic, target);
   }
 
   // optional bool client_streaming = 5 [default = false];
@@ -7394,42 +8888,47 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
-  if (_has_bits_[0 / 32] & 63u) {
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x0000003fu) {
     // optional string name = 1;
-    if (has_name()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->name());
     }
 
     // optional string input_type = 2;
-    if (has_input_type()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->input_type());
     }
 
     // optional string output_type = 3;
-    if (has_output_type()) {
+    if (cached_has_bits & 0x00000004u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->output_type());
     }
 
     // optional .google.protobuf.MethodOptions options = 4;
-    if (has_options()) {
+    if (cached_has_bits & 0x00000008u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::MessageSize(
           *options_);
     }
 
     // optional bool client_streaming = 5 [default = false];
-    if (has_client_streaming()) {
+    if (cached_has_bits & 0x00000010u) {
       total_size += 1 + 1;
     }
 
     // optional bool server_streaming = 6 [default = false];
-    if (has_server_streaming()) {
+    if (cached_has_bits & 0x00000020u) {
       total_size += 1 + 1;
     }
 
@@ -7443,7 +8942,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.MethodDescriptorProto)
   GOOGLE_DCHECK_NE(&from, this);
   const MethodDescriptorProto* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const MethodDescriptorProto>(
+      ::google::protobuf::DynamicCastToGenerated<MethodDescriptorProto>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.MethodDescriptorProto)
@@ -7462,7 +8961,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 63u) {
+  if (cached_has_bits & 0x0000003fu) {
     if (cached_has_bits & 0x00000001u) {
       set_name(from.name());
     }
@@ -7527,6 +9026,8 @@
 }
 void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   input_type_.Swap(&other->input_type_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
@@ -7536,13 +9037,11 @@
   swap(options_, other->options_);
   swap(client_streaming_, other->client_streaming_);
   swap(server_streaming_, other->server_streaming_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -7550,6 +9049,70 @@
 
 void FileOptions::InitAsDefaultInstance() {
 }
+class FileOptions::HasBitSetters {
+ public:
+  static void set_has_java_package(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_java_outer_classname(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+  static void set_has_java_multiple_files(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000400u;
+  }
+  static void set_has_java_generate_equals_and_hash(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000800u;
+  }
+  static void set_has_java_string_check_utf8(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00001000u;
+  }
+  static void set_has_optimize_for(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00080000u;
+  }
+  static void set_has_go_package(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000004u;
+  }
+  static void set_has_cc_generic_services(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00002000u;
+  }
+  static void set_has_java_generic_services(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00004000u;
+  }
+  static void set_has_py_generic_services(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00008000u;
+  }
+  static void set_has_php_generic_services(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00010000u;
+  }
+  static void set_has_deprecated(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00020000u;
+  }
+  static void set_has_cc_enable_arenas(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00040000u;
+  }
+  static void set_has_objc_class_prefix(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000008u;
+  }
+  static void set_has_csharp_namespace(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000010u;
+  }
+  static void set_has_swift_prefix(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000020u;
+  }
+  static void set_has_php_class_prefix(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000040u;
+  }
+  static void set_has_php_namespace(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000080u;
+  }
+  static void set_has_php_metadata_namespace(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000100u;
+  }
+  static void set_has_ruby_package(FileOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000200u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int FileOptions::kJavaPackageFieldNumber;
 const int FileOptions::kJavaOuterClassnameFieldNumber;
@@ -7576,8 +9139,6 @@
 
 FileOptions::FileOptions()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileOptions.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.FileOptions)
 }
@@ -7586,7 +9147,6 @@
   _extensions_(arena),
   _internal_metadata_(arena),
   uninterpreted_option_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileOptions.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.FileOptions)
@@ -7655,6 +9215,8 @@
 }
 
 void FileOptions::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_FileOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   java_package_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   java_outer_classname_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   go_package_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -7699,13 +9261,8 @@
 void FileOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* FileOptions::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const FileOptions& FileOptions::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileOptions.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_FileOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -7719,7 +9276,7 @@
   _extensions_.Clear();
   uninterpreted_option_.Clear();
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 255u) {
+  if (cached_has_bits & 0x000000ffu) {
     if (cached_has_bits & 0x00000001u) {
       java_package_.ClearNonDefaultToEmpty();
     }
@@ -7745,7 +9302,7 @@
       php_namespace_.ClearNonDefaultToEmpty();
     }
   }
-  if (cached_has_bits & 768u) {
+  if (cached_has_bits & 0x00000300u) {
     if (cached_has_bits & 0x00000100u) {
       php_metadata_namespace_.ClearNonDefaultToEmpty();
     }
@@ -7753,12 +9310,12 @@
       ruby_package_.ClearNonDefaultToEmpty();
     }
   }
-  if (cached_has_bits & 64512u) {
+  if (cached_has_bits & 0x0000fc00u) {
     ::memset(&java_multiple_files_, 0, static_cast<size_t>(
         reinterpret_cast<char*>(&py_generic_services_) -
         reinterpret_cast<char*>(&java_multiple_files_)) + sizeof(py_generic_services_));
   }
-  if (cached_has_bits & 983040u) {
+  if (cached_has_bits & 0x000f0000u) {
     ::memset(&php_generic_services_, 0, static_cast<size_t>(
         reinterpret_cast<char*>(&cc_enable_arenas_) -
         reinterpret_cast<char*>(&php_generic_services_)) + sizeof(cc_enable_arenas_));
@@ -7768,9 +9325,335 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* FileOptions::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<FileOptions*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional string java_package = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.java_package");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_java_package();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string java_outer_classname = 8;
+      case 8: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.java_outer_classname");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_java_outer_classname();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+      case 9: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 72) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        if (!::google::protobuf::FileOptions_OptimizeMode_IsValid(val)) {
+          ::google::protobuf::internal::WriteVarint(9, val, msg->mutable_unknown_fields());
+          break;
+        }
+        ::google::protobuf::FileOptions_OptimizeMode value = static_cast<::google::protobuf::FileOptions_OptimizeMode>(val);
+        msg->set_optimize_for(value);
+        break;
+      }
+      // optional bool java_multiple_files = 10 [default = false];
+      case 10: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 80) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_java_multiple_files(value);
+        break;
+      }
+      // optional string go_package = 11;
+      case 11: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 90) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.go_package");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_go_package();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional bool cc_generic_services = 16 [default = false];
+      case 16: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 128) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_cc_generic_services(value);
+        break;
+      }
+      // optional bool java_generic_services = 17 [default = false];
+      case 17: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 136) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_java_generic_services(value);
+        break;
+      }
+      // optional bool py_generic_services = 18 [default = false];
+      case 18: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 144) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_py_generic_services(value);
+        break;
+      }
+      // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
+      case 20: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 160) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_java_generate_equals_and_hash(value);
+        break;
+      }
+      // optional bool deprecated = 23 [default = false];
+      case 23: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 184) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_deprecated(value);
+        break;
+      }
+      // optional bool java_string_check_utf8 = 27 [default = false];
+      case 27: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 216) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_java_string_check_utf8(value);
+        break;
+      }
+      // optional bool cc_enable_arenas = 31 [default = false];
+      case 31: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 248) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_cc_enable_arenas(value);
+        break;
+      }
+      // optional string objc_class_prefix = 36;
+      case 36: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.objc_class_prefix");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_objc_class_prefix();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string csharp_namespace = 37;
+      case 37: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.csharp_namespace");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_csharp_namespace();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string swift_prefix = 39;
+      case 39: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.swift_prefix");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_swift_prefix();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string php_class_prefix = 40;
+      case 40: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.php_class_prefix");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_php_class_prefix();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string php_namespace = 41;
+      case 41: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 74) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.php_namespace");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_php_namespace();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional bool php_generic_services = 42 [default = false];
+      case 42: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 80) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_php_generic_services(value);
+        break;
+      }
+      // optional string php_metadata_namespace = 44;
+      case 44: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 98) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.php_metadata_namespace");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_php_metadata_namespace();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string ruby_package = 45;
+      case 45: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 106) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.FileOptions.ruby_package");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_ruby_package();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
+          object = msg->add_uninterpreted_option();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 65535) == 16058 && (ptr += 2));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+      if ((8000u <= tag)) {
+        auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
+            internal_default_instance(), &msg->_internal_metadata_, ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+        continue;
+      }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool FileOptions::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.FileOptions)
   for (;;) {
@@ -7780,8 +9663,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional string java_package = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_java_package()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -7796,8 +9678,7 @@
 
       // optional string java_outer_classname = 8;
       case 8: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (66 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_java_outer_classname()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -7812,8 +9693,7 @@
 
       // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
       case 9: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(72u /* 72 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (72 & 0xFF)) {
           int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -7822,7 +9702,7 @@
             set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value));
           } else {
             mutable_unknown_fields()->AddVarint(
-                9, static_cast< ::google::protobuf::uint64>(value));
+                9, static_cast<::google::protobuf::uint64>(value));
           }
         } else {
           goto handle_unusual;
@@ -7832,9 +9712,8 @@
 
       // optional bool java_multiple_files = 10 [default = false];
       case 10: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(80u /* 80 & 0xFF */)) {
-          set_has_java_multiple_files();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (80 & 0xFF)) {
+          HasBitSetters::set_has_java_multiple_files(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &java_multiple_files_)));
@@ -7846,8 +9725,7 @@
 
       // optional string go_package = 11;
       case 11: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(90u /* 90 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (90 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_go_package()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -7862,9 +9740,8 @@
 
       // optional bool cc_generic_services = 16 [default = false];
       case 16: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(128u /* 128 & 0xFF */)) {
-          set_has_cc_generic_services();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (128 & 0xFF)) {
+          HasBitSetters::set_has_cc_generic_services(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &cc_generic_services_)));
@@ -7876,9 +9753,8 @@
 
       // optional bool java_generic_services = 17 [default = false];
       case 17: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(136u /* 136 & 0xFF */)) {
-          set_has_java_generic_services();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (136 & 0xFF)) {
+          HasBitSetters::set_has_java_generic_services(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &java_generic_services_)));
@@ -7890,9 +9766,8 @@
 
       // optional bool py_generic_services = 18 [default = false];
       case 18: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(144u /* 144 & 0xFF */)) {
-          set_has_py_generic_services();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (144 & 0xFF)) {
+          HasBitSetters::set_has_py_generic_services(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &py_generic_services_)));
@@ -7904,9 +9779,8 @@
 
       // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
       case 20: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(160u /* 160 & 0xFF */)) {
-          set_has_java_generate_equals_and_hash();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (160 & 0xFF)) {
+          HasBitSetters::set_has_java_generate_equals_and_hash(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &java_generate_equals_and_hash_)));
@@ -7918,9 +9792,8 @@
 
       // optional bool deprecated = 23 [default = false];
       case 23: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(184u /* 184 & 0xFF */)) {
-          set_has_deprecated();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (184 & 0xFF)) {
+          HasBitSetters::set_has_deprecated(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &deprecated_)));
@@ -7932,9 +9805,8 @@
 
       // optional bool java_string_check_utf8 = 27 [default = false];
       case 27: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(216u /* 216 & 0xFF */)) {
-          set_has_java_string_check_utf8();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (216 & 0xFF)) {
+          HasBitSetters::set_has_java_string_check_utf8(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &java_string_check_utf8_)));
@@ -7946,9 +9818,8 @@
 
       // optional bool cc_enable_arenas = 31 [default = false];
       case 31: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(248u /* 248 & 0xFF */)) {
-          set_has_cc_enable_arenas();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (248 & 0xFF)) {
+          HasBitSetters::set_has_cc_enable_arenas(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &cc_enable_arenas_)));
@@ -7960,8 +9831,7 @@
 
       // optional string objc_class_prefix = 36;
       case 36: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(34u /* 290 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (290 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_objc_class_prefix()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -7976,8 +9846,7 @@
 
       // optional string csharp_namespace = 37;
       case 37: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(42u /* 298 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (298 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_csharp_namespace()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -7992,8 +9861,7 @@
 
       // optional string swift_prefix = 39;
       case 39: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 314 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (314 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_swift_prefix()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -8008,8 +9876,7 @@
 
       // optional string php_class_prefix = 40;
       case 40: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(66u /* 322 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (322 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_php_class_prefix()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -8024,8 +9891,7 @@
 
       // optional string php_namespace = 41;
       case 41: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(74u /* 330 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (330 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_php_namespace()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -8040,9 +9906,8 @@
 
       // optional bool php_generic_services = 42 [default = false];
       case 42: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(80u /* 336 & 0xFF */)) {
-          set_has_php_generic_services();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (336 & 0xFF)) {
+          HasBitSetters::set_has_php_generic_services(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &php_generic_services_)));
@@ -8054,8 +9919,7 @@
 
       // optional string php_metadata_namespace = 44;
       case 44: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(98u /* 354 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (354 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_php_metadata_namespace()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -8070,8 +9934,7 @@
 
       // optional string ruby_package = 45;
       case 45: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(106u /* 362 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (362 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_ruby_package()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -8086,8 +9949,7 @@
 
       // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
       case 999: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (7994 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_uninterpreted_option()));
         } else {
@@ -8121,6 +9983,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void FileOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -8290,8 +10153,7 @@
   }
 
   // Extension range [1000, 536870912)
-  _extensions_.SerializeWithCachedSizes(
-      1000, 536870912, output);
+  _extensions_.SerializeWithCachedSizes(1000, 536870912, output);
 
   if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
@@ -8500,6 +10362,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
     unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
@@ -8511,128 +10377,129 @@
     }
   }
 
-  if (_has_bits_[0 / 32] & 255u) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x000000ffu) {
     // optional string java_package = 1;
-    if (has_java_package()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->java_package());
     }
 
     // optional string java_outer_classname = 8;
-    if (has_java_outer_classname()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->java_outer_classname());
     }
 
     // optional string go_package = 11;
-    if (has_go_package()) {
+    if (cached_has_bits & 0x00000004u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->go_package());
     }
 
     // optional string objc_class_prefix = 36;
-    if (has_objc_class_prefix()) {
+    if (cached_has_bits & 0x00000008u) {
       total_size += 2 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->objc_class_prefix());
     }
 
     // optional string csharp_namespace = 37;
-    if (has_csharp_namespace()) {
+    if (cached_has_bits & 0x00000010u) {
       total_size += 2 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->csharp_namespace());
     }
 
     // optional string swift_prefix = 39;
-    if (has_swift_prefix()) {
+    if (cached_has_bits & 0x00000020u) {
       total_size += 2 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->swift_prefix());
     }
 
     // optional string php_class_prefix = 40;
-    if (has_php_class_prefix()) {
+    if (cached_has_bits & 0x00000040u) {
       total_size += 2 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->php_class_prefix());
     }
 
     // optional string php_namespace = 41;
-    if (has_php_namespace()) {
+    if (cached_has_bits & 0x00000080u) {
       total_size += 2 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->php_namespace());
     }
 
   }
-  if (_has_bits_[8 / 32] & 65280u) {
+  if (cached_has_bits & 0x0000ff00u) {
     // optional string php_metadata_namespace = 44;
-    if (has_php_metadata_namespace()) {
+    if (cached_has_bits & 0x00000100u) {
       total_size += 2 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->php_metadata_namespace());
     }
 
     // optional string ruby_package = 45;
-    if (has_ruby_package()) {
+    if (cached_has_bits & 0x00000200u) {
       total_size += 2 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->ruby_package());
     }
 
     // optional bool java_multiple_files = 10 [default = false];
-    if (has_java_multiple_files()) {
+    if (cached_has_bits & 0x00000400u) {
       total_size += 1 + 1;
     }
 
     // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
-    if (has_java_generate_equals_and_hash()) {
+    if (cached_has_bits & 0x00000800u) {
       total_size += 2 + 1;
     }
 
     // optional bool java_string_check_utf8 = 27 [default = false];
-    if (has_java_string_check_utf8()) {
+    if (cached_has_bits & 0x00001000u) {
       total_size += 2 + 1;
     }
 
     // optional bool cc_generic_services = 16 [default = false];
-    if (has_cc_generic_services()) {
+    if (cached_has_bits & 0x00002000u) {
       total_size += 2 + 1;
     }
 
     // optional bool java_generic_services = 17 [default = false];
-    if (has_java_generic_services()) {
+    if (cached_has_bits & 0x00004000u) {
       total_size += 2 + 1;
     }
 
     // optional bool py_generic_services = 18 [default = false];
-    if (has_py_generic_services()) {
+    if (cached_has_bits & 0x00008000u) {
       total_size += 2 + 1;
     }
 
   }
-  if (_has_bits_[16 / 32] & 983040u) {
+  if (cached_has_bits & 0x000f0000u) {
     // optional bool php_generic_services = 42 [default = false];
-    if (has_php_generic_services()) {
+    if (cached_has_bits & 0x00010000u) {
       total_size += 2 + 1;
     }
 
     // optional bool deprecated = 23 [default = false];
-    if (has_deprecated()) {
+    if (cached_has_bits & 0x00020000u) {
       total_size += 2 + 1;
     }
 
     // optional bool cc_enable_arenas = 31 [default = false];
-    if (has_cc_enable_arenas()) {
+    if (cached_has_bits & 0x00040000u) {
       total_size += 2 + 1;
     }
 
     // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
-    if (has_optimize_for()) {
+    if (cached_has_bits & 0x00080000u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::EnumSize(this->optimize_for());
     }
@@ -8647,7 +10514,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FileOptions)
   GOOGLE_DCHECK_NE(&from, this);
   const FileOptions* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const FileOptions>(
+      ::google::protobuf::DynamicCastToGenerated<FileOptions>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FileOptions)
@@ -8668,7 +10535,7 @@
 
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 255u) {
+  if (cached_has_bits & 0x000000ffu) {
     if (cached_has_bits & 0x00000001u) {
       set_java_package(from.java_package());
     }
@@ -8694,7 +10561,7 @@
       set_php_namespace(from.php_namespace());
     }
   }
-  if (cached_has_bits & 65280u) {
+  if (cached_has_bits & 0x0000ff00u) {
     if (cached_has_bits & 0x00000100u) {
       set_php_metadata_namespace(from.php_metadata_namespace());
     }
@@ -8721,7 +10588,7 @@
     }
     _has_bits_[0] |= cached_has_bits;
   }
-  if (cached_has_bits & 983040u) {
+  if (cached_has_bits & 0x000f0000u) {
     if (cached_has_bits & 0x00010000u) {
       php_generic_services_ = from.php_generic_services_;
     }
@@ -8782,6 +10649,9 @@
 }
 void FileOptions::InternalSwap(FileOptions* other) {
   using std::swap;
+  _extensions_.Swap(&other->_extensions_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
   java_package_.Swap(&other->java_package_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
@@ -8813,14 +10683,11 @@
   swap(deprecated_, other->deprecated_);
   swap(cc_enable_arenas_, other->cc_enable_arenas_);
   swap(optimize_for_, other->optimize_for_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
-  _extensions_.Swap(&other->_extensions_);
 }
 
 ::google::protobuf::Metadata FileOptions::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -8828,6 +10695,22 @@
 
 void MessageOptions::InitAsDefaultInstance() {
 }
+class MessageOptions::HasBitSetters {
+ public:
+  static void set_has_message_set_wire_format(MessageOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_no_standard_descriptor_accessor(MessageOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+  static void set_has_deprecated(MessageOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000004u;
+  }
+  static void set_has_map_entry(MessageOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000008u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int MessageOptions::kMessageSetWireFormatFieldNumber;
 const int MessageOptions::kNoStandardDescriptorAccessorFieldNumber;
@@ -8838,8 +10721,6 @@
 
 MessageOptions::MessageOptions()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MessageOptions.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.MessageOptions)
 }
@@ -8848,7 +10729,6 @@
   _extensions_(arena),
   _internal_metadata_(arena),
   uninterpreted_option_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MessageOptions.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.MessageOptions)
@@ -8867,6 +10747,8 @@
 }
 
 void MessageOptions::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_MessageOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   ::memset(&message_set_wire_format_, 0, static_cast<size_t>(
       reinterpret_cast<char*>(&map_entry_) -
       reinterpret_cast<char*>(&message_set_wire_format_)) + sizeof(map_entry_));
@@ -8890,13 +10772,8 @@
 void MessageOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* MessageOptions::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const MessageOptions& MessageOptions::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MessageOptions.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_MessageOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -8916,9 +10793,111 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* MessageOptions::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<MessageOptions*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional bool message_set_wire_format = 1 [default = false];
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_message_set_wire_format(value);
+        break;
+      }
+      // optional bool no_standard_descriptor_accessor = 2 [default = false];
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_no_standard_descriptor_accessor(value);
+        break;
+      }
+      // optional bool deprecated = 3 [default = false];
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_deprecated(value);
+        break;
+      }
+      // optional bool map_entry = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_map_entry(value);
+        break;
+      }
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
+          object = msg->add_uninterpreted_option();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 65535) == 16058 && (ptr += 2));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+      if ((8000u <= tag)) {
+        auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
+            internal_default_instance(), &msg->_internal_metadata_, ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+        continue;
+      }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool MessageOptions::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.MessageOptions)
   for (;;) {
@@ -8928,9 +10907,8 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional bool message_set_wire_format = 1 [default = false];
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
-          set_has_message_set_wire_format();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          HasBitSetters::set_has_message_set_wire_format(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &message_set_wire_format_)));
@@ -8942,9 +10920,8 @@
 
       // optional bool no_standard_descriptor_accessor = 2 [default = false];
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
-          set_has_no_standard_descriptor_accessor();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          HasBitSetters::set_has_no_standard_descriptor_accessor(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &no_standard_descriptor_accessor_)));
@@ -8956,9 +10933,8 @@
 
       // optional bool deprecated = 3 [default = false];
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
-          set_has_deprecated();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          HasBitSetters::set_has_deprecated(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &deprecated_)));
@@ -8970,9 +10946,8 @@
 
       // optional bool map_entry = 7;
       case 7: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) {
-          set_has_map_entry();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (56 & 0xFF)) {
+          HasBitSetters::set_has_map_entry(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &map_entry_)));
@@ -8984,8 +10959,7 @@
 
       // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
       case 999: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (7994 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_uninterpreted_option()));
         } else {
@@ -9019,6 +10993,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void MessageOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -9057,8 +11032,7 @@
   }
 
   // Extension range [1000, 536870912)
-  _extensions_.SerializeWithCachedSizes(
-      1000, 536870912, output);
+  _extensions_.SerializeWithCachedSizes(1000, 536870912, output);
 
   if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
@@ -9126,6 +11100,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
     unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
@@ -9137,24 +11115,25 @@
     }
   }
 
-  if (_has_bits_[0 / 32] & 15u) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x0000000fu) {
     // optional bool message_set_wire_format = 1 [default = false];
-    if (has_message_set_wire_format()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 + 1;
     }
 
     // optional bool no_standard_descriptor_accessor = 2 [default = false];
-    if (has_no_standard_descriptor_accessor()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 + 1;
     }
 
     // optional bool deprecated = 3 [default = false];
-    if (has_deprecated()) {
+    if (cached_has_bits & 0x00000004u) {
       total_size += 1 + 1;
     }
 
     // optional bool map_entry = 7;
-    if (has_map_entry()) {
+    if (cached_has_bits & 0x00000008u) {
       total_size += 1 + 1;
     }
 
@@ -9168,7 +11147,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.MessageOptions)
   GOOGLE_DCHECK_NE(&from, this);
   const MessageOptions* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const MessageOptions>(
+      ::google::protobuf::DynamicCastToGenerated<MessageOptions>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.MessageOptions)
@@ -9189,7 +11168,7 @@
 
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 15u) {
+  if (cached_has_bits & 0x0000000fu) {
     if (cached_has_bits & 0x00000001u) {
       message_set_wire_format_ = from.message_set_wire_format_;
     }
@@ -9250,19 +11229,19 @@
 }
 void MessageOptions::InternalSwap(MessageOptions* other) {
   using std::swap;
+  _extensions_.Swap(&other->_extensions_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
   swap(message_set_wire_format_, other->message_set_wire_format_);
   swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_);
   swap(deprecated_, other->deprecated_);
   swap(map_entry_, other->map_entry_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
-  _extensions_.Swap(&other->_extensions_);
 }
 
 ::google::protobuf::Metadata MessageOptions::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -9270,6 +11249,28 @@
 
 void FieldOptions::InitAsDefaultInstance() {
 }
+class FieldOptions::HasBitSetters {
+ public:
+  static void set_has_ctype(FieldOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_packed(FieldOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+  static void set_has_jstype(FieldOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000020u;
+  }
+  static void set_has_lazy(FieldOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000004u;
+  }
+  static void set_has_deprecated(FieldOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000008u;
+  }
+  static void set_has_weak(FieldOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000010u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int FieldOptions::kCtypeFieldNumber;
 const int FieldOptions::kPackedFieldNumber;
@@ -9282,8 +11283,6 @@
 
 FieldOptions::FieldOptions()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldOptions.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.FieldOptions)
 }
@@ -9292,7 +11291,6 @@
   _extensions_(arena),
   _internal_metadata_(arena),
   uninterpreted_option_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldOptions.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldOptions)
@@ -9311,6 +11309,8 @@
 }
 
 void FieldOptions::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_FieldOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   ::memset(&ctype_, 0, static_cast<size_t>(
       reinterpret_cast<char*>(&jstype_) -
       reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_));
@@ -9334,13 +11334,8 @@
 void FieldOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* FieldOptions::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const FieldOptions& FieldOptions::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FieldOptions.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_FieldOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -9354,7 +11349,7 @@
   _extensions_.Clear();
   uninterpreted_option_.Clear();
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 63u) {
+  if (cached_has_bits & 0x0000003fu) {
     ::memset(&ctype_, 0, static_cast<size_t>(
         reinterpret_cast<char*>(&jstype_) -
         reinterpret_cast<char*>(&ctype_)) + sizeof(jstype_));
@@ -9363,9 +11358,139 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* FieldOptions::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<FieldOptions*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        if (!::google::protobuf::FieldOptions_CType_IsValid(val)) {
+          ::google::protobuf::internal::WriteVarint(1, val, msg->mutable_unknown_fields());
+          break;
+        }
+        ::google::protobuf::FieldOptions_CType value = static_cast<::google::protobuf::FieldOptions_CType>(val);
+        msg->set_ctype(value);
+        break;
+      }
+      // optional bool packed = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_packed(value);
+        break;
+      }
+      // optional bool deprecated = 3 [default = false];
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_deprecated(value);
+        break;
+      }
+      // optional bool lazy = 5 [default = false];
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_lazy(value);
+        break;
+      }
+      // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 48) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        if (!::google::protobuf::FieldOptions_JSType_IsValid(val)) {
+          ::google::protobuf::internal::WriteVarint(6, val, msg->mutable_unknown_fields());
+          break;
+        }
+        ::google::protobuf::FieldOptions_JSType value = static_cast<::google::protobuf::FieldOptions_JSType>(val);
+        msg->set_jstype(value);
+        break;
+      }
+      // optional bool weak = 10 [default = false];
+      case 10: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 80) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_weak(value);
+        break;
+      }
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
+          object = msg->add_uninterpreted_option();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 65535) == 16058 && (ptr += 2));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+      if ((8000u <= tag)) {
+        auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
+            internal_default_instance(), &msg->_internal_metadata_, ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+        continue;
+      }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool FieldOptions::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.FieldOptions)
   for (;;) {
@@ -9375,8 +11500,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
           int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -9385,7 +11509,7 @@
             set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value));
           } else {
             mutable_unknown_fields()->AddVarint(
-                1, static_cast< ::google::protobuf::uint64>(value));
+                1, static_cast<::google::protobuf::uint64>(value));
           }
         } else {
           goto handle_unusual;
@@ -9395,9 +11519,8 @@
 
       // optional bool packed = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
-          set_has_packed();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          HasBitSetters::set_has_packed(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &packed_)));
@@ -9409,9 +11532,8 @@
 
       // optional bool deprecated = 3 [default = false];
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
-          set_has_deprecated();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          HasBitSetters::set_has_deprecated(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &deprecated_)));
@@ -9423,9 +11545,8 @@
 
       // optional bool lazy = 5 [default = false];
       case 5: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
-          set_has_lazy();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
+          HasBitSetters::set_has_lazy(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &lazy_)));
@@ -9437,8 +11558,7 @@
 
       // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
       case 6: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (48 & 0xFF)) {
           int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -9447,7 +11567,7 @@
             set_jstype(static_cast< ::google::protobuf::FieldOptions_JSType >(value));
           } else {
             mutable_unknown_fields()->AddVarint(
-                6, static_cast< ::google::protobuf::uint64>(value));
+                6, static_cast<::google::protobuf::uint64>(value));
           }
         } else {
           goto handle_unusual;
@@ -9457,9 +11577,8 @@
 
       // optional bool weak = 10 [default = false];
       case 10: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(80u /* 80 & 0xFF */)) {
-          set_has_weak();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (80 & 0xFF)) {
+          HasBitSetters::set_has_weak(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &weak_)));
@@ -9471,8 +11590,7 @@
 
       // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
       case 999: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (7994 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_uninterpreted_option()));
         } else {
@@ -9506,6 +11624,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void FieldOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -9556,8 +11675,7 @@
   }
 
   // Extension range [1000, 536870912)
-  _extensions_.SerializeWithCachedSizes(
-      1000, 536870912, output);
+  _extensions_.SerializeWithCachedSizes(1000, 536870912, output);
 
   if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
@@ -9637,6 +11755,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
     unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
@@ -9648,35 +11770,36 @@
     }
   }
 
-  if (_has_bits_[0 / 32] & 63u) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x0000003fu) {
     // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
-    if (has_ctype()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::EnumSize(this->ctype());
     }
 
     // optional bool packed = 2;
-    if (has_packed()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 + 1;
     }
 
     // optional bool lazy = 5 [default = false];
-    if (has_lazy()) {
+    if (cached_has_bits & 0x00000004u) {
       total_size += 1 + 1;
     }
 
     // optional bool deprecated = 3 [default = false];
-    if (has_deprecated()) {
+    if (cached_has_bits & 0x00000008u) {
       total_size += 1 + 1;
     }
 
     // optional bool weak = 10 [default = false];
-    if (has_weak()) {
+    if (cached_has_bits & 0x00000010u) {
       total_size += 1 + 1;
     }
 
     // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];
-    if (has_jstype()) {
+    if (cached_has_bits & 0x00000020u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::EnumSize(this->jstype());
     }
@@ -9691,7 +11814,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldOptions)
   GOOGLE_DCHECK_NE(&from, this);
   const FieldOptions* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const FieldOptions>(
+      ::google::protobuf::DynamicCastToGenerated<FieldOptions>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FieldOptions)
@@ -9712,7 +11835,7 @@
 
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 63u) {
+  if (cached_has_bits & 0x0000003fu) {
     if (cached_has_bits & 0x00000001u) {
       ctype_ = from.ctype_;
     }
@@ -9779,6 +11902,9 @@
 }
 void FieldOptions::InternalSwap(FieldOptions* other) {
   using std::swap;
+  _extensions_.Swap(&other->_extensions_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
   swap(ctype_, other->ctype_);
   swap(packed_, other->packed_);
@@ -9786,14 +11912,11 @@
   swap(deprecated_, other->deprecated_);
   swap(weak_, other->weak_);
   swap(jstype_, other->jstype_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
-  _extensions_.Swap(&other->_extensions_);
 }
 
 ::google::protobuf::Metadata FieldOptions::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -9801,14 +11924,16 @@
 
 void OneofOptions::InitAsDefaultInstance() {
 }
+class OneofOptions::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int OneofOptions::kUninterpretedOptionFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 OneofOptions::OneofOptions()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofOptions.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.OneofOptions)
 }
@@ -9817,7 +11942,6 @@
   _extensions_(arena),
   _internal_metadata_(arena),
   uninterpreted_option_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofOptions.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofOptions)
@@ -9833,6 +11957,8 @@
 }
 
 void OneofOptions::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_OneofOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
 }
 
 OneofOptions::~OneofOptions() {
@@ -9853,13 +11979,8 @@
 void OneofOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* OneofOptions::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const OneofOptions& OneofOptions::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_OneofOptions.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_OneofOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -9876,9 +11997,71 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* OneofOptions::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<OneofOptions*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
+          object = msg->add_uninterpreted_option();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 65535) == 16058 && (ptr += 2));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+      if ((8000u <= tag)) {
+        auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
+            internal_default_instance(), &msg->_internal_metadata_, ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+        continue;
+      }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool OneofOptions::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.OneofOptions)
   for (;;) {
@@ -9888,8 +12071,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
       case 999: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (7994 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_uninterpreted_option()));
         } else {
@@ -9923,6 +12105,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void OneofOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -9940,8 +12123,7 @@
   }
 
   // Extension range [1000, 536870912)
-  _extensions_.SerializeWithCachedSizes(
-      1000, 536870912, output);
+  _extensions_.SerializeWithCachedSizes(1000, 536870912, output);
 
   if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
@@ -9988,6 +12170,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
     unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
@@ -10008,7 +12194,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.OneofOptions)
   GOOGLE_DCHECK_NE(&from, this);
   const OneofOptions* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const OneofOptions>(
+      ::google::protobuf::DynamicCastToGenerated<OneofOptions>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.OneofOptions)
@@ -10074,15 +12260,15 @@
 }
 void OneofOptions::InternalSwap(OneofOptions* other) {
   using std::swap;
-  CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
   _extensions_.Swap(&other->_extensions_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
+  CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
 }
 
 ::google::protobuf::Metadata OneofOptions::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -10090,6 +12276,16 @@
 
 void EnumOptions::InitAsDefaultInstance() {
 }
+class EnumOptions::HasBitSetters {
+ public:
+  static void set_has_allow_alias(EnumOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_deprecated(EnumOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int EnumOptions::kAllowAliasFieldNumber;
 const int EnumOptions::kDeprecatedFieldNumber;
@@ -10098,8 +12294,6 @@
 
 EnumOptions::EnumOptions()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumOptions.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.EnumOptions)
 }
@@ -10108,7 +12302,6 @@
   _extensions_(arena),
   _internal_metadata_(arena),
   uninterpreted_option_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumOptions.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumOptions)
@@ -10127,6 +12320,8 @@
 }
 
 void EnumOptions::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_EnumOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   ::memset(&allow_alias_, 0, static_cast<size_t>(
       reinterpret_cast<char*>(&deprecated_) -
       reinterpret_cast<char*>(&allow_alias_)) + sizeof(deprecated_));
@@ -10150,13 +12345,8 @@
 void EnumOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* EnumOptions::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const EnumOptions& EnumOptions::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumOptions.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_EnumOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -10176,9 +12366,91 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EnumOptions::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EnumOptions*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional bool allow_alias = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_allow_alias(value);
+        break;
+      }
+      // optional bool deprecated = 3 [default = false];
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_deprecated(value);
+        break;
+      }
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
+          object = msg->add_uninterpreted_option();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 65535) == 16058 && (ptr += 2));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+      if ((8000u <= tag)) {
+        auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
+            internal_default_instance(), &msg->_internal_metadata_, ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+        continue;
+      }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool EnumOptions::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.EnumOptions)
   for (;;) {
@@ -10188,9 +12460,8 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional bool allow_alias = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
-          set_has_allow_alias();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          HasBitSetters::set_has_allow_alias(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &allow_alias_)));
@@ -10202,9 +12473,8 @@
 
       // optional bool deprecated = 3 [default = false];
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
-          set_has_deprecated();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          HasBitSetters::set_has_deprecated(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &deprecated_)));
@@ -10216,8 +12486,7 @@
 
       // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
       case 999: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (7994 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_uninterpreted_option()));
         } else {
@@ -10251,6 +12520,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void EnumOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -10279,8 +12549,7 @@
   }
 
   // Extension range [1000, 536870912)
-  _extensions_.SerializeWithCachedSizes(
-      1000, 536870912, output);
+  _extensions_.SerializeWithCachedSizes(1000, 536870912, output);
 
   if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
@@ -10338,6 +12607,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
     unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
@@ -10349,14 +12622,15 @@
     }
   }
 
-  if (_has_bits_[0 / 32] & 3u) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000003u) {
     // optional bool allow_alias = 2;
-    if (has_allow_alias()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 + 1;
     }
 
     // optional bool deprecated = 3 [default = false];
-    if (has_deprecated()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 + 1;
     }
 
@@ -10370,7 +12644,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumOptions)
   GOOGLE_DCHECK_NE(&from, this);
   const EnumOptions* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const EnumOptions>(
+      ::google::protobuf::DynamicCastToGenerated<EnumOptions>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.EnumOptions)
@@ -10391,7 +12665,7 @@
 
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       allow_alias_ = from.allow_alias_;
     }
@@ -10446,17 +12720,17 @@
 }
 void EnumOptions::InternalSwap(EnumOptions* other) {
   using std::swap;
+  _extensions_.Swap(&other->_extensions_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
   swap(allow_alias_, other->allow_alias_);
   swap(deprecated_, other->deprecated_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
-  _extensions_.Swap(&other->_extensions_);
 }
 
 ::google::protobuf::Metadata EnumOptions::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -10464,6 +12738,13 @@
 
 void EnumValueOptions::InitAsDefaultInstance() {
 }
+class EnumValueOptions::HasBitSetters {
+ public:
+  static void set_has_deprecated(EnumValueOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int EnumValueOptions::kDeprecatedFieldNumber;
 const int EnumValueOptions::kUninterpretedOptionFieldNumber;
@@ -10471,8 +12752,6 @@
 
 EnumValueOptions::EnumValueOptions()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueOptions.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.EnumValueOptions)
 }
@@ -10481,7 +12760,6 @@
   _extensions_(arena),
   _internal_metadata_(arena),
   uninterpreted_option_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueOptions.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueOptions)
@@ -10498,6 +12776,8 @@
 }
 
 void EnumValueOptions::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_EnumValueOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   deprecated_ = false;
 }
 
@@ -10519,13 +12799,8 @@
 void EnumValueOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const EnumValueOptions& EnumValueOptions::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_EnumValueOptions.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_EnumValueOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -10543,9 +12818,81 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EnumValueOptions::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EnumValueOptions*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional bool deprecated = 1 [default = false];
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_deprecated(value);
+        break;
+      }
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
+          object = msg->add_uninterpreted_option();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 65535) == 16058 && (ptr += 2));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+      if ((8000u <= tag)) {
+        auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
+            internal_default_instance(), &msg->_internal_metadata_, ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+        continue;
+      }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool EnumValueOptions::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.EnumValueOptions)
   for (;;) {
@@ -10555,9 +12902,8 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional bool deprecated = 1 [default = false];
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
-          set_has_deprecated();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          HasBitSetters::set_has_deprecated(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &deprecated_)));
@@ -10569,8 +12915,7 @@
 
       // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
       case 999: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (7994 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_uninterpreted_option()));
         } else {
@@ -10604,6 +12949,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void EnumValueOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -10627,8 +12973,7 @@
   }
 
   // Extension range [1000, 536870912)
-  _extensions_.SerializeWithCachedSizes(
-      1000, 536870912, output);
+  _extensions_.SerializeWithCachedSizes(1000, 536870912, output);
 
   if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
@@ -10681,6 +13026,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
     unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
@@ -10693,7 +13042,8 @@
   }
 
   // optional bool deprecated = 1 [default = false];
-  if (has_deprecated()) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000001u) {
     total_size += 1 + 1;
   }
 
@@ -10706,7 +13056,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumValueOptions)
   GOOGLE_DCHECK_NE(&from, this);
   const EnumValueOptions* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const EnumValueOptions>(
+      ::google::protobuf::DynamicCastToGenerated<EnumValueOptions>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.EnumValueOptions)
@@ -10775,16 +13125,16 @@
 }
 void EnumValueOptions::InternalSwap(EnumValueOptions* other) {
   using std::swap;
+  _extensions_.Swap(&other->_extensions_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
   swap(deprecated_, other->deprecated_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
-  _extensions_.Swap(&other->_extensions_);
 }
 
 ::google::protobuf::Metadata EnumValueOptions::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -10792,6 +13142,13 @@
 
 void ServiceOptions::InitAsDefaultInstance() {
 }
+class ServiceOptions::HasBitSetters {
+ public:
+  static void set_has_deprecated(ServiceOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int ServiceOptions::kDeprecatedFieldNumber;
 const int ServiceOptions::kUninterpretedOptionFieldNumber;
@@ -10799,8 +13156,6 @@
 
 ServiceOptions::ServiceOptions()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceOptions.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.ServiceOptions)
 }
@@ -10809,7 +13164,6 @@
   _extensions_(arena),
   _internal_metadata_(arena),
   uninterpreted_option_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceOptions.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceOptions)
@@ -10826,6 +13180,8 @@
 }
 
 void ServiceOptions::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ServiceOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   deprecated_ = false;
 }
 
@@ -10847,13 +13203,8 @@
 void ServiceOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* ServiceOptions::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const ServiceOptions& ServiceOptions::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_ServiceOptions.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_ServiceOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -10871,9 +13222,81 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ServiceOptions::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ServiceOptions*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional bool deprecated = 33 [default = false];
+      case 33: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_deprecated(value);
+        break;
+      }
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
+          object = msg->add_uninterpreted_option();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 65535) == 16058 && (ptr += 2));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+      if ((8000u <= tag)) {
+        auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
+            internal_default_instance(), &msg->_internal_metadata_, ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+        continue;
+      }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool ServiceOptions::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.ServiceOptions)
   for (;;) {
@@ -10883,9 +13306,8 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional bool deprecated = 33 [default = false];
       case 33: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 264 & 0xFF */)) {
-          set_has_deprecated();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (264 & 0xFF)) {
+          HasBitSetters::set_has_deprecated(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &deprecated_)));
@@ -10897,8 +13319,7 @@
 
       // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
       case 999: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (7994 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_uninterpreted_option()));
         } else {
@@ -10932,6 +13353,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void ServiceOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -10955,8 +13377,7 @@
   }
 
   // Extension range [1000, 536870912)
-  _extensions_.SerializeWithCachedSizes(
-      1000, 536870912, output);
+  _extensions_.SerializeWithCachedSizes(1000, 536870912, output);
 
   if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
@@ -11009,6 +13430,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
     unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
@@ -11021,7 +13446,8 @@
   }
 
   // optional bool deprecated = 33 [default = false];
-  if (has_deprecated()) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000001u) {
     total_size += 2 + 1;
   }
 
@@ -11034,7 +13460,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ServiceOptions)
   GOOGLE_DCHECK_NE(&from, this);
   const ServiceOptions* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const ServiceOptions>(
+      ::google::protobuf::DynamicCastToGenerated<ServiceOptions>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.ServiceOptions)
@@ -11103,16 +13529,16 @@
 }
 void ServiceOptions::InternalSwap(ServiceOptions* other) {
   using std::swap;
+  _extensions_.Swap(&other->_extensions_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
   swap(deprecated_, other->deprecated_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
-  _extensions_.Swap(&other->_extensions_);
 }
 
 ::google::protobuf::Metadata ServiceOptions::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -11120,6 +13546,16 @@
 
 void MethodOptions::InitAsDefaultInstance() {
 }
+class MethodOptions::HasBitSetters {
+ public:
+  static void set_has_deprecated(MethodOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_idempotency_level(MethodOptions* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int MethodOptions::kDeprecatedFieldNumber;
 const int MethodOptions::kIdempotencyLevelFieldNumber;
@@ -11128,8 +13564,6 @@
 
 MethodOptions::MethodOptions()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodOptions.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.MethodOptions)
 }
@@ -11138,7 +13572,6 @@
   _extensions_(arena),
   _internal_metadata_(arena),
   uninterpreted_option_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodOptions.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodOptions)
@@ -11157,6 +13590,8 @@
 }
 
 void MethodOptions::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_MethodOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   ::memset(&deprecated_, 0, static_cast<size_t>(
       reinterpret_cast<char*>(&idempotency_level_) -
       reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_));
@@ -11180,13 +13615,8 @@
 void MethodOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* MethodOptions::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const MethodOptions& MethodOptions::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_MethodOptions.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_MethodOptions_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -11200,7 +13630,7 @@
   _extensions_.Clear();
   uninterpreted_option_.Clear();
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     ::memset(&deprecated_, 0, static_cast<size_t>(
         reinterpret_cast<char*>(&idempotency_level_) -
         reinterpret_cast<char*>(&deprecated_)) + sizeof(idempotency_level_));
@@ -11209,9 +13639,95 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* MethodOptions::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<MethodOptions*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // optional bool deprecated = 33 [default = false];
+      case 33: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_deprecated(value);
+        break;
+      }
+      // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
+      case 34: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        if (!::google::protobuf::MethodOptions_IdempotencyLevel_IsValid(val)) {
+          ::google::protobuf::internal::WriteVarint(34, val, msg->mutable_unknown_fields());
+          break;
+        }
+        ::google::protobuf::MethodOptions_IdempotencyLevel value = static_cast<::google::protobuf::MethodOptions_IdempotencyLevel>(val);
+        msg->set_idempotency_level(value);
+        break;
+      }
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::UninterpretedOption::_InternalParse;
+          object = msg->add_uninterpreted_option();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 65535) == 16058 && (ptr += 2));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+      if ((8000u <= tag)) {
+        auto res = msg->_extensions_.ParseField(tag, {_InternalParse, msg}, ptr, end,
+            internal_default_instance(), &msg->_internal_metadata_, ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+        continue;
+      }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool MethodOptions::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.MethodOptions)
   for (;;) {
@@ -11221,9 +13737,8 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // optional bool deprecated = 33 [default = false];
       case 33: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 264 & 0xFF */)) {
-          set_has_deprecated();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (264 & 0xFF)) {
+          HasBitSetters::set_has_deprecated(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &deprecated_)));
@@ -11235,8 +13750,7 @@
 
       // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
       case 34: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 272 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (272 & 0xFF)) {
           int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -11245,7 +13759,7 @@
             set_idempotency_level(static_cast< ::google::protobuf::MethodOptions_IdempotencyLevel >(value));
           } else {
             mutable_unknown_fields()->AddVarint(
-                34, static_cast< ::google::protobuf::uint64>(value));
+                34, static_cast<::google::protobuf::uint64>(value));
           }
         } else {
           goto handle_unusual;
@@ -11255,8 +13769,7 @@
 
       // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
       case 999: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 7994 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (7994 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_uninterpreted_option()));
         } else {
@@ -11290,6 +13803,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void MethodOptions::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -11319,8 +13833,7 @@
   }
 
   // Extension range [1000, 536870912)
-  _extensions_.SerializeWithCachedSizes(
-      1000, 536870912, output);
+  _extensions_.SerializeWithCachedSizes(1000, 536870912, output);
 
   if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
@@ -11379,6 +13892,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   {
     unsigned int count = static_cast<unsigned int>(this->uninterpreted_option_size());
@@ -11390,14 +13907,15 @@
     }
   }
 
-  if (_has_bits_[0 / 32] & 3u) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000003u) {
     // optional bool deprecated = 33 [default = false];
-    if (has_deprecated()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 2 + 1;
     }
 
     // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];
-    if (has_idempotency_level()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 2 +
         ::google::protobuf::internal::WireFormatLite::EnumSize(this->idempotency_level());
     }
@@ -11412,7 +13930,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.MethodOptions)
   GOOGLE_DCHECK_NE(&from, this);
   const MethodOptions* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const MethodOptions>(
+      ::google::protobuf::DynamicCastToGenerated<MethodOptions>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.MethodOptions)
@@ -11433,7 +13951,7 @@
 
   uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       deprecated_ = from.deprecated_;
     }
@@ -11488,17 +14006,17 @@
 }
 void MethodOptions::InternalSwap(MethodOptions* other) {
   using std::swap;
+  _extensions_.Swap(&other->_extensions_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   CastToBase(&uninterpreted_option_)->InternalSwap(CastToBase(&other->uninterpreted_option_));
   swap(deprecated_, other->deprecated_);
   swap(idempotency_level_, other->idempotency_level_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
-  _extensions_.Swap(&other->_extensions_);
 }
 
 ::google::protobuf::Metadata MethodOptions::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -11506,6 +14024,16 @@
 
 void UninterpretedOption_NamePart::InitAsDefaultInstance() {
 }
+class UninterpretedOption_NamePart::HasBitSetters {
+ public:
+  static void set_has_name_part(UninterpretedOption_NamePart* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_is_extension(UninterpretedOption_NamePart* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int UninterpretedOption_NamePart::kNamePartFieldNumber;
 const int UninterpretedOption_NamePart::kIsExtensionFieldNumber;
@@ -11513,15 +14041,12 @@
 
 UninterpretedOption_NamePart::UninterpretedOption_NamePart()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption_NamePart.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption.NamePart)
 }
 UninterpretedOption_NamePart::UninterpretedOption_NamePart(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption_NamePart.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption.NamePart)
@@ -11541,6 +14066,8 @@
 }
 
 void UninterpretedOption_NamePart::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_UninterpretedOption_NamePart_google_2fprotobuf_2fdescriptor_2eproto.base);
   name_part_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   is_extension_ = false;
 }
@@ -11564,13 +14091,8 @@
 void UninterpretedOption_NamePart::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* UninterpretedOption_NamePart::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const UninterpretedOption_NamePart& UninterpretedOption_NamePart::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption_NamePart.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_UninterpretedOption_NamePart_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -11590,9 +14112,74 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* UninterpretedOption_NamePart::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<UninterpretedOption_NamePart*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // required string name_part = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.UninterpretedOption.NamePart.name_part");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_name_part();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // required bool is_extension = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_is_extension(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool UninterpretedOption_NamePart::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.UninterpretedOption.NamePart)
   for (;;) {
@@ -11602,8 +14189,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // required string name_part = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name_part()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -11618,9 +14204,8 @@
 
       // required bool is_extension = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
-          set_has_is_extension();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          HasBitSetters::set_has_is_extension(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                  input, &is_extension_)));
@@ -11649,6 +14234,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void UninterpretedOption_NamePart::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -11750,6 +14336,10 @@
   } else {
     total_size += RequiredFieldsByteSizeFallback();
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
   SetCachedSize(cached_size);
   return total_size;
@@ -11759,7 +14349,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UninterpretedOption.NamePart)
   GOOGLE_DCHECK_NE(&from, this);
   const UninterpretedOption_NamePart* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const UninterpretedOption_NamePart>(
+      ::google::protobuf::DynamicCastToGenerated<UninterpretedOption_NamePart>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.UninterpretedOption.NamePart)
@@ -11778,7 +14368,7 @@
   (void) cached_has_bits;
 
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       set_name_part(from.name_part());
     }
@@ -11829,16 +14419,16 @@
 }
 void UninterpretedOption_NamePart::InternalSwap(UninterpretedOption_NamePart* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   name_part_.Swap(&other->name_part_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   swap(is_extension_, other->is_extension_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -11846,6 +14436,28 @@
 
 void UninterpretedOption::InitAsDefaultInstance() {
 }
+class UninterpretedOption::HasBitSetters {
+ public:
+  static void set_has_identifier_value(UninterpretedOption* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_positive_int_value(UninterpretedOption* msg) {
+    msg->_has_bits_[0] |= 0x00000008u;
+  }
+  static void set_has_negative_int_value(UninterpretedOption* msg) {
+    msg->_has_bits_[0] |= 0x00000010u;
+  }
+  static void set_has_double_value(UninterpretedOption* msg) {
+    msg->_has_bits_[0] |= 0x00000020u;
+  }
+  static void set_has_string_value(UninterpretedOption* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+  static void set_has_aggregate_value(UninterpretedOption* msg) {
+    msg->_has_bits_[0] |= 0x00000004u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int UninterpretedOption::kNameFieldNumber;
 const int UninterpretedOption::kIdentifierValueFieldNumber;
@@ -11858,8 +14470,6 @@
 
 UninterpretedOption::UninterpretedOption()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption)
 }
@@ -11867,7 +14477,6 @@
   : ::google::protobuf::Message(),
   _internal_metadata_(arena),
   name_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption)
@@ -11900,6 +14509,8 @@
 }
 
 void UninterpretedOption::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto.base);
   identifier_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   aggregate_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -11929,13 +14540,8 @@
 void UninterpretedOption::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* UninterpretedOption::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const UninterpretedOption& UninterpretedOption::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_UninterpretedOption.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -11948,7 +14554,7 @@
 
   name_.Clear();
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 7u) {
+  if (cached_has_bits & 0x00000007u) {
     if (cached_has_bits & 0x00000001u) {
       identifier_value_.ClearNonDefaultToEmpty();
     }
@@ -11959,7 +14565,7 @@
       aggregate_value_.ClearNonDefaultToEmpty();
     }
   }
-  if (cached_has_bits & 56u) {
+  if (cached_has_bits & 0x00000038u) {
     ::memset(&positive_int_value_, 0, static_cast<size_t>(
         reinterpret_cast<char*>(&double_value_) -
         reinterpret_cast<char*>(&positive_int_value_)) + sizeof(double_value_));
@@ -11968,9 +14574,140 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* UninterpretedOption::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<UninterpretedOption*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::UninterpretedOption_NamePart::_InternalParse;
+          object = msg->add_name();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 18 && (ptr += 1));
+        break;
+      }
+      // optional string identifier_value = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.UninterpretedOption.identifier_value");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_identifier_value();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional uint64 positive_int_value = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::uint64 value = val;
+        msg->set_positive_int_value(value);
+        break;
+      }
+      // optional int64 negative_int_value = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int64 value = val;
+        msg->set_negative_int_value(value);
+        break;
+      }
+      // optional double double_value = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 49) goto handle_unusual;
+        double val;
+        ::std::memcpy(&val, ptr, 8);
+        ptr += 8;
+        msg->set_double_value(val);
+        break;
+      }
+      // optional bytes string_value = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::internal::StringParser;
+        ::std::string* str = msg->mutable_string_value();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string aggregate_value = 8;
+      case 8: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.UninterpretedOption.aggregate_value");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_aggregate_value();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool UninterpretedOption::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.UninterpretedOption)
   for (;;) {
@@ -11980,8 +14717,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_name()));
         } else {
@@ -11992,8 +14728,7 @@
 
       // optional string identifier_value = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_identifier_value()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -12008,9 +14743,8 @@
 
       // optional uint64 positive_int_value = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
-          set_has_positive_int_value();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
+          HasBitSetters::set_has_positive_int_value(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                  input, &positive_int_value_)));
@@ -12022,9 +14756,8 @@
 
       // optional int64 negative_int_value = 5;
       case 5: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
-          set_has_negative_int_value();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
+          HasBitSetters::set_has_negative_int_value(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                  input, &negative_int_value_)));
@@ -12036,9 +14769,8 @@
 
       // optional double double_value = 6;
       case 6: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(49u /* 49 & 0xFF */)) {
-          set_has_double_value();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (49 & 0xFF)) {
+          HasBitSetters::set_has_double_value(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                  input, &double_value_)));
@@ -12050,8 +14782,7 @@
 
       // optional bytes string_value = 7;
       case 7: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(58u /* 58 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (58 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                 input, this->mutable_string_value()));
         } else {
@@ -12062,8 +14793,7 @@
 
       // optional string aggregate_value = 8;
       case 8: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(66u /* 66 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (66 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_aggregate_value()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -12095,6 +14825,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void UninterpretedOption::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -12237,6 +14968,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
   {
     unsigned int count = static_cast<unsigned int>(this->name_size());
@@ -12248,44 +14983,45 @@
     }
   }
 
-  if (_has_bits_[0 / 32] & 63u) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x0000003fu) {
     // optional string identifier_value = 3;
-    if (has_identifier_value()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->identifier_value());
     }
 
     // optional bytes string_value = 7;
-    if (has_string_value()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::BytesSize(
           this->string_value());
     }
 
     // optional string aggregate_value = 8;
-    if (has_aggregate_value()) {
+    if (cached_has_bits & 0x00000004u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->aggregate_value());
     }
 
     // optional uint64 positive_int_value = 4;
-    if (has_positive_int_value()) {
+    if (cached_has_bits & 0x00000008u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::UInt64Size(
           this->positive_int_value());
     }
 
     // optional int64 negative_int_value = 5;
-    if (has_negative_int_value()) {
+    if (cached_has_bits & 0x00000010u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int64Size(
           this->negative_int_value());
     }
 
     // optional double double_value = 6;
-    if (has_double_value()) {
+    if (cached_has_bits & 0x00000020u) {
       total_size += 1 + 8;
     }
 
@@ -12299,7 +15035,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UninterpretedOption)
   GOOGLE_DCHECK_NE(&from, this);
   const UninterpretedOption* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const UninterpretedOption>(
+      ::google::protobuf::DynamicCastToGenerated<UninterpretedOption>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.UninterpretedOption)
@@ -12319,7 +15055,7 @@
 
   name_.MergeFrom(from.name_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 63u) {
+  if (cached_has_bits & 0x0000003fu) {
     if (cached_has_bits & 0x00000001u) {
       set_identifier_value(from.identifier_value());
     }
@@ -12382,6 +15118,8 @@
 }
 void UninterpretedOption::InternalSwap(UninterpretedOption* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   CastToBase(&name_)->InternalSwap(CastToBase(&other->name_));
   identifier_value_.Swap(&other->identifier_value_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
@@ -12392,13 +15130,11 @@
   swap(positive_int_value_, other->positive_int_value_);
   swap(negative_int_value_, other->negative_int_value_);
   swap(double_value_, other->double_value_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata UninterpretedOption::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -12406,6 +15142,16 @@
 
 void SourceCodeInfo_Location::InitAsDefaultInstance() {
 }
+class SourceCodeInfo_Location::HasBitSetters {
+ public:
+  static void set_has_leading_comments(SourceCodeInfo_Location* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_trailing_comments(SourceCodeInfo_Location* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int SourceCodeInfo_Location::kPathFieldNumber;
 const int SourceCodeInfo_Location::kSpanFieldNumber;
@@ -12416,8 +15162,6 @@
 
 SourceCodeInfo_Location::SourceCodeInfo_Location()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo_Location.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo.Location)
 }
@@ -12427,7 +15171,6 @@
   path_(arena),
   span_(arena),
   leading_detached_comments_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo_Location.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo.Location)
@@ -12454,6 +15197,8 @@
 }
 
 void SourceCodeInfo_Location::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_SourceCodeInfo_Location_google_2fprotobuf_2fdescriptor_2eproto.base);
   leading_comments_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   trailing_comments_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
@@ -12478,13 +15223,8 @@
 void SourceCodeInfo_Location::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* SourceCodeInfo_Location::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const SourceCodeInfo_Location& SourceCodeInfo_Location::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo_Location.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_SourceCodeInfo_Location_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -12499,7 +15239,7 @@
   span_.Clear();
   leading_detached_comments_.Clear();
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       leading_comments_.ClearNonDefaultToEmpty();
     }
@@ -12511,9 +15251,145 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* SourceCodeInfo_Location::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<SourceCodeInfo_Location*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // repeated int32 path = 1 [packed = true];
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) == 10) {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::internal::PackedInt32Parser;
+          object = msg->mutable_path();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          break;
+        } else if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        do {
+          ::google::protobuf::uint64 val;
+          ptr = Varint::Parse64(ptr, &val);
+          if (!ptr) goto error;
+          ::google::protobuf::int32 value = val;
+          msg->add_path(value);
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 8 && (ptr += 1));
+        break;
+      }
+      // repeated int32 span = 2 [packed = true];
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) == 18) {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::internal::PackedInt32Parser;
+          object = msg->mutable_span();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          break;
+        } else if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        do {
+          ::google::protobuf::uint64 val;
+          ptr = Varint::Parse64(ptr, &val);
+          if (!ptr) goto error;
+          ::google::protobuf::int32 value = val;
+          msg->add_span(value);
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 16 && (ptr += 1));
+        break;
+      }
+      // optional string leading_comments = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.SourceCodeInfo.Location.leading_comments");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_leading_comments();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional string trailing_comments = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.SourceCodeInfo.Location.trailing_comments");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_trailing_comments();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated string leading_detached_comments = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          ctx->extra_parse_data().SetFieldName("google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
+          parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+          ::std::string* str = msg->add_leading_detached_comments();
+          str->clear();
+          object = str;
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 50 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool SourceCodeInfo_Location::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.SourceCodeInfo.Location)
   for (;;) {
@@ -12523,14 +15399,11 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // repeated int32 path = 1 [packed = true];
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, this->mutable_path())));
-        } else if (
-            static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+        } else if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
           DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  1, 10u, input, this->mutable_path())));
@@ -12542,14 +15415,11 @@
 
       // repeated int32 span = 2 [packed = true];
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, this->mutable_span())));
-        } else if (
-            static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
+        } else if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
           DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  1, 18u, input, this->mutable_span())));
@@ -12561,8 +15431,7 @@
 
       // optional string leading_comments = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_leading_comments()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -12577,8 +15446,7 @@
 
       // optional string trailing_comments = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_trailing_comments()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -12593,8 +15461,7 @@
 
       // repeated string leading_detached_comments = 6;
       case 6: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->add_leading_detached_comments()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -12627,6 +15494,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void SourceCodeInfo_Location::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -12637,8 +15505,8 @@
   // repeated int32 path = 1 [packed = true];
   if (this->path_size() > 0) {
     ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
-    output->WriteVarint32(static_cast< ::google::protobuf::uint32>(
-        _path_cached_byte_size_));
+    output->WriteVarint32(_path_cached_byte_size_.load(
+        std::memory_order_relaxed));
   }
   for (int i = 0, n = this->path_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
@@ -12648,8 +15516,8 @@
   // repeated int32 span = 2 [packed = true];
   if (this->span_size() > 0) {
     ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
-    output->WriteVarint32(static_cast< ::google::protobuf::uint32>(
-        _span_cached_byte_size_));
+    output->WriteVarint32(_span_cached_byte_size_.load(
+        std::memory_order_relaxed));
   }
   for (int i = 0, n = this->span_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
@@ -12708,8 +15576,8 @@
       ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
       target);
     target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
-        static_cast< ::google::protobuf::int32>(
-            _path_cached_byte_size_), target);
+        _path_cached_byte_size_.load(std::memory_order_relaxed),
+         target);
     target = ::google::protobuf::internal::WireFormatLite::
       WriteInt32NoTagToArray(this->path_, target);
   }
@@ -12721,8 +15589,8 @@
       ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
       target);
     target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
-        static_cast< ::google::protobuf::int32>(
-            _span_cached_byte_size_), target);
+        _span_cached_byte_size_.load(std::memory_order_relaxed),
+         target);
     target = ::google::protobuf::internal::WireFormatLite::
       WriteInt32NoTagToArray(this->span_, target);
   }
@@ -12777,6 +15645,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated int32 path = 1 [packed = true];
   {
     size_t data_size = ::google::protobuf::internal::WireFormatLite::
@@ -12784,12 +15656,11 @@
     if (data_size > 0) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
-            static_cast< ::google::protobuf::int32>(data_size));
+            static_cast<::google::protobuf::int32>(data_size));
     }
     int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);
-    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
-    _path_cached_byte_size_ = cached_size;
-    GOOGLE_SAFE_CONCURRENT_WRITES_END();
+    _path_cached_byte_size_.store(cached_size,
+                                    std::memory_order_relaxed);
     total_size += data_size;
   }
 
@@ -12800,12 +15671,11 @@
     if (data_size > 0) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
-            static_cast< ::google::protobuf::int32>(data_size));
+            static_cast<::google::protobuf::int32>(data_size));
     }
     int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);
-    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
-    _span_cached_byte_size_ = cached_size;
-    GOOGLE_SAFE_CONCURRENT_WRITES_END();
+    _span_cached_byte_size_.store(cached_size,
+                                    std::memory_order_relaxed);
     total_size += data_size;
   }
 
@@ -12817,16 +15687,17 @@
       this->leading_detached_comments(i));
   }
 
-  if (_has_bits_[0 / 32] & 3u) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000003u) {
     // optional string leading_comments = 3;
-    if (has_leading_comments()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->leading_comments());
     }
 
     // optional string trailing_comments = 4;
-    if (has_trailing_comments()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->trailing_comments());
@@ -12842,7 +15713,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.SourceCodeInfo.Location)
   GOOGLE_DCHECK_NE(&from, this);
   const SourceCodeInfo_Location* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const SourceCodeInfo_Location>(
+      ::google::protobuf::DynamicCastToGenerated<SourceCodeInfo_Location>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.SourceCodeInfo.Location)
@@ -12864,7 +15735,7 @@
   span_.MergeFrom(from.span_);
   leading_detached_comments_.MergeFrom(from.leading_detached_comments_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 3u) {
+  if (cached_has_bits & 0x00000003u) {
     if (cached_has_bits & 0x00000001u) {
       set_leading_comments(from.leading_comments());
     }
@@ -12913,6 +15784,8 @@
 }
 void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   path_.InternalSwap(&other->path_);
   span_.InternalSwap(&other->span_);
   leading_detached_comments_.InternalSwap(CastToBase(&other->leading_detached_comments_));
@@ -12920,13 +15793,11 @@
     GetArenaNoVirtual());
   trailing_comments_.Swap(&other->trailing_comments_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -12934,14 +15805,16 @@
 
 void SourceCodeInfo::InitAsDefaultInstance() {
 }
+class SourceCodeInfo::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int SourceCodeInfo::kLocationFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 SourceCodeInfo::SourceCodeInfo()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo)
 }
@@ -12949,7 +15822,6 @@
   : ::google::protobuf::Message(),
   _internal_metadata_(arena),
   location_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo)
@@ -12964,6 +15836,8 @@
 }
 
 void SourceCodeInfo::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_SourceCodeInfo_google_2fprotobuf_2fdescriptor_2eproto.base);
 }
 
 SourceCodeInfo::~SourceCodeInfo() {
@@ -12984,13 +15858,8 @@
 void SourceCodeInfo::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* SourceCodeInfo::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const SourceCodeInfo& SourceCodeInfo::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_SourceCodeInfo.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_SourceCodeInfo_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -13006,9 +15875,64 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* SourceCodeInfo::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<SourceCodeInfo*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::SourceCodeInfo_Location::_InternalParse;
+          object = msg->add_location();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 10 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool SourceCodeInfo::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.SourceCodeInfo)
   for (;;) {
@@ -13018,8 +15942,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_location()));
         } else {
@@ -13047,6 +15970,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void SourceCodeInfo::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -13102,6 +16026,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
   {
     unsigned int count = static_cast<unsigned int>(this->location_size());
@@ -13122,7 +16050,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.SourceCodeInfo)
   GOOGLE_DCHECK_NE(&from, this);
   const SourceCodeInfo* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const SourceCodeInfo>(
+      ::google::protobuf::DynamicCastToGenerated<SourceCodeInfo>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.SourceCodeInfo)
@@ -13182,14 +16110,14 @@
 }
 void SourceCodeInfo::InternalSwap(SourceCodeInfo* other) {
   using std::swap;
-  CastToBase(&location_)->InternalSwap(CastToBase(&other->location_));
-  swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
+  CastToBase(&location_)->InternalSwap(CastToBase(&other->location_));
 }
 
 ::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -13197,6 +16125,19 @@
 
 void GeneratedCodeInfo_Annotation::InitAsDefaultInstance() {
 }
+class GeneratedCodeInfo_Annotation::HasBitSetters {
+ public:
+  static void set_has_source_file(GeneratedCodeInfo_Annotation* msg) {
+    msg->_has_bits_[0] |= 0x00000001u;
+  }
+  static void set_has_begin(GeneratedCodeInfo_Annotation* msg) {
+    msg->_has_bits_[0] |= 0x00000002u;
+  }
+  static void set_has_end(GeneratedCodeInfo_Annotation* msg) {
+    msg->_has_bits_[0] |= 0x00000004u;
+  }
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int GeneratedCodeInfo_Annotation::kPathFieldNumber;
 const int GeneratedCodeInfo_Annotation::kSourceFileFieldNumber;
@@ -13206,8 +16147,6 @@
 
 GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo_Annotation.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.GeneratedCodeInfo.Annotation)
 }
@@ -13215,7 +16154,6 @@
   : ::google::protobuf::Message(),
   _internal_metadata_(arena),
   path_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo_Annotation.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo.Annotation)
@@ -13238,6 +16176,8 @@
 }
 
 void GeneratedCodeInfo_Annotation::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_GeneratedCodeInfo_Annotation_google_2fprotobuf_2fdescriptor_2eproto.base);
   source_file_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   ::memset(&begin_, 0, static_cast<size_t>(
       reinterpret_cast<char*>(&end_) -
@@ -13263,13 +16203,8 @@
 void GeneratedCodeInfo_Annotation::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* GeneratedCodeInfo_Annotation::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const GeneratedCodeInfo_Annotation& GeneratedCodeInfo_Annotation::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo_Annotation.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_GeneratedCodeInfo_Annotation_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -13285,7 +16220,7 @@
   if (cached_has_bits & 0x00000001u) {
     source_file_.ClearNonDefaultToEmpty();
   }
-  if (cached_has_bits & 6u) {
+  if (cached_has_bits & 0x00000006u) {
     ::memset(&begin_, 0, static_cast<size_t>(
         reinterpret_cast<char*>(&end_) -
         reinterpret_cast<char*>(&begin_)) + sizeof(end_));
@@ -13294,9 +16229,107 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* GeneratedCodeInfo_Annotation::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<GeneratedCodeInfo_Annotation*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // repeated int32 path = 1 [packed = true];
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) == 10) {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::internal::PackedInt32Parser;
+          object = msg->mutable_path();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          break;
+        } else if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        do {
+          ::google::protobuf::uint64 val;
+          ptr = Varint::Parse64(ptr, &val);
+          if (!ptr) goto error;
+          ::google::protobuf::int32 value = val;
+          msg->add_path(value);
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 8 && (ptr += 1));
+        break;
+      }
+      // optional string source_file = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.GeneratedCodeInfo.Annotation.source_file");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8Verify;
+        ::std::string* str = msg->mutable_source_file();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // optional int32 begin = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_begin(value);
+        break;
+      }
+      // optional int32 end = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_end(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool GeneratedCodeInfo_Annotation::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.GeneratedCodeInfo.Annotation)
   for (;;) {
@@ -13306,14 +16339,11 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // repeated int32 path = 1 [packed = true];
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, this->mutable_path())));
-        } else if (
-            static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+        } else if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
           DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  1, 10u, input, this->mutable_path())));
@@ -13325,8 +16355,7 @@
 
       // optional string source_file = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_source_file()));
           ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
@@ -13341,9 +16370,8 @@
 
       // optional int32 begin = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
-          set_has_begin();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          HasBitSetters::set_has_begin(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &begin_)));
@@ -13355,9 +16383,8 @@
 
       // optional int32 end = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
-          set_has_end();
+        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
+          HasBitSetters::set_has_end(this);
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                  input, &end_)));
@@ -13386,6 +16413,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void GeneratedCodeInfo_Annotation::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -13396,8 +16424,8 @@
   // repeated int32 path = 1 [packed = true];
   if (this->path_size() > 0) {
     ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
-    output->WriteVarint32(static_cast< ::google::protobuf::uint32>(
-        _path_cached_byte_size_));
+    output->WriteVarint32(_path_cached_byte_size_.load(
+        std::memory_order_relaxed));
   }
   for (int i = 0, n = this->path_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
@@ -13446,8 +16474,8 @@
       ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
       target);
     target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
-        static_cast< ::google::protobuf::int32>(
-            _path_cached_byte_size_), target);
+        _path_cached_byte_size_.load(std::memory_order_relaxed),
+         target);
     target = ::google::protobuf::internal::WireFormatLite::
       WriteInt32NoTagToArray(this->path_, target);
   }
@@ -13491,6 +16519,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated int32 path = 1 [packed = true];
   {
     size_t data_size = ::google::protobuf::internal::WireFormatLite::
@@ -13498,32 +16530,32 @@
     if (data_size > 0) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
-            static_cast< ::google::protobuf::int32>(data_size));
+            static_cast<::google::protobuf::int32>(data_size));
     }
     int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);
-    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
-    _path_cached_byte_size_ = cached_size;
-    GOOGLE_SAFE_CONCURRENT_WRITES_END();
+    _path_cached_byte_size_.store(cached_size,
+                                    std::memory_order_relaxed);
     total_size += data_size;
   }
 
-  if (_has_bits_[0 / 32] & 7u) {
+  cached_has_bits = _has_bits_[0];
+  if (cached_has_bits & 0x00000007u) {
     // optional string source_file = 2;
-    if (has_source_file()) {
+    if (cached_has_bits & 0x00000001u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::StringSize(
           this->source_file());
     }
 
     // optional int32 begin = 3;
-    if (has_begin()) {
+    if (cached_has_bits & 0x00000002u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->begin());
     }
 
     // optional int32 end = 4;
-    if (has_end()) {
+    if (cached_has_bits & 0x00000004u) {
       total_size += 1 +
         ::google::protobuf::internal::WireFormatLite::Int32Size(
           this->end());
@@ -13539,7 +16571,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
   GOOGLE_DCHECK_NE(&from, this);
   const GeneratedCodeInfo_Annotation* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const GeneratedCodeInfo_Annotation>(
+      ::google::protobuf::DynamicCastToGenerated<GeneratedCodeInfo_Annotation>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.GeneratedCodeInfo.Annotation)
@@ -13559,7 +16591,7 @@
 
   path_.MergeFrom(from.path_);
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 7u) {
+  if (cached_has_bits & 0x00000007u) {
     if (cached_has_bits & 0x00000001u) {
       set_source_file(from.source_file());
     }
@@ -13612,18 +16644,18 @@
 }
 void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
   path_.InternalSwap(&other->path_);
   source_file_.Swap(&other->source_file_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   swap(begin_, other->begin_);
   swap(end_, other->end_);
-  swap(_has_bits_[0], other->_has_bits_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata GeneratedCodeInfo_Annotation::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
@@ -13631,14 +16663,16 @@
 
 void GeneratedCodeInfo::InitAsDefaultInstance() {
 }
+class GeneratedCodeInfo::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int GeneratedCodeInfo::kAnnotationFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 GeneratedCodeInfo::GeneratedCodeInfo()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.GeneratedCodeInfo)
 }
@@ -13646,7 +16680,6 @@
   : ::google::protobuf::Message(),
   _internal_metadata_(arena),
   annotation_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo)
@@ -13661,6 +16694,8 @@
 }
 
 void GeneratedCodeInfo::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto.base);
 }
 
 GeneratedCodeInfo::~GeneratedCodeInfo() {
@@ -13681,13 +16716,8 @@
 void GeneratedCodeInfo::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* GeneratedCodeInfo::descriptor() {
-  ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const GeneratedCodeInfo& GeneratedCodeInfo::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_GeneratedCodeInfo.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -13703,9 +16733,64 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* GeneratedCodeInfo::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<GeneratedCodeInfo*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::GeneratedCodeInfo_Annotation::_InternalParse;
+          object = msg->add_annotation();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 10 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool GeneratedCodeInfo::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.GeneratedCodeInfo)
   for (;;) {
@@ -13715,8 +16800,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_annotation()));
         } else {
@@ -13744,6 +16828,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void GeneratedCodeInfo::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -13799,6 +16884,10 @@
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
         _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
   {
     unsigned int count = static_cast<unsigned int>(this->annotation_size());
@@ -13819,7 +16908,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.GeneratedCodeInfo)
   GOOGLE_DCHECK_NE(&from, this);
   const GeneratedCodeInfo* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const GeneratedCodeInfo>(
+      ::google::protobuf::DynamicCastToGenerated<GeneratedCodeInfo>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.GeneratedCodeInfo)
@@ -13879,14 +16968,14 @@
 }
 void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* other) {
   using std::swap;
-  CastToBase(&annotation_)->InternalSwap(CastToBase(&other->annotation_));
-  swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(_has_bits_[0], other->_has_bits_[0]);
+  CastToBase(&annotation_)->InternalSwap(CastToBase(&other->annotation_));
 }
 
 ::google::protobuf::Metadata GeneratedCodeInfo::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fdescriptor_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[kIndexInFileMessages];
 }
 
 
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index d7b2270..3459a07 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -4,18 +4,18 @@
 #ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto
 #define PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto
 
+#include <limits>
 #include <string>
 
 #include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 3006001
+#if GOOGLE_PROTOBUF_VERSION < 3006000
 #error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please update
+#error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
 #if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
 #error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please
+#error incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.
 #endif
 
@@ -32,20 +32,22 @@
 #include <google/protobuf/generated_enum_reflection.h>
 #include <google/protobuf/unknown_field_set.h>
 // @@protoc_insertion_point(includes)
-#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto LIBPROTOBUF_EXPORT
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto LIBPROTOBUF_EXPORT
 
-namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto {
 // Internal implementation detail -- do not use these members.
-struct LIBPROTOBUF_EXPORT TableStruct {
-  static const ::google::protobuf::internal::ParseTableField entries[];
-  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
-  static const ::google::protobuf::internal::ParseTable schema[27];
+struct LIBPROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fdescriptor_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[27]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
   static const ::google::protobuf::uint32 offsets[];
 };
-void LIBPROTOBUF_EXPORT AddDescriptors();
-}  // namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto
+void LIBPROTOBUF_EXPORT AddDescriptors_google_2fprotobuf_2fdescriptor_2eproto();
 namespace google {
 namespace protobuf {
 class DescriptorProto;
@@ -129,10 +131,6 @@
 class UninterpretedOption_NamePart;
 class UninterpretedOption_NamePartDefaultTypeInternal;
 LIBPROTOBUF_EXPORT extern UninterpretedOption_NamePartDefaultTypeInternal _UninterpretedOption_NamePart_default_instance_;
-}  // namespace protobuf
-}  // namespace google
-namespace google {
-namespace protobuf {
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::DescriptorProto* Arena::CreateMaybeMessage<::google::protobuf::DescriptorProto>(Arena*);
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::DescriptorProto_ExtensionRange* Arena::CreateMaybeMessage<::google::protobuf::DescriptorProto_ExtensionRange>(Arena*);
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::DescriptorProto_ReservedRange* Arena::CreateMaybeMessage<::google::protobuf::DescriptorProto_ReservedRange>(Arena*);
@@ -341,7 +339,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const FileDescriptorSet& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -375,8 +375,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -422,6 +427,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -430,7 +436,7 @@
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -473,7 +479,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const FileDescriptorProto& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -507,8 +515,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -559,8 +572,8 @@
   #endif
   void add_dependency(const char* value);
   void add_dependency(const char* value, size_t size);
-  const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const;
-  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency();
+  const ::google::protobuf::RepeatedPtrField<::std::string>& dependency() const;
+  ::google::protobuf::RepeatedPtrField<::std::string>* mutable_dependency();
 
   // repeated .google.protobuf.DescriptorProto message_type = 4;
   int message_type_size() const;
@@ -648,11 +661,11 @@
   ::std::string* mutable_name();
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name(
@@ -672,11 +685,11 @@
   ::std::string* mutable_package();
   ::std::string* release_package();
   void set_allocated_package(::std::string* package);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_package();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_package(
@@ -696,11 +709,11 @@
   ::std::string* mutable_syntax();
   ::std::string* release_syntax();
   void set_allocated_syntax(::std::string* syntax);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_syntax();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_syntax(
@@ -710,9 +723,6 @@
   bool has_options() const;
   void clear_options();
   static const int kOptionsFieldNumber = 8;
-  private:
-  const ::google::protobuf::FileOptions& _internal_options() const;
-  public:
   const ::google::protobuf::FileOptions& options() const;
   ::google::protobuf::FileOptions* release_options();
   ::google::protobuf::FileOptions* mutable_options();
@@ -725,9 +735,6 @@
   bool has_source_code_info() const;
   void clear_source_code_info();
   static const int kSourceCodeInfoFieldNumber = 9;
-  private:
-  const ::google::protobuf::SourceCodeInfo& _internal_source_code_info() const;
-  public:
   const ::google::protobuf::SourceCodeInfo& source_code_info() const;
   ::google::protobuf::SourceCodeInfo* release_source_code_info();
   ::google::protobuf::SourceCodeInfo* mutable_source_code_info();
@@ -738,16 +745,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto)
  private:
-  void set_has_name();
-  void clear_has_name();
-  void set_has_package();
-  void clear_has_package();
-  void set_has_options();
-  void clear_has_options();
-  void set_has_source_code_info();
-  void clear_has_source_code_info();
-  void set_has_syntax();
-  void clear_has_syntax();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -755,7 +753,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  ::google::protobuf::RepeatedPtrField< ::std::string> dependency_;
+  ::google::protobuf::RepeatedPtrField<::std::string> dependency_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_;
@@ -767,7 +765,7 @@
   ::google::protobuf::internal::ArenaStringPtr syntax_;
   ::google::protobuf::FileOptions* options_;
   ::google::protobuf::SourceCodeInfo* source_code_info_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -810,7 +808,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const DescriptorProto_ExtensionRange& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -844,8 +844,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -881,9 +886,6 @@
   bool has_options() const;
   void clear_options();
   static const int kOptionsFieldNumber = 3;
-  private:
-  const ::google::protobuf::ExtensionRangeOptions& _internal_options() const;
-  public:
   const ::google::protobuf::ExtensionRangeOptions& options() const;
   ::google::protobuf::ExtensionRangeOptions* release_options();
   ::google::protobuf::ExtensionRangeOptions* mutable_options();
@@ -908,12 +910,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange)
  private:
-  void set_has_start();
-  void clear_has_start();
-  void set_has_end();
-  void clear_has_end();
-  void set_has_options();
-  void clear_has_options();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -924,7 +921,7 @@
   ::google::protobuf::ExtensionRangeOptions* options_;
   ::google::protobuf::int32 start_;
   ::google::protobuf::int32 end_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -967,7 +964,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const DescriptorProto_ReservedRange& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -1001,8 +1000,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -1050,10 +1054,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ReservedRange)
  private:
-  void set_has_start();
-  void clear_has_start();
-  void set_has_end();
-  void clear_has_end();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -1063,7 +1064,7 @@
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::int32 start_;
   ::google::protobuf::int32 end_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -1106,7 +1107,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const DescriptorProto& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -1140,8 +1143,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -1279,8 +1287,8 @@
   #endif
   void add_reserved_name(const char* value);
   void add_reserved_name(const char* value, size_t size);
-  const ::google::protobuf::RepeatedPtrField< ::std::string>& reserved_name() const;
-  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_reserved_name();
+  const ::google::protobuf::RepeatedPtrField<::std::string>& reserved_name() const;
+  ::google::protobuf::RepeatedPtrField<::std::string>* mutable_reserved_name();
 
   // optional string name = 1;
   bool has_name() const;
@@ -1296,11 +1304,11 @@
   ::std::string* mutable_name();
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name(
@@ -1310,9 +1318,6 @@
   bool has_options() const;
   void clear_options();
   static const int kOptionsFieldNumber = 7;
-  private:
-  const ::google::protobuf::MessageOptions& _internal_options() const;
-  public:
   const ::google::protobuf::MessageOptions& options() const;
   ::google::protobuf::MessageOptions* release_options();
   ::google::protobuf::MessageOptions* mutable_options();
@@ -1323,10 +1328,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto)
  private:
-  void set_has_name();
-  void clear_has_name();
-  void set_has_options();
-  void clear_has_options();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -1341,10 +1343,10 @@
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto > oneof_decl_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange > reserved_range_;
-  ::google::protobuf::RepeatedPtrField< ::std::string> reserved_name_;
+  ::google::protobuf::RepeatedPtrField<::std::string> reserved_name_;
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::MessageOptions* options_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -1387,7 +1389,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const ExtensionRangeOptions& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -1421,8 +1425,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -1469,6 +1478,7 @@
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ExtensionRangeOptions)
   // @@protoc_insertion_point(class_scope:google.protobuf.ExtensionRangeOptions)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::ExtensionSet _extensions_;
 
@@ -1479,7 +1489,7 @@
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -1522,7 +1532,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const FieldDescriptorProto& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -1556,8 +1568,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -1689,11 +1706,11 @@
   ::std::string* mutable_name();
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name(
@@ -1713,11 +1730,11 @@
   ::std::string* mutable_extendee();
   ::std::string* release_extendee();
   void set_allocated_extendee(::std::string* extendee);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_extendee();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_extendee(
@@ -1737,11 +1754,11 @@
   ::std::string* mutable_type_name();
   ::std::string* release_type_name();
   void set_allocated_type_name(::std::string* type_name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_type_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_type_name(
@@ -1761,11 +1778,11 @@
   ::std::string* mutable_default_value();
   ::std::string* release_default_value();
   void set_allocated_default_value(::std::string* default_value);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_default_value();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_default_value(
@@ -1785,11 +1802,11 @@
   ::std::string* mutable_json_name();
   ::std::string* release_json_name();
   void set_allocated_json_name(::std::string* json_name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_json_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_json_name(
@@ -1799,9 +1816,6 @@
   bool has_options() const;
   void clear_options();
   static const int kOptionsFieldNumber = 8;
-  private:
-  const ::google::protobuf::FieldOptions& _internal_options() const;
-  public:
   const ::google::protobuf::FieldOptions& options() const;
   ::google::protobuf::FieldOptions* release_options();
   ::google::protobuf::FieldOptions* mutable_options();
@@ -1840,26 +1854,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
  private:
-  void set_has_name();
-  void clear_has_name();
-  void set_has_number();
-  void clear_has_number();
-  void set_has_label();
-  void clear_has_label();
-  void set_has_type();
-  void clear_has_type();
-  void set_has_type_name();
-  void clear_has_type_name();
-  void set_has_extendee();
-  void clear_has_extendee();
-  void set_has_default_value();
-  void clear_has_default_value();
-  void set_has_oneof_index();
-  void clear_has_oneof_index();
-  void set_has_json_name();
-  void clear_has_json_name();
-  void set_has_options();
-  void clear_has_options();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -1877,7 +1872,7 @@
   ::google::protobuf::int32 oneof_index_;
   int label_;
   int type_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -1920,7 +1915,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const OneofDescriptorProto& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -1954,8 +1951,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -2001,11 +2003,11 @@
   ::std::string* mutable_name();
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name(
@@ -2015,9 +2017,6 @@
   bool has_options() const;
   void clear_options();
   static const int kOptionsFieldNumber = 2;
-  private:
-  const ::google::protobuf::OneofOptions& _internal_options() const;
-  public:
   const ::google::protobuf::OneofOptions& options() const;
   ::google::protobuf::OneofOptions* release_options();
   ::google::protobuf::OneofOptions* mutable_options();
@@ -2028,10 +2027,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto)
  private:
-  void set_has_name();
-  void clear_has_name();
-  void set_has_options();
-  void clear_has_options();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -2041,7 +2037,7 @@
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::OneofOptions* options_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -2084,7 +2080,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const EnumDescriptorProto_EnumReservedRange& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -2118,8 +2116,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -2167,10 +2170,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto.EnumReservedRange)
  private:
-  void set_has_start();
-  void clear_has_start();
-  void set_has_end();
-  void clear_has_end();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -2180,7 +2180,7 @@
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::int32 start_;
   ::google::protobuf::int32 end_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -2223,7 +2223,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const EnumDescriptorProto& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -2257,8 +2259,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -2335,8 +2342,8 @@
   #endif
   void add_reserved_name(const char* value);
   void add_reserved_name(const char* value, size_t size);
-  const ::google::protobuf::RepeatedPtrField< ::std::string>& reserved_name() const;
-  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_reserved_name();
+  const ::google::protobuf::RepeatedPtrField<::std::string>& reserved_name() const;
+  ::google::protobuf::RepeatedPtrField<::std::string>* mutable_reserved_name();
 
   // optional string name = 1;
   bool has_name() const;
@@ -2352,11 +2359,11 @@
   ::std::string* mutable_name();
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name(
@@ -2366,9 +2373,6 @@
   bool has_options() const;
   void clear_options();
   static const int kOptionsFieldNumber = 3;
-  private:
-  const ::google::protobuf::EnumOptions& _internal_options() const;
-  public:
   const ::google::protobuf::EnumOptions& options() const;
   ::google::protobuf::EnumOptions* release_options();
   ::google::protobuf::EnumOptions* mutable_options();
@@ -2379,10 +2383,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto)
  private:
-  void set_has_name();
-  void clear_has_name();
-  void set_has_options();
-  void clear_has_options();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -2392,10 +2393,10 @@
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto_EnumReservedRange > reserved_range_;
-  ::google::protobuf::RepeatedPtrField< ::std::string> reserved_name_;
+  ::google::protobuf::RepeatedPtrField<::std::string> reserved_name_;
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::EnumOptions* options_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -2438,7 +2439,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const EnumValueDescriptorProto& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -2472,8 +2475,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -2519,11 +2527,11 @@
   ::std::string* mutable_name();
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name(
@@ -2533,9 +2541,6 @@
   bool has_options() const;
   void clear_options();
   static const int kOptionsFieldNumber = 3;
-  private:
-  const ::google::protobuf::EnumValueOptions& _internal_options() const;
-  public:
   const ::google::protobuf::EnumValueOptions& options() const;
   ::google::protobuf::EnumValueOptions* release_options();
   ::google::protobuf::EnumValueOptions* mutable_options();
@@ -2553,12 +2558,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto)
  private:
-  void set_has_name();
-  void clear_has_name();
-  void set_has_number();
-  void clear_has_number();
-  void set_has_options();
-  void clear_has_options();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -2569,7 +2569,7 @@
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::EnumValueOptions* options_;
   ::google::protobuf::int32 number_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -2612,7 +2612,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const ServiceDescriptorProto& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -2646,8 +2648,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -2705,11 +2712,11 @@
   ::std::string* mutable_name();
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name(
@@ -2719,9 +2726,6 @@
   bool has_options() const;
   void clear_options();
   static const int kOptionsFieldNumber = 3;
-  private:
-  const ::google::protobuf::ServiceOptions& _internal_options() const;
-  public:
   const ::google::protobuf::ServiceOptions& options() const;
   ::google::protobuf::ServiceOptions* release_options();
   ::google::protobuf::ServiceOptions* mutable_options();
@@ -2732,10 +2736,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto)
  private:
-  void set_has_name();
-  void clear_has_name();
-  void set_has_options();
-  void clear_has_options();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -2746,7 +2747,7 @@
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_;
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::ServiceOptions* options_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -2789,7 +2790,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const MethodDescriptorProto& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -2823,8 +2826,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -2870,11 +2878,11 @@
   ::std::string* mutable_name();
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name(
@@ -2894,11 +2902,11 @@
   ::std::string* mutable_input_type();
   ::std::string* release_input_type();
   void set_allocated_input_type(::std::string* input_type);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_input_type();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_input_type(
@@ -2918,11 +2926,11 @@
   ::std::string* mutable_output_type();
   ::std::string* release_output_type();
   void set_allocated_output_type(::std::string* output_type);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_output_type();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_output_type(
@@ -2932,9 +2940,6 @@
   bool has_options() const;
   void clear_options();
   static const int kOptionsFieldNumber = 4;
-  private:
-  const ::google::protobuf::MethodOptions& _internal_options() const;
-  public:
   const ::google::protobuf::MethodOptions& options() const;
   ::google::protobuf::MethodOptions* release_options();
   ::google::protobuf::MethodOptions* mutable_options();
@@ -2959,18 +2964,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto)
  private:
-  void set_has_name();
-  void clear_has_name();
-  void set_has_input_type();
-  void clear_has_input_type();
-  void set_has_output_type();
-  void clear_has_output_type();
-  void set_has_options();
-  void clear_has_options();
-  void set_has_client_streaming();
-  void clear_has_client_streaming();
-  void set_has_server_streaming();
-  void clear_has_server_streaming();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -2984,7 +2978,7 @@
   ::google::protobuf::MethodOptions* options_;
   bool client_streaming_;
   bool server_streaming_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -3027,7 +3021,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const FileOptions& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -3061,8 +3057,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -3148,11 +3149,11 @@
   ::std::string* mutable_java_package();
   ::std::string* release_java_package();
   void set_allocated_java_package(::std::string* java_package);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_java_package();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_java_package(
@@ -3172,11 +3173,11 @@
   ::std::string* mutable_java_outer_classname();
   ::std::string* release_java_outer_classname();
   void set_allocated_java_outer_classname(::std::string* java_outer_classname);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_java_outer_classname();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_java_outer_classname(
@@ -3196,11 +3197,11 @@
   ::std::string* mutable_go_package();
   ::std::string* release_go_package();
   void set_allocated_go_package(::std::string* go_package);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_go_package();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_go_package(
@@ -3220,11 +3221,11 @@
   ::std::string* mutable_objc_class_prefix();
   ::std::string* release_objc_class_prefix();
   void set_allocated_objc_class_prefix(::std::string* objc_class_prefix);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_objc_class_prefix();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_objc_class_prefix(
@@ -3244,11 +3245,11 @@
   ::std::string* mutable_csharp_namespace();
   ::std::string* release_csharp_namespace();
   void set_allocated_csharp_namespace(::std::string* csharp_namespace);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_csharp_namespace();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_csharp_namespace(
@@ -3268,11 +3269,11 @@
   ::std::string* mutable_swift_prefix();
   ::std::string* release_swift_prefix();
   void set_allocated_swift_prefix(::std::string* swift_prefix);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_swift_prefix();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_swift_prefix(
@@ -3292,11 +3293,11 @@
   ::std::string* mutable_php_class_prefix();
   ::std::string* release_php_class_prefix();
   void set_allocated_php_class_prefix(::std::string* php_class_prefix);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_php_class_prefix();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_php_class_prefix(
@@ -3316,11 +3317,11 @@
   ::std::string* mutable_php_namespace();
   ::std::string* release_php_namespace();
   void set_allocated_php_namespace(::std::string* php_namespace);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_php_namespace();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_php_namespace(
@@ -3340,11 +3341,11 @@
   ::std::string* mutable_php_metadata_namespace();
   ::std::string* release_php_metadata_namespace();
   void set_allocated_php_metadata_namespace(::std::string* php_metadata_namespace);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_php_metadata_namespace();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_php_metadata_namespace(
@@ -3364,11 +3365,11 @@
   ::std::string* mutable_ruby_package();
   ::std::string* release_ruby_package();
   void set_allocated_ruby_package(::std::string* ruby_package);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_ruby_package();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_ruby_package(
@@ -3382,11 +3383,11 @@
   void set_java_multiple_files(bool value);
 
   // optional bool java_generate_equals_and_hash = 20 [deprecated = true];
-  GOOGLE_PROTOBUF_DEPRECATED_ATTR bool has_java_generate_equals_and_hash() const;
-  GOOGLE_PROTOBUF_DEPRECATED_ATTR void clear_java_generate_equals_and_hash();
-  GOOGLE_PROTOBUF_DEPRECATED_ATTR static const int kJavaGenerateEqualsAndHashFieldNumber = 20;
-  GOOGLE_PROTOBUF_DEPRECATED_ATTR bool java_generate_equals_and_hash() const;
-  GOOGLE_PROTOBUF_DEPRECATED_ATTR void set_java_generate_equals_and_hash(bool value);
+  GOOGLE_PROTOBUF_DEPRECATED bool has_java_generate_equals_and_hash() const;
+  GOOGLE_PROTOBUF_DEPRECATED void clear_java_generate_equals_and_hash();
+  GOOGLE_PROTOBUF_DEPRECATED static const int kJavaGenerateEqualsAndHashFieldNumber = 20;
+  GOOGLE_PROTOBUF_DEPRECATED bool java_generate_equals_and_hash() const;
+  GOOGLE_PROTOBUF_DEPRECATED void set_java_generate_equals_and_hash(bool value);
 
   // optional bool java_string_check_utf8 = 27 [default = false];
   bool has_java_string_check_utf8() const;
@@ -3447,46 +3448,7 @@
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions)
   // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
  private:
-  void set_has_java_package();
-  void clear_has_java_package();
-  void set_has_java_outer_classname();
-  void clear_has_java_outer_classname();
-  void set_has_java_multiple_files();
-  void clear_has_java_multiple_files();
-  void set_has_java_generate_equals_and_hash();
-  void clear_has_java_generate_equals_and_hash();
-  void set_has_java_string_check_utf8();
-  void clear_has_java_string_check_utf8();
-  void set_has_optimize_for();
-  void clear_has_optimize_for();
-  void set_has_go_package();
-  void clear_has_go_package();
-  void set_has_cc_generic_services();
-  void clear_has_cc_generic_services();
-  void set_has_java_generic_services();
-  void clear_has_java_generic_services();
-  void set_has_py_generic_services();
-  void clear_has_py_generic_services();
-  void set_has_php_generic_services();
-  void clear_has_php_generic_services();
-  void set_has_deprecated();
-  void clear_has_deprecated();
-  void set_has_cc_enable_arenas();
-  void clear_has_cc_enable_arenas();
-  void set_has_objc_class_prefix();
-  void clear_has_objc_class_prefix();
-  void set_has_csharp_namespace();
-  void clear_has_csharp_namespace();
-  void set_has_swift_prefix();
-  void clear_has_swift_prefix();
-  void set_has_php_class_prefix();
-  void clear_has_php_class_prefix();
-  void set_has_php_namespace();
-  void clear_has_php_namespace();
-  void set_has_php_metadata_namespace();
-  void clear_has_php_metadata_namespace();
-  void set_has_ruby_package();
-  void clear_has_ruby_package();
+  class HasBitSetters;
 
   ::google::protobuf::internal::ExtensionSet _extensions_;
 
@@ -3517,7 +3479,7 @@
   bool deprecated_;
   bool cc_enable_arenas_;
   int optimize_for_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -3560,7 +3522,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const MessageOptions& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -3594,8 +3558,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -3670,14 +3639,7 @@
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions)
   // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
  private:
-  void set_has_message_set_wire_format();
-  void clear_has_message_set_wire_format();
-  void set_has_no_standard_descriptor_accessor();
-  void clear_has_no_standard_descriptor_accessor();
-  void set_has_deprecated();
-  void clear_has_deprecated();
-  void set_has_map_entry();
-  void clear_has_map_entry();
+  class HasBitSetters;
 
   ::google::protobuf::internal::ExtensionSet _extensions_;
 
@@ -3692,7 +3654,7 @@
   bool no_standard_descriptor_accessor_;
   bool deprecated_;
   bool map_entry_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -3735,7 +3697,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const FieldOptions& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -3769,8 +3733,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -3915,18 +3884,7 @@
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions)
   // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
  private:
-  void set_has_ctype();
-  void clear_has_ctype();
-  void set_has_packed();
-  void clear_has_packed();
-  void set_has_jstype();
-  void clear_has_jstype();
-  void set_has_lazy();
-  void clear_has_lazy();
-  void set_has_deprecated();
-  void clear_has_deprecated();
-  void set_has_weak();
-  void clear_has_weak();
+  class HasBitSetters;
 
   ::google::protobuf::internal::ExtensionSet _extensions_;
 
@@ -3943,7 +3901,7 @@
   bool deprecated_;
   bool weak_;
   int jstype_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -3986,7 +3944,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const OneofOptions& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -4020,8 +3980,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -4068,6 +4033,7 @@
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(OneofOptions)
   // @@protoc_insertion_point(class_scope:google.protobuf.OneofOptions)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::ExtensionSet _extensions_;
 
@@ -4078,7 +4044,7 @@
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -4121,7 +4087,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const EnumOptions& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -4155,8 +4123,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -4217,10 +4190,7 @@
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions)
   // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
  private:
-  void set_has_allow_alias();
-  void clear_has_allow_alias();
-  void set_has_deprecated();
-  void clear_has_deprecated();
+  class HasBitSetters;
 
   ::google::protobuf::internal::ExtensionSet _extensions_;
 
@@ -4233,7 +4203,7 @@
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
   bool allow_alias_;
   bool deprecated_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -4276,7 +4246,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const EnumValueOptions& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -4310,8 +4282,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -4365,8 +4342,7 @@
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions)
   // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
  private:
-  void set_has_deprecated();
-  void clear_has_deprecated();
+  class HasBitSetters;
 
   ::google::protobuf::internal::ExtensionSet _extensions_;
 
@@ -4378,7 +4354,7 @@
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
   bool deprecated_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -4421,7 +4397,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const ServiceOptions& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -4455,8 +4433,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -4510,8 +4493,7 @@
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions)
   // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
  private:
-  void set_has_deprecated();
-  void clear_has_deprecated();
+  class HasBitSetters;
 
   ::google::protobuf::internal::ExtensionSet _extensions_;
 
@@ -4523,7 +4505,7 @@
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
   bool deprecated_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -4566,7 +4548,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const MethodOptions& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -4600,8 +4584,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -4690,10 +4679,7 @@
   GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions)
   // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
  private:
-  void set_has_deprecated();
-  void clear_has_deprecated();
-  void set_has_idempotency_level();
-  void clear_has_idempotency_level();
+  class HasBitSetters;
 
   ::google::protobuf::internal::ExtensionSet _extensions_;
 
@@ -4706,7 +4692,7 @@
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
   bool deprecated_;
   int idempotency_level_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -4749,7 +4735,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const UninterpretedOption_NamePart& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -4783,8 +4771,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -4830,11 +4823,11 @@
   ::std::string* mutable_name_part();
   ::std::string* release_name_part();
   void set_allocated_name_part(::std::string* name_part);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name_part();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name_part(
@@ -4849,10 +4842,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart)
  private:
-  void set_has_name_part();
-  void clear_has_name_part();
-  void set_has_is_extension();
-  void clear_has_is_extension();
+  class HasBitSetters;
 
   // helper for ByteSizeLong()
   size_t RequiredFieldsByteSizeFallback() const;
@@ -4865,7 +4855,7 @@
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::internal::ArenaStringPtr name_part_;
   bool is_extension_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -4908,7 +4898,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const UninterpretedOption& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -4942,8 +4934,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -5003,11 +5000,11 @@
   ::std::string* mutable_identifier_value();
   ::std::string* release_identifier_value();
   void set_allocated_identifier_value(::std::string* identifier_value);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_identifier_value();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_identifier_value(
@@ -5027,11 +5024,11 @@
   ::std::string* mutable_string_value();
   ::std::string* release_string_value();
   void set_allocated_string_value(::std::string* string_value);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_string_value();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_string_value(
@@ -5051,11 +5048,11 @@
   ::std::string* mutable_aggregate_value();
   ::std::string* release_aggregate_value();
   void set_allocated_aggregate_value(::std::string* aggregate_value);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_aggregate_value();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_aggregate_value(
@@ -5084,18 +5081,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption)
  private:
-  void set_has_identifier_value();
-  void clear_has_identifier_value();
-  void set_has_positive_int_value();
-  void clear_has_positive_int_value();
-  void set_has_negative_int_value();
-  void clear_has_negative_int_value();
-  void set_has_double_value();
-  void clear_has_double_value();
-  void set_has_string_value();
-  void clear_has_string_value();
-  void set_has_aggregate_value();
-  void clear_has_aggregate_value();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -5110,7 +5096,7 @@
   ::google::protobuf::uint64 positive_int_value_;
   ::google::protobuf::int64 negative_int_value_;
   double double_value_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -5153,7 +5139,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const SourceCodeInfo_Location& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -5187,8 +5175,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -5263,8 +5256,8 @@
   #endif
   void add_leading_detached_comments(const char* value);
   void add_leading_detached_comments(const char* value, size_t size);
-  const ::google::protobuf::RepeatedPtrField< ::std::string>& leading_detached_comments() const;
-  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_leading_detached_comments();
+  const ::google::protobuf::RepeatedPtrField<::std::string>& leading_detached_comments() const;
+  ::google::protobuf::RepeatedPtrField<::std::string>* mutable_leading_detached_comments();
 
   // optional string leading_comments = 3;
   bool has_leading_comments() const;
@@ -5280,11 +5273,11 @@
   ::std::string* mutable_leading_comments();
   ::std::string* release_leading_comments();
   void set_allocated_leading_comments(::std::string* leading_comments);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_leading_comments();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_leading_comments(
@@ -5304,11 +5297,11 @@
   ::std::string* mutable_trailing_comments();
   ::std::string* release_trailing_comments();
   void set_allocated_trailing_comments(::std::string* trailing_comments);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_trailing_comments();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_trailing_comments(
@@ -5316,10 +5309,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location)
  private:
-  void set_has_leading_comments();
-  void clear_has_leading_comments();
-  void set_has_trailing_comments();
-  void clear_has_trailing_comments();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -5328,13 +5318,13 @@
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_;
-  mutable int _path_cached_byte_size_;
+  mutable std::atomic<int> _path_cached_byte_size_;
   ::google::protobuf::RepeatedField< ::google::protobuf::int32 > span_;
-  mutable int _span_cached_byte_size_;
-  ::google::protobuf::RepeatedPtrField< ::std::string> leading_detached_comments_;
+  mutable std::atomic<int> _span_cached_byte_size_;
+  ::google::protobuf::RepeatedPtrField<::std::string> leading_detached_comments_;
   ::google::protobuf::internal::ArenaStringPtr leading_comments_;
   ::google::protobuf::internal::ArenaStringPtr trailing_comments_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -5377,7 +5367,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const SourceCodeInfo& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -5411,8 +5403,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -5460,6 +5457,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -5468,7 +5466,7 @@
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -5511,7 +5509,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const GeneratedCodeInfo_Annotation& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -5545,8 +5545,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -5604,11 +5609,11 @@
   ::std::string* mutable_source_file();
   ::std::string* release_source_file();
   void set_allocated_source_file(::std::string* source_file);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_source_file();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_source_file(
@@ -5630,12 +5635,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo.Annotation)
  private:
-  void set_has_source_file();
-  void clear_has_source_file();
-  void set_has_begin();
-  void clear_has_begin();
-  void set_has_end();
-  void clear_has_end();
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -5644,11 +5644,11 @@
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_;
-  mutable int _path_cached_byte_size_;
+  mutable std::atomic<int> _path_cached_byte_size_;
   ::google::protobuf::internal::ArenaStringPtr source_file_;
   ::google::protobuf::int32 begin_;
   ::google::protobuf::int32 end_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -5691,7 +5691,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const GeneratedCodeInfo& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -5725,8 +5727,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -5774,6 +5781,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -5782,7 +5790,7 @@
   ::google::protobuf::internal::HasBits<1> _has_bits_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation > annotation_;
-  friend struct ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto;
 };
 // ===================================================================
 
@@ -5833,28 +5841,22 @@
 inline bool FileDescriptorProto::has_name() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void FileDescriptorProto::set_has_name() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void FileDescriptorProto::clear_has_name() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void FileDescriptorProto::clear_name() {
   name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& FileDescriptorProto::name() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.name)
   return name_.Get();
 }
 inline void FileDescriptorProto::set_name(const ::std::string& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.name)
 }
 #if LANG_CXX11
 inline void FileDescriptorProto::set_name(::std::string&& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileDescriptorProto.name)
@@ -5862,20 +5864,20 @@
 #endif
 inline void FileDescriptorProto::set_name(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.name)
 }
 inline void FileDescriptorProto::set_name(const char* value,
     size_t size) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.name)
 }
 inline ::std::string* FileDescriptorProto::mutable_name() {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.name)
   return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -5884,14 +5886,14 @@
   if (!has_name()) {
     return NULL;
   }
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FileDescriptorProto::set_allocated_name(::std::string* name) {
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
       GetArenaNoVirtual());
@@ -5900,7 +5902,7 @@
 inline ::std::string* FileDescriptorProto::unsafe_arena_release_name() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileDescriptorProto.name)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -5908,9 +5910,9 @@
     ::std::string* name) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       name, GetArenaNoVirtual());
@@ -5921,28 +5923,22 @@
 inline bool FileDescriptorProto::has_package() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void FileDescriptorProto::set_has_package() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void FileDescriptorProto::clear_has_package() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void FileDescriptorProto::clear_package() {
   package_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_package();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::std::string& FileDescriptorProto::package() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.package)
   return package_.Get();
 }
 inline void FileDescriptorProto::set_package(const ::std::string& value) {
-  set_has_package();
+  _has_bits_[0] |= 0x00000002u;
   package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.package)
 }
 #if LANG_CXX11
 inline void FileDescriptorProto::set_package(::std::string&& value) {
-  set_has_package();
+  _has_bits_[0] |= 0x00000002u;
   package_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileDescriptorProto.package)
@@ -5950,20 +5946,20 @@
 #endif
 inline void FileDescriptorProto::set_package(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_package();
+  _has_bits_[0] |= 0x00000002u;
   package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.package)
 }
 inline void FileDescriptorProto::set_package(const char* value,
     size_t size) {
-  set_has_package();
+  _has_bits_[0] |= 0x00000002u;
   package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.package)
 }
 inline ::std::string* FileDescriptorProto::mutable_package() {
-  set_has_package();
+  _has_bits_[0] |= 0x00000002u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.package)
   return package_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -5972,14 +5968,14 @@
   if (!has_package()) {
     return NULL;
   }
-  clear_has_package();
+  _has_bits_[0] &= ~0x00000002u;
   return package_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FileDescriptorProto::set_allocated_package(::std::string* package) {
   if (package != NULL) {
-    set_has_package();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_package();
+    _has_bits_[0] &= ~0x00000002u;
   }
   package_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), package,
       GetArenaNoVirtual());
@@ -5988,7 +5984,7 @@
 inline ::std::string* FileDescriptorProto::unsafe_arena_release_package() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileDescriptorProto.package)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_package();
+  _has_bits_[0] &= ~0x00000002u;
   return package_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -5996,9 +5992,9 @@
     ::std::string* package) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (package != NULL) {
-    set_has_package();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_package();
+    _has_bits_[0] &= ~0x00000002u;
   }
   package_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       package, GetArenaNoVirtual());
@@ -6063,12 +6059,12 @@
   dependency_.Add()->assign(reinterpret_cast<const char*>(value), size);
   // @@protoc_insertion_point(field_add_pointer:google.protobuf.FileDescriptorProto.dependency)
 }
-inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+inline const ::google::protobuf::RepeatedPtrField<::std::string>&
 FileDescriptorProto::dependency() const {
   // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.dependency)
   return dependency_;
 }
-inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+inline ::google::protobuf::RepeatedPtrField<::std::string>*
 FileDescriptorProto::mutable_dependency() {
   // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.dependency)
   return &dependency_;
@@ -6258,18 +6254,9 @@
 inline bool FileDescriptorProto::has_options() const {
   return (_has_bits_[0] & 0x00000008u) != 0;
 }
-inline void FileDescriptorProto::set_has_options() {
-  _has_bits_[0] |= 0x00000008u;
-}
-inline void FileDescriptorProto::clear_has_options() {
-  _has_bits_[0] &= ~0x00000008u;
-}
 inline void FileDescriptorProto::clear_options() {
   if (options_ != NULL) options_->Clear();
-  clear_has_options();
-}
-inline const ::google::protobuf::FileOptions& FileDescriptorProto::_internal_options() const {
-  return *options_;
+  _has_bits_[0] &= ~0x00000008u;
 }
 inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
   const ::google::protobuf::FileOptions* p = options_;
@@ -6279,7 +6266,7 @@
 }
 inline ::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000008u;
   ::google::protobuf::FileOptions* temp = options_;
   if (GetArenaNoVirtual() != NULL) {
     temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);
@@ -6289,13 +6276,13 @@
 }
 inline ::google::protobuf::FileOptions* FileDescriptorProto::unsafe_arena_release_options() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000008u;
   ::google::protobuf::FileOptions* temp = options_;
   options_ = NULL;
   return temp;
 }
 inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
-  set_has_options();
+  _has_bits_[0] |= 0x00000008u;
   if (options_ == NULL) {
     auto* p = CreateMaybeMessage<::google::protobuf::FileOptions>(GetArenaNoVirtual());
     options_ = p;
@@ -6315,9 +6302,9 @@
       options = ::google::protobuf::internal::GetOwnedMessage(
           message_arena, options, submessage_arena);
     }
-    set_has_options();
+    _has_bits_[0] |= 0x00000008u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000008u;
   }
   options_ = options;
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.options)
@@ -6327,18 +6314,9 @@
 inline bool FileDescriptorProto::has_source_code_info() const {
   return (_has_bits_[0] & 0x00000010u) != 0;
 }
-inline void FileDescriptorProto::set_has_source_code_info() {
-  _has_bits_[0] |= 0x00000010u;
-}
-inline void FileDescriptorProto::clear_has_source_code_info() {
-  _has_bits_[0] &= ~0x00000010u;
-}
 inline void FileDescriptorProto::clear_source_code_info() {
   if (source_code_info_ != NULL) source_code_info_->Clear();
-  clear_has_source_code_info();
-}
-inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::_internal_source_code_info() const {
-  return *source_code_info_;
+  _has_bits_[0] &= ~0x00000010u;
 }
 inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
   const ::google::protobuf::SourceCodeInfo* p = source_code_info_;
@@ -6348,7 +6326,7 @@
 }
 inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
   // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.source_code_info)
-  clear_has_source_code_info();
+  _has_bits_[0] &= ~0x00000010u;
   ::google::protobuf::SourceCodeInfo* temp = source_code_info_;
   if (GetArenaNoVirtual() != NULL) {
     temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);
@@ -6358,13 +6336,13 @@
 }
 inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::unsafe_arena_release_source_code_info() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileDescriptorProto.source_code_info)
-  clear_has_source_code_info();
+  _has_bits_[0] &= ~0x00000010u;
   ::google::protobuf::SourceCodeInfo* temp = source_code_info_;
   source_code_info_ = NULL;
   return temp;
 }
 inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() {
-  set_has_source_code_info();
+  _has_bits_[0] |= 0x00000010u;
   if (source_code_info_ == NULL) {
     auto* p = CreateMaybeMessage<::google::protobuf::SourceCodeInfo>(GetArenaNoVirtual());
     source_code_info_ = p;
@@ -6384,9 +6362,9 @@
       source_code_info = ::google::protobuf::internal::GetOwnedMessage(
           message_arena, source_code_info, submessage_arena);
     }
-    set_has_source_code_info();
+    _has_bits_[0] |= 0x00000010u;
   } else {
-    clear_has_source_code_info();
+    _has_bits_[0] &= ~0x00000010u;
   }
   source_code_info_ = source_code_info;
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.source_code_info)
@@ -6396,28 +6374,22 @@
 inline bool FileDescriptorProto::has_syntax() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
-inline void FileDescriptorProto::set_has_syntax() {
-  _has_bits_[0] |= 0x00000004u;
-}
-inline void FileDescriptorProto::clear_has_syntax() {
-  _has_bits_[0] &= ~0x00000004u;
-}
 inline void FileDescriptorProto::clear_syntax() {
   syntax_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_syntax();
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline const ::std::string& FileDescriptorProto::syntax() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.syntax)
   return syntax_.Get();
 }
 inline void FileDescriptorProto::set_syntax(const ::std::string& value) {
-  set_has_syntax();
+  _has_bits_[0] |= 0x00000004u;
   syntax_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.syntax)
 }
 #if LANG_CXX11
 inline void FileDescriptorProto::set_syntax(::std::string&& value) {
-  set_has_syntax();
+  _has_bits_[0] |= 0x00000004u;
   syntax_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileDescriptorProto.syntax)
@@ -6425,20 +6397,20 @@
 #endif
 inline void FileDescriptorProto::set_syntax(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_syntax();
+  _has_bits_[0] |= 0x00000004u;
   syntax_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.syntax)
 }
 inline void FileDescriptorProto::set_syntax(const char* value,
     size_t size) {
-  set_has_syntax();
+  _has_bits_[0] |= 0x00000004u;
   syntax_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.syntax)
 }
 inline ::std::string* FileDescriptorProto::mutable_syntax() {
-  set_has_syntax();
+  _has_bits_[0] |= 0x00000004u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.syntax)
   return syntax_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -6447,14 +6419,14 @@
   if (!has_syntax()) {
     return NULL;
   }
-  clear_has_syntax();
+  _has_bits_[0] &= ~0x00000004u;
   return syntax_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FileDescriptorProto::set_allocated_syntax(::std::string* syntax) {
   if (syntax != NULL) {
-    set_has_syntax();
+    _has_bits_[0] |= 0x00000004u;
   } else {
-    clear_has_syntax();
+    _has_bits_[0] &= ~0x00000004u;
   }
   syntax_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), syntax,
       GetArenaNoVirtual());
@@ -6463,7 +6435,7 @@
 inline ::std::string* FileDescriptorProto::unsafe_arena_release_syntax() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileDescriptorProto.syntax)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_syntax();
+  _has_bits_[0] &= ~0x00000004u;
   return syntax_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -6471,9 +6443,9 @@
     ::std::string* syntax) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (syntax != NULL) {
-    set_has_syntax();
+    _has_bits_[0] |= 0x00000004u;
   } else {
-    clear_has_syntax();
+    _has_bits_[0] &= ~0x00000004u;
   }
   syntax_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       syntax, GetArenaNoVirtual());
@@ -6488,22 +6460,16 @@
 inline bool DescriptorProto_ExtensionRange::has_start() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void DescriptorProto_ExtensionRange::set_has_start() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void DescriptorProto_ExtensionRange::clear_has_start() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void DescriptorProto_ExtensionRange::clear_start() {
   start_ = 0;
-  clear_has_start();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const {
   // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.start)
   return start_;
 }
 inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) {
-  set_has_start();
+  _has_bits_[0] |= 0x00000002u;
   start_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.start)
 }
@@ -6512,22 +6478,16 @@
 inline bool DescriptorProto_ExtensionRange::has_end() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
-inline void DescriptorProto_ExtensionRange::set_has_end() {
-  _has_bits_[0] |= 0x00000004u;
-}
-inline void DescriptorProto_ExtensionRange::clear_has_end() {
-  _has_bits_[0] &= ~0x00000004u;
-}
 inline void DescriptorProto_ExtensionRange::clear_end() {
   end_ = 0;
-  clear_has_end();
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const {
   // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.end)
   return end_;
 }
 inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) {
-  set_has_end();
+  _has_bits_[0] |= 0x00000004u;
   end_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.end)
 }
@@ -6536,18 +6496,9 @@
 inline bool DescriptorProto_ExtensionRange::has_options() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void DescriptorProto_ExtensionRange::set_has_options() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void DescriptorProto_ExtensionRange::clear_has_options() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void DescriptorProto_ExtensionRange::clear_options() {
   if (options_ != NULL) options_->Clear();
-  clear_has_options();
-}
-inline const ::google::protobuf::ExtensionRangeOptions& DescriptorProto_ExtensionRange::_internal_options() const {
-  return *options_;
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::google::protobuf::ExtensionRangeOptions& DescriptorProto_ExtensionRange::options() const {
   const ::google::protobuf::ExtensionRangeOptions* p = options_;
@@ -6557,7 +6508,7 @@
 }
 inline ::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange::release_options() {
   // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.ExtensionRange.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000001u;
   ::google::protobuf::ExtensionRangeOptions* temp = options_;
   if (GetArenaNoVirtual() != NULL) {
     temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);
@@ -6567,13 +6518,13 @@
 }
 inline ::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange::unsafe_arena_release_options() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.DescriptorProto.ExtensionRange.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000001u;
   ::google::protobuf::ExtensionRangeOptions* temp = options_;
   options_ = NULL;
   return temp;
 }
 inline ::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange::mutable_options() {
-  set_has_options();
+  _has_bits_[0] |= 0x00000001u;
   if (options_ == NULL) {
     auto* p = CreateMaybeMessage<::google::protobuf::ExtensionRangeOptions>(GetArenaNoVirtual());
     options_ = p;
@@ -6593,9 +6544,9 @@
       options = ::google::protobuf::internal::GetOwnedMessage(
           message_arena, options, submessage_arena);
     }
-    set_has_options();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000001u;
   }
   options_ = options;
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.ExtensionRange.options)
@@ -6609,22 +6560,16 @@
 inline bool DescriptorProto_ReservedRange::has_start() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void DescriptorProto_ReservedRange::set_has_start() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void DescriptorProto_ReservedRange::clear_has_start() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void DescriptorProto_ReservedRange::clear_start() {
   start_ = 0;
-  clear_has_start();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline ::google::protobuf::int32 DescriptorProto_ReservedRange::start() const {
   // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ReservedRange.start)
   return start_;
 }
 inline void DescriptorProto_ReservedRange::set_start(::google::protobuf::int32 value) {
-  set_has_start();
+  _has_bits_[0] |= 0x00000001u;
   start_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.start)
 }
@@ -6633,22 +6578,16 @@
 inline bool DescriptorProto_ReservedRange::has_end() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void DescriptorProto_ReservedRange::set_has_end() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void DescriptorProto_ReservedRange::clear_has_end() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void DescriptorProto_ReservedRange::clear_end() {
   end_ = 0;
-  clear_has_end();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline ::google::protobuf::int32 DescriptorProto_ReservedRange::end() const {
   // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ReservedRange.end)
   return end_;
 }
 inline void DescriptorProto_ReservedRange::set_end(::google::protobuf::int32 value) {
-  set_has_end();
+  _has_bits_[0] |= 0x00000002u;
   end_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.end)
 }
@@ -6661,28 +6600,22 @@
 inline bool DescriptorProto::has_name() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void DescriptorProto::set_has_name() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void DescriptorProto::clear_has_name() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void DescriptorProto::clear_name() {
   name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& DescriptorProto::name() const {
   // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.name)
   return name_.Get();
 }
 inline void DescriptorProto::set_name(const ::std::string& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.name)
 }
 #if LANG_CXX11
 inline void DescriptorProto::set_name(::std::string&& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.DescriptorProto.name)
@@ -6690,20 +6623,20 @@
 #endif
 inline void DescriptorProto::set_name(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.name)
 }
 inline void DescriptorProto::set_name(const char* value,
     size_t size) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.name)
 }
 inline ::std::string* DescriptorProto::mutable_name() {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.name)
   return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -6712,14 +6645,14 @@
   if (!has_name()) {
     return NULL;
   }
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void DescriptorProto::set_allocated_name(::std::string* name) {
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
       GetArenaNoVirtual());
@@ -6728,7 +6661,7 @@
 inline ::std::string* DescriptorProto::unsafe_arena_release_name() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.DescriptorProto.name)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -6736,9 +6669,9 @@
     ::std::string* name) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       name, GetArenaNoVirtual());
@@ -6929,18 +6862,9 @@
 inline bool DescriptorProto::has_options() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void DescriptorProto::set_has_options() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void DescriptorProto::clear_has_options() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void DescriptorProto::clear_options() {
   if (options_ != NULL) options_->Clear();
-  clear_has_options();
-}
-inline const ::google::protobuf::MessageOptions& DescriptorProto::_internal_options() const {
-  return *options_;
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const {
   const ::google::protobuf::MessageOptions* p = options_;
@@ -6950,7 +6874,7 @@
 }
 inline ::google::protobuf::MessageOptions* DescriptorProto::release_options() {
   // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000002u;
   ::google::protobuf::MessageOptions* temp = options_;
   if (GetArenaNoVirtual() != NULL) {
     temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);
@@ -6960,13 +6884,13 @@
 }
 inline ::google::protobuf::MessageOptions* DescriptorProto::unsafe_arena_release_options() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.DescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000002u;
   ::google::protobuf::MessageOptions* temp = options_;
   options_ = NULL;
   return temp;
 }
 inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
-  set_has_options();
+  _has_bits_[0] |= 0x00000002u;
   if (options_ == NULL) {
     auto* p = CreateMaybeMessage<::google::protobuf::MessageOptions>(GetArenaNoVirtual());
     options_ = p;
@@ -6986,9 +6910,9 @@
       options = ::google::protobuf::internal::GetOwnedMessage(
           message_arena, options, submessage_arena);
     }
-    set_has_options();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000002u;
   }
   options_ = options;
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.options)
@@ -7082,12 +7006,12 @@
   reserved_name_.Add()->assign(reinterpret_cast<const char*>(value), size);
   // @@protoc_insertion_point(field_add_pointer:google.protobuf.DescriptorProto.reserved_name)
 }
-inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+inline const ::google::protobuf::RepeatedPtrField<::std::string>&
 DescriptorProto::reserved_name() const {
   // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_name)
   return reserved_name_;
 }
-inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+inline ::google::protobuf::RepeatedPtrField<::std::string>*
 DescriptorProto::mutable_reserved_name() {
   // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_name)
   return &reserved_name_;
@@ -7135,28 +7059,22 @@
 inline bool FieldDescriptorProto::has_name() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void FieldDescriptorProto::set_has_name() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void FieldDescriptorProto::clear_has_name() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void FieldDescriptorProto::clear_name() {
   name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& FieldDescriptorProto::name() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.name)
   return name_.Get();
 }
 inline void FieldDescriptorProto::set_name(const ::std::string& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.name)
 }
 #if LANG_CXX11
 inline void FieldDescriptorProto::set_name(::std::string&& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.name)
@@ -7164,20 +7082,20 @@
 #endif
 inline void FieldDescriptorProto::set_name(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.name)
 }
 inline void FieldDescriptorProto::set_name(const char* value,
     size_t size) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.name)
 }
 inline ::std::string* FieldDescriptorProto::mutable_name() {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.name)
   return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -7186,14 +7104,14 @@
   if (!has_name()) {
     return NULL;
   }
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FieldDescriptorProto::set_allocated_name(::std::string* name) {
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
       GetArenaNoVirtual());
@@ -7202,7 +7120,7 @@
 inline ::std::string* FieldDescriptorProto::unsafe_arena_release_name() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FieldDescriptorProto.name)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -7210,9 +7128,9 @@
     ::std::string* name) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       name, GetArenaNoVirtual());
@@ -7223,22 +7141,16 @@
 inline bool FieldDescriptorProto::has_number() const {
   return (_has_bits_[0] & 0x00000040u) != 0;
 }
-inline void FieldDescriptorProto::set_has_number() {
-  _has_bits_[0] |= 0x00000040u;
-}
-inline void FieldDescriptorProto::clear_has_number() {
-  _has_bits_[0] &= ~0x00000040u;
-}
 inline void FieldDescriptorProto::clear_number() {
   number_ = 0;
-  clear_has_number();
+  _has_bits_[0] &= ~0x00000040u;
 }
 inline ::google::protobuf::int32 FieldDescriptorProto::number() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.number)
   return number_;
 }
 inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) {
-  set_has_number();
+  _has_bits_[0] |= 0x00000040u;
   number_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.number)
 }
@@ -7247,15 +7159,9 @@
 inline bool FieldDescriptorProto::has_label() const {
   return (_has_bits_[0] & 0x00000100u) != 0;
 }
-inline void FieldDescriptorProto::set_has_label() {
-  _has_bits_[0] |= 0x00000100u;
-}
-inline void FieldDescriptorProto::clear_has_label() {
-  _has_bits_[0] &= ~0x00000100u;
-}
 inline void FieldDescriptorProto::clear_label() {
   label_ = 1;
-  clear_has_label();
+  _has_bits_[0] &= ~0x00000100u;
 }
 inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.label)
@@ -7263,7 +7169,7 @@
 }
 inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) {
   assert(::google::protobuf::FieldDescriptorProto_Label_IsValid(value));
-  set_has_label();
+  _has_bits_[0] |= 0x00000100u;
   label_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.label)
 }
@@ -7272,15 +7178,9 @@
 inline bool FieldDescriptorProto::has_type() const {
   return (_has_bits_[0] & 0x00000200u) != 0;
 }
-inline void FieldDescriptorProto::set_has_type() {
-  _has_bits_[0] |= 0x00000200u;
-}
-inline void FieldDescriptorProto::clear_has_type() {
-  _has_bits_[0] &= ~0x00000200u;
-}
 inline void FieldDescriptorProto::clear_type() {
   type_ = 1;
-  clear_has_type();
+  _has_bits_[0] &= ~0x00000200u;
 }
 inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type)
@@ -7288,7 +7188,7 @@
 }
 inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) {
   assert(::google::protobuf::FieldDescriptorProto_Type_IsValid(value));
-  set_has_type();
+  _has_bits_[0] |= 0x00000200u;
   type_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type)
 }
@@ -7297,28 +7197,22 @@
 inline bool FieldDescriptorProto::has_type_name() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
-inline void FieldDescriptorProto::set_has_type_name() {
-  _has_bits_[0] |= 0x00000004u;
-}
-inline void FieldDescriptorProto::clear_has_type_name() {
-  _has_bits_[0] &= ~0x00000004u;
-}
 inline void FieldDescriptorProto::clear_type_name() {
   type_name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_type_name();
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline const ::std::string& FieldDescriptorProto::type_name() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type_name)
   return type_name_.Get();
 }
 inline void FieldDescriptorProto::set_type_name(const ::std::string& value) {
-  set_has_type_name();
+  _has_bits_[0] |= 0x00000004u;
   type_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type_name)
 }
 #if LANG_CXX11
 inline void FieldDescriptorProto::set_type_name(::std::string&& value) {
-  set_has_type_name();
+  _has_bits_[0] |= 0x00000004u;
   type_name_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.type_name)
@@ -7326,20 +7220,20 @@
 #endif
 inline void FieldDescriptorProto::set_type_name(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_type_name();
+  _has_bits_[0] |= 0x00000004u;
   type_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.type_name)
 }
 inline void FieldDescriptorProto::set_type_name(const char* value,
     size_t size) {
-  set_has_type_name();
+  _has_bits_[0] |= 0x00000004u;
   type_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.type_name)
 }
 inline ::std::string* FieldDescriptorProto::mutable_type_name() {
-  set_has_type_name();
+  _has_bits_[0] |= 0x00000004u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.type_name)
   return type_name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -7348,14 +7242,14 @@
   if (!has_type_name()) {
     return NULL;
   }
-  clear_has_type_name();
+  _has_bits_[0] &= ~0x00000004u;
   return type_name_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FieldDescriptorProto::set_allocated_type_name(::std::string* type_name) {
   if (type_name != NULL) {
-    set_has_type_name();
+    _has_bits_[0] |= 0x00000004u;
   } else {
-    clear_has_type_name();
+    _has_bits_[0] &= ~0x00000004u;
   }
   type_name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), type_name,
       GetArenaNoVirtual());
@@ -7364,7 +7258,7 @@
 inline ::std::string* FieldDescriptorProto::unsafe_arena_release_type_name() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FieldDescriptorProto.type_name)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_type_name();
+  _has_bits_[0] &= ~0x00000004u;
   return type_name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -7372,9 +7266,9 @@
     ::std::string* type_name) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (type_name != NULL) {
-    set_has_type_name();
+    _has_bits_[0] |= 0x00000004u;
   } else {
-    clear_has_type_name();
+    _has_bits_[0] &= ~0x00000004u;
   }
   type_name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       type_name, GetArenaNoVirtual());
@@ -7385,28 +7279,22 @@
 inline bool FieldDescriptorProto::has_extendee() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void FieldDescriptorProto::set_has_extendee() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void FieldDescriptorProto::clear_has_extendee() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void FieldDescriptorProto::clear_extendee() {
   extendee_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_extendee();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::std::string& FieldDescriptorProto::extendee() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.extendee)
   return extendee_.Get();
 }
 inline void FieldDescriptorProto::set_extendee(const ::std::string& value) {
-  set_has_extendee();
+  _has_bits_[0] |= 0x00000002u;
   extendee_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.extendee)
 }
 #if LANG_CXX11
 inline void FieldDescriptorProto::set_extendee(::std::string&& value) {
-  set_has_extendee();
+  _has_bits_[0] |= 0x00000002u;
   extendee_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.extendee)
@@ -7414,20 +7302,20 @@
 #endif
 inline void FieldDescriptorProto::set_extendee(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_extendee();
+  _has_bits_[0] |= 0x00000002u;
   extendee_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.extendee)
 }
 inline void FieldDescriptorProto::set_extendee(const char* value,
     size_t size) {
-  set_has_extendee();
+  _has_bits_[0] |= 0x00000002u;
   extendee_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.extendee)
 }
 inline ::std::string* FieldDescriptorProto::mutable_extendee() {
-  set_has_extendee();
+  _has_bits_[0] |= 0x00000002u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.extendee)
   return extendee_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -7436,14 +7324,14 @@
   if (!has_extendee()) {
     return NULL;
   }
-  clear_has_extendee();
+  _has_bits_[0] &= ~0x00000002u;
   return extendee_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FieldDescriptorProto::set_allocated_extendee(::std::string* extendee) {
   if (extendee != NULL) {
-    set_has_extendee();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_extendee();
+    _has_bits_[0] &= ~0x00000002u;
   }
   extendee_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), extendee,
       GetArenaNoVirtual());
@@ -7452,7 +7340,7 @@
 inline ::std::string* FieldDescriptorProto::unsafe_arena_release_extendee() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FieldDescriptorProto.extendee)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_extendee();
+  _has_bits_[0] &= ~0x00000002u;
   return extendee_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -7460,9 +7348,9 @@
     ::std::string* extendee) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (extendee != NULL) {
-    set_has_extendee();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_extendee();
+    _has_bits_[0] &= ~0x00000002u;
   }
   extendee_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       extendee, GetArenaNoVirtual());
@@ -7473,28 +7361,22 @@
 inline bool FieldDescriptorProto::has_default_value() const {
   return (_has_bits_[0] & 0x00000008u) != 0;
 }
-inline void FieldDescriptorProto::set_has_default_value() {
-  _has_bits_[0] |= 0x00000008u;
-}
-inline void FieldDescriptorProto::clear_has_default_value() {
-  _has_bits_[0] &= ~0x00000008u;
-}
 inline void FieldDescriptorProto::clear_default_value() {
   default_value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_default_value();
+  _has_bits_[0] &= ~0x00000008u;
 }
 inline const ::std::string& FieldDescriptorProto::default_value() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.default_value)
   return default_value_.Get();
 }
 inline void FieldDescriptorProto::set_default_value(const ::std::string& value) {
-  set_has_default_value();
+  _has_bits_[0] |= 0x00000008u;
   default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.default_value)
 }
 #if LANG_CXX11
 inline void FieldDescriptorProto::set_default_value(::std::string&& value) {
-  set_has_default_value();
+  _has_bits_[0] |= 0x00000008u;
   default_value_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.default_value)
@@ -7502,20 +7384,20 @@
 #endif
 inline void FieldDescriptorProto::set_default_value(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_default_value();
+  _has_bits_[0] |= 0x00000008u;
   default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.default_value)
 }
 inline void FieldDescriptorProto::set_default_value(const char* value,
     size_t size) {
-  set_has_default_value();
+  _has_bits_[0] |= 0x00000008u;
   default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.default_value)
 }
 inline ::std::string* FieldDescriptorProto::mutable_default_value() {
-  set_has_default_value();
+  _has_bits_[0] |= 0x00000008u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.default_value)
   return default_value_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -7524,14 +7406,14 @@
   if (!has_default_value()) {
     return NULL;
   }
-  clear_has_default_value();
+  _has_bits_[0] &= ~0x00000008u;
   return default_value_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FieldDescriptorProto::set_allocated_default_value(::std::string* default_value) {
   if (default_value != NULL) {
-    set_has_default_value();
+    _has_bits_[0] |= 0x00000008u;
   } else {
-    clear_has_default_value();
+    _has_bits_[0] &= ~0x00000008u;
   }
   default_value_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), default_value,
       GetArenaNoVirtual());
@@ -7540,7 +7422,7 @@
 inline ::std::string* FieldDescriptorProto::unsafe_arena_release_default_value() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FieldDescriptorProto.default_value)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_default_value();
+  _has_bits_[0] &= ~0x00000008u;
   return default_value_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -7548,9 +7430,9 @@
     ::std::string* default_value) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (default_value != NULL) {
-    set_has_default_value();
+    _has_bits_[0] |= 0x00000008u;
   } else {
-    clear_has_default_value();
+    _has_bits_[0] &= ~0x00000008u;
   }
   default_value_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       default_value, GetArenaNoVirtual());
@@ -7561,22 +7443,16 @@
 inline bool FieldDescriptorProto::has_oneof_index() const {
   return (_has_bits_[0] & 0x00000080u) != 0;
 }
-inline void FieldDescriptorProto::set_has_oneof_index() {
-  _has_bits_[0] |= 0x00000080u;
-}
-inline void FieldDescriptorProto::clear_has_oneof_index() {
-  _has_bits_[0] &= ~0x00000080u;
-}
 inline void FieldDescriptorProto::clear_oneof_index() {
   oneof_index_ = 0;
-  clear_has_oneof_index();
+  _has_bits_[0] &= ~0x00000080u;
 }
 inline ::google::protobuf::int32 FieldDescriptorProto::oneof_index() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.oneof_index)
   return oneof_index_;
 }
 inline void FieldDescriptorProto::set_oneof_index(::google::protobuf::int32 value) {
-  set_has_oneof_index();
+  _has_bits_[0] |= 0x00000080u;
   oneof_index_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.oneof_index)
 }
@@ -7585,28 +7461,22 @@
 inline bool FieldDescriptorProto::has_json_name() const {
   return (_has_bits_[0] & 0x00000010u) != 0;
 }
-inline void FieldDescriptorProto::set_has_json_name() {
-  _has_bits_[0] |= 0x00000010u;
-}
-inline void FieldDescriptorProto::clear_has_json_name() {
-  _has_bits_[0] &= ~0x00000010u;
-}
 inline void FieldDescriptorProto::clear_json_name() {
   json_name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_json_name();
+  _has_bits_[0] &= ~0x00000010u;
 }
 inline const ::std::string& FieldDescriptorProto::json_name() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.json_name)
   return json_name_.Get();
 }
 inline void FieldDescriptorProto::set_json_name(const ::std::string& value) {
-  set_has_json_name();
+  _has_bits_[0] |= 0x00000010u;
   json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.json_name)
 }
 #if LANG_CXX11
 inline void FieldDescriptorProto::set_json_name(::std::string&& value) {
-  set_has_json_name();
+  _has_bits_[0] |= 0x00000010u;
   json_name_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.json_name)
@@ -7614,20 +7484,20 @@
 #endif
 inline void FieldDescriptorProto::set_json_name(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_json_name();
+  _has_bits_[0] |= 0x00000010u;
   json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.json_name)
 }
 inline void FieldDescriptorProto::set_json_name(const char* value,
     size_t size) {
-  set_has_json_name();
+  _has_bits_[0] |= 0x00000010u;
   json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.json_name)
 }
 inline ::std::string* FieldDescriptorProto::mutable_json_name() {
-  set_has_json_name();
+  _has_bits_[0] |= 0x00000010u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.json_name)
   return json_name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -7636,14 +7506,14 @@
   if (!has_json_name()) {
     return NULL;
   }
-  clear_has_json_name();
+  _has_bits_[0] &= ~0x00000010u;
   return json_name_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FieldDescriptorProto::set_allocated_json_name(::std::string* json_name) {
   if (json_name != NULL) {
-    set_has_json_name();
+    _has_bits_[0] |= 0x00000010u;
   } else {
-    clear_has_json_name();
+    _has_bits_[0] &= ~0x00000010u;
   }
   json_name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), json_name,
       GetArenaNoVirtual());
@@ -7652,7 +7522,7 @@
 inline ::std::string* FieldDescriptorProto::unsafe_arena_release_json_name() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FieldDescriptorProto.json_name)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_json_name();
+  _has_bits_[0] &= ~0x00000010u;
   return json_name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -7660,9 +7530,9 @@
     ::std::string* json_name) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (json_name != NULL) {
-    set_has_json_name();
+    _has_bits_[0] |= 0x00000010u;
   } else {
-    clear_has_json_name();
+    _has_bits_[0] &= ~0x00000010u;
   }
   json_name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       json_name, GetArenaNoVirtual());
@@ -7673,18 +7543,9 @@
 inline bool FieldDescriptorProto::has_options() const {
   return (_has_bits_[0] & 0x00000020u) != 0;
 }
-inline void FieldDescriptorProto::set_has_options() {
-  _has_bits_[0] |= 0x00000020u;
-}
-inline void FieldDescriptorProto::clear_has_options() {
-  _has_bits_[0] &= ~0x00000020u;
-}
 inline void FieldDescriptorProto::clear_options() {
   if (options_ != NULL) options_->Clear();
-  clear_has_options();
-}
-inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::_internal_options() const {
-  return *options_;
+  _has_bits_[0] &= ~0x00000020u;
 }
 inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const {
   const ::google::protobuf::FieldOptions* p = options_;
@@ -7694,7 +7555,7 @@
 }
 inline ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
   // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000020u;
   ::google::protobuf::FieldOptions* temp = options_;
   if (GetArenaNoVirtual() != NULL) {
     temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);
@@ -7704,13 +7565,13 @@
 }
 inline ::google::protobuf::FieldOptions* FieldDescriptorProto::unsafe_arena_release_options() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FieldDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000020u;
   ::google::protobuf::FieldOptions* temp = options_;
   options_ = NULL;
   return temp;
 }
 inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() {
-  set_has_options();
+  _has_bits_[0] |= 0x00000020u;
   if (options_ == NULL) {
     auto* p = CreateMaybeMessage<::google::protobuf::FieldOptions>(GetArenaNoVirtual());
     options_ = p;
@@ -7730,9 +7591,9 @@
       options = ::google::protobuf::internal::GetOwnedMessage(
           message_arena, options, submessage_arena);
     }
-    set_has_options();
+    _has_bits_[0] |= 0x00000020u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000020u;
   }
   options_ = options;
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.options)
@@ -7746,28 +7607,22 @@
 inline bool OneofDescriptorProto::has_name() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void OneofDescriptorProto::set_has_name() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void OneofDescriptorProto::clear_has_name() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void OneofDescriptorProto::clear_name() {
   name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& OneofDescriptorProto::name() const {
   // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.name)
   return name_.Get();
 }
 inline void OneofDescriptorProto::set_name(const ::std::string& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.OneofDescriptorProto.name)
 }
 #if LANG_CXX11
 inline void OneofDescriptorProto::set_name(::std::string&& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.OneofDescriptorProto.name)
@@ -7775,20 +7630,20 @@
 #endif
 inline void OneofDescriptorProto::set_name(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.OneofDescriptorProto.name)
 }
 inline void OneofDescriptorProto::set_name(const char* value,
     size_t size) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.OneofDescriptorProto.name)
 }
 inline ::std::string* OneofDescriptorProto::mutable_name() {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.name)
   return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -7797,14 +7652,14 @@
   if (!has_name()) {
     return NULL;
   }
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void OneofDescriptorProto::set_allocated_name(::std::string* name) {
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
       GetArenaNoVirtual());
@@ -7813,7 +7668,7 @@
 inline ::std::string* OneofDescriptorProto::unsafe_arena_release_name() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.OneofDescriptorProto.name)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -7821,9 +7676,9 @@
     ::std::string* name) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       name, GetArenaNoVirtual());
@@ -7834,18 +7689,9 @@
 inline bool OneofDescriptorProto::has_options() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void OneofDescriptorProto::set_has_options() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void OneofDescriptorProto::clear_has_options() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void OneofDescriptorProto::clear_options() {
   if (options_ != NULL) options_->Clear();
-  clear_has_options();
-}
-inline const ::google::protobuf::OneofOptions& OneofDescriptorProto::_internal_options() const {
-  return *options_;
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::google::protobuf::OneofOptions& OneofDescriptorProto::options() const {
   const ::google::protobuf::OneofOptions* p = options_;
@@ -7855,7 +7701,7 @@
 }
 inline ::google::protobuf::OneofOptions* OneofDescriptorProto::release_options() {
   // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000002u;
   ::google::protobuf::OneofOptions* temp = options_;
   if (GetArenaNoVirtual() != NULL) {
     temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);
@@ -7865,13 +7711,13 @@
 }
 inline ::google::protobuf::OneofOptions* OneofDescriptorProto::unsafe_arena_release_options() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.OneofDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000002u;
   ::google::protobuf::OneofOptions* temp = options_;
   options_ = NULL;
   return temp;
 }
 inline ::google::protobuf::OneofOptions* OneofDescriptorProto::mutable_options() {
-  set_has_options();
+  _has_bits_[0] |= 0x00000002u;
   if (options_ == NULL) {
     auto* p = CreateMaybeMessage<::google::protobuf::OneofOptions>(GetArenaNoVirtual());
     options_ = p;
@@ -7891,9 +7737,9 @@
       options = ::google::protobuf::internal::GetOwnedMessage(
           message_arena, options, submessage_arena);
     }
-    set_has_options();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000002u;
   }
   options_ = options;
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.options)
@@ -7907,22 +7753,16 @@
 inline bool EnumDescriptorProto_EnumReservedRange::has_start() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void EnumDescriptorProto_EnumReservedRange::set_has_start() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void EnumDescriptorProto_EnumReservedRange::clear_has_start() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void EnumDescriptorProto_EnumReservedRange::clear_start() {
   start_ = 0;
-  clear_has_start();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline ::google::protobuf::int32 EnumDescriptorProto_EnumReservedRange::start() const {
   // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.EnumReservedRange.start)
   return start_;
 }
 inline void EnumDescriptorProto_EnumReservedRange::set_start(::google::protobuf::int32 value) {
-  set_has_start();
+  _has_bits_[0] |= 0x00000001u;
   start_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.EnumReservedRange.start)
 }
@@ -7931,22 +7771,16 @@
 inline bool EnumDescriptorProto_EnumReservedRange::has_end() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void EnumDescriptorProto_EnumReservedRange::set_has_end() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void EnumDescriptorProto_EnumReservedRange::clear_has_end() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void EnumDescriptorProto_EnumReservedRange::clear_end() {
   end_ = 0;
-  clear_has_end();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline ::google::protobuf::int32 EnumDescriptorProto_EnumReservedRange::end() const {
   // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.EnumReservedRange.end)
   return end_;
 }
 inline void EnumDescriptorProto_EnumReservedRange::set_end(::google::protobuf::int32 value) {
-  set_has_end();
+  _has_bits_[0] |= 0x00000002u;
   end_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.EnumReservedRange.end)
 }
@@ -7959,28 +7793,22 @@
 inline bool EnumDescriptorProto::has_name() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void EnumDescriptorProto::set_has_name() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void EnumDescriptorProto::clear_has_name() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void EnumDescriptorProto::clear_name() {
   name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& EnumDescriptorProto::name() const {
   // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.name)
   return name_.Get();
 }
 inline void EnumDescriptorProto::set_name(const ::std::string& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.name)
 }
 #if LANG_CXX11
 inline void EnumDescriptorProto::set_name(::std::string&& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.EnumDescriptorProto.name)
@@ -7988,20 +7816,20 @@
 #endif
 inline void EnumDescriptorProto::set_name(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.name)
 }
 inline void EnumDescriptorProto::set_name(const char* value,
     size_t size) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumDescriptorProto.name)
 }
 inline ::std::string* EnumDescriptorProto::mutable_name() {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.name)
   return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -8010,14 +7838,14 @@
   if (!has_name()) {
     return NULL;
   }
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void EnumDescriptorProto::set_allocated_name(::std::string* name) {
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
       GetArenaNoVirtual());
@@ -8026,7 +7854,7 @@
 inline ::std::string* EnumDescriptorProto::unsafe_arena_release_name() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.EnumDescriptorProto.name)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -8034,9 +7862,9 @@
     ::std::string* name) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       name, GetArenaNoVirtual());
@@ -8077,18 +7905,9 @@
 inline bool EnumDescriptorProto::has_options() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void EnumDescriptorProto::set_has_options() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void EnumDescriptorProto::clear_has_options() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void EnumDescriptorProto::clear_options() {
   if (options_ != NULL) options_->Clear();
-  clear_has_options();
-}
-inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::_internal_options() const {
-  return *options_;
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const {
   const ::google::protobuf::EnumOptions* p = options_;
@@ -8098,7 +7917,7 @@
 }
 inline ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
   // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000002u;
   ::google::protobuf::EnumOptions* temp = options_;
   if (GetArenaNoVirtual() != NULL) {
     temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);
@@ -8108,13 +7927,13 @@
 }
 inline ::google::protobuf::EnumOptions* EnumDescriptorProto::unsafe_arena_release_options() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.EnumDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000002u;
   ::google::protobuf::EnumOptions* temp = options_;
   options_ = NULL;
   return temp;
 }
 inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
-  set_has_options();
+  _has_bits_[0] |= 0x00000002u;
   if (options_ == NULL) {
     auto* p = CreateMaybeMessage<::google::protobuf::EnumOptions>(GetArenaNoVirtual());
     options_ = p;
@@ -8134,9 +7953,9 @@
       options = ::google::protobuf::internal::GetOwnedMessage(
           message_arena, options, submessage_arena);
     }
-    set_has_options();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000002u;
   }
   options_ = options;
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.options)
@@ -8230,12 +8049,12 @@
   reserved_name_.Add()->assign(reinterpret_cast<const char*>(value), size);
   // @@protoc_insertion_point(field_add_pointer:google.protobuf.EnumDescriptorProto.reserved_name)
 }
-inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+inline const ::google::protobuf::RepeatedPtrField<::std::string>&
 EnumDescriptorProto::reserved_name() const {
   // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.reserved_name)
   return reserved_name_;
 }
-inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+inline ::google::protobuf::RepeatedPtrField<::std::string>*
 EnumDescriptorProto::mutable_reserved_name() {
   // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.reserved_name)
   return &reserved_name_;
@@ -8249,28 +8068,22 @@
 inline bool EnumValueDescriptorProto::has_name() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void EnumValueDescriptorProto::set_has_name() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void EnumValueDescriptorProto::clear_has_name() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void EnumValueDescriptorProto::clear_name() {
   name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& EnumValueDescriptorProto::name() const {
   // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.name)
   return name_.Get();
 }
 inline void EnumValueDescriptorProto::set_name(const ::std::string& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.name)
 }
 #if LANG_CXX11
 inline void EnumValueDescriptorProto::set_name(::std::string&& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.EnumValueDescriptorProto.name)
@@ -8278,20 +8091,20 @@
 #endif
 inline void EnumValueDescriptorProto::set_name(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValueDescriptorProto.name)
 }
 inline void EnumValueDescriptorProto::set_name(const char* value,
     size_t size) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValueDescriptorProto.name)
 }
 inline ::std::string* EnumValueDescriptorProto::mutable_name() {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.name)
   return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -8300,14 +8113,14 @@
   if (!has_name()) {
     return NULL;
   }
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void EnumValueDescriptorProto::set_allocated_name(::std::string* name) {
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
       GetArenaNoVirtual());
@@ -8316,7 +8129,7 @@
 inline ::std::string* EnumValueDescriptorProto::unsafe_arena_release_name() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.EnumValueDescriptorProto.name)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -8324,9 +8137,9 @@
     ::std::string* name) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       name, GetArenaNoVirtual());
@@ -8337,22 +8150,16 @@
 inline bool EnumValueDescriptorProto::has_number() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
-inline void EnumValueDescriptorProto::set_has_number() {
-  _has_bits_[0] |= 0x00000004u;
-}
-inline void EnumValueDescriptorProto::clear_has_number() {
-  _has_bits_[0] &= ~0x00000004u;
-}
 inline void EnumValueDescriptorProto::clear_number() {
   number_ = 0;
-  clear_has_number();
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline ::google::protobuf::int32 EnumValueDescriptorProto::number() const {
   // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.number)
   return number_;
 }
 inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) {
-  set_has_number();
+  _has_bits_[0] |= 0x00000004u;
   number_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.number)
 }
@@ -8361,18 +8168,9 @@
 inline bool EnumValueDescriptorProto::has_options() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void EnumValueDescriptorProto::set_has_options() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void EnumValueDescriptorProto::clear_has_options() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void EnumValueDescriptorProto::clear_options() {
   if (options_ != NULL) options_->Clear();
-  clear_has_options();
-}
-inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::_internal_options() const {
-  return *options_;
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const {
   const ::google::protobuf::EnumValueOptions* p = options_;
@@ -8382,7 +8180,7 @@
 }
 inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
   // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000002u;
   ::google::protobuf::EnumValueOptions* temp = options_;
   if (GetArenaNoVirtual() != NULL) {
     temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);
@@ -8392,13 +8190,13 @@
 }
 inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::unsafe_arena_release_options() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.EnumValueDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000002u;
   ::google::protobuf::EnumValueOptions* temp = options_;
   options_ = NULL;
   return temp;
 }
 inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() {
-  set_has_options();
+  _has_bits_[0] |= 0x00000002u;
   if (options_ == NULL) {
     auto* p = CreateMaybeMessage<::google::protobuf::EnumValueOptions>(GetArenaNoVirtual());
     options_ = p;
@@ -8418,9 +8216,9 @@
       options = ::google::protobuf::internal::GetOwnedMessage(
           message_arena, options, submessage_arena);
     }
-    set_has_options();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000002u;
   }
   options_ = options;
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
@@ -8434,28 +8232,22 @@
 inline bool ServiceDescriptorProto::has_name() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void ServiceDescriptorProto::set_has_name() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void ServiceDescriptorProto::clear_has_name() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void ServiceDescriptorProto::clear_name() {
   name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& ServiceDescriptorProto::name() const {
   // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.name)
   return name_.Get();
 }
 inline void ServiceDescriptorProto::set_name(const ::std::string& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.ServiceDescriptorProto.name)
 }
 #if LANG_CXX11
 inline void ServiceDescriptorProto::set_name(::std::string&& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.ServiceDescriptorProto.name)
@@ -8463,20 +8255,20 @@
 #endif
 inline void ServiceDescriptorProto::set_name(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.ServiceDescriptorProto.name)
 }
 inline void ServiceDescriptorProto::set_name(const char* value,
     size_t size) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.ServiceDescriptorProto.name)
 }
 inline ::std::string* ServiceDescriptorProto::mutable_name() {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.name)
   return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -8485,14 +8277,14 @@
   if (!has_name()) {
     return NULL;
   }
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void ServiceDescriptorProto::set_allocated_name(::std::string* name) {
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
       GetArenaNoVirtual());
@@ -8501,7 +8293,7 @@
 inline ::std::string* ServiceDescriptorProto::unsafe_arena_release_name() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.ServiceDescriptorProto.name)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -8509,9 +8301,9 @@
     ::std::string* name) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       name, GetArenaNoVirtual());
@@ -8552,18 +8344,9 @@
 inline bool ServiceDescriptorProto::has_options() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void ServiceDescriptorProto::set_has_options() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void ServiceDescriptorProto::clear_has_options() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void ServiceDescriptorProto::clear_options() {
   if (options_ != NULL) options_->Clear();
-  clear_has_options();
-}
-inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::_internal_options() const {
-  return *options_;
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const {
   const ::google::protobuf::ServiceOptions* p = options_;
@@ -8573,7 +8356,7 @@
 }
 inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
   // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000002u;
   ::google::protobuf::ServiceOptions* temp = options_;
   if (GetArenaNoVirtual() != NULL) {
     temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);
@@ -8583,13 +8366,13 @@
 }
 inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::unsafe_arena_release_options() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.ServiceDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000002u;
   ::google::protobuf::ServiceOptions* temp = options_;
   options_ = NULL;
   return temp;
 }
 inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() {
-  set_has_options();
+  _has_bits_[0] |= 0x00000002u;
   if (options_ == NULL) {
     auto* p = CreateMaybeMessage<::google::protobuf::ServiceOptions>(GetArenaNoVirtual());
     options_ = p;
@@ -8609,9 +8392,9 @@
       options = ::google::protobuf::internal::GetOwnedMessage(
           message_arena, options, submessage_arena);
     }
-    set_has_options();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000002u;
   }
   options_ = options;
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.options)
@@ -8625,28 +8408,22 @@
 inline bool MethodDescriptorProto::has_name() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void MethodDescriptorProto::set_has_name() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void MethodDescriptorProto::clear_has_name() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void MethodDescriptorProto::clear_name() {
   name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& MethodDescriptorProto::name() const {
   // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.name)
   return name_.Get();
 }
 inline void MethodDescriptorProto::set_name(const ::std::string& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.name)
 }
 #if LANG_CXX11
 inline void MethodDescriptorProto::set_name(::std::string&& value) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.MethodDescriptorProto.name)
@@ -8654,20 +8431,20 @@
 #endif
 inline void MethodDescriptorProto::set_name(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.name)
 }
 inline void MethodDescriptorProto::set_name(const char* value,
     size_t size) {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.name)
 }
 inline ::std::string* MethodDescriptorProto::mutable_name() {
-  set_has_name();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.name)
   return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -8676,14 +8453,14 @@
   if (!has_name()) {
     return NULL;
   }
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void MethodDescriptorProto::set_allocated_name(::std::string* name) {
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
       GetArenaNoVirtual());
@@ -8692,7 +8469,7 @@
 inline ::std::string* MethodDescriptorProto::unsafe_arena_release_name() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.MethodDescriptorProto.name)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_name();
+  _has_bits_[0] &= ~0x00000001u;
   return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -8700,9 +8477,9 @@
     ::std::string* name) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (name != NULL) {
-    set_has_name();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       name, GetArenaNoVirtual());
@@ -8713,28 +8490,22 @@
 inline bool MethodDescriptorProto::has_input_type() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void MethodDescriptorProto::set_has_input_type() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void MethodDescriptorProto::clear_has_input_type() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void MethodDescriptorProto::clear_input_type() {
   input_type_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_input_type();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::std::string& MethodDescriptorProto::input_type() const {
   // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.input_type)
   return input_type_.Get();
 }
 inline void MethodDescriptorProto::set_input_type(const ::std::string& value) {
-  set_has_input_type();
+  _has_bits_[0] |= 0x00000002u;
   input_type_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.input_type)
 }
 #if LANG_CXX11
 inline void MethodDescriptorProto::set_input_type(::std::string&& value) {
-  set_has_input_type();
+  _has_bits_[0] |= 0x00000002u;
   input_type_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.MethodDescriptorProto.input_type)
@@ -8742,20 +8513,20 @@
 #endif
 inline void MethodDescriptorProto::set_input_type(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_input_type();
+  _has_bits_[0] |= 0x00000002u;
   input_type_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.input_type)
 }
 inline void MethodDescriptorProto::set_input_type(const char* value,
     size_t size) {
-  set_has_input_type();
+  _has_bits_[0] |= 0x00000002u;
   input_type_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.input_type)
 }
 inline ::std::string* MethodDescriptorProto::mutable_input_type() {
-  set_has_input_type();
+  _has_bits_[0] |= 0x00000002u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.input_type)
   return input_type_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -8764,14 +8535,14 @@
   if (!has_input_type()) {
     return NULL;
   }
-  clear_has_input_type();
+  _has_bits_[0] &= ~0x00000002u;
   return input_type_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void MethodDescriptorProto::set_allocated_input_type(::std::string* input_type) {
   if (input_type != NULL) {
-    set_has_input_type();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_input_type();
+    _has_bits_[0] &= ~0x00000002u;
   }
   input_type_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), input_type,
       GetArenaNoVirtual());
@@ -8780,7 +8551,7 @@
 inline ::std::string* MethodDescriptorProto::unsafe_arena_release_input_type() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.MethodDescriptorProto.input_type)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_input_type();
+  _has_bits_[0] &= ~0x00000002u;
   return input_type_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -8788,9 +8559,9 @@
     ::std::string* input_type) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (input_type != NULL) {
-    set_has_input_type();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_input_type();
+    _has_bits_[0] &= ~0x00000002u;
   }
   input_type_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       input_type, GetArenaNoVirtual());
@@ -8801,28 +8572,22 @@
 inline bool MethodDescriptorProto::has_output_type() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
-inline void MethodDescriptorProto::set_has_output_type() {
-  _has_bits_[0] |= 0x00000004u;
-}
-inline void MethodDescriptorProto::clear_has_output_type() {
-  _has_bits_[0] &= ~0x00000004u;
-}
 inline void MethodDescriptorProto::clear_output_type() {
   output_type_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_output_type();
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline const ::std::string& MethodDescriptorProto::output_type() const {
   // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.output_type)
   return output_type_.Get();
 }
 inline void MethodDescriptorProto::set_output_type(const ::std::string& value) {
-  set_has_output_type();
+  _has_bits_[0] |= 0x00000004u;
   output_type_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.output_type)
 }
 #if LANG_CXX11
 inline void MethodDescriptorProto::set_output_type(::std::string&& value) {
-  set_has_output_type();
+  _has_bits_[0] |= 0x00000004u;
   output_type_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.MethodDescriptorProto.output_type)
@@ -8830,20 +8595,20 @@
 #endif
 inline void MethodDescriptorProto::set_output_type(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_output_type();
+  _has_bits_[0] |= 0x00000004u;
   output_type_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.output_type)
 }
 inline void MethodDescriptorProto::set_output_type(const char* value,
     size_t size) {
-  set_has_output_type();
+  _has_bits_[0] |= 0x00000004u;
   output_type_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.output_type)
 }
 inline ::std::string* MethodDescriptorProto::mutable_output_type() {
-  set_has_output_type();
+  _has_bits_[0] |= 0x00000004u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.output_type)
   return output_type_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -8852,14 +8617,14 @@
   if (!has_output_type()) {
     return NULL;
   }
-  clear_has_output_type();
+  _has_bits_[0] &= ~0x00000004u;
   return output_type_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void MethodDescriptorProto::set_allocated_output_type(::std::string* output_type) {
   if (output_type != NULL) {
-    set_has_output_type();
+    _has_bits_[0] |= 0x00000004u;
   } else {
-    clear_has_output_type();
+    _has_bits_[0] &= ~0x00000004u;
   }
   output_type_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), output_type,
       GetArenaNoVirtual());
@@ -8868,7 +8633,7 @@
 inline ::std::string* MethodDescriptorProto::unsafe_arena_release_output_type() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.MethodDescriptorProto.output_type)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_output_type();
+  _has_bits_[0] &= ~0x00000004u;
   return output_type_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -8876,9 +8641,9 @@
     ::std::string* output_type) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (output_type != NULL) {
-    set_has_output_type();
+    _has_bits_[0] |= 0x00000004u;
   } else {
-    clear_has_output_type();
+    _has_bits_[0] &= ~0x00000004u;
   }
   output_type_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       output_type, GetArenaNoVirtual());
@@ -8889,18 +8654,9 @@
 inline bool MethodDescriptorProto::has_options() const {
   return (_has_bits_[0] & 0x00000008u) != 0;
 }
-inline void MethodDescriptorProto::set_has_options() {
-  _has_bits_[0] |= 0x00000008u;
-}
-inline void MethodDescriptorProto::clear_has_options() {
-  _has_bits_[0] &= ~0x00000008u;
-}
 inline void MethodDescriptorProto::clear_options() {
   if (options_ != NULL) options_->Clear();
-  clear_has_options();
-}
-inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::_internal_options() const {
-  return *options_;
+  _has_bits_[0] &= ~0x00000008u;
 }
 inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const {
   const ::google::protobuf::MethodOptions* p = options_;
@@ -8910,7 +8666,7 @@
 }
 inline ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
   // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000008u;
   ::google::protobuf::MethodOptions* temp = options_;
   if (GetArenaNoVirtual() != NULL) {
     temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);
@@ -8920,13 +8676,13 @@
 }
 inline ::google::protobuf::MethodOptions* MethodDescriptorProto::unsafe_arena_release_options() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.MethodDescriptorProto.options)
-  clear_has_options();
+  _has_bits_[0] &= ~0x00000008u;
   ::google::protobuf::MethodOptions* temp = options_;
   options_ = NULL;
   return temp;
 }
 inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() {
-  set_has_options();
+  _has_bits_[0] |= 0x00000008u;
   if (options_ == NULL) {
     auto* p = CreateMaybeMessage<::google::protobuf::MethodOptions>(GetArenaNoVirtual());
     options_ = p;
@@ -8946,9 +8702,9 @@
       options = ::google::protobuf::internal::GetOwnedMessage(
           message_arena, options, submessage_arena);
     }
-    set_has_options();
+    _has_bits_[0] |= 0x00000008u;
   } else {
-    clear_has_options();
+    _has_bits_[0] &= ~0x00000008u;
   }
   options_ = options;
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.options)
@@ -8958,22 +8714,16 @@
 inline bool MethodDescriptorProto::has_client_streaming() const {
   return (_has_bits_[0] & 0x00000010u) != 0;
 }
-inline void MethodDescriptorProto::set_has_client_streaming() {
-  _has_bits_[0] |= 0x00000010u;
-}
-inline void MethodDescriptorProto::clear_has_client_streaming() {
-  _has_bits_[0] &= ~0x00000010u;
-}
 inline void MethodDescriptorProto::clear_client_streaming() {
   client_streaming_ = false;
-  clear_has_client_streaming();
+  _has_bits_[0] &= ~0x00000010u;
 }
 inline bool MethodDescriptorProto::client_streaming() const {
   // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.client_streaming)
   return client_streaming_;
 }
 inline void MethodDescriptorProto::set_client_streaming(bool value) {
-  set_has_client_streaming();
+  _has_bits_[0] |= 0x00000010u;
   client_streaming_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.client_streaming)
 }
@@ -8982,22 +8732,16 @@
 inline bool MethodDescriptorProto::has_server_streaming() const {
   return (_has_bits_[0] & 0x00000020u) != 0;
 }
-inline void MethodDescriptorProto::set_has_server_streaming() {
-  _has_bits_[0] |= 0x00000020u;
-}
-inline void MethodDescriptorProto::clear_has_server_streaming() {
-  _has_bits_[0] &= ~0x00000020u;
-}
 inline void MethodDescriptorProto::clear_server_streaming() {
   server_streaming_ = false;
-  clear_has_server_streaming();
+  _has_bits_[0] &= ~0x00000020u;
 }
 inline bool MethodDescriptorProto::server_streaming() const {
   // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.server_streaming)
   return server_streaming_;
 }
 inline void MethodDescriptorProto::set_server_streaming(bool value) {
-  set_has_server_streaming();
+  _has_bits_[0] |= 0x00000020u;
   server_streaming_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.server_streaming)
 }
@@ -9010,28 +8754,22 @@
 inline bool FileOptions::has_java_package() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void FileOptions::set_has_java_package() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void FileOptions::clear_has_java_package() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void FileOptions::clear_java_package() {
   java_package_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_java_package();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& FileOptions::java_package() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_package)
   return java_package_.Get();
 }
 inline void FileOptions::set_java_package(const ::std::string& value) {
-  set_has_java_package();
+  _has_bits_[0] |= 0x00000001u;
   java_package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_package)
 }
 #if LANG_CXX11
 inline void FileOptions::set_java_package(::std::string&& value) {
-  set_has_java_package();
+  _has_bits_[0] |= 0x00000001u;
   java_package_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.java_package)
@@ -9039,20 +8777,20 @@
 #endif
 inline void FileOptions::set_java_package(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_java_package();
+  _has_bits_[0] |= 0x00000001u;
   java_package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_package)
 }
 inline void FileOptions::set_java_package(const char* value,
     size_t size) {
-  set_has_java_package();
+  _has_bits_[0] |= 0x00000001u;
   java_package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_package)
 }
 inline ::std::string* FileOptions::mutable_java_package() {
-  set_has_java_package();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_package)
   return java_package_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -9061,14 +8799,14 @@
   if (!has_java_package()) {
     return NULL;
   }
-  clear_has_java_package();
+  _has_bits_[0] &= ~0x00000001u;
   return java_package_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FileOptions::set_allocated_java_package(::std::string* java_package) {
   if (java_package != NULL) {
-    set_has_java_package();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_java_package();
+    _has_bits_[0] &= ~0x00000001u;
   }
   java_package_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), java_package,
       GetArenaNoVirtual());
@@ -9077,7 +8815,7 @@
 inline ::std::string* FileOptions::unsafe_arena_release_java_package() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.java_package)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_java_package();
+  _has_bits_[0] &= ~0x00000001u;
   return java_package_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -9085,9 +8823,9 @@
     ::std::string* java_package) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (java_package != NULL) {
-    set_has_java_package();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_java_package();
+    _has_bits_[0] &= ~0x00000001u;
   }
   java_package_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       java_package, GetArenaNoVirtual());
@@ -9098,28 +8836,22 @@
 inline bool FileOptions::has_java_outer_classname() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void FileOptions::set_has_java_outer_classname() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void FileOptions::clear_has_java_outer_classname() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void FileOptions::clear_java_outer_classname() {
   java_outer_classname_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_java_outer_classname();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::std::string& FileOptions::java_outer_classname() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_outer_classname)
   return java_outer_classname_.Get();
 }
 inline void FileOptions::set_java_outer_classname(const ::std::string& value) {
-  set_has_java_outer_classname();
+  _has_bits_[0] |= 0x00000002u;
   java_outer_classname_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_outer_classname)
 }
 #if LANG_CXX11
 inline void FileOptions::set_java_outer_classname(::std::string&& value) {
-  set_has_java_outer_classname();
+  _has_bits_[0] |= 0x00000002u;
   java_outer_classname_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.java_outer_classname)
@@ -9127,20 +8859,20 @@
 #endif
 inline void FileOptions::set_java_outer_classname(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_java_outer_classname();
+  _has_bits_[0] |= 0x00000002u;
   java_outer_classname_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_outer_classname)
 }
 inline void FileOptions::set_java_outer_classname(const char* value,
     size_t size) {
-  set_has_java_outer_classname();
+  _has_bits_[0] |= 0x00000002u;
   java_outer_classname_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_outer_classname)
 }
 inline ::std::string* FileOptions::mutable_java_outer_classname() {
-  set_has_java_outer_classname();
+  _has_bits_[0] |= 0x00000002u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_outer_classname)
   return java_outer_classname_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -9149,14 +8881,14 @@
   if (!has_java_outer_classname()) {
     return NULL;
   }
-  clear_has_java_outer_classname();
+  _has_bits_[0] &= ~0x00000002u;
   return java_outer_classname_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FileOptions::set_allocated_java_outer_classname(::std::string* java_outer_classname) {
   if (java_outer_classname != NULL) {
-    set_has_java_outer_classname();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_java_outer_classname();
+    _has_bits_[0] &= ~0x00000002u;
   }
   java_outer_classname_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), java_outer_classname,
       GetArenaNoVirtual());
@@ -9165,7 +8897,7 @@
 inline ::std::string* FileOptions::unsafe_arena_release_java_outer_classname() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.java_outer_classname)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_java_outer_classname();
+  _has_bits_[0] &= ~0x00000002u;
   return java_outer_classname_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -9173,9 +8905,9 @@
     ::std::string* java_outer_classname) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (java_outer_classname != NULL) {
-    set_has_java_outer_classname();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_java_outer_classname();
+    _has_bits_[0] &= ~0x00000002u;
   }
   java_outer_classname_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       java_outer_classname, GetArenaNoVirtual());
@@ -9186,22 +8918,16 @@
 inline bool FileOptions::has_java_multiple_files() const {
   return (_has_bits_[0] & 0x00000400u) != 0;
 }
-inline void FileOptions::set_has_java_multiple_files() {
-  _has_bits_[0] |= 0x00000400u;
-}
-inline void FileOptions::clear_has_java_multiple_files() {
-  _has_bits_[0] &= ~0x00000400u;
-}
 inline void FileOptions::clear_java_multiple_files() {
   java_multiple_files_ = false;
-  clear_has_java_multiple_files();
+  _has_bits_[0] &= ~0x00000400u;
 }
 inline bool FileOptions::java_multiple_files() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_multiple_files)
   return java_multiple_files_;
 }
 inline void FileOptions::set_java_multiple_files(bool value) {
-  set_has_java_multiple_files();
+  _has_bits_[0] |= 0x00000400u;
   java_multiple_files_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_multiple_files)
 }
@@ -9210,22 +8936,16 @@
 inline bool FileOptions::has_java_generate_equals_and_hash() const {
   return (_has_bits_[0] & 0x00000800u) != 0;
 }
-inline void FileOptions::set_has_java_generate_equals_and_hash() {
-  _has_bits_[0] |= 0x00000800u;
-}
-inline void FileOptions::clear_has_java_generate_equals_and_hash() {
-  _has_bits_[0] &= ~0x00000800u;
-}
 inline void FileOptions::clear_java_generate_equals_and_hash() {
   java_generate_equals_and_hash_ = false;
-  clear_has_java_generate_equals_and_hash();
+  _has_bits_[0] &= ~0x00000800u;
 }
 inline bool FileOptions::java_generate_equals_and_hash() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generate_equals_and_hash)
   return java_generate_equals_and_hash_;
 }
 inline void FileOptions::set_java_generate_equals_and_hash(bool value) {
-  set_has_java_generate_equals_and_hash();
+  _has_bits_[0] |= 0x00000800u;
   java_generate_equals_and_hash_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generate_equals_and_hash)
 }
@@ -9234,22 +8954,16 @@
 inline bool FileOptions::has_java_string_check_utf8() const {
   return (_has_bits_[0] & 0x00001000u) != 0;
 }
-inline void FileOptions::set_has_java_string_check_utf8() {
-  _has_bits_[0] |= 0x00001000u;
-}
-inline void FileOptions::clear_has_java_string_check_utf8() {
-  _has_bits_[0] &= ~0x00001000u;
-}
 inline void FileOptions::clear_java_string_check_utf8() {
   java_string_check_utf8_ = false;
-  clear_has_java_string_check_utf8();
+  _has_bits_[0] &= ~0x00001000u;
 }
 inline bool FileOptions::java_string_check_utf8() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_string_check_utf8)
   return java_string_check_utf8_;
 }
 inline void FileOptions::set_java_string_check_utf8(bool value) {
-  set_has_java_string_check_utf8();
+  _has_bits_[0] |= 0x00001000u;
   java_string_check_utf8_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_string_check_utf8)
 }
@@ -9258,15 +8972,9 @@
 inline bool FileOptions::has_optimize_for() const {
   return (_has_bits_[0] & 0x00080000u) != 0;
 }
-inline void FileOptions::set_has_optimize_for() {
-  _has_bits_[0] |= 0x00080000u;
-}
-inline void FileOptions::clear_has_optimize_for() {
-  _has_bits_[0] &= ~0x00080000u;
-}
 inline void FileOptions::clear_optimize_for() {
   optimize_for_ = 1;
-  clear_has_optimize_for();
+  _has_bits_[0] &= ~0x00080000u;
 }
 inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.optimize_for)
@@ -9274,7 +8982,7 @@
 }
 inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) {
   assert(::google::protobuf::FileOptions_OptimizeMode_IsValid(value));
-  set_has_optimize_for();
+  _has_bits_[0] |= 0x00080000u;
   optimize_for_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.optimize_for)
 }
@@ -9283,28 +8991,22 @@
 inline bool FileOptions::has_go_package() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
-inline void FileOptions::set_has_go_package() {
-  _has_bits_[0] |= 0x00000004u;
-}
-inline void FileOptions::clear_has_go_package() {
-  _has_bits_[0] &= ~0x00000004u;
-}
 inline void FileOptions::clear_go_package() {
   go_package_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_go_package();
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline const ::std::string& FileOptions::go_package() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.go_package)
   return go_package_.Get();
 }
 inline void FileOptions::set_go_package(const ::std::string& value) {
-  set_has_go_package();
+  _has_bits_[0] |= 0x00000004u;
   go_package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.go_package)
 }
 #if LANG_CXX11
 inline void FileOptions::set_go_package(::std::string&& value) {
-  set_has_go_package();
+  _has_bits_[0] |= 0x00000004u;
   go_package_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.go_package)
@@ -9312,20 +9014,20 @@
 #endif
 inline void FileOptions::set_go_package(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_go_package();
+  _has_bits_[0] |= 0x00000004u;
   go_package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.go_package)
 }
 inline void FileOptions::set_go_package(const char* value,
     size_t size) {
-  set_has_go_package();
+  _has_bits_[0] |= 0x00000004u;
   go_package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.go_package)
 }
 inline ::std::string* FileOptions::mutable_go_package() {
-  set_has_go_package();
+  _has_bits_[0] |= 0x00000004u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.go_package)
   return go_package_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -9334,14 +9036,14 @@
   if (!has_go_package()) {
     return NULL;
   }
-  clear_has_go_package();
+  _has_bits_[0] &= ~0x00000004u;
   return go_package_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FileOptions::set_allocated_go_package(::std::string* go_package) {
   if (go_package != NULL) {
-    set_has_go_package();
+    _has_bits_[0] |= 0x00000004u;
   } else {
-    clear_has_go_package();
+    _has_bits_[0] &= ~0x00000004u;
   }
   go_package_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), go_package,
       GetArenaNoVirtual());
@@ -9350,7 +9052,7 @@
 inline ::std::string* FileOptions::unsafe_arena_release_go_package() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.go_package)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_go_package();
+  _has_bits_[0] &= ~0x00000004u;
   return go_package_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -9358,9 +9060,9 @@
     ::std::string* go_package) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (go_package != NULL) {
-    set_has_go_package();
+    _has_bits_[0] |= 0x00000004u;
   } else {
-    clear_has_go_package();
+    _has_bits_[0] &= ~0x00000004u;
   }
   go_package_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       go_package, GetArenaNoVirtual());
@@ -9371,22 +9073,16 @@
 inline bool FileOptions::has_cc_generic_services() const {
   return (_has_bits_[0] & 0x00002000u) != 0;
 }
-inline void FileOptions::set_has_cc_generic_services() {
-  _has_bits_[0] |= 0x00002000u;
-}
-inline void FileOptions::clear_has_cc_generic_services() {
-  _has_bits_[0] &= ~0x00002000u;
-}
 inline void FileOptions::clear_cc_generic_services() {
   cc_generic_services_ = false;
-  clear_has_cc_generic_services();
+  _has_bits_[0] &= ~0x00002000u;
 }
 inline bool FileOptions::cc_generic_services() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_generic_services)
   return cc_generic_services_;
 }
 inline void FileOptions::set_cc_generic_services(bool value) {
-  set_has_cc_generic_services();
+  _has_bits_[0] |= 0x00002000u;
   cc_generic_services_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_generic_services)
 }
@@ -9395,22 +9091,16 @@
 inline bool FileOptions::has_java_generic_services() const {
   return (_has_bits_[0] & 0x00004000u) != 0;
 }
-inline void FileOptions::set_has_java_generic_services() {
-  _has_bits_[0] |= 0x00004000u;
-}
-inline void FileOptions::clear_has_java_generic_services() {
-  _has_bits_[0] &= ~0x00004000u;
-}
 inline void FileOptions::clear_java_generic_services() {
   java_generic_services_ = false;
-  clear_has_java_generic_services();
+  _has_bits_[0] &= ~0x00004000u;
 }
 inline bool FileOptions::java_generic_services() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generic_services)
   return java_generic_services_;
 }
 inline void FileOptions::set_java_generic_services(bool value) {
-  set_has_java_generic_services();
+  _has_bits_[0] |= 0x00004000u;
   java_generic_services_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generic_services)
 }
@@ -9419,22 +9109,16 @@
 inline bool FileOptions::has_py_generic_services() const {
   return (_has_bits_[0] & 0x00008000u) != 0;
 }
-inline void FileOptions::set_has_py_generic_services() {
-  _has_bits_[0] |= 0x00008000u;
-}
-inline void FileOptions::clear_has_py_generic_services() {
-  _has_bits_[0] &= ~0x00008000u;
-}
 inline void FileOptions::clear_py_generic_services() {
   py_generic_services_ = false;
-  clear_has_py_generic_services();
+  _has_bits_[0] &= ~0x00008000u;
 }
 inline bool FileOptions::py_generic_services() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.py_generic_services)
   return py_generic_services_;
 }
 inline void FileOptions::set_py_generic_services(bool value) {
-  set_has_py_generic_services();
+  _has_bits_[0] |= 0x00008000u;
   py_generic_services_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services)
 }
@@ -9443,22 +9127,16 @@
 inline bool FileOptions::has_php_generic_services() const {
   return (_has_bits_[0] & 0x00010000u) != 0;
 }
-inline void FileOptions::set_has_php_generic_services() {
-  _has_bits_[0] |= 0x00010000u;
-}
-inline void FileOptions::clear_has_php_generic_services() {
-  _has_bits_[0] &= ~0x00010000u;
-}
 inline void FileOptions::clear_php_generic_services() {
   php_generic_services_ = false;
-  clear_has_php_generic_services();
+  _has_bits_[0] &= ~0x00010000u;
 }
 inline bool FileOptions::php_generic_services() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_generic_services)
   return php_generic_services_;
 }
 inline void FileOptions::set_php_generic_services(bool value) {
-  set_has_php_generic_services();
+  _has_bits_[0] |= 0x00010000u;
   php_generic_services_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_generic_services)
 }
@@ -9467,22 +9145,16 @@
 inline bool FileOptions::has_deprecated() const {
   return (_has_bits_[0] & 0x00020000u) != 0;
 }
-inline void FileOptions::set_has_deprecated() {
-  _has_bits_[0] |= 0x00020000u;
-}
-inline void FileOptions::clear_has_deprecated() {
-  _has_bits_[0] &= ~0x00020000u;
-}
 inline void FileOptions::clear_deprecated() {
   deprecated_ = false;
-  clear_has_deprecated();
+  _has_bits_[0] &= ~0x00020000u;
 }
 inline bool FileOptions::deprecated() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.deprecated)
   return deprecated_;
 }
 inline void FileOptions::set_deprecated(bool value) {
-  set_has_deprecated();
+  _has_bits_[0] |= 0x00020000u;
   deprecated_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.deprecated)
 }
@@ -9491,22 +9163,16 @@
 inline bool FileOptions::has_cc_enable_arenas() const {
   return (_has_bits_[0] & 0x00040000u) != 0;
 }
-inline void FileOptions::set_has_cc_enable_arenas() {
-  _has_bits_[0] |= 0x00040000u;
-}
-inline void FileOptions::clear_has_cc_enable_arenas() {
-  _has_bits_[0] &= ~0x00040000u;
-}
 inline void FileOptions::clear_cc_enable_arenas() {
   cc_enable_arenas_ = false;
-  clear_has_cc_enable_arenas();
+  _has_bits_[0] &= ~0x00040000u;
 }
 inline bool FileOptions::cc_enable_arenas() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_enable_arenas)
   return cc_enable_arenas_;
 }
 inline void FileOptions::set_cc_enable_arenas(bool value) {
-  set_has_cc_enable_arenas();
+  _has_bits_[0] |= 0x00040000u;
   cc_enable_arenas_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_enable_arenas)
 }
@@ -9515,28 +9181,22 @@
 inline bool FileOptions::has_objc_class_prefix() const {
   return (_has_bits_[0] & 0x00000008u) != 0;
 }
-inline void FileOptions::set_has_objc_class_prefix() {
-  _has_bits_[0] |= 0x00000008u;
-}
-inline void FileOptions::clear_has_objc_class_prefix() {
-  _has_bits_[0] &= ~0x00000008u;
-}
 inline void FileOptions::clear_objc_class_prefix() {
   objc_class_prefix_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_objc_class_prefix();
+  _has_bits_[0] &= ~0x00000008u;
 }
 inline const ::std::string& FileOptions::objc_class_prefix() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.objc_class_prefix)
   return objc_class_prefix_.Get();
 }
 inline void FileOptions::set_objc_class_prefix(const ::std::string& value) {
-  set_has_objc_class_prefix();
+  _has_bits_[0] |= 0x00000008u;
   objc_class_prefix_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.objc_class_prefix)
 }
 #if LANG_CXX11
 inline void FileOptions::set_objc_class_prefix(::std::string&& value) {
-  set_has_objc_class_prefix();
+  _has_bits_[0] |= 0x00000008u;
   objc_class_prefix_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.objc_class_prefix)
@@ -9544,20 +9204,20 @@
 #endif
 inline void FileOptions::set_objc_class_prefix(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_objc_class_prefix();
+  _has_bits_[0] |= 0x00000008u;
   objc_class_prefix_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.objc_class_prefix)
 }
 inline void FileOptions::set_objc_class_prefix(const char* value,
     size_t size) {
-  set_has_objc_class_prefix();
+  _has_bits_[0] |= 0x00000008u;
   objc_class_prefix_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.objc_class_prefix)
 }
 inline ::std::string* FileOptions::mutable_objc_class_prefix() {
-  set_has_objc_class_prefix();
+  _has_bits_[0] |= 0x00000008u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.objc_class_prefix)
   return objc_class_prefix_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -9566,14 +9226,14 @@
   if (!has_objc_class_prefix()) {
     return NULL;
   }
-  clear_has_objc_class_prefix();
+  _has_bits_[0] &= ~0x00000008u;
   return objc_class_prefix_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FileOptions::set_allocated_objc_class_prefix(::std::string* objc_class_prefix) {
   if (objc_class_prefix != NULL) {
-    set_has_objc_class_prefix();
+    _has_bits_[0] |= 0x00000008u;
   } else {
-    clear_has_objc_class_prefix();
+    _has_bits_[0] &= ~0x00000008u;
   }
   objc_class_prefix_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), objc_class_prefix,
       GetArenaNoVirtual());
@@ -9582,7 +9242,7 @@
 inline ::std::string* FileOptions::unsafe_arena_release_objc_class_prefix() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.objc_class_prefix)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_objc_class_prefix();
+  _has_bits_[0] &= ~0x00000008u;
   return objc_class_prefix_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -9590,9 +9250,9 @@
     ::std::string* objc_class_prefix) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (objc_class_prefix != NULL) {
-    set_has_objc_class_prefix();
+    _has_bits_[0] |= 0x00000008u;
   } else {
-    clear_has_objc_class_prefix();
+    _has_bits_[0] &= ~0x00000008u;
   }
   objc_class_prefix_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       objc_class_prefix, GetArenaNoVirtual());
@@ -9603,28 +9263,22 @@
 inline bool FileOptions::has_csharp_namespace() const {
   return (_has_bits_[0] & 0x00000010u) != 0;
 }
-inline void FileOptions::set_has_csharp_namespace() {
-  _has_bits_[0] |= 0x00000010u;
-}
-inline void FileOptions::clear_has_csharp_namespace() {
-  _has_bits_[0] &= ~0x00000010u;
-}
 inline void FileOptions::clear_csharp_namespace() {
   csharp_namespace_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_csharp_namespace();
+  _has_bits_[0] &= ~0x00000010u;
 }
 inline const ::std::string& FileOptions::csharp_namespace() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_namespace)
   return csharp_namespace_.Get();
 }
 inline void FileOptions::set_csharp_namespace(const ::std::string& value) {
-  set_has_csharp_namespace();
+  _has_bits_[0] |= 0x00000010u;
   csharp_namespace_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_namespace)
 }
 #if LANG_CXX11
 inline void FileOptions::set_csharp_namespace(::std::string&& value) {
-  set_has_csharp_namespace();
+  _has_bits_[0] |= 0x00000010u;
   csharp_namespace_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.csharp_namespace)
@@ -9632,20 +9286,20 @@
 #endif
 inline void FileOptions::set_csharp_namespace(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_csharp_namespace();
+  _has_bits_[0] |= 0x00000010u;
   csharp_namespace_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace)
 }
 inline void FileOptions::set_csharp_namespace(const char* value,
     size_t size) {
-  set_has_csharp_namespace();
+  _has_bits_[0] |= 0x00000010u;
   csharp_namespace_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.csharp_namespace)
 }
 inline ::std::string* FileOptions::mutable_csharp_namespace() {
-  set_has_csharp_namespace();
+  _has_bits_[0] |= 0x00000010u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_namespace)
   return csharp_namespace_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -9654,14 +9308,14 @@
   if (!has_csharp_namespace()) {
     return NULL;
   }
-  clear_has_csharp_namespace();
+  _has_bits_[0] &= ~0x00000010u;
   return csharp_namespace_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FileOptions::set_allocated_csharp_namespace(::std::string* csharp_namespace) {
   if (csharp_namespace != NULL) {
-    set_has_csharp_namespace();
+    _has_bits_[0] |= 0x00000010u;
   } else {
-    clear_has_csharp_namespace();
+    _has_bits_[0] &= ~0x00000010u;
   }
   csharp_namespace_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), csharp_namespace,
       GetArenaNoVirtual());
@@ -9670,7 +9324,7 @@
 inline ::std::string* FileOptions::unsafe_arena_release_csharp_namespace() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.csharp_namespace)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_csharp_namespace();
+  _has_bits_[0] &= ~0x00000010u;
   return csharp_namespace_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -9678,9 +9332,9 @@
     ::std::string* csharp_namespace) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (csharp_namespace != NULL) {
-    set_has_csharp_namespace();
+    _has_bits_[0] |= 0x00000010u;
   } else {
-    clear_has_csharp_namespace();
+    _has_bits_[0] &= ~0x00000010u;
   }
   csharp_namespace_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       csharp_namespace, GetArenaNoVirtual());
@@ -9691,28 +9345,22 @@
 inline bool FileOptions::has_swift_prefix() const {
   return (_has_bits_[0] & 0x00000020u) != 0;
 }
-inline void FileOptions::set_has_swift_prefix() {
-  _has_bits_[0] |= 0x00000020u;
-}
-inline void FileOptions::clear_has_swift_prefix() {
-  _has_bits_[0] &= ~0x00000020u;
-}
 inline void FileOptions::clear_swift_prefix() {
   swift_prefix_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_swift_prefix();
+  _has_bits_[0] &= ~0x00000020u;
 }
 inline const ::std::string& FileOptions::swift_prefix() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.swift_prefix)
   return swift_prefix_.Get();
 }
 inline void FileOptions::set_swift_prefix(const ::std::string& value) {
-  set_has_swift_prefix();
+  _has_bits_[0] |= 0x00000020u;
   swift_prefix_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.swift_prefix)
 }
 #if LANG_CXX11
 inline void FileOptions::set_swift_prefix(::std::string&& value) {
-  set_has_swift_prefix();
+  _has_bits_[0] |= 0x00000020u;
   swift_prefix_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.swift_prefix)
@@ -9720,20 +9368,20 @@
 #endif
 inline void FileOptions::set_swift_prefix(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_swift_prefix();
+  _has_bits_[0] |= 0x00000020u;
   swift_prefix_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.swift_prefix)
 }
 inline void FileOptions::set_swift_prefix(const char* value,
     size_t size) {
-  set_has_swift_prefix();
+  _has_bits_[0] |= 0x00000020u;
   swift_prefix_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.swift_prefix)
 }
 inline ::std::string* FileOptions::mutable_swift_prefix() {
-  set_has_swift_prefix();
+  _has_bits_[0] |= 0x00000020u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.swift_prefix)
   return swift_prefix_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -9742,14 +9390,14 @@
   if (!has_swift_prefix()) {
     return NULL;
   }
-  clear_has_swift_prefix();
+  _has_bits_[0] &= ~0x00000020u;
   return swift_prefix_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FileOptions::set_allocated_swift_prefix(::std::string* swift_prefix) {
   if (swift_prefix != NULL) {
-    set_has_swift_prefix();
+    _has_bits_[0] |= 0x00000020u;
   } else {
-    clear_has_swift_prefix();
+    _has_bits_[0] &= ~0x00000020u;
   }
   swift_prefix_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), swift_prefix,
       GetArenaNoVirtual());
@@ -9758,7 +9406,7 @@
 inline ::std::string* FileOptions::unsafe_arena_release_swift_prefix() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.swift_prefix)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_swift_prefix();
+  _has_bits_[0] &= ~0x00000020u;
   return swift_prefix_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -9766,9 +9414,9 @@
     ::std::string* swift_prefix) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (swift_prefix != NULL) {
-    set_has_swift_prefix();
+    _has_bits_[0] |= 0x00000020u;
   } else {
-    clear_has_swift_prefix();
+    _has_bits_[0] &= ~0x00000020u;
   }
   swift_prefix_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       swift_prefix, GetArenaNoVirtual());
@@ -9779,28 +9427,22 @@
 inline bool FileOptions::has_php_class_prefix() const {
   return (_has_bits_[0] & 0x00000040u) != 0;
 }
-inline void FileOptions::set_has_php_class_prefix() {
-  _has_bits_[0] |= 0x00000040u;
-}
-inline void FileOptions::clear_has_php_class_prefix() {
-  _has_bits_[0] &= ~0x00000040u;
-}
 inline void FileOptions::clear_php_class_prefix() {
   php_class_prefix_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_php_class_prefix();
+  _has_bits_[0] &= ~0x00000040u;
 }
 inline const ::std::string& FileOptions::php_class_prefix() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_class_prefix)
   return php_class_prefix_.Get();
 }
 inline void FileOptions::set_php_class_prefix(const ::std::string& value) {
-  set_has_php_class_prefix();
+  _has_bits_[0] |= 0x00000040u;
   php_class_prefix_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_class_prefix)
 }
 #if LANG_CXX11
 inline void FileOptions::set_php_class_prefix(::std::string&& value) {
-  set_has_php_class_prefix();
+  _has_bits_[0] |= 0x00000040u;
   php_class_prefix_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.php_class_prefix)
@@ -9808,20 +9450,20 @@
 #endif
 inline void FileOptions::set_php_class_prefix(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_php_class_prefix();
+  _has_bits_[0] |= 0x00000040u;
   php_class_prefix_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_class_prefix)
 }
 inline void FileOptions::set_php_class_prefix(const char* value,
     size_t size) {
-  set_has_php_class_prefix();
+  _has_bits_[0] |= 0x00000040u;
   php_class_prefix_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.php_class_prefix)
 }
 inline ::std::string* FileOptions::mutable_php_class_prefix() {
-  set_has_php_class_prefix();
+  _has_bits_[0] |= 0x00000040u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_class_prefix)
   return php_class_prefix_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -9830,14 +9472,14 @@
   if (!has_php_class_prefix()) {
     return NULL;
   }
-  clear_has_php_class_prefix();
+  _has_bits_[0] &= ~0x00000040u;
   return php_class_prefix_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FileOptions::set_allocated_php_class_prefix(::std::string* php_class_prefix) {
   if (php_class_prefix != NULL) {
-    set_has_php_class_prefix();
+    _has_bits_[0] |= 0x00000040u;
   } else {
-    clear_has_php_class_prefix();
+    _has_bits_[0] &= ~0x00000040u;
   }
   php_class_prefix_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), php_class_prefix,
       GetArenaNoVirtual());
@@ -9846,7 +9488,7 @@
 inline ::std::string* FileOptions::unsafe_arena_release_php_class_prefix() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.php_class_prefix)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_php_class_prefix();
+  _has_bits_[0] &= ~0x00000040u;
   return php_class_prefix_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -9854,9 +9496,9 @@
     ::std::string* php_class_prefix) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (php_class_prefix != NULL) {
-    set_has_php_class_prefix();
+    _has_bits_[0] |= 0x00000040u;
   } else {
-    clear_has_php_class_prefix();
+    _has_bits_[0] &= ~0x00000040u;
   }
   php_class_prefix_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       php_class_prefix, GetArenaNoVirtual());
@@ -9867,28 +9509,22 @@
 inline bool FileOptions::has_php_namespace() const {
   return (_has_bits_[0] & 0x00000080u) != 0;
 }
-inline void FileOptions::set_has_php_namespace() {
-  _has_bits_[0] |= 0x00000080u;
-}
-inline void FileOptions::clear_has_php_namespace() {
-  _has_bits_[0] &= ~0x00000080u;
-}
 inline void FileOptions::clear_php_namespace() {
   php_namespace_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_php_namespace();
+  _has_bits_[0] &= ~0x00000080u;
 }
 inline const ::std::string& FileOptions::php_namespace() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_namespace)
   return php_namespace_.Get();
 }
 inline void FileOptions::set_php_namespace(const ::std::string& value) {
-  set_has_php_namespace();
+  _has_bits_[0] |= 0x00000080u;
   php_namespace_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_namespace)
 }
 #if LANG_CXX11
 inline void FileOptions::set_php_namespace(::std::string&& value) {
-  set_has_php_namespace();
+  _has_bits_[0] |= 0x00000080u;
   php_namespace_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.php_namespace)
@@ -9896,20 +9532,20 @@
 #endif
 inline void FileOptions::set_php_namespace(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_php_namespace();
+  _has_bits_[0] |= 0x00000080u;
   php_namespace_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_namespace)
 }
 inline void FileOptions::set_php_namespace(const char* value,
     size_t size) {
-  set_has_php_namespace();
+  _has_bits_[0] |= 0x00000080u;
   php_namespace_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.php_namespace)
 }
 inline ::std::string* FileOptions::mutable_php_namespace() {
-  set_has_php_namespace();
+  _has_bits_[0] |= 0x00000080u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_namespace)
   return php_namespace_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -9918,14 +9554,14 @@
   if (!has_php_namespace()) {
     return NULL;
   }
-  clear_has_php_namespace();
+  _has_bits_[0] &= ~0x00000080u;
   return php_namespace_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FileOptions::set_allocated_php_namespace(::std::string* php_namespace) {
   if (php_namespace != NULL) {
-    set_has_php_namespace();
+    _has_bits_[0] |= 0x00000080u;
   } else {
-    clear_has_php_namespace();
+    _has_bits_[0] &= ~0x00000080u;
   }
   php_namespace_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), php_namespace,
       GetArenaNoVirtual());
@@ -9934,7 +9570,7 @@
 inline ::std::string* FileOptions::unsafe_arena_release_php_namespace() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.php_namespace)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_php_namespace();
+  _has_bits_[0] &= ~0x00000080u;
   return php_namespace_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -9942,9 +9578,9 @@
     ::std::string* php_namespace) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (php_namespace != NULL) {
-    set_has_php_namespace();
+    _has_bits_[0] |= 0x00000080u;
   } else {
-    clear_has_php_namespace();
+    _has_bits_[0] &= ~0x00000080u;
   }
   php_namespace_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       php_namespace, GetArenaNoVirtual());
@@ -9955,28 +9591,22 @@
 inline bool FileOptions::has_php_metadata_namespace() const {
   return (_has_bits_[0] & 0x00000100u) != 0;
 }
-inline void FileOptions::set_has_php_metadata_namespace() {
-  _has_bits_[0] |= 0x00000100u;
-}
-inline void FileOptions::clear_has_php_metadata_namespace() {
-  _has_bits_[0] &= ~0x00000100u;
-}
 inline void FileOptions::clear_php_metadata_namespace() {
   php_metadata_namespace_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_php_metadata_namespace();
+  _has_bits_[0] &= ~0x00000100u;
 }
 inline const ::std::string& FileOptions::php_metadata_namespace() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.php_metadata_namespace)
   return php_metadata_namespace_.Get();
 }
 inline void FileOptions::set_php_metadata_namespace(const ::std::string& value) {
-  set_has_php_metadata_namespace();
+  _has_bits_[0] |= 0x00000100u;
   php_metadata_namespace_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_metadata_namespace)
 }
 #if LANG_CXX11
 inline void FileOptions::set_php_metadata_namespace(::std::string&& value) {
-  set_has_php_metadata_namespace();
+  _has_bits_[0] |= 0x00000100u;
   php_metadata_namespace_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.php_metadata_namespace)
@@ -9984,20 +9614,20 @@
 #endif
 inline void FileOptions::set_php_metadata_namespace(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_php_metadata_namespace();
+  _has_bits_[0] |= 0x00000100u;
   php_metadata_namespace_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_metadata_namespace)
 }
 inline void FileOptions::set_php_metadata_namespace(const char* value,
     size_t size) {
-  set_has_php_metadata_namespace();
+  _has_bits_[0] |= 0x00000100u;
   php_metadata_namespace_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.php_metadata_namespace)
 }
 inline ::std::string* FileOptions::mutable_php_metadata_namespace() {
-  set_has_php_metadata_namespace();
+  _has_bits_[0] |= 0x00000100u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.php_metadata_namespace)
   return php_metadata_namespace_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -10006,14 +9636,14 @@
   if (!has_php_metadata_namespace()) {
     return NULL;
   }
-  clear_has_php_metadata_namespace();
+  _has_bits_[0] &= ~0x00000100u;
   return php_metadata_namespace_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FileOptions::set_allocated_php_metadata_namespace(::std::string* php_metadata_namespace) {
   if (php_metadata_namespace != NULL) {
-    set_has_php_metadata_namespace();
+    _has_bits_[0] |= 0x00000100u;
   } else {
-    clear_has_php_metadata_namespace();
+    _has_bits_[0] &= ~0x00000100u;
   }
   php_metadata_namespace_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), php_metadata_namespace,
       GetArenaNoVirtual());
@@ -10022,7 +9652,7 @@
 inline ::std::string* FileOptions::unsafe_arena_release_php_metadata_namespace() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.php_metadata_namespace)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_php_metadata_namespace();
+  _has_bits_[0] &= ~0x00000100u;
   return php_metadata_namespace_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -10030,9 +9660,9 @@
     ::std::string* php_metadata_namespace) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (php_metadata_namespace != NULL) {
-    set_has_php_metadata_namespace();
+    _has_bits_[0] |= 0x00000100u;
   } else {
-    clear_has_php_metadata_namespace();
+    _has_bits_[0] &= ~0x00000100u;
   }
   php_metadata_namespace_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       php_metadata_namespace, GetArenaNoVirtual());
@@ -10043,28 +9673,22 @@
 inline bool FileOptions::has_ruby_package() const {
   return (_has_bits_[0] & 0x00000200u) != 0;
 }
-inline void FileOptions::set_has_ruby_package() {
-  _has_bits_[0] |= 0x00000200u;
-}
-inline void FileOptions::clear_has_ruby_package() {
-  _has_bits_[0] &= ~0x00000200u;
-}
 inline void FileOptions::clear_ruby_package() {
   ruby_package_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_ruby_package();
+  _has_bits_[0] &= ~0x00000200u;
 }
 inline const ::std::string& FileOptions::ruby_package() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.ruby_package)
   return ruby_package_.Get();
 }
 inline void FileOptions::set_ruby_package(const ::std::string& value) {
-  set_has_ruby_package();
+  _has_bits_[0] |= 0x00000200u;
   ruby_package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.ruby_package)
 }
 #if LANG_CXX11
 inline void FileOptions::set_ruby_package(::std::string&& value) {
-  set_has_ruby_package();
+  _has_bits_[0] |= 0x00000200u;
   ruby_package_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.ruby_package)
@@ -10072,20 +9696,20 @@
 #endif
 inline void FileOptions::set_ruby_package(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_ruby_package();
+  _has_bits_[0] |= 0x00000200u;
   ruby_package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.ruby_package)
 }
 inline void FileOptions::set_ruby_package(const char* value,
     size_t size) {
-  set_has_ruby_package();
+  _has_bits_[0] |= 0x00000200u;
   ruby_package_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.ruby_package)
 }
 inline ::std::string* FileOptions::mutable_ruby_package() {
-  set_has_ruby_package();
+  _has_bits_[0] |= 0x00000200u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.ruby_package)
   return ruby_package_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -10094,14 +9718,14 @@
   if (!has_ruby_package()) {
     return NULL;
   }
-  clear_has_ruby_package();
+  _has_bits_[0] &= ~0x00000200u;
   return ruby_package_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void FileOptions::set_allocated_ruby_package(::std::string* ruby_package) {
   if (ruby_package != NULL) {
-    set_has_ruby_package();
+    _has_bits_[0] |= 0x00000200u;
   } else {
-    clear_has_ruby_package();
+    _has_bits_[0] &= ~0x00000200u;
   }
   ruby_package_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ruby_package,
       GetArenaNoVirtual());
@@ -10110,7 +9734,7 @@
 inline ::std::string* FileOptions::unsafe_arena_release_ruby_package() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.ruby_package)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_ruby_package();
+  _has_bits_[0] &= ~0x00000200u;
   return ruby_package_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -10118,9 +9742,9 @@
     ::std::string* ruby_package) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (ruby_package != NULL) {
-    set_has_ruby_package();
+    _has_bits_[0] |= 0x00000200u;
   } else {
-    clear_has_ruby_package();
+    _has_bits_[0] &= ~0x00000200u;
   }
   ruby_package_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       ruby_package, GetArenaNoVirtual());
@@ -10165,22 +9789,16 @@
 inline bool MessageOptions::has_message_set_wire_format() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void MessageOptions::set_has_message_set_wire_format() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void MessageOptions::clear_has_message_set_wire_format() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void MessageOptions::clear_message_set_wire_format() {
   message_set_wire_format_ = false;
-  clear_has_message_set_wire_format();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline bool MessageOptions::message_set_wire_format() const {
   // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.message_set_wire_format)
   return message_set_wire_format_;
 }
 inline void MessageOptions::set_message_set_wire_format(bool value) {
-  set_has_message_set_wire_format();
+  _has_bits_[0] |= 0x00000001u;
   message_set_wire_format_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.message_set_wire_format)
 }
@@ -10189,22 +9807,16 @@
 inline bool MessageOptions::has_no_standard_descriptor_accessor() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void MessageOptions::set_has_no_standard_descriptor_accessor() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void MessageOptions::clear_has_no_standard_descriptor_accessor() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void MessageOptions::clear_no_standard_descriptor_accessor() {
   no_standard_descriptor_accessor_ = false;
-  clear_has_no_standard_descriptor_accessor();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline bool MessageOptions::no_standard_descriptor_accessor() const {
   // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
   return no_standard_descriptor_accessor_;
 }
 inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) {
-  set_has_no_standard_descriptor_accessor();
+  _has_bits_[0] |= 0x00000002u;
   no_standard_descriptor_accessor_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
 }
@@ -10213,22 +9825,16 @@
 inline bool MessageOptions::has_deprecated() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
-inline void MessageOptions::set_has_deprecated() {
-  _has_bits_[0] |= 0x00000004u;
-}
-inline void MessageOptions::clear_has_deprecated() {
-  _has_bits_[0] &= ~0x00000004u;
-}
 inline void MessageOptions::clear_deprecated() {
   deprecated_ = false;
-  clear_has_deprecated();
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline bool MessageOptions::deprecated() const {
   // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.deprecated)
   return deprecated_;
 }
 inline void MessageOptions::set_deprecated(bool value) {
-  set_has_deprecated();
+  _has_bits_[0] |= 0x00000004u;
   deprecated_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated)
 }
@@ -10237,22 +9843,16 @@
 inline bool MessageOptions::has_map_entry() const {
   return (_has_bits_[0] & 0x00000008u) != 0;
 }
-inline void MessageOptions::set_has_map_entry() {
-  _has_bits_[0] |= 0x00000008u;
-}
-inline void MessageOptions::clear_has_map_entry() {
-  _has_bits_[0] &= ~0x00000008u;
-}
 inline void MessageOptions::clear_map_entry() {
   map_entry_ = false;
-  clear_has_map_entry();
+  _has_bits_[0] &= ~0x00000008u;
 }
 inline bool MessageOptions::map_entry() const {
   // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.map_entry)
   return map_entry_;
 }
 inline void MessageOptions::set_map_entry(bool value) {
-  set_has_map_entry();
+  _has_bits_[0] |= 0x00000008u;
   map_entry_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.map_entry)
 }
@@ -10295,15 +9895,9 @@
 inline bool FieldOptions::has_ctype() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void FieldOptions::set_has_ctype() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void FieldOptions::clear_has_ctype() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void FieldOptions::clear_ctype() {
   ctype_ = 0;
-  clear_has_ctype();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.ctype)
@@ -10311,7 +9905,7 @@
 }
 inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) {
   assert(::google::protobuf::FieldOptions_CType_IsValid(value));
-  set_has_ctype();
+  _has_bits_[0] |= 0x00000001u;
   ctype_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.ctype)
 }
@@ -10320,22 +9914,16 @@
 inline bool FieldOptions::has_packed() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void FieldOptions::set_has_packed() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void FieldOptions::clear_has_packed() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void FieldOptions::clear_packed() {
   packed_ = false;
-  clear_has_packed();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline bool FieldOptions::packed() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.packed)
   return packed_;
 }
 inline void FieldOptions::set_packed(bool value) {
-  set_has_packed();
+  _has_bits_[0] |= 0x00000002u;
   packed_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.packed)
 }
@@ -10344,15 +9932,9 @@
 inline bool FieldOptions::has_jstype() const {
   return (_has_bits_[0] & 0x00000020u) != 0;
 }
-inline void FieldOptions::set_has_jstype() {
-  _has_bits_[0] |= 0x00000020u;
-}
-inline void FieldOptions::clear_has_jstype() {
-  _has_bits_[0] &= ~0x00000020u;
-}
 inline void FieldOptions::clear_jstype() {
   jstype_ = 0;
-  clear_has_jstype();
+  _has_bits_[0] &= ~0x00000020u;
 }
 inline ::google::protobuf::FieldOptions_JSType FieldOptions::jstype() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.jstype)
@@ -10360,7 +9942,7 @@
 }
 inline void FieldOptions::set_jstype(::google::protobuf::FieldOptions_JSType value) {
   assert(::google::protobuf::FieldOptions_JSType_IsValid(value));
-  set_has_jstype();
+  _has_bits_[0] |= 0x00000020u;
   jstype_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.jstype)
 }
@@ -10369,22 +9951,16 @@
 inline bool FieldOptions::has_lazy() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
-inline void FieldOptions::set_has_lazy() {
-  _has_bits_[0] |= 0x00000004u;
-}
-inline void FieldOptions::clear_has_lazy() {
-  _has_bits_[0] &= ~0x00000004u;
-}
 inline void FieldOptions::clear_lazy() {
   lazy_ = false;
-  clear_has_lazy();
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline bool FieldOptions::lazy() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.lazy)
   return lazy_;
 }
 inline void FieldOptions::set_lazy(bool value) {
-  set_has_lazy();
+  _has_bits_[0] |= 0x00000004u;
   lazy_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.lazy)
 }
@@ -10393,22 +9969,16 @@
 inline bool FieldOptions::has_deprecated() const {
   return (_has_bits_[0] & 0x00000008u) != 0;
 }
-inline void FieldOptions::set_has_deprecated() {
-  _has_bits_[0] |= 0x00000008u;
-}
-inline void FieldOptions::clear_has_deprecated() {
-  _has_bits_[0] &= ~0x00000008u;
-}
 inline void FieldOptions::clear_deprecated() {
   deprecated_ = false;
-  clear_has_deprecated();
+  _has_bits_[0] &= ~0x00000008u;
 }
 inline bool FieldOptions::deprecated() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.deprecated)
   return deprecated_;
 }
 inline void FieldOptions::set_deprecated(bool value) {
-  set_has_deprecated();
+  _has_bits_[0] |= 0x00000008u;
   deprecated_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.deprecated)
 }
@@ -10417,22 +9987,16 @@
 inline bool FieldOptions::has_weak() const {
   return (_has_bits_[0] & 0x00000010u) != 0;
 }
-inline void FieldOptions::set_has_weak() {
-  _has_bits_[0] |= 0x00000010u;
-}
-inline void FieldOptions::clear_has_weak() {
-  _has_bits_[0] &= ~0x00000010u;
-}
 inline void FieldOptions::clear_weak() {
   weak_ = false;
-  clear_has_weak();
+  _has_bits_[0] &= ~0x00000010u;
 }
 inline bool FieldOptions::weak() const {
   // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.weak)
   return weak_;
 }
 inline void FieldOptions::set_weak(bool value) {
-  set_has_weak();
+  _has_bits_[0] |= 0x00000010u;
   weak_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.weak)
 }
@@ -10509,22 +10073,16 @@
 inline bool EnumOptions::has_allow_alias() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void EnumOptions::set_has_allow_alias() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void EnumOptions::clear_has_allow_alias() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void EnumOptions::clear_allow_alias() {
   allow_alias_ = false;
-  clear_has_allow_alias();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline bool EnumOptions::allow_alias() const {
   // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.allow_alias)
   return allow_alias_;
 }
 inline void EnumOptions::set_allow_alias(bool value) {
-  set_has_allow_alias();
+  _has_bits_[0] |= 0x00000001u;
   allow_alias_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.allow_alias)
 }
@@ -10533,22 +10091,16 @@
 inline bool EnumOptions::has_deprecated() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void EnumOptions::set_has_deprecated() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void EnumOptions::clear_has_deprecated() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void EnumOptions::clear_deprecated() {
   deprecated_ = false;
-  clear_has_deprecated();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline bool EnumOptions::deprecated() const {
   // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.deprecated)
   return deprecated_;
 }
 inline void EnumOptions::set_deprecated(bool value) {
-  set_has_deprecated();
+  _has_bits_[0] |= 0x00000002u;
   deprecated_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated)
 }
@@ -10591,22 +10143,16 @@
 inline bool EnumValueOptions::has_deprecated() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void EnumValueOptions::set_has_deprecated() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void EnumValueOptions::clear_has_deprecated() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void EnumValueOptions::clear_deprecated() {
   deprecated_ = false;
-  clear_has_deprecated();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline bool EnumValueOptions::deprecated() const {
   // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.deprecated)
   return deprecated_;
 }
 inline void EnumValueOptions::set_deprecated(bool value) {
-  set_has_deprecated();
+  _has_bits_[0] |= 0x00000001u;
   deprecated_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.EnumValueOptions.deprecated)
 }
@@ -10649,22 +10195,16 @@
 inline bool ServiceOptions::has_deprecated() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void ServiceOptions::set_has_deprecated() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void ServiceOptions::clear_has_deprecated() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void ServiceOptions::clear_deprecated() {
   deprecated_ = false;
-  clear_has_deprecated();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline bool ServiceOptions::deprecated() const {
   // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.deprecated)
   return deprecated_;
 }
 inline void ServiceOptions::set_deprecated(bool value) {
-  set_has_deprecated();
+  _has_bits_[0] |= 0x00000001u;
   deprecated_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.ServiceOptions.deprecated)
 }
@@ -10707,22 +10247,16 @@
 inline bool MethodOptions::has_deprecated() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void MethodOptions::set_has_deprecated() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void MethodOptions::clear_has_deprecated() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void MethodOptions::clear_deprecated() {
   deprecated_ = false;
-  clear_has_deprecated();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline bool MethodOptions::deprecated() const {
   // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.deprecated)
   return deprecated_;
 }
 inline void MethodOptions::set_deprecated(bool value) {
-  set_has_deprecated();
+  _has_bits_[0] |= 0x00000001u;
   deprecated_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.deprecated)
 }
@@ -10731,15 +10265,9 @@
 inline bool MethodOptions::has_idempotency_level() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void MethodOptions::set_has_idempotency_level() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void MethodOptions::clear_has_idempotency_level() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void MethodOptions::clear_idempotency_level() {
   idempotency_level_ = 0;
-  clear_has_idempotency_level();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline ::google::protobuf::MethodOptions_IdempotencyLevel MethodOptions::idempotency_level() const {
   // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.idempotency_level)
@@ -10747,7 +10275,7 @@
 }
 inline void MethodOptions::set_idempotency_level(::google::protobuf::MethodOptions_IdempotencyLevel value) {
   assert(::google::protobuf::MethodOptions_IdempotencyLevel_IsValid(value));
-  set_has_idempotency_level();
+  _has_bits_[0] |= 0x00000002u;
   idempotency_level_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.idempotency_level)
 }
@@ -10790,28 +10318,22 @@
 inline bool UninterpretedOption_NamePart::has_name_part() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void UninterpretedOption_NamePart::set_has_name_part() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void UninterpretedOption_NamePart::clear_has_name_part() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void UninterpretedOption_NamePart::clear_name_part() {
   name_part_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_name_part();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& UninterpretedOption_NamePart::name_part() const {
   // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.name_part)
   return name_part_.Get();
 }
 inline void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) {
-  set_has_name_part();
+  _has_bits_[0] |= 0x00000001u;
   name_part_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.name_part)
 }
 #if LANG_CXX11
 inline void UninterpretedOption_NamePart::set_name_part(::std::string&& value) {
-  set_has_name_part();
+  _has_bits_[0] |= 0x00000001u;
   name_part_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.UninterpretedOption.NamePart.name_part)
@@ -10819,20 +10341,20 @@
 #endif
 inline void UninterpretedOption_NamePart::set_name_part(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_name_part();
+  _has_bits_[0] |= 0x00000001u;
   name_part_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.NamePart.name_part)
 }
 inline void UninterpretedOption_NamePart::set_name_part(const char* value,
     size_t size) {
-  set_has_name_part();
+  _has_bits_[0] |= 0x00000001u;
   name_part_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.NamePart.name_part)
 }
 inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() {
-  set_has_name_part();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.NamePart.name_part)
   return name_part_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -10841,14 +10363,14 @@
   if (!has_name_part()) {
     return NULL;
   }
-  clear_has_name_part();
+  _has_bits_[0] &= ~0x00000001u;
   return name_part_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void UninterpretedOption_NamePart::set_allocated_name_part(::std::string* name_part) {
   if (name_part != NULL) {
-    set_has_name_part();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name_part();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_part_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name_part,
       GetArenaNoVirtual());
@@ -10857,7 +10379,7 @@
 inline ::std::string* UninterpretedOption_NamePart::unsafe_arena_release_name_part() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.UninterpretedOption.NamePart.name_part)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_name_part();
+  _has_bits_[0] &= ~0x00000001u;
   return name_part_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -10865,9 +10387,9 @@
     ::std::string* name_part) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (name_part != NULL) {
-    set_has_name_part();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_name_part();
+    _has_bits_[0] &= ~0x00000001u;
   }
   name_part_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       name_part, GetArenaNoVirtual());
@@ -10878,22 +10400,16 @@
 inline bool UninterpretedOption_NamePart::has_is_extension() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void UninterpretedOption_NamePart::set_has_is_extension() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void UninterpretedOption_NamePart::clear_has_is_extension() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void UninterpretedOption_NamePart::clear_is_extension() {
   is_extension_ = false;
-  clear_has_is_extension();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline bool UninterpretedOption_NamePart::is_extension() const {
   // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.is_extension)
   return is_extension_;
 }
 inline void UninterpretedOption_NamePart::set_is_extension(bool value) {
-  set_has_is_extension();
+  _has_bits_[0] |= 0x00000002u;
   is_extension_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.is_extension)
 }
@@ -10936,28 +10452,22 @@
 inline bool UninterpretedOption::has_identifier_value() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void UninterpretedOption::set_has_identifier_value() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void UninterpretedOption::clear_has_identifier_value() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void UninterpretedOption::clear_identifier_value() {
   identifier_value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_identifier_value();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& UninterpretedOption::identifier_value() const {
   // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.identifier_value)
   return identifier_value_.Get();
 }
 inline void UninterpretedOption::set_identifier_value(const ::std::string& value) {
-  set_has_identifier_value();
+  _has_bits_[0] |= 0x00000001u;
   identifier_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.identifier_value)
 }
 #if LANG_CXX11
 inline void UninterpretedOption::set_identifier_value(::std::string&& value) {
-  set_has_identifier_value();
+  _has_bits_[0] |= 0x00000001u;
   identifier_value_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.UninterpretedOption.identifier_value)
@@ -10965,20 +10475,20 @@
 #endif
 inline void UninterpretedOption::set_identifier_value(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_identifier_value();
+  _has_bits_[0] |= 0x00000001u;
   identifier_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.identifier_value)
 }
 inline void UninterpretedOption::set_identifier_value(const char* value,
     size_t size) {
-  set_has_identifier_value();
+  _has_bits_[0] |= 0x00000001u;
   identifier_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.identifier_value)
 }
 inline ::std::string* UninterpretedOption::mutable_identifier_value() {
-  set_has_identifier_value();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.identifier_value)
   return identifier_value_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -10987,14 +10497,14 @@
   if (!has_identifier_value()) {
     return NULL;
   }
-  clear_has_identifier_value();
+  _has_bits_[0] &= ~0x00000001u;
   return identifier_value_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void UninterpretedOption::set_allocated_identifier_value(::std::string* identifier_value) {
   if (identifier_value != NULL) {
-    set_has_identifier_value();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_identifier_value();
+    _has_bits_[0] &= ~0x00000001u;
   }
   identifier_value_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), identifier_value,
       GetArenaNoVirtual());
@@ -11003,7 +10513,7 @@
 inline ::std::string* UninterpretedOption::unsafe_arena_release_identifier_value() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.UninterpretedOption.identifier_value)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_identifier_value();
+  _has_bits_[0] &= ~0x00000001u;
   return identifier_value_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -11011,9 +10521,9 @@
     ::std::string* identifier_value) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (identifier_value != NULL) {
-    set_has_identifier_value();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_identifier_value();
+    _has_bits_[0] &= ~0x00000001u;
   }
   identifier_value_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       identifier_value, GetArenaNoVirtual());
@@ -11024,22 +10534,16 @@
 inline bool UninterpretedOption::has_positive_int_value() const {
   return (_has_bits_[0] & 0x00000008u) != 0;
 }
-inline void UninterpretedOption::set_has_positive_int_value() {
-  _has_bits_[0] |= 0x00000008u;
-}
-inline void UninterpretedOption::clear_has_positive_int_value() {
-  _has_bits_[0] &= ~0x00000008u;
-}
 inline void UninterpretedOption::clear_positive_int_value() {
-  positive_int_value_ = GOOGLE_ULONGLONG(0);
-  clear_has_positive_int_value();
+  positive_int_value_ = GOOGLE_PROTOBUF_ULONGLONG(0);
+  _has_bits_[0] &= ~0x00000008u;
 }
 inline ::google::protobuf::uint64 UninterpretedOption::positive_int_value() const {
   // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.positive_int_value)
   return positive_int_value_;
 }
 inline void UninterpretedOption::set_positive_int_value(::google::protobuf::uint64 value) {
-  set_has_positive_int_value();
+  _has_bits_[0] |= 0x00000008u;
   positive_int_value_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.positive_int_value)
 }
@@ -11048,22 +10552,16 @@
 inline bool UninterpretedOption::has_negative_int_value() const {
   return (_has_bits_[0] & 0x00000010u) != 0;
 }
-inline void UninterpretedOption::set_has_negative_int_value() {
-  _has_bits_[0] |= 0x00000010u;
-}
-inline void UninterpretedOption::clear_has_negative_int_value() {
-  _has_bits_[0] &= ~0x00000010u;
-}
 inline void UninterpretedOption::clear_negative_int_value() {
-  negative_int_value_ = GOOGLE_LONGLONG(0);
-  clear_has_negative_int_value();
+  negative_int_value_ = GOOGLE_PROTOBUF_LONGLONG(0);
+  _has_bits_[0] &= ~0x00000010u;
 }
 inline ::google::protobuf::int64 UninterpretedOption::negative_int_value() const {
   // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.negative_int_value)
   return negative_int_value_;
 }
 inline void UninterpretedOption::set_negative_int_value(::google::protobuf::int64 value) {
-  set_has_negative_int_value();
+  _has_bits_[0] |= 0x00000010u;
   negative_int_value_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.negative_int_value)
 }
@@ -11072,22 +10570,16 @@
 inline bool UninterpretedOption::has_double_value() const {
   return (_has_bits_[0] & 0x00000020u) != 0;
 }
-inline void UninterpretedOption::set_has_double_value() {
-  _has_bits_[0] |= 0x00000020u;
-}
-inline void UninterpretedOption::clear_has_double_value() {
-  _has_bits_[0] &= ~0x00000020u;
-}
 inline void UninterpretedOption::clear_double_value() {
   double_value_ = 0;
-  clear_has_double_value();
+  _has_bits_[0] &= ~0x00000020u;
 }
 inline double UninterpretedOption::double_value() const {
   // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.double_value)
   return double_value_;
 }
 inline void UninterpretedOption::set_double_value(double value) {
-  set_has_double_value();
+  _has_bits_[0] |= 0x00000020u;
   double_value_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.double_value)
 }
@@ -11096,28 +10588,22 @@
 inline bool UninterpretedOption::has_string_value() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void UninterpretedOption::set_has_string_value() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void UninterpretedOption::clear_has_string_value() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void UninterpretedOption::clear_string_value() {
   string_value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_string_value();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::std::string& UninterpretedOption::string_value() const {
   // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.string_value)
   return string_value_.Get();
 }
 inline void UninterpretedOption::set_string_value(const ::std::string& value) {
-  set_has_string_value();
+  _has_bits_[0] |= 0x00000002u;
   string_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.string_value)
 }
 #if LANG_CXX11
 inline void UninterpretedOption::set_string_value(::std::string&& value) {
-  set_has_string_value();
+  _has_bits_[0] |= 0x00000002u;
   string_value_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.UninterpretedOption.string_value)
@@ -11125,20 +10611,20 @@
 #endif
 inline void UninterpretedOption::set_string_value(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_string_value();
+  _has_bits_[0] |= 0x00000002u;
   string_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.string_value)
 }
 inline void UninterpretedOption::set_string_value(const void* value,
     size_t size) {
-  set_has_string_value();
+  _has_bits_[0] |= 0x00000002u;
   string_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.string_value)
 }
 inline ::std::string* UninterpretedOption::mutable_string_value() {
-  set_has_string_value();
+  _has_bits_[0] |= 0x00000002u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.string_value)
   return string_value_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -11147,14 +10633,14 @@
   if (!has_string_value()) {
     return NULL;
   }
-  clear_has_string_value();
+  _has_bits_[0] &= ~0x00000002u;
   return string_value_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void UninterpretedOption::set_allocated_string_value(::std::string* string_value) {
   if (string_value != NULL) {
-    set_has_string_value();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_string_value();
+    _has_bits_[0] &= ~0x00000002u;
   }
   string_value_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), string_value,
       GetArenaNoVirtual());
@@ -11163,7 +10649,7 @@
 inline ::std::string* UninterpretedOption::unsafe_arena_release_string_value() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.UninterpretedOption.string_value)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_string_value();
+  _has_bits_[0] &= ~0x00000002u;
   return string_value_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -11171,9 +10657,9 @@
     ::std::string* string_value) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (string_value != NULL) {
-    set_has_string_value();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_string_value();
+    _has_bits_[0] &= ~0x00000002u;
   }
   string_value_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       string_value, GetArenaNoVirtual());
@@ -11184,28 +10670,22 @@
 inline bool UninterpretedOption::has_aggregate_value() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
-inline void UninterpretedOption::set_has_aggregate_value() {
-  _has_bits_[0] |= 0x00000004u;
-}
-inline void UninterpretedOption::clear_has_aggregate_value() {
-  _has_bits_[0] &= ~0x00000004u;
-}
 inline void UninterpretedOption::clear_aggregate_value() {
   aggregate_value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_aggregate_value();
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline const ::std::string& UninterpretedOption::aggregate_value() const {
   // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.aggregate_value)
   return aggregate_value_.Get();
 }
 inline void UninterpretedOption::set_aggregate_value(const ::std::string& value) {
-  set_has_aggregate_value();
+  _has_bits_[0] |= 0x00000004u;
   aggregate_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.aggregate_value)
 }
 #if LANG_CXX11
 inline void UninterpretedOption::set_aggregate_value(::std::string&& value) {
-  set_has_aggregate_value();
+  _has_bits_[0] |= 0x00000004u;
   aggregate_value_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.UninterpretedOption.aggregate_value)
@@ -11213,20 +10693,20 @@
 #endif
 inline void UninterpretedOption::set_aggregate_value(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_aggregate_value();
+  _has_bits_[0] |= 0x00000004u;
   aggregate_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.aggregate_value)
 }
 inline void UninterpretedOption::set_aggregate_value(const char* value,
     size_t size) {
-  set_has_aggregate_value();
+  _has_bits_[0] |= 0x00000004u;
   aggregate_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.aggregate_value)
 }
 inline ::std::string* UninterpretedOption::mutable_aggregate_value() {
-  set_has_aggregate_value();
+  _has_bits_[0] |= 0x00000004u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.aggregate_value)
   return aggregate_value_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -11235,14 +10715,14 @@
   if (!has_aggregate_value()) {
     return NULL;
   }
-  clear_has_aggregate_value();
+  _has_bits_[0] &= ~0x00000004u;
   return aggregate_value_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void UninterpretedOption::set_allocated_aggregate_value(::std::string* aggregate_value) {
   if (aggregate_value != NULL) {
-    set_has_aggregate_value();
+    _has_bits_[0] |= 0x00000004u;
   } else {
-    clear_has_aggregate_value();
+    _has_bits_[0] &= ~0x00000004u;
   }
   aggregate_value_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), aggregate_value,
       GetArenaNoVirtual());
@@ -11251,7 +10731,7 @@
 inline ::std::string* UninterpretedOption::unsafe_arena_release_aggregate_value() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.UninterpretedOption.aggregate_value)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_aggregate_value();
+  _has_bits_[0] &= ~0x00000004u;
   return aggregate_value_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -11259,9 +10739,9 @@
     ::std::string* aggregate_value) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (aggregate_value != NULL) {
-    set_has_aggregate_value();
+    _has_bits_[0] |= 0x00000004u;
   } else {
-    clear_has_aggregate_value();
+    _has_bits_[0] &= ~0x00000004u;
   }
   aggregate_value_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       aggregate_value, GetArenaNoVirtual());
@@ -11336,28 +10816,22 @@
 inline bool SourceCodeInfo_Location::has_leading_comments() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void SourceCodeInfo_Location::set_has_leading_comments() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void SourceCodeInfo_Location::clear_has_leading_comments() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void SourceCodeInfo_Location::clear_leading_comments() {
   leading_comments_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_leading_comments();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& SourceCodeInfo_Location::leading_comments() const {
   // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_comments)
   return leading_comments_.Get();
 }
 inline void SourceCodeInfo_Location::set_leading_comments(const ::std::string& value) {
-  set_has_leading_comments();
+  _has_bits_[0] |= 0x00000001u;
   leading_comments_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_comments)
 }
 #if LANG_CXX11
 inline void SourceCodeInfo_Location::set_leading_comments(::std::string&& value) {
-  set_has_leading_comments();
+  _has_bits_[0] |= 0x00000001u;
   leading_comments_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.SourceCodeInfo.Location.leading_comments)
@@ -11365,20 +10839,20 @@
 #endif
 inline void SourceCodeInfo_Location::set_leading_comments(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_leading_comments();
+  _has_bits_[0] |= 0x00000001u;
   leading_comments_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_comments)
 }
 inline void SourceCodeInfo_Location::set_leading_comments(const char* value,
     size_t size) {
-  set_has_leading_comments();
+  _has_bits_[0] |= 0x00000001u;
   leading_comments_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_comments)
 }
 inline ::std::string* SourceCodeInfo_Location::mutable_leading_comments() {
-  set_has_leading_comments();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_comments)
   return leading_comments_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -11387,14 +10861,14 @@
   if (!has_leading_comments()) {
     return NULL;
   }
-  clear_has_leading_comments();
+  _has_bits_[0] &= ~0x00000001u;
   return leading_comments_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void SourceCodeInfo_Location::set_allocated_leading_comments(::std::string* leading_comments) {
   if (leading_comments != NULL) {
-    set_has_leading_comments();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_leading_comments();
+    _has_bits_[0] &= ~0x00000001u;
   }
   leading_comments_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), leading_comments,
       GetArenaNoVirtual());
@@ -11403,7 +10877,7 @@
 inline ::std::string* SourceCodeInfo_Location::unsafe_arena_release_leading_comments() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.SourceCodeInfo.Location.leading_comments)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_leading_comments();
+  _has_bits_[0] &= ~0x00000001u;
   return leading_comments_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -11411,9 +10885,9 @@
     ::std::string* leading_comments) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (leading_comments != NULL) {
-    set_has_leading_comments();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_leading_comments();
+    _has_bits_[0] &= ~0x00000001u;
   }
   leading_comments_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       leading_comments, GetArenaNoVirtual());
@@ -11424,28 +10898,22 @@
 inline bool SourceCodeInfo_Location::has_trailing_comments() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void SourceCodeInfo_Location::set_has_trailing_comments() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void SourceCodeInfo_Location::clear_has_trailing_comments() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void SourceCodeInfo_Location::clear_trailing_comments() {
   trailing_comments_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_trailing_comments();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline const ::std::string& SourceCodeInfo_Location::trailing_comments() const {
   // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.trailing_comments)
   return trailing_comments_.Get();
 }
 inline void SourceCodeInfo_Location::set_trailing_comments(const ::std::string& value) {
-  set_has_trailing_comments();
+  _has_bits_[0] |= 0x00000002u;
   trailing_comments_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.trailing_comments)
 }
 #if LANG_CXX11
 inline void SourceCodeInfo_Location::set_trailing_comments(::std::string&& value) {
-  set_has_trailing_comments();
+  _has_bits_[0] |= 0x00000002u;
   trailing_comments_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.SourceCodeInfo.Location.trailing_comments)
@@ -11453,20 +10921,20 @@
 #endif
 inline void SourceCodeInfo_Location::set_trailing_comments(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_trailing_comments();
+  _has_bits_[0] |= 0x00000002u;
   trailing_comments_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.trailing_comments)
 }
 inline void SourceCodeInfo_Location::set_trailing_comments(const char* value,
     size_t size) {
-  set_has_trailing_comments();
+  _has_bits_[0] |= 0x00000002u;
   trailing_comments_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.trailing_comments)
 }
 inline ::std::string* SourceCodeInfo_Location::mutable_trailing_comments() {
-  set_has_trailing_comments();
+  _has_bits_[0] |= 0x00000002u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.trailing_comments)
   return trailing_comments_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -11475,14 +10943,14 @@
   if (!has_trailing_comments()) {
     return NULL;
   }
-  clear_has_trailing_comments();
+  _has_bits_[0] &= ~0x00000002u;
   return trailing_comments_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void SourceCodeInfo_Location::set_allocated_trailing_comments(::std::string* trailing_comments) {
   if (trailing_comments != NULL) {
-    set_has_trailing_comments();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_trailing_comments();
+    _has_bits_[0] &= ~0x00000002u;
   }
   trailing_comments_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), trailing_comments,
       GetArenaNoVirtual());
@@ -11491,7 +10959,7 @@
 inline ::std::string* SourceCodeInfo_Location::unsafe_arena_release_trailing_comments() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.SourceCodeInfo.Location.trailing_comments)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_trailing_comments();
+  _has_bits_[0] &= ~0x00000002u;
   return trailing_comments_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -11499,9 +10967,9 @@
     ::std::string* trailing_comments) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (trailing_comments != NULL) {
-    set_has_trailing_comments();
+    _has_bits_[0] |= 0x00000002u;
   } else {
-    clear_has_trailing_comments();
+    _has_bits_[0] &= ~0x00000002u;
   }
   trailing_comments_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       trailing_comments, GetArenaNoVirtual());
@@ -11566,12 +11034,12 @@
   leading_detached_comments_.Add()->assign(reinterpret_cast<const char*>(value), size);
   // @@protoc_insertion_point(field_add_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
 }
-inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+inline const ::google::protobuf::RepeatedPtrField<::std::string>&
 SourceCodeInfo_Location::leading_detached_comments() const {
   // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
   return leading_detached_comments_;
 }
-inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+inline ::google::protobuf::RepeatedPtrField<::std::string>*
 SourceCodeInfo_Location::mutable_leading_detached_comments() {
   // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
   return &leading_detached_comments_;
@@ -11649,28 +11117,22 @@
 inline bool GeneratedCodeInfo_Annotation::has_source_file() const {
   return (_has_bits_[0] & 0x00000001u) != 0;
 }
-inline void GeneratedCodeInfo_Annotation::set_has_source_file() {
-  _has_bits_[0] |= 0x00000001u;
-}
-inline void GeneratedCodeInfo_Annotation::clear_has_source_file() {
-  _has_bits_[0] &= ~0x00000001u;
-}
 inline void GeneratedCodeInfo_Annotation::clear_source_file() {
   source_file_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
-  clear_has_source_file();
+  _has_bits_[0] &= ~0x00000001u;
 }
 inline const ::std::string& GeneratedCodeInfo_Annotation::source_file() const {
   // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
   return source_file_.Get();
 }
 inline void GeneratedCodeInfo_Annotation::set_source_file(const ::std::string& value) {
-  set_has_source_file();
+  _has_bits_[0] |= 0x00000001u;
   source_file_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
 }
 #if LANG_CXX11
 inline void GeneratedCodeInfo_Annotation::set_source_file(::std::string&& value) {
-  set_has_source_file();
+  _has_bits_[0] |= 0x00000001u;
   source_file_.Set(
     &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_rvalue:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
@@ -11678,20 +11140,20 @@
 #endif
 inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value) {
   GOOGLE_DCHECK(value != NULL);
-  set_has_source_file();
+  _has_bits_[0] |= 0x00000001u;
   source_file_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
               GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_char:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
 }
 inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value,
     size_t size) {
-  set_has_source_file();
+  _has_bits_[0] |= 0x00000001u;
   source_file_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
       reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
   // @@protoc_insertion_point(field_set_pointer:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
 }
 inline ::std::string* GeneratedCodeInfo_Annotation::mutable_source_file() {
-  set_has_source_file();
+  _has_bits_[0] |= 0x00000001u;
   // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
   return source_file_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
@@ -11700,14 +11162,14 @@
   if (!has_source_file()) {
     return NULL;
   }
-  clear_has_source_file();
+  _has_bits_[0] &= ~0x00000001u;
   return source_file_.ReleaseNonDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
 }
 inline void GeneratedCodeInfo_Annotation::set_allocated_source_file(::std::string* source_file) {
   if (source_file != NULL) {
-    set_has_source_file();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_source_file();
+    _has_bits_[0] &= ~0x00000001u;
   }
   source_file_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), source_file,
       GetArenaNoVirtual());
@@ -11716,7 +11178,7 @@
 inline ::std::string* GeneratedCodeInfo_Annotation::unsafe_arena_release_source_file() {
   // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
-  clear_has_source_file();
+  _has_bits_[0] &= ~0x00000001u;
   return source_file_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       GetArenaNoVirtual());
 }
@@ -11724,9 +11186,9 @@
     ::std::string* source_file) {
   GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
   if (source_file != NULL) {
-    set_has_source_file();
+    _has_bits_[0] |= 0x00000001u;
   } else {
-    clear_has_source_file();
+    _has_bits_[0] &= ~0x00000001u;
   }
   source_file_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
       source_file, GetArenaNoVirtual());
@@ -11737,22 +11199,16 @@
 inline bool GeneratedCodeInfo_Annotation::has_begin() const {
   return (_has_bits_[0] & 0x00000002u) != 0;
 }
-inline void GeneratedCodeInfo_Annotation::set_has_begin() {
-  _has_bits_[0] |= 0x00000002u;
-}
-inline void GeneratedCodeInfo_Annotation::clear_has_begin() {
-  _has_bits_[0] &= ~0x00000002u;
-}
 inline void GeneratedCodeInfo_Annotation::clear_begin() {
   begin_ = 0;
-  clear_has_begin();
+  _has_bits_[0] &= ~0x00000002u;
 }
 inline ::google::protobuf::int32 GeneratedCodeInfo_Annotation::begin() const {
   // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.begin)
   return begin_;
 }
 inline void GeneratedCodeInfo_Annotation::set_begin(::google::protobuf::int32 value) {
-  set_has_begin();
+  _has_bits_[0] |= 0x00000002u;
   begin_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.begin)
 }
@@ -11761,22 +11217,16 @@
 inline bool GeneratedCodeInfo_Annotation::has_end() const {
   return (_has_bits_[0] & 0x00000004u) != 0;
 }
-inline void GeneratedCodeInfo_Annotation::set_has_end() {
-  _has_bits_[0] |= 0x00000004u;
-}
-inline void GeneratedCodeInfo_Annotation::clear_has_end() {
-  _has_bits_[0] &= ~0x00000004u;
-}
 inline void GeneratedCodeInfo_Annotation::clear_end() {
   end_ = 0;
-  clear_has_end();
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline ::google::protobuf::int32 GeneratedCodeInfo_Annotation::end() const {
   // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.end)
   return end_;
 }
 inline void GeneratedCodeInfo_Annotation::set_end(::google::protobuf::int32 value) {
-  set_has_end();
+  _has_bits_[0] |= 0x00000004u;
   end_ = value;
   // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.end)
 }
@@ -11915,4 +11365,5 @@
 
 // @@protoc_insertion_point(global_scope)
 
+#include <google/protobuf/port_undef.inc>
 #endif  // PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto
diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc
index ba85ef1..1f5ba48 100644
--- a/src/google/protobuf/descriptor_database.cc
+++ b/src/google/protobuf/descriptor_database.cc
@@ -214,6 +214,17 @@
 }
 
 template <typename Value>
+void SimpleDescriptorDatabase::DescriptorIndex<Value>::FindAllFileNames(
+    std::vector<string>* output) {
+  output->resize(by_name_.size());
+  int i = 0;
+  for (const auto& kv : by_name_) {
+    (*output)[i] = kv.first;
+    i++;
+  }
+}
+
+template <typename Value>
 typename std::map<string, Value>::iterator
 SimpleDescriptorDatabase::DescriptorIndex<Value>::FindLastLessOrEqual(
     const string& name) {
@@ -293,6 +304,11 @@
 }
 
 
+bool SimpleDescriptorDatabase::FindAllFileNames(std::vector<string>* output) {
+  index_.FindAllFileNames(output);
+  return true;
+}
+
 bool SimpleDescriptorDatabase::MaybeCopy(const FileDescriptorProto* file,
                                          FileDescriptorProto* output) {
   if (file == NULL) return false;
diff --git a/src/google/protobuf/descriptor_database.h b/src/google/protobuf/descriptor_database.h
index 0752366..0a87a14 100644
--- a/src/google/protobuf/descriptor_database.h
+++ b/src/google/protobuf/descriptor_database.h
@@ -164,6 +164,8 @@
   bool FindAllExtensionNumbers(const string& extendee_type,
                                std::vector<int>* output) override;
 
+  bool FindAllFileNames(std::vector<string>* output) override;
+
  private:
   // So that it can use DescriptorIndex.
   friend class EncodedDescriptorDatabase;
@@ -188,6 +190,7 @@
     Value FindExtension(const string& containing_type, int field_number);
     bool FindAllExtensionNumbers(const string& containing_type,
                                  std::vector<int>* output);
+    void FindAllFileNames(std::vector<string>* output);
 
    private:
     std::map<string, Value> by_name_;
@@ -378,6 +381,6 @@
 };
 
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
diff --git a/src/google/protobuf/descriptor_database_unittest.cc b/src/google/protobuf/descriptor_database_unittest.cc
index 083ef8f..7d3f17c 100644
--- a/src/google/protobuf/descriptor_database_unittest.cc
+++ b/src/google/protobuf/descriptor_database_unittest.cc
@@ -44,6 +44,7 @@
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
+#include <gmock/gmock.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 
@@ -77,7 +78,7 @@
 // three nearly-identical sets of tests, we use parameterized tests to apply
 // the same code to all three.
 
-// The parameterized test runs against a DescriptarDatabaseTestCase.  We have
+// The parameterized test runs against a DescriptorDatabaseTestCase.  We have
 // implementations for each of the three classes we want to test.
 class DescriptorDatabaseTestCase {
  public:
@@ -519,6 +520,21 @@
   EXPECT_FALSE(db.FindNameOfFileContainingSymbol("baz.Baz", &filename));
 }
 
+TEST(SimpleDescriptorDatabaseExtraTest, FindAllFileNames) {
+  FileDescriptorProto f;
+  f.set_name("foo.proto");
+  f.set_package("foo");
+  f.add_message_type()->set_name("Foo");
+
+  SimpleDescriptorDatabase db;
+  db.Add(f);
+
+  // Test!
+  std::vector<string> all_files;
+  db.FindAllFileNames(&all_files);
+  EXPECT_THAT(all_files, testing::ElementsAre("foo.proto"));
+}
+
 // ===================================================================
 
 class MergedDescriptorDatabaseTest : public testing::Test {
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index 54da095..0d16078 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -57,6 +57,7 @@
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 
@@ -512,7 +513,7 @@
   debug_strings->push_back(std::make_pair(file->name(), file->DebugString()));
 }
 
-class SimpleErrorCollector : public google::protobuf::io::ErrorCollector {
+class SimpleErrorCollector : public io::ErrorCollector {
  public:
   // implements ErrorCollector ---------------------------------------
   void AddError(int line, int column, const string& message) {
@@ -542,10 +543,10 @@
   for (int i = 0; i < debug_strings.size(); ++i) {
     const string& name = debug_strings[i].first;
     const string& content = debug_strings[i].second;
-    google::protobuf::io::ArrayInputStream input_stream(content.data(), content.size());
+    io::ArrayInputStream input_stream(content.data(), content.size());
     SimpleErrorCollector error_collector;
-    google::protobuf::io::Tokenizer tokenizer(&input_stream, &error_collector);
-    google::protobuf::compiler::Parser parser;
+    io::Tokenizer tokenizer(&input_stream, &error_collector);
+    compiler::Parser parser;
     parser.RecordErrorsTo(&error_collector);
     FileDescriptorProto proto;
     ASSERT_TRUE(parser.Parse(&tokenizer, &proto))
@@ -3407,7 +3408,7 @@
 // Verifies that proto files can correctly be parsed, even if the
 // custom options defined in the file are incompatible with those
 // compiled in the binary. See http://b/19276250.
-TEST(CustomOptions, OptionsWithRequiredEnums) {
+TEST(CustomOptions, OptionsWithIncompatibleDescriptors) {
   DescriptorPool pool;
 
   FileDescriptorProto file_proto;
@@ -3446,38 +3447,12 @@
       "    name_part: 'required_enum_opt' "
       "    is_extension: true "
       "  } "
-      "  aggregate_value: 'value: NEW_VALUE' "
+      "  aggregate_value: 'value: NEW_VALUE'"
       "}",
       test_message_type->mutable_options()));
 
-  // Add the file descriptor to the pool.
-  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
-
-  // Find the test message.
-  const Descriptor* test_message = pool.FindMessageTypeByName(
-      "protobuf_unittest.TestMessageWithRequiredEnumOption");
-  ASSERT_TRUE(test_message != NULL);
-
-  const MessageOptions& options = test_message->options();
-  // Extract the "required_enum_opt" option. Since the binary does not
-  // know that the extension was updated, this will still return an
-  // OldOptionType message.
-  ASSERT_TRUE(
-      options.HasExtension(protobuf_unittest::required_enum_opt));
-  const protobuf_unittest::OldOptionType& old_enum_opt =
-      options.GetExtension(protobuf_unittest::required_enum_opt);
-
-  // Confirm that the required enum field is missing.
-  EXPECT_FALSE(old_enum_opt.IsInitialized());
-  EXPECT_FALSE(old_enum_opt.has_value());
-
-  string buf;
-  // Verify that the required enum field does show up when the option
-  // is re-parsed as a NewOptionType message;
-  protobuf_unittest::NewOptionType new_enum_opt;
-  EXPECT_TRUE(old_enum_opt.AppendPartialToString(&buf));
-  EXPECT_TRUE(new_enum_opt.ParseFromString(buf));
-  EXPECT_EQ(protobuf_unittest::NewOptionType::NEW_VALUE, new_enum_opt.value());
+  // Adding the file descriptor to the pool should fail.
+  EXPECT_TRUE(pool.BuildFile(file_proto) == NULL);
 }
 
 // Test that FileDescriptor::DebugString() formats custom options correctly.
@@ -5156,7 +5131,9 @@
     "                                        is_extension: false } "
     "                                 positive_int_value: 1 } }",
 
-    "qux.proto: qux.proto: OPTION_NAME: Option \"(baaz.bar)\" unknown.\n");
+    "qux.proto: qux.proto: OPTION_NAME: Option \"(baaz.bar)\" unknown. Ensure "
+    "that your proto definition file imports the proto which defines the "
+    "option.\n");
 }
 
 TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) {
@@ -5429,6 +5406,26 @@
     "string option \"foo\".\n");
 }
 
+TEST_F(ValidationErrorTest, JsonNameOptionOnExtensions) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "package: \"foo\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  extension_range { start: 10 end: 20 }"
+    "}"
+    "extension {"
+    "  name: \"value\""
+    "  number: 10"
+    "  label: LABEL_OPTIONAL"
+    "  type: TYPE_INT32"
+    "  extendee: \"foo.Foo\""
+    "  json_name: \"myName\""
+    "}",
+    "foo.proto: foo.value: OPTION_NAME: option json_name is not allowed on "
+    "extension fields.\n");
+}
+
 TEST_F(ValidationErrorTest, DuplicateExtensionFieldNumber) {
   BuildDescriptorMessagesInTestPool();
 
@@ -6814,8 +6811,8 @@
         name.substr(name.size()- end_size, end_size) != end_with) {
       return;
     }
-    safe_strto32(name.substr(begin_size, name.size() - end_size - begin_size),
-                 file_num);
+    safe_strto32(
+        name.substr(begin_size, name.size() - end_size - begin_size), file_num);
   }
 
   bool PopulateFile(int file_num, FileDescriptorProto* output) {
@@ -6916,83 +6913,82 @@
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SingletonSourceTree);
 };
 
-const char *const kSourceLocationTestInput =
-  "syntax = \"proto2\";\n"
-  "option java_package = \"com.foo.bar\";\n"
-  "option (test_file_opt) = \"foobar\";\n"
-  "message A {\n"
-  "  option (test_msg_opt) = \"foobar\";\n"
-  "  optional int32 a = 1 [deprecated = true];\n"
-  "  message B {\n"
-  "    required double b = 1 [(test_field_opt) = \"foobar\"];\n"
-  "  }\n"
-  "  oneof c {\n"
-  "    option (test_oneof_opt) = \"foobar\";\n"
-  "    string d = 2;\n"
-  "    string e = 3;\n"
-  "    string f = 4;\n"
-  "  }\n"
-  "}\n"
-  "enum Indecision {\n"
-  "  option (test_enum_opt) = 21;\n"
-  "  option (test_enum_opt) = 42;\n"
-  "  option (test_enum_opt) = 63;\n"
-  "  YES   = 1 [(test_enumval_opt).a = 100];\n"
-  "  NO    = 2 [(test_enumval_opt) = {a:200}];\n"
-  "  MAYBE = 3;\n"
-  "}\n"
-  "service S {\n"
-  "  option (test_svc_opt) = {a:100};\n"
-  "  option (test_svc_opt) = {a:200};\n"
-  "  option (test_svc_opt) = {a:300};\n"
-  "  rpc Method(A) returns (A.B);\n"
-  // Put an empty line here to make the source location range match.
-  "\n"
-  "  rpc OtherMethod(A) returns (A) {\n"
-  "    option deprecated = true;\n"
-  "    option (test_method_opt) = \"foobar\";\n"
-  "  }\n"
-  "}\n"
-  "message MessageWithExtensions {\n"
-  "  extensions 1000 to 2000, 2001 to max [(test_ext_opt) = \"foobar\"];\n"
-  "}\n"
-  "extend MessageWithExtensions {\n"
-  "  repeated int32 int32_extension = 1001 [packed=true];\n"
-  "}\n"
-  "message C {\n"
-  "  extend MessageWithExtensions {\n"
-  "    optional C message_extension = 1002;\n"
-  "  }\n"
-  "}\n"
-  "import \"google/protobuf/descriptor.proto\";\n"
-  "extend google.protobuf.FileOptions {\n"
-  "  optional string test_file_opt = 10101;\n"
-  "}\n"
-  "extend google.protobuf.MessageOptions {\n"
-  "  optional string test_msg_opt = 10101;\n"
-  "}\n"
-  "extend google.protobuf.FieldOptions {\n"
-  "  optional string test_field_opt = 10101;\n"
-  "}\n"
-  "extend google.protobuf.EnumOptions {\n"
-  "  repeated int32 test_enum_opt = 10101;\n"
-  "}\n"
-  "extend google.protobuf.EnumValueOptions {\n"
-  "  optional A test_enumval_opt = 10101;\n"
-  "}\n"
-  "extend google.protobuf.ServiceOptions {\n"
-  "  repeated A test_svc_opt = 10101;\n"
-  "}\n"
-  "extend google.protobuf.MethodOptions {\n"
-  "  optional string test_method_opt = 10101;\n"
-  "}\n"
-  "extend google.protobuf.OneofOptions {\n"
-  "  optional string test_oneof_opt = 10101;\n"
-  "}\n"
-  "extend google.protobuf.ExtensionRangeOptions {\n"
-  "  optional string test_ext_opt = 10101;\n"
-  "}\n"
-  ;
+const char* const kSourceLocationTestInput =
+    "syntax = \"proto2\";\n"
+    "option java_package = \"com.foo.bar\";\n"
+    "option (test_file_opt) = \"foobar\";\n"
+    "message A {\n"
+    "  option (test_msg_opt) = \"foobar\";\n"
+    "  optional int32 a = 1 [deprecated = true];\n"
+    "  message B {\n"
+    "    required double b = 1 [(test_field_opt) = \"foobar\"];\n"
+    "  }\n"
+    "  oneof c {\n"
+    "    option (test_oneof_opt) = \"foobar\";\n"
+    "    string d = 2;\n"
+    "    string e = 3;\n"
+    "    string f = 4;\n"
+    "  }\n"
+    "}\n"
+    "enum Indecision {\n"
+    "  option (test_enum_opt) = 21;\n"
+    "  option (test_enum_opt) = 42;\n"
+    "  option (test_enum_opt) = 63;\n"
+    "  YES   = 1 [(test_enumval_opt).a = 100];\n"
+    "  NO    = 2 [(test_enumval_opt) = {a:200}];\n"
+    "  MAYBE = 3;\n"
+    "}\n"
+    "service S {\n"
+    "  option (test_svc_opt) = {a:100};\n"
+    "  option (test_svc_opt) = {a:200};\n"
+    "  option (test_svc_opt) = {a:300};\n"
+    "  rpc Method(A) returns (A.B);\n"
+    // Put an empty line here to make the source location range match.
+    "\n"
+    "  rpc OtherMethod(A) returns (A) {\n"
+    "    option deprecated = true;\n"
+    "    option (test_method_opt) = \"foobar\";\n"
+    "  }\n"
+    "}\n"
+    "message MessageWithExtensions {\n"
+    "  extensions 1000 to 2000, 2001 to max [(test_ext_opt) = \"foobar\"];\n"
+    "}\n"
+    "extend MessageWithExtensions {\n"
+    "  repeated int32 int32_extension = 1001 [packed=true];\n"
+    "}\n"
+    "message C {\n"
+    "  extend MessageWithExtensions {\n"
+    "    optional C message_extension = 1002;\n"
+    "  }\n"
+    "}\n"
+    "import \"google/protobuf/descriptor.proto\";\n"
+    "extend google.protobuf.FileOptions {\n"
+    "  optional string test_file_opt = 10101;\n"
+    "}\n"
+    "extend google.protobuf.MessageOptions {\n"
+    "  optional string test_msg_opt = 10101;\n"
+    "}\n"
+    "extend google.protobuf.FieldOptions {\n"
+    "  optional string test_field_opt = 10101;\n"
+    "}\n"
+    "extend google.protobuf.EnumOptions {\n"
+    "  repeated int32 test_enum_opt = 10101;\n"
+    "}\n"
+    "extend google.protobuf.EnumValueOptions {\n"
+    "  optional A test_enumval_opt = 10101;\n"
+    "}\n"
+    "extend google.protobuf.ServiceOptions {\n"
+    "  repeated A test_svc_opt = 10101;\n"
+    "}\n"
+    "extend google.protobuf.MethodOptions {\n"
+    "  optional string test_method_opt = 10101;\n"
+    "}\n"
+    "extend google.protobuf.OneofOptions {\n"
+    "  optional string test_oneof_opt = 10101;\n"
+    "}\n"
+    "extend google.protobuf.ExtensionRangeOptions {\n"
+    "  optional string test_ext_opt = 10101;\n"
+    "}\n";
 
 class SourceLocationTest : public testing::Test {
  public:
@@ -7020,9 +7016,9 @@
   FileDescriptorProto file_proto_;
   AbortingErrorCollector collector_;
   SingletonSourceTree source_tree_;
-  SimpleDescriptorDatabase simple_db_; // contains descriptor.proto
-  compiler::SourceTreeDescriptorDatabase source_tree_db_; // loads test.proto
-  MergedDescriptorDatabase merged_db_; // combines above two dbs
+  SimpleDescriptorDatabase simple_db_;  // contains descriptor.proto
+  compiler::SourceTreeDescriptorDatabase source_tree_db_;  // loads test.proto
+  MergedDescriptorDatabase merged_db_;  // combines above two dbs
 
  protected:
   DescriptorPool pool_;
@@ -7030,7 +7026,7 @@
   // tag number of all custom options in above test file
   static const int kCustomOptionFieldNumber = 10101;
   // tag number of field "a" in message type "A" in above test file
-  static const int kA_aFieldNumber = 1;
+  static const int kAFieldNumber = 1;
 };
 
 // TODO(adonovan): implement support for option fields and for
@@ -7039,7 +7035,7 @@
 TEST_F(SourceLocationTest, GetSourceLocation) {
   SourceLocation loc;
 
-  const FileDescriptor *file_desc =
+  const FileDescriptor* file_desc =
       GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
 
   const Descriptor *a_desc = file_desc->FindMessageTypeByName("A");
@@ -7071,7 +7067,7 @@
 TEST_F(SourceLocationTest, ExtensionSourceLocation) {
   SourceLocation loc;
 
-  const FileDescriptor *file_desc =
+  const FileDescriptor* file_desc =
       GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
 
   const FieldDescriptor *int32_extension_desc =
@@ -7088,7 +7084,6 @@
   EXPECT_TRUE(message_extension_desc->GetSourceLocation(&loc));
   EXPECT_EQ("44:5-44:41", PrintSourceLocation(loc));
 }
-
 TEST_F(SourceLocationTest, InterpretedOptionSourceLocation) {
   // This one's a doozy. It checks every kind of option, including
   // extension range options.
@@ -7099,16 +7094,15 @@
 
   SourceLocation loc;
 
-  const FileDescriptor *file_desc =
+  const FileDescriptor* file_desc =
       GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
 
   // File options
   {
-    int path[]  = {FileDescriptorProto::kOptionsFieldNumber,
-                   FileOptions::kJavaPackageFieldNumber};
+    int path[] = {FileDescriptorProto::kOptionsFieldNumber,
+                  FileOptions::kJavaPackageFieldNumber};
     int unint[] = {FileDescriptorProto::kOptionsFieldNumber,
-                   FileOptions::kUninterpretedOptionFieldNumber,
-                   0};
+                   FileOptions::kUninterpretedOptionFieldNumber, 0};
 
     std::vector<int> vpath(path, path + 2);
     EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
@@ -7118,11 +7112,10 @@
     EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
   }
   {
-    int path[]  = {FileDescriptorProto::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber};
+    int path[] = {FileDescriptorProto::kOptionsFieldNumber,
+                  kCustomOptionFieldNumber};
     int unint[] = {FileDescriptorProto::kOptionsFieldNumber,
-                   FileOptions::kUninterpretedOptionFieldNumber,
-                   1};
+                   FileOptions::kUninterpretedOptionFieldNumber, 1};
     std::vector<int> vpath(path, path + 2);
     EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
     EXPECT_EQ("3:1-3:35", PrintSourceLocation(loc));
@@ -7133,15 +7126,12 @@
 
   // Message option
   {
-    int path[]  = {FileDescriptorProto::kMessageTypeFieldNumber,
-                   0,
+    int path[] = {FileDescriptorProto::kMessageTypeFieldNumber, 0,
+                  DescriptorProto::kOptionsFieldNumber,
+                  kCustomOptionFieldNumber};
+    int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber, 0,
                    DescriptorProto::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber};
-    int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
-                   0,
-                   DescriptorProto::kOptionsFieldNumber,
-                   MessageOptions::kUninterpretedOptionFieldNumber,
-                   0};
+                   MessageOptions::kUninterpretedOptionFieldNumber, 0};
     std::vector<int> vpath(path, path + 4);
     EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
     EXPECT_EQ("5:3-5:36", PrintSourceLocation(loc));
@@ -7152,12 +7142,12 @@
 
   // Field option
   {
-    int path[]  = {FileDescriptorProto::kMessageTypeFieldNumber,
-                   0,
-                   DescriptorProto::kFieldFieldNumber,
-                   0,
-                   FieldDescriptorProto::kOptionsFieldNumber,
-                   FieldOptions::kDeprecatedFieldNumber};
+    int path[] = {FileDescriptorProto::kMessageTypeFieldNumber,
+                  0,
+                  DescriptorProto::kFieldFieldNumber,
+                  0,
+                  FieldDescriptorProto::kOptionsFieldNumber,
+                  FieldOptions::kDeprecatedFieldNumber};
     int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
                    0,
                    DescriptorProto::kFieldFieldNumber,
@@ -7175,14 +7165,11 @@
 
   // Nested message option
   {
-    int path[]  = {FileDescriptorProto::kMessageTypeFieldNumber,
-                   0,
-                   DescriptorProto::kNestedTypeFieldNumber,
-                   0,
-                   DescriptorProto::kFieldFieldNumber,
-                   0,
-                   FieldDescriptorProto::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber};
+    int path[] = {
+        FileDescriptorProto::kMessageTypeFieldNumber, 0,
+        DescriptorProto::kNestedTypeFieldNumber,      0,
+        DescriptorProto::kFieldFieldNumber,           0,
+        FieldDescriptorProto::kOptionsFieldNumber,    kCustomOptionFieldNumber};
     int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
                    0,
                    DescriptorProto::kNestedTypeFieldNumber,
@@ -7202,12 +7189,10 @@
 
   // One-of option
   {
-    int path[]  = {FileDescriptorProto::kMessageTypeFieldNumber,
-                   0,
-                   DescriptorProto::kOneofDeclFieldNumber,
-                   0,
-                   OneofDescriptorProto::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber};
+    int path[] = {
+        FileDescriptorProto::kMessageTypeFieldNumber, 0,
+        DescriptorProto::kOneofDeclFieldNumber,       0,
+        OneofDescriptorProto::kOptionsFieldNumber,    kCustomOptionFieldNumber};
     int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
                    0,
                    DescriptorProto::kOneofDeclFieldNumber,
@@ -7225,16 +7210,12 @@
 
   // Enum option, repeated options
   {
-    int path[]  = {FileDescriptorProto::kEnumTypeFieldNumber,
-                   0,
+    int path[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
+                  EnumDescriptorProto::kOptionsFieldNumber,
+                  kCustomOptionFieldNumber, 0};
+    int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
                    EnumDescriptorProto::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber,
-                   0};
-    int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber,
-                   0,
-                   EnumDescriptorProto::kOptionsFieldNumber,
-                   EnumOptions::kUninterpretedOptionFieldNumber,
-                   0};
+                   EnumOptions::kUninterpretedOptionFieldNumber, 0};
     std::vector<int> vpath(path, path + 5);
     EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
     EXPECT_EQ("18:3-18:31", PrintSourceLocation(loc));
@@ -7243,16 +7224,12 @@
     EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
   }
   {
-    int path[]  = {FileDescriptorProto::kEnumTypeFieldNumber,
-                   0,
+    int path[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
+                  EnumDescriptorProto::kOptionsFieldNumber,
+                  kCustomOptionFieldNumber, 1};
+    int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
                    EnumDescriptorProto::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber,
-                   1};
-    int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber,
-                   0,
-                   EnumDescriptorProto::kOptionsFieldNumber,
-                   EnumOptions::kUninterpretedOptionFieldNumber,
-                   1};
+                   EnumOptions::kUninterpretedOptionFieldNumber, 1};
     std::vector<int> vpath(path, path + 5);
     EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
     EXPECT_EQ("19:3-19:31", PrintSourceLocation(loc));
@@ -7261,16 +7238,12 @@
     EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
   }
   {
-    int path[]  = {FileDescriptorProto::kEnumTypeFieldNumber,
-                   0,
+    int path[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
+                  EnumDescriptorProto::kOptionsFieldNumber,
+                  kCustomOptionFieldNumber, 2};
+    int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
                    EnumDescriptorProto::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber,
-                   2};
-    int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber,
-                   0,
-                   EnumDescriptorProto::kOptionsFieldNumber,
-                   OneofOptions::kUninterpretedOptionFieldNumber,
-                   2};
+                   OneofOptions::kUninterpretedOptionFieldNumber, 2};
     std::vector<int> vpath(path, path + 5);
     EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
     EXPECT_EQ("20:3-20:31", PrintSourceLocation(loc));
@@ -7282,13 +7255,13 @@
   // Enum value options
   {
     // option w/ message type that directly sets field
-    int path[]  = {FileDescriptorProto::kEnumTypeFieldNumber,
-                   0,
-                   EnumDescriptorProto::kValueFieldNumber,
-                   0,
-                   EnumValueDescriptorProto::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber,
-                   kA_aFieldNumber};
+    int path[] = {FileDescriptorProto::kEnumTypeFieldNumber,
+                  0,
+                  EnumDescriptorProto::kValueFieldNumber,
+                  0,
+                  EnumValueDescriptorProto::kOptionsFieldNumber,
+                  kCustomOptionFieldNumber,
+                  kAFieldNumber};
     int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber,
                    0,
                    EnumDescriptorProto::kValueFieldNumber,
@@ -7304,12 +7277,12 @@
     EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
   }
   {
-    int path[]  = {FileDescriptorProto::kEnumTypeFieldNumber,
-                   0,
-                   EnumDescriptorProto::kValueFieldNumber,
-                   1,
-                   EnumValueDescriptorProto::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber};
+    int path[] = {FileDescriptorProto::kEnumTypeFieldNumber,
+                  0,
+                  EnumDescriptorProto::kValueFieldNumber,
+                  1,
+                  EnumValueDescriptorProto::kOptionsFieldNumber,
+                  kCustomOptionFieldNumber};
     int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber,
                    0,
                    EnumDescriptorProto::kValueFieldNumber,
@@ -7327,16 +7300,12 @@
 
   // Service option, repeated options
   {
-    int path[]  = {FileDescriptorProto::kServiceFieldNumber,
-                   0,
+    int path[] = {FileDescriptorProto::kServiceFieldNumber, 0,
+                  ServiceDescriptorProto::kOptionsFieldNumber,
+                  kCustomOptionFieldNumber, 0};
+    int unint[] = {FileDescriptorProto::kServiceFieldNumber, 0,
                    ServiceDescriptorProto::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber,
-                   0};
-    int unint[] = {FileDescriptorProto::kServiceFieldNumber,
-                   0,
-                   ServiceDescriptorProto::kOptionsFieldNumber,
-                   ServiceOptions::kUninterpretedOptionFieldNumber,
-                   0};
+                   ServiceOptions::kUninterpretedOptionFieldNumber, 0};
     std::vector<int> vpath(path, path + 5);
     EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
     EXPECT_EQ("26:3-26:35", PrintSourceLocation(loc));
@@ -7345,16 +7314,12 @@
     EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
   }
   {
-    int path[]  = {FileDescriptorProto::kServiceFieldNumber,
-                   0,
+    int path[] = {FileDescriptorProto::kServiceFieldNumber, 0,
+                  ServiceDescriptorProto::kOptionsFieldNumber,
+                  kCustomOptionFieldNumber, 1};
+    int unint[] = {FileDescriptorProto::kServiceFieldNumber, 0,
                    ServiceDescriptorProto::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber,
-                   1};
-    int unint[] = {FileDescriptorProto::kServiceFieldNumber,
-                   0,
-                   ServiceDescriptorProto::kOptionsFieldNumber,
-                   ServiceOptions::kUninterpretedOptionFieldNumber,
-                   1};
+                   ServiceOptions::kUninterpretedOptionFieldNumber, 1};
     std::vector<int> vpath(path, path + 5);
     EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
     EXPECT_EQ("27:3-27:35", PrintSourceLocation(loc));
@@ -7363,16 +7328,12 @@
     EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
   }
   {
-    int path[]  = {FileDescriptorProto::kServiceFieldNumber,
-                   0,
+    int path[] = {FileDescriptorProto::kServiceFieldNumber, 0,
+                  ServiceDescriptorProto::kOptionsFieldNumber,
+                  kCustomOptionFieldNumber, 2};
+    int unint[] = {FileDescriptorProto::kServiceFieldNumber, 0,
                    ServiceDescriptorProto::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber,
-                   2};
-    int unint[] = {FileDescriptorProto::kServiceFieldNumber,
-                   0,
-                   ServiceDescriptorProto::kOptionsFieldNumber,
-                   ServiceOptions::kUninterpretedOptionFieldNumber,
-                   2};
+                   ServiceOptions::kUninterpretedOptionFieldNumber, 2};
     std::vector<int> vpath(path, path + 5);
     EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
     EXPECT_EQ("28:3-28:35", PrintSourceLocation(loc));
@@ -7383,12 +7344,12 @@
 
   // Method options
   {
-    int path[]  = {FileDescriptorProto::kServiceFieldNumber,
-                   0,
-                   ServiceDescriptorProto::kMethodFieldNumber,
-                   1,
-                   MethodDescriptorProto::kOptionsFieldNumber,
-                   MethodOptions::kDeprecatedFieldNumber};
+    int path[] = {FileDescriptorProto::kServiceFieldNumber,
+                  0,
+                  ServiceDescriptorProto::kMethodFieldNumber,
+                  1,
+                  MethodDescriptorProto::kOptionsFieldNumber,
+                  MethodOptions::kDeprecatedFieldNumber};
     int unint[] = {FileDescriptorProto::kServiceFieldNumber,
                    0,
                    ServiceDescriptorProto::kMethodFieldNumber,
@@ -7404,12 +7365,10 @@
     EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
   }
   {
-    int path[]  = {FileDescriptorProto::kServiceFieldNumber,
-                   0,
-                   ServiceDescriptorProto::kMethodFieldNumber,
-                   1,
-                   MethodDescriptorProto::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber};
+    int path[] = {
+        FileDescriptorProto::kServiceFieldNumber,   0,
+        ServiceDescriptorProto::kMethodFieldNumber, 1,
+        MethodDescriptorProto::kOptionsFieldNumber, kCustomOptionFieldNumber};
     int unint[] = {FileDescriptorProto::kServiceFieldNumber,
                    0,
                    ServiceDescriptorProto::kMethodFieldNumber,
@@ -7427,22 +7386,20 @@
 
   // Extension range options
   {
-    int path[]  = {FileDescriptorProto::kMessageTypeFieldNumber,
-                   1,
-                   DescriptorProto::kExtensionRangeFieldNumber,
-                   0,
-                   DescriptorProto_ExtensionRange::kOptionsFieldNumber};
+    int path[] = {FileDescriptorProto::kMessageTypeFieldNumber, 1,
+                  DescriptorProto::kExtensionRangeFieldNumber, 0,
+                  DescriptorProto_ExtensionRange::kOptionsFieldNumber};
     std::vector<int> vpath(path, path + 5);
     EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
     EXPECT_EQ("37:40-37:67", PrintSourceLocation(loc));
   }
   {
-    int path[]  = {FileDescriptorProto::kMessageTypeFieldNumber,
-                   1,
-                   DescriptorProto::kExtensionRangeFieldNumber,
-                   0,
-                   DescriptorProto_ExtensionRange::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber};
+    int path[] = {FileDescriptorProto::kMessageTypeFieldNumber,
+                  1,
+                  DescriptorProto::kExtensionRangeFieldNumber,
+                  0,
+                  DescriptorProto_ExtensionRange::kOptionsFieldNumber,
+                  kCustomOptionFieldNumber};
     int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
                    1,
                    DescriptorProto::kExtensionRangeFieldNumber,
@@ -7458,12 +7415,12 @@
     EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
   }
   {
-    int path[]  = {FileDescriptorProto::kMessageTypeFieldNumber,
-                   1,
-                   DescriptorProto::kExtensionRangeFieldNumber,
-                   1,
-                   DescriptorProto_ExtensionRange::kOptionsFieldNumber,
-                   kCustomOptionFieldNumber};
+    int path[] = {FileDescriptorProto::kMessageTypeFieldNumber,
+                  1,
+                  DescriptorProto::kExtensionRangeFieldNumber,
+                  1,
+                  DescriptorProto_ExtensionRange::kOptionsFieldNumber,
+                  kCustomOptionFieldNumber};
     int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
                    1,
                    DescriptorProto::kExtensionRangeFieldNumber,
@@ -7481,15 +7438,12 @@
 
   // Field option on extension
   {
-    int path[]  = {FileDescriptorProto::kExtensionFieldNumber,
-                   0,
+    int path[] = {FileDescriptorProto::kExtensionFieldNumber, 0,
+                  FieldDescriptorProto::kOptionsFieldNumber,
+                  FieldOptions::kPackedFieldNumber};
+    int unint[] = {FileDescriptorProto::kExtensionFieldNumber, 0,
                    FieldDescriptorProto::kOptionsFieldNumber,
-                   FieldOptions::kPackedFieldNumber};
-    int unint[] = {FileDescriptorProto::kExtensionFieldNumber,
-                   0,
-                   FieldDescriptorProto::kOptionsFieldNumber,
-                   FieldOptions::kUninterpretedOptionFieldNumber,
-                   0};
+                   FieldOptions::kUninterpretedOptionFieldNumber, 0};
     std::vector<int> vpath(path, path + 4);
     EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
     EXPECT_EQ("40:42-40:53", PrintSourceLocation(loc));
@@ -7503,7 +7457,7 @@
 TEST_F(SourceLocationTest, GetSourceLocation_MissingSourceCodeInfo) {
   SourceLocation loc;
 
-  const FileDescriptor *file_desc =
+  const FileDescriptor* file_desc =
       GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
 
   FileDescriptorProto proto;
@@ -7521,7 +7475,7 @@
 TEST_F(SourceLocationTest, GetSourceLocation_BogusSourceCodeInfo) {
   SourceLocation loc;
 
-  const FileDescriptor *file_desc =
+  const FileDescriptor* file_desc =
       GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
 
   FileDescriptorProto proto;
@@ -7890,7 +7844,7 @@
   // Verify custom options work when defined in an import that isn't loaded,
   // and that a non-default value of a custom option doesn't load the file
   // where that enum is defined.
-  const google::protobuf::MessageOptions& options =
+  const MessageOptions& options =
       protobuf_unittest::lazy_imports::MessageCustomOption::descriptor()
           ->options();
   protobuf_unittest::lazy_imports::LazyEnum custom_option_value =
@@ -7902,7 +7856,7 @@
       "google/protobuf/unittest_lazy_dependencies_enum.proto"));
   EXPECT_EQ(custom_option_value, protobuf_unittest::lazy_imports::LAZY_ENUM_1);
 
-  const google::protobuf::MessageOptions& options2 =
+  const MessageOptions& options2 =
       protobuf_unittest::lazy_imports::MessageCustomOption2::descriptor()
           ->options();
   custom_option_value =
diff --git a/src/google/protobuf/drop_unknown_fields_test.cc b/src/google/protobuf/drop_unknown_fields_test.cc
index 437a04e..55b9ecd 100644
--- a/src/google/protobuf/drop_unknown_fields_test.cc
+++ b/src/google/protobuf/drop_unknown_fields_test.cc
@@ -35,35 +35,13 @@
 #include <google/protobuf/message_lite.h>
 #include <gtest/gtest.h>
 
-namespace google {
 using unittest_drop_unknown_fields::Foo;
 using unittest_drop_unknown_fields::FooWithExtraFields;
 
+namespace google {
 namespace protobuf {
 
-TEST(DropUnknownFieldsTest, GeneratedMessageDefaultDrop) {
-  ::google::protobuf::internal::SetProto3PreserveUnknownsDefault(false);
-  FooWithExtraFields foo_with_extra_fields;
-  foo_with_extra_fields.set_int32_value(1);
-  foo_with_extra_fields.set_enum_value(FooWithExtraFields::QUX);
-  foo_with_extra_fields.set_extra_int32_value(2);
-
-  Foo foo;
-  ASSERT_TRUE(foo.ParseFromString(foo_with_extra_fields.SerializeAsString()));
-  EXPECT_EQ(1, foo.int32_value());
-  EXPECT_EQ(static_cast<int>(FooWithExtraFields::QUX),
-            static_cast<int>(foo.enum_value()));
-  EXPECT_TRUE(foo.GetReflection()->GetUnknownFields(foo).empty());
-
-  ASSERT_TRUE(foo_with_extra_fields.ParseFromString(foo.SerializeAsString()));
-  EXPECT_EQ(1, foo_with_extra_fields.int32_value());
-  EXPECT_EQ(FooWithExtraFields::QUX, foo_with_extra_fields.enum_value());
-  // The "extra_int32_value" field should be lost.
-  EXPECT_EQ(0, foo_with_extra_fields.extra_int32_value());
-}
-
-TEST(DropUnknownFieldsTest, GeneratedMessageDefaultPreserve) {
-  ::google::protobuf::internal::SetProto3PreserveUnknownsDefault(true);
+TEST(DropUnknownFieldsTest, GeneratedMessage) {
   FooWithExtraFields foo_with_extra_fields;
   foo_with_extra_fields.set_int32_value(1);
   foo_with_extra_fields.set_enum_value(FooWithExtraFields::QUX);
@@ -83,36 +61,14 @@
   EXPECT_EQ(2, foo_with_extra_fields.extra_int32_value());
 }
 
-TEST(DropUnknownFieldsTest, DynamicMessageDefaultDrop) {
-  internal::SetProto3PreserveUnknownsDefault(false);
+TEST(DropUnknownFieldsTest, DynamicMessage) {
   FooWithExtraFields foo_with_extra_fields;
   foo_with_extra_fields.set_int32_value(1);
   foo_with_extra_fields.set_enum_value(FooWithExtraFields::QUX);
   foo_with_extra_fields.set_extra_int32_value(2);
 
-  google::protobuf::DynamicMessageFactory factory;
-  std::unique_ptr<google::protobuf::Message> foo(
-      factory.GetPrototype(Foo::descriptor())->New());
-  ASSERT_TRUE(foo->ParseFromString(foo_with_extra_fields.SerializeAsString()));
-  EXPECT_TRUE(foo->GetReflection()->GetUnknownFields(*foo).empty());
-
-  ASSERT_TRUE(foo_with_extra_fields.ParseFromString(foo->SerializeAsString()));
-  EXPECT_EQ(1, foo_with_extra_fields.int32_value());
-  EXPECT_EQ(FooWithExtraFields::QUX, foo_with_extra_fields.enum_value());
-  // The "extra_int32_value" field should be lost.
-  EXPECT_EQ(0, foo_with_extra_fields.extra_int32_value());
-}
-
-TEST(DropUnknownFieldsTest, DynamicMessageDefaultPreserve) {
-  internal::SetProto3PreserveUnknownsDefault(true);
-  FooWithExtraFields foo_with_extra_fields;
-  foo_with_extra_fields.set_int32_value(1);
-  foo_with_extra_fields.set_enum_value(FooWithExtraFields::QUX);
-  foo_with_extra_fields.set_extra_int32_value(2);
-
-  google::protobuf::DynamicMessageFactory factory;
-  std::unique_ptr<google::protobuf::Message> foo(
-      factory.GetPrototype(Foo::descriptor())->New());
+  DynamicMessageFactory factory;
+  std::unique_ptr<Message> foo(factory.GetPrototype(Foo::descriptor())->New());
   ASSERT_TRUE(foo->ParseFromString(foo_with_extra_fields.SerializeAsString()));
   EXPECT_FALSE(foo->GetReflection()->GetUnknownFields(*foo).empty());
 
diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc
index e8417a7..e9a8277 100644
--- a/src/google/protobuf/duration.pb.cc
+++ b/src/google/protobuf/duration.pb.cc
@@ -6,8 +6,8 @@
 #include <algorithm>
 
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
@@ -18,18 +18,17 @@
 #include "third_party/protobuf/version.h"
 #endif
 // @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
 
 namespace google {
 namespace protobuf {
 class DurationDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Duration>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Duration> _instance;
 } _Duration_default_instance_;
 }  // namespace protobuf
 }  // namespace google
-namespace protobuf_google_2fprotobuf_2fduration_2eproto {
-static void InitDefaultsDuration() {
+static void InitDefaultsDuration_google_2fprotobuf_2fduration_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -40,16 +39,18 @@
   ::google::protobuf::Duration::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Duration =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsDuration}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Duration_google_2fprotobuf_2fduration_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsDuration_google_2fprotobuf_2fduration_2eproto}, {}};
 
-void InitDefaults() {
-  ::google::protobuf::internal::InitSCC(&scc_info_Duration.base);
+void InitDefaults_google_2fprotobuf_2fduration_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_Duration_google_2fprotobuf_2fduration_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata[1];
+::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fduration_2eproto[1];
+constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr;
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fduration_2eproto = nullptr;
 
-const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fduration_2eproto::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Duration, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -66,51 +67,33 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Duration_default_instance_),
 };
 
-static void protobuf_AssignDescriptors() {
-  AddDescriptors();
-  AssignDescriptors(
-      "google/protobuf/duration.proto", schemas, file_default_instances, TableStruct::offsets,
-      file_level_metadata, NULL, NULL);
-}
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fduration_2eproto = {
+  {}, AddDescriptors_google_2fprotobuf_2fduration_2eproto, "google/protobuf/duration.proto", schemas,
+  file_default_instances, TableStruct_google_2fprotobuf_2fduration_2eproto::offsets,
+  file_level_metadata_google_2fprotobuf_2fduration_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fduration_2eproto, file_level_service_descriptors_google_2fprotobuf_2fduration_2eproto,
+};
 
-static void protobuf_AssignDescriptorsOnce() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
-}
+::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fduration_2eproto = {
+  false, InitDefaults_google_2fprotobuf_2fduration_2eproto, 
+  "\n\036google/protobuf/duration.proto\022\017google"
+  ".protobuf\"*\n\010Duration\022\017\n\007seconds\030\001 \001(\003\022\r"
+  "\n\005nanos\030\002 \001(\005B|\n\023com.google.protobufB\rDu"
+  "rationProtoP\001Z*github.com/golang/protobu"
+  "f/ptypes/duration\370\001\001\242\002\003GPB\252\002\036Google.Prot"
+  "obuf.WellKnownTypesb\006proto3"
+,
+  "google/protobuf/duration.proto", &assign_descriptors_table_google_2fprotobuf_2fduration_2eproto, 227,
+};
 
-void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
-void protobuf_RegisterTypes(const ::std::string&) {
-  protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
-}
-
-static void AddDescriptorsImpl() {
-  InitDefaults();
-  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
-      "\n\036google/protobuf/duration.proto\022\017google"
-      ".protobuf\"*\n\010Duration\022\017\n\007seconds\030\001 \001(\003\022\r"
-      "\n\005nanos\030\002 \001(\005B|\n\023com.google.protobufB\rDu"
-      "rationProtoP\001Z*github.com/golang/protobu"
-      "f/ptypes/duration\370\001\001\242\002\003GPB\252\002\036Google.Prot"
-      "obuf.WellKnownTypesb\006proto3"
+void AddDescriptors_google_2fprotobuf_2fduration_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
   };
-  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 227);
-  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
-    "google/protobuf/duration.proto", &protobuf_RegisterTypes);
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fduration_2eproto, deps, 0);
 }
 
-void AddDescriptors() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
-}
-// Force AddDescriptors() to be called at dynamic initialization time.
-struct StaticDescriptorInitializer {
-  StaticDescriptorInitializer() {
-    AddDescriptors();
-  }
-} static_descriptor_initializer;
-}  // namespace protobuf_google_2fprotobuf_2fduration_2eproto
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_google_2fprotobuf_2fduration_2eproto = []() { AddDescriptors_google_2fprotobuf_2fduration_2eproto(); return true; }();
 namespace google {
 namespace protobuf {
 
@@ -118,6 +101,10 @@
 
 void Duration::InitAsDefaultInstance() {
 }
+class Duration::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Duration::kSecondsFieldNumber;
 const int Duration::kNanosFieldNumber;
@@ -125,15 +112,12 @@
 
 Duration::Duration()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fduration_2eproto::scc_info_Duration.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Duration)
 }
 Duration::Duration(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fduration_2eproto::scc_info_Duration.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.Duration)
@@ -172,13 +156,8 @@
 void Duration::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Duration::descriptor() {
-  ::protobuf_google_2fprotobuf_2fduration_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fduration_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Duration& Duration::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fduration_2eproto::scc_info_Duration.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Duration_google_2fprotobuf_2fduration_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -195,9 +174,68 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Duration::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Duration*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // int64 seconds = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int64 value = val;
+        msg->set_seconds(value);
+        break;
+      }
+      // int32 nanos = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_nanos(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Duration::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Duration)
   for (;;) {
@@ -207,8 +245,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // int64 seconds = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
@@ -221,8 +258,7 @@
 
       // int32 nanos = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
@@ -252,6 +288,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Duration::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -269,9 +306,9 @@
     ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->nanos(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Duration)
 }
@@ -293,9 +330,9 @@
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->nanos(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Duration)
   return target;
@@ -305,11 +342,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Duration)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // int64 seconds = 1;
   if (this->seconds() != 0) {
     total_size += 1 +
@@ -333,7 +374,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Duration)
   GOOGLE_DCHECK_NE(&from, this);
   const Duration* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Duration>(
+      ::google::protobuf::DynamicCastToGenerated<Duration>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Duration)
@@ -398,14 +439,14 @@
 }
 void Duration::InternalSwap(Duration* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   swap(seconds_, other->seconds_);
   swap(nanos_, other->nanos_);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata Duration::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fduration_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fduration_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fduration_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fduration_2eproto[kIndexInFileMessages];
 }
 
 
diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h
index 19241eb..1d32e1b 100644
--- a/src/google/protobuf/duration.pb.h
+++ b/src/google/protobuf/duration.pb.h
@@ -4,18 +4,18 @@
 #ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2fduration_2eproto
 #define PROTOBUF_INCLUDED_google_2fprotobuf_2fduration_2eproto
 
+#include <limits>
 #include <string>
 
 #include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 3006001
+#if GOOGLE_PROTOBUF_VERSION < 3006000
 #error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please update
+#error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
 #if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
 #error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please
+#error incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.
 #endif
 
@@ -31,29 +31,27 @@
 #include <google/protobuf/extension_set.h>  // IWYU pragma: export
 #include <google/protobuf/unknown_field_set.h>
 // @@protoc_insertion_point(includes)
-#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fduration_2eproto LIBPROTOBUF_EXPORT
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fduration_2eproto LIBPROTOBUF_EXPORT
 
-namespace protobuf_google_2fprotobuf_2fduration_2eproto {
 // Internal implementation detail -- do not use these members.
-struct LIBPROTOBUF_EXPORT TableStruct {
-  static const ::google::protobuf::internal::ParseTableField entries[];
-  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
-  static const ::google::protobuf::internal::ParseTable schema[1];
+struct LIBPROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fduration_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[1]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
   static const ::google::protobuf::uint32 offsets[];
 };
-void LIBPROTOBUF_EXPORT AddDescriptors();
-}  // namespace protobuf_google_2fprotobuf_2fduration_2eproto
+void LIBPROTOBUF_EXPORT AddDescriptors_google_2fprotobuf_2fduration_2eproto();
 namespace google {
 namespace protobuf {
 class Duration;
 class DurationDefaultTypeInternal;
 LIBPROTOBUF_EXPORT extern DurationDefaultTypeInternal _Duration_default_instance_;
-}  // namespace protobuf
-}  // namespace google
-namespace google {
-namespace protobuf {
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::Duration* Arena::CreateMaybeMessage<::google::protobuf::Duration>(Arena*);
 }  // namespace protobuf
 }  // namespace google
@@ -94,7 +92,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Duration& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -128,8 +128,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -175,6 +180,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Duration)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -183,7 +189,7 @@
   ::google::protobuf::int64 seconds_;
   ::google::protobuf::int32 nanos_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fduration_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fduration_2eproto;
 };
 // ===================================================================
 
@@ -198,7 +204,7 @@
 
 // int64 seconds = 1;
 inline void Duration::clear_seconds() {
-  seconds_ = GOOGLE_LONGLONG(0);
+  seconds_ = GOOGLE_PROTOBUF_LONGLONG(0);
 }
 inline ::google::protobuf::int64 Duration::seconds() const {
   // @@protoc_insertion_point(field_get:google.protobuf.Duration.seconds)
@@ -235,4 +241,5 @@
 
 // @@protoc_insertion_point(global_scope)
 
+#include <google/protobuf/port_undef.inc>
 #endif  // PROTOBUF_INCLUDED_google_2fprotobuf_2fduration_2eproto
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc
index 8ad112c..6e4338f 100644
--- a/src/google/protobuf/dynamic_message.cc
+++ b/src/google/protobuf/dynamic_message.cc
@@ -63,16 +63,16 @@
 // I don't have the book on me right now so I'm not sure.
 
 #include <algorithm>
-#include <google/protobuf/stubs/hash.h>
 #include <memory>
+#include <unordered_map>
 
-#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/hash.h>
 
-#include <google/protobuf/dynamic_message.h>
-#include <google/protobuf/descriptor.h>
 #include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/dynamic_message.h>
 #include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/arenastring.h>
 #include <google/protobuf/extension_set.h>
 #include <google/protobuf/map_field.h>
@@ -259,8 +259,8 @@
   // implements Message ----------------------------------------------
 
   Message* New() const override;
-  Message* New(::google::protobuf::Arena* arena) const override;
-  ::google::protobuf::Arena* GetArena() const override { return arena_; }
+  Message* New(Arena* arena) const override;
+  Arena* GetArena() const override { return arena_; }
 
   int GetCachedSize() const override;
   void SetCachedSize(int size) const override;
@@ -279,7 +279,7 @@
 #endif  // !_MSC_VER
 
  private:
-  DynamicMessage(const TypeInfo* type_info, ::google::protobuf::Arena* arena);
+  DynamicMessage(const TypeInfo* type_info, Arena* arena);
 
   void SharedCtor(bool lock_factory);
 
@@ -299,8 +299,7 @@
 
   const TypeInfo* type_info_;
   Arena* const arena_;
-  // TODO(kenton):  Make this an atomic<int> when C++ supports it.
-  mutable int cached_byte_size_;
+  mutable std::atomic<int> cached_byte_size_;
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
 };
 
@@ -309,8 +308,7 @@
   SharedCtor(true);
 }
 
-DynamicMessage::DynamicMessage(const TypeInfo* type_info,
-                               ::google::protobuf::Arena* arena)
+DynamicMessage::DynamicMessage(const TypeInfo* type_info, Arena* arena)
     : type_info_(type_info), arena_(arena), cached_byte_size_(0) {
   SharedCtor(true);
 }
@@ -579,7 +577,7 @@
 
 Message* DynamicMessage::New() const { return New(NULL); }
 
-Message* DynamicMessage::New(::google::protobuf::Arena* arena) const {
+Message* DynamicMessage::New(Arena* arena) const {
   if (arena != NULL) {
     void* new_base = Arena::CreateArray<char>(arena, type_info_->size);
     memset(new_base, 0, type_info_->size);
@@ -592,16 +590,11 @@
 }
 
 int DynamicMessage::GetCachedSize() const {
-  return cached_byte_size_;
+  return cached_byte_size_.load(std::memory_order_relaxed);
 }
 
 void DynamicMessage::SetCachedSize(int size) const {
-  // This is theoretically not thread-compatible, but in practice it works
-  // because if multiple threads write this simultaneously, they will be
-  // writing the exact same value.
-  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
-  cached_byte_size_ = size;
-  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  cached_byte_size_.store(size, std::memory_order_relaxed);
 }
 
 Metadata DynamicMessage::GetMetadata() const {
@@ -614,7 +607,8 @@
 // ===================================================================
 
 struct DynamicMessageFactory::PrototypeMap {
-  typedef hash_map<const Descriptor*, const DynamicMessage::TypeInfo*> Map;
+  typedef std::unordered_map<const Descriptor*, const DynamicMessage::TypeInfo*>
+      Map;
   Map map_;
 };
 
diff --git a/src/google/protobuf/dynamic_message.h b/src/google/protobuf/dynamic_message.h
index 940d5e1..c614ee5 100644
--- a/src/google/protobuf/dynamic_message.h
+++ b/src/google/protobuf/dynamic_message.h
@@ -43,9 +43,13 @@
 #include <vector>
 
 #include <google/protobuf/message.h>
+#include <google/protobuf/stubs/mutex.h>
 #include <google/protobuf/repeated_field.h>
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/mutex.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
 
 namespace google {
 namespace protobuf {
@@ -121,14 +125,14 @@
   const DescriptorPool* pool_;
   bool delegate_to_generated_factory_;
 
-  // This struct just contains a hash_map.  We can't #include <google/protobuf/stubs/hash.h> from
+  // This struct just contains a hash_map.  We can't #include <hash_map> from
   // this header due to hacks needed for hash_map portability in the open source
   // release.  Namely, stubs/hash.h, which defines hash_map portably, is not a
   // public header (for good reason), but dynamic_message.h is, and public
   // headers may only #include other public headers.
   struct PrototypeMap;
   std::unique_ptr<PrototypeMap> prototypes_;
-  mutable Mutex prototypes_mutex_;
+  mutable internal::WrappedMutex prototypes_mutex_;
 
   friend class DynamicMessage;
   const Message* GetPrototypeNoLock(const Descriptor* type);
@@ -228,6 +232,6 @@
 };
 
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc
index 163a4f6..5ca9266 100644
--- a/src/google/protobuf/empty.pb.cc
+++ b/src/google/protobuf/empty.pb.cc
@@ -6,8 +6,8 @@
 #include <algorithm>
 
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
@@ -18,18 +18,17 @@
 #include "third_party/protobuf/version.h"
 #endif
 // @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
 
 namespace google {
 namespace protobuf {
 class EmptyDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Empty>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Empty> _instance;
 } _Empty_default_instance_;
 }  // namespace protobuf
 }  // namespace google
-namespace protobuf_google_2fprotobuf_2fempty_2eproto {
-static void InitDefaultsEmpty() {
+static void InitDefaultsEmpty_google_2fprotobuf_2fempty_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -40,16 +39,18 @@
   ::google::protobuf::Empty::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Empty =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsEmpty}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Empty_google_2fprotobuf_2fempty_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsEmpty_google_2fprotobuf_2fempty_2eproto}, {}};
 
-void InitDefaults() {
-  ::google::protobuf::internal::InitSCC(&scc_info_Empty.base);
+void InitDefaults_google_2fprotobuf_2fempty_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_Empty_google_2fprotobuf_2fempty_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata[1];
+::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fempty_2eproto[1];
+constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr;
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fempty_2eproto = nullptr;
 
-const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fempty_2eproto::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Empty, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -64,50 +65,32 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Empty_default_instance_),
 };
 
-static void protobuf_AssignDescriptors() {
-  AddDescriptors();
-  AssignDescriptors(
-      "google/protobuf/empty.proto", schemas, file_default_instances, TableStruct::offsets,
-      file_level_metadata, NULL, NULL);
-}
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fempty_2eproto = {
+  {}, AddDescriptors_google_2fprotobuf_2fempty_2eproto, "google/protobuf/empty.proto", schemas,
+  file_default_instances, TableStruct_google_2fprotobuf_2fempty_2eproto::offsets,
+  file_level_metadata_google_2fprotobuf_2fempty_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fempty_2eproto, file_level_service_descriptors_google_2fprotobuf_2fempty_2eproto,
+};
 
-static void protobuf_AssignDescriptorsOnce() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
-}
+::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fempty_2eproto = {
+  false, InitDefaults_google_2fprotobuf_2fempty_2eproto, 
+  "\n\033google/protobuf/empty.proto\022\017google.pr"
+  "otobuf\"\007\n\005EmptyBv\n\023com.google.protobufB\n"
+  "EmptyProtoP\001Z\'github.com/golang/protobuf"
+  "/ptypes/empty\370\001\001\242\002\003GPB\252\002\036Google.Protobuf"
+  ".WellKnownTypesb\006proto3"
+,
+  "google/protobuf/empty.proto", &assign_descriptors_table_google_2fprotobuf_2fempty_2eproto, 183,
+};
 
-void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
-void protobuf_RegisterTypes(const ::std::string&) {
-  protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
-}
-
-static void AddDescriptorsImpl() {
-  InitDefaults();
-  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
-      "\n\033google/protobuf/empty.proto\022\017google.pr"
-      "otobuf\"\007\n\005EmptyBv\n\023com.google.protobufB\n"
-      "EmptyProtoP\001Z\'github.com/golang/protobuf"
-      "/ptypes/empty\370\001\001\242\002\003GPB\252\002\036Google.Protobuf"
-      ".WellKnownTypesb\006proto3"
+void AddDescriptors_google_2fprotobuf_2fempty_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
   };
-  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 183);
-  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
-    "google/protobuf/empty.proto", &protobuf_RegisterTypes);
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fempty_2eproto, deps, 0);
 }
 
-void AddDescriptors() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
-}
-// Force AddDescriptors() to be called at dynamic initialization time.
-struct StaticDescriptorInitializer {
-  StaticDescriptorInitializer() {
-    AddDescriptors();
-  }
-} static_descriptor_initializer;
-}  // namespace protobuf_google_2fprotobuf_2fempty_2eproto
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_google_2fprotobuf_2fempty_2eproto = []() { AddDescriptors_google_2fprotobuf_2fempty_2eproto(); return true; }();
 namespace google {
 namespace protobuf {
 
@@ -115,20 +98,21 @@
 
 void Empty::InitAsDefaultInstance() {
 }
+class Empty::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Empty::Empty()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fempty_2eproto::scc_info_Empty.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Empty)
 }
 Empty::Empty(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fempty_2eproto::scc_info_Empty.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.Empty)
@@ -161,13 +145,8 @@
 void Empty::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Empty::descriptor() {
-  ::protobuf_google_2fprotobuf_2fempty_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fempty_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Empty& Empty::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fempty_2eproto::scc_info_Empty.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Empty_google_2fprotobuf_2fempty_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -181,9 +160,48 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Empty::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Empty*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Empty::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Empty)
   for (;;) {
@@ -205,6 +223,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Empty::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -212,9 +231,9 @@
   ::google::protobuf::uint32 cached_has_bits = 0;
   (void) cached_has_bits;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Empty)
 }
@@ -226,9 +245,9 @@
   ::google::protobuf::uint32 cached_has_bits = 0;
   (void) cached_has_bits;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Empty)
   return target;
@@ -238,11 +257,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Empty)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
   SetCachedSize(cached_size);
   return total_size;
@@ -252,7 +275,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Empty)
   GOOGLE_DCHECK_NE(&from, this);
   const Empty* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Empty>(
+      ::google::protobuf::DynamicCastToGenerated<Empty>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Empty)
@@ -315,8 +338,8 @@
 }
 
 ::google::protobuf::Metadata Empty::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fempty_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fempty_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fempty_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fempty_2eproto[kIndexInFileMessages];
 }
 
 
diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h
index 4d65108..65f0b19 100644
--- a/src/google/protobuf/empty.pb.h
+++ b/src/google/protobuf/empty.pb.h
@@ -4,18 +4,18 @@
 #ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2fempty_2eproto
 #define PROTOBUF_INCLUDED_google_2fprotobuf_2fempty_2eproto
 
+#include <limits>
 #include <string>
 
 #include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 3006001
+#if GOOGLE_PROTOBUF_VERSION < 3006000
 #error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please update
+#error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
 #if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
 #error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please
+#error incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.
 #endif
 
@@ -31,29 +31,27 @@
 #include <google/protobuf/extension_set.h>  // IWYU pragma: export
 #include <google/protobuf/unknown_field_set.h>
 // @@protoc_insertion_point(includes)
-#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fempty_2eproto LIBPROTOBUF_EXPORT
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fempty_2eproto LIBPROTOBUF_EXPORT
 
-namespace protobuf_google_2fprotobuf_2fempty_2eproto {
 // Internal implementation detail -- do not use these members.
-struct LIBPROTOBUF_EXPORT TableStruct {
-  static const ::google::protobuf::internal::ParseTableField entries[];
-  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
-  static const ::google::protobuf::internal::ParseTable schema[1];
+struct LIBPROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fempty_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[1]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
   static const ::google::protobuf::uint32 offsets[];
 };
-void LIBPROTOBUF_EXPORT AddDescriptors();
-}  // namespace protobuf_google_2fprotobuf_2fempty_2eproto
+void LIBPROTOBUF_EXPORT AddDescriptors_google_2fprotobuf_2fempty_2eproto();
 namespace google {
 namespace protobuf {
 class Empty;
 class EmptyDefaultTypeInternal;
 LIBPROTOBUF_EXPORT extern EmptyDefaultTypeInternal _Empty_default_instance_;
-}  // namespace protobuf
-}  // namespace google
-namespace google {
-namespace protobuf {
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::Empty* Arena::CreateMaybeMessage<::google::protobuf::Empty>(Arena*);
 }  // namespace protobuf
 }  // namespace google
@@ -94,7 +92,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Empty& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -128,8 +128,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -163,13 +168,14 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Empty)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fempty_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fempty_2eproto;
 };
 // ===================================================================
 
@@ -193,4 +199,5 @@
 
 // @@protoc_insertion_point(global_scope)
 
+#include <google/protobuf/port_undef.inc>
 #endif  // PROTOBUF_INCLUDED_google_2fprotobuf_2fempty_2eproto
diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc
index cb205c4..cb40ab7 100644
--- a/src/google/protobuf/extension_set.cc
+++ b/src/google/protobuf/extension_set.cc
@@ -32,16 +32,25 @@
 //  Based on original Protocol Buffers design by
 //  Sanjay Ghemawat, Jeff Dean, and others.
 
-#include <google/protobuf/stubs/hash.h>
+#include <google/protobuf/extension_set.h>
+
 #include <tuple>
+#include <unordered_map>
 #include <utility>
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/extension_set.h>
-#include <google/protobuf/message_lite.h>
 #include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/metadata_lite.h>
 #include <google/protobuf/repeated_field.h>
+#include <google/protobuf/wire_format_lite_inl.h>
 #include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/port_def.inc>
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+#include <google/protobuf/parse_context.h>
+#endif
 
 namespace google {
 namespace protobuf {
@@ -77,8 +86,16 @@
 }
 
 // Registry stuff.
-typedef hash_map<std::pair<const MessageLite*, int>,
-                 ExtensionInfo> ExtensionRegistry;
+struct ExtensionHasher {
+  std::size_t operator()(const std::pair<const MessageLite*, int>& p) const {
+    return std::hash<const MessageLite*>{}(p.first) ^
+           std::hash<int>{}(p.second);
+  }
+};
+
+typedef std::unordered_map<std::pair<const MessageLite*, int>, ExtensionInfo,
+                           ExtensionHasher>
+    ExtensionRegistry;
 
 static const ExtensionRegistry* global_registry = nullptr;
 
@@ -89,7 +106,7 @@
   static auto local_static_registry = OnShutdownDelete(new ExtensionRegistry);
   global_registry = local_static_registry;
   if (!InsertIfNotPresent(local_static_registry,
-                          std::make_pair(containing_type, number), info)) {
+                               std::make_pair(containing_type, number), info)) {
     GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
                << containing_type->GetTypeName()
                << "\", field number " << number << ".";
@@ -99,8 +116,9 @@
 const ExtensionInfo* FindRegisteredExtension(
     const MessageLite* containing_type, int number) {
   return global_registry == nullptr
-      ? nullptr
-      : FindOrNull(*global_registry, std::make_pair(containing_type, number));
+             ? nullptr
+             : FindOrNull(*global_registry,
+                               std::make_pair(containing_type, number));
 }
 
 }  // namespace
@@ -168,21 +186,21 @@
 // ===================================================================
 // Constructors and basic methods.
 
-ExtensionSet::ExtensionSet(::google::protobuf::Arena* arena)
+ExtensionSet::ExtensionSet(Arena* arena)
     : arena_(arena),
       flat_capacity_(0),
       flat_size_(0),
-      map_{flat_capacity_ == 0 ? NULL
-                               : ::google::protobuf::Arena::CreateArray<KeyValue>(
-                                     arena_, flat_capacity_)} {}
+      map_{flat_capacity_ == 0
+               ? NULL
+               : Arena::CreateArray<KeyValue>(arena_, flat_capacity_)} {}
 
 ExtensionSet::ExtensionSet()
     : arena_(NULL),
       flat_capacity_(0),
       flat_size_(0),
-      map_{flat_capacity_ == 0 ? NULL
-                               : ::google::protobuf::Arena::CreateArray<KeyValue>(
-                                     arena_, flat_capacity_)} {}
+      map_{flat_capacity_ == 0
+               ? NULL
+               : Arena::CreateArray<KeyValue>(arena_, flat_capacity_)} {}
 
 ExtensionSet::~ExtensionSet() {
   // Deletes all allocated extensions.
@@ -191,11 +209,27 @@
     if (GOOGLE_PREDICT_FALSE(is_large())) {
       delete map_.large;
     } else {
-      delete[] map_.flat;
+      DeleteFlatMap(map_.flat, flat_capacity_);
     }
   }
 }
 
+void ExtensionSet::DeleteFlatMap(
+    const ExtensionSet::KeyValue* flat, uint16 flat_capacity) {
+#ifdef __cpp_sized_deallocation
+  // Arena::CreateArray already requires a trivially destructible type, but
+  // ensure this constraint is not violated in the future.
+  static_assert(std::is_trivially_destructible<KeyValue>::value,
+                "CreateArray requires a trivially destructible type");
+  // A const-cast is needed, but this is safe as we are about to deallocate the
+  // array.
+  ::operator delete[](
+      const_cast<ExtensionSet::KeyValue*>(flat), sizeof(*flat) * flat_capacity);
+#else  // !__cpp_sized_deallocation
+  delete[] flat;
+#endif  // !__cpp_sized_deallocation
+}
+
 // Defined in extension_set_heavy.cc.
 // void ExtensionSet::AppendToList(const Descriptor* containing_type,
 //                                 const DescriptorPool* pool,
@@ -594,7 +628,7 @@
     ClearExtension(number);
     return;
   }
-  ::google::protobuf::Arena* message_arena = message->GetArena();
+  Arena* message_arena = message->GetArena();
   Extension* extension;
   if (MaybeNewExtension(number, descriptor, &extension)) {
     extension->type = type;
@@ -746,10 +780,9 @@
 
   // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
   // allocate an abstract object, so we have to be tricky.
-  MessageLite* result =
-      reinterpret_cast<::google::protobuf::internal::RepeatedPtrFieldBase*>(
-          extension->repeated_message_value)
-          ->AddFromCleared<GenericTypeHandler<MessageLite> >();
+  MessageLite* result = reinterpret_cast<internal::RepeatedPtrFieldBase*>(
+                            extension->repeated_message_value)
+                            ->AddFromCleared<GenericTypeHandler<MessageLite>>();
   if (result == NULL) {
     result = prototype.New(arena_);
     extension->repeated_message_value->AddAllocated(result);
@@ -945,9 +978,9 @@
         for (int i = 0; i < other_repeated_message->size(); i++) {
           const MessageLite& other_message = other_repeated_message->Get(i);
           MessageLite* target =
-              reinterpret_cast<::google::protobuf::internal::RepeatedPtrFieldBase*>(
+              reinterpret_cast<internal::RepeatedPtrFieldBase*>(
                   extension->repeated_message_value)
-                  ->AddFromCleared<GenericTypeHandler<MessageLite> >();
+                  ->AddFromCleared<GenericTypeHandler<MessageLite>>();
           if (target == NULL) {
             target = other_message.New(arena_);
             extension->repeated_message_value->AddAllocated(target);
@@ -1167,6 +1200,214 @@
   }
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+std::pair<const char*, bool> ExtensionSet::ParseField(
+    uint32 tag, ParseClosure parent, const char* begin, const char* end,
+    const MessageLite* containing_type,
+    internal::InternalMetadataWithArenaLite* metadata,
+    internal::ParseContext* ctx) {
+  GeneratedExtensionFinder finder(containing_type);
+  int number;
+  bool was_packed_on_wire;
+  ExtensionInfo extension;
+  if (!FindExtensionInfoFromTag(tag, &finder, &number, &extension,
+                                &was_packed_on_wire)) {
+    return UnknownFieldParse(tag, parent, begin, end,
+                             metadata->mutable_unknown_fields(), ctx);
+  }
+  auto ptr = begin;
+  ParseClosure child;
+  int depth;
+  if (was_packed_on_wire) {
+    switch (extension.type) {
+#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE)                                \
+  case WireFormatLite::TYPE_##UPPERCASE:                                     \
+    child = {                                                                \
+        internal::Packed##CPP_CAMELCASE##Parser,                             \
+        MutableRawRepeatedField(number, extension.type, extension.is_packed, \
+                                extension.descriptor)};                      \
+    goto length_delim
+      HANDLE_TYPE(INT32, Int32);
+      HANDLE_TYPE(INT64, Int64);
+      HANDLE_TYPE(UINT32, UInt32);
+      HANDLE_TYPE(UINT64, UInt64);
+      HANDLE_TYPE(SINT32, SInt32);
+      HANDLE_TYPE(SINT64, SInt64);
+      HANDLE_TYPE(FIXED32, Fixed32);
+      HANDLE_TYPE(FIXED64, Fixed64);
+      HANDLE_TYPE(SFIXED32, SFixed32);
+      HANDLE_TYPE(SFIXED64, SFixed64);
+      HANDLE_TYPE(FLOAT, Float);
+      HANDLE_TYPE(DOUBLE, Double);
+      HANDLE_TYPE(BOOL, Bool);
+#undef HANDLE_TYPE
+
+      case WireFormatLite::TYPE_ENUM:
+        ctx->extra_parse_data().SetEnumValidatorArg(
+            extension.enum_validity_check.func,
+            extension.enum_validity_check.arg,
+            metadata->mutable_unknown_fields(), tag >> 3);
+        child = {
+            internal::PackedValidEnumParserLiteArg,
+            MutableRawRepeatedField(number, extension.type, extension.is_packed,
+                                    extension.descriptor)};
+        goto length_delim;
+      case WireFormatLite::TYPE_STRING:
+      case WireFormatLite::TYPE_BYTES:
+      case WireFormatLite::TYPE_GROUP:
+      case WireFormatLite::TYPE_MESSAGE:
+        GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
+        break;
+    }
+  } else {
+    switch (extension.type) {
+#define HANDLE_VARINT_TYPE(UPPERCASE, CPP_CAMELCASE)                        \
+  case WireFormatLite::TYPE_##UPPERCASE: {                                  \
+    uint64 value;                                                           \
+    ptr = Varint::Parse64(ptr, &value);                                     \
+    if (ptr == nullptr) goto error;                                         \
+    if (extension.is_repeated) {                                            \
+      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
+                         extension.is_packed, value, extension.descriptor); \
+    } else {                                                                \
+      Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,   \
+                         extension.descriptor);                             \
+    }                                                                       \
+  } break
+
+      HANDLE_VARINT_TYPE(INT32, Int32);
+      HANDLE_VARINT_TYPE(INT64, Int64);
+      HANDLE_VARINT_TYPE(UINT32, UInt32);
+      HANDLE_VARINT_TYPE(UINT64, UInt64);
+#undef HANDLE_VARINT_TYPE
+#define HANDLE_SVARINT_TYPE(UPPERCASE, CPP_CAMELCASE, SIZE)                 \
+  case WireFormatLite::TYPE_##UPPERCASE: {                                  \
+    uint64 val;                                                             \
+    ptr = Varint::Parse64(ptr, &val);                                       \
+    auto value = WireFormatLite::ZigZagDecode##SIZE(val);                   \
+    if (extension.is_repeated) {                                            \
+      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
+                         extension.is_packed, value, extension.descriptor); \
+    } else {                                                                \
+      Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,   \
+                         extension.descriptor);                             \
+    }                                                                       \
+  } break
+
+      HANDLE_SVARINT_TYPE(SINT32, Int32, 32);
+      HANDLE_SVARINT_TYPE(SINT64, Int64, 64);
+#undef HANDLE_SVARINT_TYPE
+#define HANDLE_FIXED_TYPE(UPPERCASE, CPP_CAMELCASE, CPPTYPE)                \
+  case WireFormatLite::TYPE_##UPPERCASE: {                                  \
+    CPPTYPE value;                                                          \
+    std::memcpy(&value, ptr, sizeof(CPPTYPE));                              \
+    ptr += sizeof(CPPTYPE);                                                 \
+    if (extension.is_repeated) {                                            \
+      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
+                         extension.is_packed, value, extension.descriptor); \
+    } else {                                                                \
+      Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,   \
+                         extension.descriptor);                             \
+    }                                                                       \
+  } break
+
+      HANDLE_FIXED_TYPE(FIXED32, UInt32, uint32);
+      HANDLE_FIXED_TYPE(FIXED64, UInt64, uint64);
+      HANDLE_FIXED_TYPE(SFIXED32, Int32, int32);
+      HANDLE_FIXED_TYPE(SFIXED64, Int64, int64);
+      HANDLE_FIXED_TYPE(FLOAT, Float, float);
+      HANDLE_FIXED_TYPE(DOUBLE, Double, double);
+      HANDLE_FIXED_TYPE(BOOL, Bool, bool);
+#undef HANDLE_FIXED_TYPE
+
+      case WireFormatLite::TYPE_ENUM: {
+        uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (ptr == nullptr) goto error;
+        int value = val;
+
+        if (!extension.enum_validity_check.func(
+                extension.enum_validity_check.arg, value)) {
+          WriteVarint(number, val, metadata->mutable_unknown_fields());
+        } else if (extension.is_repeated) {
+          AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
+                  extension.descriptor);
+        } else {
+          SetEnum(number, WireFormatLite::TYPE_ENUM, value,
+                  extension.descriptor);
+        }
+        break;
+      }
+
+      case WireFormatLite::TYPE_BYTES:
+      case WireFormatLite::TYPE_STRING: {
+        string* value = extension.is_repeated
+                            ? AddString(number, WireFormatLite::TYPE_STRING,
+                                        extension.descriptor)
+                            : MutableString(number, WireFormatLite::TYPE_STRING,
+                                            extension.descriptor);
+        child = {StringParser, value};
+        goto length_delim;
+      }
+
+      case WireFormatLite::TYPE_GROUP: {
+        MessageLite* value =
+            extension.is_repeated
+                ? AddMessage(number, WireFormatLite::TYPE_GROUP,
+                             *extension.message_prototype, extension.descriptor)
+                : MutableMessage(number, WireFormatLite::TYPE_GROUP,
+                                 *extension.message_prototype,
+                                 extension.descriptor);
+        child = {value->_ParseFunc(), value};
+        if (!ctx->PrepareGroup(tag, &depth)) goto error;
+        ptr = child(ptr, end, ctx);
+        if (!ptr) goto error;
+        if (ctx->GroupContinues(depth)) goto group_continues;
+        break;
+      }
+
+      case WireFormatLite::TYPE_MESSAGE: {
+        MessageLite* value =
+            extension.is_repeated
+                ? AddMessage(number, WireFormatLite::TYPE_MESSAGE,
+                             *extension.message_prototype, extension.descriptor)
+                : MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
+                                 *extension.message_prototype,
+                                 extension.descriptor);
+        child = {value->_ParseFunc(), value};
+        goto length_delim;
+      }
+    }
+  }
+
+  return std::make_pair(ptr, false);
+
+error:
+  return std::make_pair(nullptr, true);
+
+length_delim:
+  uint32 size;
+  ptr = Varint::Parse32Inline(ptr, &size);
+  if (!ptr) goto error;
+  if (size > end - ptr) goto len_delim_till_end;
+  {
+    auto newend = ptr + size;
+    if (!ctx->ParseExactRange(child, ptr, newend)) {
+      goto error;
+    }
+    ptr = newend;
+  }
+  return std::make_pair(ptr, false);
+len_delim_till_end:
+  return std::make_pair(ctx->StoreAndTailCall(ptr, end, parent, child, size),
+                        true);
+
+group_continues:
+  ctx->StoreGroup(parent, child, depth);
+  return std::make_pair(ptr, true);
+}
+#endif
+
 bool ExtensionSet::ParseFieldWithExtensionInfo(
     int number, bool was_packed_on_wire, const ExtensionInfo& extension,
     io::CodedInputStream* input,
@@ -1342,15 +1583,60 @@
   return ParseField(tag, input, &finder, &skipper);
 }
 
-// Defined in extension_set_heavy.cc.
-// bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
-//                               const MessageLite* containing_type,
-//                               UnknownFieldSet* unknown_fields)
+bool ExtensionSet::ParseMessageSetLite(io::CodedInputStream* input,
+                                       ExtensionFinder* extension_finder,
+                                       FieldSkipper* field_skipper) {
+  while (true) {
+    const uint32 tag = input->ReadTag();
+    switch (tag) {
+      case 0:
+        return true;
+      case WireFormatLite::kMessageSetItemStartTag:
+        if (!ParseMessageSetItemLite(input, extension_finder, field_skipper)) {
+          return false;
+        }
+        break;
+      default:
+        if (!ParseField(tag, input, extension_finder, field_skipper)) {
+          return false;
+        }
+        break;
+    }
+  }
+}
 
-// Defined in extension_set_heavy.cc.
-// bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
-//                                    const MessageLite* containing_type,
-//                                    UnknownFieldSet* unknown_fields);
+bool ExtensionSet::ParseMessageSetItemLite(io::CodedInputStream* input,
+                                           ExtensionFinder* extension_finder,
+                                           FieldSkipper* field_skipper) {
+  struct MSLite {
+    bool ParseField(int type_id, io::CodedInputStream* input) {
+      return me->ParseField(
+          WireFormatLite::WIRETYPE_LENGTH_DELIMITED + 8 * type_id, input,
+          extension_finder, field_skipper);
+    }
+
+    bool SkipField(uint32 tag, io::CodedInputStream* input) {
+      return field_skipper->SkipField(input, tag);
+    }
+
+    ExtensionSet* me;
+    ExtensionFinder* extension_finder;
+    FieldSkipper* field_skipper;
+  };
+
+  return ParseMessageSetItemImpl(input,
+                                 MSLite{this, extension_finder, field_skipper});
+}
+
+bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
+                                   const MessageLite* containing_type,
+                                   string* unknown_fields) {
+  io::StringOutputStream zcis(unknown_fields);
+  io::CodedOutputStream output(&zcis);
+  CodedOutputStreamFieldSkipper skipper(&output);
+  GeneratedExtensionFinder finder(containing_type);
+  return ParseMessageSetLite(input, &finder, &skipper);
+}
 
 void ExtensionSet::SerializeWithCachedSizes(
     int start_field_number, int end_field_number,
@@ -1859,6 +2145,8 @@
     return;
   }
 
+  const auto old_flat_capacity = flat_capacity_;
+
   do {
     flat_capacity_ = flat_capacity_ == 0 ? 1 : flat_capacity_ * 4;
   } while (flat_capacity_ < minimum_new_capacity);
@@ -1867,17 +2155,19 @@
   const KeyValue* end = flat_end();
   if (flat_capacity_ > kMaximumFlatCapacity) {
     // Switch to LargeMap
-    map_.large = ::google::protobuf::Arena::Create<LargeMap>(arena_);
+    map_.large = Arena::Create<LargeMap>(arena_);
     LargeMap::iterator hint = map_.large->begin();
     for (const KeyValue* it = begin; it != end; ++it) {
       hint = map_.large->insert(hint, {it->first, it->second});
     }
     flat_size_ = 0;
   } else {
-    map_.flat = ::google::protobuf::Arena::CreateArray<KeyValue>(arena_, flat_capacity_);
+    map_.flat = Arena::CreateArray<KeyValue>(arena_, flat_capacity_);
     std::copy(begin, end, map_.flat);
   }
-  if (arena_ == NULL) delete[] begin;
+  if (arena_ == nullptr) {
+    DeleteFlatMap(begin, old_flat_capacity);
+  }
 }
 
 // static
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index 04d0e62..c22dfe0 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -47,32 +47,45 @@
 
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/once.h>
 #include <google/protobuf/repeated_field.h>
 
+#include <google/protobuf/port_def.inc>
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+#include <google/protobuf/parse_context.h>
+#endif
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
-
 namespace protobuf {
-  class Arena;
-  class Descriptor;                                    // descriptor.h
-  class FieldDescriptor;                               // descriptor.h
-  class DescriptorPool;                                // descriptor.h
-  class MessageLite;                                   // message_lite.h
-  class Message;                                       // message.h
-  class MessageFactory;                                // message.h
-  class UnknownFieldSet;                               // unknown_field_set.h
-  namespace io {
-    class CodedInputStream;                              // coded_stream.h
-    class CodedOutputStream;                             // coded_stream.h
-  }
-  namespace internal {
-    class FieldSkipper;                                  // wire_format_lite.h
-  }
+class Arena;
+class Descriptor;       // descriptor.h
+class FieldDescriptor;  // descriptor.h
+class DescriptorPool;   // descriptor.h
+class MessageLite;      // message_lite.h
+class Message;          // message.h
+class MessageFactory;   // message.h
+class UnknownFieldSet;  // unknown_field_set.h
+namespace io {
+class CodedInputStream;   // coded_stream.h
+class CodedOutputStream;  // coded_stream.h
+}  // namespace io
+namespace internal {
+class FieldSkipper;  // wire_format_lite.h
 }
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace internal {
 
+class InternalMetadataWithArenaLite;
+class InternalMetadataWithArena;
+
 // Used to store values of type WireFormatLite::FieldType without having to
 // #include wire_format_lite.h.  Also, ensures that we use only one byte to
 // store these values, which is important to keep the layout of
@@ -92,7 +105,9 @@
 struct ExtensionInfo {
   inline ExtensionInfo() {}
   inline ExtensionInfo(FieldType type_param, bool isrepeated, bool ispacked)
-      : type(type_param), is_repeated(isrepeated), is_packed(ispacked),
+      : type(type_param),
+        is_repeated(isrepeated),
+        is_packed(ispacked),
         descriptor(NULL) {}
 
   FieldType type;
@@ -134,7 +149,7 @@
   virtual ~GeneratedExtensionFinder() {}
 
   // Returns true and fills in *output if found, otherwise returns false.
-  virtual bool Find(int number, ExtensionInfo* output) override;
+  bool Find(int number, ExtensionInfo* output) override;
 
  private:
   const MessageLite* containing_type_;
@@ -160,7 +175,7 @@
 class LIBPROTOBUF_EXPORT ExtensionSet {
  public:
   ExtensionSet();
-  explicit ExtensionSet(::google::protobuf::Arena* arena);
+  explicit ExtensionSet(Arena* arena);
   ~ExtensionSet();
 
   // These are called at startup by protocol-compiler-generated code to
@@ -168,9 +183,9 @@
   // to look up extensions for parsed field numbers.  Note that dynamic parsing
   // does not use ParseField(); only protocol-compiler-generated parsing
   // methods do.
-  static void RegisterExtension(const MessageLite* containing_type,
-                                int number, FieldType type,
-                                bool is_repeated, bool is_packed);
+  static void RegisterExtension(const MessageLite* containing_type, int number,
+                                FieldType type, bool is_repeated,
+                                bool is_packed);
   static void RegisterEnumExtension(const MessageLite* containing_type,
                                     int number, FieldType type,
                                     bool is_repeated, bool is_packed,
@@ -219,22 +234,22 @@
   // - Strings provide Mutable() in addition to Set() accessors.
 
   bool Has(int number) const;
-  int ExtensionSize(int number) const;   // Size of a repeated extension.
-  int NumExtensions() const;  // The number of extensions
+  int ExtensionSize(int number) const;  // Size of a repeated extension.
+  int NumExtensions() const;            // The number of extensions
   FieldType ExtensionType(int number) const;
   void ClearExtension(int number);
 
   // singular fields -------------------------------------------------
 
-  int32  GetInt32 (int number, int32  default_value) const;
-  int64  GetInt64 (int number, int64  default_value) const;
+  int32 GetInt32(int number, int32 default_value) const;
+  int64 GetInt64(int number, int64 default_value) const;
   uint32 GetUInt32(int number, uint32 default_value) const;
   uint64 GetUInt64(int number, uint64 default_value) const;
-  float  GetFloat (int number, float  default_value) const;
+  float GetFloat(int number, float default_value) const;
   double GetDouble(int number, double default_value) const;
-  bool   GetBool  (int number, bool   default_value) const;
-  int    GetEnum  (int number, int    default_value) const;
-  const string & GetString (int number, const string&  default_value) const;
+  bool GetBool(int number, bool default_value) const;
+  int GetEnum(int number, int default_value) const;
+  const string& GetString(int number, const string& default_value) const;
   const MessageLite& GetMessage(int number,
                                 const MessageLite& default_value) const;
   const MessageLite& GetMessage(int number, const Descriptor* message_type,
@@ -244,16 +259,16 @@
   // the extension lives in the same pool as the descriptor for the containing
   // type.
 #define desc const FieldDescriptor* descriptor  // avoid line wrapping
-  void SetInt32 (int number, FieldType type, int32  value, desc);
-  void SetInt64 (int number, FieldType type, int64  value, desc);
+  void SetInt32(int number, FieldType type, int32 value, desc);
+  void SetInt64(int number, FieldType type, int64 value, desc);
   void SetUInt32(int number, FieldType type, uint32 value, desc);
   void SetUInt64(int number, FieldType type, uint64 value, desc);
-  void SetFloat (int number, FieldType type, float  value, desc);
+  void SetFloat(int number, FieldType type, float value, desc);
   void SetDouble(int number, FieldType type, double value, desc);
-  void SetBool  (int number, FieldType type, bool   value, desc);
-  void SetEnum  (int number, FieldType type, int    value, desc);
+  void SetBool(int number, FieldType type, bool value, desc);
+  void SetEnum(int number, FieldType type, int value, desc);
   void SetString(int number, FieldType type, const string& value, desc);
-  string * MutableString (int number, FieldType type, desc);
+  string* MutableString(int number, FieldType type, desc);
   MessageLite* MutableMessage(int number, FieldType type,
                               const MessageLite& prototype, desc);
   MessageLite* MutableMessage(const FieldDescriptor* decsriptor,
@@ -268,15 +283,15 @@
                                       const FieldDescriptor* descriptor,
                                       MessageLite* message);
   MessageLite* ReleaseMessage(int number, const MessageLite& prototype);
-  MessageLite* UnsafeArenaReleaseMessage(
-      int number, const MessageLite& prototype);
+  MessageLite* UnsafeArenaReleaseMessage(int number,
+                                         const MessageLite& prototype);
 
   MessageLite* ReleaseMessage(const FieldDescriptor* descriptor,
                               MessageFactory* factory);
   MessageLite* UnsafeArenaReleaseMessage(const FieldDescriptor* descriptor,
                                          MessageFactory* factory);
 #undef desc
-  ::google::protobuf::Arena* GetArenaNoVirtual() const { return arena_; }
+  Arena* GetArenaNoVirtual() const { return arena_; }
 
   // repeated fields -------------------------------------------------
 
@@ -287,8 +302,8 @@
   // Fetches a mutable version of a RepeatedField extension by number,
   // instantiating one if none exists. Similar to above, user should not use
   // this directly; it underlies MutableRepeatedExtension().
-  void* MutableRawRepeatedField(int number, FieldType field_type,
-                                bool packed, const FieldDescriptor* desc);
+  void* MutableRawRepeatedField(int number, FieldType field_type, bool packed,
+                                const FieldDescriptor* desc);
 
   // This is an overload of MutableRawRepeatedField to maintain compatibility
   // with old code using a previous API. This version of
@@ -296,40 +311,40 @@
   // (E.g.: borg/clients/internal/proto1/proto2_reflection.cc.)
   void* MutableRawRepeatedField(int number);
 
-  int32  GetRepeatedInt32 (int number, int index) const;
-  int64  GetRepeatedInt64 (int number, int index) const;
+  int32 GetRepeatedInt32(int number, int index) const;
+  int64 GetRepeatedInt64(int number, int index) const;
   uint32 GetRepeatedUInt32(int number, int index) const;
   uint64 GetRepeatedUInt64(int number, int index) const;
-  float  GetRepeatedFloat (int number, int index) const;
+  float GetRepeatedFloat(int number, int index) const;
   double GetRepeatedDouble(int number, int index) const;
-  bool   GetRepeatedBool  (int number, int index) const;
-  int    GetRepeatedEnum  (int number, int index) const;
-  const string & GetRepeatedString (int number, int index) const;
+  bool GetRepeatedBool(int number, int index) const;
+  int GetRepeatedEnum(int number, int index) const;
+  const string& GetRepeatedString(int number, int index) const;
   const MessageLite& GetRepeatedMessage(int number, int index) const;
 
-  void SetRepeatedInt32 (int number, int index, int32  value);
-  void SetRepeatedInt64 (int number, int index, int64  value);
+  void SetRepeatedInt32(int number, int index, int32 value);
+  void SetRepeatedInt64(int number, int index, int64 value);
   void SetRepeatedUInt32(int number, int index, uint32 value);
   void SetRepeatedUInt64(int number, int index, uint64 value);
-  void SetRepeatedFloat (int number, int index, float  value);
+  void SetRepeatedFloat(int number, int index, float value);
   void SetRepeatedDouble(int number, int index, double value);
-  void SetRepeatedBool  (int number, int index, bool   value);
-  void SetRepeatedEnum  (int number, int index, int    value);
+  void SetRepeatedBool(int number, int index, bool value);
+  void SetRepeatedEnum(int number, int index, int value);
   void SetRepeatedString(int number, int index, const string& value);
-  string * MutableRepeatedString (int number, int index);
+  string* MutableRepeatedString(int number, int index);
   MessageLite* MutableRepeatedMessage(int number, int index);
 
 #define desc const FieldDescriptor* descriptor  // avoid line wrapping
-  void AddInt32 (int number, FieldType type, bool packed, int32  value, desc);
-  void AddInt64 (int number, FieldType type, bool packed, int64  value, desc);
+  void AddInt32(int number, FieldType type, bool packed, int32 value, desc);
+  void AddInt64(int number, FieldType type, bool packed, int64 value, desc);
   void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc);
   void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc);
-  void AddFloat (int number, FieldType type, bool packed, float  value, desc);
+  void AddFloat(int number, FieldType type, bool packed, float value, desc);
   void AddDouble(int number, FieldType type, bool packed, double value, desc);
-  void AddBool  (int number, FieldType type, bool packed, bool   value, desc);
-  void AddEnum  (int number, FieldType type, bool packed, int    value, desc);
+  void AddBool(int number, FieldType type, bool packed, bool value, desc);
+  void AddEnum(int number, FieldType type, bool packed, int value, desc);
   void AddString(int number, FieldType type, const string& value, desc);
-  string * AddString (int number, FieldType type, desc);
+  string* AddString(int number, FieldType type, desc);
   MessageLite* AddMessage(int number, FieldType type,
                           const MessageLite& prototype, desc);
   MessageLite* AddMessage(const FieldDescriptor* descriptor,
@@ -378,8 +393,31 @@
                   const MessageLite* containing_type,
                   io::CodedOutputStream* unknown_fields);
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  // Lite parser
+  std::pair<const char*, bool> ParseField(
+      uint32 tag, ParseClosure parent, const char* begin, const char* end,
+      const MessageLite* containing_type,
+      internal::InternalMetadataWithArenaLite* metadata,
+      internal::ParseContext* ctx);
+  // Full parser
+  std::pair<const char*, bool> ParseField(
+      uint32 tag, ParseClosure parent, const char* begin, const char* end,
+      const Message* containing_type,
+      internal::InternalMetadataWithArena* metadata,
+      internal::ParseContext* ctx);
+  const char* ParseMessageSetItem(ParseClosure parent, const char* begin,
+                                  const char* end,
+                                  const Message* containing_type,
+                                  internal::InternalMetadataWithArena* metadata,
+                                  internal::ParseContext* ctx);
+#endif
+
   // Parse an entire message in MessageSet format.  Such messages have no
   // fields, only extensions.
+  bool ParseMessageSetLite(io::CodedInputStream* input,
+                           ExtensionFinder* extension_finder,
+                           FieldSkipper* field_skipper);
   bool ParseMessageSet(io::CodedInputStream* input,
                        ExtensionFinder* extension_finder,
                        MessageSetFieldSkipper* field_skipper);
@@ -387,7 +425,8 @@
   // Specific versions for lite or full messages (constructs the appropriate
   // FieldSkipper automatically).
   bool ParseMessageSet(io::CodedInputStream* input,
-                       const MessageLite* containing_type);
+                       const MessageLite* containing_type,
+                       string* unknown_fields);
   bool ParseMessageSet(io::CodedInputStream* input,
                        const Message* containing_type,
                        UnknownFieldSet* unknown_fields);
@@ -396,8 +435,7 @@
   //   [start_field_number, end_field_number)
   // to the output stream, using the cached sizes computed when ByteSize() was
   // last called.  Note that the range bounds are inclusive-exclusive.
-  void SerializeWithCachedSizes(int start_field_number,
-                                int end_field_number,
+  void SerializeWithCachedSizes(int start_field_number, int end_field_number,
                                 io::CodedOutputStream* output) const;
 
   // Same as SerializeWithCachedSizes, but without any bounds checking.
@@ -446,29 +484,26 @@
   int SpaceUsedExcludingSelf() const;
 
  private:
-
   // Interface of a lazily parsed singular message extension.
   class LIBPROTOBUF_EXPORT LazyMessageExtension {
    public:
     LazyMessageExtension() {}
     virtual ~LazyMessageExtension() {}
 
-    virtual LazyMessageExtension* New(::google::protobuf::Arena* arena) const = 0;
+    virtual LazyMessageExtension* New(Arena* arena) const = 0;
     virtual const MessageLite& GetMessage(
         const MessageLite& prototype) const = 0;
     virtual MessageLite* MutableMessage(const MessageLite& prototype) = 0;
-    virtual void SetAllocatedMessage(MessageLite *message) = 0;
-    virtual void UnsafeArenaSetAllocatedMessage(MessageLite *message) = 0;
+    virtual void SetAllocatedMessage(MessageLite* message) = 0;
+    virtual void UnsafeArenaSetAllocatedMessage(MessageLite* message) = 0;
     virtual MessageLite* ReleaseMessage(const MessageLite& prototype) = 0;
     virtual MessageLite* UnsafeArenaReleaseMessage(
         const MessageLite& prototype) = 0;
 
     virtual bool IsInitialized() const = 0;
 
-    PROTOBUF_RUNTIME_DEPRECATED("Please use ByteSizeLong() instead")
-    virtual int ByteSize() const {
-      return internal::ToIntSize(ByteSizeLong());
-    }
+    GOOGLE_PROTOBUF_DEPRECATED_MSG("Please use ByteSizeLong() instead")
+    virtual int ByteSize() const { return internal::ToIntSize(ByteSizeLong()); }
     virtual size_t ByteSizeLong() const = 0;
     virtual size_t SpaceUsedLong() const = 0;
 
@@ -496,27 +531,27 @@
     // The order of these fields packs Extension into 24 bytes when using 8
     // byte alignment. Consider this when adding or removing fields here.
     union {
-      int32                 int32_value;
-      int64                 int64_value;
-      uint32                uint32_value;
-      uint64                uint64_value;
-      float                 float_value;
-      double                double_value;
-      bool                  bool_value;
-      int                   enum_value;
-      string*               string_value;
-      MessageLite*          message_value;
+      int32 int32_value;
+      int64 int64_value;
+      uint32 uint32_value;
+      uint64 uint64_value;
+      float float_value;
+      double double_value;
+      bool bool_value;
+      int enum_value;
+      string* string_value;
+      MessageLite* message_value;
       LazyMessageExtension* lazymessage_value;
 
-      RepeatedField   <int32      >* repeated_int32_value;
-      RepeatedField   <int64      >* repeated_int64_value;
-      RepeatedField   <uint32     >* repeated_uint32_value;
-      RepeatedField   <uint64     >* repeated_uint64_value;
-      RepeatedField   <float      >* repeated_float_value;
-      RepeatedField   <double     >* repeated_double_value;
-      RepeatedField   <bool       >* repeated_bool_value;
-      RepeatedField   <int        >* repeated_enum_value;
-      RepeatedPtrField<string     >* repeated_string_value;
+      RepeatedField<int32>* repeated_int32_value;
+      RepeatedField<int64>* repeated_int64_value;
+      RepeatedField<uint32>* repeated_uint32_value;
+      RepeatedField<uint64>* repeated_uint64_value;
+      RepeatedField<float>* repeated_float_value;
+      RepeatedField<double>* repeated_double_value;
+      RepeatedField<bool>* repeated_bool_value;
+      RepeatedField<int>* repeated_enum_value;
+      RepeatedPtrField<string>* repeated_string_value;
       RepeatedPtrField<MessageLite>* repeated_message_value;
     };
 
@@ -552,20 +587,15 @@
     const FieldDescriptor* descriptor;
 
     // Some helper methods for operations on a single Extension.
-    void SerializeFieldWithCachedSizes(
-        int number,
-        io::CodedOutputStream* output) const;
-    uint8* InternalSerializeFieldWithCachedSizesToArray(
-        int number,
-        bool deterministic,
-        uint8* target) const;
+    void SerializeFieldWithCachedSizes(int number,
+                                       io::CodedOutputStream* output) const;
+    uint8* InternalSerializeFieldWithCachedSizesToArray(int number,
+                                                        bool deterministic,
+                                                        uint8* target) const;
     void SerializeMessageSetItemWithCachedSizes(
-        int number,
-        io::CodedOutputStream* output) const;
+        int number, io::CodedOutputStream* output) const;
     uint8* InternalSerializeMessageSetItemWithCachedSizesToArray(
-        int number,
-        bool deterministic,
-        uint8* target) const;
+        int number, bool deterministic, uint8* target) const;
     size_t ByteSize(int number) const;
     size_t MessageSetItemByteSize(int number) const;
     void Clear();
@@ -659,6 +689,13 @@
   // Merges existing Extension from other_extension
   void InternalExtensionMergeFrom(int number, const Extension& other_extension);
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  bool FindExtension(uint32 tag, const Message* containing_type,
+                     const internal::ParseContext* ctx,
+                     ExtensionInfo* extension, int* number,
+                     bool* was_packed_on_wire);
+#endif
+
   // Returns true and fills field_number and extension if extension is found.
   // Note to support packed repeated field compatibility, it also fills whether
   // the tag on wire is packed, which can be different from
@@ -680,8 +717,7 @@
   // positioned immediately after the wire tag. This method is called in
   // ParseField() after field number and was_packed_on_wire is extracted from
   // the wire tag and ExtensionInfo is found by the field number.
-  bool ParseFieldWithExtensionInfo(int field_number,
-                                   bool was_packed_on_wire,
+  bool ParseFieldWithExtensionInfo(int field_number, bool was_packed_on_wire,
                                    const ExtensionInfo& extension,
                                    io::CodedInputStream* input,
                                    FieldSkipper* field_skipper);
@@ -704,6 +740,11 @@
 
   // Parse a single MessageSet item -- called just after the item group start
   // tag has been read.
+  bool ParseMessageSetItemLite(io::CodedInputStream* input,
+                               ExtensionFinder* extension_finder,
+                               FieldSkipper* field_skipper);
+  // Parse a single MessageSet item -- called just after the item group start
+  // tag has been read.
   bool ParseMessageSetItem(io::CodedInputStream* input,
                            ExtensionFinder* extension_finder,
                            MessageSetFieldSkipper* field_skipper);
@@ -735,7 +776,7 @@
     return map_.flat + flat_size_;
   }
 
-  ::google::protobuf::Arena* arena_;
+  Arena* arena_;
 
   // Manual memory-management:
   // map_.flat is an allocated array of flat_capacity_ elements.
@@ -750,6 +791,8 @@
     LargeMap* large;
   } map_;
 
+  static void DeleteFlatMap(const KeyValue* flat, uint16 flat_capacity);
+
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
 };
 
@@ -841,8 +884,8 @@
 
   static inline ConstType Get(int number, const ExtensionSet& set,
                               ConstType default_value);
-  static inline void Set(int number, FieldType field_type,
-                         ConstType value, ExtensionSet* set);
+  static inline void Set(int number, FieldType field_type, ConstType value,
+                         ExtensionSet* set);
   template <typename ExtendeeT>
   static void Register(int number, FieldType type, bool is_packed) {
     ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number,
@@ -861,14 +904,15 @@
 
   static inline Type Get(int number, const ExtensionSet& set, int index);
   static inline void Set(int number, int index, Type value, ExtensionSet* set);
-  static inline void Add(int number, FieldType field_type,
-                         bool is_packed, Type value, ExtensionSet* set);
+  static inline void Add(int number, FieldType field_type, bool is_packed,
+                         Type value, ExtensionSet* set);
 
-  static inline const RepeatedField<ConstType>&
-      GetRepeated(int number, const ExtensionSet& set);
-  static inline RepeatedField<Type>*
-      MutableRepeated(int number, FieldType field_type,
-                      bool is_packed, ExtensionSet* set);
+  static inline const RepeatedField<ConstType>& GetRepeated(
+      int number, const ExtensionSet& set);
+  static inline RepeatedField<Type>* MutableRepeated(int number,
+                                                     FieldType field_type,
+                                                     bool is_packed,
+                                                     ExtensionSet* set);
 
   static const RepeatedFieldType* GetDefaultRepeatedField();
   template <typename ExtendeeT>
@@ -878,11 +922,10 @@
   }
 };
 
-LIBPROTOBUF_EXPORT extern ProtobufOnceType repeated_primitive_generic_type_traits_once_init_;
-
 class LIBPROTOBUF_EXPORT RepeatedPrimitiveDefaults {
  private:
-  template<typename Type> friend class RepeatedPrimitiveTypeTraits;
+  template <typename Type>
+  friend class RepeatedPrimitiveTypeTraits;
   static const RepeatedPrimitiveDefaults* default_instance();
   RepeatedField<int32> default_repeated_field_int32_;
   RepeatedField<int64> default_repeated_field_int64_;
@@ -893,57 +936,62 @@
   RepeatedField<bool> default_repeated_field_bool_;
 };
 
-#define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD)                       \
-template<> inline TYPE PrimitiveTypeTraits<TYPE>::Get(                     \
-    int number, const ExtensionSet& set, TYPE default_value) {             \
-  return set.Get##METHOD(number, default_value);                           \
-}                                                                          \
-template<> inline void PrimitiveTypeTraits<TYPE>::Set(                     \
-    int number, FieldType field_type, TYPE value, ExtensionSet* set) {     \
-  set->Set##METHOD(number, field_type, value, NULL);                       \
-}                                                                          \
-                                                                           \
-template<> inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get(             \
-    int number, const ExtensionSet& set, int index) {                      \
-  return set.GetRepeated##METHOD(number, index);                           \
-}                                                                          \
-template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Set(             \
-    int number, int index, TYPE value, ExtensionSet* set) {                \
-  set->SetRepeated##METHOD(number, index, value);                          \
-}                                                                          \
-template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add(             \
-    int number, FieldType field_type, bool is_packed,                      \
-    TYPE value, ExtensionSet* set) {                                       \
-  set->Add##METHOD(number, field_type, is_packed, value, NULL);            \
-}                                                                          \
-template<> inline const RepeatedField<TYPE>*                               \
-    RepeatedPrimitiveTypeTraits<TYPE>::GetDefaultRepeatedField() {         \
-  return &RepeatedPrimitiveDefaults::default_instance()                    \
-              ->default_repeated_field_##TYPE##_;                          \
-}                                                                          \
-template<> inline const RepeatedField<TYPE>&                               \
-    RepeatedPrimitiveTypeTraits<TYPE>::GetRepeated(int number,             \
-                                               const ExtensionSet& set) {  \
-  return *reinterpret_cast<const RepeatedField<TYPE>*>(                    \
-                            set.GetRawRepeatedField(                       \
-                                number, GetDefaultRepeatedField()));       \
-}                                                                          \
-template<> inline RepeatedField<TYPE>*                                     \
-    RepeatedPrimitiveTypeTraits<TYPE>::MutableRepeated(int number,         \
-                                                   FieldType field_type,   \
-                                                   bool is_packed,         \
-                                                   ExtensionSet* set) {    \
-  return reinterpret_cast<RepeatedField<TYPE>*>(                           \
-      set->MutableRawRepeatedField(number, field_type, is_packed, NULL));  \
-}
+#define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD)                           \
+  template <>                                                                  \
+  inline TYPE PrimitiveTypeTraits<TYPE>::Get(                                  \
+      int number, const ExtensionSet& set, TYPE default_value) {               \
+    return set.Get##METHOD(number, default_value);                             \
+  }                                                                            \
+  template <>                                                                  \
+  inline void PrimitiveTypeTraits<TYPE>::Set(int number, FieldType field_type, \
+                                             TYPE value, ExtensionSet* set) {  \
+    set->Set##METHOD(number, field_type, value, NULL);                         \
+  }                                                                            \
+                                                                               \
+  template <>                                                                  \
+  inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get(                          \
+      int number, const ExtensionSet& set, int index) {                        \
+    return set.GetRepeated##METHOD(number, index);                             \
+  }                                                                            \
+  template <>                                                                  \
+  inline void RepeatedPrimitiveTypeTraits<TYPE>::Set(                          \
+      int number, int index, TYPE value, ExtensionSet* set) {                  \
+    set->SetRepeated##METHOD(number, index, value);                            \
+  }                                                                            \
+  template <>                                                                  \
+  inline void RepeatedPrimitiveTypeTraits<TYPE>::Add(                          \
+      int number, FieldType field_type, bool is_packed, TYPE value,            \
+      ExtensionSet* set) {                                                     \
+    set->Add##METHOD(number, field_type, is_packed, value, NULL);              \
+  }                                                                            \
+  template <>                                                                  \
+  inline const RepeatedField<TYPE>*                                            \
+  RepeatedPrimitiveTypeTraits<TYPE>::GetDefaultRepeatedField() {               \
+    return &RepeatedPrimitiveDefaults::default_instance()                      \
+                ->default_repeated_field_##TYPE##_;                            \
+  }                                                                            \
+  template <>                                                                  \
+  inline const RepeatedField<TYPE>&                                            \
+  RepeatedPrimitiveTypeTraits<TYPE>::GetRepeated(int number,                   \
+                                                 const ExtensionSet& set) {    \
+    return *reinterpret_cast<const RepeatedField<TYPE>*>(                      \
+        set.GetRawRepeatedField(number, GetDefaultRepeatedField()));           \
+  }                                                                            \
+  template <>                                                                  \
+  inline RepeatedField<TYPE>*                                                  \
+  RepeatedPrimitiveTypeTraits<TYPE>::MutableRepeated(                          \
+      int number, FieldType field_type, bool is_packed, ExtensionSet* set) {   \
+    return reinterpret_cast<RepeatedField<TYPE>*>(                             \
+        set->MutableRawRepeatedField(number, field_type, is_packed, NULL));    \
+  }
 
-PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32,  Int32)
-PROTOBUF_DEFINE_PRIMITIVE_TYPE( int64,  Int64)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(int32, Int32)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(int64, Int64)
 PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32, UInt32)
 PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64, UInt64)
-PROTOBUF_DEFINE_PRIMITIVE_TYPE( float,  Float)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(float, Float)
 PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double)
-PROTOBUF_DEFINE_PRIMITIVE_TYPE(  bool,   Bool)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(bool, Bool)
 
 #undef PROTOBUF_DEFINE_PRIMITIVE_TYPE
 
@@ -961,8 +1009,8 @@
                                   ConstType default_value) {
     return set.GetString(number, default_value);
   }
-  static inline void Set(int number, FieldType field_type,
-                         const string& value, ExtensionSet* set) {
+  static inline void Set(int number, FieldType field_type, const string& value,
+                         ExtensionSet* set) {
     set->SetString(number, field_type, value, NULL);
   }
   static inline string* Mutable(int number, FieldType field_type,
@@ -988,34 +1036,33 @@
                                   int index) {
     return set.GetRepeatedString(number, index);
   }
-  static inline void Set(int number, int index,
-                         const string& value, ExtensionSet* set) {
+  static inline void Set(int number, int index, const string& value,
+                         ExtensionSet* set) {
     set->SetRepeatedString(number, index, value);
   }
   static inline string* Mutable(int number, int index, ExtensionSet* set) {
     return set->MutableRepeatedString(number, index);
   }
-  static inline void Add(int number, FieldType field_type,
-                         bool /*is_packed*/, const string& value,
-                         ExtensionSet* set) {
+  static inline void Add(int number, FieldType field_type, bool /*is_packed*/,
+                         const string& value, ExtensionSet* set) {
     set->AddString(number, field_type, value, NULL);
   }
   static inline string* Add(int number, FieldType field_type,
                             ExtensionSet* set) {
     return set->AddString(number, field_type, NULL);
   }
-  static inline const RepeatedPtrField<string>&
-      GetRepeated(int number, const ExtensionSet& set) {
+  static inline const RepeatedPtrField<string>& GetRepeated(
+      int number, const ExtensionSet& set) {
     return *reinterpret_cast<const RepeatedPtrField<string>*>(
         set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
   }
 
-  static inline RepeatedPtrField<string>*
-      MutableRepeated(int number, FieldType field_type,
-                      bool is_packed, ExtensionSet* set) {
+  static inline RepeatedPtrField<string>* MutableRepeated(int number,
+                                                          FieldType field_type,
+                                                          bool is_packed,
+                                                          ExtensionSet* set) {
     return reinterpret_cast<RepeatedPtrField<string>*>(
-        set->MutableRawRepeatedField(number, field_type,
-                                     is_packed, NULL));
+        set->MutableRawRepeatedField(number, field_type, is_packed, NULL));
   }
 
   static const RepeatedFieldType* GetDefaultRepeatedField();
@@ -1047,8 +1094,8 @@
                               ConstType default_value) {
     return static_cast<Type>(set.GetEnum(number, default_value));
   }
-  static inline void Set(int number, FieldType field_type,
-                         ConstType value, ExtensionSet* set) {
+  static inline void Set(int number, FieldType field_type, ConstType value,
+                         ExtensionSet* set) {
     GOOGLE_DCHECK(IsValid(value));
     set->SetEnum(number, field_type, value, NULL);
   }
@@ -1071,19 +1118,18 @@
   static inline ConstType Get(int number, const ExtensionSet& set, int index) {
     return static_cast<Type>(set.GetRepeatedEnum(number, index));
   }
-  static inline void Set(int number, int index,
-                         ConstType value, ExtensionSet* set) {
+  static inline void Set(int number, int index, ConstType value,
+                         ExtensionSet* set) {
     GOOGLE_DCHECK(IsValid(value));
     set->SetRepeatedEnum(number, index, value);
   }
-  static inline void Add(int number, FieldType field_type,
-                         bool is_packed, ConstType value, ExtensionSet* set) {
+  static inline void Add(int number, FieldType field_type, bool is_packed,
+                         ConstType value, ExtensionSet* set) {
     GOOGLE_DCHECK(IsValid(value));
     set->AddEnum(number, field_type, is_packed, value, NULL);
   }
-  static inline const RepeatedField<Type>& GetRepeated(int number,
-                                                       const ExtensionSet&
-                                                       set) {
+  static inline const RepeatedField<Type>& GetRepeated(
+      int number, const ExtensionSet& set) {
     // Hack: the `Extension` struct stores a RepeatedField<int> for enums.
     // RepeatedField<int> cannot implicitly convert to RepeatedField<EnumType>
     // so we need to do some casting magic. See message.h for similar
@@ -1132,13 +1178,12 @@
 
   static inline ConstType Get(int number, const ExtensionSet& set,
                               ConstType default_value) {
-    return static_cast<const Type&>(
-        set.GetMessage(number, default_value));
+    return static_cast<const Type&>(set.GetMessage(number, default_value));
   }
   static inline MutableType Mutable(int number, FieldType field_type,
                                     ExtensionSet* set) {
-    return static_cast<Type*>(
-      set->MutableMessage(number, field_type, Type::default_instance(), NULL));
+    return static_cast<Type*>(set->MutableMessage(
+        number, field_type, Type::default_instance(), NULL));
   }
   static inline void SetAllocated(int number, FieldType field_type,
                                   MutableType message, ExtensionSet* set) {
@@ -1151,14 +1196,14 @@
   }
   static inline MutableType Release(int number, FieldType /* field_type */,
                                     ExtensionSet* set) {
-    return static_cast<Type*>(set->ReleaseMessage(
-        number, Type::default_instance()));
+    return static_cast<Type*>(
+        set->ReleaseMessage(number, Type::default_instance()));
   }
   static inline MutableType UnsafeArenaRelease(int number,
                                                FieldType /* field_type */,
                                                ExtensionSet* set) {
-    return static_cast<Type*>(set->UnsafeArenaReleaseMessage(
-        number, Type::default_instance()));
+    return static_cast<Type*>(
+        set->UnsafeArenaReleaseMessage(number, Type::default_instance()));
   }
   template <typename ExtendeeT>
   static void Register(int number, FieldType type, bool is_packed) {
@@ -1191,9 +1236,8 @@
     return static_cast<Type*>(
         set->AddMessage(number, field_type, Type::default_instance(), NULL));
   }
-  static inline const RepeatedPtrField<Type>& GetRepeated(int number,
-                                                          const ExtensionSet&
-                                                          set) {
+  static inline const RepeatedPtrField<Type>& GetRepeated(
+      int number, const ExtensionSet& set) {
     // See notes above in RepeatedEnumTypeTraits::GetRepeated(): same
     // casting hack applies here, because a RepeatedPtrField<MessageLite>
     // cannot naturally become a RepeatedPtrType<Type> even though Type is
@@ -1219,9 +1263,9 @@
   }
 };
 
-template<typename Type> inline
-    const typename RepeatedMessageTypeTraits<Type>::RepeatedFieldType*
-    RepeatedMessageTypeTraits<Type>::GetDefaultRepeatedField() {
+template <typename Type>
+inline const typename RepeatedMessageTypeTraits<Type>::RepeatedFieldType*
+RepeatedMessageTypeTraits<Type>::GetDefaultRepeatedField() {
   static auto instance = OnShutdownDelete(new RepeatedFieldType);
   return instance;
 }
@@ -1236,15 +1280,15 @@
 //
 // Note that we could, in theory, supply the field number as a template
 // parameter, and thus make an instance of ExtensionIdentifier have no
-// actual contents.  However, if we did that, then using at extension
+// actual contents.  However, if we did that, then using an extension
 // identifier would not necessarily cause the compiler to output any sort
 // of reference to any symbol defined in the extension's .pb.o file.  Some
 // linkers will actually drop object files that are not explicitly referenced,
 // but that would be bad because it would cause this extension to not be
 // registered at static initialization, and therefore using it would crash.
 
-template <typename ExtendeeType, typename TypeTraitsType,
-          FieldType field_type, bool is_packed>
+template <typename ExtendeeType, typename TypeTraitsType, FieldType field_type,
+          bool is_packed>
 class ExtensionIdentifier {
  public:
   typedef TypeTraitsType TypeTraits;
@@ -1284,179 +1328,179 @@
 #define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME)                        \
   /* Has, Size, Clear */                                                      \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline bool HasExtension(                                                   \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \
     return _extensions_.Has(id.number());                                     \
   }                                                                           \
                                                                               \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline void ClearExtension(                                                 \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {       \
     _extensions_.ClearExtension(id.number());                                 \
   }                                                                           \
                                                                               \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline int ExtensionSize(                                                   \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \
     return _extensions_.ExtensionSize(id.number());                           \
   }                                                                           \
                                                                               \
   /* Singular accessors */                                                    \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline typename _proto_TypeTraits::Singular::ConstType GetExtension(        \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \
     return _proto_TypeTraits::Get(id.number(), _extensions_,                  \
                                   id.default_value());                        \
   }                                                                           \
                                                                               \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(  \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {       \
     return _proto_TypeTraits::Mutable(id.number(), _field_type,               \
                                       &_extensions_);                         \
   }                                                                           \
                                                                               \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline void SetExtension(                                                   \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,         \
       typename _proto_TypeTraits::Singular::ConstType value) {                \
     _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);   \
   }                                                                           \
                                                                               \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline void SetAllocatedExtension(                                          \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,         \
       typename _proto_TypeTraits::Singular::MutableType value) {              \
-    _proto_TypeTraits::SetAllocated(id.number(), _field_type,                 \
-                                    value, &_extensions_);                    \
+    _proto_TypeTraits::SetAllocated(id.number(), _field_type, value,          \
+                                    &_extensions_);                           \
   }                                                                           \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline void UnsafeArenaSetAllocatedExtension(                               \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,         \
       typename _proto_TypeTraits::Singular::MutableType value) {              \
     _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type,      \
                                                value, &_extensions_);         \
   }                                                                           \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline typename _proto_TypeTraits::Singular::MutableType ReleaseExtension(  \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {       \
     return _proto_TypeTraits::Release(id.number(), _field_type,               \
                                       &_extensions_);                         \
   }                                                                           \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline typename _proto_TypeTraits::Singular::MutableType                    \
-      UnsafeArenaReleaseExtension(                                            \
-          const ::google::protobuf::internal::ExtensionIdentifier<                      \
-            CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {     \
+  UnsafeArenaReleaseExtension(                                                \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {       \
     return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type,    \
                                                  &_extensions_);              \
   }                                                                           \
                                                                               \
   /* Repeated accessors */                                                    \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(        \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,         \
       int index) const {                                                      \
     return _proto_TypeTraits::Get(id.number(), _extensions_, index);          \
   }                                                                           \
                                                                               \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(  \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,         \
       int index) {                                                            \
     return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);     \
   }                                                                           \
                                                                               \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline void SetExtension(                                                   \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,         \
       int index, typename _proto_TypeTraits::Repeated::ConstType value) {     \
     _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);         \
   }                                                                           \
                                                                               \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(      \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {       \
     return _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);   \
   }                                                                           \
                                                                               \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline void AddExtension(                                                   \
-      const ::google::protobuf::internal::ExtensionIdentifier<                          \
-        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,         \
       typename _proto_TypeTraits::Repeated::ConstType value) {                \
-    _proto_TypeTraits::Add(id.number(), _field_type, _is_packed,              \
-                           value, &_extensions_);                             \
+    _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value,       \
+                           &_extensions_);                                    \
   }                                                                           \
                                                                               \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&       \
-      GetRepeatedExtension(                                                   \
-          const ::google::protobuf::internal::ExtensionIdentifier<                      \
-            CLASSNAME, _proto_TypeTraits, _field_type,                        \
-            _is_packed>& id) const {                                          \
+  GetRepeatedExtension(                                                       \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const { \
     return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);         \
   }                                                                           \
                                                                               \
   template <typename _proto_TypeTraits,                                       \
-            ::google::protobuf::internal::FieldType _field_type,                        \
+            ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::FieldType _field_type, \
             bool _is_packed>                                                  \
   inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*             \
-      MutableRepeatedExtension(                                               \
-          const ::google::protobuf::internal::ExtensionIdentifier<                      \
-              CLASSNAME, _proto_TypeTraits, _field_type,                      \
-              _is_packed>& id) {                                              \
+  MutableRepeatedExtension(                                                   \
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier<   \
+          CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {       \
     return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,       \
                                               _is_packed, &_extensions_);     \
   }
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_EXTENSION_SET_H__
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc
index 372aea5..7c93c61 100644
--- a/src/google/protobuf/extension_set_heavy.cc
+++ b/src/google/protobuf/extension_set_heavy.cc
@@ -47,8 +47,10 @@
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 
-namespace google {
 
+#include <google/protobuf/port_def.inc>
+
+namespace google {
 namespace protobuf {
 namespace internal {
 
@@ -85,9 +87,9 @@
                                 MessageFactory* factory,
                                 const Descriptor* containing_type)
       : pool_(pool), factory_(factory), containing_type_(containing_type) {}
-  virtual ~DescriptorPoolExtensionFinder() override {}
+  ~DescriptorPoolExtensionFinder() override {}
 
-  virtual bool Find(int number, ExtensionInfo* output) override;
+  bool Find(int number, ExtensionInfo* output) override;
 
  private:
   const DescriptorPool* pool_;
@@ -244,7 +246,7 @@
     GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
     extension->is_repeated = true;
     extension->repeated_message_value =
-        ::google::protobuf::Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
+        Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
   } else {
     GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
   }
@@ -258,7 +260,7 @@
   // RepeatedPtrField<Message> does not know how to Add() since it cannot
   // allocate an abstract object, so we have to be tricky.
   MessageLite* result =
-      reinterpret_cast<::google::protobuf::internal::RepeatedPtrFieldBase*>(
+      reinterpret_cast<internal::RepeatedPtrFieldBase*>(
           extension->repeated_message_value)
           ->AddFromCleared<GenericTypeHandler<MessageLite> >();
   if (result == NULL) {
@@ -312,6 +314,235 @@
   }
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ExtensionSet::FindExtension(uint32 tag, const Message* containing_type,
+                                 const internal::ParseContext* ctx,
+                                 ExtensionInfo* extension, int* number,
+                                 bool* was_packed_on_wire) {
+  if (ctx->extra_parse_data().pool == nullptr) {
+    GeneratedExtensionFinder finder(containing_type);
+    if (!FindExtensionInfoFromTag(tag, &finder, number, extension,
+                                  was_packed_on_wire)) {
+      return false;
+    }
+  } else {
+    DescriptorPoolExtensionFinder finder(ctx->extra_parse_data().pool,
+                                         ctx->extra_parse_data().factory,
+                                         containing_type->GetDescriptor());
+    if (!FindExtensionInfoFromTag(tag, &finder, number, extension,
+                                  was_packed_on_wire)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+std::pair<const char*, bool> ExtensionSet::ParseField(
+    uint32 tag, ParseClosure parent, const char* begin, const char* end,
+    const Message* containing_type,
+    internal::InternalMetadataWithArena* metadata,
+    internal::ParseContext* ctx) {
+  int number;
+  bool was_packed_on_wire;
+  ExtensionInfo extension;
+  if (!FindExtension(tag, containing_type, ctx, &extension, &number,
+                     &was_packed_on_wire)) {
+    return UnknownFieldParse(tag, parent, begin, end,
+                             metadata->mutable_unknown_fields(), ctx);
+  }
+  auto ptr = begin;
+  ParseClosure child;
+  int depth;
+  if (was_packed_on_wire) {
+    switch (extension.type) {
+#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE)                                \
+  case WireFormatLite::TYPE_##UPPERCASE:                                     \
+    child = {                                                                \
+        internal::Packed##CPP_CAMELCASE##Parser,                             \
+        MutableRawRepeatedField(number, extension.type, extension.is_packed, \
+                                extension.descriptor)};                      \
+    goto length_delim
+      HANDLE_TYPE(INT32, Int32);
+      HANDLE_TYPE(INT64, Int64);
+      HANDLE_TYPE(UINT32, UInt32);
+      HANDLE_TYPE(UINT64, UInt64);
+      HANDLE_TYPE(SINT32, SInt32);
+      HANDLE_TYPE(SINT64, SInt64);
+      HANDLE_TYPE(FIXED32, Fixed32);
+      HANDLE_TYPE(FIXED64, Fixed64);
+      HANDLE_TYPE(SFIXED32, SFixed32);
+      HANDLE_TYPE(SFIXED64, SFixed64);
+      HANDLE_TYPE(FLOAT, Float);
+      HANDLE_TYPE(DOUBLE, Double);
+      HANDLE_TYPE(BOOL, Bool);
+#undef HANDLE_TYPE
+
+      case WireFormatLite::TYPE_ENUM:
+        ctx->extra_parse_data().SetEnumValidatorArg(
+            extension.enum_validity_check.func,
+            extension.enum_validity_check.arg,
+            metadata->mutable_unknown_fields(), tag >> 3);
+        child = {
+            internal::PackedValidEnumParserArg,
+            MutableRawRepeatedField(number, extension.type, extension.is_packed,
+                                    extension.descriptor)};
+        goto length_delim;
+      case WireFormatLite::TYPE_STRING:
+      case WireFormatLite::TYPE_BYTES:
+      case WireFormatLite::TYPE_GROUP:
+      case WireFormatLite::TYPE_MESSAGE:
+        GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
+        break;
+    }
+  } else {
+    switch (extension.type) {
+#define HANDLE_VARINT_TYPE(UPPERCASE, CPP_CAMELCASE)                        \
+  case WireFormatLite::TYPE_##UPPERCASE: {                                  \
+    uint64 value;                                                           \
+    ptr = Varint::Parse64(ptr, &value);                                     \
+    if (ptr == nullptr) goto error;                                         \
+    if (extension.is_repeated) {                                            \
+      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
+                         extension.is_packed, value, extension.descriptor); \
+    } else {                                                                \
+      Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,   \
+                         extension.descriptor);                             \
+    }                                                                       \
+  } break
+
+      HANDLE_VARINT_TYPE(INT32, Int32);
+      HANDLE_VARINT_TYPE(INT64, Int64);
+      HANDLE_VARINT_TYPE(UINT32, UInt32);
+      HANDLE_VARINT_TYPE(UINT64, UInt64);
+#undef HANDLE_VARINT_TYPE
+#define HANDLE_SVARINT_TYPE(UPPERCASE, CPP_CAMELCASE, SIZE)                 \
+  case WireFormatLite::TYPE_##UPPERCASE: {                                  \
+    uint64 val;                                                             \
+    ptr = Varint::Parse64(ptr, &val);                                       \
+    auto value = WireFormatLite::ZigZagDecode##SIZE(val);                   \
+    if (extension.is_repeated) {                                            \
+      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
+                         extension.is_packed, value, extension.descriptor); \
+    } else {                                                                \
+      Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,   \
+                         extension.descriptor);                             \
+    }                                                                       \
+  } break
+
+      HANDLE_SVARINT_TYPE(SINT32, Int32, 32);
+      HANDLE_SVARINT_TYPE(SINT64, Int64, 64);
+#undef HANDLE_SVARINT_TYPE
+#define HANDLE_FIXED_TYPE(UPPERCASE, CPP_CAMELCASE, CPPTYPE)                \
+  case WireFormatLite::TYPE_##UPPERCASE: {                                  \
+    CPPTYPE value;                                                          \
+    std::memcpy(&value, ptr, sizeof(CPPTYPE));                              \
+    ptr += sizeof(CPPTYPE);                                                 \
+    if (extension.is_repeated) {                                            \
+      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
+                         extension.is_packed, value, extension.descriptor); \
+    } else {                                                                \
+      Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,   \
+                         extension.descriptor);                             \
+    }                                                                       \
+  } break
+
+      HANDLE_FIXED_TYPE(FIXED32, UInt32, uint32);
+      HANDLE_FIXED_TYPE(FIXED64, UInt64, uint64);
+      HANDLE_FIXED_TYPE(SFIXED32, Int32, int32);
+      HANDLE_FIXED_TYPE(SFIXED64, Int64, int64);
+      HANDLE_FIXED_TYPE(FLOAT, Float, float);
+      HANDLE_FIXED_TYPE(DOUBLE, Double, double);
+      HANDLE_FIXED_TYPE(BOOL, Bool, bool);
+#undef HANDLE_FIXED_TYPE
+
+      case WireFormatLite::TYPE_ENUM: {
+        uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (ptr == nullptr) goto error;
+        int value = val;
+
+        if (!extension.enum_validity_check.func(
+                extension.enum_validity_check.arg, value)) {
+          WriteVarint(number, val, metadata->mutable_unknown_fields());
+        } else if (extension.is_repeated) {
+          AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
+                  extension.descriptor);
+        } else {
+          SetEnum(number, WireFormatLite::TYPE_ENUM, value,
+                  extension.descriptor);
+        }
+        break;
+      }
+
+      case WireFormatLite::TYPE_BYTES:
+      case WireFormatLite::TYPE_STRING: {
+        string* value = extension.is_repeated
+                            ? AddString(number, WireFormatLite::TYPE_STRING,
+                                        extension.descriptor)
+                            : MutableString(number, WireFormatLite::TYPE_STRING,
+                                            extension.descriptor);
+        child = {StringParser, value};
+        goto length_delim;
+      }
+
+      case WireFormatLite::TYPE_GROUP: {
+        MessageLite* value =
+            extension.is_repeated
+                ? AddMessage(number, WireFormatLite::TYPE_GROUP,
+                             *extension.message_prototype, extension.descriptor)
+                : MutableMessage(number, WireFormatLite::TYPE_GROUP,
+                                 *extension.message_prototype,
+                                 extension.descriptor);
+        child = {value->_ParseFunc(), value};
+        if (!ctx->PrepareGroup(tag, &depth)) goto error;
+        ptr = child(ptr, end, ctx);
+        if (!ptr) goto error;
+        if (ctx->GroupContinues(depth)) goto group_continues;
+        break;
+      }
+
+      case WireFormatLite::TYPE_MESSAGE: {
+        MessageLite* value =
+            extension.is_repeated
+                ? AddMessage(number, WireFormatLite::TYPE_MESSAGE,
+                             *extension.message_prototype, extension.descriptor)
+                : MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
+                                 *extension.message_prototype,
+                                 extension.descriptor);
+        child = {value->_ParseFunc(), value};
+        goto length_delim;
+      }
+    }
+  }
+
+  return std::make_pair(ptr, false);
+
+error:
+  return std::make_pair(nullptr, true);
+
+length_delim:
+  uint32 size;
+  ptr = Varint::Parse32Inline(ptr, &size);
+  if (!ptr) goto error;
+  if (size > end - ptr) goto len_delim_till_end;
+  {
+    auto newend = ptr + size;
+    if (!ctx->ParseExactRange(child, ptr, newend)) {
+      goto error;
+    }
+    ptr = newend;
+  }
+  return std::make_pair(ptr, false);
+len_delim_till_end:
+  return std::make_pair(ctx->StoreAndTailCall(ptr, end, parent, child, size),
+                        true);
+
+group_continues:
+  ctx->StoreGroup(parent, child, depth);
+  return std::make_pair(ptr, true);
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
                               const Message* containing_type,
                               UnknownFieldSet* unknown_fields) {
@@ -327,6 +558,88 @@
   }
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ExtensionSet::ParseMessageSetItem(
+    ParseClosure parent, const char* begin, const char* end,
+    const Message* containing_type,
+    internal::InternalMetadataWithArena* metadata,
+    internal::ParseContext* ctx) {
+  auto ptr = begin;
+  while (ptr < end) {
+    uint32 tag = *ptr++;
+    if (tag == WireFormatLite::kMessageSetTypeIdTag) {
+      uint32 type_id;
+      ptr = Varint::Parse32(ptr, &type_id);
+      if (!ptr) goto error;
+
+      if (ctx->extra_parse_data().payload.empty()) {
+        tag = *ptr++;
+        if (tag == WireFormatLite::kMessageSetMessageTag) {
+          auto res = ParseField(type_id * 8 + 2, parent, ptr, end,
+                                containing_type, metadata, ctx);
+          ptr = res.first;
+          if (res.second) break;
+        } else {
+          goto error;
+        }
+      } else {
+        ExtensionInfo extension;
+        GeneratedExtensionFinder finder(containing_type);
+        int number;
+        bool was_packed_on_wire;
+        if (!FindExtension(type_id * 8 + 2, containing_type, ctx, &extension,
+                           &number, &was_packed_on_wire)) {
+          metadata->mutable_unknown_fields()->AddLengthDelimited(
+              type_id, ctx->extra_parse_data().payload);
+          continue;
+        }
+        MessageLite* value =
+            extension.is_repeated
+                ? AddMessage(number, WireFormatLite::TYPE_MESSAGE,
+                             *extension.message_prototype, extension.descriptor)
+                : MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
+                                 *extension.message_prototype,
+                                 extension.descriptor);
+        ParseClosure parser = {value->_ParseFunc(), value};
+        StringPiece chunk(ctx->extra_parse_data().payload.data());
+        if (!ctx->ParseExactRange(parser, chunk.begin(), chunk.end())) {
+          return nullptr;
+        }
+      }
+    } else if (tag == WireFormatLite::kMessageSetItemEndTag) {
+      if (!ctx->ValidEndGroup(tag)) goto error;
+      break;
+    } else if (tag == WireFormatLite::kMessageSetMessageTag) {
+      uint32 size;
+      ptr = Varint::Parse32Inline(ptr, &size);
+      if (!ptr) goto error;
+      ParseClosure child = {internal::StringParser,
+                            &ctx->extra_parse_data().payload};
+      if (size > end - ptr) {
+        return ctx->StoreAndTailCall(ptr, end, parent, child, size);
+      } else {
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange(child, ptr, newend)) {
+          goto error;
+        }
+        ptr = newend;
+      }
+    } else {
+      ptr--;
+      ptr = Varint::Parse32(ptr, &tag);
+      if (ptr == nullptr) goto error;
+      auto res =
+          ParseField(tag, parent, ptr, end, containing_type, metadata, ctx);
+      ptr = res.first;
+      if (res.second) break;
+    }
+  }
+  return ptr;
+error:
+  return nullptr;
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
 bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
                                    const Message* containing_type,
                                    UnknownFieldSet* unknown_fields) {
@@ -385,11 +698,10 @@
         // but MessageLite has no SpaceUsedLong(), so we must directly call
         // RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong() with a different
         // type handler.
-        total_size +=
-            sizeof(*repeated_message_value) +
-            RepeatedMessage_SpaceUsedExcludingSelfLong(
-                reinterpret_cast<::google::protobuf::internal::RepeatedPtrFieldBase*>(
-                    repeated_message_value));
+        total_size += sizeof(*repeated_message_value) +
+                      RepeatedMessage_SpaceUsedExcludingSelfLong(
+                          reinterpret_cast<internal::RepeatedPtrFieldBase*>(
+                              repeated_message_value));
         break;
     }
   } else {
@@ -420,15 +732,13 @@
                                                      uint8* target) const {
   return InternalSerializeWithCachedSizesToArray(
       start_field_number, end_field_number,
-      google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(),
-      target);
+      io::CodedOutputStream::IsDefaultSerializationDeterministic(), target);
 }
 
 uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
     uint8* target) const {
   return InternalSerializeMessageSetWithCachedSizesToArray(
-      google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(),
-      target);
+      io::CodedOutputStream::IsDefaultSerializationDeterministic(), target);
 }
 
 uint8* ExtensionSet::InternalSerializeWithCachedSizesToArray(
@@ -650,89 +960,27 @@
   }
 }
 
-bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
-                                   const MessageLite* containing_type) {
-  MessageSetFieldSkipper skipper(NULL);
-  GeneratedExtensionFinder finder(containing_type);
-  return ParseMessageSet(input, &finder, &skipper);
-}
-
 bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
                                        ExtensionFinder* extension_finder,
                                        MessageSetFieldSkipper* field_skipper) {
-  // TODO(kenton):  It would be nice to share code between this and
-  // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
-  // differences would be hard to factor out.
-
-  // This method parses a group which should contain two fields:
-  //   required int32 type_id = 2;
-  //   required data message = 3;
-
-  uint32 last_type_id = 0;
-
-  // If we see message data before the type_id, we'll append it to this so
-  // we can parse it later.
-  string message_data;
-
-  while (true) {
-    const uint32 tag = input->ReadTagNoLastTag();
-    if (tag == 0) return false;
-
-    switch (tag) {
-      case WireFormatLite::kMessageSetTypeIdTag: {
-        uint32 type_id;
-        if (!input->ReadVarint32(&type_id)) return false;
-        last_type_id = type_id;
-
-        if (!message_data.empty()) {
-          // We saw some message data before the type_id.  Have to parse it
-          // now.
-          io::CodedInputStream sub_input(
-              reinterpret_cast<const uint8*>(message_data.data()),
-              message_data.size());
-          if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
-                                     last_type_id, &sub_input,
-                                     extension_finder, field_skipper)) {
-            return false;
-          }
-          message_data.clear();
-        }
-
-        break;
-      }
-
-      case WireFormatLite::kMessageSetMessageTag: {
-        if (last_type_id == 0) {
-          // We haven't seen a type_id yet.  Append this data to message_data.
-          string temp;
-          uint32 length;
-          if (!input->ReadVarint32(&length)) return false;
-          if (!input->ReadString(&temp, length)) return false;
-          io::StringOutputStream output_stream(&message_data);
-          io::CodedOutputStream coded_output(&output_stream);
-          coded_output.WriteVarint32(length);
-          coded_output.WriteString(temp);
-        } else {
-          // Already saw type_id, so we can parse this directly.
-          if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
-                                     last_type_id, input,
-                                     extension_finder, field_skipper)) {
-            return false;
-          }
-        }
-
-        break;
-      }
-
-      case WireFormatLite::kMessageSetItemEndTag: {
-        return true;
-      }
-
-      default: {
-        if (!field_skipper->SkipField(input, tag)) return false;
-      }
+  struct MSFull {
+    bool ParseField(int type_id, io::CodedInputStream* input) {
+      return me->ParseFieldMaybeLazily(
+          WireFormatLite::WIRETYPE_LENGTH_DELIMITED, type_id, input,
+          extension_finder, field_skipper);
     }
-  }
+
+    bool SkipField(uint32 tag, io::CodedInputStream* input) {
+      return field_skipper->SkipField(input, tag);
+    }
+
+    ExtensionSet* me;
+    ExtensionFinder* extension_finder;
+    MessageSetFieldSkipper* field_skipper;
+  };
+
+  return ParseMessageSetItemImpl(input,
+                                 MSFull{this, extension_finder, field_skipper});
 }
 
 void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc
index bc65d29..f3346c8 100644
--- a/src/google/protobuf/extension_set_unittest.cc
+++ b/src/google/protobuf/extension_set_unittest.cc
@@ -53,13 +53,13 @@
 #include <gtest/gtest.h>
 #include <google/protobuf/stubs/stl_util.h>
 
-namespace google {
 
+namespace google {
 namespace protobuf {
 namespace internal {
 namespace {
 
-// This test closely mirrors google/protobuf/compiler/cpp/unittest.cc
+// This test closely mirrors net/proto2/compiler/cpp/internal/unittest.cc
 // except that it uses extensions rather than regular fields.
 
 TEST(ExtensionSetTest, Defaults) {
@@ -208,9 +208,9 @@
 }
 
 TEST(ExtensionSetTest, ArenaUnsafeArenaSetAllocatedAndRelease) {
-  ::google::protobuf::Arena arena;
+  Arena arena;
   unittest::TestAllExtensions* message =
-      ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+      Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
   unittest::ForeignMessage extension;
   message->UnsafeArenaSetAllocatedExtension(
       unittest::optional_foreign_message_extension,
@@ -258,9 +258,9 @@
 }
 
 TEST(ExtensionSetTest, ArenaUnsafeArenaReleaseOfHeapAlloc) {
-  ::google::protobuf::Arena arena;
+  Arena arena;
   unittest::TestAllExtensions* message =
-      ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+      Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
   unittest::ForeignMessage* extension = new unittest::ForeignMessage;
   message->SetAllocatedExtension(
       unittest::optional_foreign_message_extension,
@@ -392,17 +392,17 @@
 }
 
 TEST(ExtensionSetTest, ArenaSetAllExtension) {
-  ::google::protobuf::Arena arena1;
+  Arena arena1;
   unittest::TestAllExtensions* message1 =
-      ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
+      Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
   TestUtil::SetAllExtensions(message1);
   TestUtil::ExpectAllExtensionsSet(*message1);
 }
 
 TEST(ExtensionSetTest, ArenaCopyConstructor) {
-  ::google::protobuf::Arena arena1;
+  Arena arena1;
   unittest::TestAllExtensions* message1 =
-      ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
+      Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
   TestUtil::SetAllExtensions(message1);
   unittest::TestAllExtensions message2(*message1);
   arena1.Reset();
@@ -410,9 +410,9 @@
 }
 
 TEST(ExtensionSetTest, ArenaMergeFrom) {
-  ::google::protobuf::Arena arena1;
+  Arena arena1;
   unittest::TestAllExtensions* message1 =
-      ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
+      Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
   TestUtil::SetAllExtensions(message1);
   unittest::TestAllExtensions message2;
   message2.MergeFrom(*message1);
@@ -421,9 +421,9 @@
 }
 
 TEST(ExtensionSetTest, ArenaSetAllocatedMessageAndRelease) {
-  ::google::protobuf::Arena arena;
+  Arena arena;
   unittest::TestAllExtensions* message =
-      ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+      Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
   EXPECT_FALSE(message->HasExtension(
       unittest::optional_foreign_message_extension));
   // Add a extension using SetAllocatedExtension
@@ -444,8 +444,8 @@
 }
 
 TEST(ExtensionSetTest, SwapExtensionBothFullWithArena) {
-  ::google::protobuf::Arena arena1;
-  std::unique_ptr<google::protobuf::Arena> arena2(new ::google::protobuf::Arena());
+  Arena arena1;
+  std::unique_ptr<Arena> arena2(new Arena());
 
   unittest::TestAllExtensions* message1 =
       Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
@@ -467,7 +467,7 @@
   arena2.reset(NULL);
   TestUtil::ExpectAllExtensionsSet(*message1);
   // Test corner cases, when one is empty and other is not.
-  ::google::protobuf::Arena arena3, arena4;
+  Arena arena3, arena4;
 
   unittest::TestAllExtensions* message3 =
       Arena::CreateMessage<unittest::TestAllExtensions>(&arena3);
@@ -480,8 +480,8 @@
 }
 
 TEST(ExtensionSetTest, SwapFieldsOfExtensionBothFullWithArena) {
-  google::protobuf::Arena arena1;
-  google::protobuf::Arena* arena2 = new ::google::protobuf::Arena();
+  Arena arena1;
+  Arena* arena2 = new Arena();
 
   unittest::TestAllExtensions* message1 =
       Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
@@ -527,7 +527,7 @@
   int size = source.ByteSize();
   string data;
   data.resize(size);
-  uint8* target = reinterpret_cast<uint8*>(string_as_array(&data));
+  uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
   uint8* end = source.SerializeWithCachedSizesToArray(target);
   EXPECT_EQ(size, end - target);
   EXPECT_TRUE(destination.ParseFromString(data));
@@ -549,7 +549,7 @@
   string data;
   data.resize(size);
   {
-    io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+    io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
     io::CodedOutputStream output_stream(&array_stream);
     source.SerializeWithCachedSizes(&output_stream);
     ASSERT_FALSE(output_stream.HadError());
@@ -571,7 +571,7 @@
   int size = source.ByteSize();
   string data;
   data.resize(size);
-  uint8* target = reinterpret_cast<uint8*>(string_as_array(&data));
+  uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
   uint8* end = source.SerializeWithCachedSizesToArray(target);
   EXPECT_EQ(size, end - target);
   EXPECT_TRUE(destination.ParseFromString(data));
@@ -593,7 +593,7 @@
   string data;
   data.resize(size);
   {
-    io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+    io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
     io::CodedOutputStream output_stream(&array_stream);
     source.SerializeWithCachedSizes(&output_stream);
     ASSERT_FALSE(output_stream.HadError());
@@ -1055,7 +1055,7 @@
            unittest::repeated_nested_enum_extension).begin(),
        enum_const_end  = message.GetRepeatedExtension(
            unittest::repeated_nested_enum_extension).end();
-       enum_iter != enum_end; ++enum_iter) {
+       enum_const_iter != enum_const_end; ++enum_const_iter) {
     ASSERT_EQ(*enum_const_iter, unittest::TestAllTypes::NestedEnum_MAX);
   }
 
@@ -1271,10 +1271,10 @@
     const Message& sub_message =
         message.GetReflection()->GetMessage(message, message_extension);
     const unittest::ForeignMessage* typed_sub_message =
-#ifdef GOOGLE_PROTOBUF_NO_RTTI
-        static_cast<const unittest::ForeignMessage*>(&sub_message);
-#else
+#if GOOGLE_PROTOBUF_RTTI
         dynamic_cast<const unittest::ForeignMessage*>(&sub_message);
+#else
+        static_cast<const unittest::ForeignMessage*>(&sub_message);
 #endif
     ASSERT_TRUE(typed_sub_message != NULL);
     EXPECT_EQ(456, typed_sub_message->c());
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index 2ce061d..9791b97 100644
--- a/src/google/protobuf/field_mask.pb.cc
+++ b/src/google/protobuf/field_mask.pb.cc
@@ -6,8 +6,8 @@
 #include <algorithm>
 
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
@@ -18,18 +18,17 @@
 #include "third_party/protobuf/version.h"
 #endif
 // @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
 
 namespace google {
 namespace protobuf {
 class FieldMaskDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<FieldMask>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<FieldMask> _instance;
 } _FieldMask_default_instance_;
 }  // namespace protobuf
 }  // namespace google
-namespace protobuf_google_2fprotobuf_2ffield_5fmask_2eproto {
-static void InitDefaultsFieldMask() {
+static void InitDefaultsFieldMask_google_2fprotobuf_2ffield_5fmask_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -40,16 +39,18 @@
   ::google::protobuf::FieldMask::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_FieldMask =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsFieldMask}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_FieldMask_google_2fprotobuf_2ffield_5fmask_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsFieldMask_google_2fprotobuf_2ffield_5fmask_2eproto}, {}};
 
-void InitDefaults() {
-  ::google::protobuf::internal::InitSCC(&scc_info_FieldMask.base);
+void InitDefaults_google_2fprotobuf_2ffield_5fmask_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_FieldMask_google_2fprotobuf_2ffield_5fmask_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata[1];
+::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto[1];
+constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr;
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto = nullptr;
 
-const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::FieldMask, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -65,51 +66,33 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_FieldMask_default_instance_),
 };
 
-static void protobuf_AssignDescriptors() {
-  AddDescriptors();
-  AssignDescriptors(
-      "google/protobuf/field_mask.proto", schemas, file_default_instances, TableStruct::offsets,
-      file_level_metadata, NULL, NULL);
-}
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2ffield_5fmask_2eproto = {
+  {}, AddDescriptors_google_2fprotobuf_2ffield_5fmask_2eproto, "google/protobuf/field_mask.proto", schemas,
+  file_default_instances, TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto::offsets,
+  file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto, file_level_service_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto,
+};
 
-static void protobuf_AssignDescriptorsOnce() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
-}
+::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto = {
+  false, InitDefaults_google_2fprotobuf_2ffield_5fmask_2eproto, 
+  "\n google/protobuf/field_mask.proto\022\017goog"
+  "le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB"
+  "\214\001\n\023com.google.protobufB\016FieldMaskProtoP"
+  "\001Z9google.golang.org/genproto/protobuf/f"
+  "ield_mask;field_mask\370\001\001\242\002\003GPB\252\002\036Google.P"
+  "rotobuf.WellKnownTypesb\006proto3"
+,
+  "google/protobuf/field_mask.proto", &assign_descriptors_table_google_2fprotobuf_2ffield_5fmask_2eproto, 230,
+};
 
-void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
-void protobuf_RegisterTypes(const ::std::string&) {
-  protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
-}
-
-static void AddDescriptorsImpl() {
-  InitDefaults();
-  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
-      "\n google/protobuf/field_mask.proto\022\017goog"
-      "le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB"
-      "\211\001\n\023com.google.protobufB\016FieldMaskProtoP"
-      "\001Z9google.golang.org/genproto/protobuf/f"
-      "ield_mask;field_mask\242\002\003GPB\252\002\036Google.Prot"
-      "obuf.WellKnownTypesb\006proto3"
+void AddDescriptors_google_2fprotobuf_2ffield_5fmask_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
   };
-  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 227);
-  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
-    "google/protobuf/field_mask.proto", &protobuf_RegisterTypes);
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto, deps, 0);
 }
 
-void AddDescriptors() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
-}
-// Force AddDescriptors() to be called at dynamic initialization time.
-struct StaticDescriptorInitializer {
-  StaticDescriptorInitializer() {
-    AddDescriptors();
-  }
-} static_descriptor_initializer;
-}  // namespace protobuf_google_2fprotobuf_2ffield_5fmask_2eproto
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_google_2fprotobuf_2ffield_5fmask_2eproto = []() { AddDescriptors_google_2fprotobuf_2ffield_5fmask_2eproto(); return true; }();
 namespace google {
 namespace protobuf {
 
@@ -117,17 +100,27 @@
 
 void FieldMask::InitAsDefaultInstance() {
 }
+class FieldMask::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int FieldMask::kPathsFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 FieldMask::FieldMask()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::scc_info_FieldMask.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.FieldMask)
 }
+FieldMask::FieldMask(::google::protobuf::Arena* arena)
+  : ::google::protobuf::Message(),
+  _internal_metadata_(arena),
+  paths_(arena) {
+  SharedCtor();
+  RegisterArenaDtor(arena);
+  // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldMask)
+}
 FieldMask::FieldMask(const FieldMask& from)
   : ::google::protobuf::Message(),
       _internal_metadata_(NULL),
@@ -137,6 +130,8 @@
 }
 
 void FieldMask::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_FieldMask_google_2fprotobuf_2ffield_5fmask_2eproto.base);
 }
 
 FieldMask::~FieldMask() {
@@ -145,18 +140,20 @@
 }
 
 void FieldMask::SharedDtor() {
+  GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);
 }
 
+void FieldMask::ArenaDtor(void* object) {
+  FieldMask* _this = reinterpret_cast< FieldMask* >(object);
+  (void)_this;
+}
+void FieldMask::RegisterArenaDtor(::google::protobuf::Arena*) {
+}
 void FieldMask::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* FieldMask::descriptor() {
-  ::protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const FieldMask& FieldMask::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::scc_info_FieldMask.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_FieldMask_google_2fprotobuf_2ffield_5fmask_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -171,9 +168,67 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* FieldMask::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<FieldMask*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // repeated string paths = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          ctx->extra_parse_data().SetFieldName("google.protobuf.FieldMask.paths");
+          parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+          ::std::string* str = msg->add_paths();
+          str->clear();
+          object = str;
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 10 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool FieldMask::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.FieldMask)
   for (;;) {
@@ -183,8 +238,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // repeated string paths = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->add_paths()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -217,6 +271,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void FieldMask::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -234,9 +289,9 @@
       1, this->paths(i), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.FieldMask)
 }
@@ -258,9 +313,9 @@
       WriteStringToArray(1, this->paths(i), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldMask)
   return target;
@@ -270,11 +325,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldMask)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated string paths = 1;
   total_size += 1 *
       ::google::protobuf::internal::FromIntSize(this->paths_size());
@@ -292,7 +351,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldMask)
   GOOGLE_DCHECK_NE(&from, this);
   const FieldMask* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const FieldMask>(
+      ::google::protobuf::DynamicCastToGenerated<FieldMask>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FieldMask)
@@ -333,17 +392,32 @@
 
 void FieldMask::Swap(FieldMask* other) {
   if (other == this) return;
+  if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+    InternalSwap(other);
+  } else {
+    FieldMask* temp = New(GetArenaNoVirtual());
+    temp->MergeFrom(*other);
+    other->CopyFrom(*this);
+    InternalSwap(temp);
+    if (GetArenaNoVirtual() == NULL) {
+      delete temp;
+    }
+  }
+}
+void FieldMask::UnsafeArenaSwap(FieldMask* other) {
+  if (other == this) return;
+  GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
   InternalSwap(other);
 }
 void FieldMask::InternalSwap(FieldMask* other) {
   using std::swap;
-  paths_.InternalSwap(CastToBase(&other->paths_));
   _internal_metadata_.Swap(&other->_internal_metadata_);
+  paths_.InternalSwap(CastToBase(&other->paths_));
 }
 
 ::google::protobuf::Metadata FieldMask::GetMetadata() const {
-  protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2ffield_5fmask_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto[kIndexInFileMessages];
 }
 
 
@@ -353,7 +427,7 @@
 namespace google {
 namespace protobuf {
 template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::FieldMask* Arena::CreateMaybeMessage< ::google::protobuf::FieldMask >(Arena* arena) {
-  return Arena::CreateInternal< ::google::protobuf::FieldMask >(arena);
+  return Arena::CreateMessageInternal< ::google::protobuf::FieldMask >(arena);
 }
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h
index 54b6372..2055e96 100644
--- a/src/google/protobuf/field_mask.pb.h
+++ b/src/google/protobuf/field_mask.pb.h
@@ -4,18 +4,18 @@
 #ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto
 #define PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto
 
+#include <limits>
 #include <string>
 
 #include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 3006001
+#if GOOGLE_PROTOBUF_VERSION < 3006000
 #error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please update
+#error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
 #if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
 #error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please
+#error incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.
 #endif
 
@@ -31,29 +31,27 @@
 #include <google/protobuf/extension_set.h>  // IWYU pragma: export
 #include <google/protobuf/unknown_field_set.h>
 // @@protoc_insertion_point(includes)
-#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2ffield_5fmask_2eproto LIBPROTOBUF_EXPORT
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ffield_5fmask_2eproto LIBPROTOBUF_EXPORT
 
-namespace protobuf_google_2fprotobuf_2ffield_5fmask_2eproto {
 // Internal implementation detail -- do not use these members.
-struct LIBPROTOBUF_EXPORT TableStruct {
-  static const ::google::protobuf::internal::ParseTableField entries[];
-  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
-  static const ::google::protobuf::internal::ParseTable schema[1];
+struct LIBPROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[1]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
   static const ::google::protobuf::uint32 offsets[];
 };
-void LIBPROTOBUF_EXPORT AddDescriptors();
-}  // namespace protobuf_google_2fprotobuf_2ffield_5fmask_2eproto
+void LIBPROTOBUF_EXPORT AddDescriptors_google_2fprotobuf_2ffield_5fmask_2eproto();
 namespace google {
 namespace protobuf {
 class FieldMask;
 class FieldMaskDefaultTypeInternal;
 LIBPROTOBUF_EXPORT extern FieldMaskDefaultTypeInternal _FieldMask_default_instance_;
-}  // namespace protobuf
-}  // namespace google
-namespace google {
-namespace protobuf {
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::FieldMask* Arena::CreateMaybeMessage<::google::protobuf::FieldMask>(Arena*);
 }  // namespace protobuf
 }  // namespace google
@@ -88,7 +86,15 @@
     return *this;
   }
   #endif
-  static const ::google::protobuf::Descriptor* descriptor();
+  inline ::google::protobuf::Arena* GetArena() const final {
+    return GetArenaNoVirtual();
+  }
+  inline void* GetMaybeArenaPointer() const final {
+    return MaybeArenaPtr();
+  }
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const FieldMask& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -99,6 +105,7 @@
   static constexpr int kIndexInFileMessages =
     0;
 
+  void UnsafeArenaSwap(FieldMask* other);
   void Swap(FieldMask* other);
   friend void swap(FieldMask& a, FieldMask& b) {
     a.Swap(&b);
@@ -121,8 +128,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -134,12 +146,17 @@
   void SharedDtor();
   void SetCachedSize(int size) const final;
   void InternalSwap(FieldMask* other);
+  protected:
+  explicit FieldMask(::google::protobuf::Arena* arena);
+  private:
+  static void ArenaDtor(void* object);
+  inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
   private:
   inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
-    return NULL;
+    return _internal_metadata_.arena();
   }
   inline void* MaybeArenaPtr() const {
-    return NULL;
+    return _internal_metadata_.raw_arena_ptr();
   }
   public:
 
@@ -168,16 +185,20 @@
   #endif
   void add_paths(const char* value);
   void add_paths(const char* value, size_t size);
-  const ::google::protobuf::RepeatedPtrField< ::std::string>& paths() const;
-  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_paths();
+  const ::google::protobuf::RepeatedPtrField<::std::string>& paths() const;
+  ::google::protobuf::RepeatedPtrField<::std::string>* mutable_paths();
 
   // @@protoc_insertion_point(class_scope:google.protobuf.FieldMask)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
-  ::google::protobuf::RepeatedPtrField< ::std::string> paths_;
+  template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
+  typedef void InternalArenaConstructable_;
+  typedef void DestructorSkippable_;
+  ::google::protobuf::RepeatedPtrField<::std::string> paths_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto;
 };
 // ===================================================================
 
@@ -248,12 +269,12 @@
   paths_.Add()->assign(reinterpret_cast<const char*>(value), size);
   // @@protoc_insertion_point(field_add_pointer:google.protobuf.FieldMask.paths)
 }
-inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+inline const ::google::protobuf::RepeatedPtrField<::std::string>&
 FieldMask::paths() const {
   // @@protoc_insertion_point(field_list:google.protobuf.FieldMask.paths)
   return paths_;
 }
-inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+inline ::google::protobuf::RepeatedPtrField<::std::string>*
 FieldMask::mutable_paths() {
   // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldMask.paths)
   return &paths_;
@@ -270,4 +291,5 @@
 
 // @@protoc_insertion_point(global_scope)
 
+#include <google/protobuf/port_undef.inc>
 #endif  // PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto
diff --git a/src/google/protobuf/field_mask.proto b/src/google/protobuf/field_mask.proto
index 76e09f3..4015b1a 100644
--- a/src/google/protobuf/field_mask.proto
+++ b/src/google/protobuf/field_mask.proto
@@ -38,6 +38,7 @@
 option java_multiple_files = true;
 option objc_class_prefix = "GPB";
 option go_package = "google.golang.org/genproto/protobuf/field_mask;field_mask";
+option cc_enable_arenas = true;
 
 // `FieldMask` represents a set of symbolic field paths, for example:
 //
@@ -107,57 +108,49 @@
 // describe the updated values, the API ignores the values of all
 // fields not covered by the mask.
 //
-// If a repeated field is specified for an update operation, the existing
-// repeated values in the target resource will be overwritten by the new values.
-// Note that a repeated field is only allowed in the last position of a `paths`
-// string.
+// If a repeated field is specified for an update operation, new values will
+// be appended to the existing repeated field in the target resource. Note that
+// a repeated field is only allowed in the last position of a `paths` string.
 //
 // If a sub-message is specified in the last position of the field mask for an
-// update operation, then the existing sub-message in the target resource is
-// overwritten. Given the target message:
+// update operation, then new value will be merged into the existing sub-message
+// in the target resource.
+//
+// For example, given the target message:
 //
 //     f {
 //       b {
-//         d : 1
-//         x : 2
+//         d: 1
+//         x: 2
 //       }
-//       c : 1
+//       c: [1]
 //     }
 //
 // And an update message:
 //
 //     f {
 //       b {
-//         d : 10
+//         d: 10
 //       }
+//       c: [2]
 //     }
 //
 // then if the field mask is:
 //
-//  paths: "f.b"
+//  paths: ["f.b", "f.c"]
 //
 // then the result will be:
 //
 //     f {
 //       b {
-//         d : 10
+//         d: 10
+//         x: 2
 //       }
-//       c : 1
+//       c: [1, 2]
 //     }
 //
-// However, if the update mask was:
-//
-//  paths: "f.b.d"
-//
-// then the result would be:
-//
-//     f {
-//       b {
-//         d : 10
-//         x : 2
-//       }
-//       c : 1
-//     }
+// An implementation may provide options to override this default behavior for
+// repeated and message fields.
 //
 // In order to reset a field's value to the default, the field must
 // be in the mask and set to the default value in the provided resource.
diff --git a/src/google/protobuf/generated_enum_reflection.h b/src/google/protobuf/generated_enum_reflection.h
index 983d318..27aac3f 100644
--- a/src/google/protobuf/generated_enum_reflection.h
+++ b/src/google/protobuf/generated_enum_reflection.h
@@ -41,13 +41,20 @@
 
 #include <string>
 
+#include <google/protobuf/port.h>
 #include <google/protobuf/generated_enum_util.h>
 
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
   class EnumDescriptor;
 }  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 
 // Returns the EnumDescriptor for enum type E, which must be a
@@ -82,6 +89,6 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
diff --git a/src/google/protobuf/generated_enum_util.h b/src/google/protobuf/generated_enum_util.h
index 96b03cc..5c4dd65 100644
--- a/src/google/protobuf/generated_enum_util.h
+++ b/src/google/protobuf/generated_enum_util.h
@@ -33,6 +33,10 @@
 
 #include <type_traits>
 
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 
@@ -41,6 +45,6 @@
 template <typename T> struct is_proto_enum : ::std::false_type {};
 
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index 74ad00e..e24f030 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -44,6 +44,8 @@
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/inlined_string_field.h>
 #include <google/protobuf/map_field.h>
+#include <google/protobuf/map_field_inl.h>
+#include <google/protobuf/stubs/mutex.h>
 #include <google/protobuf/repeated_field.h>
 #include <google/protobuf/wire_format.h>
 
@@ -200,15 +202,7 @@
 
 const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields(
     const Message& message) const {
-  if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
-      !GetProto3PreserveUnknownsDefault()) {
-    // We have to ensure that any mutations made to the return value of
-    // MutableUnknownFields() are not reflected here when Proto3 defaults to
-    // discard unknowns.
-    return *UnknownFieldSet::default_instance();
-  } else {
-    return GetInternalMetadataWithArena(message).unknown_fields();
-  }
+  return GetInternalMetadataWithArena(message).unknown_fields();
 }
 
 UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields(
@@ -369,15 +363,12 @@
         break;
       case FieldDescriptor::CPPTYPE_MESSAGE:
         if (IsMapFieldInApi(field)) {
-          MutableRaw<MapFieldBase>(message1, field)->
-            MutableRepeatedField()->
-              Swap<GenericTypeHandler<google::protobuf::Message> >(
-                MutableRaw<MapFieldBase>(message2, field)->
-                  MutableRepeatedField());
+          MutableRaw<MapFieldBase>(message1, field)->Swap(
+              MutableRaw<MapFieldBase>(message2, field));
         } else {
-          MutableRaw<RepeatedPtrFieldBase>(message1, field)->
-            Swap<GenericTypeHandler<google::protobuf::Message> >(
-              MutableRaw<RepeatedPtrFieldBase>(message2, field));
+          MutableRaw<RepeatedPtrFieldBase>(message1, field)
+              ->Swap<GenericTypeHandler<Message> >(
+                  MutableRaw<RepeatedPtrFieldBase>(message2, field));
         }
         break;
 
@@ -1035,8 +1026,6 @@
   const uint32* const has_bits =
       schema_.HasHasbits() ? GetHasBits(message) : NULL;
   const uint32* const has_bits_indices = schema_.has_bit_indices_;
-  const uint32* const oneof_case_array =
-      GetConstPointerAtOffset<uint32>(&message, schema_.oneof_case_offset_);
   output->reserve(descriptor_->field_count());
   for (int i = 0; i <= last_non_weak_field_index_; i++) {
     const FieldDescriptor* field = descriptor_->field(i);
@@ -1047,6 +1036,8 @@
     } else {
       const OneofDescriptor* containing_oneof = field->containing_oneof();
       if (containing_oneof) {
+        const uint32* const oneof_case_array = GetConstPointerAtOffset<uint32>(
+            &message, schema_.oneof_case_offset_);
         // Equivalent to: HasOneofField(message, field)
         if (oneof_case_array[containing_oneof->index()] == field->number()) {
           output->push_back(field);
@@ -1330,11 +1321,8 @@
     const EnumValueDescriptor* value_desc =
         field->enum_type()->FindValueByNumber(value);
     if (value_desc == NULL) {
-      GOOGLE_LOG(DFATAL) << "SetEnumValue accepts only valid integer values: value "
-                  << value << " unexpected for field " << field->full_name();
-      // In production builds, DFATAL will not terminate the program, so we have
-      // to do something reasonable: just set the default value.
-      value = field->default_value_enum()->number();
+      MutableUnknownFields(message)->AddVarint(field->number(), value);
+      return;
     }
   }
   SetEnumValueInternal(message, field, value);
@@ -1391,12 +1379,8 @@
     const EnumValueDescriptor* value_desc =
         field->enum_type()->FindValueByNumber(value);
     if (value_desc == NULL) {
-      GOOGLE_LOG(DFATAL) << "SetRepeatedEnumValue accepts only valid integer values: "
-                  << "value " << value << " unexpected for field "
-                  << field->full_name();
-      // In production builds, DFATAL will not terminate the program, so we have
-      // to do something reasonable: just set the default value.
-      value = field->default_value_enum()->number();
+      MutableUnknownFields(message)->AddVarint(field->number(), value);
+      return;
     }
   }
   SetRepeatedEnumValueInternal(message, field, index, value);
@@ -1432,11 +1416,8 @@
     const EnumValueDescriptor* value_desc =
         field->enum_type()->FindValueByNumber(value);
     if (value_desc == NULL) {
-      GOOGLE_LOG(DFATAL) << "AddEnumValue accepts only valid integer values: value "
-                  << value << " unexpected for field " << field->full_name();
-      // In production builds, DFATAL will not terminate the program, so we have
-      // to do something reasonable: just set the default value.
-      value = field->default_value_enum()->number();
+      MutableUnknownFields(message)->AddVarint(field->number(), value);
+      return;
     }
   }
   AddEnumValueInternal(message, field, value);
@@ -2298,7 +2279,7 @@
         descriptor,
         MigrationToReflectionSchema(default_instance_data_, offsets_,
                                     *schemas_),
-        ::google::protobuf::DescriptorPool::generated_pool(), factory_);
+        DescriptorPool::generated_pool(), factory_);
     for (int i = 0; i < descriptor->enum_type_count(); i++) {
       AssignEnumDescriptor(descriptor->enum_type(i));
     }
@@ -2336,8 +2317,9 @@
   }
 
   void AddArray(const Metadata* begin, const Metadata* end) {
-    MutexLock lock(&mu_);
+    mu_.Lock();
     metadata_arrays_.push_back(std::make_pair(begin, end));
+    mu_.Unlock();
   }
 
   static MetadataOwner* Instance() {
@@ -2348,28 +2330,30 @@
  private:
   MetadataOwner() = default;  // private because singleton
 
-  Mutex mu_;
+  WrappedMutex mu_;
   std::vector<std::pair<const Metadata*, const Metadata*> > metadata_arrays_;
 };
 
-}  // namespace
-
-void AssignDescriptors(
-    const string& filename, const MigrationSchema* schemas,
-    const Message* const* default_instances_, const uint32* offsets,
-    // update the following descriptor arrays.
-    Metadata* file_level_metadata,
-    const EnumDescriptor** file_level_enum_descriptors,
-    const ServiceDescriptor** file_level_service_descriptors) {
-  const ::google::protobuf::FileDescriptor* file =
-      ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(filename);
+void AssignDescriptorsImpl(const AssignDescriptorsTable* table) {
+  // Ensure the file descriptor is added to the pool.
+  {
+    // This only happens once per proto file. So a global mutex to serialize
+    // calls to AddDescriptors.
+    static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED};
+    mu.Lock();
+    table->add_descriptors();
+    mu.Unlock();
+  }
+  // Fill the arrays with pointers to descriptors and reflection classes.
+  const FileDescriptor* file =
+      DescriptorPool::generated_pool()->FindFileByName(table->filename);
   GOOGLE_CHECK(file != NULL);
 
   MessageFactory* factory = MessageFactory::generated_factory();
 
-  AssignDescriptorsHelper<MigrationSchema> helper(factory, file_level_metadata,
-                                 file_level_enum_descriptors, schemas,
-                                 default_instances_, offsets);
+  AssignDescriptorsHelper<MigrationSchema> helper(
+      factory, table->file_level_metadata, table->file_level_enum_descriptors,
+      table->schemas, table->default_instances, table->offsets);
 
   for (int i = 0; i < file->message_type_count(); i++) {
     helper.AssignMessageDescriptor(file->message_type(i));
@@ -2380,13 +2364,48 @@
   }
   if (file->options().cc_generic_services()) {
     for (int i = 0; i < file->service_count(); i++) {
-      file_level_service_descriptors[i] = file->service(i);
+      table->file_level_service_descriptors[i] = file->service(i);
     }
   }
-  MetadataOwner::Instance()->AddArray(
-      file_level_metadata, helper.GetCurrentMetadataPtr());
+  MetadataOwner::Instance()->AddArray(table->file_level_metadata,
+                                      helper.GetCurrentMetadataPtr());
 }
 
+void AddDescriptorsImpl(const DescriptorTable* table, const InitFunc* deps,
+                        int num_deps) {
+  // Ensure default instances of this proto file are initialized.
+  table->init_defaults();
+  // Ensure all dependent descriptors are registered to the generated descriptor
+  // pool and message factory.
+  for (int i = 0; i < num_deps; i++) {
+    // In case of weak fields deps[i] could be null.
+    if (deps[i]) deps[i]();
+  }
+  // Register the descriptor of this file.
+  DescriptorPool::InternalAddGeneratedFile(table->descriptor, table->size);
+  MessageFactory::InternalRegisterGeneratedFile(
+      table->filename, table->assign_descriptors_table);
+}
+
+}  // namespace
+
+void AssignDescriptors(AssignDescriptorsTable* table) {
+  call_once(table->once, AssignDescriptorsImpl, table);
+}
+
+void AddDescriptors(DescriptorTable* table, const InitFunc* deps,
+                    int num_deps) {
+  // AddDescriptors is not thread safe. Callers need to ensure calls are
+  // properly serialized. This function is only called pre-main by global
+  // descriptors and we can assume single threaded access or it's called
+  // by AssignDescriptorImpl which uses a mutex to sequence calls.
+  if (table->is_initialized) return;
+  table->is_initialized = true;
+  AddDescriptorsImpl(table, deps, num_deps);
+}
+
+// Separate function because it needs to be a friend of
+// GeneratedMessageReflection
 void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) {
   for (int i = 0; i < size; i++) {
     const GeneratedMessageReflection* reflection =
@@ -2394,26 +2413,28 @@
            file_level_metadata[i].reflection);
     if (reflection) {
       // It's not a map type
-      ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      MessageFactory::InternalRegisterGeneratedMessage(
           file_level_metadata[i].descriptor,
           reflection->schema_.default_instance_);
     }
   }
 }
 
-void RegisterAllTypes(const Metadata* file_level_metadata, int size) {
-  RegisterAllTypesInternal(file_level_metadata, size);
+void RegisterFileLevelMetadata(void* assign_descriptors_table) {
+  auto table = static_cast<AssignDescriptorsTable*>(assign_descriptors_table);
+  AssignDescriptors(table);
+  RegisterAllTypesInternal(table->file_level_metadata, table->num_messages);
 }
 
 void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag,
                                uint32 has_offset,
-                               ::google::protobuf::io::CodedOutputStream* output) {
+                               io::CodedOutputStream* output) {
   const void* ptr = base + offset;
   const InternalMetadataWithArena* metadata =
       static_cast<const InternalMetadataWithArena*>(ptr);
   if (metadata->have_unknown_fields()) {
-    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        metadata->unknown_fields(), output);
+    internal::WireFormat::SerializeUnknownFields(metadata->unknown_fields(),
+                                                 output);
   }
 }
 
diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h
index 28a023b..177312c 100644
--- a/src/google/protobuf/generated_message_reflection.h
+++ b/src/google/protobuf/generated_message_reflection.h
@@ -47,33 +47,44 @@
 #include <google/protobuf/generated_enum_reflection.h>
 #include <google/protobuf/message.h>
 #include <google/protobuf/metadata.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/port.h>
 #include <google/protobuf/unknown_field_set.h>
 
 
-namespace google {
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace upb {
 namespace google_opensource {
 class GMR_Handlers;
 }  // namespace google_opensource
 }  // namespace upb
 
+namespace google {
 namespace protobuf {
 class DescriptorPool;
 class MapKey;
 class MapValueRef;
 }  // namespace protobuf
+}  // namespace google
 
-
+namespace google {
 namespace protobuf {
 namespace flat {
 class MetadataBuilder;
 }  // namespace flat
 }  // namespace protobuf
+}  // namespace google
 
-
+namespace google {
 namespace protobuf {
 namespace internal {
 class DefaultEmptyOneof;
+class ReflectionAccessor;
 
 // Defined in this file.
 class GeneratedMessageReflection;
@@ -98,7 +109,7 @@
 //                  macro. For each none oneof field, the offset is related to
 //                  the start of the message object.  These can be computed at
 //                  compile time using the
-//                  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro.
+//                  PROTO2_GENERATED_MESSAGE_FIELD_OFFSET() macro.
 //                  Besides offsets for all fields, this array also contains
 //                  offsets for oneof unions. The offset of the i-th oneof union
 //                  is offsets[descriptor->field_count() + i].
@@ -304,7 +315,6 @@
                              const DescriptorPool* pool,
                              MessageFactory* factory);
 
-
   ~GeneratedMessageReflection() override;
 
   // implements Reflection -------------------------------------------
@@ -324,32 +334,33 @@
   bool HasOneof(const Message& message,
                 const OneofDescriptor* oneof_descriptor) const override;
   void ClearOneof(Message* message,
-                  const OneofDescriptor* field) const override;
+                  const OneofDescriptor* oneof_descriptor) const override;
   void RemoveLast(Message* message,
                   const FieldDescriptor* field) const override;
   Message* ReleaseLast(Message* message,
                        const FieldDescriptor* field) const override;
   void Swap(Message* message1, Message* message2) const override;
-  void SwapFields(Message* message1, Message* message2,
-                  const std::vector<const FieldDescriptor*>& fields) const override;
-  void SwapElements(Message* message, const FieldDescriptor* field,
-                    int index1, int index2) const override;
+  void SwapFields(
+      Message* message1, Message* message2,
+      const std::vector<const FieldDescriptor*>& fields) const override;
+  void SwapElements(Message* message, const FieldDescriptor* field, int index1,
+                    int index2) const override;
   void ListFields(const Message& message,
                   std::vector<const FieldDescriptor*>* output) const override;
-  int32  GetInt32 (const Message& message,
-                   const FieldDescriptor* field) const override;
-  int64  GetInt64 (const Message& message,
-                   const FieldDescriptor* field) const override;
+  int32 GetInt32(const Message& message,
+                 const FieldDescriptor* field) const override;
+  int64 GetInt64(const Message& message,
+                 const FieldDescriptor* field) const override;
   uint32 GetUInt32(const Message& message,
                    const FieldDescriptor* field) const override;
   uint64 GetUInt64(const Message& message,
                    const FieldDescriptor* field) const override;
-  float  GetFloat (const Message& message,
-                   const FieldDescriptor* field) const override;
+  float GetFloat(const Message& message,
+                 const FieldDescriptor* field) const override;
   double GetDouble(const Message& message,
                    const FieldDescriptor* field) const override;
-  bool   GetBool  (const Message& message,
-                   const FieldDescriptor* field) const override;
+  bool GetBool(const Message& message,
+               const FieldDescriptor* field) const override;
   string GetString(const Message& message,
                    const FieldDescriptor* field) const override;
   const string& GetStringReference(const Message& message,
@@ -368,51 +379,44 @@
       const OneofDescriptor* oneof_descriptor) const override;
 
  private:
-  bool ContainsMapKey(const Message& message,
-                      const FieldDescriptor* field,
+  bool ContainsMapKey(const Message& message, const FieldDescriptor* field,
                       const MapKey& key) const override;
-  bool InsertOrLookupMapValue(Message* message,
-                              const FieldDescriptor* field,
+  bool InsertOrLookupMapValue(Message* message, const FieldDescriptor* field,
                               const MapKey& key,
                               MapValueRef* val) const override;
-  bool DeleteMapValue(Message* message,
-                      const FieldDescriptor* field,
+  bool DeleteMapValue(Message* message, const FieldDescriptor* field,
                       const MapKey& key) const override;
-  MapIterator MapBegin(
-      Message* message,
-      const FieldDescriptor* field) const override;
-  MapIterator MapEnd(
-      Message* message,
-      const FieldDescriptor* field) const override;
+  MapIterator MapBegin(Message* message,
+                       const FieldDescriptor* field) const override;
+  MapIterator MapEnd(Message* message,
+                     const FieldDescriptor* field) const override;
   int MapSize(const Message& message,
               const FieldDescriptor* field) const override;
 
  public:
-  void SetInt32 (Message* message,
-                 const FieldDescriptor* field, int32  value) const override;
-  void SetInt64 (Message* message,
-                 const FieldDescriptor* field, int64  value) const override;
-  void SetUInt32(Message* message,
-                 const FieldDescriptor* field, uint32 value) const override;
-  void SetUInt64(Message* message,
-                 const FieldDescriptor* field, uint64 value) const override;
-  void SetFloat (Message* message,
-                 const FieldDescriptor* field, float  value) const override;
-  void SetDouble(Message* message,
-                 const FieldDescriptor* field, double value) const override;
-  void SetBool  (Message* message,
-                 const FieldDescriptor* field, bool   value) const override;
-  void SetString(Message* message,
-                 const FieldDescriptor* field,
+  void SetInt32(Message* message, const FieldDescriptor* field,
+                int32 value) const override;
+  void SetInt64(Message* message, const FieldDescriptor* field,
+                int64 value) const override;
+  void SetUInt32(Message* message, const FieldDescriptor* field,
+                 uint32 value) const override;
+  void SetUInt64(Message* message, const FieldDescriptor* field,
+                 uint64 value) const override;
+  void SetFloat(Message* message, const FieldDescriptor* field,
+                float value) const override;
+  void SetDouble(Message* message, const FieldDescriptor* field,
+                 double value) const override;
+  void SetBool(Message* message, const FieldDescriptor* field,
+               bool value) const override;
+  void SetString(Message* message, const FieldDescriptor* field,
                  const string& value) const override;
-  void SetEnum  (Message* message, const FieldDescriptor* field,
-                 const EnumValueDescriptor* value) const override;
+  void SetEnum(Message* message, const FieldDescriptor* field,
+               const EnumValueDescriptor* value) const override;
   void SetEnumValue(Message* message, const FieldDescriptor* field,
                     int value) const override;
   Message* MutableMessage(Message* message, const FieldDescriptor* field,
                           MessageFactory* factory = NULL) const override;
-  void SetAllocatedMessage(Message* message,
-                           Message* sub_message,
+  void SetAllocatedMessage(Message* message, Message* sub_message,
                            const FieldDescriptor* field) const override;
   Message* ReleaseMessage(Message* message, const FieldDescriptor* field,
                           MessageFactory* factory = NULL) const override;
@@ -433,7 +437,7 @@
                        int index) const override;
   string GetRepeatedString(const Message& message, const FieldDescriptor* field,
                            int index) const override;
-  const string &GetRepeatedStringReference(const Message& message,
+  const string& GetRepeatedStringReference(const Message& message,
                                            const FieldDescriptor* field,
                                            int index,
                                            string* scratch) const override;
@@ -442,7 +446,7 @@
                                              int index) const override;
   int GetRepeatedEnumValue(const Message& message, const FieldDescriptor* field,
                            int index) const override;
-  const Message &GetRepeatedMessage(const Message& message,
+  const Message& GetRepeatedMessage(const Message& message,
                                     const FieldDescriptor* field,
                                     int index) const override;
 
@@ -462,7 +466,7 @@
   void SetRepeatedBool(Message* message, const FieldDescriptor* field,
                        int index, bool value) const override;
   void SetRepeatedString(Message* message, const FieldDescriptor* field,
-                         int index, const string &value) const override;
+                         int index, const string& value) const override;
   void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
                        int index,
                        const EnumValueDescriptor* value) const override;
@@ -473,33 +477,30 @@
                                   const FieldDescriptor* field,
                                   int index) const override;
 
-  void AddInt32 (Message* message,
-                 const FieldDescriptor* field, int32  value) const override;
-  void AddInt64 (Message* message,
-                 const FieldDescriptor* field, int64  value) const override;
-  void AddUInt32(Message* message,
-                 const FieldDescriptor* field, uint32 value) const override;
-  void AddUInt64(Message* message,
-                 const FieldDescriptor* field, uint64 value) const override;
-  void AddFloat (Message* message,
-                 const FieldDescriptor* field, float  value) const override;
-  void AddDouble(Message* message,
-                 const FieldDescriptor* field, double value) const override;
-  void AddBool  (Message* message,
-                 const FieldDescriptor* field, bool   value) const override;
+  void AddInt32(Message* message, const FieldDescriptor* field,
+                int32 value) const override;
+  void AddInt64(Message* message, const FieldDescriptor* field,
+                int64 value) const override;
+  void AddUInt32(Message* message, const FieldDescriptor* field,
+                 uint32 value) const override;
+  void AddUInt64(Message* message, const FieldDescriptor* field,
+                 uint64 value) const override;
+  void AddFloat(Message* message, const FieldDescriptor* field,
+                float value) const override;
+  void AddDouble(Message* message, const FieldDescriptor* field,
+                 double value) const override;
+  void AddBool(Message* message, const FieldDescriptor* field,
+               bool value) const override;
   void AddString(Message* message, const FieldDescriptor* field,
                  const string& value) const override;
-  void AddEnum(Message* message,
-               const FieldDescriptor* field,
+  void AddEnum(Message* message, const FieldDescriptor* field,
                const EnumValueDescriptor* value) const override;
-  void AddEnumValue(Message* message,
-                    const FieldDescriptor* field,
+  void AddEnumValue(Message* message, const FieldDescriptor* field,
                     int value) const override;
   Message* AddMessage(Message* message, const FieldDescriptor* field,
                       MessageFactory* factory = NULL) const override;
-  void AddAllocatedMessage(
-      Message* message, const FieldDescriptor* field,
-      Message* new_entry) const override;
+  void AddAllocatedMessage(Message* message, const FieldDescriptor* field,
+                           Message* new_entry) const override;
 
   const FieldDescriptor* FindKnownExtensionByName(
       const string& name) const override;
@@ -521,24 +522,24 @@
   static const int kUnknownFieldSetInMetadata = -1;
 
  protected:
-  void* MutableRawRepeatedField(
-      Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
-      int ctype, const Descriptor* desc) const override;
+  void* MutableRawRepeatedField(Message* message, const FieldDescriptor* field,
+                                FieldDescriptor::CppType, int ctype,
+                                const Descriptor* desc) const override;
 
-  const void* GetRawRepeatedField(
-      const Message& message, const FieldDescriptor* field,
-      FieldDescriptor::CppType, int ctype,
-      const Descriptor* desc) const override;
+  const void* GetRawRepeatedField(const Message& message,
+                                  const FieldDescriptor* field,
+                                  FieldDescriptor::CppType, int ctype,
+                                  const Descriptor* desc) const override;
 
-  virtual MessageFactory* GetMessageFactory() const override;
+  MessageFactory* GetMessageFactory() const override;
 
-  virtual void* RepeatedFieldData(
-      Message* message, const FieldDescriptor* field,
-      FieldDescriptor::CppType cpp_type,
-      const Descriptor* message_type) const override;
+  void* RepeatedFieldData(Message* message, const FieldDescriptor* field,
+                          FieldDescriptor::CppType cpp_type,
+                          const Descriptor* message_type) const override;
 
  private:
   friend class google::protobuf::flat::MetadataBuilder;
+  friend class ReflectionAccessor;
   friend class upb::google_opensource::GMR_Handlers;
 
   const Descriptor* const descriptor_;
@@ -669,8 +670,8 @@
                                       Message* sub_message,
                                       const FieldDescriptor* field) const;
 
-  internal::MapFieldBase* MapData(
-      Message* message, const FieldDescriptor* field) const override;
+  internal::MapFieldBase* MapData(Message* message,
+                                  const FieldDescriptor* field) const override;
 
   friend inline  // inline so nobody can call this function.
       void
@@ -678,89 +679,46 @@
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
 };
 
-// There are some places in proto2 where dynamic_cast would be useful as an
-// optimization.  For example, take Message::MergeFrom(const Message& other).
-// For a given generated message FooMessage, we generate these two methods:
-//   void MergeFrom(const FooMessage& other);
-//   void MergeFrom(const Message& other);
-// The former method can be implemented directly in terms of FooMessage's
-// inline accessors, but the latter method must work with the reflection
-// interface.  However, if the parameter to the latter method is actually of
-// type FooMessage, then we'd like to be able to just call the other method
-// as an optimization.  So, we use dynamic_cast to check this.
-//
-// That said, dynamic_cast requires RTTI, which many people like to disable
-// for performance and code size reasons.  When RTTI is not available, we
-// still need to produce correct results.  So, in this case we have to fall
-// back to using reflection, which is what we would have done anyway if the
-// objects were not of the exact same class.
-//
-// dynamic_cast_if_available() implements this logic.  If RTTI is
-// enabled, it does a dynamic_cast.  If RTTI is disabled, it just returns
-// NULL.
-template<typename To, typename From>
-inline To dynamic_cast_if_available(From from) {
-#ifdef GOOGLE_PROTOBUF_NO_RTTI
-  // Avoid the compiler warning about unused variables.
-  (void)from;
-  return NULL;
-#else
-  return dynamic_cast<To>(from);
-#endif
-}
+typedef void (*InitFunc)();
 
-// Tries to downcast this message to a generated message type.
-// Returns NULL if this class is not an instance of T.
-//
-// This is like dynamic_cast_if_available, except it works even when
-// dynamic_cast is not available by using Reflection.  However it only works
-// with Message objects.
-//
-// TODO(haberman): can we remove dynamic_cast_if_available in favor of this?
-template <typename T>
-T* DynamicCastToGenerated(const Message* from) {
-  // Compile-time assert that T is a generated type that has a
-  // default_instance() accessor, but avoid actually calling it.
-  const T&(*get_default_instance)() = &T::default_instance;
-  (void)get_default_instance;
+struct LIBPROTOBUF_EXPORT AssignDescriptorsTable {
+  once_flag once;
+  InitFunc add_descriptors;
+  const char* filename;
+  const MigrationSchema* schemas;
+  const Message* const* default_instances;
+  const uint32* offsets;
+  // update the following descriptor arrays.
+  Metadata* file_level_metadata;
+  int num_messages;
+  const EnumDescriptor** file_level_enum_descriptors;
+  const ServiceDescriptor** file_level_service_descriptors;
+};
 
-  // Compile-time assert that T is a subclass of google::protobuf::Message.
-  const Message* unused = static_cast<T*>(NULL);
-  (void)unused;
+void LIBPROTOBUF_EXPORT AssignDescriptors(AssignDescriptorsTable* table);
 
-#ifdef GOOGLE_PROTOBUF_NO_RTTI
-  bool ok = &T::default_instance() ==
-            from->GetReflection()->GetMessageFactory()->GetPrototype(
-                from->GetDescriptor());
-  return ok ? down_cast<T*>(from) : NULL;
-#else
-  return dynamic_cast<T*>(from);
-#endif
-}
+struct LIBPROTOBUF_EXPORT DescriptorTable {
+  bool is_initialized;
+  InitFunc init_defaults;
+  const char* descriptor;
+  const char* filename;
+  AssignDescriptorsTable* assign_descriptors_table;
+  int size;  // of serialized descriptor
+};
 
-template <typename T>
-T* DynamicCastToGenerated(Message* from) {
-  const Message* message_const = from;
-  return const_cast<T*>(DynamicCastToGenerated<const T>(message_const));
-}
-
-LIBPROTOBUF_EXPORT void AssignDescriptors(
-    const string& filename, const MigrationSchema* schemas,
-    const Message* const* default_instances_, const uint32* offsets,
-    // update the following descriptor arrays.
-    Metadata* file_level_metadata,
-    const EnumDescriptor** file_level_enum_descriptors,
-    const ServiceDescriptor** file_level_service_descriptors);
-
-LIBPROTOBUF_EXPORT void RegisterAllTypes(const Metadata* file_level_metadata, int size);
+void LIBPROTOBUF_EXPORT AddDescriptors(DescriptorTable* table,
+                                       const InitFunc* deps,
+                                       int num_deps);
 
 // These cannot be in lite so we put them in the reflection.
 LIBPROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag,
                                uint32 has_offset,
-                               ::google::protobuf::io::CodedOutputStream* output);
+                               io::CodedOutputStream* output);
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
diff --git a/src/google/protobuf/generated_message_reflection_unittest.cc b/src/google/protobuf/generated_message_reflection_unittest.cc
index 61eb660..c74e4f5 100644
--- a/src/google/protobuf/generated_message_reflection_unittest.cc
+++ b/src/google/protobuf/generated_message_reflection_unittest.cc
@@ -520,9 +520,9 @@
 TEST(GeneratedMessageReflectionTest, SetAllocatedMessageOnArenaTest) {
   unittest::TestAllTypes from_message1;
   unittest::TestAllTypes from_message2;
-  ::google::protobuf::Arena arena;
+  Arena arena;
   unittest::TestAllTypes* to_message =
-      ::google::protobuf::Arena::CreateMessage<unittest::TestAllTypes>(&arena);
+      Arena::CreateMessage<unittest::TestAllTypes>(&arena);
   TestUtil::ReflectionTester reflection_tester(
     unittest::TestAllTypes::descriptor());
   reflection_tester.SetAllFieldsViaReflection(&from_message1);
@@ -586,9 +586,9 @@
 }
 
 TEST(GeneratedMessageReflectionTest, SetAllocatedExtensionMessageOnArenaTest) {
-  ::google::protobuf::Arena arena;
+  Arena arena;
   unittest::TestAllExtensions* to_message =
-      ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+      Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
   unittest::TestAllExtensions from_message1;
   unittest::TestAllExtensions from_message2;
   TestUtil::ReflectionTester reflection_tester(
@@ -798,9 +798,9 @@
 TEST(GeneratedMessageReflectionTest, SetAllocatedOneofMessageOnArenaTest) {
   unittest::TestOneof2 from_message1;
   unittest::TestOneof2 from_message2;
-  ::google::protobuf::Arena arena;
+  Arena arena;
   unittest::TestOneof2* to_message =
-      ::google::protobuf::Arena::CreateMessage<unittest::TestOneof2>(&arena);
+      Arena::CreateMessage<unittest::TestOneof2>(&arena);
   const Descriptor* descriptor = unittest::TestOneof2::descriptor();
   const Reflection* reflection = to_message->GetReflection();
 
@@ -921,9 +921,9 @@
 }
 
 TEST(GeneratedMessageReflectionTest, ArenaReleaseMessageTest) {
-  ::google::protobuf::Arena arena;
+  Arena arena;
   unittest::TestAllTypes* message =
-      ::google::protobuf::Arena::CreateMessage<unittest::TestAllTypes>(&arena);
+      Arena::CreateMessage<unittest::TestAllTypes>(&arena);
   TestUtil::ReflectionTester reflection_tester(
       unittest::TestAllTypes::descriptor());
 
@@ -945,9 +945,9 @@
 }
 
 TEST(GeneratedMessageReflectionTest, ArenaReleaseExtensionMessageTest) {
-  ::google::protobuf::Arena arena;
+  Arena arena;
   unittest::TestAllExtensions* message =
-      ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+      Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
   TestUtil::ReflectionTester reflection_tester(
       unittest::TestAllExtensions::descriptor());
 
@@ -969,9 +969,9 @@
 }
 
 TEST(GeneratedMessageReflectionTest, ArenaReleaseOneofMessageTest) {
-  ::google::protobuf::Arena arena;
+  Arena arena;
   unittest::TestOneof2* message =
-      ::google::protobuf::Arena::CreateMessage<unittest::TestOneof2>(&arena);
+      Arena::CreateMessage<unittest::TestOneof2>(&arena);
   TestUtil::ReflectionTester::SetOneofViaReflection(message);
 
   const Descriptor* descriptor = unittest::TestOneof2::descriptor();
diff --git a/src/google/protobuf/generated_message_table_driven.h b/src/google/protobuf/generated_message_table_driven.h
index 10ca3aa..eb85ef5 100644
--- a/src/google/protobuf/generated_message_table_driven.h
+++ b/src/google/protobuf/generated_message_table_driven.h
@@ -48,6 +48,10 @@
 #define PROTOBUF_CONSTEXPR_VAR
 #endif  // !_clang
 
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 namespace internal {
@@ -64,6 +68,10 @@
 static constexpr const unsigned char kInvalidMask = 0x20;
 
 enum ProcessingTypes {
+  TYPE_STRING_CORD = 19,
+  TYPE_STRING_STRING_PIECE = 20,
+  TYPE_BYTES_CORD = 21,
+  TYPE_BYTES_STRING_PIECE = 22,
   TYPE_STRING_INLINED = 23,
   TYPE_BYTES_INLINED = 24,
   TYPE_MAP = 25,
@@ -183,18 +191,16 @@
 template <typename Entry>
 bool ParseMap(io::CodedInputStream* input, void* map_field) {
   typedef typename MapEntryToMapField<Entry>::MapFieldType MapFieldType;
-  typedef google::protobuf::Map<typename Entry::EntryKeyType,
-                      typename Entry::EntryValueType>
+  typedef Map<typename Entry::EntryKeyType, typename Entry::EntryValueType>
       MapType;
   typedef typename Entry::template Parser<MapFieldType, MapType> ParserType;
 
   ParserType parser(static_cast<MapFieldType*>(map_field));
-  return ::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(input,
-                                                                  &parser);
+  return WireFormatLite::ReadMessageNoVirtual(input, &parser);
 }
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_H__
diff --git a/src/google/protobuf/generated_message_table_driven_lite.cc b/src/google/protobuf/generated_message_table_driven_lite.cc
index 961329f..83c8180 100644
--- a/src/google/protobuf/generated_message_table_driven_lite.cc
+++ b/src/google/protobuf/generated_message_table_driven_lite.cc
@@ -54,23 +54,21 @@
                    io::CodedInputStream* input,
                    int tag) {
     GOOGLE_DCHECK(!table.unknown_field_set);
-    ::google::protobuf::io::StringOutputStream unknown_fields_string(
+    io::StringOutputStream unknown_fields_string(
         MutableUnknownFields(msg, table.arena_offset));
-    ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
-        &unknown_fields_string, false);
+    io::CodedOutputStream unknown_fields_stream(&unknown_fields_string, false);
 
-    return ::google::protobuf::internal::WireFormatLite::SkipField(
-        input, tag, &unknown_fields_stream);
+    return internal::WireFormatLite::SkipField(input, tag,
+                                               &unknown_fields_stream);
   }
 
   static void Varint(MessageLite* msg, const ParseTable& table,
                      int tag, int value) {
     GOOGLE_DCHECK(!table.unknown_field_set);
 
-    ::google::protobuf::io::StringOutputStream unknown_fields_string(
+    io::StringOutputStream unknown_fields_string(
         MutableUnknownFields(msg, table.arena_offset));
-    ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
-        &unknown_fields_string, false);
+    io::CodedOutputStream unknown_fields_stream(&unknown_fields_string, false);
     unknown_fields_stream.WriteVarint32(tag);
     unknown_fields_stream.WriteVarint32(value);
   }
@@ -86,10 +84,9 @@
     const MessageLite* prototype = table.default_instance();
 
     GOOGLE_DCHECK(!table.unknown_field_set);
-    ::google::protobuf::io::StringOutputStream unknown_fields_string(
+    io::StringOutputStream unknown_fields_string(
         MutableUnknownFields(msg, table.arena_offset));
-    ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
-        &unknown_fields_string, false);
+    io::CodedOutputStream unknown_fields_stream(&unknown_fields_string, false);
     return extensions->ParseField(
         tag, input, prototype, &unknown_fields_stream);
   }
diff --git a/src/google/protobuf/generated_message_table_driven_lite.h b/src/google/protobuf/generated_message_table_driven_lite.h
index 0d90fe3..4b461f1 100644
--- a/src/google/protobuf/generated_message_table_driven_lite.h
+++ b/src/google/protobuf/generated_message_table_driven_lite.h
@@ -104,15 +104,14 @@
                 std::is_same<Type, InlinedStringField>::value,
                 "Do not assign");
 
-  google::protobuf::RepeatedField<Type>* repeated =
-      Raw<google::protobuf::RepeatedField<Type> >(msg, offset);
+  RepeatedField<Type>* repeated = Raw<RepeatedField<Type>>(msg, offset);
   return repeated->Add();
 }
 
 template <>
 inline string* AddField<string>(MessageLite* msg, int64 offset) {
-  google::protobuf::RepeatedPtrField<string>* repeated =
-      Raw<google::protobuf::RepeatedPtrField<string> >(msg, offset);
+  RepeatedPtrField<string>* repeated =
+      Raw<RepeatedPtrField<string>>(msg, offset);
   return repeated->Add();
 }
 
@@ -168,7 +167,7 @@
     case WireFormatLite::TYPE_STRING:
     case WireFormatLite::TYPE_BYTES:
       Raw<ArenaStringPtr>(msg, field.offset)
-          ->Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena);
+          ->Destroy(&GetEmptyStringAlreadyInited(), arena);
       break;
 
     case TYPE_STRING_INLINED:
@@ -432,8 +431,7 @@
     break;                                                                     \
   }                                                                            \
   case (WireFormatLite::TYPE_##TYPE) | kRepeatedMask: {                        \
-    google::protobuf::RepeatedField<CPPTYPE>* values =                                   \
-        Raw<google::protobuf::RepeatedField<CPPTYPE> >(msg, offset);                     \
+    RepeatedField<CPPTYPE>* values = Raw<RepeatedField<CPPTYPE>>(msg, offset); \
     if (GOOGLE_PREDICT_FALSE((!WireFormatLite::ReadRepeatedPrimitive<            \
                             CPPTYPE, WireFormatLite::TYPE_##TYPE>(             \
             data->tag_size, tag, input, values)))) {                           \
@@ -678,8 +676,7 @@
             const MessageLite* prototype =
                 table.aux[field_number].messages.default_message();
             if (prototype == NULL) {
-              prototype =
-                  ::google::protobuf::internal::ImplicitWeakMessage::default_instance();
+              prototype = ImplicitWeakMessage::default_instance();
             }
             submsg = prototype->New(arena);
             *submsg_holder = submsg;
@@ -698,8 +695,7 @@
           const MessageLite* prototype =
               table.aux[field_number].messages.default_message();
           if (prototype == NULL) {
-            prototype =
-                ::google::protobuf::internal::ImplicitWeakMessage::default_instance();
+            prototype = ImplicitWeakMessage::default_instance();
           }
 
           MessageLite* submsg =
@@ -772,16 +768,15 @@
       // Mask out kRepeatedMask bit, allowing the jump table to be smaller.
       switch (static_cast<WireFormatLite::FieldType>(
           processing_type ^ kRepeatedMask)) {
-#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                 \
-  case WireFormatLite::TYPE_##TYPE: {                                     \
-    google::protobuf::RepeatedField<CPPTYPE>* values =                              \
-        Raw<google::protobuf::RepeatedField<CPPTYPE> >(msg, offset);                \
-    if (GOOGLE_PREDICT_FALSE(                                               \
-            (!WireFormatLite::ReadPackedPrimitive<                        \
-                CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, values)))) { \
-      return false;                                                       \
-    }                                                                     \
-    break;                                                                \
+#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                      \
+  case WireFormatLite::TYPE_##TYPE: {                                          \
+    RepeatedField<CPPTYPE>* values = Raw<RepeatedField<CPPTYPE>>(msg, offset); \
+    if (GOOGLE_PREDICT_FALSE(                                                    \
+            (!WireFormatLite::ReadPackedPrimitive<                             \
+                CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, values)))) {      \
+      return false;                                                            \
+    }                                                                          \
+    break;                                                                     \
   }
 
         HANDLE_PACKED_TYPE(INT32, int32, Int32)
@@ -813,14 +808,13 @@
 
           AuxillaryParseTableField::EnumValidator validator =
               table.aux[field_number].enums.validator;
-          google::protobuf::RepeatedField<int>* values =
-              Raw<google::protobuf::RepeatedField<int> >(msg, offset);
+          RepeatedField<int>* values = Raw<RepeatedField<int>>(msg, offset);
 
           io::CodedInputStream::Limit limit = input->PushLimit(length);
           while (input->BytesUntilLimit() > 0) {
             int value;
             if (GOOGLE_PREDICT_FALSE(
-                    (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                    (!WireFormatLite::ReadPrimitive<
                         int, WireFormatLite::TYPE_ENUM>(input, &value)))) {
               return false;
             }
@@ -868,6 +862,6 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__
diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc
index e024136..ba8ec6d 100644
--- a/src/google/protobuf/generated_message_util.cc
+++ b/src/google/protobuf/generated_message_util.cc
@@ -47,13 +47,14 @@
 #include <google/protobuf/message_lite.h>
 #include <google/protobuf/metadata_lite.h>
 #include <google/protobuf/stubs/mutex.h>
-#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/repeated_field.h>
 #include <google/protobuf/wire_format_lite.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 
-namespace google {
+#include <google/protobuf/port_def.inc>
 
+
+namespace google {
 namespace protobuf {
 namespace internal {
 
@@ -62,14 +63,8 @@
 }
 void DestroyString(const void* s) { static_cast<const string*>(s)->~string(); }
 
-ExplicitlyConstructed<std::string> fixed_address_empty_string;
+ExplicitlyConstructed<::std::string> fixed_address_empty_string;
 
-double Infinity() {
-  return std::numeric_limits<double>::infinity();
-}
-double NaN() {
-  return std::numeric_limits<double>::quiet_NaN();
-}
 
 static bool InitProtobufDefaultsImpl() {
   fixed_address_empty_string.DefaultConstruct();
@@ -108,8 +103,7 @@
 template <>
 struct PrimitiveTypeHelper<WireFormatLite::TYPE_BOOL> {
   typedef bool Type;
-  static void Serialize(const void* ptr,
-                        ::google::protobuf::io::CodedOutputStream* output) {
+  static void Serialize(const void* ptr, io::CodedOutputStream* output) {
     WireFormatLite::WriteBoolNoTag(Get<bool>(ptr), output);
   }
   static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
@@ -120,8 +114,7 @@
 template <>
 struct PrimitiveTypeHelper<WireFormatLite::TYPE_INT32> {
   typedef int32 Type;
-  static void Serialize(const void* ptr,
-                        ::google::protobuf::io::CodedOutputStream* output) {
+  static void Serialize(const void* ptr, io::CodedOutputStream* output) {
     WireFormatLite::WriteInt32NoTag(Get<int32>(ptr), output);
   }
   static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
@@ -132,8 +125,7 @@
 template <>
 struct PrimitiveTypeHelper<WireFormatLite::TYPE_SINT32> {
   typedef int32 Type;
-  static void Serialize(const void* ptr,
-                        ::google::protobuf::io::CodedOutputStream* output) {
+  static void Serialize(const void* ptr, io::CodedOutputStream* output) {
     WireFormatLite::WriteSInt32NoTag(Get<int32>(ptr), output);
   }
   static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
@@ -144,8 +136,7 @@
 template <>
 struct PrimitiveTypeHelper<WireFormatLite::TYPE_UINT32> {
   typedef uint32 Type;
-  static void Serialize(const void* ptr,
-                        ::google::protobuf::io::CodedOutputStream* output) {
+  static void Serialize(const void* ptr, io::CodedOutputStream* output) {
     WireFormatLite::WriteUInt32NoTag(Get<uint32>(ptr), output);
   }
   static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
@@ -155,8 +146,7 @@
 template <>
 struct PrimitiveTypeHelper<WireFormatLite::TYPE_INT64> {
   typedef int64 Type;
-  static void Serialize(const void* ptr,
-                        ::google::protobuf::io::CodedOutputStream* output) {
+  static void Serialize(const void* ptr, io::CodedOutputStream* output) {
     WireFormatLite::WriteInt64NoTag(Get<int64>(ptr), output);
   }
   static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
@@ -167,8 +157,7 @@
 template <>
 struct PrimitiveTypeHelper<WireFormatLite::TYPE_SINT64> {
   typedef int64 Type;
-  static void Serialize(const void* ptr,
-                        ::google::protobuf::io::CodedOutputStream* output) {
+  static void Serialize(const void* ptr, io::CodedOutputStream* output) {
     WireFormatLite::WriteSInt64NoTag(Get<int64>(ptr), output);
   }
   static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
@@ -178,8 +167,7 @@
 template <>
 struct PrimitiveTypeHelper<WireFormatLite::TYPE_UINT64> {
   typedef uint64 Type;
-  static void Serialize(const void* ptr,
-                        ::google::protobuf::io::CodedOutputStream* output) {
+  static void Serialize(const void* ptr, io::CodedOutputStream* output) {
     WireFormatLite::WriteUInt64NoTag(Get<uint64>(ptr), output);
   }
   static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
@@ -190,8 +178,7 @@
 template <>
 struct PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED32> {
   typedef uint32 Type;
-  static void Serialize(const void* ptr,
-                        ::google::protobuf::io::CodedOutputStream* output) {
+  static void Serialize(const void* ptr, io::CodedOutputStream* output) {
     WireFormatLite::WriteFixed32NoTag(Get<uint32>(ptr), output);
   }
   static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
@@ -202,8 +189,7 @@
 template <>
 struct PrimitiveTypeHelper<WireFormatLite::TYPE_FIXED64> {
   typedef uint64 Type;
-  static void Serialize(const void* ptr,
-                        ::google::protobuf::io::CodedOutputStream* output) {
+  static void Serialize(const void* ptr, io::CodedOutputStream* output) {
     WireFormatLite::WriteFixed64NoTag(Get<uint64>(ptr), output);
   }
   static uint8* SerializeToArray(const void* ptr, uint8* buffer) {
@@ -239,8 +225,7 @@
 template <>
 struct PrimitiveTypeHelper<WireFormatLite::TYPE_STRING> {
   typedef string Type;
-  static void Serialize(const void* ptr,
-                        ::google::protobuf::io::CodedOutputStream* output) {
+  static void Serialize(const void* ptr, io::CodedOutputStream* output) {
     const Type& value = *static_cast<const Type*>(ptr);
     output->WriteVarint32(value.size());
     output->WriteRawMaybeAliased(value.data(), value.size());
@@ -283,9 +268,8 @@
 
 // Specialization for coded output stream
 template <int type>
-struct OutputHelper<::google::protobuf::io::CodedOutputStream, type> {
-  static void Serialize(const void* ptr,
-                        ::google::protobuf::io::CodedOutputStream* output) {
+struct OutputHelper<io::CodedOutputStream, type> {
+  static void Serialize(const void* ptr, io::CodedOutputStream* output) {
     PrimitiveTypeHelper<type>::Serialize(ptr, output);
   }
 };
@@ -304,7 +288,7 @@
 };
 
 void SerializeMessageNoTable(const MessageLite* msg,
-                             ::google::protobuf::io::CodedOutputStream* output) {
+                             io::CodedOutputStream* output) {
   msg->SerializeWithCachedSizes(output);
 }
 
@@ -314,10 +298,10 @@
 }
 
 // Helper to branch to fast path if possible
-void SerializeMessageDispatch(const ::google::protobuf::MessageLite& msg,
+void SerializeMessageDispatch(const MessageLite& msg,
                               const FieldMetadata* field_table, int num_fields,
                               int32 cached_size,
-                              ::google::protobuf::io::CodedOutputStream* output) {
+                              io::CodedOutputStream* output) {
   const uint8* base = reinterpret_cast<const uint8*>(&msg);
   // Try the fast path
   uint8* ptr = output->GetDirectBufferForNBytesAndAdvance(cached_size);
@@ -332,7 +316,7 @@
 }
 
 // Helper to branch to fast path if possible
-void SerializeMessageDispatch(const ::google::protobuf::MessageLite& msg,
+void SerializeMessageDispatch(const MessageLite& msg,
                               const FieldMetadata* field_table, int num_fields,
                               int32 cached_size, ArrayOutput* output) {
   const uint8* base = reinterpret_cast<const uint8*>(&msg);
@@ -635,8 +619,7 @@
 
 void SerializeInternal(const uint8* base,
                        const FieldMetadata* field_metadata_table,
-                       int32 num_fields,
-                       ::google::protobuf::io::CodedOutputStream* output) {
+                       int32 num_fields, io::CodedOutputStream* output) {
   for (int i = 0; i < num_fields; i++) {
     const FieldMetadata& field_metadata = field_metadata_table[i];
     const uint8* ptr = base + field_metadata.offset;
@@ -725,15 +708,14 @@
 #undef SERIALIZERS_FOR_TYPE
 
 void ExtensionSerializer(const uint8* ptr, uint32 offset, uint32 tag,
-                         uint32 has_offset,
-                         ::google::protobuf::io::CodedOutputStream* output) {
+                         uint32 has_offset, io::CodedOutputStream* output) {
   reinterpret_cast<const ExtensionSet*>(ptr + offset)
       ->SerializeWithCachedSizes(tag, has_offset, output);
 }
 
 void UnknownFieldSerializerLite(const uint8* ptr, uint32 offset, uint32 tag,
                                 uint32 has_offset,
-                                ::google::protobuf::io::CodedOutputStream* output) {
+                                io::CodedOutputStream* output) {
   output->WriteString(
       reinterpret_cast<const InternalMetadataWithArenaLite*>(ptr + offset)
           ->unknown_fields());
diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h
index 76b8124..23d1009 100644
--- a/src/google/protobuf/generated_message_util.h
+++ b/src/google/protobuf/generated_message_util.h
@@ -46,15 +46,26 @@
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/once.h>  // Add direct dep on port for pb.cc
 #include <google/protobuf/has_bits.h>
 #include <google/protobuf/implicit_weak_message.h>
 #include <google/protobuf/map_entry_lite.h>
 #include <google/protobuf/message_lite.h>
+#include <google/protobuf/stubs/once.h>  // Add direct dep on port for pb.cc
+#include <google/protobuf/port.h>
 #include <google/protobuf/wire_format_lite.h>
 
-namespace google {
+#include <google/protobuf/port_def.inc>
 
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
+#if GOOGLE_PROTOBUF_ENABLE_MOMI_PARSER
+#include <google/protobuf/parse_context.h>
+#endif
+
+
+namespace google {
 namespace protobuf {
 
 class Arena;
@@ -64,18 +75,6 @@
 namespace internal {
 
 
-// Annotation for the compiler to emit a deprecation message if a field marked
-// with option 'deprecated=true' is used in the code, or for other things in
-// generated code which are deprecated.
-//
-// For internal use in the pb.cc files, deprecation warnings are suppressed
-// there.
-#undef DEPRECATED_PROTOBUF_FIELD
-#define PROTOBUF_DEPRECATED
-
-#define GOOGLE_PROTOBUF_DEPRECATED_ATTR
-
-
 // Returns the offset of the given field within the given aggregate type.
 // This is equivalent to the ANSI C offsetof() macro.  However, according
 // to the C++ standard, offsetof() only works on POD types, and GCC
@@ -88,7 +87,7 @@
 // For Clang we use __builtin_offsetof() and suppress the warning,
 // to avoid Control Flow Integrity and UBSan vptr sanitizers from
 // crashing while trying to validate the invalid reinterpet_casts.
-#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)  \
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \
   _Pragma("clang diagnostic push")                                   \
   _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"")         \
   __builtin_offsetof(TYPE, FIELD)                                    \
@@ -98,25 +97,21 @@
 // just use zero, GCC complains about dereferencing a NULL pointer.  We
 // choose 16 rather than some other number just in case the compiler would
 // be confused by an unaligned pointer.
-#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)  \
-  static_cast< ::google::protobuf::uint32>(                           \
-      reinterpret_cast<const char*>(                                 \
-          &reinterpret_cast<const TYPE*>(16)->FIELD) -               \
-      reinterpret_cast<const char*>(16))
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)      \
+  static_cast< ::google::protobuf::uint32>(reinterpret_cast<const char*>(                   \
+                             &reinterpret_cast<const TYPE*>(16)->FIELD) - \
+                         reinterpret_cast<const char*>(16))
 #endif
 
-// Constants for special floating point values.
-LIBPROTOBUF_EXPORT double Infinity();
-LIBPROTOBUF_EXPORT double NaN();
-
 LIBPROTOBUF_EXPORT void InitProtobufDefaults();
 
 // This used by proto1
-inline const std::string& GetEmptyString() {
+LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() {
   InitProtobufDefaults();
   return GetEmptyStringAlreadyInited();
 }
 
+
 // True if IsInitialized() is true for all elements of t.  Type is expected
 // to be a RepeatedPtrField<some message type>.  It's useful to have this
 // helper here to keep the protobuf compiler from ever having to emit loops in
@@ -133,10 +128,10 @@
 // This version operates on MessageLite to avoid introducing a dependency on the
 // concrete message type.
 template <class T>
-bool AllAreInitializedWeak(const ::google::protobuf::RepeatedPtrField<T>& t) {
+bool AllAreInitializedWeak(const RepeatedPtrField<T>& t) {
   for (int i = t.size(); --i >= 0;) {
-    if (!reinterpret_cast<const ::google::protobuf::internal::RepeatedPtrFieldBase&>(t)
-             .Get<::google::protobuf::internal::ImplicitWeakTypeHandler<T> >(i)
+    if (!reinterpret_cast<const RepeatedPtrFieldBase&>(t)
+             .Get<ImplicitWeakTypeHandler<T> >(i)
              .IsInitialized()) {
       return false;
     }
@@ -191,14 +186,13 @@
 
 typedef void (*SpecialSerializer)(const uint8* base, uint32 offset, uint32 tag,
                                   uint32 has_offset,
-                                  ::google::protobuf::io::CodedOutputStream* output);
+                                  io::CodedOutputStream* output);
 
 LIBPROTOBUF_EXPORT void ExtensionSerializer(const uint8* base, uint32 offset, uint32 tag,
-                         uint32 has_offset,
-                         ::google::protobuf::io::CodedOutputStream* output);
+                         uint32 has_offset, io::CodedOutputStream* output);
 LIBPROTOBUF_EXPORT void UnknownFieldSerializerLite(const uint8* base, uint32 offset, uint32 tag,
                                 uint32 has_offset,
-                                ::google::protobuf::io::CodedOutputStream* output);
+                                io::CodedOutputStream* output);
 
 struct SerializationTable {
   int num_fields;
@@ -206,11 +200,11 @@
 };
 
 LIBPROTOBUF_EXPORT void SerializeInternal(const uint8* base, const FieldMetadata* table,
-                       int32 num_fields, ::google::protobuf::io::CodedOutputStream* output);
+                       int32 num_fields, io::CodedOutputStream* output);
 
-inline void TableSerialize(const ::google::protobuf::MessageLite& msg,
+inline void TableSerialize(const MessageLite& msg,
                            const SerializationTable* table,
-                           ::google::protobuf::io::CodedOutputStream* output) {
+                           io::CodedOutputStream* output) {
   const FieldMetadata* field_table = table->field_table;
   int num_fields = table->num_fields - 1;
   const uint8* base = reinterpret_cast<const uint8*>(&msg);
@@ -227,7 +221,7 @@
                                 int32 num_fields, bool is_deterministic,
                                 uint8* buffer);
 
-inline uint8* TableSerializeToArray(const ::google::protobuf::MessageLite& msg,
+inline uint8* TableSerializeToArray(const MessageLite& msg,
                                     const SerializationTable* table,
                                     bool is_deterministic, uint8* buffer) {
   const uint8* base = reinterpret_cast<const uint8*>(&msg);
@@ -262,8 +256,7 @@
 
 template <typename MapFieldType, const SerializationTable* table>
 void MapFieldSerializer(const uint8* base, uint32 offset, uint32 tag,
-                        uint32 has_offset,
-                        ::google::protobuf::io::CodedOutputStream* output) {
+                        uint32 has_offset, io::CodedOutputStream* output) {
   typedef MapEntryHelper<typename MapFieldType::EntryTypeTrait> Entry;
   typedef typename MapFieldType::MapType::const_iterator Iter;
 
@@ -340,15 +333,15 @@
     kRunning = 1,
     kUninitialized = -1,  // initial state
   };
-#ifndef _MSC_VER
-  std::atomic<int> visit_status;
-#else
+#if defined(_MSC_VER) && !defined(__clang__)
   // MSVC doesnt make std::atomic constant initialized. This union trick
   // makes it so.
   union {
     int visit_status_to_make_linker_init;
     std::atomic<int> visit_status;
   };
+#else
+  std::atomic<int> visit_status;
 #endif
   int num_deps;
   void (*init_func)();
@@ -380,12 +373,14 @@
   OnShutdownRun(DestroyMessage, ptr);
 }
 // Destroy the string (call string destructor)
-inline void OnShutdownDestroyString(const std::string* ptr) {
+inline void OnShutdownDestroyString(const ::std::string* ptr) {
   OnShutdownRun(DestroyString, ptr);
 }
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
diff --git a/src/google/protobuf/has_bits.h b/src/google/protobuf/has_bits.h
index e3a0149..edf4e82 100644
--- a/src/google/protobuf/has_bits.h
+++ b/src/google/protobuf/has_bits.h
@@ -32,7 +32,13 @@
 #define GOOGLE_PROTOBUF_HAS_BITS_H__
 
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/port.h>
+
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
 
 namespace google {
 namespace protobuf {
@@ -52,7 +58,7 @@
   }
 
   const ::google::protobuf::uint32& operator[](int index) const
-  GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
+      GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
     return has_bits_[index];
   }
 
@@ -100,6 +106,8 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_HAS_BITS_H__
diff --git a/src/google/protobuf/implicit_weak_message.cc b/src/google/protobuf/implicit_weak_message.cc
index 7a1d444..7e47cdc 100644
--- a/src/google/protobuf/implicit_weak_message.cc
+++ b/src/google/protobuf/implicit_weak_message.cc
@@ -30,8 +30,11 @@
 
 #include <google/protobuf/implicit_weak_message.h>
 
-#include <google/protobuf/stubs/once.h>
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+#include <google/protobuf/parse_context.h>
+#endif
+#include <google/protobuf/stubs/once.h>
 #include <google/protobuf/wire_format_lite.h>
 
 namespace google {
@@ -44,17 +47,26 @@
   return WireFormatLite::SkipMessage(input, &coded_stream);
 }
 
-::google::protobuf::internal::ExplicitlyConstructed<ImplicitWeakMessage>
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ImplicitWeakMessage::_InternalParse(const char* begin,
+                                                const char* end, void* object,
+                                                ParseContext* ctx) {
+  return internal::StringParser(
+      begin, end, &(static_cast<ImplicitWeakMessage*>(object)->data_), ctx);
+}
+#endif
+
+ExplicitlyConstructed<ImplicitWeakMessage>
     implicit_weak_message_default_instance;
-GOOGLE_PROTOBUF_DECLARE_ONCE(implicit_weak_message_once_init_);
+internal::once_flag implicit_weak_message_once_init_;
 
 void InitImplicitWeakMessageDefaultInstance() {
   implicit_weak_message_default_instance.DefaultConstruct();
 }
 
 const ImplicitWeakMessage* ImplicitWeakMessage::default_instance() {
-  ::google::protobuf::GoogleOnceInit(&implicit_weak_message_once_init_,
-                 &InitImplicitWeakMessageDefaultInstance);
+  internal::call_once(implicit_weak_message_once_init_,
+                      InitImplicitWeakMessageDefaultInstance);
   return &implicit_weak_message_default_instance.get();
 }
 
diff --git a/src/google/protobuf/implicit_weak_message.h b/src/google/protobuf/implicit_weak_message.h
index 3279bd1..2983628 100644
--- a/src/google/protobuf/implicit_weak_message.h
+++ b/src/google/protobuf/implicit_weak_message.h
@@ -31,10 +31,15 @@
 #ifndef GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__
 #define GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__
 
+#include <string>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/message_lite.h>
 
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 // This file is logically internal-only and should only be used by protobuf
 // generated code.
 
@@ -71,6 +76,13 @@
 
   bool MergePartialFromCodedStream(io::CodedInputStream* input);
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  ParseFunc _ParseFunc() const { return _InternalParse; }
+
+  static const char* _InternalParse(const char* begin, const char* end,
+                                    void* object, ParseContext* ctx);
+#endif
+
   size_t ByteSizeLong() const { return data_.size(); }
 
   void SerializeWithCachedSizes(io::CodedOutputStream* output) const {
@@ -92,7 +104,7 @@
 class ImplicitWeakTypeHandler {
  public:
   typedef ImplicitWeakType Type;
-  typedef ::google::protobuf::MessageLite WeakType;
+  typedef MessageLite WeakType;
   static const bool Moveable = false;
 
   // With implicit weak fields, we need separate NewFromPrototype and
@@ -100,27 +112,24 @@
   // strong dependency on the message type, and it just delegates to the
   // GenericTypeHandler. The latter avoids creating a strong dependency, by
   // simply calling MessageLite::New.
-  static inline ::google::protobuf::MessageLite* NewFromPrototype(
-      const ::google::protobuf::MessageLite* prototype, ::google::protobuf::Arena* arena = NULL) {
+  static inline MessageLite* NewFromPrototype(const MessageLite* prototype,
+                                              Arena* arena = NULL) {
     return prototype->New(arena);
   }
 
-  static inline void Delete(::google::protobuf::MessageLite* value, Arena* arena) {
+  static inline void Delete(MessageLite* value, Arena* arena) {
     if (arena == NULL) {
       delete value;
     }
   }
-  static inline ::google::protobuf::Arena* GetArena(::google::protobuf::MessageLite* value) {
+  static inline Arena* GetArena(MessageLite* value) {
     return value->GetArena();
   }
-  static inline void* GetMaybeArenaPointer(::google::protobuf::MessageLite* value) {
+  static inline void* GetMaybeArenaPointer(MessageLite* value) {
     return value->GetArena();
   }
-  static inline void Clear(::google::protobuf::MessageLite* value) {
-    value->Clear();
-  }
-  static void Merge(const ::google::protobuf::MessageLite& from,
-                    ::google::protobuf::MessageLite* to) {
+  static inline void Clear(MessageLite* value) { value->Clear(); }
+  static void Merge(const MessageLite& from, MessageLite* to) {
     to->CheckTypeAndMergeFrom(from);
   }
   static inline size_t SpaceUsedLong(const Type& value) {
@@ -130,6 +139,6 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__
diff --git a/src/google/protobuf/inlined_string_field.h b/src/google/protobuf/inlined_string_field.h
index 95d4687..1509193 100644
--- a/src/google/protobuf/inlined_string_field.h
+++ b/src/google/protobuf/inlined_string_field.h
@@ -32,10 +32,17 @@
 #define GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
 
 #include <string>
+#include <utility>
 
-#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/port.h>
 #include <google/protobuf/stubs/stringpiece.h>
 
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 
@@ -53,16 +60,15 @@
 // the generated binary.
 class LIBPROTOBUF_EXPORT InlinedStringField {
  public:
-  InlinedStringField()
-    GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
+  InlinedStringField() GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
   explicit InlinedStringField(const ::std::string& default_value);
 
   void AssignWithDefault(const ::std::string* default_value,
                          const InlinedStringField& from)
-    GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
+      GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
 
-  void ClearToEmpty(const ::std::string* default_value, Arena* arena)
-      GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
+  void ClearToEmpty(const ::std::string* default_value,
+                    Arena* arena) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
     ClearToEmptyNoArena(default_value);
   }
   void ClearNonDefaultToEmpty() GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
@@ -72,34 +78,33 @@
       GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
     ClearNonDefaultToEmptyNoArena();
   }
-  void ClearNonDefaultToEmptyNoArena()
-    GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
+  void ClearNonDefaultToEmptyNoArena() GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
 
-  void ClearToDefault(const ::std::string* default_value, Arena* arena)
-      GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
+  void ClearToDefault(const ::std::string* default_value,
+                      Arena* arena) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
     ClearToDefaultNoArena(default_value);
   }
   void ClearToDefaultNoArena(const ::std::string* default_value)
-    GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
+      GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
 
-  void Destroy(const ::std::string* default_value, Arena* arena)
-      GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
+  void Destroy(const ::std::string* default_value,
+               Arena* arena) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
     DestroyNoArena(default_value);
   }
   void DestroyNoArena(const ::std::string* default_value)
-    GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
+      GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
 
   const ::std::string& Get() const GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
     return GetNoArena();
   }
   const ::std::string& GetNoArena() const GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
 
-  ::std::string* Mutable(const ::std::string* default_value, Arena* arena)
-      GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
+  ::std::string* Mutable(const ::std::string* default_value,
+                    Arena* arena) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
     return MutableNoArena(default_value);
   }
   ::std::string* MutableNoArena(const ::std::string* default_value)
-    GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
+      GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
 
   ::std::string* Release(const ::std::string* default_value, Arena* arena) {
     return ReleaseNoArena(default_value);
@@ -112,37 +117,31 @@
   }
   ::std::string* ReleaseNonDefaultNoArena(const ::std::string* default_value);
 
-  void Set(const ::std::string* default_value,
-           StringPiece value,
+  void Set(const ::std::string* default_value, StringPiece value,
            Arena* arena) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
     SetNoArena(default_value, value);
   }
-  void SetLite(const ::std::string* default_value,
-               StringPiece value,
+  void SetLite(const ::std::string* default_value, StringPiece value,
                Arena* arena) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
     SetNoArena(default_value, value);
   }
-  void SetNoArena(const ::std::string* default_value,
-                  StringPiece value) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
+  void SetNoArena(const ::std::string* default_value, StringPiece value)
+      GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
 
-  void Set(const ::std::string* default_value,
-           const ::std::string& value,
+  void Set(const ::std::string* default_value, const ::std::string& value,
            Arena* arena) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
     SetNoArena(default_value, value);
   }
-  void SetLite(const ::std::string* default_value,
-               const ::std::string& value,
+  void SetLite(const ::std::string* default_value, const ::std::string& value,
                Arena* arena) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE {
     SetNoArena(default_value, value);
   }
-  void SetNoArena(const ::std::string* default_value,
-                  const ::std::string& value)
-    GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
+  void SetNoArena(const ::std::string* default_value, const ::std::string& value)
+      GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
 
 #if LANG_CXX11
   void SetNoArena(const ::std::string* default_value,
-                  ::std::string&& value)
-    GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
+                  ::std::string&& value) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
 #endif
   void SetAllocated(const ::std::string* default_value,
                     ::std::string* value,
@@ -151,8 +150,7 @@
   }
   void SetAllocatedNoArena(const ::std::string* default_value,
                            ::std::string* value);
-  void Swap(InlinedStringField* from)
-    GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
+  void Swap(InlinedStringField* from) GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE;
   ::std::string* UnsafeMutablePointer();
   void UnsafeSetDefault(const ::std::string* default_value);
   ::std::string* UnsafeArenaRelease(const ::std::string* default_value, Arena* arena);
@@ -220,8 +218,8 @@
   return released;
 }
 
-inline void InlinedStringField::SetNoArena(
-    const ::std::string* default_value, StringPiece value) {
+inline void InlinedStringField::SetNoArena(const ::std::string* default_value,
+                                           StringPiece value) {
   value_.assign(value.data(), value.length());
 }
 
@@ -266,6 +264,8 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc
index 0851ff0..311668c 100644
--- a/src/google/protobuf/io/coded_stream.cc
+++ b/src/google/protobuf/io/coded_stream.cc
@@ -49,6 +49,8 @@
 #include <google/protobuf/stubs/stl_util.h>
 
 
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 namespace io {
@@ -191,7 +193,7 @@
                 "big (more than " << total_bytes_limit_
              << " bytes).  To increase the limit (or to disable these "
                 "warnings), see CodedInputStream::SetTotalBytesLimit() "
-                "in google/protobuf/io/coded_stream.h.";
+                "in net/proto2/io/public/coded_stream.h.";
 }
 
 bool CodedInputStream::SkipFallback(int count, int original_buffer_size) {
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index 0f70ecd..71a4f5f 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -133,11 +133,17 @@
   #endif
 #endif
 #include <google/protobuf/stubs/common.h>
+#include <google/protobuf/port.h>
 #include <google/protobuf/stubs/port.h>
-#include <google/protobuf/stubs/port.h>
+
+
+#include <google/protobuf/port_def.inc>
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+#include "util/coding/varint.h"
+#endif
 
 namespace google {
-
 namespace protobuf {
 
 class DescriptorPool;
@@ -263,7 +269,6 @@
 
   GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTagNoLastTag();
 
-
   // This usually a faster alternative to ReadTag() when cutoff is a manifest
   // constant.  It does particularly well for cutoff >= 127.  The first part
   // of the return value is the tag that was read, though it can also be 0 in
@@ -328,6 +333,7 @@
   // It also checks for some cases where, due to optimizations,
   // MergeFromCodedStream() can incorrectly return true.
   bool ConsumedEntireMessage();
+  void SetConsumed() { legitimate_message_end_ = true; }
 
   // Limits ----------------------------------------------------------
   // Limits are used when parsing length-delimited embedded messages.
@@ -384,7 +390,7 @@
   // This is unrelated to PushLimit()/PopLimit().
   void SetTotalBytesLimit(int total_bytes_limit);
 
-  PROTOBUF_RUNTIME_DEPRECATED(
+  GOOGLE_PROTOBUF_DEPRECATED_MSG(
       "Please use the single parameter version of SetTotalBytesLimit(). The "
       "second parameter is ignored.")
   void SetTotalBytesLimit(int total_bytes_limit, int) {
@@ -851,7 +857,8 @@
   }
 
   static bool IsDefaultSerializationDeterministic() {
-    return default_serialization_deterministic_.load(std::memory_order_relaxed) != 0;
+    return default_serialization_deterministic_.load(
+               std::memory_order_relaxed) != 0;
   }
 
  private:
@@ -889,7 +896,7 @@
   // that wants deterministic serialization by default needs to call
   // SetDefaultSerializationDeterministic() or ensure on its own that another
   // thread has done so.
-  friend void ::google::protobuf::internal::MapTestForceDeterministic();
+  friend void internal::MapTestForceDeterministic();
   static void SetDefaultSerializationDeterministic() {
     default_serialization_deterministic_.store(true, std::memory_order_relaxed);
   }
@@ -1390,11 +1397,13 @@
 
 }  // namespace io
 }  // namespace protobuf
+}  // namespace google
 
 
 #if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
   #pragma runtime_checks("c", restore)
 #endif  // _MSC_VER && !defined(__INTEL_COMPILER)
 
-}  // namespace google
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc
index 1c8d327..bcda8c8 100644
--- a/src/google/protobuf/io/coded_stream_unittest.cc
+++ b/src/google/protobuf/io/coded_stream_unittest.cc
@@ -44,18 +44,18 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
-
+#include <google/protobuf/stubs/casts.h>
 
 // This declares an unsigned long long integer literal in a portable way.
 // (The original macro is way too big and ruins my formatting.)
 #undef ULL
 #define ULL(x) GOOGLE_ULONGLONG(x)
 
-namespace google {
 
+namespace google {
 namespace protobuf {
 namespace io {
 namespace {
diff --git a/src/google/protobuf/io/gzip_stream.h b/src/google/protobuf/io/gzip_stream.h
index df1a446..ba1475c 100644
--- a/src/google/protobuf/io/gzip_stream.h
+++ b/src/google/protobuf/io/gzip_stream.h
@@ -45,6 +45,7 @@
 
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/port.h>
 #include <zlib.h>
 
 namespace google {
@@ -204,6 +205,6 @@
 
 }  // namespace io
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
diff --git a/src/google/protobuf/io/package_info.h b/src/google/protobuf/io/package_info.h
index dc1fc91..46c3dac 100644
--- a/src/google/protobuf/io/package_info.h
+++ b/src/google/protobuf/io/package_info.h
@@ -37,7 +37,6 @@
 // documentation generator.
 
 namespace google {
-
 namespace protobuf {
 
 // Auxiliary classes used for I/O.
diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc
index de67cef..e988db8 100644
--- a/src/google/protobuf/io/printer.cc
+++ b/src/google/protobuf/io/printer.cc
@@ -32,6 +32,8 @@
 //  Based on original Protocol Buffers design by
 //  Sanjay Ghemawat, Jeff Dean, and others.
 
+#include <cctype>
+
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/stubs/logging.h>
@@ -178,123 +180,6 @@
   WriteRaw(text + pos, size - pos);
 }
 
-void Printer::Print(const char* text) {
-  static std::map<string, string> empty;
-  Print(empty, text);
-}
-
-void Printer::Print(const char* text,
-                    const char* variable, const string& value) {
-  std::map<string, string> vars;
-  vars[variable] = value;
-  Print(vars, text);
-}
-
-void Printer::Print(const char* text,
-                    const char* variable1, const string& value1,
-                    const char* variable2, const string& value2) {
-  std::map<string, string> vars;
-  vars[variable1] = value1;
-  vars[variable2] = value2;
-  Print(vars, text);
-}
-
-void Printer::Print(const char* text,
-                    const char* variable1, const string& value1,
-                    const char* variable2, const string& value2,
-                    const char* variable3, const string& value3) {
-  std::map<string, string> vars;
-  vars[variable1] = value1;
-  vars[variable2] = value2;
-  vars[variable3] = value3;
-  Print(vars, text);
-}
-
-void Printer::Print(const char* text,
-                    const char* variable1, const string& value1,
-                    const char* variable2, const string& value2,
-                    const char* variable3, const string& value3,
-                    const char* variable4, const string& value4) {
-  std::map<string, string> vars;
-  vars[variable1] = value1;
-  vars[variable2] = value2;
-  vars[variable3] = value3;
-  vars[variable4] = value4;
-  Print(vars, text);
-}
-
-void Printer::Print(const char* text,
-                    const char* variable1, const string& value1,
-                    const char* variable2, const string& value2,
-                    const char* variable3, const string& value3,
-                    const char* variable4, const string& value4,
-                    const char* variable5, const string& value5) {
-  std::map<string, string> vars;
-  vars[variable1] = value1;
-  vars[variable2] = value2;
-  vars[variable3] = value3;
-  vars[variable4] = value4;
-  vars[variable5] = value5;
-  Print(vars, text);
-}
-
-void Printer::Print(const char* text,
-                    const char* variable1, const string& value1,
-                    const char* variable2, const string& value2,
-                    const char* variable3, const string& value3,
-                    const char* variable4, const string& value4,
-                    const char* variable5, const string& value5,
-                    const char* variable6, const string& value6) {
-  std::map<string, string> vars;
-  vars[variable1] = value1;
-  vars[variable2] = value2;
-  vars[variable3] = value3;
-  vars[variable4] = value4;
-  vars[variable5] = value5;
-  vars[variable6] = value6;
-  Print(vars, text);
-}
-
-void Printer::Print(const char* text,
-                    const char* variable1, const string& value1,
-                    const char* variable2, const string& value2,
-                    const char* variable3, const string& value3,
-                    const char* variable4, const string& value4,
-                    const char* variable5, const string& value5,
-                    const char* variable6, const string& value6,
-                    const char* variable7, const string& value7) {
-  std::map<string, string> vars;
-  vars[variable1] = value1;
-  vars[variable2] = value2;
-  vars[variable3] = value3;
-  vars[variable4] = value4;
-  vars[variable5] = value5;
-  vars[variable6] = value6;
-  vars[variable7] = value7;
-  Print(vars, text);
-}
-
-void Printer::Print(const char* text,
-                    const char* variable1, const string& value1,
-                    const char* variable2, const string& value2,
-                    const char* variable3, const string& value3,
-                    const char* variable4, const string& value4,
-                    const char* variable5, const string& value5,
-                    const char* variable6, const string& value6,
-                    const char* variable7, const string& value7,
-                    const char* variable8, const string& value8) {
-  std::map<string, string> vars;
-  vars[variable1] = value1;
-  vars[variable2] = value2;
-  vars[variable3] = value3;
-  vars[variable4] = value4;
-  vars[variable5] = value5;
-  vars[variable6] = value6;
-  vars[variable7] = value7;
-  vars[variable8] = value8;
-  Print(vars, text);
-}
-
 void Printer::Indent() {
   indent_ += "  ";
 }
@@ -343,6 +228,18 @@
   CopyToBuffer(data, size);
 }
 
+bool Printer::Next() {
+  do {
+    void* void_buffer;
+    if (!output_->Next(&void_buffer, &buffer_size_)) {
+      failed_ = true;
+      return false;
+    }
+    buffer_ = reinterpret_cast<char*>(void_buffer);
+  } while (buffer_size_ == 0);
+  return true;
+}
+
 void Printer::CopyToBuffer(const char* data, int size) {
   if (failed_) return;
   if (size == 0) return;
@@ -369,6 +266,134 @@
   offset_ += size;
 }
 
+void Printer::IndentIfAtStart() {
+  if (at_start_of_line_) {
+    CopyToBuffer(indent_.data(), indent_.size());
+    at_start_of_line_ = false;
+  }
+}
+
+void Printer::FormatInternal(const std::vector<string>& args,
+                             const std::map<string, string>& vars,
+                             const char* format) {
+  auto save = format;
+  int arg_index = 0;
+  std::vector<AnnotationCollector::Annotation> annotations;
+  while (*format) {
+    char c = *format++;
+    switch (c) {
+      case '$':
+        format = WriteVariable(args, vars, format, &arg_index, &annotations);
+        continue;
+      case '\n':
+        at_start_of_line_ = true;
+        line_start_variables_.clear();
+        break;
+      default:
+        IndentIfAtStart();
+        break;
+    }
+    push_back(c);
+  }
+  if (arg_index != args.size()) {
+    GOOGLE_LOG(FATAL) << " Unused arguments. " << save;
+  }
+  if (!annotations.empty()) {
+    GOOGLE_LOG(FATAL) << " Annotation range is not-closed, expect $}$. " << save;
+  }
+}
+
+const char* Printer::WriteVariable(
+    const std::vector<string>& args, const std::map<string, string>& vars,
+    const char* format, int* arg_index,
+    std::vector<AnnotationCollector::Annotation>* annotations) {
+  auto start = format;
+  auto end = strchr(format, '$');
+  if (!end) {
+    GOOGLE_LOG(FATAL) << " Unclosed variable name.";
+  }
+  format = end + 1;
+  if (end == start) {
+    // "$$" is an escape for just '$'
+    IndentIfAtStart();
+    push_back('$');
+    return format;
+  }
+  if (*start == '{') {
+    GOOGLE_CHECK(std::isdigit(start[1]));
+    GOOGLE_CHECK_EQ(end - start, 2);
+    int idx = start[1] - '1';
+    if (idx < 0 || idx >= args.size()) {
+      GOOGLE_LOG(FATAL) << "Annotation ${" << idx + 1 << "$ is out of bounds.";
+    }
+    if (idx > *arg_index) {
+      GOOGLE_LOG(FATAL) << "Annotation arg must be in correct order as given. Expected"
+                 << " ${" << (*arg_index) + 1 << "$ got ${" << idx + 1 << "$.";
+    } else if (idx == *arg_index) {
+      (*arg_index)++;
+    }
+    IndentIfAtStart();
+    annotations->push_back({{offset_, 0}, args[idx]});
+    return format;
+  } else if (*start == '}') {
+    GOOGLE_CHECK(annotations);
+    if (annotations->empty()) {
+      GOOGLE_LOG(FATAL) << "Unexpected end of annotation found.";
+    }
+    auto& a = annotations->back();
+    a.first.second = offset_;
+    if (annotation_collector_) annotation_collector_->AddAnnotationNew(a);
+    annotations->pop_back();
+    return format;
+  }
+  auto start_var = start;
+  while (start_var < end && *start_var == ' ') start_var++;
+  if (start_var == end) {
+    GOOGLE_LOG(FATAL) << " Empty variable.";
+  }
+  auto end_var = end;
+  while (start_var < end_var && *(end_var - 1) == ' ') end_var--;
+  string var_name{start_var,
+                  static_cast<string::size_type>(end_var - start_var)};
+  string sub;
+  if (std::isdigit(var_name[0])) {
+    GOOGLE_CHECK_EQ(var_name.size(), 1);  // No need for multi-digits
+    int idx = var_name[0] - '1';   // Start counting at 1
+    GOOGLE_CHECK_GE(idx, 0);
+    if (idx >= args.size()) {
+      GOOGLE_LOG(FATAL) << "Argument $" << idx + 1 << "$ is out of bounds.";
+    }
+    if (idx > *arg_index) {
+      GOOGLE_LOG(FATAL) << "Arguments must be used in same order as given. Expected $"
+                 << (*arg_index) + 1 << "$ got $" << idx + 1 << "$.";
+    } else if (idx == *arg_index) {
+      (*arg_index)++;
+    }
+    sub = args[idx];
+  } else {
+    auto it = vars.find(var_name);
+    if (it == vars.end()) {
+      GOOGLE_LOG(FATAL) << " Unknown variable: " << var_name << ".";
+    }
+    sub = it->second;
+  }
+
+  // By returning here in case of empty we also skip possible spaces inside
+  // the $...$, i.e. "void$ dllexpor$ f();" -> "void f();" in the empty case.
+  if (sub.empty()) return format;
+
+  // We're going to write something non-empty so we need a possible indent.
+  IndentIfAtStart();
+
+  // Write the possible spaces in front.
+  CopyToBuffer(start, start_var - start);
+  // Write a non-empty substituted variable.
+  CopyToBuffer(sub.c_str(), sub.size());
+  // Finish off with writing possible trailing spaces.
+  CopyToBuffer(end_var, end - end_var);
+  return format;
+}
+
 }  // namespace io
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/io/printer.h b/src/google/protobuf/io/printer.h
index d11745c..236aed4 100644
--- a/src/google/protobuf/io/printer.h
+++ b/src/google/protobuf/io/printer.h
@@ -51,12 +51,19 @@
 // Records annotations about a Printer's output.
 class LIBPROTOBUF_EXPORT AnnotationCollector {
  public:
+  // Annotation is a ofset range and a payload pair.
+  typedef std::pair<std::pair<size_t, size_t>, string> Annotation;
+
   // Records that the bytes in file_path beginning with begin_offset and ending
   // before end_offset are associated with the SourceCodeInfo-style path.
   virtual void AddAnnotation(size_t begin_offset, size_t end_offset,
                              const string& file_path,
                              const std::vector<int>& path) = 0;
 
+  // TODO(gerbens) I don't see why we need virtuals here. Just a vector of
+  // range, payload pairs stored in a context should suffice.
+  virtual void AddAnnotationNew(Annotation& a) {}
+
   virtual ~AnnotationCollector() {}
 };
 
@@ -84,6 +91,13 @@
     annotation->set_begin(begin_offset);
     annotation->set_end(end_offset);
   }
+  // Override for AnnotationCollector::AddAnnotation.
+  virtual void AddAnnotationNew(Annotation& a) {
+    auto* annotation = annotation_proto_->add_annotation();
+    annotation->ParseFromString(a.second);
+    annotation->set_begin(a.first.first);
+    annotation->set_end(a.first.second);
+  }
 
  private:
   // The protocol buffer to which new annotations should be added.
@@ -229,51 +243,11 @@
   void Print(const std::map<string, string>& variables, const char* text);
 
   // Like the first Print(), except the substitutions are given as parameters.
-  void Print(const char* text);
-  // Like the first Print(), except the substitutions are given as parameters.
-  void Print(const char* text, const char* variable, const string& value);
-  // Like the first Print(), except the substitutions are given as parameters.
-  void Print(const char* text, const char* variable1, const string& value1,
-                               const char* variable2, const string& value2);
-  // Like the first Print(), except the substitutions are given as parameters.
-  void Print(const char* text, const char* variable1, const string& value1,
-                               const char* variable2, const string& value2,
-                               const char* variable3, const string& value3);
-  // Like the first Print(), except the substitutions are given as parameters.
-  void Print(const char* text, const char* variable1, const string& value1,
-                               const char* variable2, const string& value2,
-                               const char* variable3, const string& value3,
-                               const char* variable4, const string& value4);
-  // Like the first Print(), except the substitutions are given as parameters.
-  void Print(const char* text, const char* variable1, const string& value1,
-                               const char* variable2, const string& value2,
-                               const char* variable3, const string& value3,
-                               const char* variable4, const string& value4,
-                               const char* variable5, const string& value5);
-  // Like the first Print(), except the substitutions are given as parameters.
-  void Print(const char* text, const char* variable1, const string& value1,
-                               const char* variable2, const string& value2,
-                               const char* variable3, const string& value3,
-                               const char* variable4, const string& value4,
-                               const char* variable5, const string& value5,
-                               const char* variable6, const string& value6);
-  // Like the first Print(), except the substitutions are given as parameters.
-  void Print(const char* text, const char* variable1, const string& value1,
-                               const char* variable2, const string& value2,
-                               const char* variable3, const string& value3,
-                               const char* variable4, const string& value4,
-                               const char* variable5, const string& value5,
-                               const char* variable6, const string& value6,
-                               const char* variable7, const string& value7);
-  // Like the first Print(), except the substitutions are given as parameters.
-  void Print(const char* text, const char* variable1, const string& value1,
-                               const char* variable2, const string& value2,
-                               const char* variable3, const string& value3,
-                               const char* variable4, const string& value4,
-                               const char* variable5, const string& value5,
-                               const char* variable6, const string& value6,
-                               const char* variable7, const string& value7,
-                               const char* variable8, const string& value8);
+  template <typename... Args>
+  void Print(const char* text, const Args&... args) {
+    std::map<string, string> vars;
+    PrintInternal(&vars, text, args...);
+  }
 
   // Indent text by two spaces.  After calling Indent(), two spaces will be
   // inserted at the beginning of each line of text.  Indent() may be called
@@ -296,6 +270,14 @@
   // This method does not look for newlines to add indentation.
   void WriteRaw(const char* data, int size);
 
+  // FormatInternal is a helper function not meant to use directly, use
+  // compiler::cpp::Formatter instead. This function is meant to support
+  // formatting text using named variables (eq. "$foo$) from a lookup map (vars)
+  // and variables directly supplied by arguments (eq "$1$" meaning first
+  // argument which is the zero index element of args).
+  void FormatInternal(const std::vector<string>& args,
+                      const std::map<string, string>& vars, const char* format);
+
   // True if any write to the underlying stream failed.  (We don't just
   // crash in this case because this is an I/O failure, not a programming
   // error.)
@@ -311,9 +293,40 @@
   void Annotate(const char* begin_varname, const char* end_varname,
                 const string& file_path, const std::vector<int>& path);
 
+  // Base case
+  void PrintInternal(std::map<string, string>* vars, const char* text) {
+    Print(*vars, text);
+  }
+
+  template <typename... Args>
+  void PrintInternal(std::map<string, string>* vars, const char* text,
+                     const char* key, const string& value,
+                     const Args&... args) {
+    (*vars)[key] = value;
+    PrintInternal(vars, text, args...);
+  }
+
   // Copy size worth of bytes from data to buffer_.
   void CopyToBuffer(const char* data, int size);
 
+  void push_back(char c) {
+    if (failed_) return;
+    if (buffer_size_ == 0) {
+      if (!Next()) return;
+    }
+    *buffer_++ = c;
+    buffer_size_--;
+    offset_++;
+  }
+
+  bool Next();
+
+  inline void IndentIfAtStart();
+  const char* WriteVariable(
+      const std::vector<string>& args, const std::map<string, string>& vars,
+      const char* format, int* arg_index,
+      std::vector<AnnotationCollector::Annotation>* annotations);
+
   const char variable_delimiter_;
 
   ZeroCopyOutputStream* const output_;
@@ -358,6 +371,6 @@
 
 }  // namespace io
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_IO_PRINTER_H__
diff --git a/src/google/protobuf/io/printer_unittest.cc b/src/google/protobuf/io/printer_unittest.cc
index d0a0ebe..fe46cee 100644
--- a/src/google/protobuf/io/printer_unittest.cc
+++ b/src/google/protobuf/io/printer_unittest.cc
@@ -46,7 +46,6 @@
 namespace google {
 namespace protobuf {
 namespace io {
-namespace {
 
 // Each test repeats over several block sizes in order to test both cases
 // where particular writes cross a buffer boundary and cases where they do
@@ -195,7 +194,7 @@
 
  private:
   // Allows access to GetLocationPath.
-  friend class ::google::protobuf::io::Printer;
+  friend class Printer;
 
   // Copies the pre-stored path to output.
   void GetLocationPath(std::vector<int>* output) const { *output = path_; }
@@ -594,7 +593,136 @@
   EXPECT_EQ("0123456789abcdef", string(buffer, sizeof(buffer)));
 }
 
-}  // namespace
+TEST(Printer, FormatInternal) {
+  std::vector<string> args{"arg1", "arg2"};
+  std::map<string, string> vars{{"foo", "bar"}, {"baz", "bla"}, {"empty", ""}};
+  // Substitution tests
+  {
+    // Direct arg substitution
+    string s;
+    {
+      StringOutputStream output(&s);
+      Printer printer(&output, '$');
+      printer.FormatInternal(args, vars, "$1$ $2$");
+    }
+    EXPECT_EQ("arg1 arg2", s);
+  }
+  {
+    // Variable substitution including spaces left
+    string s;
+    {
+      StringOutputStream output(&s);
+      Printer printer(&output, '$');
+      printer.FormatInternal({}, vars, "$foo$$ baz$$ empty$");
+    }
+    EXPECT_EQ("bar bla", s);
+  }
+  {
+    // Variable substitution including spaces right
+    string s;
+    {
+      StringOutputStream output(&s);
+      Printer printer(&output, '$');
+      printer.FormatInternal({}, vars, "$empty $$foo $$baz$");
+    }
+    EXPECT_EQ("bar bla", s);
+  }
+  {
+    // Mixed variable substitution
+    string s;
+    {
+      StringOutputStream output(&s);
+      Printer printer(&output, '$');
+      printer.FormatInternal(args, vars, "$empty $$1$ $foo $$2$ $baz$");
+    }
+    EXPECT_EQ("arg1 bar arg2 bla", s);
+  }
+
+  // Indentation tests
+  {
+    // Empty lines shouldn't indent.
+    string s;
+    {
+      StringOutputStream output(&s);
+      Printer printer(&output, '$');
+      printer.Indent();
+      printer.FormatInternal(args, vars, "$empty $\n\n$1$ $foo $$2$\n$baz$");
+      printer.Outdent();
+    }
+    EXPECT_EQ("\n\n  arg1 bar arg2\n  bla", s);
+  }
+  {
+    // Annotations should respect indentation.
+    string s;
+    GeneratedCodeInfo info;
+    {
+      StringOutputStream output(&s);
+      AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+      Printer printer(&output, '$', &info_collector);
+      printer.Indent();
+      GeneratedCodeInfo::Annotation annotation;
+      annotation.set_source_file("file.proto");
+      annotation.add_path(33);
+      std::vector<string> args{annotation.SerializeAsString(), "arg1", "arg2"};
+      printer.FormatInternal(args, vars, "$empty $\n\n${1$$2$$}$ $3$\n$baz$");
+      printer.Outdent();
+    }
+    EXPECT_EQ("\n\n  arg1 arg2\n  bla", s);
+    ASSERT_EQ(1, info.annotation_size());
+    const GeneratedCodeInfo::Annotation* arg1 = &info.annotation(0);
+    ASSERT_EQ(1, arg1->path_size());
+    EXPECT_EQ(33, arg1->path(0));
+    EXPECT_EQ("file.proto", arg1->source_file());
+    EXPECT_EQ(4, arg1->begin());
+    EXPECT_EQ(8, arg1->end());
+  }
+#ifdef PROTOBUF_HAS_DEATH_TEST
+  // Death tests in case of illegal format strings.
+  {
+    // Unused arguments
+    string s;
+    StringOutputStream output(&s);
+    Printer printer(&output, '$');
+    EXPECT_DEATH(printer.FormatInternal(args, vars, "$empty $$1$"), "Unused");
+  }
+  {
+    // Wrong order arguments
+    string s;
+    StringOutputStream output(&s);
+    Printer printer(&output, '$');
+    EXPECT_DEATH(printer.FormatInternal(args, vars, "$2$ $1$"), "order");
+  }
+  {
+    // Zero is illegal argument
+    string s;
+    StringOutputStream output(&s);
+    Printer printer(&output, '$');
+    EXPECT_DEATH(printer.FormatInternal(args, vars, "$0$"), "failed");
+  }
+  {
+    // Argument out of bounds
+    string s;
+    StringOutputStream output(&s);
+    Printer printer(&output, '$');
+    EXPECT_DEATH(printer.FormatInternal(args, vars, "$1$ $2$ $3$"), "bounds");
+  }
+  {
+    // Unknown variable
+    string s;
+    StringOutputStream output(&s);
+    Printer printer(&output, '$');
+    EXPECT_DEATH(printer.FormatInternal(args, vars, "$huh$ $1$$2$"), "Unknown");
+  }
+  {
+    // Illegal variable
+    string s;
+    StringOutputStream output(&s);
+    Printer printer(&output, '$');
+    EXPECT_DEATH(printer.FormatInternal({}, vars, "$ $"), "Empty");
+  }
+#endif  // PROTOBUF_HAS_DEATH_TEST
+}
+
 }  // namespace io
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/io/strtod.h b/src/google/protobuf/io/strtod.h
index f56e41c..38f544a 100644
--- a/src/google/protobuf/io/strtod.h
+++ b/src/google/protobuf/io/strtod.h
@@ -50,6 +50,6 @@
 
 }  // namespace io
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_IO_STRTOD_H__
diff --git a/src/google/protobuf/io/tokenizer.h b/src/google/protobuf/io/tokenizer.h
index e80d564..59b6772 100644
--- a/src/google/protobuf/io/tokenizer.h
+++ b/src/google/protobuf/io/tokenizer.h
@@ -406,6 +406,6 @@
 
 }  // namespace io
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_IO_TOKENIZER_H__
diff --git a/src/google/protobuf/io/zero_copy_stream.h b/src/google/protobuf/io/zero_copy_stream.h
index 62ace7a..f532d75 100644
--- a/src/google/protobuf/io/zero_copy_stream.h
+++ b/src/google/protobuf/io/zero_copy_stream.h
@@ -110,8 +110,8 @@
 #include <string>
 #include <google/protobuf/stubs/common.h>
 
-namespace google {
 
+namespace google {
 namespace protobuf {
 namespace io {
 
@@ -243,6 +243,6 @@
 
 }  // namespace io
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h
index ef9fc9d..206fd0d 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl.h
+++ b/src/google/protobuf/io/zero_copy_stream_impl.h
@@ -351,6 +351,6 @@
 
 }  // namespace io
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
index 66ad49b..7d7b689 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
+++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
@@ -37,9 +37,9 @@
 #include <algorithm>
 #include <limits>
 
-#include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/stl_util.h>
 
 namespace google {
@@ -200,8 +200,8 @@
   char junk[4096];
   int skipped = 0;
   while (skipped < count) {
-    int bytes =
-        Read(junk, std::min(count - skipped, implicit_cast<int>(sizeof(junk))));
+    int bytes = Read(junk, std::min(count - skipped,
+                                    ::google::protobuf::implicit_cast<int>(sizeof(junk))));
     if (bytes <= 0) {
       // EOF or read error.
       return skipped;
diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/google/protobuf/io/zero_copy_stream_impl_lite.h
index 38b6cde..da4ef45 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h
+++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h
@@ -381,6 +381,6 @@
 
 }  // namespace io
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc
index 08de8cb..4813206 100644
--- a/src/google/protobuf/io/zero_copy_stream_unittest.cc
+++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc
@@ -59,6 +59,7 @@
 #include <sstream>
 
 #include <google/protobuf/testing/file.h>
+#include <google/protobuf/test_util2.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 
@@ -566,11 +567,10 @@
 TEST_F(IoTest, CompressionOptions) {
   // Some ad-hoc testing of compression options.
 
+  string golden_filename =
+      TestUtil::GetTestDataPath("net/proto2/internal/testdata/golden_message");
   string golden;
-  GOOGLE_CHECK_OK(File::GetContents(
-      TestSourceDir() +
-          "/google/protobuf/testdata/golden_message",
-      &golden, true));
+  GOOGLE_CHECK_OK(File::GetContents(golden_filename, &golden, true));
 
   GzipOutputStream::Options options;
   string gzip_compressed = Compress(golden, options);
diff --git a/src/google/protobuf/lite_arena_unittest.cc b/src/google/protobuf/lite_arena_unittest.cc
index 3e88314..df88d2c 100644
--- a/src/google/protobuf/lite_arena_unittest.cc
+++ b/src/google/protobuf/lite_arena_unittest.cc
@@ -45,7 +45,7 @@
     arena_.reset(new Arena(options));
     // Trigger the allocation of the first arena block, so that further use of
     // the arena will not require any heap allocations.
-    google::protobuf::Arena::CreateArray<char>(arena_.get(), 1);
+    Arena::CreateArray<char>(arena_.get(), 1);
   }
 
   std::unique_ptr<Arena> arena_;
@@ -58,23 +58,23 @@
   {
     // TODO(teboring): Enable no heap check when ArenaStringPtr is used in
     // Map.
-    // google::protobuf::internal::NoHeapChecker no_heap;
+    // internal::NoHeapChecker no_heap;
 
     protobuf_unittest::TestArenaMapLite* from =
         Arena::CreateMessage<protobuf_unittest::TestArenaMapLite>(arena_.get());
-    google::protobuf::MapLiteTestUtil::SetArenaMapFields(from);
+    MapLiteTestUtil::SetArenaMapFields(from);
     from->SerializeToString(&data);
 
     protobuf_unittest::TestArenaMapLite* to =
         Arena::CreateMessage<protobuf_unittest::TestArenaMapLite>(arena_.get());
     to->ParseFromString(data);
-    google::protobuf::MapLiteTestUtil::ExpectArenaMapFieldsSet(*to);
+    MapLiteTestUtil::ExpectArenaMapFieldsSet(*to);
   }
 }
 
 TEST_F(LiteArenaTest, UnknownFieldMemLeak) {
   protobuf_unittest::ForeignMessageArenaLite* message =
-      google::protobuf::Arena::CreateMessage<protobuf_unittest::ForeignMessageArenaLite>(
+      Arena::CreateMessage<protobuf_unittest::ForeignMessageArenaLite>(
           arena_.get());
   string data = "\012\000";
   int original_capacity = data.capacity();
diff --git a/src/google/protobuf/lite_unittest.cc b/src/google/protobuf/lite_unittest.cc
index b42a7b1..ee44f51 100644
--- a/src/google/protobuf/lite_unittest.cc
+++ b/src/google/protobuf/lite_unittest.cc
@@ -50,18 +50,20 @@
 
 using std::string;
 
-namespace {
+namespace google {
+namespace protobuf {
+
 // Helper methods to test parsing merge behavior.
-void ExpectMessageMerged(const google::protobuf::unittest::TestAllTypesLite& message) {
+void ExpectMessageMerged(const unittest::TestAllTypesLite& message) {
   EXPECT_EQ(message.optional_int32(), 3);
   EXPECT_EQ(message.optional_int64(), 2);
   EXPECT_EQ(message.optional_string(), "hello");
 }
 
 void AssignParsingMergeMessages(
-    google::protobuf::unittest::TestAllTypesLite* msg1,
-    google::protobuf::unittest::TestAllTypesLite* msg2,
-    google::protobuf::unittest::TestAllTypesLite* msg3) {
+    unittest::TestAllTypesLite* msg1,
+    unittest::TestAllTypesLite* msg2,
+    unittest::TestAllTypesLite* msg3) {
   msg1->set_optional_int32(1);
   msg2->set_optional_int64(2);
   msg3->set_optional_int32(3);
@@ -69,18 +71,18 @@
 }
 
 void SetAllTypesInEmptyMessageUnknownFields(
-    google::protobuf::unittest::TestEmptyMessageLite* empty_message) {
+    unittest::TestEmptyMessageLite* empty_message) {
   protobuf_unittest::TestAllTypesLite message;
-  google::protobuf::TestUtilLite::ExpectClear(message);
-  google::protobuf::TestUtilLite::SetAllFields(&message);
+  TestUtilLite::ExpectClear(message);
+  TestUtilLite::SetAllFields(&message);
   string data = message.SerializeAsString();
   empty_message->ParseFromString(data);
 }
 
 void SetSomeTypesInEmptyMessageUnknownFields(
-    google::protobuf::unittest::TestEmptyMessageLite* empty_message) {
+    unittest::TestEmptyMessageLite* empty_message) {
   protobuf_unittest::TestAllTypesLite message;
-  google::protobuf::TestUtilLite::ExpectClear(message);
+  TestUtilLite::ExpectClear(message);
   message.set_optional_int32(101);
   message.set_optional_int64(102);
   message.set_optional_uint32(103);
@@ -89,25 +91,23 @@
   empty_message->ParseFromString(data);
 }
 
-}  // namespace
-
 TEST(Lite, AllLite1) {
   string data;
 
   {
     protobuf_unittest::TestAllTypesLite message, message2, message3;
-    google::protobuf::TestUtilLite::ExpectClear(message);
-    google::protobuf::TestUtilLite::SetAllFields(&message);
+    TestUtilLite::ExpectClear(message);
+    TestUtilLite::SetAllFields(&message);
     message2.CopyFrom(message);
     data = message.SerializeAsString();
     message3.ParseFromString(data);
-    google::protobuf::TestUtilLite::ExpectAllFieldsSet(message);
-    google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2);
-    google::protobuf::TestUtilLite::ExpectAllFieldsSet(message3);
-    google::protobuf::TestUtilLite::ModifyRepeatedFields(&message);
-    google::protobuf::TestUtilLite::ExpectRepeatedFieldsModified(message);
+    TestUtilLite::ExpectAllFieldsSet(message);
+    TestUtilLite::ExpectAllFieldsSet(message2);
+    TestUtilLite::ExpectAllFieldsSet(message3);
+    TestUtilLite::ModifyRepeatedFields(&message);
+    TestUtilLite::ExpectRepeatedFieldsModified(message);
     message.Clear();
-    google::protobuf::TestUtilLite::ExpectClear(message);
+    TestUtilLite::ExpectClear(message);
   }
 }
 
@@ -115,18 +115,18 @@
   string data;
   {
     protobuf_unittest::TestAllExtensionsLite message, message2, message3;
-    google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
-    google::protobuf::TestUtilLite::SetAllExtensions(&message);
+    TestUtilLite::ExpectExtensionsClear(message);
+    TestUtilLite::SetAllExtensions(&message);
     message2.CopyFrom(message);
     string extensions_data = message.SerializeAsString();
     message3.ParseFromString(extensions_data);
-    google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message);
-    google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2);
-    google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message3);
-    google::protobuf::TestUtilLite::ModifyRepeatedExtensions(&message);
-    google::protobuf::TestUtilLite::ExpectRepeatedExtensionsModified(message);
+    TestUtilLite::ExpectAllExtensionsSet(message);
+    TestUtilLite::ExpectAllExtensionsSet(message2);
+    TestUtilLite::ExpectAllExtensionsSet(message3);
+    TestUtilLite::ModifyRepeatedExtensions(&message);
+    TestUtilLite::ExpectRepeatedExtensionsModified(message);
     message.Clear();
-    google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
+    TestUtilLite::ExpectExtensionsClear(message);
   }
 }
 
@@ -135,35 +135,35 @@
 
   {
     protobuf_unittest::TestPackedTypesLite message, message2, message3;
-    google::protobuf::TestUtilLite::ExpectPackedClear(message);
-    google::protobuf::TestUtilLite::SetPackedFields(&message);
+    TestUtilLite::ExpectPackedClear(message);
+    TestUtilLite::SetPackedFields(&message);
     message2.CopyFrom(message);
     packed_data = message.SerializeAsString();
     message3.ParseFromString(packed_data);
-    google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message);
-    google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2);
-    google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message3);
-    google::protobuf::TestUtilLite::ModifyPackedFields(&message);
-    google::protobuf::TestUtilLite::ExpectPackedFieldsModified(message);
+    TestUtilLite::ExpectPackedFieldsSet(message);
+    TestUtilLite::ExpectPackedFieldsSet(message2);
+    TestUtilLite::ExpectPackedFieldsSet(message3);
+    TestUtilLite::ModifyPackedFields(&message);
+    TestUtilLite::ExpectPackedFieldsModified(message);
     message.Clear();
-    google::protobuf::TestUtilLite::ExpectPackedClear(message);
+    TestUtilLite::ExpectPackedClear(message);
   }
 
   {
     protobuf_unittest::TestPackedExtensionsLite message, message2, message3;
-    google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
-    google::protobuf::TestUtilLite::SetPackedExtensions(&message);
+    TestUtilLite::ExpectPackedExtensionsClear(message);
+    TestUtilLite::SetPackedExtensions(&message);
     message2.CopyFrom(message);
     string packed_extensions_data = message.SerializeAsString();
     EXPECT_EQ(packed_extensions_data, packed_data);
     message3.ParseFromString(packed_extensions_data);
-    google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message);
-    google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2);
-    google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message3);
-    google::protobuf::TestUtilLite::ModifyPackedExtensions(&message);
-    google::protobuf::TestUtilLite::ExpectPackedExtensionsModified(message);
+    TestUtilLite::ExpectPackedExtensionsSet(message);
+    TestUtilLite::ExpectPackedExtensionsSet(message2);
+    TestUtilLite::ExpectPackedExtensionsSet(message3);
+    TestUtilLite::ModifyPackedExtensions(&message);
+    TestUtilLite::ExpectPackedExtensionsModified(message);
     message.Clear();
-    google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
+    TestUtilLite::ExpectPackedExtensionsClear(message);
   }
 }
 
@@ -173,10 +173,10 @@
   {
     // Test that if an optional or required message/group field appears multiple
     // times in the input, they need to be merged.
-    google::protobuf::unittest::TestParsingMergeLite::RepeatedFieldsGenerator generator;
-    google::protobuf::unittest::TestAllTypesLite* msg1;
-    google::protobuf::unittest::TestAllTypesLite* msg2;
-    google::protobuf::unittest::TestAllTypesLite* msg3;
+    unittest::TestParsingMergeLite::RepeatedFieldsGenerator generator;
+    unittest::TestAllTypesLite* msg1;
+    unittest::TestAllTypesLite* msg2;
+    unittest::TestAllTypesLite* msg3;
 
 #define ASSIGN_REPEATED_FIELD(FIELD)                \
   msg1 = generator.add_##FIELD();                   \
@@ -204,7 +204,7 @@
 
     string buffer;
     generator.SerializeToString(&buffer);
-    google::protobuf::unittest::TestParsingMergeLite parsing_merge;
+    unittest::TestParsingMergeLite parsing_merge;
     parsing_merge.ParseFromString(buffer);
 
     // Required and optional fields should be merged.
@@ -213,13 +213,13 @@
     ExpectMessageMerged(
         parsing_merge.optionalgroup().optional_group_all_types());
     ExpectMessageMerged(parsing_merge.GetExtension(
-        google::protobuf::unittest::TestParsingMergeLite::optional_ext));
+        unittest::TestParsingMergeLite::optional_ext));
 
     // Repeated fields should not be merged.
     EXPECT_EQ(parsing_merge.repeated_all_types_size(), 3);
     EXPECT_EQ(parsing_merge.repeatedgroup_size(), 3);
     EXPECT_EQ(parsing_merge.ExtensionSize(
-                  google::protobuf::unittest::TestParsingMergeLite::repeated_ext),
+                  unittest::TestParsingMergeLite::repeated_ext),
               3);
   }
 }
@@ -231,17 +231,17 @@
   {
     protobuf_unittest::TestAllTypesLite message, message2;
     protobuf_unittest::TestEmptyMessageLite empty_message;
-    google::protobuf::TestUtilLite::ExpectClear(message);
-    google::protobuf::TestUtilLite::SetAllFields(&message);
+    TestUtilLite::ExpectClear(message);
+    TestUtilLite::SetAllFields(&message);
     data = message.SerializeAsString();
     empty_message.ParseFromString(data);
     data.clear();
     data = empty_message.SerializeAsString();
     message2.ParseFromString(data);
     data = message2.SerializeAsString();
-    google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2);
+    TestUtilLite::ExpectAllFieldsSet(message2);
     message.Clear();
-    google::protobuf::TestUtilLite::ExpectClear(message);
+    TestUtilLite::ExpectClear(message);
   }
 }
 
@@ -251,17 +251,17 @@
   {
     protobuf_unittest::TestAllExtensionsLite message, message2;
     protobuf_unittest::TestEmptyMessageLite empty_message;
-    google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
-    google::protobuf::TestUtilLite::SetAllExtensions(&message);
+    TestUtilLite::ExpectExtensionsClear(message);
+    TestUtilLite::SetAllExtensions(&message);
     data = message.SerializeAsString();
     empty_message.ParseFromString(data);
     data.clear();
     data = empty_message.SerializeAsString();
     message2.ParseFromString(data);
     data = message2.SerializeAsString();
-    google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2);
+    TestUtilLite::ExpectAllExtensionsSet(message2);
     message.Clear();
-    google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
+    TestUtilLite::ExpectExtensionsClear(message);
   }
 }
 
@@ -271,17 +271,17 @@
   {
     protobuf_unittest::TestPackedTypesLite message, message2;
     protobuf_unittest::TestEmptyMessageLite empty_message;
-    google::protobuf::TestUtilLite::ExpectPackedClear(message);
-    google::protobuf::TestUtilLite::SetPackedFields(&message);
+    TestUtilLite::ExpectPackedClear(message);
+    TestUtilLite::SetPackedFields(&message);
     data = message.SerializeAsString();
     empty_message.ParseFromString(data);
     data.clear();
     data = empty_message.SerializeAsString();
     message2.ParseFromString(data);
     data = message2.SerializeAsString();
-    google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2);
+    TestUtilLite::ExpectPackedFieldsSet(message2);
     message.Clear();
-    google::protobuf::TestUtilLite::ExpectPackedClear(message);
+    TestUtilLite::ExpectPackedClear(message);
   }
 }
 
@@ -291,17 +291,17 @@
   {
     protobuf_unittest::TestPackedExtensionsLite message, message2;
     protobuf_unittest::TestEmptyMessageLite empty_message;
-    google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
-    google::protobuf::TestUtilLite::SetPackedExtensions(&message);
+    TestUtilLite::ExpectPackedExtensionsClear(message);
+    TestUtilLite::SetPackedExtensions(&message);
     data = message.SerializeAsString();
     empty_message.ParseFromString(data);
     data.clear();
     data = empty_message.SerializeAsString();
     message2.ParseFromString(data);
     data = message2.SerializeAsString();
-    google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2);
+    TestUtilLite::ExpectPackedExtensionsSet(message2);
     message.Clear();
-    google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
+    TestUtilLite::ExpectPackedExtensionsClear(message);
   }
 }
 
@@ -343,10 +343,10 @@
     protobuf_unittest::TestEmptyMessageLite empty_message, empty_message2;
     message.set_optional_int32(101);
     message.add_repeated_int32(201);
-    message.set_optional_nested_enum(google::protobuf::unittest::TestAllTypesLite::BAZ);
+    message.set_optional_nested_enum(unittest::TestAllTypesLite::BAZ);
     message2.set_optional_int64(102);
     message2.add_repeated_int64(202);
-    message2.set_optional_foreign_enum(google::protobuf::unittest::FOREIGN_LITE_BAZ);
+    message2.set_optional_foreign_enum(unittest::FOREIGN_LITE_BAZ);
 
     data = message.SerializeAsString();
     empty_message.ParseFromString(data);
@@ -372,15 +372,15 @@
     protobuf_unittest::TestAllTypesLite message;
     string buffer;
     {
-      google::protobuf::io::StringOutputStream output_stream(&buffer);
-      google::protobuf::io::CodedOutputStream coded_output(&output_stream);
-      google::protobuf::internal::WireFormatLite::WriteTag(
+      io::StringOutputStream output_stream(&buffer);
+      io::CodedOutputStream coded_output(&output_stream);
+      internal::WireFormatLite::WriteTag(
           protobuf_unittest::TestAllTypesLite::kOptionalNestedEnumFieldNumber,
-          google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT, &coded_output);
+          internal::WireFormatLite::WIRETYPE_VARINT, &coded_output);
       coded_output.WriteVarint32(10);
-      google::protobuf::internal::WireFormatLite::WriteTag(
+      internal::WireFormatLite::WriteTag(
           protobuf_unittest::TestAllTypesLite::kRepeatedNestedEnumFieldNumber,
-          google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT, &coded_output);
+          internal::WireFormatLite::WIRETYPE_VARINT, &coded_output);
       coded_output.WriteVarint32(20);
     }
     message.ParseFromString(buffer);
@@ -410,11 +410,11 @@
     // Accessors
     protobuf_unittest::TestMapLite message;
 
-    google::protobuf::MapLiteTestUtil::SetMapFields(&message);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message);
+    MapLiteTestUtil::SetMapFields(&message);
+    MapLiteTestUtil::ExpectMapFieldsSet(message);
 
-    google::protobuf::MapLiteTestUtil::ModifyMapFields(&message);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsModified(message);
+    MapLiteTestUtil::ModifyMapFields(&message);
+    MapLiteTestUtil::ExpectMapFieldsModified(message);
   }
 }
 
@@ -425,8 +425,8 @@
     // SetMapFieldsInitialized
     protobuf_unittest::TestMapLite message;
 
-    google::protobuf::MapLiteTestUtil::SetMapFieldsInitialized(&message);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSetInitialized(message);
+    MapLiteTestUtil::SetMapFieldsInitialized(&message);
+    MapLiteTestUtil::ExpectMapFieldsSetInitialized(message);
   }
 }
 
@@ -437,9 +437,9 @@
     // Clear
     protobuf_unittest::TestMapLite message;
 
-    google::protobuf::MapLiteTestUtil::SetMapFields(&message);
+    MapLiteTestUtil::SetMapFields(&message);
     message.Clear();
-    google::protobuf::MapLiteTestUtil::ExpectClear(message);
+    MapLiteTestUtil::ExpectClear(message);
   }
 }
 
@@ -451,7 +451,7 @@
     protobuf_unittest::TestMessageMapLite message;
 
     // Creates a TestAllTypes with default value
-    google::protobuf::TestUtilLite::ExpectClear(
+    TestUtilLite::ExpectClear(
         (*message.mutable_map_int32_message())[0]);
   }
 }
@@ -463,13 +463,13 @@
     // CopyFrom
     protobuf_unittest::TestMapLite message1, message2;
 
-    google::protobuf::MapLiteTestUtil::SetMapFields(&message1);
+    MapLiteTestUtil::SetMapFields(&message1);
     message2.CopyFrom(message1);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
+    MapLiteTestUtil::ExpectMapFieldsSet(message2);
 
     // Copying from self should be a no-op.
     message2.CopyFrom(message2);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
+    MapLiteTestUtil::ExpectMapFieldsSet(message2);
   }
 }
 
@@ -498,13 +498,13 @@
     // SwapWithEmpty
     protobuf_unittest::TestMapLite message1, message2;
 
-    google::protobuf::MapLiteTestUtil::SetMapFields(&message1);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message1);
-    google::protobuf::MapLiteTestUtil::ExpectClear(message2);
+    MapLiteTestUtil::SetMapFields(&message1);
+    MapLiteTestUtil::ExpectMapFieldsSet(message1);
+    MapLiteTestUtil::ExpectClear(message2);
 
     message1.Swap(&message2);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
-    google::protobuf::MapLiteTestUtil::ExpectClear(message1);
+    MapLiteTestUtil::ExpectMapFieldsSet(message2);
+    MapLiteTestUtil::ExpectClear(message1);
   }
 }
 
@@ -515,11 +515,11 @@
     // SwapWithSelf
     protobuf_unittest::TestMapLite message;
 
-    google::protobuf::MapLiteTestUtil::SetMapFields(&message);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message);
+    MapLiteTestUtil::SetMapFields(&message);
+    MapLiteTestUtil::ExpectMapFieldsSet(message);
 
     message.Swap(&message);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message);
+    MapLiteTestUtil::ExpectMapFieldsSet(message);
   }
 }
 
@@ -530,13 +530,13 @@
     // SwapWithOther
     protobuf_unittest::TestMapLite message1, message2;
 
-    google::protobuf::MapLiteTestUtil::SetMapFields(&message1);
-    google::protobuf::MapLiteTestUtil::SetMapFields(&message2);
-    google::protobuf::MapLiteTestUtil::ModifyMapFields(&message2);
+    MapLiteTestUtil::SetMapFields(&message1);
+    MapLiteTestUtil::SetMapFields(&message2);
+    MapLiteTestUtil::ModifyMapFields(&message2);
 
     message1.Swap(&message2);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsModified(message1);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
+    MapLiteTestUtil::ExpectMapFieldsModified(message1);
+    MapLiteTestUtil::ExpectMapFieldsSet(message2);
   }
 }
 
@@ -546,10 +546,10 @@
   {
     // CopyConstructor
     protobuf_unittest::TestMapLite message1;
-    google::protobuf::MapLiteTestUtil::SetMapFields(&message1);
+    MapLiteTestUtil::SetMapFields(&message1);
 
     protobuf_unittest::TestMapLite message2(message1);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
+    MapLiteTestUtil::ExpectMapFieldsSet(message2);
   }
 }
 
@@ -559,15 +559,15 @@
   {
     // CopyAssignmentOperator
     protobuf_unittest::TestMapLite message1;
-    google::protobuf::MapLiteTestUtil::SetMapFields(&message1);
+    MapLiteTestUtil::SetMapFields(&message1);
 
     protobuf_unittest::TestMapLite message2;
     message2 = message1;
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
+    MapLiteTestUtil::ExpectMapFieldsSet(message2);
 
     // Make sure that self-assignment does something sane.
     message2.operator=(message2);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
+    MapLiteTestUtil::ExpectMapFieldsSet(message2);
   }
 }
 
@@ -578,7 +578,7 @@
     // NonEmptyMergeFrom
     protobuf_unittest::TestMapLite message1, message2;
 
-    google::protobuf::MapLiteTestUtil::SetMapFields(&message1);
+    MapLiteTestUtil::SetMapFields(&message1);
 
     // This field will test merging into an empty spot.
     (*message2.mutable_map_int32_int32())[1] = 1;
@@ -589,7 +589,7 @@
     (*message1.mutable_map_int32_double())[1] = 2;
 
     message1.MergeFrom(message2);
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message1);
+    MapLiteTestUtil::ExpectMapFieldsSet(message1);
   }
 }
 
@@ -618,14 +618,14 @@
     // Test the generated SerializeWithCachedSizesToArray()
     protobuf_unittest::TestMapLite message1, message2;
     string data;
-    google::protobuf::MapLiteTestUtil::SetMapFields(&message1);
+    MapLiteTestUtil::SetMapFields(&message1);
     int size = message1.ByteSize();
     data.resize(size);
     ::google::protobuf::uint8* start = reinterpret_cast<::google::protobuf::uint8*>(::google::protobuf::string_as_array(&data));
     ::google::protobuf::uint8* end = message1.SerializeWithCachedSizesToArray(start);
     EXPECT_EQ(size, end - start);
     EXPECT_TRUE(message2.ParseFromString(data));
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
+    MapLiteTestUtil::ExpectMapFieldsSet(message2);
   }
 }
 
@@ -635,21 +635,20 @@
   {
     // Test the generated SerializeWithCachedSizes()
     protobuf_unittest::TestMapLite message1, message2;
-    google::protobuf::MapLiteTestUtil::SetMapFields(&message1);
+    MapLiteTestUtil::SetMapFields(&message1);
     int size = message1.ByteSize();
     string data;
     data.resize(size);
     {
       // Allow the output stream to buffer only one byte at a time.
-      google::protobuf::io::ArrayOutputStream array_stream(
-          ::google::protobuf::string_as_array(&data), size, 1);
-      google::protobuf::io::CodedOutputStream output_stream(&array_stream);
+      io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
+      io::CodedOutputStream output_stream(&array_stream);
       message1.SerializeWithCachedSizes(&output_stream);
       EXPECT_FALSE(output_stream.HadError());
       EXPECT_EQ(size, output_stream.ByteCount());
     }
     EXPECT_TRUE(message2.ParseFromString(data));
-    google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2);
+    MapLiteTestUtil::ExpectMapFieldsSet(message2);
   }
 }
 
@@ -875,7 +874,7 @@
   {
     protobuf_unittest::TestOneofParsingLite message2;
     message2.mutable_oneof_submessage();
-    google::protobuf::io::CodedInputStream input_stream(
+    io::CodedInputStream input_stream(
         reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), serialized.size());
     EXPECT_TRUE(message2.MergeFromCodedStream(&input_stream));
     EXPECT_EQ(17, message2.oneof_int32());
@@ -885,7 +884,7 @@
   {
     protobuf_unittest::TestOneofParsingLite message2;
     message2.set_oneof_string("string");
-    google::protobuf::io::CodedInputStream input_stream(
+    io::CodedInputStream input_stream(
         reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), serialized.size());
     EXPECT_TRUE(message2.MergeFromCodedStream(&input_stream));
     EXPECT_EQ(17, message2.oneof_int32());
@@ -895,7 +894,7 @@
   {
     protobuf_unittest::TestOneofParsingLite message2;
     message2.set_oneof_bytes("bytes");
-    google::protobuf::io::CodedInputStream input_stream(
+    io::CodedInputStream input_stream(
         reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()), serialized.size());
     EXPECT_TRUE(message2.MergeFromCodedStream(&input_stream));
     EXPECT_EQ(17, message2.oneof_int32());
@@ -914,7 +913,7 @@
     EXPECT_TRUE(original.SerializeToString(&serialized));
     protobuf_unittest::TestOneofParsingLite parsed;
     for (int i = 0; i < 2; ++i) {
-      google::protobuf::io::CodedInputStream input_stream(
+      io::CodedInputStream input_stream(
           reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()),
           serialized.size());
       EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream));
@@ -930,7 +929,7 @@
     EXPECT_TRUE(original.SerializeToString(&serialized));
     protobuf_unittest::TestOneofParsingLite parsed;
     for (int i = 0; i < 2; ++i) {
-      google::protobuf::io::CodedInputStream input_stream(
+      io::CodedInputStream input_stream(
           reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()),
           serialized.size());
       EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream));
@@ -946,7 +945,7 @@
     EXPECT_TRUE(original.SerializeToString(&serialized));
     protobuf_unittest::TestOneofParsingLite parsed;
     for (int i = 0; i < 2; ++i) {
-      google::protobuf::io::CodedInputStream input_stream(
+      io::CodedInputStream input_stream(
           reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()),
           serialized.size());
       EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream));
@@ -962,7 +961,7 @@
     EXPECT_TRUE(original.SerializeToString(&serialized));
     protobuf_unittest::TestOneofParsingLite parsed;
     for (int i = 0; i < 2; ++i) {
-      google::protobuf::io::CodedInputStream input_stream(
+      io::CodedInputStream input_stream(
           reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()),
           serialized.size());
       EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream));
@@ -978,7 +977,7 @@
     EXPECT_TRUE(original.SerializeToString(&serialized));
     protobuf_unittest::TestOneofParsingLite parsed;
     for (int i = 0; i < 2; ++i) {
-      google::protobuf::io::CodedInputStream input_stream(
+      io::CodedInputStream input_stream(
           reinterpret_cast<const ::google::protobuf::uint8*>(serialized.data()),
           serialized.size());
       EXPECT_TRUE(parsed.MergeFromCodedStream(&input_stream));
@@ -995,7 +994,7 @@
 
   protobuf_unittest::ForeignMessageLite a;
   EXPECT_TRUE(a.ParseFromString(data));
-  google::protobuf::io::CodedInputStream input_stream(
+  io::CodedInputStream input_stream(
       reinterpret_cast<const ::google::protobuf::uint8*>(data.data()), data.size());
   EXPECT_TRUE(a.MergePartialFromCodedStream(&input_stream));
 
@@ -1034,3 +1033,6 @@
   ASSERT_EQ(1, packed.repeated_fixed32_size());
   EXPECT_EQ(42, packed.repeated_fixed32(0));
 }
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h
index 6463ac2..c5afa20 100644
--- a/src/google/protobuf/map.h
+++ b/src/google/protobuf/map.h
@@ -49,6 +49,10 @@
 #include <google/protobuf/map_type_handler.h>
 #include <google/protobuf/stubs/hash.h>
 
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 
@@ -78,7 +82,7 @@
 class GeneratedMessageReflection;
 }  // namespace internal
 
-// This is the class for google::protobuf::Map's internal value_type. Instead of using
+// This is the class for Map's internal value_type. Instead of using
 // std::pair as value_type, we use this class which provides us more control of
 // its process of construction and destruction.
 template <typename Key, typename T>
@@ -105,11 +109,11 @@
   T second;
 
  private:
-  friend class ::google::protobuf::Arena;
+  friend class Arena;
   friend class Map<Key, T>;
 };
 
-// google::protobuf::Map is an associative container type used to store protobuf map
+// Map is an associative container type used to store protobuf map
 // fields.  Each Map instance may or may not use a different hash function, a
 // different iteration order, and so on.  E.g., please don't examine
 // implementation details to decide if the following would work:
@@ -181,7 +185,7 @@
   }
 
   // re-implement std::allocator to use arena allocator for memory allocation.
-  // Used for google::protobuf::Map implementation. Users should not use this class
+  // Used for Map implementation. Users should not use this class
   // directly.
   template <typename U>
   class MapAllocator {
@@ -1047,9 +1051,8 @@
     value_type** value =  &(*elements_)[key];
     if (*value == NULL) {
       *value = CreateValueTypeInternal(key);
-      internal::MapValueInitializer<google::protobuf::is_proto_enum<T>::value,
-                                    T>::Initialize((*value)->second,
-                                                   default_enum_value_);
+      internal::MapValueInitializer<is_proto_enum<T>::value, T>::Initialize(
+          (*value)->second, default_enum_value_);
     }
     return (*value)->second;
   }
@@ -1203,7 +1206,7 @@
   int default_enum_value_;
   InnerMap* elements_;
 
-  friend class ::google::protobuf::Arena;
+  friend class Arena;
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
   template <typename Derived, typename K, typename V,
@@ -1214,6 +1217,6 @@
 };
 
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_MAP_H__
diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h
index f170f97..53f3507 100644
--- a/src/google/protobuf/map_entry.h
+++ b/src/google/protobuf/map_entry.h
@@ -35,10 +35,17 @@
 #include <google/protobuf/map_entry_lite.h>
 #include <google/protobuf/map_type_handler.h>
 #include <google/protobuf/metadata.h>
+#include <google/protobuf/port.h>
 #include <google/protobuf/reflection_ops.h>
 #include <google/protobuf/unknown_field_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 class Arena;
@@ -48,8 +55,10 @@
           WireFormatLite::FieldType kValueFieldType, int default_enum_value>
 class MapField;
 }
-}
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace internal {
 
@@ -95,9 +104,10 @@
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
 
-  typedef typename MapEntryImpl<
-      Derived, Message, Key, Value, kKeyFieldType, kValueFieldType,
-      default_enum_value>::KeyTypeHandler KeyTypeHandler;
+  typedef
+      typename MapEntryImpl<Derived, Message, Key, Value, kKeyFieldType,
+                            kValueFieldType, default_enum_value>::KeyTypeHandler
+          KeyTypeHandler;
   typedef typename MapEntryImpl<
       Derived, Message, Key, Value, kKeyFieldType, kValueFieldType,
       default_enum_value>::ValueTypeHandler ValueTypeHandler;
@@ -111,7 +121,7 @@
   InternalMetadataWithArena _internal_metadata_;
 
  private:
-  friend class ::google::protobuf::Arena;
+  friend class ::GOOGLE_PROTOBUF_NAMESPACE_ID::Arena;
   template <typename C, typename K, typename V,
             WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType,
             int default_enum>
@@ -148,6 +158,8 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_MAP_ENTRY_H__
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index 01c734b..982f0f4 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -32,15 +32,22 @@
 #define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
 
 #include <assert.h>
+#include <string>
 
 #include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arenastring.h>
 #include <google/protobuf/map.h>
 #include <google/protobuf/map_type_handler.h>
-#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/port.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 namespace internal {
@@ -54,7 +61,9 @@
 class MapFieldLite;
 }  // namespace internal
 }  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace internal {
 
@@ -183,7 +192,7 @@
     MergeFromInternal(*::google::protobuf::down_cast<const Derived*>(&other));
   }
 
-  bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) override {
+  bool MergePartialFromCodedStream(io::CodedInputStream* input) override {
     uint32 tag;
 
     for (;;) {
@@ -233,13 +242,13 @@
     return size;
   }
 
-  void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const override {
+  void SerializeWithCachedSizes(io::CodedOutputStream* output) const override {
     KeyTypeHandler::Write(kKeyFieldNumber, key(), output);
     ValueTypeHandler::Write(kValueFieldNumber, value(), output);
   }
 
-  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(bool deterministic,
-                                                   ::google::protobuf::uint8* output) const override {
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* output) const override {
     output = KeyTypeHandler::InternalWriteToArray(kKeyFieldNumber, key(),
                                                   deterministic, output);
     output = ValueTypeHandler::InternalWriteToArray(kValueFieldNumber, value(),
@@ -260,7 +269,9 @@
     return size;
   }
 
-  bool IsInitialized() const override { return ValueTypeHandler::IsInitialized(value_); }
+  bool IsInitialized() const override {
+    return ValueTypeHandler::IsInitialized(value_);
+  }
 
   Base* New() const override {
     Derived* entry = new Derived;
@@ -305,20 +316,18 @@
     ValueTypeHandler::AssignDefaultValue(&d->value_);
   }
 
-  Arena* GetArena() const override {
-    return GetArenaNoVirtual();
-  }
+  Arena* GetArena() const override { return GetArenaNoVirtual(); }
 
-  // Create a MapEntryImpl for given key and value from google::protobuf::Map in
+  // Create a MapEntryImpl for given key and value from Map in
   // serialization. This function is only called when value is enum. Enum is
   // treated differently because its type in MapEntry is int and its type in
-  // google::protobuf::Map is enum. We cannot create a reference to int from an enum.
+  // Map is enum. We cannot create a reference to int from an enum.
   static Derived* EnumWrap(const Key& key, const Value value, Arena* arena) {
     return Arena::CreateMessage<MapEnumEntryWrapper>(arena, key, value);
   }
 
   // Like above, but for all the other types. This avoids value copy to create
-  // MapEntryImpl from google::protobuf::Map in serialization.
+  // MapEntryImpl from Map in serialization.
   static Derived* Wrap(const Key& key, const Value& value, Arena* arena) {
     return Arena::CreateMessage<MapEntryWrapper>(arena, key, value);
   }
@@ -333,7 +342,7 @@
     // This does what the typical MergePartialFromCodedStream() is expected to
     // do, with the additional side-effect that if successful (i.e., if true is
     // going to be its return value) it inserts the key-value pair into map_.
-    bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
+    bool MergePartialFromCodedStream(io::CodedInputStream* input) {
       // Look for the expected thing: a key and then a value.  If it fails,
       // invoke the enclosing class's MergePartialFromCodedStream, or return
       // false if that would be pointless.
@@ -397,7 +406,7 @@
     // After reading a key and value successfully, and inserting that data
     // into map_, we are not at the end of the input.  This is unusual, but
     // allowed by the spec.
-    bool ReadBeyondKeyValuePair(::google::protobuf::io::CodedInputStream* input)
+    bool ReadBeyondKeyValuePair(io::CodedInputStream* input)
         GOOGLE_PROTOBUF_ATTRIBUTE_COLD {
       typedef MoveHelper<KeyTypeHandler::kIsEnum,
                          KeyTypeHandler::kIsMessage,
@@ -438,9 +447,9 @@
 
  private:
   // Serializing a generated message containing map field involves serializing
-  // key-value pairs from google::protobuf::Map. The wire format of each key-value pair
+  // key-value pairs from Map. The wire format of each key-value pair
   // after serialization should be the same as that of a MapEntry message
-  // containing the same key and value inside it.  However, google::protobuf::Map doesn't
+  // containing the same key and value inside it.  However, Map doesn't
   // store key and value as MapEntry message, which disables us to use existing
   // code to serialize message. In order to use existing code to serialize
   // message, we need to construct a MapEntry from key-value pair. But it
@@ -459,14 +468,16 @@
       BaseClass::set_has_key();
       BaseClass::set_has_value();
     }
-    inline const KeyMapEntryAccessorType &key() const override { return key_; }
-    inline const ValueMapEntryAccessorType& value() const override { return value_; }
+    inline const KeyMapEntryAccessorType& key() const override { return key_; }
+    inline const ValueMapEntryAccessorType& value() const override {
+      return value_;
+    }
 
    private:
     const Key& key_;
     const Value& value_;
 
-    friend class ::google::protobuf::Arena;
+    friend class ::GOOGLE_PROTOBUF_NAMESPACE_ID::Arena;
     typedef void InternalArenaConstructable_;
     typedef void DestructorSkippable_;
   };
@@ -496,7 +507,7 @@
     const KeyMapEntryAccessorType& key_;
     const ValueMapEntryAccessorType value_;
 
-    friend class google::protobuf::Arena;
+    friend class ::GOOGLE_PROTOBUF_NAMESPACE_ID::Arena;
     typedef void DestructorSkippable_;
   };
 
@@ -511,7 +522,7 @@
   uint32 _has_bits_[1];
 
  private:
-  friend class ::google::protobuf::Arena;
+  friend class ::GOOGLE_PROTOBUF_NAMESPACE_ID::Arena;
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
   template <typename C, typename K, typename V, WireFormatLite::FieldType,
@@ -659,6 +670,8 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc
index ac29c7e..2ce54cb 100644
--- a/src/google/protobuf/map_field.cc
+++ b/src/google/protobuf/map_field.cc
@@ -43,15 +43,13 @@
 
 const RepeatedPtrFieldBase& MapFieldBase::GetRepeatedField() const {
   SyncRepeatedFieldWithMap();
-  return *reinterpret_cast<::google::protobuf::internal::RepeatedPtrFieldBase*>(
-      repeated_field_);
+  return *reinterpret_cast<RepeatedPtrFieldBase*>(repeated_field_);
 }
 
 RepeatedPtrFieldBase* MapFieldBase::MutableRepeatedField() {
   SyncRepeatedFieldWithMap();
   SetRepeatedDirty();
-  return reinterpret_cast<::google::protobuf::internal::RepeatedPtrFieldBase*>(
-      repeated_field_);
+  return reinterpret_cast<RepeatedPtrFieldBase*>(repeated_field_);
 }
 
 size_t MapFieldBase::SpaceUsedExcludingSelfLong() const {
@@ -179,12 +177,12 @@
     // Allocate memory for the inserted MapValueRef, and initialize to
     // default value.
     switch (val_des->cpp_type()) {
-#define HANDLE_TYPE(CPPTYPE, TYPE)                              \
-      case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: {        \
-        TYPE * value = new TYPE();                              \
-        map_val.SetValue(value);                                \
-        break;                                                  \
-      }
+#define HANDLE_TYPE(CPPTYPE, TYPE)           \
+  case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
+    TYPE* value = new TYPE();                \
+    map_val.SetValue(value);                 \
+    break;                                   \
+  }
       HANDLE_TYPE(INT32, int32);
       HANDLE_TYPE(INT64, int64);
       HANDLE_TYPE(UINT32, uint32);
@@ -195,7 +193,7 @@
       HANDLE_TYPE(STRING, string);
       HANDLE_TYPE(ENUM, int32);
 #undef HANDLE_TYPE
-      case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
+      case FieldDescriptor::CPPTYPE_MESSAGE: {
         const Message& message = default_entry_->GetReflection()->GetMessage(
             *default_entry_, val_des);
         Message* value = message.New();
@@ -245,6 +243,17 @@
   map_iter->value_.CopyFrom(iter->second);
 }
 
+void DynamicMapField::Swap(MapFieldBase* other) {
+  DynamicMapField* other_field = down_cast<DynamicMapField*>(other);
+  std::swap(this->MapFieldBase::repeated_field_, other_field->repeated_field_);
+  map_.swap(other_field->map_);
+  // a relaxed swap of the atomic
+  auto other_state = other_field->state_.load(std::memory_order_relaxed);
+  auto this_state = this->MapFieldBase::state_.load(std::memory_order_relaxed);
+  other_field->state_.store(this_state, std::memory_order_relaxed);
+  this->MapFieldBase::state_.store(other_state, std::memory_order_relaxed);
+}
+
 void DynamicMapField::SyncRepeatedFieldWithMapNoLock() const {
   const Reflection* reflection = default_entry_->GetReflection();
   const FieldDescriptor* key_des =
@@ -269,61 +278,61 @@
     MapFieldBase::repeated_field_->AddAllocated(new_entry);
     const MapKey& map_key = it->first;
     switch (key_des->cpp_type()) {
-      case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
+      case FieldDescriptor::CPPTYPE_STRING:
         reflection->SetString(new_entry, key_des, map_key.GetStringValue());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
+      case FieldDescriptor::CPPTYPE_INT64:
         reflection->SetInt64(new_entry, key_des, map_key.GetInt64Value());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
+      case FieldDescriptor::CPPTYPE_INT32:
         reflection->SetInt32(new_entry, key_des, map_key.GetInt32Value());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
+      case FieldDescriptor::CPPTYPE_UINT64:
         reflection->SetUInt64(new_entry, key_des, map_key.GetUInt64Value());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
+      case FieldDescriptor::CPPTYPE_UINT32:
         reflection->SetUInt32(new_entry, key_des, map_key.GetUInt32Value());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
+      case FieldDescriptor::CPPTYPE_BOOL:
         reflection->SetBool(new_entry, key_des, map_key.GetBoolValue());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
-      case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
-      case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
-      case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
+      case FieldDescriptor::CPPTYPE_DOUBLE:
+      case FieldDescriptor::CPPTYPE_FLOAT:
+      case FieldDescriptor::CPPTYPE_ENUM:
+      case FieldDescriptor::CPPTYPE_MESSAGE:
         GOOGLE_LOG(FATAL) << "Can't get here.";
         break;
     }
     const MapValueRef& map_val = it->second;
     switch (val_des->cpp_type()) {
-      case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
+      case FieldDescriptor::CPPTYPE_STRING:
         reflection->SetString(new_entry, val_des, map_val.GetStringValue());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
+      case FieldDescriptor::CPPTYPE_INT64:
         reflection->SetInt64(new_entry, val_des, map_val.GetInt64Value());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
+      case FieldDescriptor::CPPTYPE_INT32:
         reflection->SetInt32(new_entry, val_des, map_val.GetInt32Value());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
+      case FieldDescriptor::CPPTYPE_UINT64:
         reflection->SetUInt64(new_entry, val_des, map_val.GetUInt64Value());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
+      case FieldDescriptor::CPPTYPE_UINT32:
         reflection->SetUInt32(new_entry, val_des, map_val.GetUInt32Value());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
+      case FieldDescriptor::CPPTYPE_BOOL:
         reflection->SetBool(new_entry, val_des, map_val.GetBoolValue());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
+      case FieldDescriptor::CPPTYPE_DOUBLE:
         reflection->SetDouble(new_entry, val_des, map_val.GetDoubleValue());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
+      case FieldDescriptor::CPPTYPE_FLOAT:
         reflection->SetFloat(new_entry, val_des, map_val.GetFloatValue());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
+      case FieldDescriptor::CPPTYPE_ENUM:
         reflection->SetEnumValue(new_entry, val_des, map_val.GetEnumValue());
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
+      case FieldDescriptor::CPPTYPE_MESSAGE: {
         const Message& message = map_val.GetMessageValue();
         reflection->MutableMessage(new_entry, val_des)->CopyFrom(message);
         break;
@@ -351,28 +360,28 @@
        it != MapFieldBase::repeated_field_->end(); ++it) {
     MapKey map_key;
     switch (key_des->cpp_type()) {
-      case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
+      case FieldDescriptor::CPPTYPE_STRING:
         map_key.SetStringValue(reflection->GetString(*it, key_des));
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
+      case FieldDescriptor::CPPTYPE_INT64:
         map_key.SetInt64Value(reflection->GetInt64(*it, key_des));
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
+      case FieldDescriptor::CPPTYPE_INT32:
         map_key.SetInt32Value(reflection->GetInt32(*it, key_des));
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
+      case FieldDescriptor::CPPTYPE_UINT64:
         map_key.SetUInt64Value(reflection->GetUInt64(*it, key_des));
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
+      case FieldDescriptor::CPPTYPE_UINT32:
         map_key.SetUInt32Value(reflection->GetUInt32(*it, key_des));
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
+      case FieldDescriptor::CPPTYPE_BOOL:
         map_key.SetBoolValue(reflection->GetBool(*it, key_des));
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
-      case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
-      case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
-      case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
+      case FieldDescriptor::CPPTYPE_DOUBLE:
+      case FieldDescriptor::CPPTYPE_FLOAT:
+      case FieldDescriptor::CPPTYPE_ENUM:
+      case FieldDescriptor::CPPTYPE_MESSAGE:
         GOOGLE_LOG(FATAL) << "Can't get here.";
         break;
     }
@@ -386,13 +395,13 @@
     MapValueRef& map_val = (*map)[map_key];
     map_val.SetType(val_des->cpp_type());
     switch (val_des->cpp_type()) {
-#define HANDLE_TYPE(CPPTYPE, TYPE, METHOD)                      \
-      case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: {        \
-        TYPE * value = new TYPE;                                \
-        *value = reflection->Get##METHOD(*it, val_des);         \
-            map_val.SetValue(value);                            \
-            break;                                              \
-      }
+#define HANDLE_TYPE(CPPTYPE, TYPE, METHOD)          \
+  case FieldDescriptor::CPPTYPE_##CPPTYPE: {        \
+    TYPE* value = new TYPE;                         \
+    *value = reflection->Get##METHOD(*it, val_des); \
+    map_val.SetValue(value);                        \
+    break;                                          \
+  }
       HANDLE_TYPE(INT32, int32, Int32);
       HANDLE_TYPE(INT64, int64, Int64);
       HANDLE_TYPE(UINT32, uint32, UInt32);
@@ -403,7 +412,7 @@
       HANDLE_TYPE(STRING, string, String);
       HANDLE_TYPE(ENUM, int32, EnumValue);
 #undef HANDLE_TYPE
-      case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
+      case FieldDescriptor::CPPTYPE_MESSAGE: {
         const Message& message = reflection->GetMessage(*it, val_des);
         Message* value = message.New();
         value->CopyFrom(message);
@@ -426,16 +435,16 @@
     size += sizeof(it->first) * map_size;
     size += sizeof(it->second) * map_size;
     // If key is string, add the allocated space.
-    if (it->first.type() == google::protobuf::FieldDescriptor::CPPTYPE_STRING) {
+    if (it->first.type() == FieldDescriptor::CPPTYPE_STRING) {
       size += sizeof(string) * map_size;
     }
     // Add the allocated space in MapValueRef.
     switch (it->second.type()) {
-#define HANDLE_TYPE(CPPTYPE, TYPE)                              \
-      case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: {        \
-        size += sizeof(TYPE) * map_size;                        \
-        break;                                                  \
-      }
+#define HANDLE_TYPE(CPPTYPE, TYPE)           \
+  case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
+    size += sizeof(TYPE) * map_size;         \
+    break;                                   \
+  }
       HANDLE_TYPE(INT32, int32);
       HANDLE_TYPE(INT64, int64);
       HANDLE_TYPE(UINT32, uint32);
@@ -446,7 +455,7 @@
       HANDLE_TYPE(STRING, string);
       HANDLE_TYPE(ENUM, int32);
 #undef HANDLE_TYPE
-      case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
+      case FieldDescriptor::CPPTYPE_MESSAGE: {
         while (it != map_.end()) {
           const Message& message = it->second.GetMessageValue();
           size += message.GetReflection()->SpaceUsedLong(message);
diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h
index 44ca29b..9e60191 100644
--- a/src/google/protobuf/map_field.h
+++ b/src/google/protobuf/map_field.h
@@ -33,23 +33,30 @@
 
 #include <atomic>
 
-#include <google/protobuf/stubs/mutex.h>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/generated_message_reflection.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
 #include <google/protobuf/map_entry.h>
 #include <google/protobuf/map_field_lite.h>
 #include <google/protobuf/map_type_handler.h>
 #include <google/protobuf/message.h>
+#include <google/protobuf/stubs/mutex.h>
+#include <google/protobuf/port.h>
 #include <google/protobuf/repeated_field.h>
 #include <google/protobuf/unknown_field_set.h>
 
 
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 class DynamicMessage;
 class MapKey;
+class MapIterator;
 namespace internal {
 
 class ContendedMapCleanTest;
@@ -76,7 +83,7 @@
   virtual ~MapFieldBase();
 
   // Returns reference to internal repeated field. Data written using
-  // google::protobuf::Map's api prior to calling this function is guarantted to be
+  // Map's api prior to calling this function is guarantted to be
   // included in repeated field.
   const RepeatedPtrFieldBase& GetRepeatedField() const;
 
@@ -96,6 +103,7 @@
                              const MapIterator& b) const = 0;
   virtual void MapBegin(MapIterator* map_iter) const = 0;
   virtual void MapEnd(MapIterator* map_iter) const = 0;
+  virtual void Swap(MapFieldBase* other) = 0;
   // Sync Map with repeated field and returns the size of map.
   virtual int size() const = 0;
 
@@ -141,7 +149,7 @@
   Arena* arena_;
   mutable RepeatedPtrField<Message>* repeated_field_;
 
-  mutable Mutex mutex_;  // The thread to synchronize map and repeated field
+  mutable internal::WrappedMutex mutex_;  // The thread to synchronize map and repeated field
                          // needs to get lock first;
   mutable std::atomic<State> state_;
 
@@ -149,13 +157,13 @@
   friend class ContendedMapCleanTest;
   friend class GeneratedMessageReflection;
   friend class MapFieldAccessor;
-  friend class ::google::protobuf::DynamicMessage;
+  friend class DynamicMessage;
 
   // Virtual helper methods for MapIterator. MapIterator doesn't have the
   // type helper for key and value. Call these help methods to deal with
   // different types. Real helper methods are implemented in
   // TypeDefinedMapFieldBase.
-  friend class ::google::protobuf::MapIterator;
+  friend class ::GOOGLE_PROTOBUF_NAMESPACE_ID::MapIterator;
   // Allocate map<...>::iterator for MapIterator.
   virtual void InitializeIterator(MapIterator* map_iter) const = 0;
 
@@ -228,7 +236,7 @@
       MapFieldLiteType;
 
   // Enum needs to be handled differently from other types because it has
-  // different exposed type in google::protobuf::Map's api and repeated field's api. For
+  // different exposed type in Map's api and repeated field's api. For
   // details see the comment in the implementation of
   // SyncMapWithRepeatedFieldNoLock.
   static const bool kIsValueEnum = ValueTypeHandler::kIsEnum;
@@ -263,7 +271,7 @@
   int size() const override;
   void Clear();
   void MergeFrom(const MapField& other);
-  void Swap(MapField* other);
+  void Swap(MapFieldBase* other) override;
 
   // Used in the implementation of parsing. Caller should take the ownership iff
   // arena_ is NULL.
@@ -285,7 +293,6 @@
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
 
-
   // Implements MapFieldBase
   void SyncRepeatedFieldWithMapNoLock() const override;
   void SyncMapWithRepeatedFieldNoLock() const override;
@@ -293,7 +300,7 @@
 
   void SetMapIteratorValue(MapIterator* map_iter) const override;
 
-  friend class ::google::protobuf::Arena;
+  friend class ::GOOGLE_PROTOBUF_NAMESPACE_ID::Arena;
   friend class MapFieldStateTest;  // For testing, it needs raw access to impl_
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapField);
 };
@@ -318,6 +325,7 @@
   bool ContainsMapKey(const MapKey& map_key) const override;
   bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
   bool DeleteMapValue(const MapKey& map_key) override;
+  void Swap(MapFieldBase* other) override;
 
   const Map<MapKey, MapValueRef>& GetMap() const override;
   Map<MapKey, MapValueRef>* MutableMap() override;
@@ -526,7 +534,7 @@
  private:
   template <typename K, typename V>
   friend class internal::TypeDefinedMapFieldBase;
-  friend class MapIterator;
+  friend class ::GOOGLE_PROTOBUF_NAMESPACE_ID::MapIterator;
   friend class internal::DynamicMapField;
 
   union KeyValue {
@@ -672,7 +680,7 @@
   friend class internal::MapField;
   template <typename K, typename V>
   friend class internal::TypeDefinedMapFieldBase;
-  friend class MapIterator;
+  friend class ::GOOGLE_PROTOBUF_NAMESPACE_ID::MapIterator;
   friend class internal::GeneratedMessageReflection;
   friend class internal::DynamicMapField;
 
@@ -698,11 +706,11 @@
   // Only used in DynamicMapField
   void DeleteData() {
     switch (type_) {
-#define HANDLE_TYPE(CPPTYPE, TYPE)                              \
-      case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: {        \
-        delete reinterpret_cast<TYPE*>(data_);                  \
-        break;                                                  \
-      }
+#define HANDLE_TYPE(CPPTYPE, TYPE)           \
+  case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
+    delete reinterpret_cast<TYPE*>(data_);   \
+    break;                                   \
+  }
       HANDLE_TYPE(INT32, int32);
       HANDLE_TYPE(INT64, int64);
       HANDLE_TYPE(UINT32, uint32);
@@ -721,7 +729,6 @@
   void* data_;
   // type_ is 0 or a valid FieldDescriptor::CppType.
   int type_;
-  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapValueRef);
 };
 
 #undef TYPE_CHECK
@@ -802,39 +809,41 @@
 }  // namespace google
 
 GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START
-template<>
-struct hash<google::protobuf::MapKey> {
-  size_t
-  operator()(const google::protobuf::MapKey& map_key) const {
+template <>
+struct hash<::GOOGLE_PROTOBUF_NAMESPACE_ID::MapKey> {
+  size_t operator()(
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::MapKey& map_key) const {
     switch (map_key.type()) {
-      case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
-      case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
-      case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
-      case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
+      case ::GOOGLE_PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_DOUBLE:
+      case ::GOOGLE_PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_FLOAT:
+      case ::GOOGLE_PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_ENUM:
+      case ::GOOGLE_PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_MESSAGE:
         GOOGLE_LOG(FATAL) << "Unsupported";
         break;
-      case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
+      case ::GOOGLE_PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_STRING:
         return hash<string>()(map_key.GetStringValue());
-      case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
+      case ::GOOGLE_PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT64:
         return hash<::google::protobuf::int64>()(map_key.GetInt64Value());
-      case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
+      case ::GOOGLE_PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT32:
         return hash<::google::protobuf::int32>()(map_key.GetInt32Value());
-      case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
+      case ::GOOGLE_PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT64:
         return hash<::google::protobuf::uint64>()(map_key.GetUInt64Value());
-      case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
+      case ::GOOGLE_PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT32:
         return hash<::google::protobuf::uint32>()(map_key.GetUInt32Value());
-      case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
+      case ::GOOGLE_PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_BOOL:
         return hash<bool>()(map_key.GetBoolValue());
     }
     GOOGLE_LOG(FATAL) << "Can't get here.";
     return 0;
   }
-  bool
-  operator()(const google::protobuf::MapKey& map_key1,
-             const google::protobuf::MapKey& map_key2) const {
+  bool operator()(
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::MapKey& map_key1,
+      const ::GOOGLE_PROTOBUF_NAMESPACE_ID::MapKey& map_key2) const {
     return map_key1 < map_key2;
   }
 };
 GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END
 
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_MAP_FIELD_H__
diff --git a/src/google/protobuf/map_field_inl.h b/src/google/protobuf/map_field_inl.h
index d051779..169b3e2 100644
--- a/src/google/protobuf/map_field_inl.h
+++ b/src/google/protobuf/map_field_inl.h
@@ -38,6 +38,10 @@
 #include <google/protobuf/map_field.h>
 #include <google/protobuf/map_type_handler.h>
 
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 namespace internal {
@@ -249,13 +253,14 @@
           WireFormatLite::FieldType kKeyFieldType,
           WireFormatLite::FieldType kValueFieldType, int default_enum_value>
 void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType,
-              default_enum_value>::Swap(MapField* other) {
-  std::swap(this->MapFieldBase::repeated_field_, other->repeated_field_);
-  impl_.Swap(&other->impl_);
+              default_enum_value>::Swap(MapFieldBase* other) {
+  MapField* other_field = down_cast<MapField*>(other);
+  std::swap(this->MapFieldBase::repeated_field_, other_field->repeated_field_);
+  impl_.Swap(&other_field->impl_);
   // a relaxed swap of the atomic
-  auto other_state = other->state_.load(std::memory_order_relaxed);
+  auto other_state = other_field->state_.load(std::memory_order_relaxed);
   auto this_state = this->MapFieldBase::state_.load(std::memory_order_relaxed);
-  other->state_.store(this_state, std::memory_order_relaxed);
+  other_field->state_.store(this_state, std::memory_order_relaxed);
   this->MapFieldBase::state_.store(other_state, std::memory_order_relaxed);
 }
 
@@ -338,6 +343,6 @@
 }
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_MAP_FIELD_INL_H__
diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h
index f648b43..36b5b80 100644
--- a/src/google/protobuf/map_field_lite.h
+++ b/src/google/protobuf/map_field_lite.h
@@ -33,8 +33,15 @@
 
 #include <google/protobuf/map.h>
 #include <google/protobuf/map_entry_lite.h>
+#include <google/protobuf/port.h>
 #include <google/protobuf/wire_format_lite.h>
 
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 namespace internal {
@@ -105,7 +112,7 @@
   Arena* arena_;
   Map<Key, T> map_;
 
-  friend class ::google::protobuf::Arena;
+  friend class ::GOOGLE_PROTOBUF_NAMESPACE_ID::Arena;
 };
 
 // True if IsInitialized() is true for value field in all elements of t. T is
@@ -138,6 +145,8 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc
index f58d59e..dcfcca7 100644
--- a/src/google/protobuf/map_field_test.cc
+++ b/src/google/protobuf/map_field_test.cc
@@ -30,22 +30,23 @@
 
 #include <map>
 #include <memory>
+#include <unordered_map>
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
+#include <google/protobuf/arena_test_util.h>
+#include <google/protobuf/map_test_util.h>
+#include <google/protobuf/map_unittest.pb.h>
+#include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/map.h>
-#include <google/protobuf/arena_test_util.h>
-#include <google/protobuf/map_unittest.pb.h>
-#include <google/protobuf/map_test_util.h>
-#include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/map_field_inl.h>
 #include <google/protobuf/message.h>
 #include <google/protobuf/repeated_field.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 #include <gtest/gtest.h>
-namespace google {
 
+namespace google {
 namespace protobuf {
 
 namespace internal {
@@ -95,6 +96,7 @@
   int size() const { return 0; }
   void MapBegin(MapIterator* map_iter) const {}
   void MapEnd(MapIterator* map_iter) const {}
+  void Swap(MapFieldBase* other) {}
   void InitializeIterator(MapIterator* map_iter) const {}
   void DeleteIterator(MapIterator* map_iter) const {}
   void CopyIterator(MapIterator* this_iterator,
diff --git a/src/google/protobuf/map_lite_test_util.h b/src/google/protobuf/map_lite_test_util.h
index 66dedde..573de7b 100644
--- a/src/google/protobuf/map_lite_test_util.h
+++ b/src/google/protobuf/map_lite_test_util.h
@@ -75,6 +75,6 @@
 };
 
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_MAP_LITE_TEST_UTIL_H__
diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc
index 51fde2c..beaacc4 100644
--- a/src/google/protobuf/map_test.cc
+++ b/src/google/protobuf/map_test.cc
@@ -37,14 +37,13 @@
 #endif  // _WIN32
 
 #include <algorithm>
-#include <google/protobuf/stubs/hash.h>
 #include <map>
 #include <memory>
 #include <set>
 #include <sstream>
+#include <unordered_map>
 #include <vector>
 
-#include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/stringprintf.h>
@@ -54,6 +53,7 @@
 #include <google/protobuf/map_test_util.h>
 #include <google/protobuf/map_unittest.pb.h>
 #include <google/protobuf/test_util.h>
+#include <google/protobuf/test_util2.h>
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/tokenizer.h>
@@ -76,19 +76,21 @@
 #include <gmock/gmock.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
+#include <google/protobuf/stubs/casts.h>
+
 
 namespace google {
-
-using google::protobuf::unittest::ForeignMessage;
-using google::protobuf::unittest::TestAllTypes;
-using google::protobuf::unittest::TestMap;
-using google::protobuf::unittest::TestRecursiveMapMessage;
-
 namespace protobuf {
+
+using unittest::ForeignMessage;
+using unittest::TestAllTypes;
+using unittest::TestMap;
+using unittest::TestRecursiveMapMessage;
+
 namespace internal {
 
 void MapTestForceDeterministic() {
-  ::google::protobuf::io::CodedOutputStream::SetDefaultSerializationDeterministic();
+  io::CodedOutputStream::SetDefaultSerializationDeterministic();
 }
 
 // Map API Test =====================================================
@@ -309,8 +311,8 @@
 }
 
 static int64 Now() {
-  return google::protobuf::util::TimeUtil::TimestampToNanoseconds(
-      google::protobuf::util::TimeUtil::GetCurrentTime());
+  return util::TimeUtil::TimestampToNanoseconds(
+      util::TimeUtil::GetCurrentTime());
 }
 
 // Arbitrary odd integers for creating test data.
@@ -505,8 +507,8 @@
   ASSERT_EQ(n, m.size());
   // Create maps of pointers and iterators.
   // These should remain valid even if we modify m.
-  hash_map<int, Map<int, int>::value_type*> mp(n);
-  hash_map<int, Map<int, int>::iterator> mi(n);
+  std::unordered_map<int, Map<int, int>::value_type*> mp(n);
+  std::unordered_map<int, Map<int, int>::iterator> mi(n);
   for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it) {
     mp[it->first] = &*it;
     mi[it->first] = it;
@@ -868,7 +870,7 @@
   EXPECT_TRUE(other.find(key_other) == other.end());
 
   // Self assign
-  other = other;
+  other = *&other;  // Avoid -Wself-assign.
   EXPECT_EQ(2, other.size());
   EXPECT_EQ(value1, other.at(key1));
   EXPECT_EQ(value2, other.at(key2));
@@ -895,8 +897,8 @@
   int key = 100, key_missing = 101;
   map_[key] = 100;
 
-  std::pair<google::protobuf::Map<int32, int32>::iterator,
-            google::protobuf::Map<int32, int32>::iterator> range = map_.equal_range(key);
+  std::pair<Map<int32, int32>::iterator, Map<int32, int32>::iterator> range =
+      map_.equal_range(key);
   EXPECT_TRUE(map_.find(key) == range.first);
   EXPECT_TRUE(++map_.find(key) == range.second);
 
@@ -904,9 +906,9 @@
   EXPECT_TRUE(map_.end() == range.first);
   EXPECT_TRUE(map_.end() == range.second);
 
-  std::pair<google::protobuf::Map<int32, int32>::const_iterator,
-            google::protobuf::Map<int32, int32>::const_iterator> const_range =
-      const_map_.equal_range(key);
+  std::pair<Map<int32, int32>::const_iterator,
+            Map<int32, int32>::const_iterator>
+      const_range = const_map_.equal_range(key);
   EXPECT_TRUE(const_map_.find(key) == const_range.first);
   EXPECT_TRUE(++const_map_.find(key) == const_range.second);
 
@@ -1436,7 +1438,7 @@
   // Test iterators.
   {
     int index = 0;
-    hash_map<int32, int32> result;
+    std::unordered_map<int32, int32> result;
     for (RepeatedFieldRef<Message>::iterator it = mf_int32_int32.begin();
          it != mf_int32_int32.end(); ++it) {
       const Message& message = *it;
@@ -1448,7 +1450,7 @@
       ++index;
     }
     EXPECT_EQ(10, index);
-    for (hash_map<int32, int32>::const_iterator it = result.begin();
+    for (std::unordered_map<int32, int32>::const_iterator it = result.begin();
          it != result.end(); ++it) {
       EXPECT_EQ(message.map_int32_int32().at(it->first), it->second);
     }
@@ -1456,7 +1458,7 @@
 
   {
     int index = 0;
-    hash_map<int32, double> result;
+    std::unordered_map<int32, double> result;
     for (RepeatedFieldRef<Message>::iterator it = mf_int32_double.begin();
          it != mf_int32_double.end(); ++it) {
       const Message& message = *it;
@@ -1468,7 +1470,7 @@
       ++index;
     }
     EXPECT_EQ(10, index);
-    for (hash_map<int32, double>::const_iterator it = result.begin();
+    for (std::unordered_map<int32, double>::const_iterator it = result.begin();
          it != result.end(); ++it) {
       EXPECT_EQ(message.map_int32_double().at(it->first), it->second);
     }
@@ -1476,7 +1478,7 @@
 
   {
     int index = 0;
-    hash_map<string, string> result;
+    std::unordered_map<string, string> result;
     for (RepeatedFieldRef<Message>::iterator it = mf_string_string.begin();
          it != mf_string_string.end(); ++it) {
       const Message& message = *it;
@@ -1488,7 +1490,7 @@
       ++index;
     }
     EXPECT_EQ(10, index);
-    for (hash_map<string, string>::const_iterator it = result.begin();
+    for (std::unordered_map<string, string>::const_iterator it = result.begin();
          it != result.end(); ++it) {
       EXPECT_EQ(message.map_string_string().at(it->first), it->second);
     }
@@ -1975,8 +1977,7 @@
   MapTestUtil::ExpectMapFieldsSet(message2);
 }
 
-#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || \
-        !defined(GOOGLE_PROTOBUF_NO_RTTI)
+#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || GOOGLE_PROTOBUF_RTTI
 TEST(GeneratedMapFieldTest, UpcastCopyFrom) {
   // Test the CopyFrom method that takes in the generic const Message&
   // parameter.
@@ -1984,7 +1985,7 @@
 
   MapTestUtil::SetMapFields(&message1);
 
-  const Message* source = implicit_cast<const Message*>(&message1);
+  const Message* source = ::google::protobuf::implicit_cast<const Message*>(&message1);
   message2.CopyFrom(*source);
 
   MapTestUtil::ExpectMapFieldsSet(message2);
@@ -2116,7 +2117,7 @@
   MapTestUtil::SetMapFields(&message1);
   int size = message1.ByteSize();
   data.resize(size);
-  uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+  uint8* start = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
   uint8* end = message1.SerializeWithCachedSizesToArray(start);
   EXPECT_EQ(size, end - start);
   EXPECT_TRUE(message2.ParseFromString(data));
@@ -2132,7 +2133,7 @@
   data.resize(size);
   {
     // Allow the output stream to buffer only one byte at a time.
-    io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+    io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
     io::CodedOutputStream output_stream(&array_stream);
     message1.SerializeWithCachedSizes(&output_stream);
     EXPECT_FALSE(output_stream.HadError());
@@ -2330,7 +2331,7 @@
       "  key: 1234567890\n"
       "}";
 
-  EXPECT_TRUE(google::protobuf::TextFormat::ParseFromString(text, &message));
+  EXPECT_TRUE(TextFormat::ParseFromString(text, &message));
   EXPECT_EQ(1, message.map_int32_foreign_message().size());
   EXPECT_EQ(11, message.ByteSize());
 }
@@ -3041,7 +3042,7 @@
     const T& t) {
   const int size = t.ByteSize();
   string result(size, '\0');
-  io::ArrayOutputStream array_stream(string_as_array(&result), size);
+  io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size);
   io::CodedOutputStream output_stream(&array_stream);
   output_stream.SetSerializationDeterministic(true);
   t.SerializePartialToCodedStream(&output_stream);
@@ -3054,7 +3055,7 @@
 static string DeterministicSerializationWithSerializeToCodedStream(const T& t) {
   const int size = t.ByteSize();
   string result(size, '\0');
-  io::ArrayOutputStream array_stream(string_as_array(&result), size);
+  io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size);
   io::CodedOutputStream output_stream(&array_stream);
   output_stream.SetSerializationDeterministic(true);
   t.SerializeToCodedStream(&output_stream);
@@ -3067,7 +3068,7 @@
 static string DeterministicSerialization(const T& t) {
   const int size = t.ByteSize();
   string result(size, '\0');
-  io::ArrayOutputStream array_stream(string_as_array(&result), size);
+  io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size);
   io::CodedOutputStream output_stream(&array_stream);
   output_stream.SetSerializationDeterministic(true);
   t.SerializeWithCachedSizes(&output_stream);
@@ -3084,13 +3085,13 @@
                                            const string& filename) {
   string expected;
   GOOGLE_CHECK_OK(File::GetContents(
-      TestSourceDir() + "/google/protobuf/testdata/" + filename,
+      TestUtil::GetTestDataPath("net/proto2/internal/testdata/" + filename),
       &expected, true));
   const string actual = DeterministicSerialization(t);
   EXPECT_EQ(expected, actual);
   protobuf_unittest::TestMaps u;
   EXPECT_TRUE(u.ParseFromString(actual));
-  EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(u, t));
+  EXPECT_TRUE(util::MessageDifferencer::Equals(u, t));
 }
 
 // Helper for MapSerializationTest.  Return a 7-bit ASCII string.
@@ -3146,7 +3147,7 @@
   const string filename = "golden_message_maps";
   string golden;
   GOOGLE_CHECK_OK(File::GetContents(
-      TestSourceDir() + "/google/protobuf/testdata/" + filename,
+      TestUtil::GetTestDataPath("net/proto2/internal/testdata/" + filename),
       &golden, true));
   t.ParseFromString(golden);
   *(p.mutable_m()) = t;
@@ -3183,12 +3184,12 @@
   tester.SetMapFieldsViaReflection(&message);
 
   string expected_text;
-  GOOGLE_CHECK_OK(File::GetContentsAsText(
-      TestSourceDir() +
-          "/google/protobuf/"
-          "testdata/map_test_data.txt",
-      &expected_text, true));
+  GOOGLE_CHECK_OK(
+      File::GetContents(TestUtil::GetTestDataPath("net/proto2/internal/"
+                                                  "testdata/map_test_data.txt"),
+                        &expected_text, true));
 
+  CleanStringLineEndings(&expected_text, false);
   EXPECT_EQ(message.DebugString(), expected_text);
 
   // Test again on the reverse order.
@@ -3200,10 +3201,10 @@
 
 TEST(TextFormatMapTest, ParseCorruptedString) {
   string serialized_message;
-  GOOGLE_CHECK_OK(File::GetContents(
-      TestSourceDir() +
-          "/google/protobuf/testdata/golden_message_maps",
-      &serialized_message, true));
+  GOOGLE_CHECK_OK(
+      File::GetContents(TestUtil::GetTestDataPath(
+                            "net/proto2/internal/testdata/golden_message_maps"),
+                        &serialized_message, true));
   protobuf_unittest::TestMaps message;
   GOOGLE_CHECK(message.ParseFromString(serialized_message));
   TestParseCorruptedString<protobuf_unittest::TestMaps, true>(message);
diff --git a/src/google/protobuf/map_test_util.h b/src/google/protobuf/map_test_util.h
index dd39761..53d1575 100644
--- a/src/google/protobuf/map_test_util.h
+++ b/src/google/protobuf/map_test_util.h
@@ -161,6 +161,6 @@
 };
 
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_MAP_TEST_UTIL_H__
diff --git a/src/google/protobuf/map_test_util_impl.h b/src/google/protobuf/map_test_util_impl.h
index ad4d1a3..2e8b4ba 100644
--- a/src/google/protobuf/map_test_util_impl.h
+++ b/src/google/protobuf/map_test_util_impl.h
@@ -36,9 +36,9 @@
 #include <gtest/gtest.h>
 
 
-namespace google {
 namespace protobuf_unittest {}  // forward declaration
 
+namespace google {
 namespace protobuf {
 
 namespace unittest = ::protobuf_unittest;
@@ -480,6 +480,6 @@
 }
 
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_MAP_TEST_UTIL_IMPL_H__
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h
index 7f7b1e0..0489851 100644
--- a/src/google/protobuf/map_type_handler.h
+++ b/src/google/protobuf/map_type_handler.h
@@ -34,6 +34,10 @@
 #include <google/protobuf/arena.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 namespace internal {
@@ -548,92 +552,89 @@
 
 // Definition for string/bytes handler
 
-#define STRING_OR_BYTES_HANDLER_FUNCTIONS(FieldType)                           \
-  template <typename Type>                                                     \
-  inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,       \
-                                       Type>::MapEntryAccessorType&            \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType,                             \
-                 Type>::GetExternalReference(const TypeOnMemory& value) {      \
-    return value.Get();                                                        \
-  }                                                                            \
-  template <typename Type>                                                     \
-  inline size_t                                                                \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType,                             \
-                 Type>::SpaceUsedInMapEntryLong(const TypeOnMemory& value) {   \
-    return sizeof(value);                                                      \
-  }                                                                            \
-  template <typename Type>                                                     \
-  inline size_t                                                                \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapLong(  \
-      const TypeOnMemory& value) {                                             \
-    return sizeof(value);                                                      \
-  }                                                                            \
-  template <typename Type>                                                     \
-  inline size_t                                                                \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapLong(  \
-      const string& value) {                                                   \
-    return sizeof(value);                                                      \
-  }                                                                            \
-  template <typename Type>                                                     \
-  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear(   \
-      TypeOnMemory* value, Arena* arena) {                                     \
-    value->ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),    \
-                        arena);                                                \
-  }                                                                            \
-  template <typename Type>                                                     \
-  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::         \
-      ClearMaybeByDefaultEnum(TypeOnMemory* value, Arena* arena,               \
-                              int /* default_enum */) {                        \
-    Clear(value, arena);                                                       \
-  }                                                                            \
-  template <typename Type>                                                     \
-  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge(   \
-      const MapEntryAccessorType& from, TypeOnMemory* to, Arena* arena) {      \
-    to->Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from, arena);  \
-  }                                                                            \
-  template <typename Type>                                                     \
-  void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::DeleteNoArena(  \
-      TypeOnMemory& value) {                                                   \
-    value.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());  \
-  }                                                                            \
-  template <typename Type>                                                     \
-  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType,                 \
-                             Type>::AssignDefaultValue(TypeOnMemory* /* value */) {} \
-  template <typename Type>                                                     \
-  inline void                                                                  \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize(          \
-      TypeOnMemory* value, Arena* /* arena */) {                               \
-    value->UnsafeSetDefault(                                                   \
-        &::google::protobuf::internal::GetEmptyStringAlreadyInited());                   \
-  }                                                                            \
-  template <typename Type>                                                     \
-  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::         \
-      InitializeMaybeByDefaultEnum(TypeOnMemory* value,                        \
-                                   int /* default_enum_value */,               \
-                                   Arena* arena) {                             \
-    Initialize(value, arena);                                                  \
-  }                                                                            \
-  template <typename Type>                                                     \
-  inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,             \
-                                 Type>::MapEntryAccessorType*                  \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable(       \
-      TypeOnMemory* value, Arena* arena) {                                     \
-    return value->Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),  \
-                          arena);                                              \
-  }                                                                            \
-  template <typename Type>                                                     \
-  inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,       \
-                                       Type>::MapEntryAccessorType&            \
-  MapTypeHandler<WireFormatLite::TYPE_##FieldType,                             \
-                 Type>::DefaultIfNotInitialized(const TypeOnMemory& value,     \
-                                                const TypeOnMemory&            \
-                                                    /* default_value */) {     \
-    return value.Get();                                                        \
-  }                                                                            \
-  template <typename Type>                                                     \
-  inline bool MapTypeHandler<WireFormatLite::TYPE_##FieldType,                 \
-                             Type>::IsInitialized(const TypeOnMemory& /* value */) { \
-    return true;                                                               \
+#define STRING_OR_BYTES_HANDLER_FUNCTIONS(FieldType)                          \
+  template <typename Type>                                                    \
+  inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,      \
+                                       Type>::MapEntryAccessorType&           \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType,                            \
+                 Type>::GetExternalReference(const TypeOnMemory& value) {     \
+    return value.Get();                                                       \
+  }                                                                           \
+  template <typename Type>                                                    \
+  inline size_t                                                               \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType,                            \
+                 Type>::SpaceUsedInMapEntryLong(const TypeOnMemory& value) {  \
+    return sizeof(value);                                                     \
+  }                                                                           \
+  template <typename Type>                                                    \
+  inline size_t                                                               \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapLong( \
+      const TypeOnMemory& value) {                                            \
+    return sizeof(value);                                                     \
+  }                                                                           \
+  template <typename Type>                                                    \
+  inline size_t                                                               \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapLong( \
+      const string& value) {                                                  \
+    return sizeof(value);                                                     \
+  }                                                                           \
+  template <typename Type>                                                    \
+  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear(  \
+      TypeOnMemory* value, Arena* arena) {                                    \
+    value->ClearToEmpty(&internal::GetEmptyStringAlreadyInited(), arena);     \
+  }                                                                           \
+  template <typename Type>                                                    \
+  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::        \
+      ClearMaybeByDefaultEnum(TypeOnMemory* value, Arena* arena,              \
+                              int /* default_enum */) {                       \
+    Clear(value, arena);                                                      \
+  }                                                                           \
+  template <typename Type>                                                    \
+  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge(  \
+      const MapEntryAccessorType& from, TypeOnMemory* to, Arena* arena) {     \
+    to->Set(&internal::GetEmptyStringAlreadyInited(), from, arena);           \
+  }                                                                           \
+  template <typename Type>                                                    \
+  void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::DeleteNoArena( \
+      TypeOnMemory& value) {                                                  \
+    value.DestroyNoArena(&internal::GetEmptyStringAlreadyInited());           \
+  }                                                                           \
+  template <typename Type>                                                    \
+  inline void                                                                 \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::AssignDefaultValue( \
+      TypeOnMemory* /* value */) {}                                           \
+  template <typename Type>                                                    \
+  inline void                                                                 \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize(         \
+      TypeOnMemory* value, Arena* /* arena */) {                              \
+    value->UnsafeSetDefault(&internal::GetEmptyStringAlreadyInited());        \
+  }                                                                           \
+  template <typename Type>                                                    \
+  inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::        \
+      InitializeMaybeByDefaultEnum(                                           \
+          TypeOnMemory* value, int /* default_enum_value */, Arena* arena) {  \
+    Initialize(value, arena);                                                 \
+  }                                                                           \
+  template <typename Type>                                                    \
+  inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,            \
+                                 Type>::MapEntryAccessorType*                 \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable(      \
+      TypeOnMemory* value, Arena* arena) {                                    \
+    return value->Mutable(&internal::GetEmptyStringAlreadyInited(), arena);   \
+  }                                                                           \
+  template <typename Type>                                                    \
+  inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType,      \
+                                       Type>::MapEntryAccessorType&           \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::                    \
+      DefaultIfNotInitialized(const TypeOnMemory& value,                      \
+                              const TypeOnMemory& /* default_value */) {      \
+    return value.Get();                                                       \
+  }                                                                           \
+  template <typename Type>                                                    \
+  inline bool                                                                 \
+  MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::IsInitialized(      \
+      const TypeOnMemory& /* value */) {                                      \
+    return true;                                                              \
   }
 STRING_OR_BYTES_HANDLER_FUNCTIONS(STRING)
 STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES)
@@ -734,6 +735,6 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_TYPE_HANDLER_H__
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index a536615..b5a624b 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -34,15 +34,13 @@
 
 #include <iostream>
 #include <stack>
-#include <google/protobuf/stubs/hash.h>
+#include <unordered_map>
 
 #include <google/protobuf/message.h>
 
 #include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/mutex.h>
-#include <google/protobuf/stubs/once.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/reflection_internal.h>
 #include <google/protobuf/io/coded_stream.h>
@@ -50,19 +48,26 @@
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/map_field.h>
+#include <google/protobuf/map_field_inl.h>
 #include <google/protobuf/reflection_ops.h>
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/strutil.h>
 
 #include <google/protobuf/stubs/map_util.h>
-#include <google/protobuf/stubs/singleton.h>
 #include <google/protobuf/stubs/stl_util.h>
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/port_def.inc>
 
 namespace google {
 namespace protobuf {
 
-using internal::WireFormat;
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+using internal::ParseClosure;
+#endif
 using internal::ReflectionOps;
+using internal::WireFormat;
+using internal::WireFormatLite;
 
 void Message::MergeFrom(const Message& from) {
   const Descriptor* descriptor = GetDescriptor();
@@ -118,9 +123,11 @@
   return ReflectionOps::DiscardUnknownFields(this);
 }
 
+#if !GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) {
   return WireFormat::ParseAndMergePartial(input, this);
 }
+#endif
 
 bool Message::ParseFromFileDescriptor(int file_descriptor) {
   io::FileInputStream input(file_descriptor);
@@ -142,6 +149,449 @@
   return ParsePartialFromZeroCopyStream(&zero_copy_input) && input->eof();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+namespace internal {
+
+class ReflectionAccessor {
+ public:
+  static void* GetOffset(void* msg, const google::protobuf::FieldDescriptor* f,
+                         const google::protobuf::Reflection* r) {
+    auto gr =
+        dynamic_cast<const google::protobuf::internal::GeneratedMessageReflection*>(r);
+    GOOGLE_CHECK(gr != nullptr);
+    return static_cast<char*>(msg) + gr->schema_.GetFieldOffset(f);
+  }
+
+  static google::protobuf::internal::ExtensionSet* GetExtensionSet(
+      void* msg, const google::protobuf::Reflection* r) {
+    auto gr =
+        dynamic_cast<const google::protobuf::internal::GeneratedMessageReflection*>(r);
+    GOOGLE_CHECK(gr != nullptr);
+    return reinterpret_cast<google::protobuf::internal::ExtensionSet*>(
+        static_cast<char*>(msg) + gr->schema_.GetExtensionSetOffset());
+  }
+  static google::protobuf::internal::InternalMetadataWithArena* GetMetadata(
+      void* msg, const google::protobuf::Reflection* r) {
+    auto gr =
+        dynamic_cast<const google::protobuf::internal::GeneratedMessageReflection*>(r);
+    GOOGLE_CHECK(gr != nullptr);
+    return reinterpret_cast<google::protobuf::internal::InternalMetadataWithArena*>(
+        static_cast<char*>(msg) + gr->schema_.GetMetadataOffset());
+  }
+};
+
+}  // namespace internal
+
+void SetField(uint64 val, const FieldDescriptor* field, Message* msg,
+              const Reflection* reflection) {
+#define STORE_TYPE(CPPTYPE_METHOD)                        \
+  do                                                      \
+    if (field->is_repeated()) {                           \
+      reflection->Add##CPPTYPE_METHOD(msg, field, value); \
+    } else {                                              \
+      reflection->Set##CPPTYPE_METHOD(msg, field, value); \
+    }                                                     \
+  while (0)
+
+  switch (field->type()) {
+#define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \
+  case FieldDescriptor::TYPE_##TYPE: {             \
+    CPPTYPE value = val;                           \
+    STORE_TYPE(CPPTYPE_METHOD);                    \
+    break;                                         \
+  }
+
+    // Varints
+    HANDLE_TYPE(INT32, int32, Int32)
+    HANDLE_TYPE(INT64, int64, Int64)
+    HANDLE_TYPE(UINT32, uint32, UInt32)
+    HANDLE_TYPE(UINT64, uint64, UInt64)
+    case FieldDescriptor::TYPE_SINT32: {
+      int32 value = WireFormatLite::ZigZagDecode32(val);
+      STORE_TYPE(Int32);
+      break;
+    }
+    case FieldDescriptor::TYPE_SINT64: {
+      int64 value = WireFormatLite::ZigZagDecode64(val);
+      STORE_TYPE(Int64);
+      break;
+    }
+      HANDLE_TYPE(BOOL, bool, Bool)
+
+      // Fixed
+      HANDLE_TYPE(FIXED32, uint32, UInt32)
+      HANDLE_TYPE(FIXED64, uint64, UInt64)
+      HANDLE_TYPE(SFIXED32, int32, Int32)
+      HANDLE_TYPE(SFIXED64, int64, Int64)
+
+    case FieldDescriptor::TYPE_FLOAT: {
+      float value;
+      uint32 bit_rep = val;
+      std::memcpy(&value, &bit_rep, sizeof(value));
+      STORE_TYPE(Float);
+      break;
+    }
+    case FieldDescriptor::TYPE_DOUBLE: {
+      double value;
+      uint64 bit_rep = val;
+      std::memcpy(&value, &bit_rep, sizeof(value));
+      STORE_TYPE(Double);
+      break;
+    }
+    case FieldDescriptor::TYPE_ENUM: {
+      int value = val;
+      if (field->is_repeated()) {
+        reflection->AddEnumValue(msg, field, value);
+      } else {
+        reflection->SetEnumValue(msg, field, value);
+      }
+      break;
+    }
+    default:
+      GOOGLE_LOG(FATAL) << "Error in descriptors, primitve field with field type "
+                 << field->type();
+  }
+#undef STORE_TYPE
+#undef HANDLE_TYPE
+}
+
+bool ReflectiveValidator(const void* arg, int val) {
+  auto d = static_cast<const EnumDescriptor*>(arg);
+  return d->FindValueByNumber(val) != nullptr;
+}
+
+ParseClosure GetPackedField(const FieldDescriptor* field, Message* msg,
+                            const Reflection* reflection,
+                            internal::ParseContext* ctx) {
+  switch (field->type()) {
+#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, METHOD_NAME) \
+  case FieldDescriptor::TYPE_##TYPE:                   \
+    return {internal::Packed##METHOD_NAME##Parser,     \
+            reflection->MutableRepeatedField<CPPTYPE>(msg, field)}
+    HANDLE_PACKED_TYPE(INT32, int32, Int32);
+    HANDLE_PACKED_TYPE(INT64, int64, Int64);
+    HANDLE_PACKED_TYPE(SINT32, int32, SInt32);
+    HANDLE_PACKED_TYPE(SINT64, int64, SInt64);
+    HANDLE_PACKED_TYPE(UINT32, uint32, UInt32);
+    HANDLE_PACKED_TYPE(UINT64, uint64, UInt64);
+    HANDLE_PACKED_TYPE(BOOL, bool, Bool);
+    case FieldDescriptor::TYPE_ENUM: {
+      if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
+        auto object =
+            internal::ReflectionAccessor::GetOffset(msg, field, reflection);
+        return {internal::PackedEnumParser, object};
+      } else {
+        ctx->extra_parse_data().SetEnumValidatorArg(
+            ReflectiveValidator, field->enum_type(),
+            reflection->MutableUnknownFields(msg), field->number());
+        auto object =
+            internal::ReflectionAccessor::GetOffset(msg, field, reflection);
+        return {internal::PackedValidEnumParserArg, object};
+      }
+    }
+      HANDLE_PACKED_TYPE(FIXED32, uint32, Fixed32);
+      HANDLE_PACKED_TYPE(FIXED64, uint64, Fixed64);
+      HANDLE_PACKED_TYPE(SFIXED32, int32, SFixed32);
+      HANDLE_PACKED_TYPE(SFIXED64, int64, SFixed64);
+      HANDLE_PACKED_TYPE(FLOAT, float, Float);
+      HANDLE_PACKED_TYPE(DOUBLE, double, Double);
+#undef HANDLE_PACKED_TYPE
+
+    default:
+      GOOGLE_LOG(FATAL) << "Type is not packable " << field->type();
+  }
+}
+
+ParseClosure GetLenDelim(int field_number, const FieldDescriptor* field,
+                         Message* msg, UnknownFieldSet* unknown,
+                         const Reflection* reflection,
+                         internal::ParseContext* ctx) {
+  if (field == nullptr || WireFormat::WireTypeForFieldType(field->type()) !=
+                              WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+    if (field && field->is_packable()) {
+      return GetPackedField(field, msg, reflection, ctx);
+    }
+    return {internal::StringParser, unknown->AddLengthDelimited(field_number)};
+  }
+  enum { kNone = 0, kVerify, kStrict } utf8_level = kNone;
+  internal::ParseFunc string_parsers[] = {internal::StringParser,
+                                          internal::StringParserUTF8Verify,
+                                          internal::StringParserUTF8};
+  internal::ParseFunc cord_parsers[] = {internal::CordParser,
+                                        internal::CordParserUTF8Verify,
+                                        internal::CordParserUTF8};
+  internal::ParseFunc string_piece_parsers[] = {
+      internal::StringPieceParser, internal::StringPieceParserUTF8Verify,
+      internal::StringPieceParserUTF8};
+  switch (field->type()) {
+    case FieldDescriptor::TYPE_STRING:
+      if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3
+      ) {
+        ctx->extra_parse_data().SetFieldName(field->full_name().c_str());
+        utf8_level = kStrict;
+      } else if (
+          true) {
+        ctx->extra_parse_data().SetFieldName(field->full_name().c_str());
+        utf8_level = kVerify;
+      }
+      GOOGLE_FALLTHROUGH_INTENDED;
+    case FieldDescriptor::TYPE_BYTES: {
+      if (field->is_repeated()) {
+        int index = reflection->FieldSize(*msg, field);
+        // Add new empty value.
+        reflection->AddString(msg, field, "");
+        if (field->options().ctype() == FieldOptions::STRING ||
+            field->is_extension()) {
+          auto object = reflection->MutableRepeatedPtrField<string>(msg, field)
+                            ->Mutable(index);
+          return {string_parsers[utf8_level], object};
+        } else if (field->options().ctype() == FieldOptions::CORD) {
+          auto object = reflection->MutableRepeatedField<Cord>(msg, field)
+                            ->Mutable(index);
+          return {cord_parsers[utf8_level], object};
+        } else if (field->options().ctype() == FieldOptions::STRING_PIECE) {
+          auto object =
+              reflection
+                  ->MutableRepeatedPtrField<internal::StringPieceField>(msg,
+                                                                        field)
+                  ->Mutable(index);
+          return {string_piece_parsers[utf8_level], object};
+        }
+      } else {
+        // Clear value and make sure it's set.
+        reflection->SetString(msg, field, "");
+        if (field->options().ctype() == FieldOptions::STRING ||
+            field->is_extension()) {
+          // HACK around inability to get mutable_string in reflection
+          string* object = &const_cast<string&>(
+              reflection->GetStringReference(*msg, field, nullptr));
+          return {string_parsers[utf8_level], object};
+        } else {
+          void* object =
+              internal::ReflectionAccessor::GetOffset(msg, field, reflection);
+          if (field->containing_oneof()) {
+            object = *static_cast<Cord**>(object);
+          }
+          if (field->options().ctype() == FieldOptions::CORD) {
+            return {cord_parsers[utf8_level], object};
+          } else if (field->options().ctype() == FieldOptions::STRING_PIECE) {
+            return {string_piece_parsers[utf8_level], object};
+          }
+        }
+      }
+      GOOGLE_LOG(FATAL) << "No other type than string supported";
+    }
+    case FieldDescriptor::TYPE_MESSAGE: {
+      Message* object;
+      if (field->is_repeated()) {
+        object = reflection->AddMessage(msg, field, nullptr);
+      } else {
+        object = reflection->MutableMessage(msg, field, nullptr);
+      }
+      return {object->_ParseFunc(), object};
+    }
+    default:
+      GOOGLE_LOG(FATAL) << "Wrong type for length delim " << field->type();
+  }
+}
+
+const char* ReflectiveParseMessageSetItem(const char* begin, const char* end,
+                                          void* object,
+                                          internal::ParseContext* ctx) {
+  ParseClosure child;
+  auto msg = static_cast<Message*>(object);
+  auto reflection = msg->GetReflection();
+  uint32 size;
+  auto ptr = begin;
+  while (ptr < end) {
+    uint32 tag = *ptr++;
+    if (tag == WireFormatLite::kMessageSetTypeIdTag) {
+      uint32 type_id;
+      ptr = Varint::Parse32(ptr, &type_id);
+      if (!ptr) goto error;
+
+      auto field = reflection->FindKnownExtensionByNumber(type_id);
+
+      if (ctx->extra_parse_data().payload.empty()) {
+        tag = *ptr++;
+        if (tag == WireFormatLite::kMessageSetMessageTag) {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          child = GetLenDelim(type_id * 8 + 2, field, msg,
+                              reflection->MutableUnknownFields(msg), reflection,
+                              ctx);
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange(child, ptr, newend)) goto error;
+          ptr = newend;
+        } else {
+          goto error;
+        }
+      } else {
+        GOOGLE_LOG(FATAL) << "Wrong order";
+      }
+    } else if (tag == WireFormatLite::kMessageSetItemEndTag) {
+      if (!ctx->ValidEndGroup(tag)) goto error;
+      break;
+    } else if (tag == WireFormatLite::kMessageSetMessageTag) {
+      uint32 size;
+      ptr = Varint::Parse32Inline(ptr, &size);
+      if (!ptr) goto error;
+      child = {internal::StringParser, &ctx->extra_parse_data().payload};
+      if (size > end - ptr) goto len_delim_till_end;
+      auto newend = ptr + size;
+      if (!ctx->ParseExactRange(child, ptr, newend)) goto error;
+      ptr = newend;
+    } else {
+      GOOGLE_LOG(FATAL) << "Unknown message set item tag";
+    }
+  }
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {ReflectiveParseMessageSetItem, msg},
+                               child, size);
+}
+
+ParseClosure GetGroup(int field_number, const FieldDescriptor* field,
+                      Message* msg, UnknownFieldSet* unknown,
+                      const Reflection* reflection) {
+  if (field == nullptr && field_number == 1 &&
+      msg->GetDescriptor()->options().message_set_wire_format()) {
+    return {ReflectiveParseMessageSetItem, msg};
+  }
+  if (field == nullptr || WireFormat::WireTypeForFieldType(field->type()) !=
+                              WireFormatLite::WIRETYPE_START_GROUP) {
+    return {internal::UnknownGroupParse, unknown->AddGroup(field_number)};
+  }
+
+  Message* object;
+  if (field->is_repeated()) {
+    object = reflection->AddMessage(msg, field, nullptr);
+  } else {
+    object = reflection->MutableMessage(msg, field, nullptr);
+  }
+  return {object->_ParseFunc(), object};
+}
+
+const char* Message::_InternalParse(const char* begin, const char* end,
+                                    void* object, internal::ParseContext* ctx) {
+  auto msg = static_cast<Message*>(object);
+  const Descriptor* descriptor = msg->GetDescriptor();
+  const Reflection* reflection = msg->GetReflection();
+  auto unknown = reflection->MutableUnknownFields(msg);
+  GOOGLE_DCHECK(descriptor);
+  GOOGLE_DCHECK(reflection);
+
+  GOOGLE_DCHECK(begin <= end);
+  uint32 size;
+  internal::ParseFunc parser_till_end;
+  uint32 tag;
+  int depth;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (ptr == nullptr) return nullptr;
+    if ((tag >> 3) == 0) return nullptr;
+    const FieldDescriptor* field = nullptr;
+
+    int field_number = WireFormatLite::GetTagFieldNumber(tag);
+    field = descriptor->FindFieldByNumber(field_number);
+
+    // If that failed, check if the field is an extension.
+    if (field == nullptr && descriptor->IsExtensionNumber(field_number)) {
+      field = reflection->FindKnownExtensionByNumber(field_number);
+    }
+
+    // if (field) GOOGLE_LOG(ERROR) << "Encountered field " << field->name();
+
+    switch (tag & 7) {
+      case 0: {
+        uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        if (field == nullptr ||
+            WireFormat::WireTypeForFieldType(field->type()) != 0) {
+          unknown->AddVarint(field_number, val);
+          break;
+        }
+        SetField(val, field, msg, reflection);
+        break;
+      }
+      case 1: {
+        uint64 val = UNALIGNED_LOAD64(ptr);
+        ptr = ptr + 8;
+        if (field == nullptr ||
+            WireFormat::WireTypeForFieldType(field->type()) != 1) {
+          unknown->AddFixed64(field_number, val);
+          break;
+        }
+        SetField(val, field, msg, reflection);
+        break;
+      }
+      case 2: {
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ParseClosure child =
+            GetLenDelim(field_number, field, msg, unknown, reflection, ctx);
+        parser_till_end = child.func;
+        object = child.object;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange(child, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      case 3: {
+        if (!ctx->PrepareGroup(tag, &depth)) goto error;
+
+        ParseClosure child =
+            GetGroup(field_number, field, msg, unknown, reflection);
+        parser_till_end = child.func;
+        object = child.object;
+
+        if (ptr < end) ptr = child(ptr, end, ctx);
+        if (!ptr) goto error;
+        if (ctx->GroupContinues(depth)) goto group_continues;
+        break;
+      }
+      case 4: {
+        if (!ctx->ValidEndGroup(tag)) goto error;
+        return ptr;
+      }
+      case 5: {
+        uint32 val = UNALIGNED_LOAD32(ptr);
+        ptr = ptr + 4;
+        if (field == nullptr ||
+            WireFormat::WireTypeForFieldType(field->type()) != 5) {
+          unknown->AddFixed64(field_number, val);
+          break;
+        }
+        SetField(val, field, msg, reflection);
+        break;
+      }
+      default:
+        goto error;
+    }
+  }
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end:
+  // Length delimited field crosses end
+  return ctx->StoreAndTailCall(ptr, end, {Message::_InternalParse, msg},
+                               {parser_till_end, object}, size);
+group_continues:
+  GOOGLE_DCHECK(ptr >= end);
+  // Group crossed end and must be continued. Either this a parse failure
+  // or we need to resume on the next chunk and thus save the state.
+  ctx->StoreGroup({Message::_InternalParse, msg}, {parser_till_end, object},
+                  depth);
+  return ptr;
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
 
 void Message::SerializeWithCachedSizes(
     io::CodedOutputStream* output) const {
@@ -258,14 +708,32 @@
 
 MessageFactory::~MessageFactory() {}
 
+namespace internal {
+
+// TODO(gerbens) make this factorized better. This should not have to hop
+// to reflection. Currently uses GeneratedMessageReflection and thus is
+// defined in generated_message_reflection.cc
+void RegisterFileLevelMetadata(void* assign_descriptors_table);
+
+}  // namespace internal
+
 namespace {
 
+void RegisterFileLevelMetadata(void* assign_descriptors_table,
+                               const string& filename) {
+  internal::RegisterFileLevelMetadata(assign_descriptors_table);
+}
+
 class GeneratedMessageFactory : public MessageFactory {
  public:
   static GeneratedMessageFactory* singleton();
 
-  typedef void RegistrationFunc(const string&);
-  void RegisterFile(const char* file, RegistrationFunc* registration_func);
+  struct RegistrationData {
+    const Metadata* file_level_metadata;
+    int size;
+  };
+
+  void RegisterFile(const char* file, void* registration_data);
   void RegisterType(const Descriptor* descriptor, const Message* prototype);
 
   // implements MessageFactory ---------------------------------------
@@ -273,22 +741,24 @@
 
  private:
   // Only written at static init time, so does not require locking.
-  hash_map<const char*, RegistrationFunc*,
-           hash<const char*>, streq> file_map_;
+  std::unordered_map<const char*, void*, hash<const char*>,
+                     streq>
+      file_map_;
 
-  Mutex mutex_;
+  internal::WrappedMutex mutex_;
   // Initialized lazily, so requires locking.
-  hash_map<const Descriptor*, const Message*> type_map_;
+  std::unordered_map<const Descriptor*, const Message*> type_map_;
 };
 
 GeneratedMessageFactory* GeneratedMessageFactory::singleton() {
-  static auto instance = internal::OnShutdownDelete(new GeneratedMessageFactory);
+  static auto instance =
+      internal::OnShutdownDelete(new GeneratedMessageFactory);
   return instance;
 }
 
-void GeneratedMessageFactory::RegisterFile(
-    const char* file, RegistrationFunc* registration_func) {
-  if (!InsertIfNotPresent(&file_map_, file, registration_func)) {
+void GeneratedMessageFactory::RegisterFile(const char* file,
+                                           void* registration_data) {
+  if (!InsertIfNotPresent(&file_map_, file, registration_data)) {
     GOOGLE_LOG(FATAL) << "File is already registered: " << file;
   }
 }
@@ -321,9 +791,9 @@
   if (type->file()->pool() != DescriptorPool::generated_pool()) return NULL;
 
   // Apparently the file hasn't been registered yet.  Let's do that now.
-  RegistrationFunc* registration_func =
+  void* registration_data =
       FindPtrOrNull(file_map_, type->file()->name().c_str());
-  if (registration_func == NULL) {
+  if (registration_data == NULL) {
     GOOGLE_LOG(DFATAL) << "File appears to be in generated pool but wasn't "
                    "registered: " << type->file()->name();
     return NULL;
@@ -335,7 +805,7 @@
   const Message* result = FindPtrOrNull(type_map_, type);
   if (result == NULL) {
     // Nope.  OK, register everything.
-    registration_func(type->file()->name());
+    RegisterFileLevelMetadata(registration_data, type->file()->name());
     // Should be here now.
     result = FindPtrOrNull(type_map_, type);
   }
@@ -355,9 +825,9 @@
 }
 
 void MessageFactory::InternalRegisterGeneratedFile(
-    const char* filename, void (*register_messages)(const string&)) {
+    const char* filename, void* assign_descriptors_table) {
   GeneratedMessageFactory::singleton()->RegisterFile(filename,
-                                                     register_messages);
+                                                     assign_descriptors_table);
 }
 
 void MessageFactory::InternalRegisterGeneratedMessage(
@@ -379,18 +849,21 @@
   return NULL;
 }
 
-namespace internal {
-RepeatedFieldAccessor::~RepeatedFieldAccessor() {
+namespace {
+template <typename T>
+T* GetSingleton() {
+  static T singleton;
+  return &singleton;
 }
-}  // namespace internal
+}  // namespace
 
 const internal::RepeatedFieldAccessor* Reflection::RepeatedFieldAccessor(
     const FieldDescriptor* field) const {
   GOOGLE_CHECK(field->is_repeated());
   switch (field->cpp_type()) {
 #define HANDLE_PRIMITIVE_TYPE(TYPE, type) \
-    case FieldDescriptor::CPPTYPE_ ## TYPE: \
-      return internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<type> >::get();
+  case FieldDescriptor::CPPTYPE_##TYPE:   \
+    return GetSingleton<internal::RepeatedFieldPrimitiveAccessor<type> >();
     HANDLE_PRIMITIVE_TYPE(INT32, int32)
     HANDLE_PRIMITIVE_TYPE(UINT32, uint32)
     HANDLE_PRIMITIVE_TYPE(INT64, int64)
@@ -404,14 +877,14 @@
       switch (field->options().ctype()) {
         default:
         case FieldOptions::STRING:
-          return internal::Singleton<internal::RepeatedPtrFieldStringAccessor>::get();
+          return GetSingleton<internal::RepeatedPtrFieldStringAccessor>();
       }
       break;
     case FieldDescriptor::CPPTYPE_MESSAGE:
       if (field->is_map()) {
-        return internal::Singleton<internal::MapFieldAccessor>::get();
+        return GetSingleton<internal::MapFieldAccessor>();
       } else {
-        return internal::Singleton<internal::RepeatedPtrFieldMessageAccessor>::get();
+        return GetSingleton<internal::RepeatedPtrFieldMessageAccessor>();
       }
   }
   GOOGLE_LOG(FATAL) << "Should not reach here.";
@@ -419,55 +892,35 @@
 }
 
 namespace internal {
-namespace {
-void ShutdownRepeatedFieldAccessor() {
-  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<int32> >::ShutDown();
-  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<uint32> >::ShutDown();
-  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<int64> >::ShutDown();
-  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<uint64> >::ShutDown();
-  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<float> >::ShutDown();
-  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<double> >::ShutDown();
-  internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<bool> >::ShutDown();
-  internal::Singleton<internal::RepeatedPtrFieldStringAccessor>::ShutDown();
-  internal::Singleton<internal::RepeatedPtrFieldMessageAccessor>::ShutDown();
-  internal::Singleton<internal::MapFieldAccessor>::ShutDown();
-}
-
-struct ShutdownRepeatedFieldRegister {
-  ShutdownRepeatedFieldRegister() {
-    OnShutdown(&ShutdownRepeatedFieldAccessor);
-  }
-} shutdown_;
-
-}  // namespace
-}  // namespace internal
-
-namespace internal {
-template<>
+template <>
 #if defined(_MSC_VER) && (_MSC_VER >= 1800)
-// Note: force noinline to workaround MSVC compiler bug with /Zc:inline, issue #240
+// Note: force noinline to workaround MSVC compiler bug with /Zc:inline, issue
+// #240
 GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
 #endif
-Message* GenericTypeHandler<Message>::NewFromPrototype(
-    const Message* prototype, google::protobuf::Arena* arena) {
+    Message*
+    GenericTypeHandler<Message>::NewFromPrototype(const Message* prototype,
+                                                  Arena* arena) {
   return prototype->New(arena);
 }
-template<>
+template <>
 #if defined(_MSC_VER) && (_MSC_VER >= 1800)
-// Note: force noinline to workaround MSVC compiler bug with /Zc:inline, issue #240
+// Note: force noinline to workaround MSVC compiler bug with /Zc:inline, issue
+// #240
 GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
 #endif
-google::protobuf::Arena* GenericTypeHandler<Message>::GetArena(
-    Message* value) {
+    Arena*
+    GenericTypeHandler<Message>::GetArena(Message* value) {
   return value->GetArena();
 }
-template<>
+template <>
 #if defined(_MSC_VER) && (_MSC_VER >= 1800)
-// Note: force noinline to workaround MSVC compiler bug with /Zc:inline, issue #240
+// Note: force noinline to workaround MSVC compiler bug with /Zc:inline, issue
+// #240
 GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
 #endif
-void* GenericTypeHandler<Message>::GetMaybeArenaPointer(
-    Message* value) {
+    void*
+    GenericTypeHandler<Message>::GetMaybeArenaPointer(Message* value) {
   return value->GetMaybeArenaPointer();
 }
 }  // namespace internal
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index 4bdda3a..007dafa 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -115,16 +115,23 @@
 #include <type_traits>
 #include <vector>
 
-#include <google/protobuf/arena.h>
-#include <google/protobuf/message_lite.h>
-
+#include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/common.h>
+#include <google/protobuf/arena.h>
 #include <google/protobuf/descriptor.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/port.h>
 
 
 #define GOOGLE_PROTOBUF_HAS_ONEOF
 #define GOOGLE_PROTOBUF_HAS_ARENAS
 
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 
@@ -196,12 +203,12 @@
   // Construct a new instance of the same type.  Ownership is passed to the
   // caller.  (This is also defined in MessageLite, but is defined again here
   // for return-type covariance.)
-  virtual Message* New() const override = 0;
+  Message* New() const override = 0;
 
   // Construct a new instance on the arena. Ownership is passed to the caller
   // if arena is a NULL. Default implementation allows for API compatibility
   // during the Arena transition.
-  virtual Message* New(::google::protobuf::Arena* arena) const override {
+  Message* New(Arena* arena) const override {
     Message* message = New();
     if (arena != NULL) {
       arena->Own(message);
@@ -257,7 +264,7 @@
   // fields defined for the proto.
   virtual size_t SpaceUsedLong() const;
 
-  PROTOBUF_RUNTIME_DEPRECATED("Please use SpaceUsedLong() instead")
+  GOOGLE_PROTOBUF_DEPRECATED_MSG("Please use SpaceUsedLong() instead")
   int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); }
 
   // Debugging & Testing----------------------------------------------
@@ -305,13 +312,23 @@
   // These methods are pure-virtual in MessageLite, but Message provides
   // reflection-based default implementations.
 
-  virtual string GetTypeName() const override;
-  virtual void Clear() override;
-  virtual bool IsInitialized() const override;
-  virtual void CheckTypeAndMergeFrom(const MessageLite& other) override;
-  virtual bool MergePartialFromCodedStream(io::CodedInputStream* input) override;
-  virtual size_t ByteSizeLong() const override;
-  virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const override;
+  string GetTypeName() const override;
+  void Clear() override;
+  bool IsInitialized() const override;
+  void CheckTypeAndMergeFrom(const MessageLite& other) override;
+#if !GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  bool MergePartialFromCodedStream(io::CodedInputStream* input) override;
+#endif
+  size_t ByteSizeLong() const override;
+  void SerializeWithCachedSizes(io::CodedOutputStream* output) const override;
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  internal::ParseFunc _ParseFunc() const override { return _InternalParse; }
+
+  // Reflective parser
+  static const char* _InternalParse(const char* begin, const char* end,
+                                    void* object, internal::ParseContext* ctx);
+#endif
 
  private:
   // This is called only by the default implementation of ByteSize(), to
@@ -327,8 +344,6 @@
 
   // Introspection ---------------------------------------------------
 
-  // Typedef for backwards-compatibility.
-  typedef google::protobuf::Reflection Reflection;
 
   // Get a non-owning pointer to a Descriptor for this message's type.  This
   // describes what fields the message contains, the types of those fields, etc.
@@ -430,7 +445,7 @@
   // Estimate the amount of memory used by the message object.
   virtual size_t SpaceUsedLong(const Message& message) const = 0;
 
-  PROTOBUF_RUNTIME_DEPRECATED("Please use SpaceUsedLong() instead")
+  GOOGLE_PROTOBUF_DEPRECATED_MSG("Please use SpaceUsedLong() instead")
   int SpaceUsed(const Message& message) const {
     return internal::ToIntSize(SpaceUsedLong(message));
   }
@@ -554,7 +569,7 @@
   // *scratch and return that.
   //
   // Note:  It is perfectly reasonable and useful to write code like:
-  //     str = reflection->GetStringReference(field, &str);
+  //     str = reflection->GetStringReference(message, field, &str);
   //   This line would ensure that only one copy of the string is made
   //   regardless of the field's underlying representation.  When initializing
   //   a newly-constructed string, though, it's just as fast and more readable
@@ -589,9 +604,12 @@
                          const FieldDescriptor* field,
                          const EnumValueDescriptor* value) const = 0;
   // Set an enum field's value with an integer rather than EnumValueDescriptor.
-  // If the value does not correspond to a known enum value, either behavior is
-  // undefined (for proto2 messages), or the value is accepted silently for
-  // messages with new unknown-enum-value semantics.
+  // For proto3 this is just setting the enum field to the value specified, for
+  // proto2 it's more complicated. If value is a known enum value the field is
+  // set as usual. If the value is unknown then it is added to the unknown field
+  // set. Note this matches the behavior of parsing unknown enum values.
+  // If multiple calls with unknown values happen than they are all added to the
+  // unknown field set in order of the calls.
   virtual void SetEnumValue(Message* message,
                             const FieldDescriptor* field,
                             int value) const = 0;
@@ -707,9 +725,12 @@
                                const FieldDescriptor* field, int index,
                                const EnumValueDescriptor* value) const = 0;
   // Set an enum field's value with an integer rather than EnumValueDescriptor.
-  // If the value does not correspond to a known enum value, either behavior is
-  // undefined (for proto2 messages), or the value is accepted silently for
-  // messages with new unknown-enum-value semantics.
+  // For proto3 this is just setting the enum field to the value specified, for
+  // proto2 it's more complicated. If value is a known enum value the field is
+  // set as usual. If the value is unknown then it is added to the unknown field
+  // set. Note this matches the behavior of parsing unknown enum values.
+  // If multiple calls with unknown values happen than they are all added to the
+  // unknown field set in order of the calls.
   virtual void SetRepeatedEnumValue(Message* message,
                                     const FieldDescriptor* field, int index,
                                     int value) const = 0;
@@ -742,10 +763,13 @@
   virtual void AddEnum  (Message* message,
                          const FieldDescriptor* field,
                          const EnumValueDescriptor* value) const = 0;
-  // Set an enum field's value with an integer rather than EnumValueDescriptor.
-  // If the value does not correspond to a known enum value, either behavior is
-  // undefined (for proto2 messages), or the value is accepted silently for
-  // messages with new unknown-enum-value semantics.
+  // Add an integer value to a repeated enum field rather than
+  // EnumValueDescriptor. For proto3 this is just setting the enum field to the
+  // value specified, for proto2 it's more complicated. If value is a known enum
+  // value the field is set as usual. If the value is unknown then it is added
+  // to the unknown field set. Note this matches the behavior of parsing unknown
+  // enum values. If multiple calls with unknown values happen than they are all
+  // added to the unknown field set in order of the calls.
   virtual void AddEnumValue(Message* message,
                             const FieldDescriptor* field,
                             int value) const = 0;
@@ -755,7 +779,7 @@
                               MessageFactory* factory = NULL) const = 0;
 
   // Appends an already-allocated object 'new_entry' to the repeated field
-  // specifyed by 'field' passing ownership to the message.
+  // specified by 'field' passing ownership to the message.
   // TODO(tmarek): Make virtual after all subclasses have been
   // updated.
   virtual void AddAllocatedMessage(Message* message,
@@ -785,7 +809,7 @@
   // long as the message is not destroyed.
   //
   // Note that to use this method users need to include the header file
-  // "google/protobuf/reflection.h" (which defines the RepeatedFieldRef
+  // "net/proto2/public/reflection.h" (which defines the RepeatedFieldRef
   // class templates).
   template<typename T>
   RepeatedFieldRef<T> GetRepeatedFieldRef(
@@ -814,36 +838,40 @@
   // DEPRECATED. Please use GetRepeatedFieldRef().
   //
   // for T = Cord and all protobuf scalar types except enums.
-  template<typename T>
-  PROTOBUF_RUNTIME_DEPRECATED("Please use GetRepeatedFieldRef() instead")
-  const RepeatedField<T>& GetRepeatedField(
-      const Message&, const FieldDescriptor*) const;
+  template <typename T>
+  GOOGLE_PROTOBUF_DEPRECATED_MSG(
+      "Please use GetRepeatedFieldRef() instead")
+  const RepeatedField<T>& GetRepeatedField(const Message&,
+                                           const FieldDescriptor*) const;
 
   // DEPRECATED. Please use GetMutableRepeatedFieldRef().
   //
   // for T = Cord and all protobuf scalar types except enums.
-  template<typename T>
-  PROTOBUF_RUNTIME_DEPRECATED("Please use GetMutableRepeatedFieldRef() instead")
-  RepeatedField<T>* MutableRepeatedField(
-      Message*, const FieldDescriptor*) const;
+  template <typename T>
+  GOOGLE_PROTOBUF_DEPRECATED_MSG(
+      "Please use GetMutableRepeatedFieldRef() instead")
+  RepeatedField<T>* MutableRepeatedField(Message*,
+                                         const FieldDescriptor*) const;
 
   // DEPRECATED. Please use GetRepeatedFieldRef().
   //
   // for T = string, google::protobuf::internal::StringPieceField
   //         google::protobuf::Message & descendants.
-  template<typename T>
-  PROTOBUF_RUNTIME_DEPRECATED("Please use GetRepeatedFieldRef() instead")
-  const RepeatedPtrField<T>& GetRepeatedPtrField(
-      const Message&, const FieldDescriptor*) const;
+  template <typename T>
+  GOOGLE_PROTOBUF_DEPRECATED_MSG(
+      "Please use GetRepeatedFieldRef() instead")
+  const RepeatedPtrField<T>& GetRepeatedPtrField(const Message&,
+                                                 const FieldDescriptor*) const;
 
   // DEPRECATED. Please use GetMutableRepeatedFieldRef().
   //
   // for T = string, google::protobuf::internal::StringPieceField
   //         google::protobuf::Message & descendants.
-  template<typename T>
-  PROTOBUF_RUNTIME_DEPRECATED("Please use GetMutableRepeatedFieldRef() instead")
-  RepeatedPtrField<T>* MutableRepeatedPtrField(
-      Message*, const FieldDescriptor*) const;
+  template <typename T>
+  GOOGLE_PROTOBUF_DEPRECATED_MSG(
+      "Please use GetMutableRepeatedFieldRef() instead")
+  RepeatedPtrField<T>* MutableRepeatedPtrField(Message*,
+                                               const FieldDescriptor*) const;
 
   // Extensions ----------------------------------------------------------------
 
@@ -952,9 +980,9 @@
   friend class RepeatedFieldRef;
   template<typename T, typename Enable>
   friend class MutableRepeatedFieldRef;
-  friend class ::google::protobuf::python::MapReflectionFriend;
+  friend class python::MapReflectionFriend;
 #define GOOGLE_PROTOBUF_HAS_CEL_MAP_REFLECTION_FRIEND
-  friend class ::google::protobuf::expr::CelMapReflectionFriend;
+  friend class expr::CelMapReflectionFriend;
   friend class internal::MapFieldReflectionTest;
   friend class internal::MapKeySorter;
   friend class internal::WireFormat;
@@ -1078,8 +1106,8 @@
   // in the file.  This strange mechanism is necessary because descriptors are
   // built lazily, so we can't register types by their descriptor until we
   // know that the descriptor exists.  |filename| must be a permanent string.
-  static void InternalRegisterGeneratedFile(
-      const char* filename, void (*register_messages)(const string&));
+  static void InternalRegisterGeneratedFile(const char* filename,
+                                            void* assign_descriptors_table);
 
   // For internal use only:  Registers a message type.  Called only by the
   // functions which are registered with InternalRegisterGeneratedFile(),
@@ -1113,6 +1141,53 @@
 
 #undef DECLARE_GET_REPEATED_FIELD
 
+// Tries to downcast this message to a generated message type.  Returns NULL if
+// this class is not an instance of T.  This works even if RTTI is disabled.
+//
+// This also has the effect of creating a strong reference to T that will
+// prevent the linker from stripping it out at link time.  This can be important
+// if you are using a DynamicMessageFactory that delegates to the generated
+// factory.
+template <typename T>
+const T* DynamicCastToGenerated(const Message* from) {
+  // Compile-time assert that T is a generated type that has a
+  // default_instance() accessor, but avoid actually calling it.
+  const T&(*get_default_instance)() = &T::default_instance;
+  (void)get_default_instance;
+
+  // Compile-time assert that T is a subclass of google::protobuf::Message.
+  const Message* unused = static_cast<T*>(nullptr);
+  (void)unused;
+
+#ifdef GOOGLE_PROTOBUF_NO_RTTI
+  bool ok = T::default_instance().GetReflection() == from->GetReflection();
+  return ok ? down_cast<const T*>(from) : nullptr;
+#else
+  return dynamic_cast<const T*>(from);
+#endif
+}
+
+template <typename T>
+T* DynamicCastToGenerated(Message* from) {
+  const Message* message_const = from;
+  return const_cast<T*>(DynamicCastToGenerated<T>(message_const));
+}
+
+namespace internal {
+
+// Legacy functions, to preserve compatibility with existing callers.
+// These had a slightly different signature, so we have to adjust "T".
+template <typename T>
+T dynamic_cast_if_available(const Message* from) {
+  return DynamicCastToGenerated<typename std::remove_pointer<T>::type>(from);
+}
+template <typename T>
+T dynamic_cast_if_available(Message* from) {
+  return DynamicCastToGenerated<typename std::remove_pointer<T>::type>(from);
+}
+
+}  // namespace internal
+
 // =============================================================================
 // Implementation details for {Get,Mutable}RawRepeatedPtrField.  We provide
 // specializations for <string>, <StringPieceField> and <Message> and handle
@@ -1171,6 +1246,8 @@
           PB::default_instance().GetDescriptor()));
 }
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_MESSAGE_H__
diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc
index 65af7ce..33ee632 100644
--- a/src/google/protobuf/message_lite.cc
+++ b/src/google/protobuf/message_lite.cc
@@ -34,18 +34,27 @@
 //  Sanjay Ghemawat, Jeff Dean, and others.
 
 #include <climits>
+#include <string>
 
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/generated_message_util.h>
 #include <google/protobuf/message_lite.h>
 #include <google/protobuf/repeated_field.h>
-#include <string>
-#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <google/protobuf/stubs/stl_util.h>
 
+#include <google/protobuf/port_def.inc>
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+#include <google/protobuf/parse_context.h>
+#include "util/utf8/public/unilib.h"
+#include "util/utf8/public/unilib_utf8_utils.h"
+#endif
+
 namespace google {
 namespace protobuf {
 
@@ -96,6 +105,180 @@
   return result;
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+// This is wrapper to turn a ZeroCopyInputStream (ZCIS) into a
+// InputStreamWithOverlap. This is done by copying data around the seams,
+// pictorially if ZCIS presents a stream in chunks like so
+// [---------------------------------------------------------------]
+// [---------------------] chunk 1
+//                      [----------------------------] chunk 2
+//                                          chunk 3 [--------------]
+// this class will convert this into chunks
+// [-----------------....] chunk 1
+//                  [----....] patch
+//                      [------------------------....] chunk 2
+//                                              [----....] patch
+//                                          chunk 3 [----------....]
+//                                                      patch [----****]
+// by using a fixed size buffer to patch over the seams. This requires
+// copying of an "epsilon" neighboorhood around the seams.
+
+template <int kSlopBytes>
+class EpsCopyInputStream {
+ public:
+  EpsCopyInputStream(io::CodedInputStream* input) : input_(input) {}
+  ~EpsCopyInputStream() {
+    if (skip_) input_->Skip(skip_);
+  }
+
+  StringPiece NextWithOverlap() {
+    switch (next_state_) {
+      case kEOS:
+        // End of stream
+        return nullptr;
+      case kChunk:
+        // chunk_ contains a buffer of sufficient size (> kSlopBytes).
+        // To parse the last kSlopBytes we need to copy the bytes into the
+        // buffer. Hence we set,
+        next_state_ = kBuffer;
+        return {chunk_.begin(), chunk_.size() - kSlopBytes};
+      case kBuffer:
+        // We have to parse the last kSlopBytes of chunk_, which could alias
+        // buffer_ so we have to memmove.
+        std::memmove(buffer_, chunk_.end() - kSlopBytes, kSlopBytes);
+        chunk_ = GetChunk();
+        if (chunk_.size() > kSlopBytes) {
+          next_state_ = kChunk;
+          std::memcpy(buffer_ + kSlopBytes, chunk_.begin(), kSlopBytes);
+          return {buffer_, kSlopBytes};
+        } else if (chunk_.empty()) {
+          next_state_ = kEOS;
+          return {buffer_, kSlopBytes};
+        } else {
+          auto size = chunk_.size();
+          // The next chunk is not big enough. So we copy it in the current
+          // after the current buffer. Resulting in a buffer with
+          // size + kSlopBytes bytes.
+          std::memcpy(buffer_ + kSlopBytes, chunk_.begin(), size);
+          chunk_ = {buffer_, size + kSlopBytes};
+          return {buffer_, size};
+        }
+      case kStart: {
+        size_t i = 0;
+        do {
+          chunk_ = GetChunk();
+          if (chunk_.size() > kSlopBytes) {
+            if (i == 0) {
+              next_state_ = kBuffer;
+              return {chunk_.begin(), chunk_.size() - kSlopBytes};
+            }
+            std::memcpy(buffer_ + i, chunk_.begin(), kSlopBytes);
+            next_state_ = kChunk;
+            return {buffer_, i};
+          }
+          if (chunk_.empty()) {
+            next_state_ = kEOS;
+            return {buffer_, i};
+          }
+          std::memcpy(buffer_ + i, chunk_.begin(), chunk_.size());
+          i += chunk_.size();
+        } while (i <= kSlopBytes);
+        chunk_ = {buffer_, i};
+        next_state_ = kBuffer;
+        return {buffer_, i - kSlopBytes};
+      }
+    }
+  }
+
+  StringPiece NextWithOverlapEndingSafe(const char* ptr, int nesting) {
+    switch (next_state_) {
+      case kEOS:
+        // End of stream
+        return nullptr;
+      case kChunk:
+        // chunk_ contains a buffer of sufficient size (> kSlopBytes).
+        // To parse the last kSlopBytes we need to copy the bytes into the
+        // buffer. Hence we set,
+        next_state_ = kBuffer;
+        return {chunk_.begin(), chunk_.size() - kSlopBytes};
+      case kBuffer:
+        // We have to parse the last kSlopBytes of chunk_, which could alias
+        // buffer_ so we have to memmove.
+        if (!SafeCopy(buffer_, chunk_.end() - kSlopBytes, nesting)) {
+          // We will terminate
+        }
+        chunk_ = GetChunk();
+        if (chunk_.size() > kSlopBytes) {
+          next_state_ = kChunk;
+          std::memcpy(buffer_ + kSlopBytes, chunk_.begin(), kSlopBytes);
+          return {buffer_, kSlopBytes};
+        } else if (chunk_.empty()) {
+          next_state_ = kEOS;
+          return {buffer_, kSlopBytes};
+        } else {
+          auto size = chunk_.size();
+          // The next chunk is not big enough. So we copy it in the current
+          // after the current buffer. Resulting in a buffer with
+          // size + kSlopBytes bytes.
+          std::memcpy(buffer_ + kSlopBytes, chunk_.begin(), size);
+          chunk_ = {buffer_, size + kSlopBytes};
+          return {buffer_, size};
+        }
+      case kStart: {
+        size_t i = 0;
+        do {
+          chunk_ = GetChunk();
+          if (chunk_.size() > kSlopBytes) {
+            if (i == 0) {
+              next_state_ = kBuffer;
+              return {chunk_.begin(), chunk_.size() - kSlopBytes};
+            }
+            std::memcpy(buffer_ + i, chunk_.begin(), kSlopBytes);
+            next_state_ = kChunk;
+            return {buffer_, i};
+          }
+          if (chunk_.empty()) {
+            next_state_ = kEOS;
+            return {buffer_, i};
+          }
+          std::memcpy(buffer_ + i, chunk_.begin(), chunk_.size());
+          i += chunk_.size();
+        } while (i <= kSlopBytes);
+        chunk_ = {buffer_, i};
+        next_state_ = kBuffer;
+        return {buffer_, i - kSlopBytes};
+      }
+    }
+  }
+
+  void Backup(const char* ptr) { skip_ = ptr - chunk_.data(); }
+
+ private:
+  io::CodedInputStream* input_;
+  StringPiece chunk_;
+  char buffer_[2 * kSlopBytes];
+  enum State {
+    kEOS = 0,     // -> end of stream.
+    kChunk = 1,   // -> chunk_ contains the data for Next.
+    kBuffer = 2,  // -> We need to copy the left over from previous chunk_ and
+                  //    load and patch the start of the next chunk in the
+                  //    local buffer.
+    kStart = 3,
+  };
+  State next_state_ = kStart;
+  int skip_ = 0;
+
+  StringPiece GetChunk() {
+    const void* ptr;
+    if (skip_) input_->Skip(skip_);
+    if (!input_->GetDirectBufferPointer(&ptr, &skip_)) {
+      return nullptr;
+    }
+    return StringPiece(static_cast<const char*>(ptr), skip_);
+  }
+};
+#endif
+
 // Several of the Parse methods below just do one thing and then call another
 // method.  In a naive implementation, we might have ParseFromString() call
 // ParseFromArray() which would call ParseFromZeroCopyStream() which would call
@@ -103,20 +286,30 @@
 // call MergePartialFromCodedStream().  However, when parsing very small
 // messages, every function call introduces significant overhead.  To avoid
 // this without reproducing code, we use these forced-inline helpers.
-GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE bool InlineMergeFromCodedStream(
-    io::CodedInputStream* input, MessageLite* message);
-GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE bool InlineParseFromCodedStream(
-    io::CodedInputStream* input, MessageLite* message);
-GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE bool InlineParsePartialFromCodedStream(
-    io::CodedInputStream* input, MessageLite* message);
-GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE bool InlineParseFromArray(
-    const void* data, int size, MessageLite* message);
-GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE bool InlineParsePartialFromArray(
-    const void* data, int size, MessageLite* message);
+
+inline bool InlineMergePartialFromCodedStream(io::CodedInputStream* input,
+                                              MessageLite* message) {
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  EpsCopyInputStream<internal::ParseContext::kSlopBytes> eps_input(input);
+  internal::ParseContext ctx;
+  auto res = ctx.ParseNoLimit({message->_ParseFunc(), message}, &eps_input);
+  if (res == 1) {
+    input->SetConsumed();
+    return true;
+  } else if (res == 2) {
+    return false;
+  } else {
+    input->SetLastTag(res);
+    return true;
+  }
+#else
+  return message->MergePartialFromCodedStream(input);
+#endif
+}
 
 inline bool InlineMergeFromCodedStream(io::CodedInputStream* input,
                                        MessageLite* message) {
-  if (!message->MergePartialFromCodedStream(input)) return false;
+  if (!InlineMergePartialFromCodedStream(input, message)) return false;
   if (!message->IsInitialized()) {
     GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message);
     return false;
@@ -124,36 +317,81 @@
   return true;
 }
 
+inline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
+                                              MessageLite* message) {
+  message->Clear();
+  return InlineMergePartialFromCodedStream(input, message);
+}
+
 inline bool InlineParseFromCodedStream(io::CodedInputStream* input,
                                        MessageLite* message) {
   message->Clear();
   return InlineMergeFromCodedStream(input, message);
 }
 
-inline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
-                                              MessageLite* message) {
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+template <int kSlopBytes>
+class ArrayInput {
+ public:
+  ArrayInput(StringPiece chunk) : chunk_(chunk) {}
+  StringPiece NextWithOverlap() {
+    auto res = chunk_;
+    chunk_ = nullptr;
+    return res;
+  }
+
+  void Backup(const char*) { GOOGLE_CHECK(false) << "Can't backup arrayinput"; }
+
+ private:
+  StringPiece chunk_;
+};
+#endif
+
+inline bool InlineMergePartialFromArray(const void* data, int size,
+                                        MessageLite* message,
+                                        bool aliasing = false) {
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  internal::ParseContext ctx;
+  ArrayInput<internal::ParseContext::kSlopBytes> input(
+      StringPiece(static_cast<const char*>(data), size));
+  return ctx.Parse({message->_ParseFunc(), message}, size, &input);
+#else
+  io::CodedInputStream input(static_cast<const uint8*>(data), size);
+  return message->MergePartialFromCodedStream(&input) &&
+         input.ConsumedEntireMessage();
+#endif
+}
+
+inline bool InlineMergeFromArray(const void* data, int size,
+                                 MessageLite* message, bool aliasing = false) {
+  if (!InlineMergePartialFromArray(data, size, message, aliasing)) return false;
+  if (!message->IsInitialized()) {
+    GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message);
+    return false;
+  }
+  return true;
+}
+
+inline bool InlineParsePartialFromArray(const void* data, int size,
+                                        MessageLite* message,
+                                        bool aliasing = false) {
   message->Clear();
-  return message->MergePartialFromCodedStream(input);
+  return InlineMergePartialFromArray(data, size, message, aliasing);
 }
 
-inline bool InlineParseFromArray(
-    const void* data, int size, MessageLite* message) {
-  io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
-  return InlineParseFromCodedStream(&input, message) &&
-         input.ConsumedEntireMessage();
-}
-
-inline bool InlineParsePartialFromArray(
-    const void* data, int size, MessageLite* message) {
-  io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
-  return InlineParsePartialFromCodedStream(&input, message) &&
-         input.ConsumedEntireMessage();
+inline bool InlineParseFromArray(const void* data, int size,
+                                 MessageLite* message, bool aliasing = false) {
+  if (!InlineParsePartialFromArray(data, size, message, aliasing)) return false;
+  if (!message->IsInitialized()) {
+    GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message);
+    return false;
+  }
+  return true;
 }
 
 }  // namespace
 
-
-MessageLite* MessageLite::New(::google::protobuf::Arena* arena) const {
+MessageLite* MessageLite::New(Arena* arena) const {
   MessageLite* message = New();
   if (arena != NULL) {
     arena->Own(message);
@@ -161,6 +399,12 @@
   return message;
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool MessageLite::MergePartialFromCodedStream(io::CodedInputStream* input) {
+  return InlineMergePartialFromCodedStream(input, this);
+}
+#endif
+
 bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) {
   return InlineMergeFromCodedStream(input, this);
 }
@@ -236,7 +480,8 @@
     io::CodedOutputStream* output) const {
   const size_t size = ByteSizeLong();  // Force size to be cached.
   if (size > INT_MAX) {
-    GOOGLE_LOG(ERROR) << "Exceeded maximum protobuf size of 2GB: " << size;
+    GOOGLE_LOG(ERROR) << GetTypeName() << " exceeded maximum protobuf size of 2GB: "
+               << size;
     return false;
   }
 
@@ -286,7 +531,8 @@
   size_t old_size = output->size();
   size_t byte_size = ByteSizeLong();
   if (byte_size > INT_MAX) {
-    GOOGLE_LOG(ERROR) << "Exceeded maximum protobuf size of 2GB: " << byte_size;
+    GOOGLE_LOG(ERROR) << GetTypeName() << " exceeded maximum protobuf size of 2GB: "
+               << byte_size;
     return false;
   }
 
@@ -316,9 +562,10 @@
 }
 
 bool MessageLite::SerializePartialToArray(void* data, int size) const {
-  size_t byte_size = ByteSizeLong();
+  const size_t byte_size = ByteSizeLong();
   if (byte_size > INT_MAX) {
-    GOOGLE_LOG(ERROR) << "Exceeded maximum protobuf size of 2GB: " << size;
+    GOOGLE_LOG(ERROR) << GetTypeName() << " exceeded maximum protobuf size of 2GB: "
+               << byte_size;
     return false;
   }
   if (size < byte_size) return false;
@@ -382,9 +629,10 @@
 }
 
 namespace internal {
-template<>
+
+template <>
 MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
-    const MessageLite* prototype, google::protobuf::Arena* arena) {
+    const MessageLite* prototype, Arena* arena) {
   return prototype->New(arena);
 }
 template <>
@@ -398,13 +646,6 @@
   *to = from;
 }
 
-bool proto3_preserve_unknown_ = true;
-
-void SetProto3PreserveUnknownsDefault(bool preserve) {
-  proto3_preserve_unknown_ = preserve;
-}
-
-
 }  // namespace internal
 
 }  // namespace protobuf
diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h
index b864414..21d5491 100644
--- a/src/google/protobuf/message_lite.h
+++ b/src/google/protobuf/message_lite.h
@@ -40,29 +40,47 @@
 #define GOOGLE_PROTOBUF_MESSAGE_LITE_H__
 
 #include <climits>
+#include <string>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/once.h>
 #include <google/protobuf/arena.h>
-#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/port.h>
+
+
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
 
 namespace google {
 namespace protobuf {
+
 template <typename T>
 class RepeatedPtrField;
+
 namespace io {
+
 class CodedInputStream;
 class CodedOutputStream;
 class ZeroCopyInputStream;
 class ZeroCopyOutputStream;
-}
+
+}  // namespace io
 namespace internal {
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+// See parse_context.h for explanation
+class ParseContext;
+typedef const char* (*ParseFunc)(const char* ptr, const char* end, void* object,
+                                 ParseContext* ctx);
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
 class RepeatedPtrFieldBase;
 class WireFormatLite;
 class WeakFieldMap;
 
-#ifndef SWIG
 // We compute sizes as size_t but cache them as int.  This function converts a
 // computed size to a cached size.  Since we don't proceed with serialization
 // if the total size was > INT_MAX, it is not important what this function
@@ -128,14 +146,16 @@
 
 // Default empty string object. Don't use this directly. Instead, call
 // GetEmptyString() to get the reference.
-LIBPROTOBUF_EXPORT extern ExplicitlyConstructed<::std::string> fixed_address_empty_string;
+LIBPROTOBUF_EXPORT extern ExplicitlyConstructed<::std::string>
+    fixed_address_empty_string;
+
 
 LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyStringAlreadyInited() {
   return fixed_address_empty_string.get();
 }
 
 LIBPROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const string& str);
-#endif  // SWIG
+
 }  // namespace internal
 
 // Interface to light weight protocol messages.
@@ -177,14 +197,14 @@
 
   // Construct a new instance on the arena. Ownership is passed to the caller
   // if arena is a NULL. Default implementation for backwards compatibility.
-  virtual MessageLite* New(::google::protobuf::Arena* arena) const;
+  virtual MessageLite* New(Arena* arena) const;
 
   // Get the arena, if any, associated with this message. Virtual method
   // required for generic operations but most arena-related operations should
   // use the GetArenaNoVirtual() generated-code method. Default implementation
   // to reduce code size by avoiding the need for per-type implementations
   // when types do not implement arena support.
-  virtual ::google::protobuf::Arena* GetArena() const { return NULL; }
+  virtual Arena* GetArena() const { return NULL; }
 
   // Get a pointer that may be equal to this message's arena, or may not be.
   // If the value returned by this method is equal to some arena pointer, then
@@ -278,7 +298,14 @@
   //
   // MergeFromCodedStream() is just implemented as MergePartialFromCodedStream()
   // followed by IsInitialized().
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  virtual bool MergePartialFromCodedStream(io::CodedInputStream* input);
+#else
   virtual bool MergePartialFromCodedStream(io::CodedInputStream* input) = 0;
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+  // Merge a protocol buffer contained in a string.
+  bool MergeFromString(const string& data);
 
 
   // Serialization ---------------------------------------------------
@@ -331,7 +358,7 @@
   virtual size_t ByteSizeLong() const = 0;
 
   // Legacy ByteSize() API.
-  PROTOBUF_RUNTIME_DEPRECATED("Please use ByteSizeLong() instead")
+  GOOGLE_PROTOBUF_DEPRECATED_MSG("Please use ByteSizeLong() instead")
   int ByteSize() const {
     return internal::ToIntSize(ByteSizeLong());
   }
@@ -370,19 +397,25 @@
   virtual uint8* InternalSerializeWithCachedSizesToArray(bool deterministic,
                                                          uint8* target) const;
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  virtual internal::ParseFunc _ParseFunc() const {
+    return nullptr;
+  }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
  protected:
   // CastToBase allows generated code to cast a RepeatedPtrField<T> to
   // RepeatedPtrFieldBase. We try to restrict access to RepeatedPtrFieldBase
   // because it is an implementation detail that user code should not access
   // directly.
   template <typename T>
-  static ::google::protobuf::internal::RepeatedPtrFieldBase* CastToBase(
-      ::google::protobuf::RepeatedPtrField<T>* repeated) {
+  static internal::RepeatedPtrFieldBase* CastToBase(
+      RepeatedPtrField<T>* repeated) {
     return repeated;
   }
   template <typename T>
-  static const ::google::protobuf::internal::RepeatedPtrFieldBase& CastToBase(
-      const ::google::protobuf::RepeatedPtrField<T>& repeated) {
+  static const internal::RepeatedPtrFieldBase& CastToBase(
+      const RepeatedPtrField<T>& repeated) {
     return repeated;
   }
 
@@ -402,23 +435,9 @@
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite);
 };
 
-namespace internal {
-
-extern bool LIBPROTOBUF_EXPORT proto3_preserve_unknown_;
-
-// DO NOT USE: For migration only. Will be removed when Proto3 defaults to
-// preserve unknowns.
-inline bool GetProto3PreserveUnknownsDefault() {
-  return proto3_preserve_unknown_;
-}
-
-// DO NOT USE: For migration only. Will be removed when Proto3 defaults to
-// preserve unknowns.
-void LIBPROTOBUF_EXPORT SetProto3PreserveUnknownsDefault(bool preserve);
-}  // namespace internal
-
-
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_MESSAGE_LITE_H__
diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc
index 45b46be..0840e7b 100644
--- a/src/google/protobuf/message_unittest.cc
+++ b/src/google/protobuf/message_unittest.cc
@@ -43,9 +43,3 @@
 // Must include after the above macros.
 #include <google/protobuf/test_util.inc>
 #include <google/protobuf/message_unittest.inc>
-
-// Make extract script happy.
-namespace google {
-namespace protobuf {
-}  // namespace protobuf
-}  // namespace google
diff --git a/src/google/protobuf/message_unittest.inc b/src/google/protobuf/message_unittest.inc
index 6ffdcce..0b9d565 100644
--- a/src/google/protobuf/message_unittest.inc
+++ b/src/google/protobuf/message_unittest.inc
@@ -46,6 +46,7 @@
 #include <fstream>
 #include <sstream>
 
+#include <google/protobuf/test_util2.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
@@ -117,8 +118,8 @@
 }
 
 TEST(MESSAGE_TEST_NAME, ParseFromFileDescriptor) {
-  string filename = TestSourceDir() +
-                    "/google/protobuf/testdata/golden_message";
+  string filename =
+      TestUtil::GetTestDataPath("net/proto2/internal/testdata/golden_message");
   int file = open(filename.c_str(), O_RDONLY | O_BINARY);
   ASSERT_GE(file, 0);
 
@@ -130,9 +131,8 @@
 }
 
 TEST(MESSAGE_TEST_NAME, ParsePackedFromFileDescriptor) {
-  string filename =
-      TestSourceDir() +
-      "/google/protobuf/testdata/golden_packed_fields_message";
+  string filename = TestUtil::GetTestDataPath(
+      "net/proto2/internal/testdata/golden_packed_fields_message");
   int file = open(filename.c_str(), O_RDONLY | O_BINARY);
   ASSERT_GE(file, 0);
 
@@ -223,23 +223,18 @@
 TEST(MESSAGE_TEST_NAME, DynamicCastToGenerated) {
   UNITTEST::TestAllTypes test_all_types;
 
-  google::protobuf::Message* test_all_types_pointer = &test_all_types;
-  EXPECT_EQ(&test_all_types,
-            google::protobuf::internal::DynamicCastToGenerated<UNITTEST::TestAllTypes>(
-                test_all_types_pointer));
-  EXPECT_EQ(nullptr,
-            google::protobuf::internal::DynamicCastToGenerated<UNITTEST::TestRequired>(
-                test_all_types_pointer));
+  Message* test_all_types_pointer = &test_all_types;
+  EXPECT_EQ(&test_all_types, DynamicCastToGenerated<UNITTEST::TestAllTypes>(
+                                 test_all_types_pointer));
+  EXPECT_EQ(nullptr, DynamicCastToGenerated<UNITTEST::TestRequired>(
+                         test_all_types_pointer));
 
-  const google::protobuf::Message* test_all_types_pointer_const = &test_all_types;
-  EXPECT_EQ(
-      &test_all_types,
-      google::protobuf::internal::DynamicCastToGenerated<const UNITTEST::TestAllTypes>(
-          test_all_types_pointer_const));
-  EXPECT_EQ(
-      nullptr,
-      google::protobuf::internal::DynamicCastToGenerated<const UNITTEST::TestRequired>(
-          test_all_types_pointer_const));
+  const Message* test_all_types_pointer_const = &test_all_types;
+  EXPECT_EQ(&test_all_types,
+            DynamicCastToGenerated<const UNITTEST::TestAllTypes>(
+                test_all_types_pointer_const));
+  EXPECT_EQ(nullptr, DynamicCastToGenerated<const UNITTEST::TestRequired>(
+                         test_all_types_pointer_const));
 }
 
 #ifdef PROTOBUF_HAS_DEATH_TEST  // death tests do not work on Windows yet.
@@ -406,9 +401,9 @@
   // payload.
   string invalid_string_data = "\x72\x01";
   {
-    google::protobuf::Arena arena;
+    Arena arena;
     UNITTEST::TestAllTypes* arena_message =
-        google::protobuf::Arena::CreateMessage<UNITTEST::TestAllTypes>(&arena);
+        Arena::CreateMessage<UNITTEST::TestAllTypes>(&arena);
     EXPECT_FALSE(arena_message->ParseFromString(invalid_string_data));
     arena_message->Clear();
     EXPECT_EQ("", arena_message->optional_string());
diff --git a/src/google/protobuf/metadata.h b/src/google/protobuf/metadata.h
index 0a6507c..928bbf5 100644
--- a/src/google/protobuf/metadata.h
+++ b/src/google/protobuf/metadata.h
@@ -41,6 +41,10 @@
 #include <google/protobuf/metadata_lite.h>
 #include <google/protobuf/unknown_field_set.h>
 
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 namespace internal {
@@ -73,6 +77,6 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_METADATA_H__
diff --git a/src/google/protobuf/metadata_lite.h b/src/google/protobuf/metadata_lite.h
index 454d088..3c36a55 100644
--- a/src/google/protobuf/metadata_lite.h
+++ b/src/google/protobuf/metadata_lite.h
@@ -31,10 +31,17 @@
 #ifndef GOOGLE_PROTOBUF_METADATA_LITE_H__
 #define GOOGLE_PROTOBUF_METADATA_LITE_H__
 
+#include <string>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/message_lite.h>
-#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/port.h>
+
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
 
 namespace google {
 namespace protobuf {
@@ -103,7 +110,8 @@
     }
   }
 
-  GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void MergeFrom(const Derived& other) {
+  GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void MergeFrom(
+      const Derived& other) {
     if (other.have_unknown_fields()) {
       static_cast<Derived*>(this)->DoMergeFrom(other.unknown_fields());
     }
@@ -219,6 +227,8 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_METADATA_LITE_H__
diff --git a/src/google/protobuf/no_field_presence_test.cc b/src/google/protobuf/no_field_presence_test.cc
index bc41bee..d212fb1 100644
--- a/src/google/protobuf/no_field_presence_test.cc
+++ b/src/google/protobuf/no_field_presence_test.cc
@@ -280,19 +280,19 @@
   // behaves properly for message fields.
 
   proto2_nofieldpresence_unittest::TestAllTypes message;
-  const google::protobuf::Reflection* r = message.GetReflection();
-  const google::protobuf::Descriptor* desc = message.GetDescriptor();
+  const Reflection* r = message.GetReflection();
+  const Descriptor* desc = message.GetDescriptor();
 
   // Check initial state: scalars not present (due to need to be consistent with
   // MergeFrom()), message fields not present, oneofs not present.
   for (int i = 0; i < desc->field_count(); i++) {
-    const google::protobuf::FieldDescriptor* field = desc->field(i);
+    const FieldDescriptor* field = desc->field(i);
     if (field->is_repeated()) continue;
     EXPECT_EQ(false, r->HasField(message, field));
   }
 
   // Test field presence of a message field on the default instance.
-  const google::protobuf::FieldDescriptor* msg_field =
+  const FieldDescriptor* msg_field =
       desc->FindFieldByName("optional_nested_message");
   EXPECT_EQ(false, r->HasField(
       proto2_nofieldpresence_unittest::TestAllTypes::
@@ -301,11 +301,11 @@
   // Fill all fields, expect everything to report true (check oneofs below).
   FillValues(&message);
   for (int i = 0; i < desc->field_count(); i++) {
-    const google::protobuf::FieldDescriptor* field = desc->field(i);
+    const FieldDescriptor* field = desc->field(i);
     if (field->is_repeated() || field->containing_oneof()) {
       continue;
     }
-    if (field->options().ctype() != google::protobuf::FieldOptions::STRING) {
+    if (field->options().ctype() != FieldOptions::STRING) {
       continue;
     }
     EXPECT_EQ(true, r->HasField(message, field));
@@ -314,12 +314,11 @@
   message.Clear();
 
   // Check zero/empty-means-not-present semantics.
-  const google::protobuf::FieldDescriptor* field_int32 = desc->FindFieldByName(
-      "optional_int32");
-  const google::protobuf::FieldDescriptor* field_double = desc->FindFieldByName(
-      "optional_double");
-  const google::protobuf::FieldDescriptor* field_string = desc->FindFieldByName(
-      "optional_string");
+  const FieldDescriptor* field_int32 = desc->FindFieldByName("optional_int32");
+  const FieldDescriptor* field_double =
+      desc->FindFieldByName("optional_double");
+  const FieldDescriptor* field_string =
+      desc->FindFieldByName("optional_string");
 
   EXPECT_EQ(false, r->HasField(message, field_int32));
   EXPECT_EQ(false, r->HasField(message, field_double));
@@ -344,19 +343,18 @@
 TEST(NoFieldPresenceTest, ReflectionClearFieldTest) {
   proto2_nofieldpresence_unittest::TestAllTypes message;
 
-  const google::protobuf::Reflection* r = message.GetReflection();
-  const google::protobuf::Descriptor* desc = message.GetDescriptor();
+  const Reflection* r = message.GetReflection();
+  const Descriptor* desc = message.GetDescriptor();
 
-  const google::protobuf::FieldDescriptor* field_int32 = desc->FindFieldByName(
-      "optional_int32");
-  const google::protobuf::FieldDescriptor* field_double = desc->FindFieldByName(
-      "optional_double");
-  const google::protobuf::FieldDescriptor* field_string = desc->FindFieldByName(
-      "optional_string");
-  const google::protobuf::FieldDescriptor* field_message = desc->FindFieldByName(
-      "optional_nested_message");
-  const google::protobuf::FieldDescriptor* field_lazy = desc->FindFieldByName(
-      "optional_lazy_message");
+  const FieldDescriptor* field_int32 = desc->FindFieldByName("optional_int32");
+  const FieldDescriptor* field_double =
+      desc->FindFieldByName("optional_double");
+  const FieldDescriptor* field_string =
+      desc->FindFieldByName("optional_string");
+  const FieldDescriptor* field_message =
+      desc->FindFieldByName("optional_nested_message");
+  const FieldDescriptor* field_lazy =
+      desc->FindFieldByName("optional_lazy_message");
 
   message.set_optional_int32(42);
   r->ClearField(&message, field_int32);
@@ -385,17 +383,17 @@
   // check that HasField behaves properly for oneofs.
   proto2_nofieldpresence_unittest::TestAllTypes message;
 
-  const google::protobuf::Reflection* r = message.GetReflection();
-  const google::protobuf::Descriptor* desc = message.GetDescriptor();
-  const google::protobuf::FieldDescriptor* desc_oneof_uint32 =
+  const Reflection* r = message.GetReflection();
+  const Descriptor* desc = message.GetDescriptor();
+  const FieldDescriptor* desc_oneof_uint32 =
       desc->FindFieldByName("oneof_uint32");
-  const google::protobuf::FieldDescriptor* desc_oneof_nested_message =
+  const FieldDescriptor* desc_oneof_nested_message =
       desc->FindFieldByName("oneof_nested_message");
-  const google::protobuf::FieldDescriptor* desc_oneof_string =
+  const FieldDescriptor* desc_oneof_string =
       desc->FindFieldByName("oneof_string");
-  GOOGLE_CHECK_NOTNULL(desc_oneof_uint32);
-  GOOGLE_CHECK_NOTNULL(desc_oneof_nested_message);
-  GOOGLE_CHECK_NOTNULL(desc_oneof_string);
+  GOOGLE_CHECK(desc_oneof_uint32 != nullptr);
+  GOOGLE_CHECK(desc_oneof_nested_message != nullptr);
+  GOOGLE_CHECK(desc_oneof_string != nullptr);
 
   EXPECT_EQ(false, r->HasField(message, desc_oneof_uint32));
   EXPECT_EQ(false, r->HasField(message, desc_oneof_nested_message));
@@ -498,11 +496,10 @@
   // Check that has-bit interaction with lazy message works (has-bit before and
   // after lazy decode).
   proto2_nofieldpresence_unittest::TestAllTypes message;
-  const google::protobuf::Reflection* r = message.GetReflection();
-  const google::protobuf::Descriptor* desc = message.GetDescriptor();
-  const google::protobuf::FieldDescriptor* field = desc->FindFieldByName(
-      "optional_lazy_message");
-  GOOGLE_CHECK_NOTNULL(field);
+  const Reflection* r = message.GetReflection();
+  const Descriptor* desc = message.GetDescriptor();
+  const FieldDescriptor* field = desc->FindFieldByName("optional_lazy_message");
+  GOOGLE_CHECK(field != nullptr);
 
   EXPECT_EQ(false, message.has_optional_lazy_message());
   EXPECT_EQ(false, r->HasField(message, field));
@@ -573,5 +570,5 @@
 
 }  // namespace
 }  // namespace protobuf
-
 }  // namespace google
+
diff --git a/src/google/protobuf/package_info.h b/src/google/protobuf/package_info.h
index 935e963..2b61679 100644
--- a/src/google/protobuf/package_info.h
+++ b/src/google/protobuf/package_info.h
@@ -36,8 +36,6 @@
 // It is not compiled into anything, but it may be read by an automated
 // documentation generator.
 
-namespace google {
-
 // Core components of the Protocol Buffers runtime library.
 //
 // The files in this package represent the core of the Protocol Buffer
@@ -60,5 +58,9 @@
 // The implementation does contain some "const" methods which actually modify
 // the object behind the scenes -- e.g., to cache results -- but in these cases
 // mutex locking is used to make the access thread-safe.
-namespace protobuf {}
+namespace google {
+namespace protobuf {
+// TODO(gerbens) remove this comment, we need it to prevent clang-format
+// from combining the brackets. Which would mess with extract script
+}  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/port.h b/src/google/protobuf/port.h
new file mode 100644
index 0000000..6345226
--- /dev/null
+++ b/src/google/protobuf/port.h
@@ -0,0 +1,6 @@
+#ifndef THIRD_PARTY_PROTOBUF_TESTING_PROTOBUF_SRC_GOOGLE_PROTOBUF_PORT_H_
+#define THIRD_PARTY_PROTOBUF_TESTING_PROTOBUF_SRC_GOOGLE_PROTOBUF_PORT_H_
+
+#include <google/protobuf/stubs/port.h>
+
+#endif  // THIRD_PARTY_PROTOBUF_TESTING_PROTOBUF_SRC_GOOGLE_PROTOBUF_PORT_H_
diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc
new file mode 100644
index 0000000..3c119c1
--- /dev/null
+++ b/src/google/protobuf/port_def.inc
@@ -0,0 +1,15 @@
+#if defined(GOOGLE_PROTOBUF_NO_RTTI) && GOOGLE_PROTOBUF_NO_RTTI
+#define GOOGLE_PROTOBUF_RTTI 0
+#else
+#define GOOGLE_PROTOBUF_RTTI 1
+#endif
+#define GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER 0
+
+#define GOOGLE_PROTOBUF_PREDICT_TRUE(x) GOOGLE_PREDICT_TRUE(x)
+#define GOOGLE_PROTOBUF_PREDICT_FALSE(x) GOOGLE_PREDICT_FALSE(x)
+#define GOOGLE_PROTOBUF_DEPRECATED
+#define GOOGLE_PROTOBUF_DEPRECATED_MSG(x)
+#define GOOGLE_PROTOBUF_LONGLONG(x) GOOGLE_LONGLONG(x)
+#define GOOGLE_PROTOBUF_ULONGLONG(x) GOOGLE_ULONGLONG(x)
+
+#define GOOGLE_PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3006000
diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc
new file mode 100644
index 0000000..721241c
--- /dev/null
+++ b/src/google/protobuf/port_undef.inc
@@ -0,0 +1,9 @@
+#undef GOOGLE_PROTOBUF_RTTI
+#undef GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+#undef GOOGLE_PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC
+#undef GOOGLE_PROTOBUF_PREDICT_TRUE
+#undef GOOGLE_PROTOBUF_PREDICT_FALSE
+#undef GOOGLE_PROTOBUF_DEPRECATED
+#undef GOOGLE_PROTOBUF_DEPRECATED_MSG
+#undef GOOGLE_PROTOBUF_LONGLONG
+#undef GOOGLE_PROTOBUF_ULONGLONG
diff --git a/src/google/protobuf/preserve_unknown_enum_test.cc b/src/google/protobuf/preserve_unknown_enum_test.cc
index e292199..71826c3 100644
--- a/src/google/protobuf/preserve_unknown_enum_test.cc
+++ b/src/google/protobuf/preserve_unknown_enum_test.cc
@@ -119,9 +119,12 @@
   FillMessage(&orig_message);
   string serialized = orig_message.SerializeAsString();
 
-  google::protobuf::DynamicMessageFactory factory;
-  std::unique_ptr<google::protobuf::Message> message(factory.GetPrototype(
-      proto3_preserve_unknown_enum_unittest::MyMessage::descriptor())->New());
+  DynamicMessageFactory factory;
+  std::unique_ptr<Message> message(
+      factory
+          .GetPrototype(
+              proto3_preserve_unknown_enum_unittest::MyMessage::descriptor())
+          ->New());
   EXPECT_EQ(true, message->ParseFromString(serialized));
   message->DiscardUnknownFields();
 
@@ -160,9 +163,12 @@
   string serialized;
   orig_message.SerializeToString(&serialized);
 
-  google::protobuf::DynamicMessageFactory factory;
-  std::unique_ptr<google::protobuf::Message> message(factory.GetPrototype(
-      proto2_preserve_unknown_enum_unittest::MyMessage::descriptor())->New());
+  DynamicMessageFactory factory;
+  std::unique_ptr<Message> message(
+      factory
+          .GetPrototype(
+              proto2_preserve_unknown_enum_unittest::MyMessage::descriptor())
+          ->New());
   EXPECT_EQ(true, message->ParseFromString(serialized));
   // The intermediate message has everything in its "unknown fields".
   proto2_preserve_unknown_enum_unittest::MyMessage message2;
@@ -188,23 +194,21 @@
   EXPECT_EQ(true, message.ParseFromString(serialized));
   CheckMessage(message);
 
-  const google::protobuf::Reflection* r = message.GetReflection();
-  const google::protobuf::Descriptor* d = message.GetDescriptor();
-  const google::protobuf::FieldDescriptor* field = d->FindFieldByName("e");
+  const Reflection* r = message.GetReflection();
+  const Descriptor* d = message.GetDescriptor();
+  const FieldDescriptor* field = d->FindFieldByName("e");
 
   // This should dynamically create an EnumValueDescriptor.
-  const google::protobuf::EnumValueDescriptor* enum_value = r->GetEnum(message, field);
+  const EnumValueDescriptor* enum_value = r->GetEnum(message, field);
   EXPECT_EQ(enum_value->number(),
             static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA));
 
   // Fetching value for a second time should return the same pointer.
-  const google::protobuf::EnumValueDescriptor* enum_value_second =
-      r->GetEnum(message, field);
+  const EnumValueDescriptor* enum_value_second = r->GetEnum(message, field);
   EXPECT_EQ(enum_value, enum_value_second);
 
   // Check the repeated case too.
-  const google::protobuf::FieldDescriptor* repeated_field =
-      d->FindFieldByName("repeated_e");
+  const FieldDescriptor* repeated_field = d->FindFieldByName("repeated_e");
   enum_value = r->GetRepeatedEnum(message, repeated_field, 0);
   EXPECT_EQ(enum_value->number(),
             static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA));
@@ -213,7 +217,7 @@
 
   // We should be able to use the returned value descriptor to set a value on
   // another message.
-  google::protobuf::Message* m = message.New();
+  Message* m = message.New();
   r->SetEnum(m, field, enum_value);
   EXPECT_EQ(enum_value, r->GetEnum(*m, field));
   delete m;
@@ -222,12 +226,11 @@
 // Test that the new integer-based enum reflection API works.
 TEST(PreserveUnknownEnumTest, IntegerEnumReflectionAPI) {
   proto3_preserve_unknown_enum_unittest::MyMessage message;
-  const google::protobuf::Reflection* r = message.GetReflection();
-  const google::protobuf::Descriptor* d = message.GetDescriptor();
+  const Reflection* r = message.GetReflection();
+  const Descriptor* d = message.GetDescriptor();
 
-  const google::protobuf::FieldDescriptor* singular_field = d->FindFieldByName("e");
-  const google::protobuf::FieldDescriptor* repeated_field =
-      d->FindFieldByName("repeated_e");
+  const FieldDescriptor* singular_field = d->FindFieldByName("e");
+  const FieldDescriptor* repeated_field = d->FindFieldByName("repeated_e");
 
   r->SetEnumValue(&message, singular_field, 42);
   EXPECT_EQ(42, r->GetEnumValue(message, singular_field));
@@ -236,51 +239,58 @@
   EXPECT_EQ(42, r->GetRepeatedEnumValue(message, repeated_field, 0));
   r->SetRepeatedEnumValue(&message, repeated_field, 1, 84);
   EXPECT_EQ(84, r->GetRepeatedEnumValue(message, repeated_field, 1));
-  const google::protobuf::EnumValueDescriptor* enum_value = r->GetEnum(message,
-                                                             singular_field);
+  const EnumValueDescriptor* enum_value = r->GetEnum(message, singular_field);
   EXPECT_EQ(42, enum_value->number());
 }
 
 // Test that the EnumValue API works properly for proto2 messages as well.
 TEST(PreserveUnknownEnumTest, Proto2CatchesUnknownValues) {
   protobuf_unittest::TestAllTypes message;  // proto2 message
-  const google::protobuf::Reflection* r = message.GetReflection();
-  const google::protobuf::Descriptor* d = message.GetDescriptor();
-  const google::protobuf::FieldDescriptor* repeated_field =
+  const Reflection* r = message.GetReflection();
+  const Descriptor* d = message.GetDescriptor();
+  const FieldDescriptor* repeated_field =
       d->FindFieldByName("repeated_nested_enum");
   // Add one element to the repeated field so that we can test
   // SetRepeatedEnumValue.
-  const google::protobuf::EnumValueDescriptor* enum_value =
+  const EnumValueDescriptor* enum_value =
       repeated_field->enum_type()->FindValueByName("BAR");
   EXPECT_TRUE(enum_value != NULL);
   r->AddEnum(&message, repeated_field, enum_value);
 
-#ifdef PROTOBUF_HAS_DEATH_TEST
-  const google::protobuf::FieldDescriptor* singular_field =
+  const FieldDescriptor* singular_field =
       d->FindFieldByName("optional_nested_enum");
-  // Enum-field integer-based setters GOOGLE_DCHECK-fail on invalid values, in order to
-  // remain consistent with proto2 generated code.
-  EXPECT_DEBUG_DEATH({
-    r->SetEnumValue(&message, singular_field, 4242);
-    r->GetEnum(message, singular_field)->number();
-  }, "SetEnumValue accepts only valid integer values");
-  EXPECT_DEBUG_DEATH({
-    r->SetRepeatedEnumValue(&message, repeated_field, 0, 4242);
-    r->GetRepeatedEnum(message, repeated_field, 0);
-  }, "SetRepeatedEnumValue accepts only valid integer values");
-  EXPECT_DEBUG_DEATH({
-    r->AddEnumValue(&message, repeated_field, 4242);
-    r->GetRepeatedEnum(message, repeated_field, 1);
-  }, "AddEnumValue accepts only valid integer values");
-#endif  // PROTOBUF_HAS_DEATH_TEST
+  // Enum-field integer-based setters treat as unknown integer values as
+  // unknown fields.
+  r->SetEnumValue(&message, singular_field, 4242);
+  EXPECT_EQ(r->GetEnum(message, singular_field)->number(),
+            protobuf_unittest::TestAllTypes::FOO);
+  r->SetRepeatedEnumValue(&message, repeated_field, 0, 4242);
+  // repeated_nested_enum was set to bar above, this should not have changed.
+  EXPECT_EQ(r->GetRepeatedEnum(message, repeated_field, 0)->number(),
+            protobuf_unittest::TestAllTypes::BAR);
+  r->AddEnumValue(&message, repeated_field, 4242);
+  // No element should be added
+  EXPECT_EQ(message.repeated_nested_enum_size(), 1);
+
+  // We require the enums to end up in unknown field set
+  ASSERT_EQ(message.unknown_fields().field_count(), 3);
+  EXPECT_EQ(message.unknown_fields().field(0).number(),
+            singular_field->number());
+  EXPECT_EQ(message.unknown_fields().field(0).varint(), 4242);
+  EXPECT_EQ(message.unknown_fields().field(1).number(),
+            repeated_field->number());
+  EXPECT_EQ(message.unknown_fields().field(1).varint(), 4242);
+  EXPECT_EQ(message.unknown_fields().field(2).number(),
+            repeated_field->number());
+  EXPECT_EQ(message.unknown_fields().field(2).varint(), 4242);
 }
 
 TEST(PreserveUnknownEnumTest, SupportsUnknownEnumValuesAPI) {
   protobuf_unittest::TestAllTypes proto2_message;
   proto3_preserve_unknown_enum_unittest::MyMessage new_message;
 
-  const google::protobuf::Reflection* proto2_reflection = proto2_message.GetReflection();
-  const google::protobuf::Reflection* new_reflection = new_message.GetReflection();
+  const Reflection* proto2_reflection = proto2_message.GetReflection();
+  const Reflection* new_reflection = new_message.GetReflection();
 
   EXPECT_FALSE(proto2_reflection->SupportsUnknownEnumValues());
   EXPECT_TRUE(new_reflection->SupportsUnknownEnumValues());
diff --git a/src/google/protobuf/proto3_arena_lite_unittest.cc b/src/google/protobuf/proto3_arena_lite_unittest.cc
index 2ac775d..6d2abf6 100644
--- a/src/google/protobuf/proto3_arena_lite_unittest.cc
+++ b/src/google/protobuf/proto3_arena_lite_unittest.cc
@@ -37,9 +37,9 @@
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 
-namespace google {
 using proto3_arena_unittest::TestAllTypes;
 
+namespace google {
 namespace protobuf {
 namespace {
 // We selectively set/check a few representative fields rather than all fields
diff --git a/src/google/protobuf/proto3_arena_unittest.cc b/src/google/protobuf/proto3_arena_unittest.cc
index dac7378..3091aa0 100644
--- a/src/google/protobuf/proto3_arena_unittest.cc
+++ b/src/google/protobuf/proto3_arena_unittest.cc
@@ -39,9 +39,9 @@
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 
-namespace google {
 using proto3_arena_unittest::TestAllTypes;
 
+namespace google {
 namespace protobuf {
 namespace {
 // We selectively set/check a few representative fields rather than all fields
@@ -126,30 +126,7 @@
   ExpectAllFieldsSet(*arena_message);
 }
 
-TEST(Proto3ArenaTest, UnknownFieldsDefaultDrop) {
-  ::google::protobuf::internal::SetProto3PreserveUnknownsDefault(false);
-  TestAllTypes original;
-  SetAllFields(&original);
-
-  Arena arena;
-  TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
-  arena_message->ParseFromString(original.SerializeAsString());
-  ExpectAllFieldsSet(*arena_message);
-
-  // In proto3 we can still get a pointer to the UnknownFieldSet through
-  // reflection API.
-  UnknownFieldSet* unknown_fields =
-      arena_message->GetReflection()->MutableUnknownFields(arena_message);
-  // We can modify this UnknownFieldSet.
-  unknown_fields->AddVarint(1, 2);
-  // But the change will never will serialized back.
-  ASSERT_EQ(original.ByteSize(), arena_message->ByteSize());
-  ASSERT_TRUE(
-      arena_message->GetReflection()->GetUnknownFields(*arena_message).empty());
-}
-
-TEST(Proto3ArenaTest, UnknownFieldsDefaultPreserve) {
-  ::google::protobuf::internal::SetProto3PreserveUnknownsDefault(true);
+TEST(Proto3ArenaTest, UnknownFields) {
   TestAllTypes original;
   SetAllFields(&original);
 
diff --git a/src/google/protobuf/proto3_lite_unittest.cc b/src/google/protobuf/proto3_lite_unittest.cc
index 8b2c574..abeeedb 100644
--- a/src/google/protobuf/proto3_lite_unittest.cc
+++ b/src/google/protobuf/proto3_lite_unittest.cc
@@ -28,113 +28,16 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include <string>
-#include <memory>
-#include <vector>
+#include <google/protobuf/unittest_proto3.pb.h>
 
-#include <google/protobuf/unittest_proto3_lite.pb.h>
-#include <google/protobuf/arena.h>
-#include <google/protobuf/testing/googletest.h>
-#include <gtest/gtest.h>
+#define LITE_TEST_NAME Proto3LiteTest
+#define UNITTEST ::proto3_unittest
 
+// Must include after the above macros.
+#include <google/protobuf/proto3_lite_unittest.inc>
+
+// Make extract script happy.
 namespace google {
-using proto3_lite_unittest::TestAllTypes;
-
 namespace protobuf {
-namespace {
-// We selectively set/check a few representative fields rather than all fields
-// as this test is only expected to cover the basics of lite support.
-void SetAllFields(TestAllTypes* m) {
-  m->set_optional_int32(100);
-  m->set_optional_string("asdf");
-  m->set_optional_bytes("jkl;");
-  m->mutable_optional_nested_message()->set_bb(42);
-  m->mutable_optional_foreign_message()->set_c(43);
-  m->set_optional_nested_enum(
-      proto3_lite_unittest::TestAllTypes_NestedEnum_BAZ);
-  m->set_optional_foreign_enum(
-      proto3_lite_unittest::FOREIGN_BAZ);
-  m->mutable_optional_lazy_message()->set_bb(45);
-  m->add_repeated_int32(100);
-  m->add_repeated_string("asdf");
-  m->add_repeated_bytes("jkl;");
-  m->add_repeated_nested_message()->set_bb(46);
-  m->add_repeated_foreign_message()->set_c(47);
-  m->add_repeated_nested_enum(
-      proto3_lite_unittest::TestAllTypes_NestedEnum_BAZ);
-  m->add_repeated_foreign_enum(
-      proto3_lite_unittest::FOREIGN_BAZ);
-  m->add_repeated_lazy_message()->set_bb(49);
-
-  m->set_oneof_uint32(1);
-  m->mutable_oneof_nested_message()->set_bb(50);
-  m->set_oneof_string("test");  // only this one remains set
-}
-
-void ExpectAllFieldsSet(const TestAllTypes& m) {
-  EXPECT_EQ(100, m.optional_int32());
-  EXPECT_EQ("asdf", m.optional_string());
-  EXPECT_EQ("jkl;", m.optional_bytes());
-  EXPECT_EQ(true, m.has_optional_nested_message());
-  EXPECT_EQ(42, m.optional_nested_message().bb());
-  EXPECT_EQ(true, m.has_optional_foreign_message());
-  EXPECT_EQ(43, m.optional_foreign_message().c());
-  EXPECT_EQ(proto3_lite_unittest::TestAllTypes_NestedEnum_BAZ,
-            m.optional_nested_enum());
-  EXPECT_EQ(proto3_lite_unittest::FOREIGN_BAZ,
-            m.optional_foreign_enum());
-  EXPECT_EQ(true, m.has_optional_lazy_message());
-  EXPECT_EQ(45, m.optional_lazy_message().bb());
-
-  EXPECT_EQ(1, m.repeated_int32_size());
-  EXPECT_EQ(100, m.repeated_int32(0));
-  EXPECT_EQ(1, m.repeated_string_size());
-  EXPECT_EQ("asdf", m.repeated_string(0));
-  EXPECT_EQ(1, m.repeated_bytes_size());
-  EXPECT_EQ("jkl;", m.repeated_bytes(0));
-  EXPECT_EQ(1, m.repeated_nested_message_size());
-  EXPECT_EQ(46, m.repeated_nested_message(0).bb());
-  EXPECT_EQ(1, m.repeated_foreign_message_size());
-  EXPECT_EQ(47, m.repeated_foreign_message(0).c());
-  EXPECT_EQ(1, m.repeated_nested_enum_size());
-  EXPECT_EQ(proto3_lite_unittest::TestAllTypes_NestedEnum_BAZ,
-            m.repeated_nested_enum(0));
-  EXPECT_EQ(1, m.repeated_foreign_enum_size());
-  EXPECT_EQ(proto3_lite_unittest::FOREIGN_BAZ,
-            m.repeated_foreign_enum(0));
-  EXPECT_EQ(1, m.repeated_lazy_message_size());
-  EXPECT_EQ(49, m.repeated_lazy_message(0).bb());
-
-  EXPECT_EQ(proto3_lite_unittest::TestAllTypes::kOneofString,
-            m.oneof_field_case());
-  EXPECT_EQ("test", m.oneof_string());
-}
-
-// In this file we only test some basic functionalities of in proto3 and expect
-// the rest is fully tested in proto2 unittests because proto3 shares most code
-// with proto2.
-
-TEST(Proto3LiteTest, Parsing) {
-  TestAllTypes original;
-  SetAllFields(&original);
-
-  TestAllTypes msg;
-  msg.ParseFromString(original.SerializeAsString());
-  ExpectAllFieldsSet(msg);
-}
-
-TEST(Proto3LiteTest, Swap) {
-  // Test Swap().
-  TestAllTypes msg1;
-  TestAllTypes msg2;
-  msg1.set_optional_string("123");
-  msg2.set_optional_string("3456");
-  msg1.Swap(&msg2);
-  EXPECT_EQ("3456", msg1.optional_string());
-  EXPECT_EQ("123", msg2.optional_string());
-  EXPECT_EQ(msg1.ByteSize(), msg2.ByteSize() + 1);
-}
-
-}  // namespace
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/proto3_lite_unittest.inc b/src/google/protobuf/proto3_lite_unittest.inc
new file mode 100644
index 0000000..eca9b70
--- /dev/null
+++ b/src/google/protobuf/proto3_lite_unittest.inc
@@ -0,0 +1,139 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <string>
+#include <memory>
+#include <vector>
+
+#include <google/protobuf/arena.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+using UNITTEST::TestAllTypes;
+
+namespace google {
+namespace protobuf {
+namespace {
+// We selectively set/check a few representative fields rather than all fields
+// as this test is only expected to cover the basics of lite support.
+void SetAllFields(TestAllTypes* m) {
+  m->set_optional_int32(100);
+  m->set_optional_string("asdf");
+  m->set_optional_bytes("jkl;");
+  m->mutable_optional_nested_message()->set_bb(42);
+  m->mutable_optional_foreign_message()->set_c(43);
+  m->set_optional_nested_enum(
+      UNITTEST::TestAllTypes_NestedEnum_BAZ);
+  m->set_optional_foreign_enum(
+      UNITTEST::FOREIGN_BAZ);
+  m->mutable_optional_lazy_message()->set_bb(45);
+  m->add_repeated_int32(100);
+  m->add_repeated_string("asdf");
+  m->add_repeated_bytes("jkl;");
+  m->add_repeated_nested_message()->set_bb(46);
+  m->add_repeated_foreign_message()->set_c(47);
+  m->add_repeated_nested_enum(
+      UNITTEST::TestAllTypes_NestedEnum_BAZ);
+  m->add_repeated_foreign_enum(
+      UNITTEST::FOREIGN_BAZ);
+  m->add_repeated_lazy_message()->set_bb(49);
+
+  m->set_oneof_uint32(1);
+  m->mutable_oneof_nested_message()->set_bb(50);
+  m->set_oneof_string("test");  // only this one remains set
+}
+
+void ExpectAllFieldsSet(const TestAllTypes& m) {
+  EXPECT_EQ(100, m.optional_int32());
+  EXPECT_EQ("asdf", m.optional_string());
+  EXPECT_EQ("jkl;", m.optional_bytes());
+  EXPECT_EQ(true, m.has_optional_nested_message());
+  EXPECT_EQ(42, m.optional_nested_message().bb());
+  EXPECT_EQ(true, m.has_optional_foreign_message());
+  EXPECT_EQ(43, m.optional_foreign_message().c());
+  EXPECT_EQ(UNITTEST::TestAllTypes_NestedEnum_BAZ,
+            m.optional_nested_enum());
+  EXPECT_EQ(UNITTEST::FOREIGN_BAZ,
+            m.optional_foreign_enum());
+  EXPECT_EQ(true, m.has_optional_lazy_message());
+  EXPECT_EQ(45, m.optional_lazy_message().bb());
+
+  EXPECT_EQ(1, m.repeated_int32_size());
+  EXPECT_EQ(100, m.repeated_int32(0));
+  EXPECT_EQ(1, m.repeated_string_size());
+  EXPECT_EQ("asdf", m.repeated_string(0));
+  EXPECT_EQ(1, m.repeated_bytes_size());
+  EXPECT_EQ("jkl;", m.repeated_bytes(0));
+  EXPECT_EQ(1, m.repeated_nested_message_size());
+  EXPECT_EQ(46, m.repeated_nested_message(0).bb());
+  EXPECT_EQ(1, m.repeated_foreign_message_size());
+  EXPECT_EQ(47, m.repeated_foreign_message(0).c());
+  EXPECT_EQ(1, m.repeated_nested_enum_size());
+  EXPECT_EQ(UNITTEST::TestAllTypes_NestedEnum_BAZ,
+            m.repeated_nested_enum(0));
+  EXPECT_EQ(1, m.repeated_foreign_enum_size());
+  EXPECT_EQ(UNITTEST::FOREIGN_BAZ,
+            m.repeated_foreign_enum(0));
+  EXPECT_EQ(1, m.repeated_lazy_message_size());
+  EXPECT_EQ(49, m.repeated_lazy_message(0).bb());
+
+  EXPECT_EQ(UNITTEST::TestAllTypes::kOneofString,
+            m.oneof_field_case());
+  EXPECT_EQ("test", m.oneof_string());
+}
+
+// In this file we only test some basic functionalities of in proto3 and expect
+// the rest is fully tested in proto2 unittests because proto3 shares most code
+// with proto2.
+
+TEST(LITE_TEST_NAME, Parsing) {
+  TestAllTypes original;
+  SetAllFields(&original);
+
+  TestAllTypes msg;
+  msg.ParseFromString(original.SerializeAsString());
+  ExpectAllFieldsSet(msg);
+}
+
+TEST(LITE_TEST_NAME, Swap) {
+  // Test Swap().
+  TestAllTypes msg1;
+  TestAllTypes msg2;
+  msg1.set_optional_string("123");
+  msg2.set_optional_string("3456");
+  msg1.Swap(&msg2);
+  EXPECT_EQ("3456", msg1.optional_string());
+  EXPECT_EQ("123", msg2.optional_string());
+  EXPECT_EQ(msg1.ByteSize(), msg2.ByteSize() + 1);
+}
+
+}  // namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h
index 5d0fc42..c14a896 100644
--- a/src/google/protobuf/reflection.h
+++ b/src/google/protobuf/reflection.h
@@ -38,6 +38,10 @@
 #include <google/protobuf/message.h>
 #include <google/protobuf/generated_enum_util.h>
 
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 namespace internal {
@@ -347,7 +351,6 @@
   typedef void Value;
   typedef void Iterator;
 
-  virtual ~RepeatedFieldAccessor();
   virtual bool IsEmpty(const Field* data) const = 0;
   virtual int Size(const Field* data) const = 0;
   // Depends on the underlying representation of the repeated field, this
@@ -425,6 +428,13 @@
     ActualType tmp = static_cast<ActualType>(value);
     Add(data, static_cast<const Value*>(&tmp));
   }
+
+ protected:
+  // We want the destructor to be completely trivial as to allow it to be
+  // a function local static. Hence we make it non-virtual and protected,
+  // this class only live as part of a global singleton and should not be
+  // deleted.
+  ~RepeatedFieldAccessor() = default;
 };
 
 // Implement (Mutable)RepeatedFieldRef::iterator
diff --git a/src/google/protobuf/reflection_internal.h b/src/google/protobuf/reflection_internal.h
index 840d611..f664d8e 100644
--- a/src/google/protobuf/reflection_internal.h
+++ b/src/google/protobuf/reflection_internal.h
@@ -43,36 +43,34 @@
 // corresponding random-access methods.
 class RandomAccessRepeatedFieldAccessor : public RepeatedFieldAccessor {
  public:
-  virtual ~RandomAccessRepeatedFieldAccessor() override {}
-
-  virtual Iterator* BeginIterator(const Field* data) const override {
+  Iterator* BeginIterator(const Field* data) const override {
     return PositionToIterator(0);
   }
-  virtual Iterator* EndIterator(const Field* data) const override {
+  Iterator* EndIterator(const Field* data) const override {
     return PositionToIterator(this->Size(data));
   }
-  virtual Iterator* CopyIterator(const Field* data,
+  Iterator* CopyIterator(const Field* data,
                          const Iterator* iterator) const override {
     return const_cast<Iterator*>(iterator);
   }
-  virtual Iterator* AdvanceIterator(const Field* data,
+  Iterator* AdvanceIterator(const Field* data,
                             Iterator* iterator) const override {
     return PositionToIterator(IteratorToPosition(iterator) + 1);
   }
-  virtual bool EqualsIterator(const Field* data,
-                      const Iterator* a,
+  bool EqualsIterator(const Field* data, const Iterator* a,
                       const Iterator* b) const override {
     return a == b;
   }
-  virtual void DeleteIterator(const Field* data, Iterator* iterator) const override {
-  }
-  virtual const Value* GetIteratorValue(const Field* data,
-                                const Iterator* iterator,
+  void DeleteIterator(const Field* data, Iterator* iterator) const override {}
+  const Value* GetIteratorValue(const Field* data, const Iterator* iterator,
                                 Value* scratch_space) const override {
     return Get(data, static_cast<int>(IteratorToPosition(iterator)),
                scratch_space);
   }
 
+ protected:
+  ~RandomAccessRepeatedFieldAccessor() = default;
+
  private:
   static intptr_t IteratorToPosition(const Iterator* iterator) {
     return reinterpret_cast<intptr_t>(iterator);
@@ -88,34 +86,34 @@
 class RepeatedFieldWrapper : public RandomAccessRepeatedFieldAccessor {
  public:
   RepeatedFieldWrapper() {}
-  virtual ~RepeatedFieldWrapper() override {}
-  virtual bool IsEmpty(const Field* data) const override {
+  bool IsEmpty(const Field* data) const override {
     return GetRepeatedField(data)->empty();
   }
-  virtual int Size(const Field* data) const override {
+  int Size(const Field* data) const override {
     return GetRepeatedField(data)->size();
   }
-  virtual const Value* Get(const Field* data, int index,
+  const Value* Get(const Field* data, int index,
                    Value* scratch_space) const override {
     return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space);
   }
-  virtual void Clear(Field* data) const override {
+  void Clear(Field* data) const override {
     MutableRepeatedField(data)->Clear();
   }
-  virtual void Set(Field* data, int index, const Value* value) const override {
+  void Set(Field* data, int index, const Value* value) const override {
     MutableRepeatedField(data)->Set(index, ConvertToT(value));
   }
-  virtual void Add(Field* data, const Value* value) const override {
+  void Add(Field* data, const Value* value) const override {
     MutableRepeatedField(data)->Add(ConvertToT(value));
   }
-  virtual void RemoveLast(Field* data) const override {
+  void RemoveLast(Field* data) const override {
     MutableRepeatedField(data)->RemoveLast();
   }
-  virtual void SwapElements(Field* data, int index1, int index2) const override {
+  void SwapElements(Field* data, int index1, int index2) const override {
     MutableRepeatedField(data)->SwapElements(index1, index2);
   }
 
  protected:
+  ~RepeatedFieldWrapper() = default;
   typedef RepeatedField<T> RepeatedFieldType;
   static const RepeatedFieldType* GetRepeatedField(const Field* data) {
     return reinterpret_cast<const RepeatedFieldType*>(data);
@@ -142,37 +140,36 @@
 template<typename T>
 class RepeatedPtrFieldWrapper : public RandomAccessRepeatedFieldAccessor {
  public:
-  RepeatedPtrFieldWrapper() {}
-  virtual ~RepeatedPtrFieldWrapper() {}
-  virtual bool IsEmpty(const Field* data) const override {
+  bool IsEmpty(const Field* data) const override {
     return GetRepeatedField(data)->empty();
   }
-  virtual int Size(const Field* data) const override {
+  int Size(const Field* data) const override {
     return GetRepeatedField(data)->size();
   }
-  virtual const Value* Get(const Field* data, int index,
+  const Value* Get(const Field* data, int index,
                    Value* scratch_space) const override {
     return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space);
   }
-  virtual void Clear(Field* data) const override {
+  void Clear(Field* data) const override {
     MutableRepeatedField(data)->Clear();
   }
-  virtual void Set(Field* data, int index, const Value* value) const override {
+  void Set(Field* data, int index, const Value* value) const override {
     ConvertToT(value, MutableRepeatedField(data)->Mutable(index));
   }
-  virtual void Add(Field* data, const Value* value) const override {
+  void Add(Field* data, const Value* value) const override {
     T* allocated = New(value);
     ConvertToT(value, allocated);
     MutableRepeatedField(data)->AddAllocated(allocated);
   }
-  virtual void RemoveLast(Field* data) const override {
+  void RemoveLast(Field* data) const override {
     MutableRepeatedField(data)->RemoveLast();
   }
-  virtual void SwapElements(Field* data, int index1, int index2) const override {
+  void SwapElements(Field* data, int index1, int index2) const override {
     MutableRepeatedField(data)->SwapElements(index1, index2);
   }
 
  protected:
+  ~RepeatedPtrFieldWrapper() = default;
   typedef RepeatedPtrField<T> RepeatedFieldType;
   static const RepeatedFieldType* GetRepeatedField(const Field* data) {
     return reinterpret_cast<const RepeatedFieldType*>(data);
@@ -202,41 +199,39 @@
 
 // An implementation of RandomAccessRepeatedFieldAccessor that manipulates
 // MapFieldBase.
-class MapFieldAccessor : public RandomAccessRepeatedFieldAccessor {
+class MapFieldAccessor final : public RandomAccessRepeatedFieldAccessor {
  public:
   MapFieldAccessor() {}
-  virtual ~MapFieldAccessor() override {}
-  virtual bool IsEmpty(const Field* data) const override {
+  virtual ~MapFieldAccessor() {}
+  virtual bool IsEmpty(const Field* data) const {
     return GetRepeatedField(data)->empty();
   }
-  virtual int Size(const Field* data) const override {
+  int Size(const Field* data) const override {
     return GetRepeatedField(data)->size();
   }
-  virtual const Value* Get(const Field* data, int index,
+  const Value* Get(const Field* data, int index,
                    Value* scratch_space) const override {
     return ConvertFromEntry(GetRepeatedField(data)->Get(index), scratch_space);
   }
-  virtual void Clear(Field* data) const override {
+  void Clear(Field* data) const override {
     MutableRepeatedField(data)->Clear();
   }
-  virtual void Set(Field* data, int index, const Value* value) const override {
+  void Set(Field* data, int index, const Value* value) const override {
     ConvertToEntry(value, MutableRepeatedField(data)->Mutable(index));
   }
-  virtual void Add(Field* data, const Value* value) const override {
+  void Add(Field* data, const Value* value) const override {
     Message* allocated = New(value);
     ConvertToEntry(value, allocated);
     MutableRepeatedField(data)->AddAllocated(allocated);
   }
-  virtual void RemoveLast(Field* data) const override {
+  void RemoveLast(Field* data) const override {
     MutableRepeatedField(data)->RemoveLast();
   }
-  virtual void SwapElements(Field* data, int index1, int index2) const override {
+  void SwapElements(Field* data, int index1, int index2) const override {
     MutableRepeatedField(data)->SwapElements(index1, index2);
   }
-  virtual void Swap(
-      Field* data,
-      const internal::RepeatedFieldAccessor* other_mutator,
-      Field* other_data) const override {
+  void Swap(Field* data, const internal::RepeatedFieldAccessor* other_mutator,
+            Field* other_data) const override {
     GOOGLE_CHECK(this == other_mutator);
     MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
   }
@@ -268,19 +263,16 @@
 };
 
 // Default implementations of RepeatedFieldAccessor for primitive types.
-template<typename T>
-class RepeatedFieldPrimitiveAccessor : public RepeatedFieldWrapper<T> {
+template <typename T>
+class RepeatedFieldPrimitiveAccessor final : public RepeatedFieldWrapper<T> {
   typedef void Field;
   typedef void Value;
   using RepeatedFieldWrapper<T>::MutableRepeatedField;
 
  public:
   RepeatedFieldPrimitiveAccessor() {}
-  virtual ~RepeatedFieldPrimitiveAccessor() override {}
-  virtual void Swap(
-      Field* data,
-      const internal::RepeatedFieldAccessor* other_mutator,
-      Field* other_data) const override {
+  void Swap(Field* data, const internal::RepeatedFieldAccessor* other_mutator,
+            Field* other_data) const override {
     // Currently RepeatedFieldPrimitiveAccessor is the only implementation of
     // RepeatedFieldAccessor for primitive types. As we are using singletons
     // for these accessors, here "other_mutator" must be "this".
@@ -289,10 +281,10 @@
   }
 
  protected:
-  virtual T ConvertToT(const Value* value) const override {
+  T ConvertToT(const Value* value) const override {
     return *static_cast<const T*>(value);
   }
-  virtual const Value* ConvertFromT(const T& value,
+  const Value* ConvertFromT(const T& value,
                             Value* scratch_space) const override {
     return static_cast<const Value*>(&value);
   }
@@ -300,18 +292,16 @@
 
 // Default implementation of RepeatedFieldAccessor for string fields with
 // ctype=STRING.
-class RepeatedPtrFieldStringAccessor : public RepeatedPtrFieldWrapper<string> {
+class RepeatedPtrFieldStringAccessor final
+    : public RepeatedPtrFieldWrapper<string> {
   typedef void Field;
   typedef void Value;
   using RepeatedFieldAccessor::Add;
 
  public:
   RepeatedPtrFieldStringAccessor() {}
-  virtual ~RepeatedPtrFieldStringAccessor() override {}
-  virtual void Swap(
-      Field* data,
-      const internal::RepeatedFieldAccessor* other_mutator,
-      Field* other_data) const override {
+  void Swap(Field* data, const internal::RepeatedFieldAccessor* other_mutator,
+            Field* other_data) const override {
     if (this == other_mutator) {
       MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
     } else {
@@ -330,49 +320,44 @@
   }
 
  protected:
-  virtual string* New(const Value*) const override {
-    return new string();
-  }
-  virtual void ConvertToT(const Value* value, string* result) const override {
+  string* New(const Value*) const override { return new string(); }
+  void ConvertToT(const Value* value, string* result) const override {
     *result = *static_cast<const string*>(value);
   }
-  virtual const Value* ConvertFromT(const string& value,
+  const Value* ConvertFromT(const string& value,
                             Value* scratch_space) const override {
     return static_cast<const Value*>(&value);
   }
 };
 
 
-class RepeatedPtrFieldMessageAccessor
+class RepeatedPtrFieldMessageAccessor final
     : public RepeatedPtrFieldWrapper<Message> {
   typedef void Field;
   typedef void Value;
 
  public:
   RepeatedPtrFieldMessageAccessor() {}
-  virtual ~RepeatedPtrFieldMessageAccessor() override {}
-  virtual void Swap(
-      Field* data,
-      const internal::RepeatedFieldAccessor* other_mutator,
-      Field* other_data) const override {
+  void Swap(Field* data, const internal::RepeatedFieldAccessor* other_mutator,
+            Field* other_data) const override {
     GOOGLE_CHECK(this == other_mutator);
     MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
   }
 
  protected:
-  virtual Message* New(const Value* value) const override {
+  Message* New(const Value* value) const override {
     return static_cast<const Message*>(value)->New();
   }
-  virtual void ConvertToT(const Value* value, Message* result) const override {
+  void ConvertToT(const Value* value, Message* result) const override {
     result->CopyFrom(*static_cast<const Message*>(value));
   }
-  virtual const Value* ConvertFromT(const Message& value,
+  const Value* ConvertFromT(const Message& value,
                             Value* scratch_space) const override {
     return static_cast<const Value*>(&value);
   }
 };
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_REFLECTION_INTERNAL_H__
diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc
index 3cd5034..f028b2b 100644
--- a/src/google/protobuf/reflection_ops.cc
+++ b/src/google/protobuf/reflection_ops.cc
@@ -41,6 +41,7 @@
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/map_field.h>
+#include <google/protobuf/map_field_inl.h>
 #include <google/protobuf/unknown_field_set.h>
 #include <google/protobuf/stubs/strutil.h>
 
diff --git a/src/google/protobuf/reflection_ops.h b/src/google/protobuf/reflection_ops.h
index 45d8c65..78666f3 100644
--- a/src/google/protobuf/reflection_ops.h
+++ b/src/google/protobuf/reflection_ops.h
@@ -41,6 +41,10 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/message.h>
 
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 namespace internal {
@@ -76,6 +80,6 @@
 
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_REFLECTION_OPS_H__
diff --git a/src/google/protobuf/repeated_field.cc b/src/google/protobuf/repeated_field.cc
index 310000a..89d70a7 100644
--- a/src/google/protobuf/repeated_field.cc
+++ b/src/google/protobuf/repeated_field.cc
@@ -62,8 +62,7 @@
   if (arena == NULL) {
     rep_ = reinterpret_cast<Rep*>(::operator new(bytes));
   } else {
-    rep_ = reinterpret_cast<Rep*>(
-        ::google::protobuf::Arena::CreateArray<char>(arena, bytes));
+    rep_ = reinterpret_cast<Rep*>(Arena::CreateArray<char>(arena, bytes));
   }
 #if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
   const int old_total_size = total_size_;
@@ -103,18 +102,17 @@
   rep_->allocated_size -= num;
 }
 
-google::protobuf::MessageLite* RepeatedPtrFieldBase::AddWeak(
-    const google::protobuf::MessageLite* prototype) {
+MessageLite* RepeatedPtrFieldBase::AddWeak(const MessageLite* prototype) {
   if (rep_ != NULL && current_size_ < rep_->allocated_size) {
-    return reinterpret_cast<google::protobuf::MessageLite*>(
-        rep_->elements[current_size_++]);
+    return reinterpret_cast<MessageLite*>(rep_->elements[current_size_++]);
   }
   if (!rep_ || rep_->allocated_size == total_size_) {
     Reserve(total_size_ + 1);
   }
   ++rep_->allocated_size;
-  google::protobuf::MessageLite* result = prototype ? prototype->New(arena_) :
-      Arena::CreateMessage<ImplicitWeakMessage>(arena_);
+  MessageLite* result = prototype
+                            ? prototype->New(arena_)
+                            : Arena::CreateMessage<ImplicitWeakMessage>(arena_);
   rep_->elements[current_size_++] = result;
   return result;
 }
@@ -122,5 +120,14 @@
 }  // namespace internal
 
 
+template class LIBPROTOBUF_EXPORT RepeatedField<bool>;
+template class LIBPROTOBUF_EXPORT RepeatedField<int32>;
+template class LIBPROTOBUF_EXPORT RepeatedField<uint32>;
+template class LIBPROTOBUF_EXPORT RepeatedField<int64>;
+template class LIBPROTOBUF_EXPORT RepeatedField<uint64>;
+template class LIBPROTOBUF_EXPORT RepeatedField<float>;
+template class LIBPROTOBUF_EXPORT RepeatedField<double>;
+template class LIBPROTOBUF_EXPORT RepeatedPtrField<string>;
+
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index 79682b6..63062c1 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -46,6 +46,7 @@
 #ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
 #define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
 
+#include <utility>
 #ifdef _MSC_VER
 // This is required for min/max on VS2013 only.
 #include <algorithm>
@@ -54,24 +55,30 @@
 #include <iterator>
 #include <limits>
 #include <string>
-#include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/implicit_weak_message.h>
 #include <google/protobuf/message_lite.h>
-#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/port.h>
+#include <google/protobuf/stubs/casts.h>
 #include <type_traits>
 
 
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 // Forward-declare these so that we can make them friends.
-namespace google {
 namespace upb {
 namespace google_opensource {
 class GMR_Handlers;
 }  // namespace google_opensource
 }  // namespace upb
 
+namespace google {
 namespace protobuf {
 
 class Message;
@@ -246,9 +253,7 @@
   iterator erase(const_iterator first, const_iterator last);
 
   // Get the Arena on which this RepeatedField stores its elements.
-  ::google::protobuf::Arena* GetArena() const {
-    return GetArenaNoVirtual();
-  }
+  Arena* GetArena() const { return GetArenaNoVirtual(); }
 
   // For internal use only.
   //
@@ -280,16 +285,23 @@
   static const size_t kRepHeaderSize;
 
   // We reuse the Rep* for an Arena* when total_size == 0, to avoid having to do
-  // an allocation in the constructor when we have an Arena.
+  // an allocation in the constructor when we have an Arena.  
   union Pointer {
     Pointer(Arena* a) : arena(a) {}
-    Arena* arena;   // When total_size_ == 0.
-    Rep* rep;       // When total_size_ != 0.
+    Arena* arena;       // When total_size_ == 0.
+    Element* elements;  // When total_size_ != 0, this is Rep->elements of Rep.
   } ptr_;
 
+  Element* elements() const {
+    GOOGLE_DCHECK_GT(total_size_, 0);
+    return ptr_.elements;
+  }
+
   Rep* rep() const {
     GOOGLE_DCHECK_GT(total_size_, 0);
-    return ptr_.rep;
+    char* addr =
+        reinterpret_cast<char*>(ptr_.elements) - offsetof(Rep, elements);
+    return reinterpret_cast<Rep*>(addr);
   }
 
   friend class Arena;
@@ -306,7 +318,7 @@
 
   // Internal helper expected by Arena methods.
   inline Arena* GetArenaNoVirtual() const {
-    return (total_size_ == 0) ? ptr_.arena : ptr_.rep->arena;
+    return (total_size_ == 0) ? ptr_.arena : rep()->arena;
   }
 
   // Internal helper to delete all elements and deallocate the storage.
@@ -413,7 +425,7 @@
 //     typedef MyType WeakType;
 //     static Type* New();
 //     static WeakType* NewFromPrototype(const WeakType* prototype,
-//                                       ::google::protobuf::Arena* arena);
+//                                       Arena* arena);
 //     static void Delete(Type*);
 //     static void Clear(Type*);
 //     static void Merge(const Type& from, Type* to);
@@ -424,7 +436,7 @@
 class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
  protected:
   RepeatedPtrFieldBase();
-  explicit RepeatedPtrFieldBase(::google::protobuf::Arena* arena);
+  explicit RepeatedPtrFieldBase(Arena* arena);
   ~RepeatedPtrFieldBase() {}
 
   // Must be called from destructor.
@@ -453,7 +465,7 @@
   // a link-time dependency on the concrete message type. This method is used to
   // implement implicit weak fields. The prototype may be NULL, in which case an
   // ImplicitWeakMessage will be used as a placeholder.
-  google::protobuf::MessageLite* AddWeak(const google::protobuf::MessageLite* prototype);
+  MessageLite* AddWeak(const MessageLite* prototype);
 
   template <typename TypeHandler>
   void Clear();
@@ -488,8 +500,9 @@
   template <typename TypeHandler>
   const typename TypeHandler::Type* const* data() const;
 
-  template <typename TypeHandler> GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
-  void Swap(RepeatedPtrFieldBase* other);
+  template <typename TypeHandler>
+  GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void Swap(
+      RepeatedPtrFieldBase* other);
 
   void SwapElements(int index1, int index2);
 
@@ -533,20 +546,21 @@
   template <typename TypeHandler>
   void AddAllocatedInternal(typename TypeHandler::Type* value, std::false_type);
 
-  template <typename TypeHandler> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
-  void AddAllocatedSlowWithCopy(typename TypeHandler::Type* value,
-                                Arena* value_arena,
-                                Arena* my_arena);
-  template <typename TypeHandler> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
-  void AddAllocatedSlowWithoutCopy(typename TypeHandler::Type* value);
+  template <typename TypeHandler>
+  GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE void AddAllocatedSlowWithCopy(
+      typename TypeHandler::Type* value, Arena* value_arena, Arena* my_arena);
+  template <typename TypeHandler>
+  GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE void AddAllocatedSlowWithoutCopy(
+      typename TypeHandler::Type* value);
 
   template <typename TypeHandler>
   typename TypeHandler::Type* ReleaseLastInternal(std::true_type);
   template <typename TypeHandler>
   typename TypeHandler::Type* ReleaseLastInternal(std::false_type);
 
-  template<typename TypeHandler> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
-  void SwapFallback(RepeatedPtrFieldBase* other);
+  template <typename TypeHandler>
+  GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE void SwapFallback(
+      RepeatedPtrFieldBase* other);
 
   inline Arena* GetArenaNoVirtual() const {
     return arena_;
@@ -640,20 +654,20 @@
   static const bool Moveable = false;
 
   static inline GenericType* New(Arena* arena) {
-    return ::google::protobuf::Arena::CreateMaybeMessage<Type>(arena);
+    return Arena::CreateMaybeMessage<Type>(arena);
   }
-  static inline GenericType* NewFromPrototype(
-      const GenericType* prototype, ::google::protobuf::Arena* arena = NULL);
+  static inline GenericType* NewFromPrototype(const GenericType* prototype,
+                                              Arena* arena = NULL);
   static inline void Delete(GenericType* value, Arena* arena) {
     if (arena == NULL) {
       delete value;
     }
   }
-  static inline ::google::protobuf::Arena* GetArena(GenericType* value) {
-    return ::google::protobuf::Arena::GetArena<Type>(value);
+  static inline Arena* GetArena(GenericType* value) {
+    return Arena::GetArena<Type>(value);
   }
   static inline void* GetMaybeArenaPointer(GenericType* value) {
-    return ::google::protobuf::Arena::GetArena<Type>(value);
+    return Arena::GetArena<Type>(value);
   }
 
   static inline void Clear(GenericType* value) { value->Clear(); }
@@ -666,7 +680,7 @@
 
 template <typename GenericType>
 GenericType* GenericTypeHandler<GenericType>::NewFromPrototype(
-    const GenericType* /* prototype */, ::google::protobuf::Arena* arena) {
+    const GenericType* /* prototype */, Arena* arena) {
   return New(arena);
 }
 template <typename GenericType>
@@ -678,12 +692,11 @@
 // NewFromPrototype() and Merge() are not defined inline here, as we will need
 // to do a virtual function dispatch anyways to go from Message* to call
 // New/Merge.
-template<>
+template <>
 MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
-    const MessageLite* prototype, google::protobuf::Arena* arena);
-template<>
-inline google::protobuf::Arena* GenericTypeHandler<MessageLite>::GetArena(
-    MessageLite* value) {
+    const MessageLite* prototype, Arena* arena);
+template <>
+inline Arena* GenericTypeHandler<MessageLite>::GetArena(MessageLite* value) {
   return value->GetArena();
 }
 template<>
@@ -704,16 +717,14 @@
 
 // Declarations of the specialization as we cannot define them here, as the
 // header that defines ProtocolMessage depends on types defined in this header.
-#define DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(TypeName)                 \
-    template<> LIBPROTOBUF_EXPORT                                              \
-    TypeName* GenericTypeHandler<TypeName>::NewFromPrototype(                  \
-        const TypeName* prototype, google::protobuf::Arena* arena);                      \
-    template<> LIBPROTOBUF_EXPORT                                              \
-    google::protobuf::Arena* GenericTypeHandler<TypeName>::GetArena(                     \
-        TypeName* value);                                                      \
-    template<> LIBPROTOBUF_EXPORT                                              \
-    void* GenericTypeHandler<TypeName>::GetMaybeArenaPointer(                  \
-        TypeName* value);
+#define DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(TypeName)    \
+  template <> LIBPROTOBUF_EXPORT                                  \
+  TypeName* GenericTypeHandler<TypeName>::NewFromPrototype(       \
+      const TypeName* prototype, Arena* arena);                   \
+  template <> LIBPROTOBUF_EXPORT                                  \
+  Arena* GenericTypeHandler<TypeName>::GetArena(TypeName* value); \
+  template <> LIBPROTOBUF_EXPORT                                  \
+  void* GenericTypeHandler<TypeName>::GetMaybeArenaPointer(TypeName* value);
 
 // Message specialization bodies defined in message.cc. This split is necessary
 // to allow proto2-lite (which includes this header) to be independent of
@@ -736,13 +747,10 @@
   static inline string* New(Arena* arena, string&& value) {
     return Arena::Create<string>(arena, std::move(value));
   }
-  static inline string* NewFromPrototype(const string*,
-                                         ::google::protobuf::Arena* arena) {
+  static inline string* NewFromPrototype(const string*, Arena* arena) {
     return New(arena);
   }
-  static inline ::google::protobuf::Arena* GetArena(string*) {
-    return NULL;
-  }
+  static inline Arena* GetArena(string*) { return NULL; }
   static inline void* GetMaybeArenaPointer(string* /* value */) {
     return NULL;
   }
@@ -766,7 +774,7 @@
 class RepeatedPtrField final : private internal::RepeatedPtrFieldBase {
  public:
   RepeatedPtrField();
-  explicit RepeatedPtrField(::google::protobuf::Arena* arena);
+  explicit RepeatedPtrField(Arena* arena);
 
   RepeatedPtrField(const RepeatedPtrField& other);
   template <typename Iter>
@@ -992,9 +1000,7 @@
   iterator erase(const_iterator first, const_iterator last);
 
   // Gets the arena on which this RepeatedPtrField stores its elements.
-  ::google::protobuf::Arena* GetArena() const {
-    return GetArenaNoVirtual();
-  }
+  Arena* GetArena() const { return GetArenaNoVirtual(); }
 
   // For internal use only.
   //
@@ -1131,22 +1137,27 @@
 template<typename Element>
 inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) {
   GOOGLE_DCHECK_LT(current_size_, total_size_);
-  rep()->elements[current_size_++] = value;
+  elements()[current_size_++] = value;
 }
 
 template<typename Element>
 inline Element* RepeatedField<Element>::AddAlreadyReserved() {
   GOOGLE_DCHECK_LT(current_size_, total_size_);
-  return &rep()->elements[current_size_++];
+  return &elements()[current_size_++];
 }
 
 template<typename Element>
-inline Element* RepeatedField<Element>::AddNAlreadyReserved(int elements) {
-  GOOGLE_DCHECK_LE(current_size_ + elements, total_size_);
-  // Warning: total_size_ can be NULL if elements == 0 && current_size_ == 0.
-  // Existing callers depend on this behavior. :(
-  Element* ret = &ptr_.rep->elements[current_size_];
-  current_size_ += elements;
+inline Element* RepeatedField<Element>::AddNAlreadyReserved(int n) {
+  GOOGLE_DCHECK_GE(total_size_ - current_size_, n)
+      << total_size_ << ", " << current_size_;
+  // Warning: sometimes people call this when n==0 and total_size_==0.  This
+  // forces us to add this branch, to avoid reading the non-active union member
+  // (which is UB).  Luckily the compiler is smart enough to optimize the branch
+  // away.
+  Element* ret =
+      total_size_ == 0 ? reinterpret_cast<Element*>(ptr_.arena) : ptr_.elements;
+  ret += current_size_;
+  current_size_ += n;
   return ret;
 }
 
@@ -1155,8 +1166,7 @@
   GOOGLE_DCHECK_GE(new_size, 0);
   if (new_size > current_size_) {
     Reserve(new_size);
-    std::fill(&rep()->elements[current_size_],
-              &rep()->elements[new_size], value);
+    std::fill(&elements()[current_size_], &elements()[new_size], value);
   }
   current_size_ = new_size;
 }
@@ -1165,33 +1175,33 @@
 inline const Element& RepeatedField<Element>::Get(int index) const {
   GOOGLE_DCHECK_GE(index, 0);
   GOOGLE_DCHECK_LT(index, current_size_);
-  return rep()->elements[index];
+  return elements()[index];
 }
 
 template <typename Element>
 inline Element* RepeatedField<Element>::Mutable(int index) {
   GOOGLE_DCHECK_GE(index, 0);
   GOOGLE_DCHECK_LT(index, current_size_);
-  return &rep()->elements[index];
+  return &elements()[index];
 }
 
 template <typename Element>
 inline void RepeatedField<Element>::Set(int index, const Element& value) {
   GOOGLE_DCHECK_GE(index, 0);
   GOOGLE_DCHECK_LT(index, current_size_);
-  rep()->elements[index] = value;
+  elements()[index] = value;
 }
 
 template <typename Element>
 inline void RepeatedField<Element>::Add(const Element& value) {
   if (current_size_ == total_size_) Reserve(total_size_ + 1);
-  rep()->elements[current_size_++] = value;
+  elements()[current_size_++] = value;
 }
 
 template <typename Element>
 inline Element* RepeatedField<Element>::Add() {
   if (current_size_ == total_size_) Reserve(total_size_ + 1);
-  return &rep()->elements[current_size_++];
+  return &elements()[current_size_++];
 }
 
 template <typename Element>
@@ -1262,17 +1272,17 @@
 
 template <typename Element>
 inline Element* RepeatedField<Element>::mutable_data() {
-  return total_size_ > 0 ? rep()->elements : NULL;
+  return total_size_ > 0 ? elements() : NULL;
 }
 
 template <typename Element>
 inline const Element* RepeatedField<Element>::data() const {
-  return total_size_ > 0 ? rep()->elements : NULL;
+  return total_size_ > 0 ? elements() : NULL;
 }
 
 template <typename Element>
 inline const Element* RepeatedField<Element>::unsafe_data() const {
-  return rep()->elements;
+  return elements();
 }
 
 template <typename Element>
@@ -1307,38 +1317,38 @@
 template <typename Element>
 void RepeatedField<Element>::SwapElements(int index1, int index2) {
   using std::swap;  // enable ADL with fallback
-  swap(rep()->elements[index1], rep()->elements[index2]);
+  swap(elements()[index1], elements()[index2]);
 }
 
 template <typename Element>
 inline typename RepeatedField<Element>::iterator
 RepeatedField<Element>::begin() {
-  return total_size_ > 0 ? rep()->elements : NULL;
+  return total_size_ > 0 ? elements() : NULL;
 }
 template <typename Element>
 inline typename RepeatedField<Element>::const_iterator
 RepeatedField<Element>::begin() const {
-  return total_size_ > 0 ? rep()->elements : NULL;
+  return total_size_ > 0 ? elements() : NULL;
 }
 template <typename Element>
 inline typename RepeatedField<Element>::const_iterator
 RepeatedField<Element>::cbegin() const {
-  return total_size_ > 0 ? rep()->elements : NULL;
+  return total_size_ > 0 ? elements() : NULL;
 }
 template <typename Element>
 inline typename RepeatedField<Element>::iterator
 RepeatedField<Element>::end() {
-  return total_size_ > 0 ? rep()->elements + current_size_ : NULL;
+  return total_size_ > 0 ? elements() + current_size_ : NULL;
 }
 template <typename Element>
 inline typename RepeatedField<Element>::const_iterator
 RepeatedField<Element>::end() const {
-  return total_size_ > 0 ? rep()->elements + current_size_ : NULL;
+  return total_size_ > 0 ? elements() + current_size_ : NULL;
 }
 template <typename Element>
 inline typename RepeatedField<Element>::const_iterator
 RepeatedField<Element>::cend() const {
-  return total_size_ > 0 ? rep()->elements + current_size_ : NULL;
+  return total_size_ > 0 ? elements() + current_size_ : NULL;
 }
 
 template <typename Element>
@@ -1352,8 +1362,9 @@
 void RepeatedField<Element>::Reserve(int new_size) {
   if (total_size_ >= new_size) return;
   Rep* old_rep = total_size_ > 0 ? rep() : NULL;
+  Rep* new_rep;
   Arena* arena = GetArenaNoVirtual();
-  new_size = std::max(google::protobuf::internal::kMinRepeatedFieldAllocationSize,
+  new_size = std::max(internal::kMinRepeatedFieldAllocationSize,
                       std::max(total_size_ * 2, new_size));
   GOOGLE_DCHECK_LE(
       static_cast<size_t>(new_size),
@@ -1361,14 +1372,14 @@
       << "Requested size is too large to fit into size_t.";
   size_t bytes = kRepHeaderSize + sizeof(Element) * static_cast<size_t>(new_size);
   if (arena == NULL) {
-    ptr_.rep = static_cast<Rep*>(::operator new(bytes));
+    new_rep = static_cast<Rep*>(::operator new(bytes));
   } else {
-    ptr_.rep = reinterpret_cast<Rep*>(
-            ::google::protobuf::Arena::CreateArray<char>(arena, bytes));
+    new_rep = reinterpret_cast<Rep*>(Arena::CreateArray<char>(arena, bytes));
   }
-  ptr_.rep->arena = arena;
+  new_rep->arena = arena;
   int old_total_size = total_size_;
   total_size_ = new_size;
+  ptr_.elements = new_rep->elements;
   // Invoke placement-new on newly allocated elements. We shouldn't have to do
   // this, since Element is supposed to be POD, but a previous version of this
   // code allocated storage with "new Element[size]" and some code uses
@@ -1378,13 +1389,13 @@
   // effect unless its side-effects are required for correctness.
   // Note that we do this before MoveArray() below because Element's copy
   // assignment implementation will want an initialized instance first.
-  Element* e = &rep()->elements[0];
+  Element* e = &elements()[0];
   Element* limit = e + total_size_;
   for (; e < limit; e++) {
     new (e) Element;
   }
   if (current_size_ > 0) {
-    MoveArray(&rep()->elements[0], old_rep->elements, current_size_);
+    MoveArray(&elements()[0], old_rep->elements, current_size_);
   }
 
   // Likewise, we need to invoke destructors on the old array.
@@ -1441,12 +1452,8 @@
     rep_(NULL) {
 }
 
-inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(::google::protobuf::Arena* arena)
-  : arena_(arena),
-    current_size_(0),
-    total_size_(0),
-    rep_(NULL) {
-}
+inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(Arena* arena)
+    : arena_(arena), current_size_(0), total_size_(0), rep_(NULL) {}
 
 template <typename TypeHandler>
 void RepeatedPtrFieldBase::Destroy() {
@@ -1887,8 +1894,8 @@
   : RepeatedPtrFieldBase() {}
 
 template <typename Element>
-inline RepeatedPtrField<Element>::RepeatedPtrField(::google::protobuf::Arena* arena) :
-  RepeatedPtrFieldBase(arena) {}
+inline RepeatedPtrField<Element>::RepeatedPtrField(Arena* arena)
+    : RepeatedPtrFieldBase(arena) {}
 
 template <typename Element>
 inline RepeatedPtrField<Element>::RepeatedPtrField(
@@ -2233,7 +2240,7 @@
       : it_(other.it_) {
     // Force a compiler error if the other type is not convertible to ours.
     if (false) {
-      implicit_cast<Element*>(static_cast<OtherElement*>(nullptr));
+      ::google::protobuf::implicit_cast<Element*>(static_cast<OtherElement*>(nullptr));
     }
   }
 
@@ -2440,13 +2447,12 @@
       const_cast<const void* const*>(raw_data() + size()));
 }
 
-
 // Iterators and helper functions that follow the spirit of the STL
 // std::back_insert_iterator and std::back_inserter but are tailor-made
 // for RepeatedField and RepeatedPtrField. Typical usage would be:
 //
 //   std::copy(some_sequence.begin(), some_sequence.end(),
-//             google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
+//             RepeatedFieldBackInserter(proto.mutable_sequence()));
 //
 // Ported by johannes from util/gtl/proto-array-iterators.h
 
@@ -2548,9 +2554,8 @@
     : public std::iterator<std::output_iterator_tag, T> {
  public:
   explicit UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator(
-    ::google::protobuf::RepeatedPtrField<T>* const mutable_field)
-  : field_(mutable_field) {
-  }
+      RepeatedPtrField<T>* const mutable_field)
+      : field_(mutable_field) {}
   UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
     T const* const ptr_to_value) {
     field_->UnsafeArenaAddAllocated(const_cast<T*>(ptr_to_value));
@@ -2568,7 +2573,7 @@
   }
 
  private:
-  ::google::protobuf::RepeatedPtrField<T>* field_;
+  RepeatedPtrField<T>* field_;
 };
 
 }  // namespace internal
@@ -2616,15 +2621,27 @@
 // If you put temp_field on the arena this fails, because the ownership
 // transfers to the arena at the "AddAllocated" call and is not released anymore
 // causing a double delete. Using UnsafeArenaAddAllocated prevents this.
-template<typename T>
+template <typename T>
 internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>
 UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
-    ::google::protobuf::RepeatedPtrField<T>* const mutable_field) {
+    RepeatedPtrField<T>* const mutable_field) {
   return internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>(
       mutable_field);
 }
 
-}  // namespace protobuf
+// Extern declarations of common instantiations to reduce libray bloat.
+extern template class LIBPROTOBUF_EXPORT RepeatedField<bool>;
+extern template class LIBPROTOBUF_EXPORT RepeatedField<int32>;
+extern template class LIBPROTOBUF_EXPORT RepeatedField<uint32>;
+extern template class LIBPROTOBUF_EXPORT RepeatedField<int64>;
+extern template class LIBPROTOBUF_EXPORT RepeatedField<uint64>;
+extern template class LIBPROTOBUF_EXPORT RepeatedField<float>;
+extern template class LIBPROTOBUF_EXPORT RepeatedField<double>;
+extern template class LIBPROTOBUF_EXPORT RepeatedPtrField<string>;
 
+}  // namespace protobuf
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_REPEATED_FIELD_H__
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc
index 053a4d6..fa86c59 100644
--- a/src/google/protobuf/repeated_field_unittest.cc
+++ b/src/google/protobuf/repeated_field_unittest.cc
@@ -45,10 +45,10 @@
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/stubs/strutil.h>
 #include <gmock/gmock.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
-#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/stl_util.h>
 
 namespace google {
diff --git a/src/google/protobuf/service.cc b/src/google/protobuf/service.cc
index ffa919d..a6616b4 100644
--- a/src/google/protobuf/service.cc
+++ b/src/google/protobuf/service.cc
@@ -42,5 +42,5 @@
 RpcController::~RpcController() {}
 
 }  // namespace protobuf
-
 }  // namespace google
+
diff --git a/src/google/protobuf/service.h b/src/google/protobuf/service.h
index ad6f968..5c6d068 100644
--- a/src/google/protobuf/service.h
+++ b/src/google/protobuf/service.h
@@ -104,6 +104,10 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/callback.h>
 
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 
@@ -287,6 +291,6 @@
 };
 
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_SERVICE_H__
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc
index af93e6b..067fcae 100644
--- a/src/google/protobuf/source_context.pb.cc
+++ b/src/google/protobuf/source_context.pb.cc
@@ -6,8 +6,8 @@
 #include <algorithm>
 
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
@@ -18,18 +18,17 @@
 #include "third_party/protobuf/version.h"
 #endif
 // @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
 
 namespace google {
 namespace protobuf {
 class SourceContextDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<SourceContext>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<SourceContext> _instance;
 } _SourceContext_default_instance_;
 }  // namespace protobuf
 }  // namespace google
-namespace protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto {
-static void InitDefaultsSourceContext() {
+static void InitDefaultsSourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -40,16 +39,18 @@
   ::google::protobuf::SourceContext::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_SourceContext =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsSourceContext}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsSourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto}, {}};
 
-void InitDefaults() {
-  ::google::protobuf::internal::InitSCC(&scc_info_SourceContext.base);
+void InitDefaults_google_2fprotobuf_2fsource_5fcontext_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata[1];
+::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto[1];
+constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr;
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto = nullptr;
 
-const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::SourceContext, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -65,52 +66,34 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_SourceContext_default_instance_),
 };
 
-static void protobuf_AssignDescriptors() {
-  AddDescriptors();
-  AssignDescriptors(
-      "google/protobuf/source_context.proto", schemas, file_default_instances, TableStruct::offsets,
-      file_level_metadata, NULL, NULL);
-}
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fsource_5fcontext_2eproto = {
+  {}, AddDescriptors_google_2fprotobuf_2fsource_5fcontext_2eproto, "google/protobuf/source_context.proto", schemas,
+  file_default_instances, TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto::offsets,
+  file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto, file_level_service_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto,
+};
 
-static void protobuf_AssignDescriptorsOnce() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
-}
+::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto = {
+  false, InitDefaults_google_2fprotobuf_2fsource_5fcontext_2eproto, 
+  "\n$google/protobuf/source_context.proto\022\017"
+  "google.protobuf\"\"\n\rSourceContext\022\021\n\tfile"
+  "_name\030\001 \001(\tB\225\001\n\023com.google.protobufB\022Sou"
+  "rceContextProtoP\001ZAgoogle.golang.org/gen"
+  "proto/protobuf/source_context;source_con"
+  "text\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTy"
+  "pesb\006proto3"
+,
+  "google/protobuf/source_context.proto", &assign_descriptors_table_google_2fprotobuf_2fsource_5fcontext_2eproto, 251,
+};
 
-void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
-void protobuf_RegisterTypes(const ::std::string&) {
-  protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
-}
-
-static void AddDescriptorsImpl() {
-  InitDefaults();
-  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
-      "\n$google/protobuf/source_context.proto\022\017"
-      "google.protobuf\"\"\n\rSourceContext\022\021\n\tfile"
-      "_name\030\001 \001(\tB\225\001\n\023com.google.protobufB\022Sou"
-      "rceContextProtoP\001ZAgoogle.golang.org/gen"
-      "proto/protobuf/source_context;source_con"
-      "text\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTy"
-      "pesb\006proto3"
+void AddDescriptors_google_2fprotobuf_2fsource_5fcontext_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
   };
-  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 251);
-  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
-    "google/protobuf/source_context.proto", &protobuf_RegisterTypes);
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto, deps, 0);
 }
 
-void AddDescriptors() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
-}
-// Force AddDescriptors() to be called at dynamic initialization time.
-struct StaticDescriptorInitializer {
-  StaticDescriptorInitializer() {
-    AddDescriptors();
-  }
-} static_descriptor_initializer;
-}  // namespace protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_google_2fprotobuf_2fsource_5fcontext_2eproto = []() { AddDescriptors_google_2fprotobuf_2fsource_5fcontext_2eproto(); return true; }();
 namespace google {
 namespace protobuf {
 
@@ -118,14 +101,16 @@
 
 void SourceContext::InitAsDefaultInstance() {
 }
+class SourceContext::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int SourceContext::kFileNameFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 SourceContext::SourceContext()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::scc_info_SourceContext.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.SourceContext)
 }
@@ -141,6 +126,8 @@
 }
 
 void SourceContext::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto.base);
   file_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 
@@ -156,13 +143,8 @@
 void SourceContext::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* SourceContext::descriptor() {
-  ::protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const SourceContext& SourceContext::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::scc_info_SourceContext.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -177,9 +159,64 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* SourceContext::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<SourceContext*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // string file_name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.SourceContext.file_name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_file_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool SourceContext::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.SourceContext)
   for (;;) {
@@ -189,8 +226,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // string file_name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_file_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -222,6 +258,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void SourceContext::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -239,9 +276,9 @@
       1, this->file_name(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.SourceContext)
 }
@@ -264,9 +301,9 @@
         1, this->file_name(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceContext)
   return target;
@@ -276,11 +313,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.SourceContext)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // string file_name = 1;
   if (this->file_name().size() > 0) {
     total_size += 1 +
@@ -297,7 +338,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.SourceContext)
   GOOGLE_DCHECK_NE(&from, this);
   const SourceContext* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const SourceContext>(
+      ::google::protobuf::DynamicCastToGenerated<SourceContext>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.SourceContext)
@@ -345,14 +386,14 @@
 }
 void SourceContext::InternalSwap(SourceContext* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   file_name_.Swap(&other->file_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata SourceContext::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fsource_5fcontext_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto[kIndexInFileMessages];
 }
 
 
diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h
index dcc856e..5355e1c 100644
--- a/src/google/protobuf/source_context.pb.h
+++ b/src/google/protobuf/source_context.pb.h
@@ -4,18 +4,18 @@
 #ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2fsource_5fcontext_2eproto
 #define PROTOBUF_INCLUDED_google_2fprotobuf_2fsource_5fcontext_2eproto
 
+#include <limits>
 #include <string>
 
 #include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 3006001
+#if GOOGLE_PROTOBUF_VERSION < 3006000
 #error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please update
+#error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
 #if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
 #error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please
+#error incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.
 #endif
 
@@ -31,29 +31,27 @@
 #include <google/protobuf/extension_set.h>  // IWYU pragma: export
 #include <google/protobuf/unknown_field_set.h>
 // @@protoc_insertion_point(includes)
-#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto LIBPROTOBUF_EXPORT
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fsource_5fcontext_2eproto LIBPROTOBUF_EXPORT
 
-namespace protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto {
 // Internal implementation detail -- do not use these members.
-struct LIBPROTOBUF_EXPORT TableStruct {
-  static const ::google::protobuf::internal::ParseTableField entries[];
-  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
-  static const ::google::protobuf::internal::ParseTable schema[1];
+struct LIBPROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[1]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
   static const ::google::protobuf::uint32 offsets[];
 };
-void LIBPROTOBUF_EXPORT AddDescriptors();
-}  // namespace protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto
+void LIBPROTOBUF_EXPORT AddDescriptors_google_2fprotobuf_2fsource_5fcontext_2eproto();
 namespace google {
 namespace protobuf {
 class SourceContext;
 class SourceContextDefaultTypeInternal;
 LIBPROTOBUF_EXPORT extern SourceContextDefaultTypeInternal _SourceContext_default_instance_;
-}  // namespace protobuf
-}  // namespace google
-namespace google {
-namespace protobuf {
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::SourceContext* Arena::CreateMaybeMessage<::google::protobuf::SourceContext>(Arena*);
 }  // namespace protobuf
 }  // namespace google
@@ -88,7 +86,9 @@
     return *this;
   }
   #endif
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const SourceContext& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -121,8 +121,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -165,11 +170,12 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.SourceContext)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::internal::ArenaStringPtr file_name_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto;
 };
 // ===================================================================
 
@@ -246,4 +252,5 @@
 
 // @@protoc_insertion_point(global_scope)
 
+#include <google/protobuf/port_undef.inc>
 #endif  // PROTOBUF_INCLUDED_google_2fprotobuf_2fsource_5fcontext_2eproto
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc
index ead8168..4294f40 100644
--- a/src/google/protobuf/struct.pb.cc
+++ b/src/google/protobuf/struct.pb.cc
@@ -6,8 +6,8 @@
 #include <algorithm>
 
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
@@ -18,26 +18,22 @@
 #include "third_party/protobuf/version.h"
 #endif
 // @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
 
-namespace protobuf_google_2fprotobuf_2fstruct_2eproto {
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fstruct_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_ListValue;
-}  // namespace protobuf_google_2fprotobuf_2fstruct_2eproto
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fstruct_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto;
 namespace google {
 namespace protobuf {
 class Struct_FieldsEntry_DoNotUseDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Struct_FieldsEntry_DoNotUse>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Struct_FieldsEntry_DoNotUse> _instance;
 } _Struct_FieldsEntry_DoNotUse_default_instance_;
 class StructDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Struct>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Struct> _instance;
 } _Struct_default_instance_;
 class ValueDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Value>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Value> _instance;
   int null_value_;
   double number_value_;
   ::google::protobuf::internal::ArenaStringPtr string_value_;
@@ -47,13 +43,11 @@
 } _Value_default_instance_;
 class ListValueDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<ListValue>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<ListValue> _instance;
 } _ListValue_default_instance_;
 }  // namespace protobuf
 }  // namespace google
-namespace protobuf_google_2fprotobuf_2fstruct_2eproto {
-static void InitDefaultsListValue() {
+static void InitDefaultsListValue_google_2fprotobuf_2fstruct_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -81,17 +75,18 @@
   ::google::protobuf::ListValue::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_ListValue =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsListValue}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsListValue_google_2fprotobuf_2fstruct_2eproto}, {}};
 
-void InitDefaults() {
-  ::google::protobuf::internal::InitSCC(&scc_info_ListValue.base);
+void InitDefaults_google_2fprotobuf_2fstruct_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata[4];
-const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[1];
+::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fstruct_2eproto[4];
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto[1];
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto = nullptr;
 
-const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fstruct_2eproto::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Struct_FieldsEntry_DoNotUse, _has_bits_),
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Struct_FieldsEntry_DoNotUse, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -140,67 +135,49 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_ListValue_default_instance_),
 };
 
-static void protobuf_AssignDescriptors() {
-  AddDescriptors();
-  AssignDescriptors(
-      "google/protobuf/struct.proto", schemas, file_default_instances, TableStruct::offsets,
-      file_level_metadata, file_level_enum_descriptors, NULL);
-}
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fstruct_2eproto = {
+  {}, AddDescriptors_google_2fprotobuf_2fstruct_2eproto, "google/protobuf/struct.proto", schemas,
+  file_default_instances, TableStruct_google_2fprotobuf_2fstruct_2eproto::offsets,
+  file_level_metadata_google_2fprotobuf_2fstruct_2eproto, 4, file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto, file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto,
+};
 
-static void protobuf_AssignDescriptorsOnce() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
-}
+::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fstruct_2eproto = {
+  false, InitDefaults_google_2fprotobuf_2fstruct_2eproto, 
+  "\n\034google/protobuf/struct.proto\022\017google.p"
+  "rotobuf\"\204\001\n\006Struct\0223\n\006fields\030\001 \003(\0132#.goo"
+  "gle.protobuf.Struct.FieldsEntry\032E\n\013Field"
+  "sEntry\022\013\n\003key\030\001 \001(\t\022%\n\005value\030\002 \001(\0132\026.goo"
+  "gle.protobuf.Value:\0028\001\"\352\001\n\005Value\0220\n\nnull"
+  "_value\030\001 \001(\0162\032.google.protobuf.NullValue"
+  "H\000\022\026\n\014number_value\030\002 \001(\001H\000\022\026\n\014string_val"
+  "ue\030\003 \001(\tH\000\022\024\n\nbool_value\030\004 \001(\010H\000\022/\n\014stru"
+  "ct_value\030\005 \001(\0132\027.google.protobuf.StructH"
+  "\000\0220\n\nlist_value\030\006 \001(\0132\032.google.protobuf."
+  "ListValueH\000B\006\n\004kind\"3\n\tListValue\022&\n\006valu"
+  "es\030\001 \003(\0132\026.google.protobuf.Value*\033\n\tNull"
+  "Value\022\016\n\nNULL_VALUE\020\000B\201\001\n\023com.google.pro"
+  "tobufB\013StructProtoP\001Z1github.com/golang/"
+  "protobuf/ptypes/struct;structpb\370\001\001\242\002\003GPB"
+  "\252\002\036Google.Protobuf.WellKnownTypesb\006proto"
+  "3"
+,
+  "google/protobuf/struct.proto", &assign_descriptors_table_google_2fprotobuf_2fstruct_2eproto, 641,
+};
 
-void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
-void protobuf_RegisterTypes(const ::std::string&) {
-  protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 4);
-}
-
-static void AddDescriptorsImpl() {
-  InitDefaults();
-  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
-      "\n\034google/protobuf/struct.proto\022\017google.p"
-      "rotobuf\"\204\001\n\006Struct\0223\n\006fields\030\001 \003(\0132#.goo"
-      "gle.protobuf.Struct.FieldsEntry\032E\n\013Field"
-      "sEntry\022\013\n\003key\030\001 \001(\t\022%\n\005value\030\002 \001(\0132\026.goo"
-      "gle.protobuf.Value:\0028\001\"\352\001\n\005Value\0220\n\nnull"
-      "_value\030\001 \001(\0162\032.google.protobuf.NullValue"
-      "H\000\022\026\n\014number_value\030\002 \001(\001H\000\022\026\n\014string_val"
-      "ue\030\003 \001(\tH\000\022\024\n\nbool_value\030\004 \001(\010H\000\022/\n\014stru"
-      "ct_value\030\005 \001(\0132\027.google.protobuf.StructH"
-      "\000\0220\n\nlist_value\030\006 \001(\0132\032.google.protobuf."
-      "ListValueH\000B\006\n\004kind\"3\n\tListValue\022&\n\006valu"
-      "es\030\001 \003(\0132\026.google.protobuf.Value*\033\n\tNull"
-      "Value\022\016\n\nNULL_VALUE\020\000B\201\001\n\023com.google.pro"
-      "tobufB\013StructProtoP\001Z1github.com/golang/"
-      "protobuf/ptypes/struct;structpb\370\001\001\242\002\003GPB"
-      "\252\002\036Google.Protobuf.WellKnownTypesb\006proto"
-      "3"
+void AddDescriptors_google_2fprotobuf_2fstruct_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
   };
-  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 641);
-  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
-    "google/protobuf/struct.proto", &protobuf_RegisterTypes);
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto, deps, 0);
 }
 
-void AddDescriptors() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
-}
-// Force AddDescriptors() to be called at dynamic initialization time.
-struct StaticDescriptorInitializer {
-  StaticDescriptorInitializer() {
-    AddDescriptors();
-  }
-} static_descriptor_initializer;
-}  // namespace protobuf_google_2fprotobuf_2fstruct_2eproto
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_google_2fprotobuf_2fstruct_2eproto = []() { AddDescriptors_google_2fprotobuf_2fstruct_2eproto(); return true; }();
 namespace google {
 namespace protobuf {
 const ::google::protobuf::EnumDescriptor* NullValue_descriptor() {
-  protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_enum_descriptors[0];
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2fstruct_2eproto);
+  return file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto[0];
 }
 bool NullValue_IsValid(int value) {
   switch (value) {
@@ -215,32 +192,39 @@
 // ===================================================================
 
 Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse() {}
-Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse(::google::protobuf::Arena* arena) : SuperType(arena) {}
+Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse(::google::protobuf::Arena* arena)
+    : SuperType(arena) {}
 void Struct_FieldsEntry_DoNotUse::MergeFrom(const Struct_FieldsEntry_DoNotUse& other) {
   MergeFromInternal(other);
 }
 ::google::protobuf::Metadata Struct_FieldsEntry_DoNotUse::GetMetadata() const {
-  ::protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[0];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fstruct_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fstruct_2eproto[0];
 }
 void Struct_FieldsEntry_DoNotUse::MergeFrom(
     const ::google::protobuf::Message& other) {
   ::google::protobuf::Message::MergeFrom(other);
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Struct_FieldsEntry_DoNotUse::_InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx) { return end; }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
 
 // ===================================================================
 
 void Struct::InitAsDefaultInstance() {
 }
+class Struct::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Struct::kFieldsFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Struct::Struct()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fstruct_2eproto::scc_info_ListValue.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Struct)
 }
@@ -248,7 +232,6 @@
   : ::google::protobuf::Message(),
   _internal_metadata_(arena),
   fields_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fstruct_2eproto::scc_info_ListValue.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.Struct)
@@ -262,6 +245,8 @@
 }
 
 void Struct::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto.base);
 }
 
 Struct::~Struct() {
@@ -282,13 +267,8 @@
 void Struct::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Struct::descriptor() {
-  ::protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Struct& Struct::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fstruct_2eproto::scc_info_ListValue.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -303,9 +283,64 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Struct::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Struct*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // map<string, .google.protobuf.Value> fields = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::Struct_FieldsEntry_DoNotUse::_InternalParse;
+          object = msg->mutable_fields();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 10 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Struct::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Struct)
   for (;;) {
@@ -315,8 +350,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // map<string, .google.protobuf.Value> fields = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           Struct_FieldsEntry_DoNotUse::Parser< ::google::protobuf::internal::MapField<
               Struct_FieldsEntry_DoNotUse,
               ::std::string, ::google::protobuf::Value,
@@ -355,6 +389,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Struct::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -391,35 +426,31 @@
       ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());
       ::std::unique_ptr<Struct_FieldsEntry_DoNotUse> entry;
       for (size_type i = 0; i < n; i++) {
-        entry.reset(fields_.NewEntryWrapper(
-            items[static_cast<ptrdiff_t>(i)]->first, items[static_cast<ptrdiff_t>(i)]->second));
-        ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-            1, *entry, output);
+        entry.reset(fields_.NewEntryWrapper(items[static_cast<ptrdiff_t>(i)]->first, items[static_cast<ptrdiff_t>(i)]->second));
+        ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(1, *entry, output);
         if (entry->GetArena() != NULL) {
           entry.release();
         }
-        Utf8Check::Check(items[static_cast<ptrdiff_t>(i)]);
+        Utf8Check::Check(&(*items[static_cast<ptrdiff_t>(i)]));
       }
     } else {
       ::std::unique_ptr<Struct_FieldsEntry_DoNotUse> entry;
       for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
           it = this->fields().begin();
           it != this->fields().end(); ++it) {
-        entry.reset(fields_.NewEntryWrapper(
-            it->first, it->second));
-        ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-            1, *entry, output);
+        entry.reset(fields_.NewEntryWrapper(it->first, it->second));
+        ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(1, *entry, output);
         if (entry->GetArena() != NULL) {
           entry.release();
         }
-        Utf8Check::Check(&*it);
+        Utf8Check::Check(&(*it));
       }
     }
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Struct)
 }
@@ -460,39 +491,31 @@
       ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());
       ::std::unique_ptr<Struct_FieldsEntry_DoNotUse> entry;
       for (size_type i = 0; i < n; i++) {
-        entry.reset(fields_.NewEntryWrapper(
-            items[static_cast<ptrdiff_t>(i)]->first, items[static_cast<ptrdiff_t>(i)]->second));
-        target = ::google::protobuf::internal::WireFormatLite::
-                   InternalWriteMessageNoVirtualToArray(
-                       1, *entry, deterministic, target);
-;
+        entry.reset(fields_.NewEntryWrapper(items[static_cast<ptrdiff_t>(i)]->first, items[static_cast<ptrdiff_t>(i)]->second));
+        target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessageNoVirtualToArray(1, *entry, deterministic, target);
         if (entry->GetArena() != NULL) {
           entry.release();
         }
-        Utf8Check::Check(items[static_cast<ptrdiff_t>(i)]);
+        Utf8Check::Check(&(*items[static_cast<ptrdiff_t>(i)]));
       }
     } else {
       ::std::unique_ptr<Struct_FieldsEntry_DoNotUse> entry;
       for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
           it = this->fields().begin();
           it != this->fields().end(); ++it) {
-        entry.reset(fields_.NewEntryWrapper(
-            it->first, it->second));
-        target = ::google::protobuf::internal::WireFormatLite::
-                   InternalWriteMessageNoVirtualToArray(
-                       1, *entry, deterministic, target);
-;
+        entry.reset(fields_.NewEntryWrapper(it->first, it->second));
+        target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessageNoVirtualToArray(1, *entry, deterministic, target);
         if (entry->GetArena() != NULL) {
           entry.release();
         }
-        Utf8Check::Check(&*it);
+        Utf8Check::Check(&(*it));
       }
     }
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Struct)
   return target;
@@ -502,11 +525,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Struct)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // map<string, .google.protobuf.Value> fields = 1;
   total_size += 1 *
       ::google::protobuf::internal::FromIntSize(this->fields_size());
@@ -536,7 +563,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Struct)
   GOOGLE_DCHECK_NE(&from, this);
   const Struct* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Struct>(
+      ::google::protobuf::DynamicCastToGenerated<Struct>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Struct)
@@ -596,13 +623,13 @@
 }
 void Struct::InternalSwap(Struct* other) {
   using std::swap;
-  fields_.Swap(&other->fields_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
+  fields_.Swap(&other->fields_);
 }
 
 ::google::protobuf::Metadata Struct::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fstruct_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fstruct_2eproto[kIndexInFileMessages];
 }
 
 
@@ -619,6 +646,20 @@
   ::google::protobuf::_Value_default_instance_.list_value_ = const_cast< ::google::protobuf::ListValue*>(
       ::google::protobuf::ListValue::internal_default_instance());
 }
+class Value::HasBitSetters {
+ public:
+  static const ::google::protobuf::Struct& struct_value(const Value* msg);
+  static const ::google::protobuf::ListValue& list_value(const Value* msg);
+};
+
+const ::google::protobuf::Struct&
+Value::HasBitSetters::struct_value(const Value* msg) {
+  return *msg->kind_.struct_value_;
+}
+const ::google::protobuf::ListValue&
+Value::HasBitSetters::list_value(const Value* msg) {
+  return *msg->kind_.list_value_;
+}
 void Value::set_allocated_struct_value(::google::protobuf::Struct* struct_value) {
   ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
   clear_kind();
@@ -660,15 +701,12 @@
 
 Value::Value()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fstruct_2eproto::scc_info_ListValue.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Value)
 }
 Value::Value(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fstruct_2eproto::scc_info_ListValue.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.Value)
@@ -711,6 +749,8 @@
 }
 
 void Value::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto.base);
   clear_has_kind();
 }
 
@@ -735,13 +775,8 @@
 void Value::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Value::descriptor() {
-  ::protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Value& Value::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fstruct_2eproto::scc_info_ListValue.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -796,9 +831,119 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Value::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Value*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // .google.protobuf.NullValue null_value = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::NullValue value = static_cast<::google::protobuf::NullValue>(val);
+        msg->set_null_value(value);
+        break;
+      }
+      // double number_value = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 17) goto handle_unusual;
+        double val;
+        ::std::memcpy(&val, ptr, 8);
+        ptr += 8;
+        msg->set_number_value(val);
+        break;
+      }
+      // string string_value = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Value.string_value");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_string_value();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // bool bool_value = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_bool_value(value);
+        break;
+      }
+      // .google.protobuf.Struct struct_value = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::Struct::_InternalParse;
+        object = msg->mutable_struct_value();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // .google.protobuf.ListValue list_value = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::ListValue::_InternalParse;
+        object = msg->mutable_list_value();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Value::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Value)
   for (;;) {
@@ -808,8 +953,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // .google.protobuf.NullValue null_value = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
           int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -823,8 +967,7 @@
 
       // double number_value = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(17u /* 17 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (17 & 0xFF)) {
           clear_kind();
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
@@ -838,8 +981,7 @@
 
       // string string_value = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_string_value()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -854,8 +996,7 @@
 
       // bool bool_value = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
           clear_kind();
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
@@ -869,8 +1010,7 @@
 
       // .google.protobuf.Struct struct_value = 5;
       case 5: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_struct_value()));
         } else {
@@ -881,8 +1021,7 @@
 
       // .google.protobuf.ListValue list_value = 6;
       case 6: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_list_value()));
         } else {
@@ -910,6 +1049,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Value::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -946,18 +1086,18 @@
   // .google.protobuf.Struct struct_value = 5;
   if (has_struct_value()) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      5, this->_internal_struct_value(), output);
+      5, HasBitSetters::struct_value(this), output);
   }
 
   // .google.protobuf.ListValue list_value = 6;
   if (has_list_value()) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      6, this->_internal_list_value(), output);
+      6, HasBitSetters::list_value(this), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Value)
 }
@@ -1000,19 +1140,19 @@
   if (has_struct_value()) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        5, this->_internal_struct_value(), deterministic, target);
+        5, HasBitSetters::struct_value(this), deterministic, target);
   }
 
   // .google.protobuf.ListValue list_value = 6;
   if (has_list_value()) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        6, this->_internal_list_value(), deterministic, target);
+        6, HasBitSetters::list_value(this), deterministic, target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Value)
   return target;
@@ -1022,11 +1162,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Value)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   switch (kind_case()) {
     // .google.protobuf.NullValue null_value = 1;
     case kNullValue: {
@@ -1078,7 +1222,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Value)
   GOOGLE_DCHECK_NE(&from, this);
   const Value* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Value>(
+      ::google::protobuf::DynamicCastToGenerated<Value>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Value)
@@ -1166,14 +1310,14 @@
 }
 void Value::InternalSwap(Value* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   swap(kind_, other->kind_);
   swap(_oneof_case_[0], other->_oneof_case_[0]);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata Value::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fstruct_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fstruct_2eproto[kIndexInFileMessages];
 }
 
 
@@ -1181,14 +1325,16 @@
 
 void ListValue::InitAsDefaultInstance() {
 }
+class ListValue::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int ListValue::kValuesFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 ListValue::ListValue()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fstruct_2eproto::scc_info_ListValue.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.ListValue)
 }
@@ -1196,7 +1342,6 @@
   : ::google::protobuf::Message(),
   _internal_metadata_(arena),
   values_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fstruct_2eproto::scc_info_ListValue.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.ListValue)
@@ -1210,6 +1355,8 @@
 }
 
 void ListValue::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto.base);
 }
 
 ListValue::~ListValue() {
@@ -1230,13 +1377,8 @@
 void ListValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* ListValue::descriptor() {
-  ::protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const ListValue& ListValue::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fstruct_2eproto::scc_info_ListValue.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -1251,9 +1393,64 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ListValue::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ListValue*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // repeated .google.protobuf.Value values = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::Value::_InternalParse;
+          object = msg->add_values();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 10 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool ListValue::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.ListValue)
   for (;;) {
@@ -1263,8 +1460,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // repeated .google.protobuf.Value values = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_values()));
         } else {
@@ -1292,6 +1488,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void ListValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -1308,9 +1505,9 @@
       output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.ListValue)
 }
@@ -1330,9 +1527,9 @@
         1, this->values(static_cast<int>(i)), deterministic, target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ListValue)
   return target;
@@ -1342,11 +1539,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.ListValue)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.Value values = 1;
   {
     unsigned int count = static_cast<unsigned int>(this->values_size());
@@ -1367,7 +1568,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ListValue)
   GOOGLE_DCHECK_NE(&from, this);
   const ListValue* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const ListValue>(
+      ::google::protobuf::DynamicCastToGenerated<ListValue>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.ListValue)
@@ -1427,13 +1628,13 @@
 }
 void ListValue::InternalSwap(ListValue* other) {
   using std::swap;
-  CastToBase(&values_)->InternalSwap(CastToBase(&other->values_));
   _internal_metadata_.Swap(&other->_internal_metadata_);
+  CastToBase(&values_)->InternalSwap(CastToBase(&other->values_));
 }
 
 ::google::protobuf::Metadata ListValue::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fstruct_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fstruct_2eproto[kIndexInFileMessages];
 }
 
 
diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h
index 1cf75d9..fa1f568 100644
--- a/src/google/protobuf/struct.pb.h
+++ b/src/google/protobuf/struct.pb.h
@@ -4,18 +4,18 @@
 #ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto
 #define PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto
 
+#include <limits>
 #include <string>
 
 #include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 3006001
+#if GOOGLE_PROTOBUF_VERSION < 3006000
 #error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please update
+#error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
 #if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
 #error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please
+#error incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.
 #endif
 
@@ -35,20 +35,22 @@
 #include <google/protobuf/generated_enum_reflection.h>
 #include <google/protobuf/unknown_field_set.h>
 // @@protoc_insertion_point(includes)
-#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fstruct_2eproto LIBPROTOBUF_EXPORT
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fstruct_2eproto LIBPROTOBUF_EXPORT
 
-namespace protobuf_google_2fprotobuf_2fstruct_2eproto {
 // Internal implementation detail -- do not use these members.
-struct LIBPROTOBUF_EXPORT TableStruct {
-  static const ::google::protobuf::internal::ParseTableField entries[];
-  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
-  static const ::google::protobuf::internal::ParseTable schema[4];
+struct LIBPROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fstruct_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[4]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
   static const ::google::protobuf::uint32 offsets[];
 };
-void LIBPROTOBUF_EXPORT AddDescriptors();
-}  // namespace protobuf_google_2fprotobuf_2fstruct_2eproto
+void LIBPROTOBUF_EXPORT AddDescriptors_google_2fprotobuf_2fstruct_2eproto();
 namespace google {
 namespace protobuf {
 class ListValue;
@@ -63,10 +65,6 @@
 class Value;
 class ValueDefaultTypeInternal;
 LIBPROTOBUF_EXPORT extern ValueDefaultTypeInternal _Value_default_instance_;
-}  // namespace protobuf
-}  // namespace google
-namespace google {
-namespace protobuf {
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::ListValue* Arena::CreateMaybeMessage<::google::protobuf::ListValue>(Arena*);
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::Struct* Arena::CreateMaybeMessage<::google::protobuf::Struct>(Arena*);
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::Struct_FieldsEntry_DoNotUse* Arena::CreateMaybeMessage<::google::protobuf::Struct_FieldsEntry_DoNotUse>(Arena*);
@@ -78,8 +76,8 @@
 
 enum NullValue {
   NULL_VALUE = 0,
-  NullValue_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,
-  NullValue_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
+  NullValue_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  NullValue_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
 };
 LIBPROTOBUF_EXPORT bool NullValue_IsValid(int value);
 const NullValue NullValue_MIN = NULL_VALUE;
@@ -104,6 +102,9 @@
     ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE,
     0 > {
 public:
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   typedef ::google::protobuf::internal::MapEntry<Struct_FieldsEntry_DoNotUse, 
     ::std::string, ::google::protobuf::Value,
     ::google::protobuf::internal::WireFormatLite::TYPE_STRING,
@@ -151,7 +152,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Struct& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -185,8 +188,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -230,6 +238,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Struct)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -242,7 +251,7 @@
       ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE,
       0 > fields_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -278,7 +287,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Value& default_instance();
 
   enum KindCase {
@@ -322,8 +333,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -389,11 +405,11 @@
   ::std::string* mutable_string_value();
   ::std::string* release_string_value();
   void set_allocated_string_value(::std::string* string_value);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_string_value();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_string_value(
@@ -412,9 +428,6 @@
   bool has_struct_value() const;
   void clear_struct_value();
   static const int kStructValueFieldNumber = 5;
-  private:
-  const ::google::protobuf::Struct& _internal_struct_value() const;
-  public:
   const ::google::protobuf::Struct& struct_value() const;
   ::google::protobuf::Struct* release_struct_value();
   ::google::protobuf::Struct* mutable_struct_value();
@@ -427,9 +440,6 @@
   bool has_list_value() const;
   void clear_list_value();
   static const int kListValueFieldNumber = 6;
-  private:
-  const ::google::protobuf::ListValue& _internal_list_value() const;
-  public:
   const ::google::protobuf::ListValue& list_value() const;
   ::google::protobuf::ListValue* release_list_value();
   ::google::protobuf::ListValue* mutable_list_value();
@@ -442,6 +452,7 @@
   KindCase kind_case() const;
   // @@protoc_insertion_point(class_scope:google.protobuf.Value)
  private:
+  class HasBitSetters;
   void set_has_null_value();
   void set_has_number_value();
   void set_has_string_value();
@@ -468,7 +479,7 @@
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   ::google::protobuf::uint32 _oneof_case_[1];
 
-  friend struct ::protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -504,7 +515,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const ListValue& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -538,8 +551,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -585,6 +603,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.ListValue)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -592,7 +611,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value > values_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto;
 };
 // ===================================================================
 
@@ -776,14 +795,12 @@
   }
 }
 inline void Value::set_allocated_string_value(::std::string* string_value) {
-  if (!has_string_value()) {
-    kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (has_kind()) {
+    clear_kind();
   }
-  clear_kind();
   if (string_value != NULL) {
     set_has_string_value();
-    kind_.string_value_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), string_value,
-        GetArenaNoVirtual());
+    kind_.string_value_.UnsafeSetDefault(string_value);
   }
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.string_value)
 }
@@ -855,9 +872,6 @@
     clear_has_kind();
   }
 }
-inline const ::google::protobuf::Struct& Value::_internal_struct_value() const {
-  return *kind_.struct_value_;
-}
 inline ::google::protobuf::Struct* Value::release_struct_value() {
   // @@protoc_insertion_point(field_release:google.protobuf.Value.struct_value)
   if (has_struct_value()) {
@@ -923,9 +937,6 @@
     clear_has_kind();
   }
 }
-inline const ::google::protobuf::ListValue& Value::_internal_list_value() const {
-  return *kind_.list_value_;
-}
 inline ::google::protobuf::ListValue* Value::release_list_value() {
   // @@protoc_insertion_point(field_release:google.protobuf.Value.list_value)
   if (has_list_value()) {
@@ -1048,4 +1059,5 @@
 
 // @@protoc_insertion_point(global_scope)
 
+#include <google/protobuf/port_undef.inc>
 #endif  // PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto
diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc
index 193436f..4b65eb8 100644
--- a/src/google/protobuf/stubs/common.cc
+++ b/src/google/protobuf/stubs/common.cc
@@ -30,7 +30,6 @@
 
 // Author: kenton@google.com (Kenton Varda)
 
-#include <google/protobuf/message_lite.h>  // TODO(gerbens) ideally remove this.
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/once.h>
 #include <google/protobuf/stubs/status.h>
diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h
index fd8ba15..a093b40 100644
--- a/src/google/protobuf/stubs/hash.h
+++ b/src/google/protobuf/stubs/hash.h
@@ -29,8 +29,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Author: kenton@google.com (Kenton Varda)
-//
-// Deals with the fact that hash_map is not defined everywhere.
 
 #ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__
 #define GOOGLE_PROTOBUF_STUBS_HASH_H__
@@ -38,304 +36,19 @@
 #include <string.h>
 #include <google/protobuf/stubs/common.h>
 
-#define GOOGLE_PROTOBUF_HAVE_HASH_MAP 1
-#define GOOGLE_PROTOBUF_HAVE_HASH_SET 1
-
-// Use C++11 unordered_{map|set} if available.
-#if ((defined(_LIBCPP_STD_VER) && _LIBCPP_STD_VER >= 11) || \
-    (((__cplusplus >= 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X)) && \
-    (__GLIBCXX__ > 20090421)))
-# define GOOGLE_PROTOBUF_HAS_CXX11_HASH
-
-// For XCode >= 4.6:  the compiler is clang with libc++.
-// For earlier XCode version: the compiler is gcc-4.2.1 with libstdc++.
-// libc++ provides <unordered_map> and friends even in non C++11 mode,
-// and it does not provide the tr1 library. Therefore the following macro
-// checks against this special case.
-// Note that we should not test the __APPLE_CC__ version number or the
-// __clang__ macro, since the new compiler can still use -stdlib=libstdc++, in
-// which case <unordered_map> is not compilable without -std=c++11
-#elif defined(__APPLE_CC__)
-# if __GNUC__ >= 4
-#  define GOOGLE_PROTOBUF_HAS_TR1
-# else
-// Not tested for gcc < 4... These setting can compile under 4.2.1 though.
-#  define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx
-#  include <ext/hash_map>
-#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
-#  include <ext/hash_set>
-#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
-# endif
-
-// Version checks for gcc.
-#elif defined(__GNUC__)
-// For GCC 4.x+, use tr1::unordered_map/set; otherwise, follow the
-// instructions from:
-// https://gcc.gnu.org/onlinedocs/libstdc++/manual/backwards.html
-# if __GNUC__ >= 4
-#  define GOOGLE_PROTOBUF_HAS_TR1
-# elif __GNUC__ >= 3
-#  include <backward/hash_map>
-#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
-#  include <backward/hash_set>
-#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
-#  if __GNUC__ == 3 && __GNUC_MINOR__ == 0
-#   define GOOGLE_PROTOBUF_HASH_NAMESPACE std       // GCC 3.0
-#  else
-#   define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx // GCC 3.1 and later
-#  endif
-# else
-#  define GOOGLE_PROTOBUF_HASH_NAMESPACE
-#  include <hash_map>
-#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
-#  include <hash_set>
-#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
-# endif
-
-// GCC <= 4.1 does not define std::tr1::hash for `long long int` or `long long unsigned int`
-# if __GNUC__ == 4 && defined(__GNUC_MINOR__) && __GNUC_MINOR__ <= 1
-#  undef GOOGLE_PROTOBUF_HAS_TR1
-#  undef GOOGLE_PROTOBUF_HAVE_HASH_MAP
-#  undef GOOGLE_PROTOBUF_HAVE_HASH_SET
-# endif
-
-// Version checks for MSC.
-// Apparently Microsoft decided to move hash_map *back* to the std namespace in
-// MSVC 2010:
-// http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx
-// And.. they are moved back to stdext in MSVC 2013 (haven't checked 2012). That
-// said, use unordered_map for MSVC 2010 and beyond is our safest bet.
-#elif defined(_MSC_VER)
-# if _MSC_VER >= 1600  // Since Visual Studio 2010
-#  define GOOGLE_PROTOBUF_HAS_CXX11_HASH
-#  define GOOGLE_PROTOBUF_HASH_COMPARE std::hash_compare
-# elif _MSC_VER >= 1500  // Since Visual Studio 2008
-#  define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext
-#  include <hash_map>
-#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
-#  include <hash_set>
-#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
-#  define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
-#  define GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE
-# elif _MSC_VER >= 1310
-#  define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext
-#  include <hash_map>
-#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
-#  include <hash_set>
-#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
-#  define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
-# else
-#  define GOOGLE_PROTOBUF_HASH_NAMESPACE std
-#  include <hash_map>
-#  define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
-#  include <hash_set>
-#  define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
-#  define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
-# endif
-
-// **ADD NEW COMPILERS SUPPORT HERE.**
-// For other compilers, undefine the macro and fallback to use std::map, in
-// google/protobuf/stubs/hash.h
-#else
-# undef GOOGLE_PROTOBUF_HAVE_HASH_MAP
-# undef GOOGLE_PROTOBUF_HAVE_HASH_SET
-#endif
-
-#if defined(GOOGLE_PROTOBUF_HAS_CXX11_HASH)
-# define GOOGLE_PROTOBUF_HASH_NAMESPACE std
-# include <unordered_map>
-# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map
-# include <unordered_set>
-# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
-#elif defined(GOOGLE_PROTOBUF_HAS_TR1)
-# define GOOGLE_PROTOBUF_HASH_NAMESPACE std::tr1
-# include <tr1/unordered_map>
-# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map
-# include <tr1/unordered_set>
-# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
-#endif
+#include <unordered_map>
+#include <unordered_set>
 
 # define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START \
   namespace google {                                      \
   namespace protobuf {
 # define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END }}
 
-#undef GOOGLE_PROTOBUF_HAS_CXX11_HASH
-#undef GOOGLE_PROTOBUF_HAS_TR1
-
-#if defined(GOOGLE_PROTOBUF_HAVE_HASH_MAP) && \
-    defined(GOOGLE_PROTOBUF_HAVE_HASH_SET)
-#else
-#define GOOGLE_PROTOBUF_MISSING_HASH
-#include <map>
-#include <set>
-#endif
-
 namespace google {
 namespace protobuf {
 
-#ifdef GOOGLE_PROTOBUF_MISSING_HASH
-#undef GOOGLE_PROTOBUF_MISSING_HASH
-
-// This system doesn't have hash_map or hash_set.  Emulate them using map and
-// set.
-
-// Make hash<T> be the same as less<T>.  Note that everywhere where custom
-// hash functions are defined in the protobuf code, they are also defined such
-// that they can be used as "less" functions, which is required by MSVC anyway.
 template <typename Key>
-struct hash {
-  // Dummy, just to make derivative hash functions compile.
-  int operator()(const Key& key) {
-    GOOGLE_LOG(FATAL) << "Should never be called.";
-    return 0;
-  }
-
-  inline bool operator()(const Key& a, const Key& b) const {
-    return a < b;
-  }
-};
-
-// Make sure char* is compared by value.
-template <>
-struct hash<const char*> {
-  // Dummy, just to make derivative hash functions compile.
-  int operator()(const char* key) {
-    GOOGLE_LOG(FATAL) << "Should never be called.";
-    return 0;
-  }
-
-  inline bool operator()(const char* a, const char* b) const {
-    return strcmp(a, b) < 0;
-  }
-};
-
-template <typename Key, typename Data,
-          typename HashFcn = hash<Key>,
-          typename EqualKey = std::equal_to<Key>,
-          typename Alloc = std::allocator< std::pair<const Key, Data> > >
-class hash_map : public std::map<Key, Data, HashFcn, Alloc> {
-  typedef std::map<Key, Data, HashFcn, Alloc> BaseClass;
-
- public:
-  hash_map(int a = 0, const HashFcn& b = HashFcn(),
-           const EqualKey& c = EqualKey(),
-           const Alloc& d = Alloc()) : BaseClass(b, d) {}
-
-  HashFcn hash_function() const { return HashFcn(); }
-};
-
-template <typename Key,
-          typename HashFcn = hash<Key>,
-          typename EqualKey = std::equal_to<Key> >
-class hash_set : public std::set<Key, HashFcn> {
- public:
-  hash_set(int = 0) {}
-
-  HashFcn hash_function() const { return HashFcn(); }
-};
-
-#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION) && \
-    !(defined(_LIBCPP_STD_VER) && _LIBCPP_STD_VER >= 11)
-
-template <typename Key>
-struct hash : public GOOGLE_PROTOBUF_HASH_COMPARE<Key> {
-};
-
-// MSVC's hash_compare<const char*> hashes based on the string contents but
-// compares based on the string pointer.  WTF?
-class CstringLess {
- public:
-  inline bool operator()(const char* a, const char* b) const {
-    return strcmp(a, b) < 0;
-  }
-};
-
-template <>
-struct hash<const char*>
-    : public GOOGLE_PROTOBUF_HASH_COMPARE<const char*, CstringLess> {};
-
-#ifdef GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE
-
-template <typename Key, typename HashFcn, typename EqualKey>
-struct InternalHashCompare : public GOOGLE_PROTOBUF_HASH_COMPARE<Key> {
-  InternalHashCompare() {}
-  InternalHashCompare(HashFcn hashfcn, EqualKey equalkey)
-      : hashfcn_(hashfcn), equalkey_(equalkey) {}
-  size_t operator()(const Key& key) const { return hashfcn_(key); }
-  bool operator()(const Key& key1, const Key& key2) const {
-    return !equalkey_(key1, key2);
-  }
-  HashFcn hashfcn_;
-  EqualKey equalkey_;
-};
-
-template <typename Key, typename Data,
-          typename HashFcn = hash<Key>,
-          typename EqualKey = std::equal_to<Key>,
-          typename Alloc = std::allocator< std::pair<const Key, Data> > >
-class hash_map
-    : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
-          Key, Data, InternalHashCompare<Key, HashFcn, EqualKey>, Alloc> {
-  typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
-      Key, Data, InternalHashCompare<Key, HashFcn, EqualKey>, Alloc> BaseClass;
-
- public:
-  hash_map(int a = 0, const HashFcn& b = HashFcn(),
-           const EqualKey& c = EqualKey(), const Alloc& d = Alloc())
-      : BaseClass(InternalHashCompare<Key, HashFcn, EqualKey>(b, c), d) {}
-
-  HashFcn hash_function() const { return HashFcn(); }
-};
-
-template <typename Key, typename HashFcn = hash<Key>,
-          typename EqualKey = std::equal_to<Key> >
-class hash_set
-    : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS<
-          Key, InternalHashCompare<Key, HashFcn, EqualKey> > {
- public:
-  hash_set(int = 0) {}
-
-  HashFcn hash_function() const { return HashFcn(); }
-};
-
-#else  // GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE
-
-template <typename Key, typename Data,
-          typename HashFcn = hash<Key>,
-          typename EqualKey = std::equal_to<Key>,
-          typename Alloc = std::allocator< std::pair<const Key, Data> > >
-class hash_map
-    : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
-          Key, Data, HashFcn, EqualKey, Alloc> {
-  typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
-      Key, Data, HashFcn, EqualKey, Alloc> BaseClass;
-
- public:
-  hash_map(int a = 0, const HashFcn& b = HashFcn(),
-           const EqualKey& c = EqualKey(),
-           const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {}
-
-  HashFcn hash_function() const { return HashFcn(); }
-};
-
-template <typename Key, typename HashFcn = hash<Key>,
-          typename EqualKey = std::equal_to<Key> >
-class hash_set
-    : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS<
-          Key, HashFcn, EqualKey> {
- public:
-  hash_set(int = 0) {}
-
-  HashFcn hash_function() const { return HashFcn(); }
-};
-#endif  // GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE
-
-#else  // defined(_MSC_VER) && !defined(_STLPORT_VERSION)
-
-template <typename Key>
-struct hash : public GOOGLE_PROTOBUF_HASH_NAMESPACE::hash<Key> {
-};
+struct hash : public std::hash<Key> {};
 
 template <typename Key>
 struct hash<const Key*> {
@@ -364,37 +77,6 @@
   }
 };
 
-template <typename Key, typename Data,
-          typename HashFcn = hash<Key>,
-          typename EqualKey = std::equal_to<Key>,
-          typename Alloc = std::allocator< std::pair<const Key, Data> > >
-class hash_map
-    : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
-          Key, Data, HashFcn, EqualKey, Alloc> {
-  typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
-      Key, Data, HashFcn, EqualKey, Alloc> BaseClass;
-
- public:
-  hash_map(int a = 0, const HashFcn& b = HashFcn(),
-           const EqualKey& c = EqualKey(),
-           const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {}
-
-  HashFcn hash_function() const { return HashFcn(); }
-};
-
-template <typename Key, typename HashFcn = hash<Key>,
-          typename EqualKey = std::equal_to<Key> >
-class hash_set
-    : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS<
-          Key, HashFcn, EqualKey> {
- public:
-  hash_set(int = 0) {}
-
-  HashFcn hash_function() const { return HashFcn(); }
-};
-
-#endif  // !GOOGLE_PROTOBUF_MISSING_HASH
-
 template <>
 struct hash<string> {
   inline size_t operator()(const string& key) const {
diff --git a/src/google/protobuf/stubs/io_win32_unittest.cc b/src/google/protobuf/stubs/io_win32_unittest.cc
index b939276..6c70d46 100644
--- a/src/google/protobuf/stubs/io_win32_unittest.cc
+++ b/src/google/protobuf/stubs/io_win32_unittest.cc
@@ -63,17 +63,17 @@
 const char kUtf8Text[] = {
     'h', 'i', ' ',
     // utf-8: 11010000 10011111, utf-16: 100 0001 1111 = 0x041F
-    0xd0, 0x9f,
+    static_cast<char>(0xd0), static_cast<char>(0x9f),
     // utf-8: 11010001 10000000, utf-16: 100 0100 0000 = 0x0440
-    0xd1, 0x80,
+    static_cast<char>(0xd1), static_cast<char>(0x80),
     // utf-8: 11010000 10111000, utf-16: 100 0011 1000 = 0x0438
-    0xd0, 0xb8,
+    static_cast<char>(0xd0), static_cast<char>(0xb8),
     // utf-8: 11010000 10110010, utf-16: 100 0011 0010 = 0x0432
-    0xd0, 0xb2,
+    static_cast<char>(0xd0), static_cast<char>(0xb2),
     // utf-8: 11010000 10110101, utf-16: 100 0011 0101 = 0x0435
-    0xd0, 0xb5,
+    static_cast<char>(0xd0), static_cast<char>(0xb5),
     // utf-8: 11010001 10000010, utf-16: 100 0100 0010 = 0x0442
-    0xd1, 0x82, 0
+    static_cast<char>(0xd1), static_cast<char>(0x82), 0
 };
 
 const wchar_t kUtf16Text[] = {
diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h
index 3aa6403..4d3d000 100644
--- a/src/google/protobuf/stubs/port.h
+++ b/src/google/protobuf/stubs/port.h
@@ -99,6 +99,7 @@
 #endif
 
 #define PROTOBUF_RUNTIME_DEPRECATED(message)
+#define GOOGLE_PROTOBUF_RUNTIME_DEPRECATED(message)
 
 // ===================================================================
 // from google3/base/port.h
@@ -175,6 +176,9 @@
 static const uint32 kuint32max = 0xFFFFFFFFu;
 static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF);
 
+#define GOOGLE_PROTOBUF_NAMESPACE "google::protobuf"
+#define GOOGLE_PROTOBUF_NAMESPACE_ID google::protobuf
+
 // -------------------------------------------------------------------
 // Annotations:  Some parts of the code have been annotated in ways that might
 //   be useful to some compilers or tools, but are not supported universally.
diff --git a/src/google/protobuf/stubs/stringpiece.h b/src/google/protobuf/stubs/stringpiece.h
index 472696b..6ab985c 100644
--- a/src/google/protobuf/stubs/stringpiece.h
+++ b/src/google/protobuf/stubs/stringpiece.h
@@ -463,6 +463,9 @@
   std::string ToString() const {
     return std::string(data_, static_cast<size_t>(size_));
   }
+
+  operator string() const { return ToString(); }
+
  private:
   const char* data_;
   stringpiece_ssize_type size_;
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc
index 059dada..5bf9f2e 100644
--- a/src/google/protobuf/stubs/strutil.cc
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -31,14 +31,14 @@
 // from google3/strings/strutil.cc
 
 #include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/stubs/mathlimits.h>
 
 #include <errno.h>
 #include <float.h>    // FLT_DIG and DBL_DIG
-#include <limits>
 #include <limits.h>
 #include <stdio.h>
+#include <cmath>
 #include <iterator>
+#include <limits>
 
 #include <google/protobuf/stubs/stl_util.h>
 
@@ -1268,7 +1268,7 @@
   } else if (value == -std::numeric_limits<double>::infinity()) {
     strcpy(buffer, "-inf");
     return buffer;
-  } else if (MathLimits<double>::IsNaN(value)) {
+  } else if (std::isnan(value)) {
     strcpy(buffer, "nan");
     return buffer;
   }
@@ -1386,7 +1386,7 @@
   } else if (value == -std::numeric_limits<double>::infinity()) {
     strcpy(buffer, "-inf");
     return buffer;
-  } else if (MathLimits<float>::IsNaN(value)) {
+  } else if (std::isnan(value)) {
     strcpy(buffer, "nan");
     return buffer;
   }
@@ -2300,5 +2300,110 @@
   return kUTF8LenTbl[*reinterpret_cast<const uint8*>(src)];
 }
 
+// ----------------------------------------------------------------------
+// CleanStringLineEndings()
+//   Clean up a multi-line string to conform to Unix line endings.
+//   Reads from src and appends to dst, so usually dst should be empty.
+//
+//   If there is no line ending at the end of a non-empty string, it can
+//   be added automatically.
+//
+//   Four different types of input are correctly handled:
+//
+//     - Unix/Linux files: line ending is LF: pass through unchanged
+//
+//     - DOS/Windows files: line ending is CRLF: convert to LF
+//
+//     - Legacy Mac files: line ending is CR: convert to LF
+//
+//     - Garbled files: random line endings: convert gracefully
+//                      lonely CR, lonely LF, CRLF: convert to LF
+//
+//   @param src The multi-line string to convert
+//   @param dst The converted string is appended to this string
+//   @param auto_end_last_line Automatically terminate the last line
+//
+//   Limitations:
+//
+//     This does not do the right thing for CRCRLF files created by
+//     broken programs that do another Unix->DOS conversion on files
+//     that are already in CRLF format.  For this, a two-pass approach
+//     brute-force would be needed that
+//
+//       (1) determines the presence of LF (first one is ok)
+//       (2) if yes, removes any CR, else convert every CR to LF
+
+void CleanStringLineEndings(const string &src, string *dst,
+                            bool auto_end_last_line) {
+  if (dst->empty()) {
+    dst->append(src);
+    CleanStringLineEndings(dst, auto_end_last_line);
+  } else {
+    string tmp = src;
+    CleanStringLineEndings(&tmp, auto_end_last_line);
+    dst->append(tmp);
+  }
+}
+
+void CleanStringLineEndings(string *str, bool auto_end_last_line) {
+  ptrdiff_t output_pos = 0;
+  bool r_seen = false;
+  ptrdiff_t len = str->size();
+
+  char *p = &(*str)[0];
+
+  for (ptrdiff_t input_pos = 0; input_pos < len;) {
+    if (!r_seen && input_pos + 8 < len) {
+      uint64_t v = GOOGLE_UNALIGNED_LOAD64(p + input_pos);
+      // Loop over groups of 8 bytes at a time until we come across
+      // a word that has a byte whose value is less than or equal to
+      // '\r' (i.e. could contain a \n (0x0a) or a \r (0x0d) ).
+      //
+      // We use a has_less macro that quickly tests a whole 64-bit
+      // word to see if any of the bytes has a value < N.
+      //
+      // For more details, see:
+      //   http://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord
+#define has_less(x, n) (((x) - ~0ULL / 255 * (n)) & ~(x) & ~0ULL / 255 * 128)
+      if (!has_less(v, '\r' + 1)) {
+#undef has_less
+        // No byte in this word has a value that could be a \r or a \n
+        if (output_pos != input_pos) {
+          GOOGLE_UNALIGNED_STORE64(p + output_pos, v);
+        }
+        input_pos += 8;
+        output_pos += 8;
+        continue;
+      }
+    }
+    string::const_reference in = p[input_pos];
+    if (in == '\r') {
+      if (r_seen) p[output_pos++] = '\n';
+      r_seen = true;
+    } else if (in == '\n') {
+      if (input_pos != output_pos)
+        p[output_pos++] = '\n';
+      else
+        output_pos++;
+      r_seen = false;
+    } else {
+      if (r_seen) p[output_pos++] = '\n';
+      r_seen = false;
+      if (input_pos != output_pos)
+        p[output_pos++] = in;
+      else
+        output_pos++;
+    }
+    input_pos++;
+  }
+  if (r_seen ||
+      (auto_end_last_line && output_pos > 0 && p[output_pos - 1] != '\n')) {
+    str->resize(output_pos + 1);
+    str->operator[](output_pos) = '\n';
+  } else if (output_pos < len) {
+    str->resize(output_pos);
+  }
+}
+
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h
index e34b998..ec5512d 100644
--- a/src/google/protobuf/stubs/strutil.h
+++ b/src/google/protobuf/stubs/strutil.h
@@ -872,6 +872,56 @@
 // ----------------------------------------------------------------------
 LIBPROTOBUF_EXPORT int UTF8FirstLetterNumBytes(const char* src, int len);
 
+// From google3/third_party/absl/strings/escaping.h
+
+// ----------------------------------------------------------------------
+// CleanStringLineEndings()
+//   Clean up a multi-line string to conform to Unix line endings.
+//   Reads from src and appends to dst, so usually dst should be empty.
+//
+//   If there is no line ending at the end of a non-empty string, it can
+//   be added automatically.
+//
+//   Four different types of input are correctly handled:
+//
+//     - Unix/Linux files: line ending is LF: pass through unchanged
+//
+//     - DOS/Windows files: line ending is CRLF: convert to LF
+//
+//     - Legacy Mac files: line ending is CR: convert to LF
+//
+//     - Garbled files: random line endings: convert gracefully
+//                      lonely CR, lonely LF, CRLF: convert to LF
+//
+//   @param src The multi-line string to convert
+//   @param dst The converted string is appended to this string
+//   @param auto_end_last_line Automatically terminate the last line
+//
+//   Limitations:
+//
+//     This does not do the right thing for CRCRLF files created by
+//     broken programs that do another Unix->DOS conversion on files
+//     that are already in CRLF format.  For this, a two-pass approach
+//     brute-force would be needed that
+//
+//       (1) determines the presence of LF (first one is ok)
+//       (2) if yes, removes any CR, else convert every CR to LF
+LIBPROTOBUF_EXPORT void CleanStringLineEndings(const string& src, string* dst,
+                                               bool auto_end_last_line);
+
+// Same as above, but transforms the argument in place.
+LIBPROTOBUF_EXPORT void CleanStringLineEndings(string* str,
+                                               bool auto_end_last_line);
+
+namespace strings {
+inline bool EndsWith(StringPiece text, StringPiece suffix) {
+  return suffix.empty() ||
+      (text.size() >= suffix.size() &&
+       memcmp(text.data() + (text.size() - suffix.size()), suffix.data(),
+              suffix.size()) == 0);
+}
+}  // namespace strings
+
 }  // namespace protobuf
 }  // namespace google
 
diff --git a/src/google/protobuf/test_util.h b/src/google/protobuf/test_util.h
index b9abb67..0308eb1 100644
--- a/src/google/protobuf/test_util.h
+++ b/src/google/protobuf/test_util.h
@@ -1296,6 +1296,6 @@
 
 }  // namespace TestUtil
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_TEST_UTIL_H__
diff --git a/src/google/protobuf/test_util2.h b/src/google/protobuf/test_util2.h
new file mode 100644
index 0000000..b1c0377
--- /dev/null
+++ b/src/google/protobuf/test_util2.h
@@ -0,0 +1,73 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_TEST_UTIL2_H__
+#define GOOGLE_PROTOBUF_TEST_UTIL2_H__
+
+#include <google/protobuf/stubs/strutil.h>
+
+#include <google/protobuf/testing/googletest.h>
+
+
+namespace google {
+namespace protobuf {
+namespace TestUtil {
+
+// Translate net/proto2/* -> google/protobuf/*
+inline ::std::string TranslatePathToOpensource(const ::std::string& google3_path) {
+  const ::std::string prefix = "net/proto2/";
+  GOOGLE_CHECK(google3_path.find(prefix) == 0) << google3_path;
+  ::std::string path = google3_path.substr(prefix.size());
+
+  path = StringReplace(path, "internal/", "", false);
+  path = StringReplace(path, "proto/", "", false);
+  path = StringReplace(path, "public/", "", false);
+  return "google/protobuf/" + path;
+}
+
+inline ::std::string MaybeTranslatePath(const ::std::string& google3_path) {
+  string path = google3_path;
+  path = TranslatePathToOpensource(path);
+  return path;
+}
+
+inline ::std::string TestSourceDir() {
+  return google::protobuf::TestSourceDir();
+}
+
+inline ::std::string GetTestDataPath(const ::std::string& google3_path) {
+  return TestSourceDir() + "/" + MaybeTranslatePath(google3_path);
+}
+
+}  // namespace TestUtil
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_TEST_UTIL2_H__
diff --git a/src/google/protobuf/test_util_lite.h b/src/google/protobuf/test_util_lite.h
index 47a2269..34edf94 100644
--- a/src/google/protobuf/test_util_lite.h
+++ b/src/google/protobuf/test_util_lite.h
@@ -96,6 +96,6 @@
 };
 
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
index a9c062e..93c24b2 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -33,6 +33,7 @@
 //  Sanjay Ghemawat, Jeff Dean, and others.
 
 #include <algorithm>
+#include <climits>
 #include <float.h>
 #include <math.h>
 #include <stdio.h>
@@ -44,12 +45,12 @@
 
 #include <google/protobuf/stubs/stringprintf.h>
 #include <google/protobuf/any.h>
+#include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/io/strtod.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/tokenizer.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
-#include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/dynamic_message.h>
 #include <google/protobuf/repeated_field.h>
@@ -58,9 +59,12 @@
 #include <google/protobuf/stubs/strutil.h>
 
 
+
+
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/stl_util.h>
 
+
 namespace google {
 namespace protobuf {
 
@@ -212,7 +216,7 @@
 // ===========================================================================
 // Internal class for parsing an ASCII representation of a Protocol Message.
 // This class makes use of the Protocol Message compiler's tokenizer found
-// in //google/protobuf/io/tokenizer.h. Note that class's Parse
+// in //net/proto2/io/public/tokenizer.h. Note that class's Parse
 // method is *not* thread-safe and should only be used in a single thread at
 // a time.
 
@@ -241,6 +245,7 @@
              SingularOverwritePolicy singular_overwrite_policy,
              bool allow_case_insensitive_field,
              bool allow_unknown_field,
+             bool allow_unknown_extension,
              bool allow_unknown_enum,
              bool allow_field_number,
              bool allow_relaxed_whitespace,
@@ -254,6 +259,7 @@
       singular_overwrite_policy_(singular_overwrite_policy),
       allow_case_insensitive_field_(allow_case_insensitive_field),
       allow_unknown_field_(allow_unknown_field),
+      allow_unknown_extension_(allow_unknown_extension),
       allow_unknown_enum_(allow_unknown_enum),
       allow_field_number_(allow_field_number),
       allow_partial_(allow_partial),
@@ -433,7 +439,7 @@
                       : DefaultFinderFindExtension(message, field_name);
 
       if (field == NULL) {
-        if (!allow_unknown_field_) {
+        if (!allow_unknown_field_ && !allow_unknown_extension_) {
           ReportError("Extension \"" + field_name + "\" is not defined or "
                       "is not an extension of \"" +
                       descriptor->full_name() + "\".");
@@ -448,7 +454,8 @@
       DO(ConsumeIdentifier(&field_name));
 
       int32 field_number;
-      if (allow_field_number_ && safe_strto32(field_name, &field_number)) {
+      if (allow_field_number_ &&
+          safe_strto32(field_name, &field_number)) {
         if (descriptor->IsExtensionNumber(field_number)) {
           field = reflection->FindKnownExtensionByNumber(field_number);
         } else if (descriptor->IsReservedNumber(field_number)) {
@@ -501,7 +508,7 @@
 
     // Skips unknown or reserved fields.
     if (field == NULL) {
-      GOOGLE_CHECK(allow_unknown_field_ || reserved_field);
+      GOOGLE_CHECK(allow_unknown_field_ || allow_unknown_extension_ || reserved_field);
 
       // Try to guess the type of this field.
       // If this field is not a message, there should be a ":" between the
@@ -758,7 +765,7 @@
                    LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
           int64 int_value;
           DO(ConsumeSignedInteger(&int_value, kint32max));
-          value = SimpleItoa(int_value);        // for error reporting
+          value = SimpleItoa(int_value);  // for error reporting
           enum_value = enum_type->FindValueByNumber(int_value);
         } else {
           ReportError("Expected integer or identifier, got: " +
@@ -882,8 +889,9 @@
 
     // If allow_field_numer_ or allow_unknown_field_ is true, we should able
     // to parse integer identifiers.
-    if ((allow_field_number_ || allow_unknown_field_)
-        && LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+    if ((allow_field_number_ || allow_unknown_field_ ||
+         allow_unknown_extension_) &&
+        LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
       *identifier = tokenizer_.current().text;
       tokenizer_.Next();
       return true;
@@ -1138,7 +1146,7 @@
     explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) :
         parser_(parser) { }
 
-    ~ParserErrorCollector() override { }
+    ~ParserErrorCollector() override {}
 
     void AddError(int line, int column, const string& message) override {
       parser_->ReportError(line, column, message);
@@ -1162,17 +1170,16 @@
   SingularOverwritePolicy singular_overwrite_policy_;
   const bool allow_case_insensitive_field_;
   const bool allow_unknown_field_;
+  const bool allow_unknown_extension_;
   const bool allow_unknown_enum_;
   const bool allow_field_number_;
   const bool allow_partial_;
   bool had_errors_;
 };
 
-#undef DO
-
 // ===========================================================================
 // Internal class for writing text to the io::ZeroCopyOutputStream. Adapted
-// from the Printer found in //google/protobuf/io/printer.h
+// from the Printer found in //net/proto2/io/public/printer.h
 class TextFormat::Printer::TextGenerator
     : public TextFormat::BaseTextGenerator {
  public:
@@ -1334,6 +1341,7 @@
     allow_partial_(false),
     allow_case_insensitive_field_(false),
     allow_unknown_field_(false),
+    allow_unknown_extension_(false),
     allow_unknown_enum_(false),
     allow_field_number_(false),
     allow_relaxed_whitespace_(false),
@@ -1342,6 +1350,22 @@
 
 TextFormat::Parser::~Parser() {}
 
+namespace {
+
+bool CheckParseInputSize(StringPiece input,
+                         io::ErrorCollector* error_collector) {
+  if (input.size() > INT_MAX) {
+    error_collector->AddError(
+        -1, 0, StrCat("Input size too large: ",
+                      static_cast<int64>(input.size()), " bytes",
+                      " > ", INT_MAX, " bytes."));
+    return false;
+  }
+  return true;
+}
+
+}  // namespace
+
 bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
                                Message* output) {
   output->Clear();
@@ -1351,17 +1375,17 @@
       ? ParserImpl::ALLOW_SINGULAR_OVERWRITES
       : ParserImpl::FORBID_SINGULAR_OVERWRITES;
 
-  ParserImpl parser(output->GetDescriptor(), input, error_collector_,
-                    finder_, parse_info_tree_,
-                    overwrites_policy,
-                    allow_case_insensitive_field_, allow_unknown_field_,
-                    allow_unknown_enum_, allow_field_number_,
-                    allow_relaxed_whitespace_, allow_partial_);
+  ParserImpl parser(
+      output->GetDescriptor(), input, error_collector_, finder_,
+      parse_info_tree_, overwrites_policy, allow_case_insensitive_field_,
+      allow_unknown_field_, allow_unknown_extension_, allow_unknown_enum_,
+      allow_field_number_, allow_relaxed_whitespace_, allow_partial_);
   return MergeUsingImpl(input, output, &parser);
 }
 
 bool TextFormat::Parser::ParseFromString(const string& input,
                                          Message* output) {
+  DO(CheckParseInputSize(input, error_collector_));
   io::ArrayInputStream input_stream(input.data(), input.size());
   return Parse(&input_stream, output);
 }
@@ -1369,17 +1393,18 @@
 
 bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
                                Message* output) {
-  ParserImpl parser(output->GetDescriptor(), input, error_collector_,
-                    finder_, parse_info_tree_,
-                    ParserImpl::ALLOW_SINGULAR_OVERWRITES,
+  ParserImpl parser(output->GetDescriptor(), input, error_collector_, finder_,
+                    parse_info_tree_, ParserImpl::ALLOW_SINGULAR_OVERWRITES,
                     allow_case_insensitive_field_, allow_unknown_field_,
-                    allow_unknown_enum_, allow_field_number_,
-                    allow_relaxed_whitespace_, allow_partial_);
+                    allow_unknown_extension_, allow_unknown_enum_,
+                    allow_field_number_, allow_relaxed_whitespace_,
+                    allow_partial_);
   return MergeUsingImpl(input, output, &parser);
 }
 
 bool TextFormat::Parser::MergeFromString(const string& input,
                                          Message* output) {
+  DO(CheckParseInputSize(input, error_collector_));
   io::ArrayInputStream input_stream(input.data(), input.size());
   return Merge(&input_stream, output);
 }
@@ -1405,12 +1430,12 @@
     const FieldDescriptor* field,
     Message* output) {
   io::ArrayInputStream input_stream(input.data(), input.size());
-  ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_,
-                    finder_, parse_info_tree_,
-                    ParserImpl::ALLOW_SINGULAR_OVERWRITES,
-                    allow_case_insensitive_field_, allow_unknown_field_,
-                    allow_unknown_enum_, allow_field_number_,
-                    allow_relaxed_whitespace_, allow_partial_);
+  ParserImpl parser(
+      output->GetDescriptor(), &input_stream, error_collector_, finder_,
+      parse_info_tree_, ParserImpl::ALLOW_SINGULAR_OVERWRITES,
+      allow_case_insensitive_field_, allow_unknown_field_,
+      allow_unknown_extension_, allow_unknown_enum_, allow_field_number_,
+      allow_relaxed_whitespace_, allow_partial_);
   return parser.ParseField(field, output);
 }
 
@@ -1435,6 +1460,8 @@
 }
 
 
+#undef DO
+
 // ===========================================================================
 
 TextFormat::BaseTextGenerator::~BaseTextGenerator() {}
@@ -1444,7 +1471,9 @@
 // A BaseTextGenerator that writes to a string.
 class StringBaseTextGenerator : public TextFormat::BaseTextGenerator {
  public:
-  void Print(const char* text, size_t size) override { output_.append(text, size); }
+  void Print(const char* text, size_t size) override {
+    output_.append(text, size);
+  }
 
 // Some compilers do not support ref-qualifiers even in C++11 mode.
 // Disable the optimization for now and revisit it later.
@@ -1642,25 +1671,32 @@
     delegate_.reset(delegate);
   }
 
-  void PrintBool(bool val, TextFormat::BaseTextGenerator* generator) const override {
+  void PrintBool(bool val,
+                 TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintBool(val));
   }
-  void PrintInt32(int32 val, TextFormat::BaseTextGenerator* generator) const override {
+  void PrintInt32(int32 val,
+                  TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintInt32(val));
   }
-  void PrintUInt32(uint32 val, TextFormat::BaseTextGenerator* generator) const override {
+  void PrintUInt32(uint32 val,
+                   TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintUInt32(val));
   }
-  void PrintInt64(int64 val, TextFormat::BaseTextGenerator* generator) const override {
+  void PrintInt64(int64 val,
+                  TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintInt64(val));
   }
-  void PrintUInt64(uint64 val, TextFormat::BaseTextGenerator* generator) const override {
+  void PrintUInt64(uint64 val,
+                   TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintUInt64(val));
   }
-  void PrintFloat(float val, TextFormat::BaseTextGenerator* generator) const override {
+  void PrintFloat(float val,
+                  TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintFloat(val));
   }
-  void PrintDouble(double val, TextFormat::BaseTextGenerator* generator) const override {
+  void PrintDouble(double val,
+                   TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintDouble(val));
   }
   void PrintString(const string& val,
@@ -1688,15 +1724,17 @@
     generator->PrintString(
         delegate_->PrintFieldName(message, reflection, field));
   }
-  void PrintMessageStart(const Message& message, int field_index,
-                         int field_count, bool single_line_mode,
-                         TextFormat::BaseTextGenerator* generator) const override {
+  void PrintMessageStart(
+      const Message& message, int field_index, int field_count,
+      bool single_line_mode,
+      TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintMessageStart(
         message, field_index, field_count, single_line_mode));
   }
-  void PrintMessageEnd(const Message& message, int field_index, int field_count,
-                       bool single_line_mode,
-                       TextFormat::BaseTextGenerator* generator) const override {
+  void PrintMessageEnd(
+      const Message& message, int field_index, int field_count,
+      bool single_line_mode,
+      TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintMessageEnd(
         message, field_index, field_count, single_line_mode));
   }
@@ -1867,7 +1905,7 @@
   }
 
   // Print the "value" in text.
-  const google::protobuf::Descriptor* value_descriptor =
+  const Descriptor* value_descriptor =
       finder_ ? finder_->FindAnyType(message, url_prefix, full_type_name)
               : DefaultFinderFindAnyType(message, url_prefix, full_type_name);
   if (value_descriptor == NULL) {
@@ -1875,7 +1913,7 @@
     return false;
   }
   DynamicMessageFactory factory;
-  std::unique_ptr<google::protobuf::Message> value_message(
+  std::unique_ptr<Message> value_message(
       factory.GetPrototype(value_descriptor)->New());
   string serialized_value = reflection->GetString(message, value_field);
   if (!value_message->ParseFromString(serialized_value)) {
diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h
index d6f3e16..df12f13 100644
--- a/src/google/protobuf/text_format.h
+++ b/src/google/protobuf/text_format.h
@@ -47,6 +47,13 @@
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/message.h>
 #include <google/protobuf/message_lite.h>
+#include <google/protobuf/port.h>
+
+#include <google/protobuf/port_def.inc>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
 
 namespace google {
 namespace protobuf {
@@ -149,8 +156,8 @@
     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FastFieldValuePrinter);
   };
 
-  class LIBPROTOBUF_EXPORT PROTOBUF_RUNTIME_DEPRECATED("Please use FastFieldValuePrinter")
-      FieldValuePrinter {
+  class LIBPROTOBUF_EXPORT GOOGLE_PROTOBUF_DEPRECATED_MSG(
+      "Please use FastFieldValuePrinter") FieldValuePrinter {
    public:
     FieldValuePrinter();
     virtual ~FieldValuePrinter();
@@ -553,6 +560,13 @@
                                    const FieldDescriptor* field,
                                    Message* output);
 
+    // When an unknown extension is met, parsing will fail if this option is set
+    // to false (the default). If true, unknown extensions will be ignored and
+    // a warning message will be generated.
+    void AllowUnknownExtension(bool allow) {
+      allow_unknown_extension_ = allow;
+    }
+
 
     void AllowFieldNumber(bool allow) {
       allow_field_number_ = allow;
@@ -575,6 +589,7 @@
     bool allow_partial_;
     bool allow_case_insensitive_field_;
     bool allow_unknown_field_;
+    bool allow_unknown_extension_;
     bool allow_unknown_enum_;
     bool allow_field_number_;
     bool allow_relaxed_whitespace_;
@@ -609,6 +624,8 @@
 }
 
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_TEXT_FORMAT_H__
diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc
index b0ea578..8df2fe3 100644
--- a/src/google/protobuf/text_format_unittest.cc
+++ b/src/google/protobuf/text_format_unittest.cc
@@ -45,13 +45,14 @@
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/testing/file.h>
 #include <google/protobuf/test_util.h>
+#include <google/protobuf/test_util2.h>
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/unittest_mset.pb.h>
 #include <google/protobuf/unittest_mset_wire_format.pb.h>
 #include <google/protobuf/io/tokenizer.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
-
 #include <google/protobuf/stubs/strutil.h>
+
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
@@ -77,11 +78,12 @@
 class TextFormatTest : public testing::Test {
  public:
   static void SetUpTestCase() {
-    GOOGLE_CHECK_OK(File::GetContentsAsText(
-        TestSourceDir() +
-            "/google/protobuf/"
-            "testdata/text_format_unittest_data_oneof_implemented.txt",
+    GOOGLE_CHECK_OK(File::GetContents(
+        TestUtil::GetTestDataPath(
+            "net/proto2/internal/"
+            "testdata/text_format_unittest_data_oneof_implemented.txt"),
         &static_proto_debug_string_, true));
+    CleanStringLineEndings(&static_proto_debug_string_, false);
   }
 
   TextFormatTest() : proto_debug_string_(static_proto_debug_string_) {}
@@ -99,10 +101,11 @@
 class TextFormatExtensionsTest : public testing::Test {
  public:
   static void SetUpTestCase() {
-    GOOGLE_CHECK_OK(File::GetContentsAsText(TestSourceDir() +
-                                   "/google/protobuf/testdata/"
-                                   "text_format_unittest_extensions_data.txt",
-                               &static_proto_debug_string_, true));
+    GOOGLE_CHECK_OK(File::GetContents(
+        TestUtil::GetTestDataPath("net/proto2/internal/testdata/"
+                                  "text_format_unittest_extensions_data.txt"),
+        &static_proto_debug_string_, true));
+    CleanStringLineEndings(&static_proto_debug_string_, false);
   }
 
   TextFormatExtensionsTest()
@@ -484,7 +487,8 @@
 class CustomMessageFieldValuePrinter : public TextFormat::FieldValuePrinter {
  public:
   virtual string PrintInt32(int32 v) const {
-    return StrCat(FieldValuePrinter::PrintInt32(v), "  # x", strings::Hex(v));
+    return StrCat(FieldValuePrinter::PrintInt32(v), "  # x",
+                        strings::Hex(v));
   }
 
   virtual string PrintMessageStart(const Message& message,
@@ -494,8 +498,8 @@
     if (single_line_mode) {
       return " { ";
     }
-    return StrCat(
-        " {  # ", message.GetDescriptor()->name(), ": ", field_index, "\n");
+    return StrCat(" {  # ", message.GetDescriptor()->name(), ": ",
+                        field_index, "\n");
   }
 };
 
@@ -575,10 +579,10 @@
     }
   }
   // To prevent compiler complaining about Woverloaded-virtual
-  void PrintFieldName(const Message& message,
-                      const Reflection* reflection,
+  void PrintFieldName(const Message& message, const Reflection* reflection,
                       const FieldDescriptor* field,
-                      TextFormat::BaseTextGenerator* generator) const override {}
+                      TextFormat::BaseTextGenerator* generator) const override {
+  }
   void PrintMessageStart(
       const Message& message, int field_index, int field_count,
       bool single_line_mode,
@@ -996,6 +1000,7 @@
 TEST_F(TextFormatTest, PrintFloatPrecision) {
   unittest::TestAllTypes message;
 
+  message.add_repeated_float(1.0);
   message.add_repeated_float(1.2);
   message.add_repeated_float(1.23);
   message.add_repeated_float(1.234);
@@ -1036,6 +1041,7 @@
   message.add_repeated_double(1.23456789876543e100);
 
   EXPECT_EQ(
+    "repeated_float: 1\n"
     "repeated_float: 1.2\n"
     "repeated_float: 1.23\n"
     "repeated_float: 1.234\n"
@@ -1272,7 +1278,8 @@
     parser.RecordErrorsTo(&error_collector);
     EXPECT_EQ(expected_result, parser.ParseFromString(input, proto))
         << input << " -> " << proto->DebugString();
-    EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) + ": " + message + "\n",
+    EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) +
+                  ": " + message + "\n",
               error_collector.text_);
   }
 
diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc
index 4269031..1085791 100644
--- a/src/google/protobuf/timestamp.pb.cc
+++ b/src/google/protobuf/timestamp.pb.cc
@@ -6,8 +6,8 @@
 #include <algorithm>
 
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
@@ -18,18 +18,17 @@
 #include "third_party/protobuf/version.h"
 #endif
 // @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
 
 namespace google {
 namespace protobuf {
 class TimestampDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Timestamp>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Timestamp> _instance;
 } _Timestamp_default_instance_;
 }  // namespace protobuf
 }  // namespace google
-namespace protobuf_google_2fprotobuf_2ftimestamp_2eproto {
-static void InitDefaultsTimestamp() {
+static void InitDefaultsTimestamp_google_2fprotobuf_2ftimestamp_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -40,16 +39,18 @@
   ::google::protobuf::Timestamp::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Timestamp =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsTimestamp}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsTimestamp_google_2fprotobuf_2ftimestamp_2eproto}, {}};
 
-void InitDefaults() {
-  ::google::protobuf::internal::InitSCC(&scc_info_Timestamp.base);
+void InitDefaults_google_2fprotobuf_2ftimestamp_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata[1];
+::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto[1];
+constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr;
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ftimestamp_2eproto = nullptr;
 
-const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2ftimestamp_2eproto::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Timestamp, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -66,51 +67,33 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Timestamp_default_instance_),
 };
 
-static void protobuf_AssignDescriptors() {
-  AddDescriptors();
-  AssignDescriptors(
-      "google/protobuf/timestamp.proto", schemas, file_default_instances, TableStruct::offsets,
-      file_level_metadata, NULL, NULL);
-}
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2ftimestamp_2eproto = {
+  {}, AddDescriptors_google_2fprotobuf_2ftimestamp_2eproto, "google/protobuf/timestamp.proto", schemas,
+  file_default_instances, TableStruct_google_2fprotobuf_2ftimestamp_2eproto::offsets,
+  file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2ftimestamp_2eproto, file_level_service_descriptors_google_2fprotobuf_2ftimestamp_2eproto,
+};
 
-static void protobuf_AssignDescriptorsOnce() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
-}
+::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftimestamp_2eproto = {
+  false, InitDefaults_google_2fprotobuf_2ftimestamp_2eproto, 
+  "\n\037google/protobuf/timestamp.proto\022\017googl"
+  "e.protobuf\"+\n\tTimestamp\022\017\n\007seconds\030\001 \001(\003"
+  "\022\r\n\005nanos\030\002 \001(\005B~\n\023com.google.protobufB\016"
+  "TimestampProtoP\001Z+github.com/golang/prot"
+  "obuf/ptypes/timestamp\370\001\001\242\002\003GPB\252\002\036Google."
+  "Protobuf.WellKnownTypesb\006proto3"
+,
+  "google/protobuf/timestamp.proto", &assign_descriptors_table_google_2fprotobuf_2ftimestamp_2eproto, 231,
+};
 
-void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
-void protobuf_RegisterTypes(const ::std::string&) {
-  protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
-}
-
-static void AddDescriptorsImpl() {
-  InitDefaults();
-  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
-      "\n\037google/protobuf/timestamp.proto\022\017googl"
-      "e.protobuf\"+\n\tTimestamp\022\017\n\007seconds\030\001 \001(\003"
-      "\022\r\n\005nanos\030\002 \001(\005B~\n\023com.google.protobufB\016"
-      "TimestampProtoP\001Z+github.com/golang/prot"
-      "obuf/ptypes/timestamp\370\001\001\242\002\003GPB\252\002\036Google."
-      "Protobuf.WellKnownTypesb\006proto3"
+void AddDescriptors_google_2fprotobuf_2ftimestamp_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
   };
-  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 231);
-  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
-    "google/protobuf/timestamp.proto", &protobuf_RegisterTypes);
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2ftimestamp_2eproto, deps, 0);
 }
 
-void AddDescriptors() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
-}
-// Force AddDescriptors() to be called at dynamic initialization time.
-struct StaticDescriptorInitializer {
-  StaticDescriptorInitializer() {
-    AddDescriptors();
-  }
-} static_descriptor_initializer;
-}  // namespace protobuf_google_2fprotobuf_2ftimestamp_2eproto
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_google_2fprotobuf_2ftimestamp_2eproto = []() { AddDescriptors_google_2fprotobuf_2ftimestamp_2eproto(); return true; }();
 namespace google {
 namespace protobuf {
 
@@ -118,6 +101,10 @@
 
 void Timestamp::InitAsDefaultInstance() {
 }
+class Timestamp::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Timestamp::kSecondsFieldNumber;
 const int Timestamp::kNanosFieldNumber;
@@ -125,15 +112,12 @@
 
 Timestamp::Timestamp()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2ftimestamp_2eproto::scc_info_Timestamp.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Timestamp)
 }
 Timestamp::Timestamp(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2ftimestamp_2eproto::scc_info_Timestamp.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.Timestamp)
@@ -172,13 +156,8 @@
 void Timestamp::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Timestamp::descriptor() {
-  ::protobuf_google_2fprotobuf_2ftimestamp_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ftimestamp_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Timestamp& Timestamp::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2ftimestamp_2eproto::scc_info_Timestamp.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -195,9 +174,68 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Timestamp::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Timestamp*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // int64 seconds = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int64 value = val;
+        msg->set_seconds(value);
+        break;
+      }
+      // int32 nanos = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_nanos(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Timestamp::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Timestamp)
   for (;;) {
@@ -207,8 +245,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // int64 seconds = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
@@ -221,8 +258,7 @@
 
       // int32 nanos = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
@@ -252,6 +288,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Timestamp::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -269,9 +306,9 @@
     ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->nanos(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Timestamp)
 }
@@ -293,9 +330,9 @@
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->nanos(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Timestamp)
   return target;
@@ -305,11 +342,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Timestamp)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // int64 seconds = 1;
   if (this->seconds() != 0) {
     total_size += 1 +
@@ -333,7 +374,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Timestamp)
   GOOGLE_DCHECK_NE(&from, this);
   const Timestamp* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Timestamp>(
+      ::google::protobuf::DynamicCastToGenerated<Timestamp>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Timestamp)
@@ -398,14 +439,14 @@
 }
 void Timestamp::InternalSwap(Timestamp* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   swap(seconds_, other->seconds_);
   swap(nanos_, other->nanos_);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata Timestamp::GetMetadata() const {
-  protobuf_google_2fprotobuf_2ftimestamp_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ftimestamp_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2ftimestamp_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto[kIndexInFileMessages];
 }
 
 
diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h
index 6e79b73..e77adbe 100644
--- a/src/google/protobuf/timestamp.pb.h
+++ b/src/google/protobuf/timestamp.pb.h
@@ -4,18 +4,18 @@
 #ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2ftimestamp_2eproto
 #define PROTOBUF_INCLUDED_google_2fprotobuf_2ftimestamp_2eproto
 
+#include <limits>
 #include <string>
 
 #include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 3006001
+#if GOOGLE_PROTOBUF_VERSION < 3006000
 #error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please update
+#error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
 #if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
 #error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please
+#error incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.
 #endif
 
@@ -31,29 +31,27 @@
 #include <google/protobuf/extension_set.h>  // IWYU pragma: export
 #include <google/protobuf/unknown_field_set.h>
 // @@protoc_insertion_point(includes)
-#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2ftimestamp_2eproto LIBPROTOBUF_EXPORT
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftimestamp_2eproto LIBPROTOBUF_EXPORT
 
-namespace protobuf_google_2fprotobuf_2ftimestamp_2eproto {
 // Internal implementation detail -- do not use these members.
-struct LIBPROTOBUF_EXPORT TableStruct {
-  static const ::google::protobuf::internal::ParseTableField entries[];
-  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
-  static const ::google::protobuf::internal::ParseTable schema[1];
+struct LIBPROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ftimestamp_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[1]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
   static const ::google::protobuf::uint32 offsets[];
 };
-void LIBPROTOBUF_EXPORT AddDescriptors();
-}  // namespace protobuf_google_2fprotobuf_2ftimestamp_2eproto
+void LIBPROTOBUF_EXPORT AddDescriptors_google_2fprotobuf_2ftimestamp_2eproto();
 namespace google {
 namespace protobuf {
 class Timestamp;
 class TimestampDefaultTypeInternal;
 LIBPROTOBUF_EXPORT extern TimestampDefaultTypeInternal _Timestamp_default_instance_;
-}  // namespace protobuf
-}  // namespace google
-namespace google {
-namespace protobuf {
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::Timestamp* Arena::CreateMaybeMessage<::google::protobuf::Timestamp>(Arena*);
 }  // namespace protobuf
 }  // namespace google
@@ -94,7 +92,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Timestamp& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -128,8 +128,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -175,6 +180,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Timestamp)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -183,7 +189,7 @@
   ::google::protobuf::int64 seconds_;
   ::google::protobuf::int32 nanos_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2ftimestamp_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2ftimestamp_2eproto;
 };
 // ===================================================================
 
@@ -198,7 +204,7 @@
 
 // int64 seconds = 1;
 inline void Timestamp::clear_seconds() {
-  seconds_ = GOOGLE_LONGLONG(0);
+  seconds_ = GOOGLE_PROTOBUF_LONGLONG(0);
 }
 inline ::google::protobuf::int64 Timestamp::seconds() const {
   // @@protoc_insertion_point(field_get:google.protobuf.Timestamp.seconds)
@@ -235,4 +241,5 @@
 
 // @@protoc_insertion_point(global_scope)
 
+#include <google/protobuf/port_undef.inc>
 #endif  // PROTOBUF_INCLUDED_google_2fprotobuf_2ftimestamp_2eproto
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc
index 72679df..de1bd6c 100644
--- a/src/google/protobuf/type.pb.cc
+++ b/src/google/protobuf/type.pb.cc
@@ -6,8 +6,8 @@
 #include <algorithm>
 
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
@@ -18,49 +18,38 @@
 #include "third_party/protobuf/version.h"
 #endif
 // @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
 
-namespace protobuf_google_2fprotobuf_2fany_2eproto {
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fany_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Any;
-}  // namespace protobuf_google_2fprotobuf_2fany_2eproto
-namespace protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto {
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_SourceContext;
-}  // namespace protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto
-namespace protobuf_google_2fprotobuf_2ftype_2eproto {
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2ftype_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValue;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2ftype_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_Field;
-extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2ftype_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_Option;
-}  // namespace protobuf_google_2fprotobuf_2ftype_2eproto
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fany_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Any_google_2fprotobuf_2fany_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fsource_5fcontext_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValue_google_2fprotobuf_2ftype_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_Field_google_2fprotobuf_2ftype_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_Option_google_2fprotobuf_2ftype_2eproto;
 namespace google {
 namespace protobuf {
 class TypeDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Type>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Type> _instance;
 } _Type_default_instance_;
 class FieldDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Field>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Field> _instance;
 } _Field_default_instance_;
 class EnumDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Enum>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Enum> _instance;
 } _Enum_default_instance_;
 class EnumValueDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<EnumValue>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<EnumValue> _instance;
 } _EnumValue_default_instance_;
 class OptionDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Option>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Option> _instance;
 } _Option_default_instance_;
 }  // namespace protobuf
 }  // namespace google
-namespace protobuf_google_2fprotobuf_2ftype_2eproto {
-static void InitDefaultsType() {
+static void InitDefaultsType_google_2fprotobuf_2ftype_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -71,13 +60,13 @@
   ::google::protobuf::Type::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<3> scc_info_Type =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 3, InitDefaultsType}, {
-      &protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Field.base,
-      &protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Option.base,
-      &protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::scc_info_SourceContext.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<3> scc_info_Type_google_2fprotobuf_2ftype_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 3, InitDefaultsType_google_2fprotobuf_2ftype_2eproto}, {
+      &scc_info_Field_google_2fprotobuf_2ftype_2eproto.base,
+      &scc_info_Option_google_2fprotobuf_2ftype_2eproto.base,
+      &scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto.base,}};
 
-static void InitDefaultsField() {
+static void InitDefaultsField_google_2fprotobuf_2ftype_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -88,11 +77,11 @@
   ::google::protobuf::Field::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_Field =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsField}, {
-      &protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Option.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_Field_google_2fprotobuf_2ftype_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsField_google_2fprotobuf_2ftype_2eproto}, {
+      &scc_info_Option_google_2fprotobuf_2ftype_2eproto.base,}};
 
-static void InitDefaultsEnum() {
+static void InitDefaultsEnum_google_2fprotobuf_2ftype_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -103,13 +92,13 @@
   ::google::protobuf::Enum::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<3> scc_info_Enum =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 3, InitDefaultsEnum}, {
-      &protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_EnumValue.base,
-      &protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Option.base,
-      &protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::scc_info_SourceContext.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<3> scc_info_Enum_google_2fprotobuf_2ftype_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 3, InitDefaultsEnum_google_2fprotobuf_2ftype_2eproto}, {
+      &scc_info_EnumValue_google_2fprotobuf_2ftype_2eproto.base,
+      &scc_info_Option_google_2fprotobuf_2ftype_2eproto.base,
+      &scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto.base,}};
 
-static void InitDefaultsEnumValue() {
+static void InitDefaultsEnumValue_google_2fprotobuf_2ftype_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -120,11 +109,11 @@
   ::google::protobuf::EnumValue::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValue =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEnumValue}, {
-      &protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Option.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_EnumValue_google_2fprotobuf_2ftype_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEnumValue_google_2fprotobuf_2ftype_2eproto}, {
+      &scc_info_Option_google_2fprotobuf_2ftype_2eproto.base,}};
 
-static void InitDefaultsOption() {
+static void InitDefaultsOption_google_2fprotobuf_2ftype_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -135,22 +124,23 @@
   ::google::protobuf::Option::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_Option =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsOption}, {
-      &protobuf_google_2fprotobuf_2fany_2eproto::scc_info_Any.base,}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_Option_google_2fprotobuf_2ftype_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsOption_google_2fprotobuf_2ftype_2eproto}, {
+      &scc_info_Any_google_2fprotobuf_2fany_2eproto.base,}};
 
-void InitDefaults() {
-  ::google::protobuf::internal::InitSCC(&scc_info_Type.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_Field.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_Enum.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_EnumValue.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_Option.base);
+void InitDefaults_google_2fprotobuf_2ftype_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_Type_google_2fprotobuf_2ftype_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Field_google_2fprotobuf_2ftype_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Enum_google_2fprotobuf_2ftype_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EnumValue_google_2fprotobuf_2ftype_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Option_google_2fprotobuf_2ftype_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata[5];
-const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[3];
+::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2ftype_2eproto[5];
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[3];
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2ftype_2eproto = nullptr;
 
-const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2ftype_2eproto::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::Type, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -219,92 +209,74 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Option_default_instance_),
 };
 
-static void protobuf_AssignDescriptors() {
-  AddDescriptors();
-  AssignDescriptors(
-      "google/protobuf/type.proto", schemas, file_default_instances, TableStruct::offsets,
-      file_level_metadata, file_level_enum_descriptors, NULL);
-}
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2ftype_2eproto = {
+  {}, AddDescriptors_google_2fprotobuf_2ftype_2eproto, "google/protobuf/type.proto", schemas,
+  file_default_instances, TableStruct_google_2fprotobuf_2ftype_2eproto::offsets,
+  file_level_metadata_google_2fprotobuf_2ftype_2eproto, 5, file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto, file_level_service_descriptors_google_2fprotobuf_2ftype_2eproto,
+};
 
-static void protobuf_AssignDescriptorsOnce() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
-}
+::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftype_2eproto = {
+  false, InitDefaults_google_2fprotobuf_2ftype_2eproto, 
+  "\n\032google/protobuf/type.proto\022\017google.pro"
+  "tobuf\032\031google/protobuf/any.proto\032$google"
+  "/protobuf/source_context.proto\"\327\001\n\004Type\022"
+  "\014\n\004name\030\001 \001(\t\022&\n\006fields\030\002 \003(\0132\026.google.p"
+  "rotobuf.Field\022\016\n\006oneofs\030\003 \003(\t\022(\n\007options"
+  "\030\004 \003(\0132\027.google.protobuf.Option\0226\n\016sourc"
+  "e_context\030\005 \001(\0132\036.google.protobuf.Source"
+  "Context\022\'\n\006syntax\030\006 \001(\0162\027.google.protobu"
+  "f.Syntax\"\325\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.googl"
+  "e.protobuf.Field.Kind\0227\n\013cardinality\030\002 \001"
+  "(\0162\".google.protobuf.Field.Cardinality\022\016"
+  "\n\006number\030\003 \001(\005\022\014\n\004name\030\004 \001(\t\022\020\n\010type_url"
+  "\030\006 \001(\t\022\023\n\013oneof_index\030\007 \001(\005\022\016\n\006packed\030\010 "
+  "\001(\010\022(\n\007options\030\t \003(\0132\027.google.protobuf.O"
+  "ption\022\021\n\tjson_name\030\n \001(\t\022\025\n\rdefault_valu"
+  "e\030\013 \001(\t\"\310\002\n\004Kind\022\020\n\014TYPE_UNKNOWN\020\000\022\017\n\013TY"
+  "PE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT6"
+  "4\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014"
+  "TYPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE"
+  "_BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n"
+  "\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TY"
+  "PE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXE"
+  "D32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020"
+  "\021\022\017\n\013TYPE_SINT64\020\022\"t\n\013Cardinality\022\027\n\023CAR"
+  "DINALITY_UNKNOWN\020\000\022\030\n\024CARDINALITY_OPTION"
+  "AL\020\001\022\030\n\024CARDINALITY_REQUIRED\020\002\022\030\n\024CARDIN"
+  "ALITY_REPEATED\020\003\"\316\001\n\004Enum\022\014\n\004name\030\001 \001(\t\022"
+  "-\n\tenumvalue\030\002 \003(\0132\032.google.protobuf.Enu"
+  "mValue\022(\n\007options\030\003 \003(\0132\027.google.protobu"
+  "f.Option\0226\n\016source_context\030\004 \001(\0132\036.googl"
+  "e.protobuf.SourceContext\022\'\n\006syntax\030\005 \001(\016"
+  "2\027.google.protobuf.Syntax\"S\n\tEnumValue\022\014"
+  "\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\022(\n\007options\030"
+  "\003 \003(\0132\027.google.protobuf.Option\";\n\006Option"
+  "\022\014\n\004name\030\001 \001(\t\022#\n\005value\030\002 \001(\0132\024.google.p"
+  "rotobuf.Any*.\n\006Syntax\022\021\n\rSYNTAX_PROTO2\020\000"
+  "\022\021\n\rSYNTAX_PROTO3\020\001B}\n\023com.google.protob"
+  "ufB\tTypeProtoP\001Z/google.golang.org/genpr"
+  "oto/protobuf/ptype;ptype\370\001\001\242\002\003GPB\252\002\036Goog"
+  "le.Protobuf.WellKnownTypesb\006proto3"
+,
+  "google/protobuf/type.proto", &assign_descriptors_table_google_2fprotobuf_2ftype_2eproto, 1594,
+};
 
-void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
-void protobuf_RegisterTypes(const ::std::string&) {
-  protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 5);
-}
-
-static void AddDescriptorsImpl() {
-  InitDefaults();
-  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
-      "\n\032google/protobuf/type.proto\022\017google.pro"
-      "tobuf\032\031google/protobuf/any.proto\032$google"
-      "/protobuf/source_context.proto\"\327\001\n\004Type\022"
-      "\014\n\004name\030\001 \001(\t\022&\n\006fields\030\002 \003(\0132\026.google.p"
-      "rotobuf.Field\022\016\n\006oneofs\030\003 \003(\t\022(\n\007options"
-      "\030\004 \003(\0132\027.google.protobuf.Option\0226\n\016sourc"
-      "e_context\030\005 \001(\0132\036.google.protobuf.Source"
-      "Context\022\'\n\006syntax\030\006 \001(\0162\027.google.protobu"
-      "f.Syntax\"\325\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.googl"
-      "e.protobuf.Field.Kind\0227\n\013cardinality\030\002 \001"
-      "(\0162\".google.protobuf.Field.Cardinality\022\016"
-      "\n\006number\030\003 \001(\005\022\014\n\004name\030\004 \001(\t\022\020\n\010type_url"
-      "\030\006 \001(\t\022\023\n\013oneof_index\030\007 \001(\005\022\016\n\006packed\030\010 "
-      "\001(\010\022(\n\007options\030\t \003(\0132\027.google.protobuf.O"
-      "ption\022\021\n\tjson_name\030\n \001(\t\022\025\n\rdefault_valu"
-      "e\030\013 \001(\t\"\310\002\n\004Kind\022\020\n\014TYPE_UNKNOWN\020\000\022\017\n\013TY"
-      "PE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT6"
-      "4\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014"
-      "TYPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE"
-      "_BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n"
-      "\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TY"
-      "PE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXE"
-      "D32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020"
-      "\021\022\017\n\013TYPE_SINT64\020\022\"t\n\013Cardinality\022\027\n\023CAR"
-      "DINALITY_UNKNOWN\020\000\022\030\n\024CARDINALITY_OPTION"
-      "AL\020\001\022\030\n\024CARDINALITY_REQUIRED\020\002\022\030\n\024CARDIN"
-      "ALITY_REPEATED\020\003\"\316\001\n\004Enum\022\014\n\004name\030\001 \001(\t\022"
-      "-\n\tenumvalue\030\002 \003(\0132\032.google.protobuf.Enu"
-      "mValue\022(\n\007options\030\003 \003(\0132\027.google.protobu"
-      "f.Option\0226\n\016source_context\030\004 \001(\0132\036.googl"
-      "e.protobuf.SourceContext\022\'\n\006syntax\030\005 \001(\016"
-      "2\027.google.protobuf.Syntax\"S\n\tEnumValue\022\014"
-      "\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\022(\n\007options\030"
-      "\003 \003(\0132\027.google.protobuf.Option\";\n\006Option"
-      "\022\014\n\004name\030\001 \001(\t\022#\n\005value\030\002 \001(\0132\024.google.p"
-      "rotobuf.Any*.\n\006Syntax\022\021\n\rSYNTAX_PROTO2\020\000"
-      "\022\021\n\rSYNTAX_PROTO3\020\001B}\n\023com.google.protob"
-      "ufB\tTypeProtoP\001Z/google.golang.org/genpr"
-      "oto/protobuf/ptype;ptype\370\001\001\242\002\003GPB\252\002\036Goog"
-      "le.Protobuf.WellKnownTypesb\006proto3"
+void AddDescriptors_google_2fprotobuf_2ftype_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[2] =
+  {
+    ::AddDescriptors_google_2fprotobuf_2fany_2eproto,
+    ::AddDescriptors_google_2fprotobuf_2fsource_5fcontext_2eproto,
   };
-  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 1594);
-  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
-    "google/protobuf/type.proto", &protobuf_RegisterTypes);
-  ::protobuf_google_2fprotobuf_2fany_2eproto::AddDescriptors();
-  ::protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::AddDescriptors();
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto, deps, 2);
 }
 
-void AddDescriptors() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
-}
-// Force AddDescriptors() to be called at dynamic initialization time.
-struct StaticDescriptorInitializer {
-  StaticDescriptorInitializer() {
-    AddDescriptors();
-  }
-} static_descriptor_initializer;
-}  // namespace protobuf_google_2fprotobuf_2ftype_2eproto
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_google_2fprotobuf_2ftype_2eproto = []() { AddDescriptors_google_2fprotobuf_2ftype_2eproto(); return true; }();
 namespace google {
 namespace protobuf {
 const ::google::protobuf::EnumDescriptor* Field_Kind_descriptor() {
-  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_enum_descriptors[0];
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2ftype_2eproto);
+  return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[0];
 }
 bool Field_Kind_IsValid(int value) {
   switch (value) {
@@ -358,8 +330,8 @@
 const int Field::Kind_ARRAYSIZE;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 const ::google::protobuf::EnumDescriptor* Field_Cardinality_descriptor() {
-  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_enum_descriptors[1];
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2ftype_2eproto);
+  return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[1];
 }
 bool Field_Cardinality_IsValid(int value) {
   switch (value) {
@@ -383,8 +355,8 @@
 const int Field::Cardinality_ARRAYSIZE;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 const ::google::protobuf::EnumDescriptor* Syntax_descriptor() {
-  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_enum_descriptors[2];
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_google_2fprotobuf_2ftype_2eproto);
+  return file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto[2];
 }
 bool Syntax_IsValid(int value) {
   switch (value) {
@@ -403,6 +375,15 @@
   ::google::protobuf::_Type_default_instance_._instance.get_mutable()->source_context_ = const_cast< ::google::protobuf::SourceContext*>(
       ::google::protobuf::SourceContext::internal_default_instance());
 }
+class Type::HasBitSetters {
+ public:
+  static const ::google::protobuf::SourceContext& source_context(const Type* msg);
+};
+
+const ::google::protobuf::SourceContext&
+Type::HasBitSetters::source_context(const Type* msg) {
+  return *msg->source_context_;
+}
 void Type::unsafe_arena_set_allocated_source_context(
     ::google::protobuf::SourceContext* source_context) {
   if (GetArenaNoVirtual() == NULL) {
@@ -433,8 +414,6 @@
 
 Type::Type()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Type.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Type)
 }
@@ -444,7 +423,6 @@
   fields_(arena),
   oneofs_(arena),
   options_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Type.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.Type)
@@ -471,6 +449,8 @@
 }
 
 void Type::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Type_google_2fprotobuf_2ftype_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   ::memset(&source_context_, 0, static_cast<size_t>(
       reinterpret_cast<char*>(&syntax_) -
@@ -497,13 +477,8 @@
 void Type::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Type::descriptor() {
-  ::protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Type& Type::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Type.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Type_google_2fprotobuf_2ftype_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -526,9 +501,138 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Type::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Type*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Type.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated .google.protobuf.Field fields = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::Field::_InternalParse;
+          object = msg->add_fields();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 18 && (ptr += 1));
+        break;
+      }
+      // repeated string oneofs = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          ctx->extra_parse_data().SetFieldName("google.protobuf.Type.oneofs");
+          parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+          ::std::string* str = msg->add_oneofs();
+          str->clear();
+          object = str;
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 26 && (ptr += 1));
+        break;
+      }
+      // repeated .google.protobuf.Option options = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::Option::_InternalParse;
+          object = msg->add_options();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 34 && (ptr += 1));
+        break;
+      }
+      // .google.protobuf.SourceContext source_context = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::SourceContext::_InternalParse;
+        object = msg->mutable_source_context();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // .google.protobuf.Syntax syntax = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 48) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::Syntax value = static_cast<::google::protobuf::Syntax>(val);
+        msg->set_syntax(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Type::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Type)
   for (;;) {
@@ -538,8 +642,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -554,8 +657,7 @@
 
       // repeated .google.protobuf.Field fields = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_fields()));
         } else {
@@ -566,8 +668,7 @@
 
       // repeated string oneofs = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->add_oneofs()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -583,8 +684,7 @@
 
       // repeated .google.protobuf.Option options = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_options()));
         } else {
@@ -595,8 +695,7 @@
 
       // .google.protobuf.SourceContext source_context = 5;
       case 5: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(42u /* 42 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_source_context()));
         } else {
@@ -607,8 +706,7 @@
 
       // .google.protobuf.Syntax syntax = 6;
       case 6: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (48 & 0xFF)) {
           int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -639,6 +737,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Type::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -687,7 +786,7 @@
   // .google.protobuf.SourceContext source_context = 5;
   if (this->has_source_context()) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      5, this->_internal_source_context(), output);
+      5, HasBitSetters::source_context(this), output);
   }
 
   // .google.protobuf.Syntax syntax = 6;
@@ -696,9 +795,9 @@
       6, this->syntax(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Type)
 }
@@ -751,7 +850,7 @@
   if (this->has_source_context()) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        5, this->_internal_source_context(), deterministic, target);
+        5, HasBitSetters::source_context(this), deterministic, target);
   }
 
   // .google.protobuf.Syntax syntax = 6;
@@ -760,9 +859,9 @@
       6, this->syntax(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Type)
   return target;
@@ -772,11 +871,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Type)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.Field fields = 2;
   {
     unsigned int count = static_cast<unsigned int>(this->fields_size());
@@ -836,7 +939,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Type)
   GOOGLE_DCHECK_NE(&from, this);
   const Type* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Type>(
+      ::google::protobuf::DynamicCastToGenerated<Type>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Type)
@@ -907,6 +1010,7 @@
 }
 void Type::InternalSwap(Type* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   CastToBase(&fields_)->InternalSwap(CastToBase(&other->fields_));
   oneofs_.InternalSwap(CastToBase(&other->oneofs_));
   CastToBase(&options_)->InternalSwap(CastToBase(&other->options_));
@@ -914,12 +1018,11 @@
     GetArenaNoVirtual());
   swap(source_context_, other->source_context_);
   swap(syntax_, other->syntax_);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata Type::GetMetadata() const {
-  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2ftype_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2ftype_2eproto[kIndexInFileMessages];
 }
 
 
@@ -927,6 +1030,10 @@
 
 void Field::InitAsDefaultInstance() {
 }
+class Field::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Field::kKindFieldNumber;
 const int Field::kCardinalityFieldNumber;
@@ -942,8 +1049,6 @@
 
 Field::Field()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Field.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Field)
 }
@@ -951,7 +1056,6 @@
   : ::google::protobuf::Message(),
   _internal_metadata_(arena),
   options_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Field.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.Field)
@@ -988,6 +1092,8 @@
 }
 
 void Field::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Field_google_2fprotobuf_2ftype_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   json_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -1019,13 +1125,8 @@
 void Field::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Field::descriptor() {
-  ::protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Field& Field::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Field.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Field_google_2fprotobuf_2ftype_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -1047,9 +1148,178 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Field::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Field*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // .google.protobuf.Field.Kind kind = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::Field_Kind value = static_cast<::google::protobuf::Field_Kind>(val);
+        msg->set_kind(value);
+        break;
+      }
+      // .google.protobuf.Field.Cardinality cardinality = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::Field_Cardinality value = static_cast<::google::protobuf::Field_Cardinality>(val);
+        msg->set_cardinality(value);
+        break;
+      }
+      // int32 number = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_number(value);
+        break;
+      }
+      // string name = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Field.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // string type_url = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Field.type_url");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_type_url();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // int32 oneof_index = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_oneof_index(value);
+        break;
+      }
+      // bool packed = 8;
+      case 8: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 64) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_packed(value);
+        break;
+      }
+      // repeated .google.protobuf.Option options = 9;
+      case 9: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 74) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::Option::_InternalParse;
+          object = msg->add_options();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 74 && (ptr += 1));
+        break;
+      }
+      // string json_name = 10;
+      case 10: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 82) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Field.json_name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_json_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // string default_value = 11;
+      case 11: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 90) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Field.default_value");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_default_value();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Field::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Field)
   for (;;) {
@@ -1059,8 +1329,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // .google.protobuf.Field.Kind kind = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
           int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -1074,8 +1343,7 @@
 
       // .google.protobuf.Field.Cardinality cardinality = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
           int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -1089,8 +1357,7 @@
 
       // int32 number = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
@@ -1103,8 +1370,7 @@
 
       // string name = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1119,8 +1385,7 @@
 
       // string type_url = 6;
       case 6: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(50u /* 50 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_type_url()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1135,8 +1400,7 @@
 
       // int32 oneof_index = 7;
       case 7: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (56 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
@@ -1149,8 +1413,7 @@
 
       // bool packed = 8;
       case 8: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(64u /* 64 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (64 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
@@ -1163,8 +1426,7 @@
 
       // repeated .google.protobuf.Option options = 9;
       case 9: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(74u /* 74 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (74 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_options()));
         } else {
@@ -1175,8 +1437,7 @@
 
       // string json_name = 10;
       case 10: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(82u /* 82 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (82 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_json_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1191,8 +1452,7 @@
 
       // string default_value = 11;
       case 11: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(90u /* 90 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (90 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_default_value()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1224,6 +1484,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Field::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -1307,9 +1568,9 @@
       11, this->default_value(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Field)
 }
@@ -1400,9 +1661,9 @@
         11, this->default_value(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Field)
   return target;
@@ -1412,11 +1673,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Field)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.Option options = 9;
   {
     unsigned int count = static_cast<unsigned int>(this->options_size());
@@ -1496,7 +1761,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Field)
   GOOGLE_DCHECK_NE(&from, this);
   const Field* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Field>(
+      ::google::protobuf::DynamicCastToGenerated<Field>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Field)
@@ -1583,6 +1848,7 @@
 }
 void Field::InternalSwap(Field* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   CastToBase(&options_)->InternalSwap(CastToBase(&other->options_));
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
@@ -1597,12 +1863,11 @@
   swap(number_, other->number_);
   swap(oneof_index_, other->oneof_index_);
   swap(packed_, other->packed_);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata Field::GetMetadata() const {
-  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2ftype_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2ftype_2eproto[kIndexInFileMessages];
 }
 
 
@@ -1612,6 +1877,15 @@
   ::google::protobuf::_Enum_default_instance_._instance.get_mutable()->source_context_ = const_cast< ::google::protobuf::SourceContext*>(
       ::google::protobuf::SourceContext::internal_default_instance());
 }
+class Enum::HasBitSetters {
+ public:
+  static const ::google::protobuf::SourceContext& source_context(const Enum* msg);
+};
+
+const ::google::protobuf::SourceContext&
+Enum::HasBitSetters::source_context(const Enum* msg) {
+  return *msg->source_context_;
+}
 void Enum::unsafe_arena_set_allocated_source_context(
     ::google::protobuf::SourceContext* source_context) {
   if (GetArenaNoVirtual() == NULL) {
@@ -1641,8 +1915,6 @@
 
 Enum::Enum()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Enum.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Enum)
 }
@@ -1651,7 +1923,6 @@
   _internal_metadata_(arena),
   enumvalue_(arena),
   options_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Enum.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.Enum)
@@ -1677,6 +1948,8 @@
 }
 
 void Enum::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Enum_google_2fprotobuf_2ftype_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   ::memset(&source_context_, 0, static_cast<size_t>(
       reinterpret_cast<char*>(&syntax_) -
@@ -1703,13 +1976,8 @@
 void Enum::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Enum::descriptor() {
-  ::protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Enum& Enum::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Enum.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Enum_google_2fprotobuf_2ftype_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -1731,9 +1999,119 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Enum::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Enum*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Enum.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // repeated .google.protobuf.EnumValue enumvalue = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::EnumValue::_InternalParse;
+          object = msg->add_enumvalue();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 18 && (ptr += 1));
+        break;
+      }
+      // repeated .google.protobuf.Option options = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::Option::_InternalParse;
+          object = msg->add_options();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 26 && (ptr += 1));
+        break;
+      }
+      // .google.protobuf.SourceContext source_context = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::SourceContext::_InternalParse;
+        object = msg->mutable_source_context();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // .google.protobuf.Syntax syntax = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::Syntax value = static_cast<::google::protobuf::Syntax>(val);
+        msg->set_syntax(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Enum::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Enum)
   for (;;) {
@@ -1743,8 +2121,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -1759,8 +2136,7 @@
 
       // repeated .google.protobuf.EnumValue enumvalue = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_enumvalue()));
         } else {
@@ -1771,8 +2147,7 @@
 
       // repeated .google.protobuf.Option options = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_options()));
         } else {
@@ -1783,8 +2158,7 @@
 
       // .google.protobuf.SourceContext source_context = 4;
       case 4: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_source_context()));
         } else {
@@ -1795,8 +2169,7 @@
 
       // .google.protobuf.Syntax syntax = 5;
       case 5: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
           int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
@@ -1827,6 +2200,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Enum::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -1865,7 +2239,7 @@
   // .google.protobuf.SourceContext source_context = 4;
   if (this->has_source_context()) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      4, this->_internal_source_context(), output);
+      4, HasBitSetters::source_context(this), output);
   }
 
   // .google.protobuf.Syntax syntax = 5;
@@ -1874,9 +2248,9 @@
       5, this->syntax(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Enum)
 }
@@ -1919,7 +2293,7 @@
   if (this->has_source_context()) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        4, this->_internal_source_context(), deterministic, target);
+        4, HasBitSetters::source_context(this), deterministic, target);
   }
 
   // .google.protobuf.Syntax syntax = 5;
@@ -1928,9 +2302,9 @@
       5, this->syntax(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Enum)
   return target;
@@ -1940,11 +2314,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Enum)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.EnumValue enumvalue = 2;
   {
     unsigned int count = static_cast<unsigned int>(this->enumvalue_size());
@@ -1996,7 +2374,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Enum)
   GOOGLE_DCHECK_NE(&from, this);
   const Enum* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Enum>(
+      ::google::protobuf::DynamicCastToGenerated<Enum>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Enum)
@@ -2066,18 +2444,18 @@
 }
 void Enum::InternalSwap(Enum* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   CastToBase(&enumvalue_)->InternalSwap(CastToBase(&other->enumvalue_));
   CastToBase(&options_)->InternalSwap(CastToBase(&other->options_));
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   swap(source_context_, other->source_context_);
   swap(syntax_, other->syntax_);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata Enum::GetMetadata() const {
-  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2ftype_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2ftype_2eproto[kIndexInFileMessages];
 }
 
 
@@ -2085,6 +2463,10 @@
 
 void EnumValue::InitAsDefaultInstance() {
 }
+class EnumValue::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int EnumValue::kNameFieldNumber;
 const int EnumValue::kNumberFieldNumber;
@@ -2093,8 +2475,6 @@
 
 EnumValue::EnumValue()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_EnumValue.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.EnumValue)
 }
@@ -2102,7 +2482,6 @@
   : ::google::protobuf::Message(),
   _internal_metadata_(arena),
   options_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_EnumValue.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValue)
@@ -2122,6 +2501,8 @@
 }
 
 void EnumValue::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_EnumValue_google_2fprotobuf_2ftype_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   number_ = 0;
 }
@@ -2145,13 +2526,8 @@
 void EnumValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* EnumValue::descriptor() {
-  ::protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const EnumValue& EnumValue::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_EnumValue.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_EnumValue_google_2fprotobuf_2ftype_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -2168,9 +2544,90 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EnumValue::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EnumValue*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.EnumValue.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // int32 number = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_number(value);
+        break;
+      }
+      // repeated .google.protobuf.Option options = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        do {
+          ptr = Varint::Parse32Inline(ptr, &size);
+          if (!ptr) goto error;
+          parser_till_end = ::google::protobuf::Option::_InternalParse;
+          object = msg->add_options();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+          ptr = newend;
+          if (ptr >= end) break;
+        } while((*reinterpret_cast<const ::google::protobuf::uint64*>(ptr) & 255) == 26 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool EnumValue::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.EnumValue)
   for (;;) {
@@ -2180,8 +2637,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -2196,8 +2652,7 @@
 
       // int32 number = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
@@ -2210,8 +2665,7 @@
 
       // repeated .google.protobuf.Option options = 3;
       case 3: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                 input, add_options()));
         } else {
@@ -2239,6 +2693,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void EnumValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -2270,9 +2725,9 @@
       output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValue)
 }
@@ -2308,9 +2763,9 @@
         3, this->options(static_cast<int>(i)), deterministic, target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValue)
   return target;
@@ -2320,11 +2775,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValue)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // repeated .google.protobuf.Option options = 3;
   {
     unsigned int count = static_cast<unsigned int>(this->options_size());
@@ -2359,7 +2818,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumValue)
   GOOGLE_DCHECK_NE(&from, this);
   const EnumValue* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const EnumValue>(
+      ::google::protobuf::DynamicCastToGenerated<EnumValue>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.EnumValue)
@@ -2425,16 +2884,16 @@
 }
 void EnumValue::InternalSwap(EnumValue* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   CastToBase(&options_)->InternalSwap(CastToBase(&other->options_));
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   swap(number_, other->number_);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata EnumValue::GetMetadata() const {
-  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2ftype_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2ftype_2eproto[kIndexInFileMessages];
 }
 
 
@@ -2444,6 +2903,15 @@
   ::google::protobuf::_Option_default_instance_._instance.get_mutable()->value_ = const_cast< ::google::protobuf::Any*>(
       ::google::protobuf::Any::internal_default_instance());
 }
+class Option::HasBitSetters {
+ public:
+  static const ::google::protobuf::Any& value(const Option* msg);
+};
+
+const ::google::protobuf::Any&
+Option::HasBitSetters::value(const Option* msg) {
+  return *msg->value_;
+}
 void Option::unsafe_arena_set_allocated_value(
     ::google::protobuf::Any* value) {
   if (GetArenaNoVirtual() == NULL) {
@@ -2470,15 +2938,12 @@
 
 Option::Option()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Option.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Option)
 }
 Option::Option(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Option.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.Option)
@@ -2501,6 +2966,8 @@
 }
 
 void Option::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Option_google_2fprotobuf_2ftype_2eproto.base);
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   value_ = NULL;
 }
@@ -2525,13 +2992,8 @@
 void Option::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Option::descriptor() {
-  ::protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Option& Option::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2ftype_2eproto::scc_info_Option.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Option_google_2fprotobuf_2ftype_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -2550,9 +3012,77 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Option::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Option*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.Option.name");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_name();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      // .google.protobuf.Any value = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::Any::_InternalParse;
+        object = msg->mutable_value();
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Option::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Option)
   for (;;) {
@@ -2562,8 +3092,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // string name = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -2578,8 +3107,7 @@
 
       // .google.protobuf.Any value = 2;
       case 2: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, mutable_value()));
         } else {
@@ -2607,6 +3135,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Option::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -2627,12 +3156,12 @@
   // .google.protobuf.Any value = 2;
   if (this->has_value()) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      2, this->_internal_value(), output);
+      2, HasBitSetters::value(this), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Option)
 }
@@ -2659,12 +3188,12 @@
   if (this->has_value()) {
     target = ::google::protobuf::internal::WireFormatLite::
       InternalWriteMessageToArray(
-        2, this->_internal_value(), deterministic, target);
+        2, HasBitSetters::value(this), deterministic, target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Option)
   return target;
@@ -2674,11 +3203,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Option)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // string name = 1;
   if (this->name().size() > 0) {
     total_size += 1 +
@@ -2702,7 +3235,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Option)
   GOOGLE_DCHECK_NE(&from, this);
   const Option* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Option>(
+      ::google::protobuf::DynamicCastToGenerated<Option>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Option)
@@ -2767,15 +3300,15 @@
 }
 void Option::InternalSwap(Option* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
   swap(value_, other->value_);
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata Option::GetMetadata() const {
-  protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2ftype_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2ftype_2eproto[kIndexInFileMessages];
 }
 
 
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h
index 468c88d..5ae22bb 100644
--- a/src/google/protobuf/type.pb.h
+++ b/src/google/protobuf/type.pb.h
@@ -4,18 +4,18 @@
 #ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto
 #define PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto
 
+#include <limits>
 #include <string>
 
 #include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 3006001
+#if GOOGLE_PROTOBUF_VERSION < 3006000
 #error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please update
+#error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
 #if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
 #error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please
+#error incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.
 #endif
 
@@ -34,20 +34,22 @@
 #include <google/protobuf/any.pb.h>
 #include <google/protobuf/source_context.pb.h>
 // @@protoc_insertion_point(includes)
-#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2ftype_2eproto LIBPROTOBUF_EXPORT
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto LIBPROTOBUF_EXPORT
 
-namespace protobuf_google_2fprotobuf_2ftype_2eproto {
 // Internal implementation detail -- do not use these members.
-struct LIBPROTOBUF_EXPORT TableStruct {
-  static const ::google::protobuf::internal::ParseTableField entries[];
-  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
-  static const ::google::protobuf::internal::ParseTable schema[5];
+struct LIBPROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ftype_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[5]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
   static const ::google::protobuf::uint32 offsets[];
 };
-void LIBPROTOBUF_EXPORT AddDescriptors();
-}  // namespace protobuf_google_2fprotobuf_2ftype_2eproto
+void LIBPROTOBUF_EXPORT AddDescriptors_google_2fprotobuf_2ftype_2eproto();
 namespace google {
 namespace protobuf {
 class Enum;
@@ -65,10 +67,6 @@
 class Type;
 class TypeDefaultTypeInternal;
 LIBPROTOBUF_EXPORT extern TypeDefaultTypeInternal _Type_default_instance_;
-}  // namespace protobuf
-}  // namespace google
-namespace google {
-namespace protobuf {
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::Enum* Arena::CreateMaybeMessage<::google::protobuf::Enum>(Arena*);
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::EnumValue* Arena::CreateMaybeMessage<::google::protobuf::EnumValue>(Arena*);
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::Field* Arena::CreateMaybeMessage<::google::protobuf::Field>(Arena*);
@@ -99,8 +97,8 @@
   Field_Kind_TYPE_SFIXED64 = 16,
   Field_Kind_TYPE_SINT32 = 17,
   Field_Kind_TYPE_SINT64 = 18,
-  Field_Kind_Field_Kind_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,
-  Field_Kind_Field_Kind_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
+  Field_Kind_Field_Kind_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  Field_Kind_Field_Kind_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
 };
 LIBPROTOBUF_EXPORT bool Field_Kind_IsValid(int value);
 const Field_Kind Field_Kind_Kind_MIN = Field_Kind_TYPE_UNKNOWN;
@@ -122,8 +120,8 @@
   Field_Cardinality_CARDINALITY_OPTIONAL = 1,
   Field_Cardinality_CARDINALITY_REQUIRED = 2,
   Field_Cardinality_CARDINALITY_REPEATED = 3,
-  Field_Cardinality_Field_Cardinality_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,
-  Field_Cardinality_Field_Cardinality_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
+  Field_Cardinality_Field_Cardinality_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  Field_Cardinality_Field_Cardinality_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
 };
 LIBPROTOBUF_EXPORT bool Field_Cardinality_IsValid(int value);
 const Field_Cardinality Field_Cardinality_Cardinality_MIN = Field_Cardinality_CARDINALITY_UNKNOWN;
@@ -143,8 +141,8 @@
 enum Syntax {
   SYNTAX_PROTO2 = 0,
   SYNTAX_PROTO3 = 1,
-  Syntax_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,
-  Syntax_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
+  Syntax_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  Syntax_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
 };
 LIBPROTOBUF_EXPORT bool Syntax_IsValid(int value);
 const Syntax Syntax_MIN = SYNTAX_PROTO2;
@@ -195,7 +193,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Type& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -229,8 +229,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -293,8 +298,8 @@
   #endif
   void add_oneofs(const char* value);
   void add_oneofs(const char* value, size_t size);
-  const ::google::protobuf::RepeatedPtrField< ::std::string>& oneofs() const;
-  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_oneofs();
+  const ::google::protobuf::RepeatedPtrField<::std::string>& oneofs() const;
+  ::google::protobuf::RepeatedPtrField<::std::string>* mutable_oneofs();
 
   // repeated .google.protobuf.Option options = 4;
   int options_size() const;
@@ -321,11 +326,11 @@
   ::std::string* mutable_name();
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name(
@@ -335,9 +340,6 @@
   bool has_source_context() const;
   void clear_source_context();
   static const int kSourceContextFieldNumber = 5;
-  private:
-  const ::google::protobuf::SourceContext& _internal_source_context() const;
-  public:
   const ::google::protobuf::SourceContext& source_context() const;
   ::google::protobuf::SourceContext* release_source_context();
   ::google::protobuf::SourceContext* mutable_source_context();
@@ -354,19 +356,20 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Type)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field > fields_;
-  ::google::protobuf::RepeatedPtrField< ::std::string> oneofs_;
+  ::google::protobuf::RepeatedPtrField<::std::string> oneofs_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::SourceContext* source_context_;
   int syntax_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -402,7 +405,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Field& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -436,8 +441,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -584,11 +594,11 @@
   ::std::string* mutable_name();
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name(
@@ -607,11 +617,11 @@
   ::std::string* mutable_type_url();
   ::std::string* release_type_url();
   void set_allocated_type_url(::std::string* type_url);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_type_url();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_type_url(
@@ -630,11 +640,11 @@
   ::std::string* mutable_json_name();
   ::std::string* release_json_name();
   void set_allocated_json_name(::std::string* json_name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_json_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_json_name(
@@ -653,11 +663,11 @@
   ::std::string* mutable_default_value();
   ::std::string* release_default_value();
   void set_allocated_default_value(::std::string* default_value);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_default_value();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_default_value(
@@ -695,6 +705,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Field)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -711,7 +722,7 @@
   ::google::protobuf::int32 oneof_index_;
   bool packed_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -747,7 +758,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Enum& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -781,8 +794,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -851,11 +869,11 @@
   ::std::string* mutable_name();
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name(
@@ -865,9 +883,6 @@
   bool has_source_context() const;
   void clear_source_context();
   static const int kSourceContextFieldNumber = 4;
-  private:
-  const ::google::protobuf::SourceContext& _internal_source_context() const;
-  public:
   const ::google::protobuf::SourceContext& source_context() const;
   ::google::protobuf::SourceContext* release_source_context();
   ::google::protobuf::SourceContext* mutable_source_context();
@@ -884,6 +899,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Enum)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -895,7 +911,7 @@
   ::google::protobuf::SourceContext* source_context_;
   int syntax_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -931,7 +947,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const EnumValue& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -965,8 +983,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -1023,11 +1046,11 @@
   ::std::string* mutable_name();
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name(
@@ -1041,6 +1064,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.EnumValue)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -1050,7 +1074,7 @@
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::int32 number_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -1086,7 +1110,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Option& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -1120,8 +1146,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -1166,11 +1197,11 @@
   ::std::string* mutable_name();
   ::std::string* release_name();
   void set_allocated_name(::std::string* name);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_name();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_name(
@@ -1180,9 +1211,6 @@
   bool has_value() const;
   void clear_value();
   static const int kValueFieldNumber = 2;
-  private:
-  const ::google::protobuf::Any& _internal_value() const;
-  public:
   const ::google::protobuf::Any& value() const;
   ::google::protobuf::Any* release_value();
   ::google::protobuf::Any* mutable_value();
@@ -1193,6 +1221,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Option)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -1201,7 +1230,7 @@
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::Any* value_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2ftype_2eproto;
 };
 // ===================================================================
 
@@ -1377,12 +1406,12 @@
   oneofs_.Add()->assign(reinterpret_cast<const char*>(value), size);
   // @@protoc_insertion_point(field_add_pointer:google.protobuf.Type.oneofs)
 }
-inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+inline const ::google::protobuf::RepeatedPtrField<::std::string>&
 Type::oneofs() const {
   // @@protoc_insertion_point(field_list:google.protobuf.Type.oneofs)
   return oneofs_;
 }
-inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+inline ::google::protobuf::RepeatedPtrField<::std::string>*
 Type::mutable_oneofs() {
   // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.oneofs)
   return &oneofs_;
@@ -1422,9 +1451,6 @@
 inline bool Type::has_source_context() const {
   return this != internal_default_instance() && source_context_ != NULL;
 }
-inline const ::google::protobuf::SourceContext& Type::_internal_source_context() const {
-  return *source_context_;
-}
 inline const ::google::protobuf::SourceContext& Type::source_context() const {
   const ::google::protobuf::SourceContext* p = source_context_;
   // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context)
@@ -2037,9 +2063,6 @@
 inline bool Enum::has_source_context() const {
   return this != internal_default_instance() && source_context_ != NULL;
 }
-inline const ::google::protobuf::SourceContext& Enum::_internal_source_context() const {
-  return *source_context_;
-}
 inline const ::google::protobuf::SourceContext& Enum::source_context() const {
   const ::google::protobuf::SourceContext* p = source_context_;
   // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context)
@@ -2311,9 +2334,6 @@
 inline bool Option::has_value() const {
   return this != internal_default_instance() && value_ != NULL;
 }
-inline const ::google::protobuf::Any& Option::_internal_value() const {
-  return *value_;
-}
 inline const ::google::protobuf::Any& Option::value() const {
   const ::google::protobuf::Any* p = value_;
   // @@protoc_insertion_point(field_get:google.protobuf.Option.value)
@@ -2406,4 +2426,5 @@
 
 // @@protoc_insertion_point(global_scope)
 
+#include <google/protobuf/port_undef.inc>
 #endif  // PROTOBUF_INCLUDED_google_2fprotobuf_2ftype_2eproto
diff --git a/src/google/protobuf/unittest_proto3.proto b/src/google/protobuf/unittest_proto3.proto
index 84815d4..1c3bf91 100644
--- a/src/google/protobuf/unittest_proto3.proto
+++ b/src/google/protobuf/unittest_proto3.proto
@@ -206,3 +206,17 @@
 message TestEmptyMessage {
 }
 
+// Same layout as TestOneof2 in unittest.proto to test unknown enum value
+// parsing behavior in oneof.
+message TestOneof2 {
+  oneof foo {
+    NestedEnum foo_enum = 6;
+  }
+
+  enum NestedEnum {
+    UNKNOWN = 0;
+    FOO = 1;
+    BAR = 2;
+    BAZ = 3;
+  }
+}
diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc
index 35f24e7..dc53016 100644
--- a/src/google/protobuf/unknown_field_set.cc
+++ b/src/google/protobuf/unknown_field_set.cc
@@ -43,6 +43,8 @@
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/stl_util.h>
 
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 
@@ -317,5 +319,133 @@
   return target;
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+namespace internal {
+
+const char* PackedValidEnumParser(const char* begin, const char* end,
+                                  void* object, ParseContext* ctx) {
+  auto repeated_field = static_cast<RepeatedField<int>*>(object);
+  auto ptr = begin;
+  while (ptr < end) {
+    uint64 varint;
+    ptr = Varint::Parse64(ptr, &varint);
+    int val = varint;
+    if (ctx->extra_parse_data().ValidateEnum<UnknownFieldSet>(val))
+      repeated_field->Add(val);
+  }
+  return ptr;
+}
+
+const char* PackedValidEnumParserArg(const char* begin, const char* end,
+                                     void* object, ParseContext* ctx) {
+  auto repeated_field = static_cast<RepeatedField<int>*>(object);
+  auto ptr = begin;
+  while (ptr < end) {
+    uint64 varint;
+    ptr = Varint::Parse64(ptr, &varint);
+    int val = varint;
+    if (ctx->extra_parse_data().ValidateEnumArg<UnknownFieldSet>(val))
+      repeated_field->Add(val);
+  }
+  return ptr;
+}
+
+const char* UnknownGroupParse(const char* begin, const char* end, void* object,
+                              ParseContext* ctx) {
+  auto unknown = static_cast<UnknownFieldSet*>(object);
+
+  auto ptr = begin;
+  while (ptr < end) {
+    uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if ((tag >> 3) == 0) return nullptr;
+
+    auto res = UnknownFieldParse(tag, {UnknownGroupParse, unknown}, ptr, end,
+                                 unknown, ctx);
+    ptr = res.first;
+    if (res.second) break;
+  }
+  return ptr;
+}
+
+std::pair<const char*, bool> UnknownFieldParse(uint32 tag, ParseClosure parent,
+                                               const char* begin,
+                                               const char* end,
+                                               UnknownFieldSet* unknown,
+                                               ParseContext* ctx) {
+  uint32 size;
+  int depth;
+  void* object;
+  auto ptr = begin;
+
+  GOOGLE_DCHECK(tag >> 3);
+
+  uint32 field_num = tag >> 3;
+  switch (tag & 7) {
+    case 0: {
+      uint64 val;
+      ptr = Varint::Parse64(ptr, &val);
+      if (!ptr) goto error;
+      unknown->AddVarint(field_num, val);
+      break;
+    }
+    case 1: {
+      uint64 val = UNALIGNED_LOAD64(ptr);
+      ptr = ptr + 8;
+      unknown->AddFixed64(field_num, val);
+      break;
+    }
+    case 2: {
+      ptr = Varint::Parse32Inline(ptr, &size);
+      if (!ptr) goto error;
+      object = unknown->AddLengthDelimited(field_num);
+      if (size > end - ptr) goto len_delim_till_end;
+      auto newend = ptr + size;
+      if (!ctx->ParseExactRange({StringParser, object}, ptr, newend)) {
+        goto error;
+      }
+      ptr = newend;
+      break;
+    }
+    case 3: {
+      object = unknown->AddGroup(field_num);
+      if (!ctx->PrepareGroup(tag, &depth)) goto error;
+      ptr = UnknownGroupParse(ptr, end, object, ctx);
+      if (!ptr) goto error;
+      if (ctx->GroupContinues(depth)) goto group_continues;
+      break;
+    }
+    case 4: {
+      if (!ctx->ValidEndGroup(tag)) goto error;
+      return std::make_pair(ptr, true);
+    }
+    case 5: {
+      uint32 val = UNALIGNED_LOAD32(ptr);
+      ptr = ptr + 4;
+      unknown->AddFixed32(field_num, val);
+      break;
+    }
+    default:
+      goto error;
+  }
+  return std::make_pair(ptr, false);
+error:
+  return std::make_pair(nullptr, true);
+len_delim_till_end:
+  // Length delimited field crosses end
+  return std::make_pair(
+      ctx->StoreAndTailCall(ptr, end, parent, {StringParser, object}, size),
+      true);
+group_continues:
+  GOOGLE_DCHECK(ptr >= end);
+  // Group crossed end and must be continued. Either this a parse failure
+  // or we need to resume on the next chunk and thus save the state.
+  ctx->StoreGroup(parent, {UnknownGroupParse, object}, depth);
+  return std::make_pair(ptr, true);
+}
+
+}  // namespace internal
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h
index 619855e..d891a9e 100644
--- a/src/google/protobuf/unknown_field_set.h
+++ b/src/google/protobuf/unknown_field_set.h
@@ -43,7 +43,19 @@
 #include <vector>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/message_lite.h>
+#include <google/protobuf/port.h>
+
+#include <google/protobuf/port_def.inc>
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+#include <google/protobuf/parse_context.h>
+#endif
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
 
 namespace google {
 namespace protobuf {
@@ -181,6 +193,60 @@
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet);
 };
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+namespace internal {
+inline void WriteVarint(uint32 num, uint64 val, UnknownFieldSet* unknown) {
+  unknown->AddVarint(num, val);
+}
+
+const char* PackedValidEnumParser(const char* begin, const char* end,
+                                  void* object, ParseContext* ctx);
+const char* PackedValidEnumParserArg(const char* begin, const char* end,
+                                     void* object, ParseContext* ctx);
+
+const char* UnknownGroupParse(const char* begin, const char* end, void* object,
+                              ParseContext* ctx);
+std::pair<const char*, bool> UnknownFieldParse(uint32 tag, ParseClosure parent,
+                                               const char* begin,
+                                               const char* end,
+                                               UnknownFieldSet* unknown,
+                                               ParseContext* ctx);
+template <typename Msg>
+const char* ParseMessageSet(const char* begin, const char* end, Msg* msg,
+                            internal::ParseContext* ctx) {
+  auto ptr = begin;
+  int depth;
+  (void)depth;
+  while (ptr < end) {
+    uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    if (tag == 11) {
+      if (!ctx->PrepareGroup(tag, &depth)) goto error;
+      ctx->extra_parse_data().payload.clear();
+      ptr = Msg::InternalParseMessageSetItem(ptr, end, msg, ctx);
+      if (!ptr) goto error;
+      if (ctx->GroupContinues(depth)) goto group_continues;
+    } else {
+      auto res = UnknownFieldParse(tag, {Msg::_InternalParse, msg}, begin, end,
+                                   msg->mutable_unknown_fields(), ctx);
+      ptr = res.first;
+      if (res.second) break;
+    }
+  }
+  return ptr;
+error:
+  return nullptr;
+group_continues:
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({Msg::_InternalParse, msg},
+                  {Msg::InternalParseMessageSetItem, msg}, depth);
+  return ptr;
+}
+
+}  // namespace internal
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
 // Represents one field in an UnknownFieldSet.
 class LIBPROTOBUF_EXPORT UnknownField {
  public:
@@ -358,6 +424,7 @@
 
 
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
 #endif  // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
diff --git a/src/google/protobuf/unknown_field_set_unittest.cc b/src/google/protobuf/unknown_field_set_unittest.cc
index a64769e..5dad1d0 100644
--- a/src/google/protobuf/unknown_field_set_unittest.cc
+++ b/src/google/protobuf/unknown_field_set_unittest.cc
@@ -35,6 +35,7 @@
 // This test is testing a lot more than just the UnknownFieldSet class.  It
 // tests handling of unknown fields throughout the system.
 
+#include <google/protobuf/stubs/mutex.h>
 #include <google/protobuf/unknown_field_set.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/io/coded_stream.h>
@@ -46,10 +47,10 @@
 #include <google/protobuf/stubs/callback.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/mutex.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 
+
 #include <google/protobuf/stubs/stl_util.h>
 
 namespace google {
@@ -195,13 +196,14 @@
   slow_buffer.resize(size);
   fast_buffer.resize(size);
 
-  uint8* target = reinterpret_cast<uint8*>(string_as_array(&fast_buffer));
+  uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&fast_buffer));
   uint8* result = WireFormat::SerializeUnknownFieldsToArray(
           empty_message_.unknown_fields(), target);
   EXPECT_EQ(size, result - target);
 
   {
-    io::ArrayOutputStream raw_stream(string_as_array(&slow_buffer), size, 1);
+    io::ArrayOutputStream raw_stream(::google::protobuf::string_as_array(&slow_buffer), size,
+                                     1);
     io::CodedOutputStream output_stream(&raw_stream);
     WireFormat::SerializeUnknownFields(empty_message_.unknown_fields(),
                                        &output_stream);
diff --git a/src/google/protobuf/util/field_comparator.cc b/src/google/protobuf/util/field_comparator.cc
index 86ddf06..ed02ac4 100644
--- a/src/google/protobuf/util/field_comparator.cc
+++ b/src/google/protobuf/util/field_comparator.cc
@@ -57,11 +57,9 @@
 DefaultFieldComparator::~DefaultFieldComparator() {}
 
 FieldComparator::ComparisonResult DefaultFieldComparator::Compare(
-      const google::protobuf::Message& message_1,
-      const google::protobuf::Message& message_2,
-      const google::protobuf::FieldDescriptor* field,
-      int index_1, int index_2,
-      const google::protobuf::util::FieldContext* field_context) {
+    const Message& message_1, const Message& message_2,
+    const FieldDescriptor* field, int index_1, int index_2,
+    const util::FieldContext* field_context) {
   const Reflection* reflection_1 = message_1.GetReflection();
   const Reflection* reflection_2 = message_2.GetReflection();
 
@@ -131,11 +129,10 @@
   }
 }
 
-bool DefaultFieldComparator::Compare(
-    MessageDifferencer* differencer,
-    const Message& message1,
-    const Message& message2,
-    const google::protobuf::util::FieldContext* field_context) {
+bool DefaultFieldComparator::Compare(MessageDifferencer* differencer,
+                                     const Message& message1,
+                                     const Message& message2,
+                                     const util::FieldContext* field_context) {
   return differencer->Compare(
       message1, message2, field_context->parent_fields());
 }
diff --git a/src/google/protobuf/util/field_comparator.h b/src/google/protobuf/util/field_comparator.h
index 63e89fb..624fb2c 100644
--- a/src/google/protobuf/util/field_comparator.h
+++ b/src/google/protobuf/util/field_comparator.h
@@ -82,12 +82,11 @@
   // FieldContext contains information about the specific instances of the
   // fields being compared, versus FieldDescriptor which only contains general
   // type information about the fields.
-  virtual ComparisonResult Compare(
-      const google::protobuf::Message& message_1,
-      const google::protobuf::Message& message_2,
-      const google::protobuf::FieldDescriptor* field,
-      int index_1, int index_2,
-      const google::protobuf::util::FieldContext* field_context) = 0;
+  virtual ComparisonResult Compare(const Message& message_1,
+                                   const Message& message_2,
+                                   const FieldDescriptor* field, int index_1,
+                                   int index_2,
+                                   const util::FieldContext* field_context) = 0;
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldComparator);
@@ -112,12 +111,10 @@
 
   ~DefaultFieldComparator() override;
 
-  ComparisonResult Compare(
-      const google::protobuf::Message& message_1,
-      const google::protobuf::Message& message_2,
-      const google::protobuf::FieldDescriptor* field,
-      int index_1, int index_2,
-      const google::protobuf::util::FieldContext* field_context) override;
+  ComparisonResult Compare(const Message& message_1, const Message& message_2,
+                           const FieldDescriptor* field, int index_1,
+                           int index_2,
+                           const util::FieldContext* field_context) override;
 
   void set_float_comparison(FloatComparison float_comparison) {
     float_comparison_ = float_comparison;
@@ -159,10 +156,9 @@
   // Compare using the provided message_differencer. For example, a subclass can
   // use this method to compare some field in a certain way using the same
   // message_differencer instance and the field context.
-  bool Compare(MessageDifferencer* differencer,
-               const google::protobuf::Message& message1,
-               const google::protobuf::Message& message2,
-               const google::protobuf::util::FieldContext* field_context);
+  bool Compare(MessageDifferencer* differencer, const Message& message1,
+               const Message& message2,
+               const util::FieldContext* field_context);
 
  private:
   // Defines the tolerance for floating point comparison (fraction and margin).
@@ -184,56 +180,53 @@
   // basic types (instead of submessages). They return true on success. One
   // can use ResultFromBoolean() to convert that boolean to a ComparisonResult
   // value.
-  bool CompareBool(const google::protobuf::FieldDescriptor& field,
-                   bool value_1, bool value_2) {
+  bool CompareBool(const FieldDescriptor& field, bool value_1, bool value_2) {
     return value_1 == value_2;
   }
 
   // Uses CompareDoubleOrFloat, a helper function used by both CompareDouble and
   // CompareFloat.
-  bool CompareDouble(const google::protobuf::FieldDescriptor& field,
-                     double value_1, double value_2);
+  bool CompareDouble(const FieldDescriptor& field, double value_1,
+                     double value_2);
 
-  bool CompareEnum(const google::protobuf::FieldDescriptor& field,
+  bool CompareEnum(const FieldDescriptor& field,
                    const EnumValueDescriptor* value_1,
                    const EnumValueDescriptor* value_2);
 
   // Uses CompareDoubleOrFloat, a helper function used by both CompareDouble and
   // CompareFloat.
-  bool CompareFloat(const google::protobuf::FieldDescriptor& field,
-                    float value_1, float value_2);
+  bool CompareFloat(const FieldDescriptor& field, float value_1, float value_2);
 
-  bool CompareInt32(const google::protobuf::FieldDescriptor& field,
-                    int32 value_1, int32 value_2) {
+  bool CompareInt32(const FieldDescriptor& field, int32 value_1,
+                    int32 value_2) {
     return value_1 == value_2;
   }
 
-  bool CompareInt64(const google::protobuf::FieldDescriptor& field,
-                    int64 value_1, int64 value_2) {
+  bool CompareInt64(const FieldDescriptor& field, int64 value_1,
+                    int64 value_2) {
     return value_1 == value_2;
   }
 
-  bool CompareString(const google::protobuf::FieldDescriptor& field,
-                     const string& value_1, const string& value_2) {
+  bool CompareString(const FieldDescriptor& field, const string& value_1,
+                     const string& value_2) {
     return value_1 == value_2;
   }
 
-  bool CompareUInt32(const google::protobuf::FieldDescriptor& field,
-                     uint32 value_1, uint32 value_2) {
+  bool CompareUInt32(const FieldDescriptor& field, uint32 value_1,
+                     uint32 value_2) {
     return value_1 == value_2;
   }
 
-  bool CompareUInt64(const google::protobuf::FieldDescriptor& field,
-                     uint64 value_1, uint64 value_2) {
+  bool CompareUInt64(const FieldDescriptor& field, uint64 value_1,
+                     uint64 value_2) {
     return value_1 == value_2;
   }
 
   // This function is used by CompareDouble and CompareFloat to avoid code
   // duplication. There are no checks done against types of the values passed,
   // but it's likely to fail if passed non-numeric arguments.
-  template<typename T>
-  bool CompareDoubleOrFloat(const google::protobuf::FieldDescriptor& field,
-                            T value_1, T value_2);
+  template <typename T>
+  bool CompareDoubleOrFloat(const FieldDescriptor& field, T value_1, T value_2);
 
   // Returns FieldComparator::SAME if boolean_result is true and
   // FieldComparator::DIFFERENT otherwise.
@@ -265,6 +258,6 @@
 
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
diff --git a/src/google/protobuf/util/field_comparator_test.cc b/src/google/protobuf/util/field_comparator_test.cc
index 249b8d5..4a1729c 100644
--- a/src/google/protobuf/util/field_comparator_test.cc
+++ b/src/google/protobuf/util/field_comparator_test.cc
@@ -482,7 +482,7 @@
             comparator_.Compare(message_1_, message_2_, field, 1, 0, NULL));
 }
 
+}  // namespace
 }  // namespace util
 }  // namespace protobuf
-}  // namespace
 }  // namespace google
diff --git a/src/google/protobuf/util/field_mask_util.cc b/src/google/protobuf/util/field_mask_util.cc
index a2e2a38..cf65ef2 100644
--- a/src/google/protobuf/util/field_mask_util.cc
+++ b/src/google/protobuf/util/field_mask_util.cc
@@ -53,7 +53,8 @@
   }
 }
 
-bool FieldMaskUtil::SnakeCaseToCamelCase(StringPiece input, string* output) {
+bool FieldMaskUtil::SnakeCaseToCamelCase(StringPiece input,
+                                         string* output) {
   output->clear();
   bool after_underscore = false;
   for (int i = 0; i < input.size(); ++i) {
@@ -82,7 +83,8 @@
   return true;
 }
 
-bool FieldMaskUtil::CamelCaseToSnakeCase(StringPiece input, string* output) {
+bool FieldMaskUtil::CamelCaseToSnakeCase(StringPiece input,
+                                         string* output) {
   output->clear();
   for (int i = 0; i < input.size(); ++i) {
     if (input[i] == '_') {
@@ -228,12 +230,13 @@
   }
 
   // Trims all fields not specified by this tree from the given message.
-  void TrimMessage(Message* message) {
+  // Returns true if the message is modified.
+  bool TrimMessage(Message* message) {
     // Do nothing if the tree is empty.
     if (root_.children.empty()) {
-      return;
+      return false;
     }
-    TrimMessage(&root_, message);
+    return TrimMessage(&root_, message);
   }
 
  private:
@@ -276,7 +279,8 @@
   void AddRequiredFieldPath(Node* node, const Descriptor* descriptor);
 
   // Trims all fields not specified by this sub-tree from the given message.
-  void TrimMessage(const Node* node, Message* message);
+  // Returns true if the message is actually modified
+  bool TrimMessage(const Node* node, Message* message);
 
   Node root_;
 
@@ -576,26 +580,39 @@
   }
 }
 
-void FieldMaskTree::TrimMessage(const Node* node, Message* message) {
+bool FieldMaskTree::TrimMessage(const Node* node, Message* message) {
   GOOGLE_DCHECK(!node->children.empty());
   const Reflection* reflection = message->GetReflection();
   const Descriptor* descriptor = message->GetDescriptor();
   const int32 field_count = descriptor->field_count();
+  bool modified = false;
   for (int index = 0; index < field_count; ++index) {
     const FieldDescriptor* field = descriptor->field(index);
     std::map<string, Node*>::const_iterator it =
         node->children.find(field->name());
     if (it == node->children.end()) {
+      if (field->is_repeated()) {
+        if (reflection->FieldSize(*message, field) != 0) {
+          modified = true;
+        }
+      } else {
+        if (reflection->HasField(*message, field)) {
+          modified = true;
+        }
+      }
       reflection->ClearField(message, field);
     } else {
       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
         Node* child = it->second;
         if (!child->children.empty() && reflection->HasField(*message, field)) {
-          TrimMessage(child, reflection->MutableMessage(message, field));
+          bool nestedMessageChanged =
+              TrimMessage(child, reflection->MutableMessage(message, field));
+          modified = nestedMessageChanged || modified;
         }
       }
     }
   }
+  return modified;
 }
 
 }  // namespace
@@ -643,7 +660,8 @@
   tree.MergeToFieldMask(out);
 }
 
-bool FieldMaskUtil::IsPathInFieldMask(StringPiece path, const FieldMask& mask) {
+bool FieldMaskUtil::IsPathInFieldMask(StringPiece path,
+                                      const FieldMask& mask) {
   for (int i = 0; i < mask.paths_size(); ++i) {
     const string& mask_path = mask.paths(i);
     if (path == mask_path) {
@@ -670,15 +688,15 @@
   tree.MergeMessage(source, options, destination);
 }
 
-void FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* destination) {
+bool FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* message) {
   // Build a FieldMaskTree and walk through the tree to merge all specified
   // fields.
   FieldMaskTree tree;
   tree.MergeFromFieldMask(mask);
-  tree.TrimMessage(GOOGLE_CHECK_NOTNULL(destination));
+  return tree.TrimMessage(GOOGLE_CHECK_NOTNULL(message));
 }
 
-void FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* destination,
+bool FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* message,
                                 const TrimOptions& options) {
   // Build a FieldMaskTree and walk through the tree to merge all specified
   // fields.
@@ -687,9 +705,9 @@
   // If keep_required_fields is true, implicitely add required fields of
   // a message present in the tree to prevent from trimming.
   if (options.keep_required_fields()) {
-    tree.AddRequiredFieldPath(GOOGLE_CHECK_NOTNULL(destination->GetDescriptor()));
+    tree.AddRequiredFieldPath(GOOGLE_CHECK_NOTNULL(message->GetDescriptor()));
   }
-  tree.TrimMessage(GOOGLE_CHECK_NOTNULL(destination));
+  return tree.TrimMessage(GOOGLE_CHECK_NOTNULL(message));
 }
 
 }  // namespace util
diff --git a/src/google/protobuf/util/field_mask_util.h b/src/google/protobuf/util/field_mask_util.h
index f0299de..6fabc3e 100644
--- a/src/google/protobuf/util/field_mask_util.h
+++ b/src/google/protobuf/util/field_mask_util.h
@@ -39,6 +39,8 @@
 #include <google/protobuf/field_mask.pb.h>
 #include <google/protobuf/stubs/stringpiece.h>
 
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 namespace util {
@@ -100,7 +102,8 @@
     return out;
   }
   template <typename T>
-  PROTOBUF_RUNTIME_DEPRECATED("Use *out = GetFieldMaskForAllFields() instead")
+  GOOGLE_PROTOBUF_DEPRECATED_MSG(
+      "Use *out = GetFieldMaskForAllFields() instead")
   static void GetFieldMaskForAllFields(FieldMask* out) {
     InternalGetFieldMaskForAllFields(T::descriptor(), out);
   }
@@ -134,21 +137,21 @@
   static bool IsPathInFieldMask(StringPiece path, const FieldMask& mask);
 
   class MergeOptions;
-  // Merges fields specified in a FieldMask into another message. See the
-  // comments in MergeOptions regarding compatibility with
-  // google/protobuf/field_mask.proto
+  // Merges fields specified in a FieldMask into another message.
   static void MergeMessageTo(const Message& source, const FieldMask& mask,
                              const MergeOptions& options, Message* destination);
 
   class TrimOptions;
   // Removes from 'message' any field that is not represented in the given
   // FieldMask. If the FieldMask is empty, does nothing.
-  static void TrimMessage(const FieldMask& mask, Message* message);
+  // Returns true if the message is modified.
+  static bool TrimMessage(const FieldMask& mask, Message* message);
 
   // Removes from 'message' any field that is not represented in the given
   // FieldMask with customized TrimOptions.
   // If the FieldMask is empty, does nothing.
-  static void TrimMessage(const FieldMask& mask, Message* message,
+  // Returns true if the message is modified.
+  static bool TrimMessage(const FieldMask& mask, Message* message,
                           const TrimOptions& options);
 
  private:
@@ -189,10 +192,6 @@
                                FieldMask* out);
 };
 
-// Note that for compatibility with the defined behaviour for FieldMask in
-// google/protobuf/field_mask.proto, set replace_message_fields and
-// replace_repeated_fields to 'true'. The default options are not compatible
-// with google/protobuf/field_mask.proto.
 class LIBPROTOBUF_EXPORT FieldMaskUtil::MergeOptions {
  public:
   MergeOptions()
@@ -240,6 +239,8 @@
 
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
diff --git a/src/google/protobuf/util/field_mask_util_test.cc b/src/google/protobuf/util/field_mask_util_test.cc
index 3ba30aa..93ad955 100644
--- a/src/google/protobuf/util/field_mask_util_test.cc
+++ b/src/google/protobuf/util/field_mask_util_test.cc
@@ -747,6 +747,75 @@
   EXPECT_EQ(11, oneof_msg.oneof_uint32());
 }
 
+TEST(FieldMaskUtilTest, TrimMessageReturnValue) {
+  FieldMask mask;
+  TestAllTypes trimed_msg;
+  TestAllTypes default_msg;
+
+  // Field mask on optional field.
+  FieldMaskUtil::FromString("optional_int32", &mask);
+
+  // Verify that if a message is updted by FieldMaskUtil::TrimMessage(), the
+  // function returns true.
+  // Test on primary field.
+  trimed_msg.set_optional_string("abc");
+  EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+  EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
+  trimed_msg.Clear();
+
+  // Test on repeated primary field.
+  trimed_msg.add_repeated_string("abc");
+  trimed_msg.add_repeated_string("def");
+  EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+  EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
+  trimed_msg.Clear();
+
+  // Test on nested message.
+  trimed_msg.mutable_optional_nested_message()->set_bb(123);
+  EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+  EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
+  trimed_msg.Clear();
+
+  // Test on repeated nested message.
+  trimed_msg.add_repeated_nested_message()->set_bb(123);
+  trimed_msg.add_repeated_nested_message()->set_bb(456);
+  EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+  EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
+  trimed_msg.Clear();
+
+  // Test on oneof field.
+  trimed_msg.set_oneof_uint32(123);
+  EXPECT_TRUE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+  EXPECT_EQ(trimed_msg.DebugString(), default_msg.DebugString());
+  trimed_msg.Clear();
+
+  // If there is no field set other then those whitelisted,
+  // FieldMaskUtil::TrimMessage() should return false.
+  trimed_msg.set_optional_int32(123);
+  EXPECT_FALSE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+  EXPECT_EQ(trimed_msg.optional_int32(), 123);
+  trimed_msg.Clear();
+
+  // Field mask on repated field.
+  FieldMaskUtil::FromString("repeated_string", &mask);
+  trimed_msg.add_repeated_string("abc");
+  trimed_msg.add_repeated_string("def");
+  EXPECT_FALSE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+  EXPECT_EQ(trimed_msg.repeated_string(0), "abc");
+  EXPECT_EQ(trimed_msg.repeated_string(1), "def");
+  trimed_msg.Clear();
+
+  // Field mask on nested message.
+  FieldMaskUtil::FromString("optional_nested_message.bb", &mask);
+  trimed_msg.mutable_optional_nested_message()->set_bb(123);
+  EXPECT_FALSE(FieldMaskUtil::TrimMessage(mask, &trimed_msg));
+  EXPECT_EQ(trimed_msg.optional_nested_message().bb(), 123);
+  trimed_msg.Clear();
+
+  // TODO(b/32443320): field mask on repeated nested message is not yet
+  // supported.
+}
+
 
 }  // namespace
 }  // namespace util
diff --git a/src/google/protobuf/util/internal/constants.h b/src/google/protobuf/util/internal/constants.h
index a018a09..3ace10c 100644
--- a/src/google/protobuf/util/internal/constants.h
+++ b/src/google/protobuf/util/internal/constants.h
@@ -96,6 +96,9 @@
 const char kFieldMaskTypeUrl[] =
     "type.googleapis.com/google.protobuf.FieldMask";
 
+// The protobuf option name of jspb.message_id;
+const char kOptionJspbMessageId[] = "jspb.message_id";
+
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
diff --git a/src/google/protobuf/util/internal/datapiece.cc b/src/google/protobuf/util/internal/datapiece.cc
index 59bc28a..72b7d17 100644
--- a/src/google/protobuf/util/internal/datapiece.cc
+++ b/src/google/protobuf/util/internal/datapiece.cc
@@ -43,8 +43,6 @@
 namespace util {
 namespace converter {
 
-using google::protobuf::EnumDescriptor;
-using google::protobuf::EnumValueDescriptor;
 ;
 ;
 ;
@@ -130,7 +128,8 @@
 }
 
 StatusOr<uint32> DataPiece::ToUint32() const {
-  if (type_ == TYPE_STRING) return StringToNumber<uint32>(safe_strtou32);
+  if (type_ == TYPE_STRING)
+    return StringToNumber<uint32>(safe_strtou32);
 
   if (type_ == TYPE_DOUBLE)
     return FloatingPointToIntConvertAndCheck<uint32, double>(double_);
@@ -154,7 +153,8 @@
 }
 
 StatusOr<uint64> DataPiece::ToUint64() const {
-  if (type_ == TYPE_STRING) return StringToNumber<uint64>(safe_strtou64);
+  if (type_ == TYPE_STRING)
+    return StringToNumber<uint64>(safe_strtou64);
 
   if (type_ == TYPE_DOUBLE)
     return FloatingPointToIntConvertAndCheck<uint64, double>(double_);
@@ -215,7 +215,7 @@
 StatusOr<string> DataPiece::ToString() const {
   switch (type_) {
     case TYPE_STRING:
-      return str_.ToString();
+      return string(str_);
     case TYPE_BYTES: {
       string base64;
       Base64Escape(str_, &base64);
@@ -227,7 +227,8 @@
   }
 }
 
-string DataPiece::ValueAsStringOrDefault(StringPiece default_string) const {
+string DataPiece::ValueAsStringOrDefault(
+    StringPiece default_string) const {
   switch (type_) {
     case TYPE_INT32:
       return SimpleItoa(i32_);
@@ -253,7 +254,7 @@
     case TYPE_NULL:
       return "null";
     default:
-      return default_string.ToString();
+      return string(default_string);
   }
 }
 
@@ -273,12 +274,13 @@
 
 StatusOr<int> DataPiece::ToEnum(const google::protobuf::Enum* enum_type,
                                 bool use_lower_camel_for_enums,
-                                bool ignore_unknown_enum_values) const {
+                                bool ignore_unknown_enum_values,
+                                bool* is_unknown_enum_value) const {
   if (type_ == TYPE_NULL) return google::protobuf::NULL_VALUE;
 
   if (type_ == TYPE_STRING) {
     // First try the given value as a name.
-    string enum_name = str_.ToString();
+    string enum_name = string(str_);
     const google::protobuf::EnumValue* value =
         FindEnumValueByNameOrNull(enum_type, enum_name);
     if (value != nullptr) return value->number();
@@ -307,9 +309,11 @@
       if (value != nullptr) return value->number();
     }
 
-    // If ignore_unknown_enum_values is true an unknown enum value is treated
-    // as the default
-    if (ignore_unknown_enum_values) return enum_type->enumvalue(0).number();
+    // If ignore_unknown_enum_values is true an unknown enum value is ignored.
+    if (ignore_unknown_enum_values) {
+      *is_unknown_enum_value = true;
+      return enum_type->enumvalue(0).number();
+    }
   } else {
     // We don't need to check whether the value is actually declared in the
     // enum because we preserve unknown enum values as well.
@@ -342,13 +346,14 @@
 }
 
 template <typename To>
-StatusOr<To> DataPiece::StringToNumber(bool (*func)(StringPiece, To*)) const {
+StatusOr<To> DataPiece::StringToNumber(bool (*func)(StringPiece,
+                                                    To*)) const {
   if (str_.size() > 0 && (str_[0] == ' ' || str_[str_.size() - 1] == ' ')) {
     return InvalidArgument(StrCat("\"", str_, "\""));
   }
   To result;
   if (func(str_, &result)) return result;
-  return InvalidArgument(StrCat("\"", str_.ToString(), "\""));
+  return InvalidArgument(StrCat("\"", string(str_), "\""));
 }
 
 bool DataPiece::DecodeBase64(StringPiece src, string* dest) const {
diff --git a/src/google/protobuf/util/internal/datapiece.h b/src/google/protobuf/util/internal/datapiece.h
index 95b133d..074fde6 100644
--- a/src/google/protobuf/util/internal/datapiece.h
+++ b/src/google/protobuf/util/internal/datapiece.h
@@ -37,16 +37,17 @@
 #include <google/protobuf/stubs/stringpiece.h>
 #include <google/protobuf/stubs/statusor.h>
 
-
 namespace google {
 namespace protobuf {
 class Enum;
 }  // namespace protobuf
+}  // namespace google
 
-
+namespace google {
 namespace protobuf {
 namespace util {
 namespace converter {
+class ProtoWriter;
 
 // Container for a single piece of data together with its data type.
 //
@@ -164,10 +165,13 @@
   // If the value is not a string, attempts to convert to a 32-bit integer.
   // If none of these succeeds, returns a conversion error status.
   util::StatusOr<int> ToEnum(const google::protobuf::Enum* enum_type,
-                               bool use_lower_camel_for_enums,
-                               bool ignore_unknown_enum_values) const;
+                               bool use_lower_camel_for_enums) const {
+    return ToEnum(enum_type, use_lower_camel_for_enums, false, nullptr);
+  }
 
  private:
+  friend class ProtoWriter;
+
   // Disallow implicit constructor.
   DataPiece();
 
@@ -175,6 +179,13 @@
   DataPiece(Type type, int32 val)
       : type_(type), i32_(val), use_strict_base64_decoding_(false) {}
 
+  // Same as the ToEnum() method above but with additional flag to ignore
+  // unknown enum values.
+  util::StatusOr<int> ToEnum(const google::protobuf::Enum* enum_type,
+                               bool use_lower_camel_for_enums,
+                               bool ignore_unknown_enum_values,
+                               bool* is_unknown_enum_value) const;
+
   // For numeric conversion between
   //     int32, int64, uint32, uint64, double, float and bool
   template <typename To>
@@ -183,7 +194,8 @@
   // For conversion from string to
   //     int32, int64, uint32, uint64, double, float and bool
   template <typename To>
-  util::StatusOr<To> StringToNumber(bool (*func)(StringPiece, To*)) const;
+  util::StatusOr<To> StringToNumber(bool (*func)(StringPiece,
+                                                   To*)) const;
 
   // Decodes a base64 string. Returns true on success.
   bool DecodeBase64(StringPiece src, string* dest) const;
@@ -215,6 +227,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_DATAPIECE_H__
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc
index b41feb7..c1d3101 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.cc
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc
@@ -30,7 +30,7 @@
 
 #include <google/protobuf/util/internal/default_value_objectwriter.h>
 
-#include <google/protobuf/stubs/hash.h>
+#include <unordered_map>
 
 #include <google/protobuf/util/internal/constants.h>
 #include <google/protobuf/util/internal/utility.h>
@@ -48,8 +48,8 @@
 // passed converter function on the DataPiece created from "value" argument.
 // If value is empty or if conversion fails, the default_value is returned.
 template <typename T>
-T ConvertTo(StringPiece value, StatusOr<T> (DataPiece::*converter_fn)() const,
-            T default_value) {
+T ConvertTo(StringPiece value,
+            StatusOr<T> (DataPiece::*converter_fn)() const, T default_value) {
   if (value.empty()) return default_value;
   StatusOr<T> result = (DataPiece(value, true).*converter_fn)();
   return result.ok() ? result.ValueOrDie() : default_value;
@@ -79,8 +79,8 @@
   }
 }
 
-DefaultValueObjectWriter* DefaultValueObjectWriter::RenderBool(StringPiece name,
-                                                               bool value) {
+DefaultValueObjectWriter* DefaultValueObjectWriter::RenderBool(
+    StringPiece name, bool value) {
   if (current_ == nullptr) {
     ow_->RenderBool(name, value);
   } else {
@@ -156,7 +156,7 @@
   } else {
     // Since StringPiece is essentially a pointer, takes a copy of "value" to
     // avoid ownership issues.
-    string_values_.push_back(new string(value.ToString()));
+    string_values_.push_back(new string(value));
     RenderDataPiece(name, DataPiece(*string_values_.back(), true));
   }
   return this;
@@ -193,42 +193,18 @@
 DefaultValueObjectWriter::Node* DefaultValueObjectWriter::CreateNewNode(
     const string& name, const google::protobuf::Type* type, NodeKind kind,
     const DataPiece& data, bool is_placeholder, const std::vector<string>& path,
-    bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback) {
+    bool suppress_empty_list, bool preserve_proto_field_names,
+    bool use_ints_for_enums, FieldScrubCallBack* field_scrub_callback) {
   return new Node(name, type, kind, data, is_placeholder, path,
-                  suppress_empty_list, field_scrub_callback);
-}
-
-DefaultValueObjectWriter::Node* DefaultValueObjectWriter::CreateNewNode(
-    const string& name, const google::protobuf::Type* type, NodeKind kind,
-    const DataPiece& data, bool is_placeholder, const std::vector<string>& path,
-    bool suppress_empty_list, bool preserve_proto_field_names, bool use_ints_for_enums,
-    FieldScrubCallBack* field_scrub_callback) {
-  return new Node(name, type, kind, data, is_placeholder, path,
-                  suppress_empty_list, preserve_proto_field_names, use_ints_for_enums,
-                  field_scrub_callback);
+                  suppress_empty_list, preserve_proto_field_names,
+                  use_ints_for_enums, field_scrub_callback);
 }
 
 DefaultValueObjectWriter::Node::Node(
     const string& name, const google::protobuf::Type* type, NodeKind kind,
     const DataPiece& data, bool is_placeholder, const std::vector<string>& path,
-    bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback)
-    : name_(name),
-      type_(type),
-      kind_(kind),
-      is_any_(false),
-      data_(data),
-      is_placeholder_(is_placeholder),
-      path_(path),
-      suppress_empty_list_(suppress_empty_list),
-      preserve_proto_field_names_(false),
-      use_ints_for_enums_(false),
-      field_scrub_callback_(field_scrub_callback) {}
-
-DefaultValueObjectWriter::Node::Node(
-    const string& name, const google::protobuf::Type* type, NodeKind kind,
-    const DataPiece& data, bool is_placeholder, const std::vector<string>& path,
-    bool suppress_empty_list, bool preserve_proto_field_names, bool use_ints_for_enums,
-    FieldScrubCallBack* field_scrub_callback)
+    bool suppress_empty_list, bool preserve_proto_field_names,
+    bool use_ints_for_enums, FieldScrubCallBack* field_scrub_callback)
     : name_(name),
       type_(type),
       kind_(kind),
@@ -337,7 +313,7 @@
     return;
   }
   std::vector<Node*> new_children;
-  hash_map<string, int> orig_children_map;
+  std::unordered_map<string, int> orig_children_map;
 
   // Creates a map of child nodes to speed up lookup.
   for (int i = 0; i < children_.size(); ++i) {
@@ -359,7 +335,7 @@
       continue;
     }
 
-    hash_map<string, int>::iterator found =
+    std::unordered_map<string, int>::iterator found =
         orig_children_map.find(field.name());
     // If the child field has already been set, we just add it to the new list
     // of children.
@@ -408,13 +384,14 @@
 
     // If the child field is of primitive type, sets its data to the default
     // value of its type.
-    std::unique_ptr<Node> child(new Node(
-        preserve_proto_field_names_ ? field.name() : field.json_name(),
-        field_type, kind,
-        kind == PRIMITIVE ? CreateDefaultDataPieceForField(field, typeinfo, use_ints_for_enums_)
-                          : DataPiece::NullData(),
-        true, path, suppress_empty_list_, preserve_proto_field_names_, use_ints_for_enums_,
-        field_scrub_callback_));
+    std::unique_ptr<Node> child(
+        new Node(preserve_proto_field_names_ ? field.name() : field.json_name(),
+                 field_type, kind,
+                 kind == PRIMITIVE ? CreateDefaultDataPieceForField(
+                                         field, typeinfo, use_ints_for_enums_)
+                                   : DataPiece::NullData(),
+                 true, path, suppress_empty_list_, preserve_proto_field_names_,
+                 use_ints_for_enums_, field_scrub_callback_));
     new_children.push_back(child.release());
   }
   // Adds all leftover nodes in children_ to the beginning of new_child.
@@ -438,7 +415,8 @@
 }
 
 DataPiece DefaultValueObjectWriter::FindEnumDefault(
-    const google::protobuf::Field& field, const TypeInfo* typeinfo, bool use_ints_for_enums) {
+    const google::protobuf::Field& field, const TypeInfo* typeinfo,
+    bool use_ints_for_enums) {
   if (!field.default_value().empty())
     return DataPiece(field.default_value(), true);
 
@@ -451,12 +429,15 @@
   }
   // We treat the first value as the default if none is specified.
   return enum_type->enumvalue_size() > 0
-             ? (use_ints_for_enums ? DataPiece(enum_type->enumvalue(0).number()) : DataPiece(enum_type->enumvalue(0).name(), true))
+             ? (use_ints_for_enums
+                    ? DataPiece(enum_type->enumvalue(0).number())
+                    : DataPiece(enum_type->enumvalue(0).name(), true))
              : DataPiece::NullData();
 }
 
 DataPiece DefaultValueObjectWriter::CreateDefaultDataPieceForField(
-    const google::protobuf::Field& field, const TypeInfo* typeinfo, bool use_ints_for_enums) {
+    const google::protobuf::Field& field, const TypeInfo* typeinfo,
+    bool use_ints_for_enums) {
   switch (field.kind()) {
     case google::protobuf::Field_Kind_TYPE_DOUBLE: {
       return DataPiece(ConvertTo<double>(
@@ -509,10 +490,10 @@
     StringPiece name) {
   if (current_ == nullptr) {
     std::vector<string> path;
-    root_.reset(CreateNewNode(string(name), &type_, OBJECT,
-                              DataPiece::NullData(), false, path,
-                              suppress_empty_list_, preserve_proto_field_names_, use_ints_for_enums_,
-                              field_scrub_callback_.get()));
+    root_.reset(CreateNewNode(
+        string(name), &type_, OBJECT, DataPiece::NullData(), false, path,
+        suppress_empty_list_, preserve_proto_field_names_, use_ints_for_enums_,
+        field_scrub_callback_.get()));
     root_->PopulateChildren(typeinfo_);
     current_ = root_.get();
     return this;
@@ -529,8 +510,8 @@
                            : nullptr),
                       OBJECT, DataPiece::NullData(), false,
                       child == nullptr ? current_->path() : child->path(),
-                      suppress_empty_list_, preserve_proto_field_names_, use_ints_for_enums_,
-                      field_scrub_callback_.get()));
+                      suppress_empty_list_, preserve_proto_field_names_,
+                      use_ints_for_enums_, field_scrub_callback_.get()));
     child = node.get();
     current_->AddChild(node.release());
   }
@@ -573,8 +554,8 @@
     std::unique_ptr<Node> node(
         CreateNewNode(string(name), nullptr, LIST, DataPiece::NullData(), false,
                       child == nullptr ? current_->path() : child->path(),
-                      suppress_empty_list_, preserve_proto_field_names_, use_ints_for_enums_,
-                      field_scrub_callback_.get()));
+                      suppress_empty_list_, preserve_proto_field_names_,
+                      use_ints_for_enums_, field_scrub_callback_.get()));
     child = node.get();
     current_->AddChild(node.release());
   }
@@ -635,8 +616,8 @@
     std::unique_ptr<Node> node(
         CreateNewNode(string(name), nullptr, PRIMITIVE, data, false,
                       child == nullptr ? current_->path() : child->path(),
-                      suppress_empty_list_, preserve_proto_field_names_, use_ints_for_enums_,
-                      field_scrub_callback_.get()));
+                      suppress_empty_list_, preserve_proto_field_names_,
+                      use_ints_for_enums_, field_scrub_callback_.get()));
     current_->AddChild(node.release());
   } else {
     child->set_data(data);
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h
index 7d245c9..d15cc7c 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.h
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.h
@@ -83,37 +83,41 @@
   virtual ~DefaultValueObjectWriter();
 
   // ObjectWriter methods.
-  virtual DefaultValueObjectWriter* StartObject(StringPiece name) override;
+  DefaultValueObjectWriter* StartObject(StringPiece name) override;
 
-  virtual DefaultValueObjectWriter* EndObject() override;
+  DefaultValueObjectWriter* EndObject() override;
 
-  virtual DefaultValueObjectWriter* StartList(StringPiece name) override;
+  DefaultValueObjectWriter* StartList(StringPiece name) override;
 
-  virtual DefaultValueObjectWriter* EndList() override;
+  DefaultValueObjectWriter* EndList() override;
 
-  virtual DefaultValueObjectWriter* RenderBool(StringPiece name, bool value) override;
+  DefaultValueObjectWriter* RenderBool(StringPiece name,
+                                       bool value) override;
 
-  virtual DefaultValueObjectWriter* RenderInt32(StringPiece name, int32 value) override;
+  DefaultValueObjectWriter* RenderInt32(StringPiece name,
+                                        int32 value) override;
 
-  virtual DefaultValueObjectWriter* RenderUint32(StringPiece name,
+  DefaultValueObjectWriter* RenderUint32(StringPiece name,
                                          uint32 value) override;
 
-  virtual DefaultValueObjectWriter* RenderInt64(StringPiece name, int64 value) override;
+  DefaultValueObjectWriter* RenderInt64(StringPiece name,
+                                        int64 value) override;
 
-  virtual DefaultValueObjectWriter* RenderUint64(StringPiece name,
+  DefaultValueObjectWriter* RenderUint64(StringPiece name,
                                          uint64 value) override;
 
-  virtual DefaultValueObjectWriter* RenderDouble(StringPiece name,
+  DefaultValueObjectWriter* RenderDouble(StringPiece name,
                                          double value) override;
 
-  virtual DefaultValueObjectWriter* RenderFloat(StringPiece name, float value) override;
+  DefaultValueObjectWriter* RenderFloat(StringPiece name,
+                                        float value) override;
 
-  virtual DefaultValueObjectWriter* RenderString(StringPiece name,
+  DefaultValueObjectWriter* RenderString(StringPiece name,
                                          StringPiece value) override;
-  virtual DefaultValueObjectWriter* RenderBytes(StringPiece name,
+  DefaultValueObjectWriter* RenderBytes(StringPiece name,
                                         StringPiece value) override;
 
-  virtual DefaultValueObjectWriter* RenderNull(StringPiece name) override;
+  virtual DefaultValueObjectWriter* RenderNull(StringPiece name);
 
   // Register the callback for scrubbing of fields. Owership of
   // field_scrub_callback pointer is also transferred to this class
@@ -130,9 +134,7 @@
 
   // If set to true, enums are rendered as ints from output when default values
   // are written.
-  void set_print_enums_as_ints(bool value) {
-    use_ints_for_enums_ = value;
-  }
+  void set_print_enums_as_ints(bool value) { use_ints_for_enums_ = value; }
 
  protected:
   enum NodeKind {
@@ -149,10 +151,6 @@
     Node(const string& name, const google::protobuf::Type* type, NodeKind kind,
          const DataPiece& data, bool is_placeholder,
          const std::vector<string>& path, bool suppress_empty_list,
-         FieldScrubCallBack* field_scrub_callback);
-    Node(const string& name, const google::protobuf::Type* type, NodeKind kind,
-         const DataPiece& data, bool is_placeholder,
-         const std::vector<string>& path, bool suppress_empty_list,
          bool preserve_proto_field_names, bool use_ints_for_enums,
          FieldScrubCallBack* field_scrub_callback);
     virtual ~Node() {
@@ -253,21 +251,20 @@
                               const DataPiece& data, bool is_placeholder,
                               const std::vector<string>& path,
                               bool suppress_empty_list,
-                              FieldScrubCallBack* field_scrub_callback);
-
-  // Creates a new Node and returns it. Caller owns memory of returned object.
-  virtual Node* CreateNewNode(const string& name,
-                              const google::protobuf::Type* type, NodeKind kind,
-                              const DataPiece& data, bool is_placeholder,
-                              const std::vector<string>& path,
-                              bool suppress_empty_list,
                               bool preserve_proto_field_names,
                               bool use_ints_for_enums,
                               FieldScrubCallBack* field_scrub_callback);
 
   // Creates a DataPiece containing the default value of the type of the field.
   static DataPiece CreateDefaultDataPieceForField(
-      const google::protobuf::Field& field, const TypeInfo* typeinfo, bool use_ints_for_enums);
+      const google::protobuf::Field& field, const TypeInfo* typeinfo) {
+    return CreateDefaultDataPieceForField(field, typeinfo, false);
+  }
+
+  // Same as the above but with a flag to use ints instead of enum names.
+  static DataPiece CreateDefaultDataPieceForField(
+      const google::protobuf::Field& field, const TypeInfo* typeinfo,
+      bool use_ints_for_enums);
 
  protected:
   // Returns a pointer to current Node in tree.
@@ -330,6 +327,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_DEFAULT_VALUE_OBJECTWRITER_H__
diff --git a/src/google/protobuf/util/internal/error_listener.h b/src/google/protobuf/util/internal/error_listener.h
index e3baa22..1866652 100644
--- a/src/google/protobuf/util/internal/error_listener.h
+++ b/src/google/protobuf/util/internal/error_listener.h
@@ -54,11 +54,13 @@
 
   // Reports an invalid name at the given location.
   virtual void InvalidName(const LocationTrackerInterface& loc,
-                           StringPiece invalid_name, StringPiece message) = 0;
+                           StringPiece invalid_name,
+                           StringPiece message) = 0;
 
   // Reports an invalid value for a field.
   virtual void InvalidValue(const LocationTrackerInterface& loc,
-                            StringPiece type_name, StringPiece value) = 0;
+                            StringPiece type_name,
+                            StringPiece value) = 0;
 
   // Reports a missing required field.
   virtual void MissingField(const LocationTrackerInterface& loc,
@@ -76,15 +78,17 @@
 class LIBPROTOBUF_EXPORT NoopErrorListener : public ErrorListener {
  public:
   NoopErrorListener() {}
-  virtual ~NoopErrorListener() override {}
+  ~NoopErrorListener() override {}
 
-  virtual void InvalidName(const LocationTrackerInterface& loc,
-                           StringPiece invalid_name, StringPiece message) override {}
+  void InvalidName(const LocationTrackerInterface& loc,
+                   StringPiece invalid_name,
+                   StringPiece message) override {}
 
-  virtual void InvalidValue(const LocationTrackerInterface &loc, StringPiece type_name,
+  void InvalidValue(const LocationTrackerInterface& loc,
+                    StringPiece type_name,
                     StringPiece value) override {}
 
-  virtual void MissingField(const LocationTrackerInterface &loc,
+  void MissingField(const LocationTrackerInterface& loc,
                     StringPiece missing_name) override {}
 
  private:
@@ -95,6 +99,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_ERROR_LISTENER_H__
diff --git a/src/google/protobuf/util/internal/expecting_objectwriter.h b/src/google/protobuf/util/internal/expecting_objectwriter.h
index ae98ddd..a7f6fc2 100644
--- a/src/google/protobuf/util/internal/expecting_objectwriter.h
+++ b/src/google/protobuf/util/internal/expecting_objectwriter.h
@@ -54,6 +54,7 @@
 #include <google/protobuf/util/internal/object_writer.h>
 #include <gmock/gmock.h>
 
+
 namespace google {
 namespace protobuf {
 namespace util {
@@ -81,7 +82,8 @@
   MOCK_METHOD2(RenderUint64, ObjectWriter*(StringPiece, uint64));
   MOCK_METHOD2(RenderDouble, ObjectWriter*(StringPiece, double));
   MOCK_METHOD2(RenderFloat, ObjectWriter*(StringPiece, float));
-  MOCK_METHOD2(RenderString, ObjectWriter*(StringPiece, StringPiece));
+  MOCK_METHOD2(RenderString,
+               ObjectWriter*(StringPiece, StringPiece));
   MOCK_METHOD2(RenderBytes, ObjectWriter*(StringPiece, StringPiece));
   MOCK_METHOD1(RenderNull, ObjectWriter*(StringPiece));
 };
@@ -91,9 +93,8 @@
   explicit ExpectingObjectWriter(MockObjectWriter* mock) : mock_(mock) {}
 
   virtual ObjectWriter* StartObject(StringPiece name) {
-    (name.empty()
-         ? EXPECT_CALL(*mock_, StartObject(IsEmpty()))
-         : EXPECT_CALL(*mock_, StartObject(StrEq(name.ToString()))))
+    (name.empty() ? EXPECT_CALL(*mock_, StartObject(IsEmpty()))
+                  : EXPECT_CALL(*mock_, StartObject(StrEq(string(name)))))
         .WillOnce(Return(mock_))
         .RetiresOnSaturation();
     return this;
@@ -107,9 +108,8 @@
   }
 
   virtual ObjectWriter* StartList(StringPiece name) {
-    (name.empty()
-         ? EXPECT_CALL(*mock_, StartList(IsEmpty()))
-         : EXPECT_CALL(*mock_, StartList(StrEq(name.ToString()))))
+    (name.empty() ? EXPECT_CALL(*mock_, StartList(IsEmpty()))
+                  : EXPECT_CALL(*mock_, StartList(StrEq(string(name)))))
         .WillOnce(Return(mock_))
         .RetiresOnSaturation();
     return this;
@@ -125,8 +125,8 @@
   virtual ObjectWriter* RenderBool(StringPiece name, bool value) {
     (name.empty()
          ? EXPECT_CALL(*mock_, RenderBool(IsEmpty(), TypedEq<bool>(value)))
-         : EXPECT_CALL(*mock_, RenderBool(StrEq(name.ToString()),
-                                          TypedEq<bool>(value))))
+         : EXPECT_CALL(*mock_,
+                       RenderBool(StrEq(string(name)), TypedEq<bool>(value))))
         .WillOnce(Return(mock_))
         .RetiresOnSaturation();
     return this;
@@ -135,8 +135,8 @@
   virtual ObjectWriter* RenderInt32(StringPiece name, int32 value) {
     (name.empty()
          ? EXPECT_CALL(*mock_, RenderInt32(IsEmpty(), TypedEq<int32>(value)))
-         : EXPECT_CALL(*mock_, RenderInt32(StrEq(name.ToString()),
-                                           TypedEq<int32>(value))))
+         : EXPECT_CALL(*mock_,
+                       RenderInt32(StrEq(string(name)), TypedEq<int32>(value))))
         .WillOnce(Return(mock_))
         .RetiresOnSaturation();
     return this;
@@ -145,7 +145,7 @@
   virtual ObjectWriter* RenderUint32(StringPiece name, uint32 value) {
     (name.empty()
          ? EXPECT_CALL(*mock_, RenderUint32(IsEmpty(), TypedEq<uint32>(value)))
-         : EXPECT_CALL(*mock_, RenderUint32(StrEq(name.ToString()),
+         : EXPECT_CALL(*mock_, RenderUint32(StrEq(string(name)),
                                             TypedEq<uint32>(value))))
         .WillOnce(Return(mock_))
         .RetiresOnSaturation();
@@ -155,8 +155,8 @@
   virtual ObjectWriter* RenderInt64(StringPiece name, int64 value) {
     (name.empty()
          ? EXPECT_CALL(*mock_, RenderInt64(IsEmpty(), TypedEq<int64>(value)))
-         : EXPECT_CALL(*mock_, RenderInt64(StrEq(name.ToString()),
-                                           TypedEq<int64>(value))))
+         : EXPECT_CALL(*mock_,
+                       RenderInt64(StrEq(string(name)), TypedEq<int64>(value))))
         .WillOnce(Return(mock_))
         .RetiresOnSaturation();
     return this;
@@ -165,7 +165,7 @@
   virtual ObjectWriter* RenderUint64(StringPiece name, uint64 value) {
     (name.empty()
          ? EXPECT_CALL(*mock_, RenderUint64(IsEmpty(), TypedEq<uint64>(value)))
-         : EXPECT_CALL(*mock_, RenderUint64(StrEq(name.ToString()),
+         : EXPECT_CALL(*mock_, RenderUint64(StrEq(string(name)),
                                             TypedEq<uint64>(value))))
         .WillOnce(Return(mock_))
         .RetiresOnSaturation();
@@ -174,9 +174,9 @@
 
   virtual ObjectWriter* RenderDouble(StringPiece name, double value) {
     (name.empty()
-         ? EXPECT_CALL(*mock_, RenderDouble(IsEmpty(),
-                                            NanSensitiveDoubleEq(value)))
-         : EXPECT_CALL(*mock_, RenderDouble(StrEq(name.ToString()),
+         ? EXPECT_CALL(*mock_,
+                       RenderDouble(IsEmpty(), NanSensitiveDoubleEq(value)))
+         : EXPECT_CALL(*mock_, RenderDouble(StrEq(string(name)),
                                             NanSensitiveDoubleEq(value))))
         .WillOnce(Return(mock_))
         .RetiresOnSaturation();
@@ -185,21 +185,24 @@
 
   virtual ObjectWriter* RenderFloat(StringPiece name, float value) {
     (name.empty()
-         ? EXPECT_CALL(*mock_, RenderFloat(IsEmpty(),
-                                           NanSensitiveFloatEq(value)))
-         : EXPECT_CALL(*mock_, RenderFloat(StrEq(name.ToString()),
+         ? EXPECT_CALL(*mock_,
+                       RenderFloat(IsEmpty(), NanSensitiveFloatEq(value)))
+         : EXPECT_CALL(*mock_, RenderFloat(StrEq(string(name)),
                                            NanSensitiveFloatEq(value))))
         .WillOnce(Return(mock_))
         .RetiresOnSaturation();
     return this;
   }
 
-  virtual ObjectWriter* RenderString(StringPiece name, StringPiece value) {
+  virtual ObjectWriter* RenderString(StringPiece name,
+                                     StringPiece value) {
     (name.empty()
-         ? EXPECT_CALL(*mock_, RenderString(IsEmpty(),
-               TypedEq<StringPiece>(value.ToString())))
-         : EXPECT_CALL(*mock_, RenderString(StrEq(name.ToString()),
-               TypedEq<StringPiece>(value.ToString()))))
+         ? EXPECT_CALL(*mock_,
+                       RenderString(IsEmpty(),
+                                    TypedEq<StringPiece>(string(value))))
+         : EXPECT_CALL(*mock_,
+                       RenderString(StrEq(string(name)),
+                                    TypedEq<StringPiece>(string(value)))))
         .WillOnce(Return(mock_))
         .RetiresOnSaturation();
     return this;
@@ -218,7 +221,7 @@
 
   virtual ObjectWriter* RenderNull(StringPiece name) {
     (name.empty() ? EXPECT_CALL(*mock_, RenderNull(IsEmpty()))
-                  : EXPECT_CALL(*mock_, RenderNull(StrEq(name.ToString())))
+                  : EXPECT_CALL(*mock_, RenderNull(StrEq(string(name))))
                         .WillOnce(Return(mock_))
                         .RetiresOnSaturation());
     return this;
@@ -233,6 +236,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_EXPECTING_OBJECTWRITER_H__
diff --git a/src/google/protobuf/util/internal/field_mask_utility.cc b/src/google/protobuf/util/internal/field_mask_utility.cc
index 778a451..014b81a 100644
--- a/src/google/protobuf/util/internal/field_mask_utility.cc
+++ b/src/google/protobuf/util/internal/field_mask_utility.cc
@@ -46,12 +46,13 @@
 }
 
 // Appends a FieldMask path segment to a prefix.
-string AppendPathSegmentToPrefix(StringPiece prefix, StringPiece segment) {
+string AppendPathSegmentToPrefix(StringPiece prefix,
+                                 StringPiece segment) {
   if (prefix.empty()) {
-    return segment.ToString();
+    return string(segment);
   }
   if (segment.empty()) {
-    return prefix.ToString();
+    return string(prefix);
   }
   // If the segment is a map key, appends it to the prefix without the ".".
   if (StringStartsWith(segment, "[\"")) {
@@ -135,8 +136,9 @@
         if (i >= length - 1 || paths[i + 1] != ']') {
           return util::Status(
               util::error::INVALID_ARGUMENT,
-              StrCat("Invalid FieldMask '", paths,
-                     "'. Map keys should be represented as [\"some_key\"]."));
+              StrCat(
+                  "Invalid FieldMask '", paths,
+                  "'. Map keys should be represented as [\"some_key\"]."));
         }
         // The end of the map key ("\"]") has been found.
         in_map_key = false;
@@ -147,8 +149,9 @@
             paths[i + 1] != ')' && paths[i + 1] != '(') {
           return util::Status(
               util::error::INVALID_ARGUMENT,
-              StrCat("Invalid FieldMask '", paths,
-                     "'. Map keys should be at the end of a path segment."));
+              StrCat(
+                  "Invalid FieldMask '", paths,
+                  "'. Map keys should be at the end of a path segment."));
         }
         is_escaping = false;
         continue;
@@ -159,8 +162,9 @@
         if (i >= length - 1 || paths[i + 1] != '\"') {
           return util::Status(
               util::error::INVALID_ARGUMENT,
-              StrCat("Invalid FieldMask '", paths,
-                     "'. Map keys should be represented as [\"some_key\"]."));
+              StrCat(
+                  "Invalid FieldMask '", paths,
+                  "'. Map keys should be represented as [\"some_key\"]."));
         }
         // "[\"" starts a map key.
         in_map_key = true;
@@ -196,21 +200,23 @@
         return util::Status(
             util::error::INVALID_ARGUMENT,
             StrCat("Invalid FieldMask '", paths,
-                   "'. Cannot find matching '(' for all ')'."));
+                         "'. Cannot find matching '(' for all ')'."));
       }
       prefix.pop();
     }
     previous_position = i + 1;
   }
   if (in_map_key) {
-    return util::Status(util::error::INVALID_ARGUMENT,
-                          StrCat("Invalid FieldMask '", paths,
-                                 "'. Cannot find matching ']' for all '['."));
+    return util::Status(
+        util::error::INVALID_ARGUMENT,
+        StrCat("Invalid FieldMask '", paths,
+                     "'. Cannot find matching ']' for all '['."));
   }
   if (!prefix.empty()) {
-    return util::Status(util::error::INVALID_ARGUMENT,
-                          StrCat("Invalid FieldMask '", paths,
-                                 "'. Cannot find matching ')' for all '('."));
+    return util::Status(
+        util::error::INVALID_ARGUMENT,
+        StrCat("Invalid FieldMask '", paths,
+                     "'. Cannot find matching ')' for all '('."));
   }
   return util::Status();
 }
diff --git a/src/google/protobuf/util/internal/field_mask_utility.h b/src/google/protobuf/util/internal/field_mask_utility.h
index 59f36f7..7d1c2af 100644
--- a/src/google/protobuf/util/internal/field_mask_utility.h
+++ b/src/google/protobuf/util/internal/field_mask_utility.h
@@ -67,6 +67,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_FIELD_MASK_UTILITY_H__
diff --git a/src/google/protobuf/util/internal/json_escaping.cc b/src/google/protobuf/util/internal/json_escaping.cc
index 06b9a7f..d167359 100644
--- a/src/google/protobuf/util/internal/json_escaping.cc
+++ b/src/google/protobuf/util/internal/json_escaping.cc
@@ -134,8 +134,8 @@
 // Returns false if we encounter an invalid UTF-8 string. Returns true
 // otherwise, including the case when we reach the end of the input (str)
 // before a complete unicode code point is read.
-bool ReadCodePoint(StringPiece str, int index,
-                   uint32 *cp, int* num_left, int *num_read) {
+bool ReadCodePoint(StringPiece str, int index, uint32* cp, int* num_left,
+                   int* num_read) {
   if (*num_left == 0) {
     // Last read was complete. Start reading a new unicode code point.
     *cp = static_cast<uint8>(str[index++]);
diff --git a/src/google/protobuf/util/internal/json_escaping.h b/src/google/protobuf/util/internal/json_escaping.h
index 5495c57..07042f6 100644
--- a/src/google/protobuf/util/internal/json_escaping.h
+++ b/src/google/protobuf/util/internal/json_escaping.h
@@ -86,6 +86,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_INTERNAL__JSON_ESCAPING_H__
diff --git a/src/google/protobuf/util/internal/json_objectwriter.cc b/src/google/protobuf/util/internal/json_objectwriter.cc
index a431177..c2d3292 100644
--- a/src/google/protobuf/util/internal/json_objectwriter.cc
+++ b/src/google/protobuf/util/internal/json_objectwriter.cc
@@ -49,7 +49,7 @@
 ;
 
 JsonObjectWriter::~JsonObjectWriter() {
-  if (!element_->is_root()) {
+  if (element_ && !element_->is_root()) {
     GOOGLE_LOG(WARNING) << "JsonObjectWriter was not fully closed.";
   }
 }
@@ -64,7 +64,7 @@
 JsonObjectWriter* JsonObjectWriter::EndObject() {
   Pop();
   WriteChar('}');
-  if (element()->is_root()) NewLine();
+  if (element() && element()->is_root()) NewLine();
   return this;
 }
 
@@ -82,11 +82,13 @@
   return this;
 }
 
-JsonObjectWriter* JsonObjectWriter::RenderBool(StringPiece name, bool value) {
+JsonObjectWriter* JsonObjectWriter::RenderBool(StringPiece name,
+                                               bool value) {
   return RenderSimple(name, value ? "true" : "false");
 }
 
-JsonObjectWriter* JsonObjectWriter::RenderInt32(StringPiece name, int32 value) {
+JsonObjectWriter* JsonObjectWriter::RenderInt32(StringPiece name,
+                                                int32 value) {
   return RenderSimple(name, SimpleItoa(value));
 }
 
@@ -95,7 +97,8 @@
   return RenderSimple(name, SimpleItoa(value));
 }
 
-JsonObjectWriter* JsonObjectWriter::RenderInt64(StringPiece name, int64 value) {
+JsonObjectWriter* JsonObjectWriter::RenderInt64(StringPiece name,
+                                                int64 value) {
   WritePrefix(name);
   WriteChar('"');
   stream_->WriteString(SimpleItoa(value));
@@ -122,7 +125,8 @@
   return RenderString(name, DoubleAsString(value));
 }
 
-JsonObjectWriter* JsonObjectWriter::RenderFloat(StringPiece name, float value) {
+JsonObjectWriter* JsonObjectWriter::RenderFloat(StringPiece name,
+                                                float value) {
   if (MathLimits<float>::IsFinite(value)) {
     return RenderSimple(name, SimpleFtoa(value));
   }
diff --git a/src/google/protobuf/util/internal/json_objectwriter.h b/src/google/protobuf/util/internal/json_objectwriter.h
index 4c25b46..c8a061d 100644
--- a/src/google/protobuf/util/internal/json_objectwriter.h
+++ b/src/google/protobuf/util/internal/json_objectwriter.h
@@ -84,30 +84,30 @@
 // JsonObjectWriter is thread-unsafe.
 class LIBPROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter {
  public:
-  JsonObjectWriter(StringPiece indent_string,
-                   google::protobuf::io::CodedOutputStream* out)
+  JsonObjectWriter(StringPiece indent_string, io::CodedOutputStream* out)
       : element_(new Element(/*parent=*/nullptr, /*is_json_object=*/false)),
         stream_(out),
         sink_(out),
-        indent_string_(indent_string.ToString()),
+        indent_string_(indent_string),
         use_websafe_base64_for_bytes_(false) {}
   virtual ~JsonObjectWriter();
 
   // ObjectWriter methods.
-  virtual JsonObjectWriter* StartObject(StringPiece name) override;
-  virtual JsonObjectWriter* EndObject() override;
-  virtual JsonObjectWriter* StartList(StringPiece name) override;
-  virtual JsonObjectWriter* EndList() override;
-  virtual JsonObjectWriter* RenderBool(StringPiece name, bool value) override;
-  virtual JsonObjectWriter* RenderInt32(StringPiece name, int32 value) override;
-  virtual JsonObjectWriter* RenderUint32(StringPiece name, uint32 value) override;
-  virtual JsonObjectWriter* RenderInt64(StringPiece name, int64 value) override;
-  virtual JsonObjectWriter* RenderUint64(StringPiece name, uint64 value) override;
-  virtual JsonObjectWriter* RenderDouble(StringPiece name, double value) override;
-  virtual JsonObjectWriter* RenderFloat(StringPiece name, float value) override;
-  virtual JsonObjectWriter* RenderString(StringPiece name, StringPiece value) override;
-  virtual JsonObjectWriter* RenderBytes(StringPiece name, StringPiece value) override;
-  virtual JsonObjectWriter* RenderNull(StringPiece name) override;
+  virtual JsonObjectWriter* StartObject(StringPiece name);
+  virtual JsonObjectWriter* EndObject();
+  virtual JsonObjectWriter* StartList(StringPiece name);
+  virtual JsonObjectWriter* EndList();
+  virtual JsonObjectWriter* RenderBool(StringPiece name, bool value);
+  virtual JsonObjectWriter* RenderInt32(StringPiece name, int32 value);
+  virtual JsonObjectWriter* RenderUint32(StringPiece name, uint32 value);
+  virtual JsonObjectWriter* RenderInt64(StringPiece name, int64 value);
+  virtual JsonObjectWriter* RenderUint64(StringPiece name, uint64 value);
+  virtual JsonObjectWriter* RenderDouble(StringPiece name, double value);
+  virtual JsonObjectWriter* RenderFloat(StringPiece name, float value);
+  virtual JsonObjectWriter* RenderString(StringPiece name,
+                                         StringPiece value);
+  virtual JsonObjectWriter* RenderBytes(StringPiece name, StringPiece value);
+  virtual JsonObjectWriter* RenderNull(StringPiece name);
   virtual JsonObjectWriter* RenderNullAsEmpty(StringPiece name);
 
   void set_use_websafe_base64_for_bytes(bool value) {
@@ -148,8 +148,7 @@
  private:
   class LIBPROTOBUF_EXPORT ByteSinkWrapper : public strings::ByteSink {
    public:
-    explicit ByteSinkWrapper(google::protobuf::io::CodedOutputStream* stream)
-        : stream_(stream) {}
+    explicit ByteSinkWrapper(io::CodedOutputStream* stream) : stream_(stream) {}
     ~ByteSinkWrapper() override {}
 
     // ByteSink methods.
@@ -158,7 +157,7 @@
     }
 
    private:
-    google::protobuf::io::CodedOutputStream* stream_;
+    io::CodedOutputStream* stream_;
 
     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ByteSinkWrapper);
   };
@@ -209,7 +208,7 @@
   void WriteChar(const char c) { stream_->WriteRaw(&c, sizeof(c)); }
 
   std::unique_ptr<Element> element_;
-  google::protobuf::io::CodedOutputStream* stream_;
+  io::CodedOutputStream* stream_;
   ByteSinkWrapper sink_;
   const string indent_string_;
 
@@ -223,6 +222,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_OBJECTWRITER_H__
diff --git a/src/google/protobuf/util/internal/json_objectwriter_test.cc b/src/google/protobuf/util/internal/json_objectwriter_test.cc
index 0dc710c..6363652 100644
--- a/src/google/protobuf/util/internal/json_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/json_objectwriter_test.cc
@@ -39,8 +39,8 @@
 namespace util {
 namespace converter {
 
-using google::protobuf::io::CodedOutputStream;
-using google::protobuf::io::StringOutputStream;
+using io::CodedOutputStream;
+using io::StringOutputStream;
 
 class JsonObjectWriterTest : public ::testing::Test {
  protected:
diff --git a/src/google/protobuf/util/internal/json_stream_parser.cc b/src/google/protobuf/util/internal/json_stream_parser.cc
index 1c63b31..e272bbd 100644
--- a/src/google/protobuf/util/internal/json_stream_parser.cc
+++ b/src/google/protobuf/util/internal/json_stream_parser.cc
@@ -39,9 +39,10 @@
 
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+
 #include <google/protobuf/util/internal/object_writer.h>
 #include <google/protobuf/util/internal/json_escaping.h>
-#include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/mathlimits.h>
 
 
@@ -63,6 +64,8 @@
 // Number of digits in an escaped UTF-16 code unit ('\\' 'u' X X X X)
 static const int kUnicodeEscapedLength = 6;
 
+static const int kDefaultMaxRecursionDepth = 100;
+
 // Length of the true, false, and null literals.
 static const int true_len = strlen("true");
 static const int false_len = strlen("false");
@@ -109,7 +112,9 @@
       chunk_storage_(),
       coerce_to_utf8_(false),
       allow_empty_null_(false),
-      loose_float_number_conversion_(false) {
+      loose_float_number_conversion_(false),
+      recursion_depth_(0),
+      max_recursion_depth_(kDefaultMaxRecursionDepth) {
   // Initialize the stack with a single value to be parsed.
   stack_.push(VALUE);
 }
@@ -201,7 +206,7 @@
     }
     // If we expect future data i.e. stack is non-empty, and we have some
     // unparsed data left, we save it for later parse.
-    leftover_ = p_.ToString();
+    leftover_ = string(p_);
   }
   return util::Status();
 }
@@ -539,7 +544,7 @@
   }
 
   // Create a string containing just the number, so we can use safe_strtoX
-  string number = p_.substr(0, index).ToString();
+  string number = string(p_.substr(0, index));
 
   // Floating point number, parse as a double.
   if (floating) {
@@ -593,6 +598,10 @@
   GOOGLE_DCHECK_EQ('{', *p_.data());
   Advance();
   ow_->StartObject(key_);
+  auto status = IncrementRecursionDepth(key_);
+  if (!status.ok()) {
+    return status;
+  }
   key_ = StringPiece();
   stack_.push(ENTRY);
   return util::Status();
@@ -607,6 +616,7 @@
   if (type == END_OBJECT) {
     Advance();
     ow_->EndObject();
+    --recursion_depth_;
     return util::Status();
   }
   // Found a comma, advance past it and get ready for an entry.
@@ -628,6 +638,7 @@
   if (type == END_OBJECT) {
     ow_->EndObject();
     Advance();
+    --recursion_depth_;
     return util::Status();
   }
 
@@ -784,6 +795,17 @@
   return ReportFailure(message);
 }
 
+util::Status JsonStreamParser::IncrementRecursionDepth(
+    StringPiece key) const {
+  if (++recursion_depth_ > max_recursion_depth_) {
+    return Status(
+        util::error::INVALID_ARGUMENT,
+        StrCat("Message too deep. Max recursion depth reached for key '",
+                     key, "'"));
+  }
+  return util::Status();
+}
+
 void JsonStreamParser::SkipWhitespace() {
   while (!p_.empty() && ascii_isspace(*p_.data())) {
     Advance();
diff --git a/src/google/protobuf/util/internal/json_stream_parser.h b/src/google/protobuf/util/internal/json_stream_parser.h
index 31933b6..4a065d2 100644
--- a/src/google/protobuf/util/internal/json_stream_parser.h
+++ b/src/google/protobuf/util/internal/json_stream_parser.h
@@ -38,11 +38,11 @@
 #include <google/protobuf/stubs/stringpiece.h>
 #include <google/protobuf/stubs/status.h>
 
-namespace google {
 namespace util {
 class Status;
 }  // namespace util
 
+namespace google {
 namespace protobuf {
 namespace util {
 namespace converter {
@@ -83,7 +83,18 @@
   util::Status FinishParse();
 
 
+  // Sets the max recursion depth of JSON message to be deserialized. JSON
+  // messages over this depth will fail to be deserialized.
+  // Default value is 100.
+  void set_max_recursion_depth(int max_depth) {
+    max_recursion_depth_ = max_depth;
+  }
+
  private:
+  friend class JsonStreamParserTest;
+  // Return the current recursion depth.
+  const int recursion_depth() { return recursion_depth_; }
+
   enum TokenType {
     BEGIN_STRING,     // " or '
     BEGIN_NUMBER,     // - or digit
@@ -195,6 +206,11 @@
   // status to return in this case.
   util::Status ReportUnknown(StringPiece message);
 
+  // Helper function to check recursion depth and increment it. It will return
+  // Status::OK if the current depth is allowed. Otherwise an error is returned.
+  // key is used for error reporting.
+  util::Status IncrementRecursionDepth(StringPiece key) const;
+
   // Advance p_ past all whitespace or until the end of the string.
   void SkipWhitespace();
 
@@ -261,12 +277,18 @@
   // Whether allows out-of-range floating point numbers or reject them.
   bool loose_float_number_conversion_;
 
+  // Tracks current recursion depth.
+  mutable int recursion_depth_;
+
+  // Maximum allowed recursion depth.
+  int max_recursion_depth_;
+
   GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(JsonStreamParser);
 };
 
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_STREAM_PARSER_H__
diff --git a/src/google/protobuf/util/internal/json_stream_parser_test.cc b/src/google/protobuf/util/internal/json_stream_parser_test.cc
index a11e9be..764c9f7 100644
--- a/src/google/protobuf/util/internal/json_stream_parser_test.cc
+++ b/src/google/protobuf/util/internal/json_stream_parser_test.cc
@@ -37,6 +37,7 @@
 #include <google/protobuf/util/internal/object_writer.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <gtest/gtest.h>
+
 #include <google/protobuf/stubs/status.h>
 
 
@@ -88,8 +89,8 @@
   JsonStreamParserTest() : mock_(), ow_(&mock_) {}
   virtual ~JsonStreamParserTest() {}
 
-  util::Status RunTest(StringPiece json, int split, bool coerce_utf8 = false,
-                       bool allow_empty_null = false,
+  util::Status RunTest(StringPiece json, int split,
+                       bool coerce_utf8 = false, bool allow_empty_null = false,
                        bool loose_float_number_conversion = false) {
     JsonStreamParser parser(&mock_);
 
@@ -117,6 +118,9 @@
         result = parser.FinishParse();
       }
     }
+    if (result.ok()){
+      EXPECT_EQ(parser.recursion_depth(), 0);
+    }
     return result;
   }
 
@@ -131,8 +135,9 @@
     EXPECT_OK(result);
   }
 
-  void DoErrorTest(StringPiece json, int split, StringPiece error_prefix,
-                   bool coerce_utf8 = false, bool allow_empty_null = false) {
+  void DoErrorTest(StringPiece json, int split,
+                   StringPiece error_prefix, bool coerce_utf8 = false,
+                   bool allow_empty_null = false) {
     util::Status result =
         RunTest(json, split, coerce_utf8, allow_empty_null);
     EXPECT_EQ(util::error::INVALID_ARGUMENT, result.error_code());
@@ -838,6 +843,49 @@
   }
 }
 
+TEST_F(JsonStreamParserTest, DeepNestJsonNotExceedLimit) {
+  int count = 99;
+  string str;
+  for (int i = 0; i < count; ++i) {
+    StrAppend(&str, "{'a':");
+  }
+  StrAppend(&str, "{'nest64':'v1', 'nest64': false, 'nest64': ['v2']}");
+  for (int i = 0; i < count; ++i) {
+    StrAppend(&str, "}");
+  }
+  ow_.StartObject("");
+  for (int i = 0; i < count; ++i) {
+    ow_.StartObject("a");
+  }
+  ow_.RenderString("nest64", "v1")
+      ->RenderBool("nest64", false)
+      ->StartList("nest64")
+      ->RenderString("", "v2")
+      ->EndList();
+  for (int i = 0; i < count; ++i) {
+    ow_.EndObject();
+  }
+  ow_.EndObject();
+  DoTest(str, 0);
+}
+
+TEST_F(JsonStreamParserTest, DeepNestJsonExceedLimit) {
+  int count = 98;
+  string str;
+  for (int i = 0; i < count; ++i) {
+    StrAppend(&str, "{'a':");
+  }
+  // Supports trailing commas.
+  StrAppend(&str,
+                  "{'nest11' : [{'nest12' : null,},],"
+                  "'nest21' : {'nest22' : {'nest23' : false}}}");
+  for (int i = 0; i < count; ++i) {
+    StrAppend(&str, "}");
+  }
+  DoErrorTest(str, 0,
+              "Message too deep. Max recursion depth reached for key 'nest22'");
+}
+
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
diff --git a/src/google/protobuf/util/internal/location_tracker.h b/src/google/protobuf/util/internal/location_tracker.h
index 0864b05..52173d7 100644
--- a/src/google/protobuf/util/internal/location_tracker.h
+++ b/src/google/protobuf/util/internal/location_tracker.h
@@ -60,6 +60,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_LOCATION_TRACKER_H__
diff --git a/src/google/protobuf/util/internal/mock_error_listener.h b/src/google/protobuf/util/internal/mock_error_listener.h
index 591c35d..1f1321f 100644
--- a/src/google/protobuf/util/internal/mock_error_listener.h
+++ b/src/google/protobuf/util/internal/mock_error_listener.h
@@ -31,11 +31,11 @@
 #ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_MOCK_ERROR_LISTENER_H__
 #define GOOGLE_PROTOBUF_UTIL_CONVERTER_MOCK_ERROR_LISTENER_H__
 
-#include <google/protobuf/stubs/stringpiece.h>
 #include <google/protobuf/util/internal/error_listener.h>
 #include <google/protobuf/util/internal/location_tracker.h>
 #include <gmock/gmock.h>
 
+
 namespace google {
 namespace protobuf {
 namespace util {
@@ -46,11 +46,12 @@
   MockErrorListener() {}
   virtual ~MockErrorListener() {}
 
-  MOCK_METHOD3(InvalidName, void(const LocationTrackerInterface& loc,
-                                 StringPiece unknown_name,
-                                 StringPiece message));
-  MOCK_METHOD3(InvalidValue, void(const LocationTrackerInterface& loc,
-                                  StringPiece type_name, StringPiece value));
+  MOCK_METHOD3(InvalidName,
+               void(const LocationTrackerInterface& loc,
+                    StringPiece unknown_name, StringPiece message));
+  MOCK_METHOD3(InvalidValue,
+               void(const LocationTrackerInterface& loc,
+                    StringPiece type_name, StringPiece value));
   MOCK_METHOD2(MissingField, void(const LocationTrackerInterface& loc,
                                   StringPiece missing_name));
 };
@@ -58,6 +59,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_MOCK_ERROR_LISTENER_H__
diff --git a/src/google/protobuf/util/internal/object_location_tracker.h b/src/google/protobuf/util/internal/object_location_tracker.h
index f9b90bc..61189a7 100644
--- a/src/google/protobuf/util/internal/object_location_tracker.h
+++ b/src/google/protobuf/util/internal/object_location_tracker.h
@@ -59,6 +59,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_LOCATION_TRACKER_H__
diff --git a/src/google/protobuf/util/internal/object_source.h b/src/google/protobuf/util/internal/object_source.h
index 2c31cfb..3a24b75 100644
--- a/src/google/protobuf/util/internal/object_source.h
+++ b/src/google/protobuf/util/internal/object_source.h
@@ -74,6 +74,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_SOURCE_H__
diff --git a/src/google/protobuf/util/internal/object_writer.cc b/src/google/protobuf/util/internal/object_writer.cc
index 57cc08a..bb1b3e5 100644
--- a/src/google/protobuf/util/internal/object_writer.cc
+++ b/src/google/protobuf/util/internal/object_writer.cc
@@ -38,8 +38,8 @@
 namespace converter {
 
 // static
-void ObjectWriter::RenderDataPieceTo(const DataPiece& data, StringPiece name,
-                                     ObjectWriter* ow) {
+void ObjectWriter::RenderDataPieceTo(const DataPiece& data,
+                                     StringPiece name, ObjectWriter* ow) {
   switch (data.type()) {
     case DataPiece::TYPE_INT32: {
       ow->RenderInt32(name, data.ToInt32().ValueOrDie());
diff --git a/src/google/protobuf/util/internal/object_writer.h b/src/google/protobuf/util/internal/object_writer.h
index 5781aa1..a92c61d 100644
--- a/src/google/protobuf/util/internal/object_writer.h
+++ b/src/google/protobuf/util/internal/object_writer.h
@@ -93,7 +93,8 @@
   virtual ObjectWriter* RenderFloat(StringPiece name, float value) = 0;
 
   // Renders a StringPiece value. This is for rendering strings.
-  virtual ObjectWriter* RenderString(StringPiece name, StringPiece value) = 0;
+  virtual ObjectWriter* RenderString(StringPiece name,
+                                     StringPiece value) = 0;
 
   // Renders a bytes value.
   virtual ObjectWriter* RenderBytes(StringPiece name, StringPiece value) = 0;
@@ -134,6 +135,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_OBJECT_WRITER_H__
diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc
index b7a52db..5292195 100644
--- a/src/google/protobuf/util/internal/proto_writer.cc
+++ b/src/google/protobuf/util/internal/proto_writer.cc
@@ -45,16 +45,18 @@
 #include <google/protobuf/stubs/statusor.h>
 
 
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 namespace util {
 namespace converter {
 
-using google::protobuf::internal::WireFormatLite;
-using google::protobuf::io::CodedOutputStream;
-using util::error::INVALID_ARGUMENT;
+using ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
+using io::CodedOutputStream;
 using util::Status;
 using util::StatusOr;
+using util::error::INVALID_ARGUMENT;
 
 
 ProtoWriter::ProtoWriter(TypeResolver* type_resolver,
@@ -263,19 +265,6 @@
   return s.status();
 }
 
-// Writes an ENUM field, including tag, to the stream.
-inline Status WriteEnum(int field_number, const DataPiece& data,
-                        const google::protobuf::Enum* enum_type,
-                        CodedOutputStream* stream,
-                        bool use_lower_camel_for_enums,
-                        bool ignore_unknown_values) {
-  StatusOr<int> e = data.ToEnum(enum_type, use_lower_camel_for_enums, ignore_unknown_values);
-  if (e.ok()) {
-    WireFormatLite::WriteEnum(field_number, e.ValueOrDie(), stream);
-  }
-  return e.status();
-}
-
 // Given a google::protobuf::Type, returns the set of all required fields.
 std::set<const google::protobuf::Field*> GetRequiredFields(
     const google::protobuf::Type& type) {
@@ -426,11 +415,13 @@
   oneof_indices_[index] = true;
 }
 
-void ProtoWriter::InvalidName(StringPiece unknown_name, StringPiece message) {
+void ProtoWriter::InvalidName(StringPiece unknown_name,
+                              StringPiece message) {
   listener_->InvalidName(location(), ToSnakeCase(unknown_name), message);
 }
 
-void ProtoWriter::InvalidValue(StringPiece type_name, StringPiece value) {
+void ProtoWriter::InvalidValue(StringPiece type_name,
+                               StringPiece value) {
   listener_->InvalidValue(location(), type_name, value);
 }
 
@@ -462,8 +453,8 @@
   const google::protobuf::Type* type = LookupType(field);
   if (type == nullptr) {
     ++invalid_depth_;
-    InvalidName(name,
-                StrCat("Missing descriptor for field: ", field->type_url()));
+    InvalidName(name, StrCat("Missing descriptor for field: ",
+                                   field->type_url()));
     return this;
   }
 
@@ -501,8 +492,8 @@
   const google::protobuf::Type* type = LookupType(field);
   if (type == nullptr) {
     ++invalid_depth_;
-    InvalidName(name,
-                StrCat("Missing descriptor for field: ", field->type_url()));
+    InvalidName(name, StrCat("Missing descriptor for field: ",
+                                   field->type_url()));
     return this;
   }
 
@@ -530,8 +521,8 @@
 
   const google::protobuf::Type* type = LookupType(field);
   if (type == nullptr) {
-    InvalidName(name,
-                StrCat("Missing descriptor for field: ", field->type_url()));
+    InvalidName(name, StrCat("Missing descriptor for field: ",
+                                   field->type_url()));
     return this;
   }
 
@@ -546,9 +537,9 @@
     if (element_->IsOneofIndexTaken(field.oneof_index())) {
       InvalidValue(
           "oneof",
-          StrCat("oneof field '",
-                 element_->type().oneofs(field.oneof_index() - 1),
-                 "' is already set. Cannot set '", unnormalized_name, "'"));
+          StrCat(
+              "oneof field '", element_->type().oneofs(field.oneof_index() - 1),
+              "' is already set. Cannot set '", unnormalized_name, "'"));
       return false;
     }
     element_->TakeOneofIndex(field.oneof_index());
@@ -574,6 +565,20 @@
   return this;
 }
 
+Status ProtoWriter::WriteEnum(int field_number, const DataPiece& data,
+                              const google::protobuf::Enum* enum_type,
+                              CodedOutputStream* stream,
+                              bool use_lower_camel_for_enums,
+                              bool ignore_unknown_values) {
+  bool is_unknown_enum_value = false;
+  StatusOr<int> e = data.ToEnum(enum_type, use_lower_camel_for_enums,
+                                ignore_unknown_values, &is_unknown_enum_value);
+  if (e.ok() && !is_unknown_enum_value) {
+    WireFormatLite::WriteEnum(field_number, e.ValueOrDie(), stream);
+  }
+  return e.status();
+}
+
 ProtoWriter* ProtoWriter::RenderPrimitiveField(
     const google::protobuf::Field& field, const google::protobuf::Type& type,
     const DataPiece& data) {
@@ -664,10 +669,9 @@
       break;
     }
     case google::protobuf::Field_Kind_TYPE_ENUM: {
-      status = WriteEnum(field.number(), data,
-                         typeinfo_->GetEnumByTypeUrl(field.type_url()),
-                         stream_.get(), use_lower_camel_for_enums_,
-                         ignore_unknown_fields_);
+      status = WriteEnum(
+          field.number(), data, typeinfo_->GetEnumByTypeUrl(field.type_url()),
+          stream_.get(), use_lower_camel_for_enums_, ignore_unknown_fields_);
       break;
     }
     default:  // TYPE_GROUP or TYPE_MESSAGE
@@ -751,7 +755,7 @@
   stream_.reset(nullptr);
   const void* data;
   int length;
-  google::protobuf::io::ArrayInputStream input_stream(buffer_.data(), buffer_.size());
+  io::ArrayInputStream input_stream(buffer_.data(), buffer_.size());
   while (input_stream.Next(&data, &length)) {
     if (length == 0) continue;
     int num_bytes = length;
diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h
index 5bdafcc..1176109 100644
--- a/src/google/protobuf/util/internal/proto_writer.h
+++ b/src/google/protobuf/util/internal/proto_writer.h
@@ -46,6 +46,7 @@
 #include <google/protobuf/util/type_resolver.h>
 #include <google/protobuf/stubs/bytestream.h>
 #include <google/protobuf/stubs/hash.h>
+#include <google/protobuf/stubs/status.h>
 
 namespace google {
 namespace protobuf {
@@ -53,14 +54,16 @@
 class CodedOutputStream;
 }  // namespace io
 }  // namespace protobuf
+}  // namespace google
 
-
+namespace google {
 namespace protobuf {
 class Type;
 class Field;
 }  // namespace protobuf
+}  // namespace google
 
-
+namespace google {
 namespace protobuf {
 namespace util {
 namespace converter {
@@ -78,7 +81,7 @@
 // Constructor. Does not take ownership of any parameter passed in.
   ProtoWriter(TypeResolver* type_resolver, const google::protobuf::Type& type,
               strings::ByteSink* output, ErrorListener* listener);
-  virtual ~ProtoWriter() override;
+  ~ProtoWriter() override;
 
   // ObjectWriter methods.
   ProtoWriter* StartObject(StringPiece name) override;
@@ -106,7 +109,8 @@
   ProtoWriter* RenderFloat(StringPiece name, float value) override {
     return RenderDataPiece(name, DataPiece(value));
   }
-  ProtoWriter* RenderString(StringPiece name, StringPiece value) override {
+  ProtoWriter* RenderString(StringPiece name,
+                            StringPiece value) override {
     return RenderDataPiece(name,
                            DataPiece(value, use_strict_base64_decoding()));
   }
@@ -133,7 +137,7 @@
   bool done() override { return done_; }
 
   // Returns the proto stream object.
-  google::protobuf::io::CodedOutputStream* stream() { return stream_.get(); }
+  io::CodedOutputStream* stream() { return stream_.get(); }
 
   // Getters and mutators of invalid_depth_.
   void IncrementInvalidDepth() { ++invalid_depth_; }
@@ -163,7 +167,7 @@
     ProtoElement(ProtoElement* parent, const google::protobuf::Field* field,
                  const google::protobuf::Type& type, bool is_list);
 
-    virtual ~ProtoElement() override {}
+    ~ProtoElement() override {}
 
     // Called just before the destructor for clean up:
     //   - reports any missing required fields
@@ -183,9 +187,9 @@
     void RegisterField(const google::protobuf::Field* field);
 
     // To report location on error messages.
-    virtual string ToString() const override;
+    string ToString() const override;
 
-    virtual ProtoElement* parent() const override {
+    ProtoElement* parent() const override {
       return static_cast<ProtoElement*>(BaseElement::parent());
     }
 
@@ -251,7 +255,8 @@
 
   // Common code for BeginObject() and BeginList() that does invalid_depth_
   // bookkeeping associated with name lookup.
-  const google::protobuf::Field* BeginNamed(StringPiece name, bool is_list);
+  const google::protobuf::Field* BeginNamed(StringPiece name,
+                                            bool is_list);
 
   // Lookup the field in the current element. Looks in the base descriptor
   // and in any extension. This will report an error if the field cannot be
@@ -298,6 +303,13 @@
                                     const DataPiece& value);
 
  private:
+  // Writes an ENUM field, including tag, to the stream.
+  static util::Status WriteEnum(int field_number, const DataPiece& data,
+                                  const google::protobuf::Enum* enum_type,
+                                  io::CodedOutputStream* stream,
+                                  bool use_lower_camel_for_enums,
+                                  bool ignore_unknown_values);
+
   // Variables for describing the structure of the input tree:
   // master_type_: descriptor for the whole protobuf message.
   // typeinfo_ : the TypeInfo object to lookup types.
@@ -331,8 +343,8 @@
   // stream_  : wrapper for writing tags and other encodings in wire format.
   strings::ByteSink* output_;
   string buffer_;
-  google::protobuf::io::StringOutputStream adapter_;
-  std::unique_ptr<google::protobuf::io::CodedOutputStream> stream_;
+  io::StringOutputStream adapter_;
+  std::unique_ptr<io::CodedOutputStream> stream_;
 
   // Variables for error tracking and reporting:
   // listener_     : a place to report any errors found.
@@ -348,6 +360,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc
index b0d86c1..2a1b251 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource.cc
@@ -30,9 +30,9 @@
 
 #include <google/protobuf/util/internal/protostream_objectsource.h>
 
+#include <unordered_map>
 #include <utility>
 
-#include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/stringprintf.h>
@@ -40,16 +40,22 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/descriptor.h>
+#include <google/protobuf/stubs/once.h>
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/wire_format_lite.h>
 #include <google/protobuf/util/internal/field_mask_utility.h>
 #include <google/protobuf/util/internal/constants.h>
 #include <google/protobuf/util/internal/utility.h>
 #include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/casts.h>
+
+
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/status_macros.h>
 
 
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 namespace util {
@@ -60,12 +66,8 @@
 using util::error::INTERNAL;
 }
 namespace converter {
-
-using google::protobuf::Descriptor;
-using google::protobuf::EnumValueDescriptor;
-using google::protobuf::FieldDescriptor;
-using google::protobuf::internal::WireFormat;
-using google::protobuf::internal::WireFormatLite;
+using ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::WireFormat;
+using ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
 using util::Status;
 using util::StatusOr;
 
@@ -113,7 +115,7 @@
 
 
 ProtoStreamObjectSource::ProtoStreamObjectSource(
-    google::protobuf::io::CodedInputStream* stream, TypeResolver* type_resolver,
+    io::CodedInputStream* stream, TypeResolver* type_resolver,
     const google::protobuf::Type& type)
     : stream_(stream),
       typeinfo_(TypeInfo::NewTypeInfo(type_resolver)),
@@ -131,7 +133,7 @@
 }
 
 ProtoStreamObjectSource::ProtoStreamObjectSource(
-    google::protobuf::io::CodedInputStream* stream, const TypeInfo* typeinfo,
+    io::CodedInputStream* stream, const TypeInfo* typeinfo,
     const google::protobuf::Type& type)
     : stream_(stream),
       typeinfo_(typeinfo),
@@ -194,7 +196,7 @@
   string field_name;
   // last_tag set to dummy value that is different from tag.
   uint32 tag = stream_->ReadTag(), last_tag = tag + 1;
-  google::protobuf::UnknownFieldSet unknown_fields;
+  UnknownFieldSet unknown_fields;
 
   if (include_start_and_end) {
     ow->StartObject(name);
@@ -246,8 +248,8 @@
 }
 
 StatusOr<uint32> ProtoStreamObjectSource::RenderList(
-    const google::protobuf::Field* field, StringPiece name, uint32 list_tag,
-    ObjectWriter* ow) const {
+    const google::protobuf::Field* field, StringPiece name,
+    uint32 list_tag, ObjectWriter* ow) const {
   uint32 tag_to_return = 0;
   ow->StartList(name);
   if (IsPackable(*field) &&
@@ -268,8 +270,8 @@
 }
 
 StatusOr<uint32> ProtoStreamObjectSource::RenderMap(
-    const google::protobuf::Field* field, StringPiece name, uint32 list_tag,
-    ObjectWriter* ow) const {
+    const google::protobuf::Field* field, StringPiece name,
+    uint32 list_tag, ObjectWriter* ow) const {
   const google::protobuf::Type* field_type =
       typeinfo_->GetTypeByTypeUrl(field->type_url());
   uint32 tag_to_return = 0;
@@ -332,9 +334,9 @@
   int64 seconds = p.first;
   int32 nanos = p.second;
   if (seconds > kTimestampMaxSeconds || seconds < kTimestampMinSeconds) {
-    return Status(
-        util::error::INTERNAL,
-        StrCat("Timestamp seconds exceeds limit for field: ", field_name));
+    return Status(util::error::INTERNAL,
+                  StrCat("Timestamp seconds exceeds limit for field: ",
+                               field_name));
   }
 
   if (nanos < 0 || nanos >= kNanosPerSecond) {
@@ -370,10 +372,11 @@
   string sign = "";
   if (seconds < 0) {
     if (nanos > 0) {
-      return Status(util::error::INTERNAL,
-                    StrCat("Duration nanos is non-negative, but seconds is "
-                           "negative for field: ",
-                           field_name));
+      return Status(
+          util::error::INTERNAL,
+          StrCat("Duration nanos is non-negative, but seconds is "
+                       "negative for field: ",
+                       field_name));
     }
     sign = "-";
     seconds = -seconds;
@@ -383,7 +386,7 @@
     nanos = -nanos;
   }
   string formatted_duration = StringPrintf(
-      "%s%lld%ss", sign.c_str(), seconds,
+      "%s%lld%ss", sign.c_str(), static_cast<long long>(seconds),  // NOLINT
       FormatNanos(nanos, os->add_trailing_zeros_for_timestamp_and_duration_)
           .c_str());
   ow->RenderString(field_name, formatted_duration);
@@ -400,7 +403,7 @@
     os->stream_->ReadLittleEndian64(&buffer64);
     os->stream_->ReadTag();
   }
-  ow->RenderDouble(field_name, bit_cast<double>(buffer64));
+  ow->RenderDouble(field_name, ::google::protobuf::bit_cast<double>(buffer64));
   return util::Status();
 }
 
@@ -414,7 +417,7 @@
     os->stream_->ReadLittleEndian32(&buffer32);
     os->stream_->ReadTag();
   }
-  ow->RenderFloat(field_name, bit_cast<float>(buffer32));
+  ow->RenderFloat(field_name, ::google::protobuf::bit_cast<float>(buffer32));
   return util::Status();
 }
 
@@ -428,7 +431,7 @@
     os->stream_->ReadVarint64(&buffer64);
     os->stream_->ReadTag();
   }
-  ow->RenderInt64(field_name, bit_cast<int64>(buffer64));
+  ow->RenderInt64(field_name, ::google::protobuf::bit_cast<int64>(buffer64));
   return util::Status();
 }
 
@@ -442,7 +445,7 @@
     os->stream_->ReadVarint64(&buffer64);
     os->stream_->ReadTag();
   }
-  ow->RenderUint64(field_name, bit_cast<uint64>(buffer64));
+  ow->RenderUint64(field_name, ::google::protobuf::bit_cast<uint64>(buffer64));
   return util::Status();
 }
 
@@ -456,7 +459,7 @@
     os->stream_->ReadVarint32(&buffer32);
     os->stream_->ReadTag();
   }
-  ow->RenderInt32(field_name, bit_cast<int32>(buffer32));
+  ow->RenderInt32(field_name, ::google::protobuf::bit_cast<int32>(buffer32));
   return util::Status();
 }
 
@@ -470,7 +473,7 @@
     os->stream_->ReadVarint32(&buffer32);
     os->stream_->ReadTag();
   }
-  ow->RenderUint32(field_name, bit_cast<uint32>(buffer32));
+  ow->RenderUint32(field_name, ::google::protobuf::bit_cast<uint32>(buffer32));
   return util::Status();
 }
 
@@ -642,8 +645,8 @@
   // nested_type cannot be null at this time.
   const google::protobuf::Type* nested_type = resolved_type.ValueOrDie();
 
-  google::protobuf::io::ArrayInputStream zero_copy_stream(value.data(), value.size());
-  google::protobuf::io::CodedInputStream in_stream(&zero_copy_stream);
+  io::ArrayInputStream zero_copy_stream(value.data(), value.size());
+  io::CodedInputStream in_stream(&zero_copy_stream);
   // We know the type so we can render it. Recursively parse the nested stream
   // using a nested ProtoStreamObjectSource using our nested type information.
   ProtoStreamObjectSource nested_os(&in_stream, os->typeinfo_, *nested_type);
@@ -696,12 +699,13 @@
 }
 
 
-hash_map<string, ProtoStreamObjectSource::TypeRenderer>*
+std::unordered_map<string, ProtoStreamObjectSource::TypeRenderer>*
     ProtoStreamObjectSource::renderers_ = NULL;
-GOOGLE_PROTOBUF_DECLARE_ONCE(source_renderers_init_);
+GOOGLE_PROTOBUF_NAMESPACE_ID::internal::once_flag source_renderers_init_;
 
 void ProtoStreamObjectSource::InitRendererMap() {
-  renderers_ = new hash_map<string, ProtoStreamObjectSource::TypeRenderer>();
+  renderers_ =
+      new std::unordered_map<string, ProtoStreamObjectSource::TypeRenderer>();
   (*renderers_)["google.protobuf.Timestamp"] =
       &ProtoStreamObjectSource::RenderTimestamp;
   (*renderers_)["google.protobuf.Duration"] =
@@ -744,7 +748,8 @@
 // static
 ProtoStreamObjectSource::TypeRenderer*
 ProtoStreamObjectSource::FindTypeRenderer(const string& type_url) {
-  ::google::protobuf::GoogleOnceInit(&source_renderers_init_, &InitRendererMap);
+  GOOGLE_PROTOBUF_NAMESPACE_ID::internal::call_once(source_renderers_init_,
+                                                     InitRendererMap);
   return FindOrNull(*renderers_, type_url);
 }
 
@@ -762,9 +767,10 @@
     const google::protobuf::Type* type =
         typeinfo_->GetTypeByTypeUrl(field->type_url());
     if (type == nullptr) {
-      return Status(util::error::INTERNAL,
-                    StrCat("Invalid configuration. Could not find the type: ",
-                           field->type_url()));
+      return Status(
+          util::error::INTERNAL,
+          StrCat("Invalid configuration. Could not find the type: ",
+                       field->type_url()));
     }
 
     // Short-circuit any special type rendering to save call-stack space.
@@ -806,22 +812,22 @@
     }
     case google::protobuf::Field_Kind_TYPE_INT32: {
       stream_->ReadVarint32(&buffer32);
-      ow->RenderInt32(field_name, bit_cast<int32>(buffer32));
+      ow->RenderInt32(field_name, ::google::protobuf::bit_cast<int32>(buffer32));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_INT64: {
       stream_->ReadVarint64(&buffer64);
-      ow->RenderInt64(field_name, bit_cast<int64>(buffer64));
+      ow->RenderInt64(field_name, ::google::protobuf::bit_cast<int64>(buffer64));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_UINT32: {
       stream_->ReadVarint32(&buffer32);
-      ow->RenderUint32(field_name, bit_cast<uint32>(buffer32));
+      ow->RenderUint32(field_name, ::google::protobuf::bit_cast<uint32>(buffer32));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_UINT64: {
       stream_->ReadVarint64(&buffer64);
-      ow->RenderUint64(field_name, bit_cast<uint64>(buffer64));
+      ow->RenderUint64(field_name, ::google::protobuf::bit_cast<uint64>(buffer64));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_SINT32: {
@@ -836,32 +842,32 @@
     }
     case google::protobuf::Field_Kind_TYPE_SFIXED32: {
       stream_->ReadLittleEndian32(&buffer32);
-      ow->RenderInt32(field_name, bit_cast<int32>(buffer32));
+      ow->RenderInt32(field_name, ::google::protobuf::bit_cast<int32>(buffer32));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_SFIXED64: {
       stream_->ReadLittleEndian64(&buffer64);
-      ow->RenderInt64(field_name, bit_cast<int64>(buffer64));
+      ow->RenderInt64(field_name, ::google::protobuf::bit_cast<int64>(buffer64));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_FIXED32: {
       stream_->ReadLittleEndian32(&buffer32);
-      ow->RenderUint32(field_name, bit_cast<uint32>(buffer32));
+      ow->RenderUint32(field_name, ::google::protobuf::bit_cast<uint32>(buffer32));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_FIXED64: {
       stream_->ReadLittleEndian64(&buffer64);
-      ow->RenderUint64(field_name, bit_cast<uint64>(buffer64));
+      ow->RenderUint64(field_name, ::google::protobuf::bit_cast<uint64>(buffer64));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_FLOAT: {
       stream_->ReadLittleEndian32(&buffer32);
-      ow->RenderFloat(field_name, bit_cast<float>(buffer32));
+      ow->RenderFloat(field_name, ::google::protobuf::bit_cast<float>(buffer32));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_DOUBLE: {
       stream_->ReadLittleEndian64(&buffer64);
-      ow->RenderDouble(field_name, bit_cast<double>(buffer64));
+      ow->RenderDouble(field_name, ::google::protobuf::bit_cast<double>(buffer64));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_ENUM: {
@@ -932,25 +938,25 @@
     case google::protobuf::Field_Kind_TYPE_INT32: {
       uint32 buffer32;
       stream_->ReadVarint32(&buffer32);
-      result = SimpleItoa(bit_cast<int32>(buffer32));
+      result = SimpleItoa(::google::protobuf::bit_cast<int32>(buffer32));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_INT64: {
       uint64 buffer64;
       stream_->ReadVarint64(&buffer64);
-      result = SimpleItoa(bit_cast<int64>(buffer64));
+      result = SimpleItoa(::google::protobuf::bit_cast<int64>(buffer64));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_UINT32: {
       uint32 buffer32;
       stream_->ReadVarint32(&buffer32);
-      result = SimpleItoa(bit_cast<uint32>(buffer32));
+      result = SimpleItoa(::google::protobuf::bit_cast<uint32>(buffer32));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_UINT64: {
       uint64 buffer64;
       stream_->ReadVarint64(&buffer64);
-      result = SimpleItoa(bit_cast<uint64>(buffer64));
+      result = SimpleItoa(::google::protobuf::bit_cast<uint64>(buffer64));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_SINT32: {
@@ -968,37 +974,37 @@
     case google::protobuf::Field_Kind_TYPE_SFIXED32: {
       uint32 buffer32;
       stream_->ReadLittleEndian32(&buffer32);
-      result = SimpleItoa(bit_cast<int32>(buffer32));
+      result = SimpleItoa(::google::protobuf::bit_cast<int32>(buffer32));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_SFIXED64: {
       uint64 buffer64;
       stream_->ReadLittleEndian64(&buffer64);
-      result = SimpleItoa(bit_cast<int64>(buffer64));
+      result = SimpleItoa(::google::protobuf::bit_cast<int64>(buffer64));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_FIXED32: {
       uint32 buffer32;
       stream_->ReadLittleEndian32(&buffer32);
-      result = SimpleItoa(bit_cast<uint32>(buffer32));
+      result = SimpleItoa(::google::protobuf::bit_cast<uint32>(buffer32));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_FIXED64: {
       uint64 buffer64;
       stream_->ReadLittleEndian64(&buffer64);
-      result = SimpleItoa(bit_cast<uint64>(buffer64));
+      result = SimpleItoa(::google::protobuf::bit_cast<uint64>(buffer64));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_FLOAT: {
       uint32 buffer32;
       stream_->ReadLittleEndian32(&buffer32);
-      result = SimpleFtoa(bit_cast<float>(buffer32));
+      result = SimpleFtoa(::google::protobuf::bit_cast<float>(buffer32));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_DOUBLE: {
       uint64 buffer64;
       stream_->ReadLittleEndian64(&buffer64);
-      result = SimpleDtoa(bit_cast<double>(buffer64));
+      result = SimpleDtoa(::google::protobuf::bit_cast<double>(buffer64));
       break;
     }
     case google::protobuf::Field_Kind_TYPE_ENUM: {
@@ -1044,7 +1050,7 @@
   const google::protobuf::Type* field_type =
       typeinfo_->GetTypeByTypeUrl(field.type_url());
   return field.kind() == google::protobuf::Field_Kind_TYPE_MESSAGE &&
-         google::protobuf::util::converter::IsMap(field, *field_type);
+         util::converter::IsMap(field, *field_type);
 }
 
 std::pair<int64, int32> ProtoStreamObjectSource::ReadSecondsAndNanos(
@@ -1066,11 +1072,11 @@
     if (field->number() == 1) {
       // read seconds
       stream_->ReadVarint64(&seconds);
-      signed_seconds = bit_cast<int64>(seconds);
+      signed_seconds = ::google::protobuf::bit_cast<int64>(seconds);
     } else if (field->number() == 2) {
       // read nanos
       stream_->ReadVarint32(&nanos);
-      signed_nanos = bit_cast<int32>(nanos);
+      signed_nanos = ::google::protobuf::bit_cast<int32>(nanos);
     }
   }
   return std::pair<int64, int32>(signed_seconds, signed_nanos);
@@ -1082,7 +1088,7 @@
     return Status(
         util::error::INVALID_ARGUMENT,
         StrCat("Message too deep. Max recursion depth reached for type '",
-               type_name, "', field '", field_name, "'"));
+                     type_name, "', field '", field_name, "'"));
   }
   return util::Status();
 }
@@ -1104,8 +1110,8 @@
 bool IsPackable(const google::protobuf::Field& field) {
   return field.cardinality() ==
              google::protobuf::Field_Cardinality_CARDINALITY_REPEATED &&
-         google::protobuf::FieldDescriptor::IsTypePackable(
-             static_cast<google::protobuf::FieldDescriptor::Type>(field.kind()));
+         FieldDescriptor::IsTypePackable(
+             static_cast<FieldDescriptor::Type>(field.kind()));
 }
 
 // TODO(skarvaje): Speed this up by not doing a linear scan.
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h
index acd081d..90e23a3 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.h
+++ b/src/google/protobuf/util/internal/protostream_objectsource.h
@@ -32,8 +32,8 @@
 #define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTSOURCE_H__
 
 #include <functional>
-#include <google/protobuf/stubs/hash.h>
 #include <string>
+#include <unordered_map>
 
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/type.pb.h>
@@ -42,17 +42,18 @@
 #include <google/protobuf/util/internal/type_info.h>
 #include <google/protobuf/util/type_resolver.h>
 #include <google/protobuf/stubs/stringpiece.h>
+#include <google/protobuf/stubs/hash.h>
 #include <google/protobuf/stubs/status.h>
 #include <google/protobuf/stubs/statusor.h>
 
-
 namespace google {
 namespace protobuf {
 class Field;
 class Type;
 }  // namespace protobuf
+}  // namespace google
 
-
+namespace google {
 namespace protobuf {
 namespace util {
 namespace converter {
@@ -74,13 +75,14 @@
 //   Status status = os.WriteTo(<some ObjectWriter>);
 class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
  public:
-  ProtoStreamObjectSource(google::protobuf::io::CodedInputStream* stream,
+  ProtoStreamObjectSource(io::CodedInputStream* stream,
                           TypeResolver* type_resolver,
                           const google::protobuf::Type& type);
 
-  virtual ~ProtoStreamObjectSource() override;
+  ~ProtoStreamObjectSource() override;
 
-  virtual util::Status NamedWriteTo(StringPiece name, ObjectWriter* ow) const override;
+  util::Status NamedWriteTo(StringPiece name,
+                              ObjectWriter* ow) const override;
 
   // Sets whether or not to use lowerCamelCase casing for enum values. If set to
   // false, enum values are output without any case conversions.
@@ -134,7 +136,8 @@
   // The include_start_and_end parameter allows this method to be called when
   // already inside of an object, and skip calling StartObject and EndObject.
   virtual util::Status WriteMessage(const google::protobuf::Type& descriptor,
-                                      StringPiece name, const uint32 end_tag,
+                                      StringPiece name,
+                                      const uint32 end_tag,
                                       bool include_start_and_end,
                                       ObjectWriter* ow) const;
 
@@ -142,8 +145,8 @@
   // reading all sequential repeating elements. The caller should use this tag
   // before reading more tags from the stream.
   virtual util::StatusOr<uint32> RenderList(
-      const google::protobuf::Field* field, StringPiece name, uint32 list_tag,
-      ObjectWriter* ow) const;
+      const google::protobuf::Field* field, StringPiece name,
+      uint32 list_tag, ObjectWriter* ow) const;
 
   // Looks up a field and verify its consistency with wire type in tag.
   const google::protobuf::Field* FindAndVerifyField(
@@ -151,7 +154,8 @@
 
   // Renders a field value to the ObjectWriter.
   util::Status RenderField(const google::protobuf::Field* field,
-                             StringPiece field_name, ObjectWriter* ow) const;
+                             StringPiece field_name,
+                             ObjectWriter* ow) const;
 
   // Reads field value according to Field spec in 'field' and returns the read
   // value as string. This only works for primitive datatypes (no message
@@ -161,7 +165,7 @@
 
 
  private:
-  ProtoStreamObjectSource(google::protobuf::io::CodedInputStream* stream,
+  ProtoStreamObjectSource(io::CodedInputStream* stream,
                           const TypeInfo* typeinfo,
                           const google::protobuf::Type& type);
   // Function that renders a well known type with a modified behavior.
@@ -188,12 +192,14 @@
   // Renders a google.protobuf.Timestamp value to ObjectWriter
   static util::Status RenderTimestamp(const ProtoStreamObjectSource* os,
                                         const google::protobuf::Type& type,
-                                        StringPiece name, ObjectWriter* ow);
+                                        StringPiece name,
+                                        ObjectWriter* ow);
 
   // Renders a google.protobuf.Duration value to ObjectWriter
   static util::Status RenderDuration(const ProtoStreamObjectSource* os,
                                        const google::protobuf::Type& type,
-                                       StringPiece name, ObjectWriter* ow);
+                                       StringPiece name,
+                                       ObjectWriter* ow);
 
   // Following RenderTYPE functions render well known types in
   // google/protobuf/wrappers.proto corresponding to TYPE.
@@ -233,7 +239,8 @@
   // Helper to render google.protobuf.Struct's Value fields to ObjectWriter.
   static util::Status RenderStructValue(const ProtoStreamObjectSource* os,
                                           const google::protobuf::Type& type,
-                                          StringPiece name, ObjectWriter* ow);
+                                          StringPiece name,
+                                          ObjectWriter* ow);
 
   // Helper to render google.protobuf.Struct's ListValue fields to ObjectWriter.
   static util::Status RenderStructListValue(
@@ -248,9 +255,10 @@
   // Render the "FieldMask" type.
   static util::Status RenderFieldMask(const ProtoStreamObjectSource* os,
                                         const google::protobuf::Type& type,
-                                        StringPiece name, ObjectWriter* ow);
+                                        StringPiece name,
+                                        ObjectWriter* ow);
 
-  static hash_map<string, TypeRenderer>* renderers_;
+  static std::unordered_map<string, TypeRenderer>* renderers_;
   static void InitRendererMap();
   static void DeleteRendererMap();
   static TypeRenderer* FindTypeRenderer(const string& type_url);
@@ -277,7 +285,7 @@
                                          StringPiece field_name) const;
 
   // Input stream to read from. Ownership rests with the caller.
-  google::protobuf::io::CodedInputStream* stream_;
+  io::CodedInputStream* stream_;
 
   // Type information for all the types used in the descriptor. Used to find
   // google::protobuf::Type of nested messages/enums.
@@ -321,6 +329,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTSOURCE_H__
diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
index 4d86b85..5e2f86f 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
@@ -33,7 +33,6 @@
 #include <memory>
 #include <sstream>
 
-#include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/any.pb.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
@@ -50,6 +49,7 @@
 #include <google/protobuf/util/internal/constants.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <gtest/gtest.h>
+#include <google/protobuf/stubs/casts.h>
 
 
 namespace google {
@@ -57,13 +57,6 @@
 namespace util {
 namespace converter {
 
-using google::protobuf::Descriptor;
-using google::protobuf::DescriptorPool;
-using google::protobuf::FileDescriptorProto;
-using google::protobuf::Message;
-using google::protobuf::io::ArrayInputStream;
-using google::protobuf::io::CodedInputStream;
-using util::Status;
 using google::protobuf::testing::AnyM;
 using google::protobuf::testing::AnyOut;
 using google::protobuf::testing::Author;
@@ -82,7 +75,10 @@
 using google::protobuf::testing::Proto3Message;
 using google::protobuf::testing::StructType;
 using google::protobuf::testing::TimestampDuration;
+using io::ArrayInputStream;
+using io::CodedInputStream;
 using ::testing::_;
+using util::Status;
 
 
 namespace {
@@ -124,7 +120,8 @@
         helper_.NewProtoSource(&in_stream, GetTypeUrl(descriptor)));
     if (use_lower_camel_for_enums_) os->set_use_lower_camel_for_enums(true);
     if (use_ints_for_enums_) os->set_use_ints_for_enums(true);
-    if (use_preserve_proto_field_names_) os->set_preserve_proto_field_names(true);
+    if (use_preserve_proto_field_names_)
+      os->set_preserve_proto_field_names(true);
     os->set_max_recursion_depth(64);
     return os->WriteTo(&mock_);
   }
@@ -132,13 +129,13 @@
   void PrepareExpectingObjectWriterForRepeatedPrimitive() {
     ow_.StartObject("")
         ->StartList("repFix32")
-        ->RenderUint32("", bit_cast<uint32>(3201))
-        ->RenderUint32("", bit_cast<uint32>(0))
-        ->RenderUint32("", bit_cast<uint32>(3202))
+        ->RenderUint32("", ::google::protobuf::bit_cast<uint32>(3201))
+        ->RenderUint32("", ::google::protobuf::bit_cast<uint32>(0))
+        ->RenderUint32("", ::google::protobuf::bit_cast<uint32>(3202))
         ->EndList()
         ->StartList("repU32")
-        ->RenderUint32("", bit_cast<uint32>(3203))
-        ->RenderUint32("", bit_cast<uint32>(0))
+        ->RenderUint32("", ::google::protobuf::bit_cast<uint32>(3203))
+        ->RenderUint32("", ::google::protobuf::bit_cast<uint32>(0))
         ->EndList()
         ->StartList("repI32")
         ->RenderInt32("", 0)
@@ -155,13 +152,13 @@
         ->RenderInt32("", 3208)
         ->EndList()
         ->StartList("repFix64")
-        ->RenderUint64("", bit_cast<uint64>(6401LL))
-        ->RenderUint64("", bit_cast<uint64>(0LL))
+        ->RenderUint64("", ::google::protobuf::bit_cast<uint64>(6401LL))
+        ->RenderUint64("", ::google::protobuf::bit_cast<uint64>(0LL))
         ->EndList()
         ->StartList("repU64")
-        ->RenderUint64("", bit_cast<uint64>(0LL))
-        ->RenderUint64("", bit_cast<uint64>(6402LL))
-        ->RenderUint64("", bit_cast<uint64>(6403LL))
+        ->RenderUint64("", ::google::protobuf::bit_cast<uint64>(0LL))
+        ->RenderUint64("", ::google::protobuf::bit_cast<uint64>(6402LL))
+        ->RenderUint64("", ::google::protobuf::bit_cast<uint64>(6403LL))
         ->EndList()
         ->StartList("repI64")
         ->RenderInt64("", 6404L)
@@ -323,13 +320,13 @@
   primitive.set_bool_(true);
 
   ow_.StartObject("")
-      ->RenderUint32("fix32", bit_cast<uint32>(3201))
-      ->RenderUint32("u32", bit_cast<uint32>(3202))
+      ->RenderUint32("fix32", ::google::protobuf::bit_cast<uint32>(3201))
+      ->RenderUint32("u32", ::google::protobuf::bit_cast<uint32>(3202))
       ->RenderInt32("i32", 3203)
       ->RenderInt32("sf32", 3204)
       ->RenderInt32("s32", 3205)
-      ->RenderUint64("fix64", bit_cast<uint64>(6401LL))
-      ->RenderUint64("u64", bit_cast<uint64>(6402LL))
+      ->RenderUint64("fix64", ::google::protobuf::bit_cast<uint64>(6401LL))
+      ->RenderUint64("u64", ::google::protobuf::bit_cast<uint64>(6402LL))
       ->RenderInt64("i64", 6403L)
       ->RenderInt64("sf64", 6404L)
       ->RenderInt64("s64", 6405L)
@@ -746,8 +743,8 @@
 class ProtostreamObjectSourceAnysTest : public ProtostreamObjectSourceTest {
  protected:
   ProtostreamObjectSourceAnysTest() {
-    helper_.ResetTypeInfo(AnyOut::descriptor(),
-                          google::protobuf::Any::descriptor());
+    helper_.ResetTypeInfo({AnyOut::descriptor(), Book::descriptor(),
+                           google::protobuf::Any::descriptor()});
   }
 };
 
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc
index a1a7030..f01a11a 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -32,28 +32,33 @@
 
 #include <functional>
 #include <stack>
+#include <unordered_map>
+#include <unordered_set>
 
-#include <google/protobuf/stubs/once.h>
 #include <google/protobuf/stubs/time.h>
+#include <google/protobuf/stubs/once.h>
 #include <google/protobuf/wire_format_lite.h>
 #include <google/protobuf/util/internal/field_mask_utility.h>
 #include <google/protobuf/util/internal/object_location_tracker.h>
 #include <google/protobuf/util/internal/constants.h>
 #include <google/protobuf/util/internal/utility.h>
 #include <google/protobuf/stubs/strutil.h>
+
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/statusor.h>
 
 
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 namespace util {
 namespace converter {
 
-using google::protobuf::internal::WireFormatLite;
-using util::error::INVALID_ARGUMENT;
+using ::GOOGLE_PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
 using util::Status;
 using util::StatusOr;
+using util::error::INVALID_ARGUMENT;
 
 
 ProtoStreamObjectWriter::ProtoStreamObjectWriter(
@@ -120,7 +125,7 @@
   // "0." + s_nanos.ToString() seconds. An int32 is used for the
   // conversion to 'nanos', rather than a double, so that there is no
   // loss of precision.
-  if (!s_nanos.empty() && !safe_strto32(s_nanos.ToString(), &i_nanos)) {
+  if (!s_nanos.empty() && !safe_strto32(s_nanos, &i_nanos)) {
     return Status(INVALID_ARGUMENT, parse_failure_message);
   }
   if (i_nanos > kNanosPerSecond || i_nanos < 0) {
@@ -305,7 +310,7 @@
   // Figure out the type url. This is a copy-paste from WriteString but we also
   // need the value, so we can't just call through to that.
   if (value.type() == DataPiece::TYPE_STRING) {
-    type_url_ = value.str().ToString();
+    type_url_ = string(value.str());
   } else {
     StatusOr<string> s = value.ToString();
     if (!s.ok()) {
@@ -368,8 +373,9 @@
     } else {
       // There are uninterpreted data, but we never got a "@type" field.
       if (!invalid_) {
-        parent_->InvalidValue("Any", StrCat("Missing @type for any field in ",
-                                            parent_->master_type_.name()));
+        parent_->InvalidValue("Any",
+                              StrCat("Missing @type for any field in ",
+                                           parent_->master_type_.name()));
         invalid_ = true;
       }
       return;
@@ -431,7 +437,7 @@
     any_.reset(new AnyWriter(ow_));
   }
   if (item_type == MAP) {
-    map_keys_.reset(new hash_set<string>);
+    map_keys_.reset(new std::unordered_set<string>);
   }
 }
 
@@ -448,13 +454,13 @@
     any_.reset(new AnyWriter(ow_));
   }
   if (item_type == MAP) {
-    map_keys_.reset(new hash_set<string>);
+    map_keys_.reset(new std::unordered_set<string>);
   }
 }
 
 bool ProtoStreamObjectWriter::Item::InsertMapKeyIfNotPresent(
     StringPiece map_key) {
-  return InsertIfNotPresent(map_keys_.get(), map_key.ToString());
+  return InsertIfNotPresent(map_keys_.get(), string(map_key));
 }
 
 ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject(
@@ -534,7 +540,8 @@
     Push("", Item::MESSAGE, false, false);
     ProtoWriter::RenderDataPiece("key",
                                  DataPiece(name, use_strict_base64_decoding()));
-    Push("value", IsAny(*Lookup("value")) ? Item::ANY : Item::MESSAGE, true, false);
+    Push("value", IsAny(*Lookup("value")) ? Item::ANY : Item::MESSAGE, true,
+         false);
 
     // Make sure we are valid so far after starting map fields.
     if (invalid_depth() > 0) return this;
@@ -618,7 +625,8 @@
   return this;
 }
 
-ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartList(StringPiece name) {
+ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartList(
+    StringPiece name) {
   if (invalid_depth() > 0) {
     IncrementInvalidDepth();
     return this;
@@ -727,7 +735,7 @@
 
     // Report an error.
     InvalidValue("Map", StrCat("Cannot have repeated items ('", name,
-                               "') within a map."));
+                                     "') within a map."));
     return this;
   }
 
@@ -818,8 +826,8 @@
   }
 
   if (IsMap(*field)) {
-    InvalidValue("Map",
-                 StrCat("Cannot bind a list to map for field '", name, "'."));
+    InvalidValue("Map", StrCat("Cannot bind a list to map for field '",
+                                     name, "'."));
     IncrementInvalidDepth();
     return this;
   }
@@ -924,7 +932,7 @@
   if (data.type() != DataPiece::TYPE_STRING) {
     return Status(INVALID_ARGUMENT,
                   StrCat("Invalid data type for timestamp, value is ",
-                         data.ValueAsStringOrDefault("")));
+                               data.ValueAsStringOrDefault("")));
   }
 
   StringPiece value(data.str());
@@ -955,13 +963,13 @@
   if (data.type() != DataPiece::TYPE_STRING) {
     return Status(INVALID_ARGUMENT,
                   StrCat("Invalid data type for field mask, value is ",
-                         data.ValueAsStringOrDefault("")));
+                               data.ValueAsStringOrDefault("")));
   }
 
 // TODO(tsun): figure out how to do proto descriptor based snake case
 // conversions as much as possible. Because ToSnakeCase sometimes returns the
 // wrong value.
-  std::unique_ptr<ResultCallback1<util::Status, StringPiece> > callback(
+  std::unique_ptr<ResultCallback1<util::Status, StringPiece>> callback(
       ::google::protobuf::NewPermanentCallback(&RenderOneFieldPath, ow));
   return DecodeCompactFieldMaskPaths(data.str(), callback.get());
 }
@@ -972,7 +980,7 @@
   if (data.type() != DataPiece::TYPE_STRING) {
     return Status(INVALID_ARGUMENT,
                   StrCat("Invalid data type for duration, value is ",
-                         data.ValueAsStringOrDefault("")));
+                               data.ValueAsStringOrDefault("")));
   }
 
   StringPiece value(data.str());
@@ -1042,8 +1050,8 @@
     ProtoWriter::StartObject(name);
     status = (*type_renderer)(this, data);
     if (!status.ok()) {
-      InvalidValue(master_type_.name(),
-                   StrCat("Field '", name, "', ", status.error_message()));
+      InvalidValue(master_type_.name(), StrCat("Field '", name, "', ",
+                                                     status.error_message()));
     }
     ProtoWriter::EndObject();
     return this;
@@ -1058,17 +1066,26 @@
   if (current_->IsMap()) {
     if (!ValidMapKey(name)) return this;
 
+    field = Lookup("value");
+    if (field == nullptr) {
+      GOOGLE_LOG(DFATAL) << "Map does not have a value field.";
+      return this;
+    }
+
+    if (options_.ignore_null_value_map_entry) {
+      // If we are rendering explicit null values and the backend proto field is
+      // not of the google.protobuf.NullType type, interpret null as absence.
+      if (data.type() == DataPiece::TYPE_NULL &&
+          field->type_url() != kStructNullValueTypeUrl) {
+        return this;
+      }
+    }
+
     // Render an item in repeated map list.
     // { "key": "<name>", "value":
     Push("", Item::MESSAGE, false, false);
     ProtoWriter::RenderDataPiece("key",
                                  DataPiece(name, use_strict_base64_decoding()));
-    field = Lookup("value");
-    if (field == nullptr) {
-      Pop();
-      GOOGLE_LOG(DFATAL) << "Map does not have a value field.";
-      return this;
-    }
 
     const TypeRenderer* type_renderer = FindTypeRenderer(field->type_url());
     if (type_renderer != nullptr) {
@@ -1079,8 +1096,8 @@
       Push("value", Item::MESSAGE, true, false);
       status = (*type_renderer)(this, data);
       if (!status.ok()) {
-        InvalidValue(field->type_url(),
-                     StrCat("Field '", name, "', ", status.error_message()));
+        InvalidValue(field->type_url(), StrCat("Field '", name, "', ",
+                                                     status.error_message()));
       }
       Pop();
       return this;
@@ -1113,8 +1130,8 @@
       Push(name, Item::MESSAGE, false, false);
       status = (*type_renderer)(this, data);
       if (!status.ok()) {
-        InvalidValue(field->type_url(),
-                     StrCat("Field '", name, "', ", status.error_message()));
+        InvalidValue(field->type_url(), StrCat("Field '", name, "', ",
+                                                     status.error_message()));
       }
       Pop();
     }
@@ -1134,12 +1151,13 @@
 
 // Map of functions that are responsible for rendering well known type
 // represented by the key.
-hash_map<string, ProtoStreamObjectWriter::TypeRenderer>*
+std::unordered_map<string, ProtoStreamObjectWriter::TypeRenderer>*
     ProtoStreamObjectWriter::renderers_ = NULL;
-GOOGLE_PROTOBUF_DECLARE_ONCE(writer_renderers_init_);
+GOOGLE_PROTOBUF_NAMESPACE_ID::internal::once_flag writer_renderers_init_;
 
 void ProtoStreamObjectWriter::InitRendererMap() {
-  renderers_ = new hash_map<string, ProtoStreamObjectWriter::TypeRenderer>();
+  renderers_ =
+      new std::unordered_map<string, ProtoStreamObjectWriter::TypeRenderer>();
   (*renderers_)["type.googleapis.com/google.protobuf.Timestamp"] =
       &ProtoStreamObjectWriter::RenderTimestamp;
   (*renderers_)["type.googleapis.com/google.protobuf.Duration"] =
@@ -1194,7 +1212,8 @@
 
 ProtoStreamObjectWriter::TypeRenderer*
 ProtoStreamObjectWriter::FindTypeRenderer(const string& type_url) {
-  ::google::protobuf::GoogleOnceInit(&writer_renderers_init_, &InitRendererMap);
+  GOOGLE_PROTOBUF_NAMESPACE_ID::internal::call_once(writer_renderers_init_,
+                                                     InitRendererMap);
   return FindOrNull(*renderers_, type_url);
 }
 
@@ -1204,14 +1223,16 @@
   if (!current_->InsertMapKeyIfNotPresent(unnormalized_name)) {
     listener()->InvalidName(
         location(), unnormalized_name,
-        StrCat("Repeated map key: '", unnormalized_name, "' is already set."));
+        StrCat("Repeated map key: '", unnormalized_name,
+                     "' is already set."));
     return false;
   }
 
   return true;
 }
 
-void ProtoStreamObjectWriter::Push(StringPiece name, Item::ItemType item_type,
+void ProtoStreamObjectWriter::Push(StringPiece name,
+                                   Item::ItemType item_type,
                                    bool is_placeholder, bool is_list) {
   is_list ? ProtoWriter::StartList(name) : ProtoWriter::StartObject(name);
 
@@ -1247,7 +1268,7 @@
   const google::protobuf::Type* field_type =
       typeinfo()->GetTypeByTypeUrl(field.type_url());
 
-  return google::protobuf::util::converter::IsMap(field, *field_type);
+  return converter::IsMap(field, *field_type);
 }
 
 bool ProtoStreamObjectWriter::IsAny(const google::protobuf::Field& field) {
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h
index d9bb432..714c556 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.h
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.h
@@ -32,8 +32,9 @@
 #define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTWRITER_H__
 
 #include <deque>
-#include <google/protobuf/stubs/hash.h>
 #include <string>
+#include <unordered_map>
+#include <unordered_set>
 
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/io/coded_stream.h>
@@ -46,6 +47,7 @@
 #include <google/protobuf/util/internal/structured_objectwriter.h>
 #include <google/protobuf/util/type_resolver.h>
 #include <google/protobuf/stubs/bytestream.h>
+#include <google/protobuf/stubs/hash.h>
 
 namespace google {
 namespace protobuf {
@@ -53,14 +55,16 @@
 class CodedOutputStream;
 }  // namespace io
 }  // namespace protobuf
+}  // namespace google
 
-
+namespace google {
 namespace protobuf {
 class Type;
 class Field;
 }  // namespace protobuf
+}  // namespace google
 
-
+namespace google {
 namespace protobuf {
 namespace util {
 namespace converter {
@@ -94,10 +98,15 @@
     // the field name.
     bool use_lower_camel_for_enums;
 
+    // If true, skips rendering the map entry if map value is null unless the
+    // value type is google.protobuf.NullType.
+    bool ignore_null_value_map_entry;
+
     Options()
         : struct_integers_as_strings(false),
           ignore_unknown_fields(false),
-          use_lower_camel_for_enums(false) {}
+          use_lower_camel_for_enums(false),
+          ignore_null_value_map_entry(false) {}
 
     // Default instance of Options with all options set to defaults.
     static const Options& Defaults() {
@@ -112,18 +121,18 @@
                           strings::ByteSink* output, ErrorListener* listener,
                           const ProtoStreamObjectWriter::Options& options =
                               ProtoStreamObjectWriter::Options::Defaults());
-  virtual ~ProtoStreamObjectWriter() override;
+  ~ProtoStreamObjectWriter() override;
 
   // ObjectWriter methods.
-  virtual ProtoStreamObjectWriter* StartObject(StringPiece name) override;
-  virtual ProtoStreamObjectWriter* EndObject() override;
-  virtual ProtoStreamObjectWriter* StartList(StringPiece name) override;
-  virtual ProtoStreamObjectWriter* EndList() override;
+  ProtoStreamObjectWriter* StartObject(StringPiece name) override;
+  ProtoStreamObjectWriter* EndObject() override;
+  ProtoStreamObjectWriter* StartList(StringPiece name) override;
+  ProtoStreamObjectWriter* EndList() override;
 
   // Renders a DataPiece 'value' into a field whose wire type is determined
   // from the given field 'name'.
-  virtual ProtoStreamObjectWriter* RenderDataPiece(StringPiece name,
-                                           const DataPiece& value) override;
+  ProtoStreamObjectWriter* RenderDataPiece(StringPiece name,
+                                           const DataPiece& data) override;
 
  protected:
   // Function that renders a well known type with modified behavior.
@@ -171,13 +180,11 @@
 
       // Constructor for START_OBJECT and START_LIST events.
       explicit Event(Type type, StringPiece name)
-          : type_(type),
-            name_(name.ToString()),
-            value_(DataPiece::NullData()) {}
+          : type_(type), name_(name), value_(DataPiece::NullData()) {}
 
       // Constructor for RENDER_DATA_PIECE events.
       explicit Event(StringPiece name, const DataPiece& value)
-          : type_(RENDER_DATA_PIECE), name_(name.ToString()), value_(value) {
+          : type_(RENDER_DATA_PIECE), name_(name), value_(value) {
         DeepCopy();
       }
 
@@ -263,7 +270,7 @@
     // Constructor for a field of a message.
     Item(Item* parent, ItemType item_type, bool is_placeholder, bool is_list);
 
-    virtual ~Item() override {}
+    ~Item() override {}
 
     // These functions return true if the element type is corresponding to the
     // type in function name.
@@ -272,7 +279,7 @@
 
     AnyWriter* any() const { return any_.get(); }
 
-    virtual Item* parent() const override {
+    Item* parent() const override {
       return static_cast<Item*>(BaseElement::parent());
     }
 
@@ -299,7 +306,7 @@
 
     // Set of map keys already seen for the type_. Used to validate incoming
     // messages so no map key appears more than once.
-    std::unique_ptr<hash_set<string> > map_keys_;
+    std::unique_ptr<std::unordered_set<string> > map_keys_;
 
     // Conveys whether this Item is a placeholder or not. Placeholder items are
     // pushed to stack to account for special types.
@@ -371,8 +378,8 @@
   // is_placeholder conveys whether the item is a placeholder item or not.
   // Placeholder items are pushed when adding auxillary types' StartObject or
   // StartList calls.
-  void Push(StringPiece name, Item::ItemType item_type, bool is_placeholder,
-            bool is_list);
+  void Push(StringPiece name, Item::ItemType item_type,
+            bool is_placeholder, bool is_list);
 
   // Pops items from the stack. All placeholder items are popped until a
   // non-placeholder item is found.
@@ -385,7 +392,7 @@
  private:
   // Helper functions to create the map and find functions responsible for
   // rendering well known types, keyed by type URL.
-  static hash_map<string, TypeRenderer>* renderers_;
+  static std::unordered_map<string, TypeRenderer>* renderers_;
 
   // Variables for describing the structure of the input tree:
   // master_type_: descriptor for the whole protobuf message.
@@ -403,6 +410,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTOSTREAM_OBJECTWRITER_H__
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
index 9c50e7d..9020670 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
@@ -58,6 +58,7 @@
 #include <gtest/gtest.h>
 
 
+
 namespace google {
 namespace protobuf {
 namespace util {
@@ -79,11 +80,6 @@
 using google::protobuf::testing::TimestampDuration;
 using google::protobuf::testing::ValueWrapper;
 using google::protobuf::testing::oneofs::OneOfsRequest;
-using google::protobuf::Descriptor;
-using google::protobuf::DescriptorPool;
-using google::protobuf::DynamicMessageFactory;
-using google::protobuf::FileDescriptorProto;
-using google::protobuf::Message;
 using strings::GrowingArrayByteSink;
 using ::testing::_;
 using ::testing::Args;
@@ -517,8 +513,8 @@
   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_SFIXED64"),
                                       StringPiece("\"NaN\"")))
       .With(Args<0>(HasObjectLocation("sf64")));
-  EXPECT_CALL(listener_,
-              InvalidValue(_, StringPiece("TYPE_BOOL"), StringPiece("\"NaN\"")))
+  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_BOOL"),
+                                      StringPiece("\"NaN\"")))
       .With(Args<0>(HasObjectLocation("bool")));
 
   ow_->StartObject("")
@@ -591,9 +587,9 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidName(
-          _, StringPiece("name"),
-          StringPiece("Proto field is not repeating, cannot start list.")))
+      InvalidName(_, StringPiece("name"),
+                  StringPiece(
+                      "Proto field is not repeating, cannot start list.")))
       .With(Args<0>(HasObjectLocation("author")));
   ow_->StartObject("")
       ->StartObject("author")
@@ -687,9 +683,9 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidName(
-          _, StringPiece("publisher"),
-          StringPiece("Proto field is not repeating, cannot start list.")))
+      InvalidName(_, StringPiece("publisher"),
+                  StringPiece(
+                      "Proto field is not repeating, cannot start list.")))
       .With(Args<0>(HasObjectLocation("")));
   ow_->StartObject("")
       ->StartObject("author")
@@ -1030,9 +1026,10 @@
   Book expected;
   expected.set_title("Annie");
 
-  EXPECT_CALL(listener_,
-              InvalidName(_, StringPiece("oops"),
-                          StringPiece("Root element should not be named.")))
+  EXPECT_CALL(
+      listener_,
+      InvalidName(_, StringPiece("oops"),
+                  StringPiece("Root element should not be named.")))
       .With(Args<0>(HasObjectLocation("")));
   ow_->StartObject("oops")->RenderString("title", "Annie")->EndObject();
   CheckOutput(expected, 7);
@@ -1041,9 +1038,10 @@
 TEST_P(ProtoStreamObjectWriterTest, RootNamedList) {
   Book empty;
 
-  EXPECT_CALL(listener_,
-              InvalidName(_, StringPiece("oops"),
-                          StringPiece("Root element should not be named.")))
+  EXPECT_CALL(
+      listener_,
+      InvalidName(_, StringPiece("oops"),
+                  StringPiece("Root element should not be named.")))
       .With(Args<0>(HasObjectLocation("")));
   ow_->StartList("oops")->RenderString("", "item")->EndList();
   CheckOutput(empty, 0);
@@ -1179,10 +1177,10 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
-                   StringPiece("Field 'ts', Invalid time format: "
-                               "2016-03-07T15:14:23+")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+          StringPiece("Field 'ts', Invalid time format: "
+                      "2016-03-07T15:14:23+")));
 
   ow_->StartObject("")->RenderString("ts", "2016-03-07T15:14:23+")->EndObject();
   CheckOutput(timestamp);
@@ -1194,10 +1192,10 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
-                   StringPiece("Field 'ts', Invalid time format: "
-                               "2016-03-07T15:14:23+08-10")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+          StringPiece("Field 'ts', Invalid time format: "
+                      "2016-03-07T15:14:23+08-10")));
 
   ow_->StartObject("")
       ->RenderString("ts", "2016-03-07T15:14:23+08-10")
@@ -1211,10 +1209,10 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
-                   StringPiece("Field 'ts', Invalid time format: "
-                               "2016-03-07T15:14:23+24:10")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+          StringPiece("Field 'ts', Invalid time format: "
+                      "2016-03-07T15:14:23+24:10")));
 
   ow_->StartObject("")
       ->RenderString("ts", "2016-03-07T15:14:23+24:10")
@@ -1228,10 +1226,10 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
-                   StringPiece("Field 'ts', Invalid time format: "
-                               "2016-03-07T15:14:23+04:60")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+          StringPiece("Field 'ts', Invalid time format: "
+                      "2016-03-07T15:14:23+04:60")));
 
   ow_->StartObject("")
       ->RenderString("ts", "2016-03-07T15:14:23+04:60")
@@ -1244,9 +1242,9 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
-                   StringPiece("Field 'ts', Invalid time format: ")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+          StringPiece("Field 'ts', Invalid time format: ")));
 
   ow_->StartObject("")->RenderString("ts", "")->EndObject();
   CheckOutput(timestamp);
@@ -1257,9 +1255,9 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
-                   StringPiece("Field 'ts', Invalid time format: Z")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+          StringPiece("Field 'ts', Invalid time format: Z")));
 
   ow_->StartObject("")->RenderString("ts", "Z")->EndObject();
   CheckOutput(timestamp);
@@ -1270,10 +1268,10 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
-                   StringPiece("Field 'ts', Invalid time format: "
-                               "1970-01-01T00:00:00.ABZ")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+          StringPiece("Field 'ts', Invalid time format: "
+                      "1970-01-01T00:00:00.ABZ")));
 
   ow_->StartObject("")
       ->RenderString("ts", "1970-01-01T00:00:00.ABZ")
@@ -1286,10 +1284,10 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
-                   StringPiece("Field 'ts', Invalid time format: "
-                               "-8031-10-18T00:00:00.000Z")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+          StringPiece("Field 'ts', Invalid time format: "
+                      "-8031-10-18T00:00:00.000Z")));
 
   ow_->StartObject("")
       ->RenderString("ts", "-8031-10-18T00:00:00.000Z")
@@ -1302,10 +1300,10 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
-                   StringPiece("Field 'ts', Invalid time format: "
-                               "2015-11-23T03:37:35.033155   Z")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+          StringPiece("Field 'ts', Invalid time format: "
+                      "2015-11-23T03:37:35.033155   Z")));
 
   ow_->StartObject("")
       // Whitespace in the Timestamp nanos is not allowed.
@@ -1319,10 +1317,10 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
-                   StringPiece("Field 'ts', Invalid time format: "
-                               "2015-11-23T03:37:35.033155 1234Z")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+          StringPiece("Field 'ts', Invalid time format: "
+                      "2015-11-23T03:37:35.033155 1234Z")));
 
   ow_->StartObject("")
       // Whitespace in the Timestamp nanos is not allowed.
@@ -1336,10 +1334,10 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
-                   StringPiece("Field 'ts', Invalid time format: "
-                               "2015-11-23T03:37:35.033abc155Z")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+          StringPiece("Field 'ts', Invalid time format: "
+                      "2015-11-23T03:37:35.033abc155Z")));
 
   ow_->StartObject("")
       // Non-numeric characters in the Timestamp nanos is not allowed.
@@ -1353,10 +1351,10 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
-                   StringPiece("Field 'ts', Invalid time format: "
-                               "0-12-31T23:59:59.000Z")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+          StringPiece("Field 'ts', Invalid time format: "
+                      "0-12-31T23:59:59.000Z")));
 
   ow_->StartObject("")
       ->RenderString("ts", "0-12-31T23:59:59.000Z")
@@ -1381,8 +1379,9 @@
       listener_,
       InvalidValue(
           _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
-          StringPiece("Field 'dur', Illegal duration format; duration must "
-                      "end with 's'")));
+          StringPiece(
+              "Field 'dur', Illegal duration format; duration must "
+              "end with 's'")));
 
   ow_->StartObject("")->RenderString("dur", "")->EndObject();
   CheckOutput(duration);
@@ -1395,8 +1394,9 @@
       listener_,
       InvalidValue(
           _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
-          StringPiece("Field 'dur', Invalid duration format, failed to parse "
-                      "seconds")));
+          StringPiece(
+              "Field 'dur', Invalid duration format, failed to parse "
+              "seconds")));
 
   ow_->StartObject("")->RenderString("dur", "s")->EndObject();
   CheckOutput(duration);
@@ -1410,7 +1410,7 @@
       InvalidValue(
           _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
           StringPiece("Field 'dur', Invalid duration format, failed to "
-                      "parse nano seconds")));
+                            "parse nano seconds")));
 
   ow_->StartObject("")->RenderString("dur", "123.DEFs")->EndObject();
   CheckOutput(duration);
@@ -1421,9 +1421,9 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Duration"),
-                   StringPiece("Field 'dur', Duration value exceeds limits")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
+          StringPiece("Field 'dur', Duration value exceeds limits")));
 
   ow_->StartObject("")->RenderString("dur", "315576000002s")->EndObject();
   CheckOutput(duration);
@@ -1434,9 +1434,9 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.Duration"),
-                   StringPiece("Field 'dur', Duration value exceeds limits")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
+          StringPiece("Field 'dur', Duration value exceeds limits")));
 
   ow_->StartObject("")->RenderString("dur", "0.1000000001s")->EndObject();
   CheckOutput(duration);
@@ -1533,8 +1533,9 @@
   StructType struct_type;
   EXPECT_CALL(
       listener_,
-      InvalidValue(_, StringPiece("type.googleapis.com/google.protobuf.Struct"),
-                   StringPiece("true")))
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.Struct"),
+          StringPiece("true")))
       .With(Args<0>(HasObjectLocation("object")));
 
   ow_->StartObject("")->RenderBool("object", true)->EndObject();
@@ -1564,10 +1565,10 @@
 }
 
 TEST_P(ProtoStreamObjectWriterStructTest, SimpleRepeatedStructMapKeyTest) {
-  EXPECT_CALL(
-      listener_,
-      InvalidName(_, StringPiece("gBike"),
-                  StringPiece("Repeated map key: 'gBike' is already set.")));
+  EXPECT_CALL(listener_,
+              InvalidName(_, StringPiece("gBike"),
+                          StringPiece(
+                              "Repeated map key: 'gBike' is already set.")));
   ow_->StartObject("")
       ->StartObject("object")
       ->RenderString("gBike", "v1")
@@ -1641,8 +1642,12 @@
 
 class ProtoStreamObjectWriterMapTest : public BaseProtoStreamObjectWriterTest {
  protected:
-  ProtoStreamObjectWriterMapTest()
-      : BaseProtoStreamObjectWriterTest(MapIn::descriptor()) {}
+  ProtoStreamObjectWriterMapTest() {
+    std::vector<const Descriptor*> descriptors;
+    descriptors.push_back(MapIn::descriptor());
+    descriptors.push_back(google::protobuf::DoubleValue::descriptor());
+    ResetTypeInfo(descriptors);
+  }
 };
 
 INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
@@ -1654,9 +1659,9 @@
   MapIn mm;
   EXPECT_CALL(
       listener_,
-      InvalidValue(
-          _, StringPiece("Map"),
-          StringPiece("Cannot bind a list to map for field 'map_input'.")));
+      InvalidValue(_, StringPiece("Map"),
+                   StringPiece(
+                       "Cannot bind a list to map for field 'map_input'.")));
   ow_->StartObject("")
       ->StartList("map_input")
       ->RenderString("a", "b")
@@ -1665,6 +1670,36 @@
   CheckOutput(mm);
 }
 
+TEST_P(ProtoStreamObjectWriterMapTest, MapAcceptsNullValue) {
+  // Null should not be a valid map value.
+  // See http://go/proto3-json-spec#heading=h.r2ddatp7y4vi
+  // This test is added for backward compatibility.
+  MapIn mm;
+  (*mm.mutable_map_input())["a"] = "b";
+  (*mm.mutable_map_input())["x"] = "";
+  ow_->StartObject("")
+      ->StartObject("map_input")
+      ->RenderString("a", "b")
+      ->RenderNull("x")
+      ->EndObject()
+      ->EndObject();
+  CheckOutput(mm);
+}
+
+TEST_P(ProtoStreamObjectWriterMapTest, MapShouldIgnoreNullValueEntry) {
+  options_.ignore_null_value_map_entry = true;
+  ResetTypeInfo(MapIn::descriptor());
+  MapIn mm;
+  (*mm.mutable_map_input())["a"] = "b";
+  ow_->StartObject("")
+      ->StartObject("map_input")
+      ->RenderString("a", "b")
+      ->RenderNull("x")
+      ->EndObject()
+      ->EndObject();
+  CheckOutput(mm);
+}
+
 TEST_P(ProtoStreamObjectWriterMapTest, RepeatedMapKeyTest) {
   EXPECT_CALL(
       listener_,
@@ -1899,10 +1934,10 @@
 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails1) {
   AnyOut any;
 
-  EXPECT_CALL(listener_,
-              InvalidValue(_, StringPiece("Any"),
-                           StringPiece("Missing @type for any field in "
-                                       "google.protobuf.testing.AnyOut")));
+  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
+                                      StringPiece(
+                                          "Missing @type for any field in "
+                                          "google.protobuf.testing.AnyOut")));
 
   ow_->StartObject("")
       ->StartObject("any")
@@ -1916,10 +1951,10 @@
 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails2) {
   AnyOut any;
 
-  EXPECT_CALL(listener_,
-              InvalidValue(_, StringPiece("Any"),
-                           StringPiece("Missing @type for any field in "
-                                       "google.protobuf.testing.AnyOut")));
+  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
+                                      StringPiece(
+                                          "Missing @type for any field in "
+                                          "google.protobuf.testing.AnyOut")));
 
   ow_->StartObject("")
       ->StartObject("any")
@@ -1933,10 +1968,10 @@
 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails3) {
   AnyOut any;
 
-  EXPECT_CALL(listener_,
-              InvalidValue(_, StringPiece("Any"),
-                           StringPiece("Missing @type for any field in "
-                                       "google.protobuf.testing.AnyOut")));
+  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
+                                      StringPiece(
+                                          "Missing @type for any field in "
+                                          "google.protobuf.testing.AnyOut")));
 
   ow_->StartObject("")
       ->StartObject("any")
@@ -1949,12 +1984,13 @@
 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithInvalidTypeUrlFails) {
   AnyOut any;
 
-  EXPECT_CALL(listener_,
-              InvalidValue(
-                  _, StringPiece("Any"),
-                  StringPiece("Invalid type URL, type URLs must be of the form "
-                              "'type.googleapis.com/<typename>', got: "
-                              "type.other.com/some.Type")));
+  EXPECT_CALL(
+      listener_,
+      InvalidValue(
+          _, StringPiece("Any"),
+          StringPiece("Invalid type URL, type URLs must be of the form "
+                            "'type.googleapis.com/<typename>', got: "
+                            "type.other.com/some.Type")));
 
   ow_->StartObject("")
       ->StartObject("any")
@@ -1968,10 +2004,10 @@
 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithUnknownTypeFails) {
   AnyOut any;
 
-  EXPECT_CALL(
-      listener_,
-      InvalidValue(_, StringPiece("Any"),
-                   StringPiece("Invalid type URL, unknown type: some.Type")));
+  EXPECT_CALL(listener_,
+              InvalidValue(_, StringPiece("Any"),
+                           StringPiece(
+                               "Invalid type URL, unknown type: some.Type")));
   ow_->StartObject("")
       ->StartObject("any")
       ->RenderString("@type", "type.googleapis.com/some.Type")
@@ -1986,7 +2022,8 @@
 
   EXPECT_CALL(
       listener_,
-      InvalidValue(_, StringPiece("type.googleapis.com/google.protobuf.Any"),
+      InvalidValue(_,
+                   StringPiece("type.googleapis.com/google.protobuf.Any"),
                    StringPiece("1")));
   ow_->StartObject("")->RenderInt32("any", 1)->EndObject();
   CheckOutput(any);
@@ -2194,8 +2231,9 @@
 //   }
 // }
 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesExpectObjectForStruct) {
-  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
-                                      StringPiece("Expect a JSON object.")));
+  EXPECT_CALL(listener_,
+              InvalidValue(_, StringPiece("Any"),
+                           StringPiece("Expect a JSON object.")));
   AnyOut any;
   google::protobuf::Any* any_type = any.mutable_any();
   any_type->set_type_url("type.googleapis.com/google.protobuf.Struct");
@@ -2218,8 +2256,9 @@
 //   }
 // }
 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesExpectObjectForAny) {
-  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
-                                      StringPiece("Expect a JSON object.")));
+  EXPECT_CALL(listener_,
+              InvalidValue(_, StringPiece("Any"),
+                           StringPiece("Expect a JSON object.")));
   AnyOut any;
   google::protobuf::Any* any_type = any.mutable_any();
   any_type->set_type_url("type.googleapis.com/google.protobuf.Any");
@@ -2480,7 +2519,7 @@
       InvalidValue(
           _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
           StringPiece("Field 'single_mask', Invalid FieldMask 'a(b,c))'. "
-                      "Cannot find matching '(' for all ')'.")));
+                            "Cannot find matching '(' for all ')'.")));
 
   ow_->StartObject("");
   ow_->RenderString("id", "1");
@@ -2525,9 +2564,10 @@
       listener_,
       InvalidValue(
           _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
-          StringPiece("Field 'single_mask', Invalid FieldMask "
-                      "'path.to.map[\"key1\"]a,path.to.map[\"key2\"]'. "
-                      "Map keys should be at the end of a path segment.")));
+          StringPiece(
+              "Field 'single_mask', Invalid FieldMask "
+              "'path.to.map[\"key1\"]a,path.to.map[\"key2\"]'. "
+              "Map keys should be at the end of a path segment.")));
 
   ow_->StartObject("");
   ow_->RenderString("single_mask",
@@ -2538,11 +2578,11 @@
 TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyMustEnd) {
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
-                   StringPiece("Field 'single_mask', Invalid FieldMask "
-                               "'path.to.map[\"key1\"'. Map keys should be "
-                               "represented as [\"some_key\"].")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
+          StringPiece("Field 'single_mask', Invalid FieldMask "
+                            "'path.to.map[\"key1\"'. Map keys should be "
+                            "represented as [\"some_key\"].")));
 
   ow_->StartObject("");
   ow_->RenderString("single_mask", "path.to.map[\"key1\"");
@@ -2552,11 +2592,11 @@
 TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyMustBeEscapedCorrectly) {
   EXPECT_CALL(
       listener_,
-      InvalidValue(_,
-                   StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
-                   StringPiece("Field 'single_mask', Invalid FieldMask "
-                               "'path.to.map[\"ke\"y1\"]'. Map keys should be "
-                               "represented as [\"some_key\"].")));
+      InvalidValue(
+          _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
+          StringPiece("Field 'single_mask', Invalid FieldMask "
+                            "'path.to.map[\"ke\"y1\"]'. Map keys should be "
+                            "represented as [\"some_key\"].")));
 
   ow_->StartObject("");
   ow_->RenderString("single_mask", "path.to.map[\"ke\"y1\"]");
@@ -2647,10 +2687,10 @@
 TEST_P(ProtoStreamObjectWriterOneOfsTest,
        MultipleOneofsFailForMessageTypesPrimitiveFirstTest) {
   // Test for setting primitive oneof field first and then message field.
-  EXPECT_CALL(listener_,
-              InvalidValue(_, StringPiece("oneof"),
-                           StringPiece("oneof field 'data' is already set. "
-                                       "Cannot set 'messageData'")));
+  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+                                      StringPiece(
+                                          "oneof field 'data' is already set. "
+                                          "Cannot set 'messageData'")));
 
   // JSON: { "strData": "blah", "messageData": { "dataValue": 123 } }
   ow_->StartObject("");
@@ -2664,10 +2704,10 @@
 TEST_P(ProtoStreamObjectWriterOneOfsTest,
        MultipleOneofsFailForMessageTypesMessageFirstTest) {
   // Test for setting message oneof field first and then primitive field.
-  EXPECT_CALL(listener_,
-              InvalidValue(_, StringPiece("oneof"),
-                           StringPiece("oneof field 'data' is already set. "
-                                       "Cannot set 'strData'")));
+  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+                                      StringPiece(
+                                          "oneof field 'data' is already set. "
+                                          "Cannot set 'strData'")));
 
   // JSON: { "messageData": { "dataValue": 123 }, "strData": "blah" }
   ow_->StartObject("");
@@ -2680,10 +2720,10 @@
 
 TEST_P(ProtoStreamObjectWriterOneOfsTest,
        MultipleOneofsFailForStructTypesPrimitiveFirstTest) {
-  EXPECT_CALL(listener_,
-              InvalidValue(_, StringPiece("oneof"),
-                           StringPiece("oneof field 'data' is already set. "
-                                       "Cannot set 'structData'")));
+  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+                                      StringPiece(
+                                          "oneof field 'data' is already set. "
+                                          "Cannot set 'structData'")));
 
   // JSON: { "strData": "blah", "structData": { "a": "b" } }
   ow_->StartObject("");
@@ -2696,10 +2736,10 @@
 
 TEST_P(ProtoStreamObjectWriterOneOfsTest,
        MultipleOneofsFailForStructTypesStructFirstTest) {
-  EXPECT_CALL(listener_,
-              InvalidValue(_, StringPiece("oneof"),
-                           StringPiece("oneof field 'data' is already set. "
-                                       "Cannot set 'strData'")));
+  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+                                      StringPiece(
+                                          "oneof field 'data' is already set. "
+                                          "Cannot set 'strData'")));
 
   // JSON: { "structData": { "a": "b" }, "strData": "blah" }
   ow_->StartObject("");
@@ -2712,10 +2752,10 @@
 
 TEST_P(ProtoStreamObjectWriterOneOfsTest,
        MultipleOneofsFailForStructValueTypesTest) {
-  EXPECT_CALL(listener_,
-              InvalidValue(_, StringPiece("oneof"),
-                           StringPiece("oneof field 'data' is already set. "
-                                       "Cannot set 'valueData'")));
+  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+                                      StringPiece(
+                                          "oneof field 'data' is already set. "
+                                          "Cannot set 'valueData'")));
 
   // JSON: { "messageData": { "dataValue": 123 }, "valueData": { "a": "b" } }
   ow_->StartObject("");
@@ -2730,10 +2770,10 @@
 
 TEST_P(ProtoStreamObjectWriterOneOfsTest,
        MultipleOneofsFailForWellKnownTypesPrimitiveFirstTest) {
-  EXPECT_CALL(listener_,
-              InvalidValue(_, StringPiece("oneof"),
-                           StringPiece("oneof field 'data' is already set. "
-                                       "Cannot set 'tsData'")));
+  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+                                      StringPiece(
+                                          "oneof field 'data' is already set. "
+                                          "Cannot set 'tsData'")));
 
   // JSON: { "intData": 123, "tsData": "1970-01-02T01:00:00.000Z" }
   ow_->StartObject("");
@@ -2744,10 +2784,10 @@
 
 TEST_P(ProtoStreamObjectWriterOneOfsTest,
        MultipleOneofsFailForWellKnownTypesWktFirstTest) {
-  EXPECT_CALL(listener_,
-              InvalidValue(_, StringPiece("oneof"),
-                           StringPiece("oneof field 'data' is already set. "
-                                       "Cannot set 'intData'")));
+  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+                                      StringPiece(
+                                          "oneof field 'data' is already set. "
+                                          "Cannot set 'intData'")));
 
   // JSON: { "tsData": "1970-01-02T01:00:00.000Z", "intData": 123 }
   ow_->StartObject("");
@@ -2758,10 +2798,10 @@
 
 TEST_P(ProtoStreamObjectWriterOneOfsTest,
        MultipleOneofsFailForWellKnownTypesAndMessageTest) {
-  EXPECT_CALL(listener_,
-              InvalidValue(_, StringPiece("oneof"),
-                           StringPiece("oneof field 'data' is already set. "
-                                       "Cannot set 'messageData'")));
+  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+                                      StringPiece(
+                                          "oneof field 'data' is already set. "
+                                          "Cannot set 'messageData'")));
 
   // JSON: { "tsData": "1970-01-02T01:00:00.000Z",
   //         "messageData": { "dataValue": 123 } }
@@ -2775,10 +2815,10 @@
 
 TEST_P(ProtoStreamObjectWriterOneOfsTest,
        MultipleOneofsFailForOneofWithinAnyTest) {
-  EXPECT_CALL(listener_,
-              InvalidValue(_, StringPiece("oneof"),
-                           StringPiece("oneof field 'data' is already set. "
-                                       "Cannot set 'intData'")));
+  EXPECT_CALL(listener_, InvalidValue(_, StringPiece("oneof"),
+                                      StringPiece(
+                                          "oneof field 'data' is already set. "
+                                          "Cannot set 'intData'")));
 
   // JSON:
   // { "anyData":
diff --git a/src/google/protobuf/util/internal/structured_objectwriter.h b/src/google/protobuf/util/internal/structured_objectwriter.h
index 8e63222..3551abc 100644
--- a/src/google/protobuf/util/internal/structured_objectwriter.h
+++ b/src/google/protobuf/util/internal/structured_objectwriter.h
@@ -110,6 +110,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_STRUCTURED_OBJECTWRITER_H__
diff --git a/src/google/protobuf/util/internal/testdata/anys.proto b/src/google/protobuf/util/internal/testdata/anys.proto
index a9ebca3..77c1043 100644
--- a/src/google/protobuf/util/internal/testdata/anys.proto
+++ b/src/google/protobuf/util/internal/testdata/anys.proto
@@ -57,6 +57,7 @@
   AnyWrapper any_with_message_containing_struct = 13;
   AnyWrapper any_with_message_containing_repeated_message = 14;
   AnyWrapper recursive_any_with_type_field_at_end = 15;
+  AnyWrapper repeated_any = 16;
 
   google.protobuf.Any top_level_any = 50;
   google.protobuf.Any top_level_any_with_type_field_at_end = 51;
@@ -87,6 +88,7 @@
   map<string, string> map_data = 7;
   google.protobuf.Struct struct_data = 8;
   repeated Data repeated_data = 9;
+  repeated google.protobuf.Any repeated_any = 10;
 }
 
 service AnyTestService {
diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc
index e32e71d..60cc3fc 100644
--- a/src/google/protobuf/util/internal/type_info.cc
+++ b/src/google/protobuf/util/internal/type_info.cc
@@ -58,7 +58,7 @@
     DeleteCachedTypes(&cached_enums_);
   }
 
-  virtual util::StatusOr<const google::protobuf::Type*> ResolveTypeUrl(
+  util::StatusOr<const google::protobuf::Type*> ResolveTypeUrl(
       StringPiece type_url) const override {
     std::map<StringPiece, StatusOrType>::iterator it =
         cached_types_.find(type_url);
@@ -68,7 +68,7 @@
     // Stores the string value so it can be referenced using StringPiece in the
     // cached_types_ map.
     const string& string_type_url =
-        *string_storage_.insert(type_url.ToString()).first;
+        *string_storage_.insert(string(type_url)).first;
     std::unique_ptr<google::protobuf::Type> type(new google::protobuf::Type());
     util::Status status =
         type_resolver_->ResolveMessageType(string_type_url, type.get());
@@ -78,13 +78,13 @@
     return result;
   }
 
-  virtual const google::protobuf::Type* GetTypeByTypeUrl(
+  const google::protobuf::Type* GetTypeByTypeUrl(
       StringPiece type_url) const override {
     StatusOrType result = ResolveTypeUrl(type_url);
     return result.ok() ? result.ValueOrDie() : NULL;
   }
 
-  virtual const google::protobuf::Enum* GetEnumByTypeUrl(
+  const google::protobuf::Enum* GetEnumByTypeUrl(
       StringPiece type_url) const override {
     std::map<StringPiece, StatusOrEnum>::iterator it =
         cached_enums_.find(type_url);
@@ -94,7 +94,7 @@
     // Stores the string value so it can be referenced using StringPiece in the
     // cached_enums_ map.
     const string& string_type_url =
-        *string_storage_.insert(type_url.ToString()).first;
+        *string_storage_.insert(string(type_url)).first;
     std::unique_ptr<google::protobuf::Enum> enum_type(
         new google::protobuf::Enum());
     util::Status status =
@@ -105,8 +105,7 @@
     return result.ok() ? result.ValueOrDie() : NULL;
   }
 
-
-  virtual const google::protobuf::Field* FindField(
+  const google::protobuf::Field* FindField(
       const google::protobuf::Type* type,
       StringPiece camel_case_name) const override {
     std::map<const google::protobuf::Type*, CamelCaseNameTable>::const_iterator
@@ -115,8 +114,8 @@
         (it == indexed_types_.end())
             ? PopulateNameLookupTable(type, &indexed_types_[type])
             : it->second;
-    StringPiece name =
-        FindWithDefault(camel_case_name_table, camel_case_name, StringPiece());
+    StringPiece name = FindWithDefault(
+        camel_case_name_table, camel_case_name, StringPiece());
     if (name.empty()) {
       // Didn't find a mapping. Use whatever provided.
       name = camel_case_name;
@@ -131,7 +130,8 @@
 
   template <typename T>
   static void DeleteCachedTypes(std::map<StringPiece, T>* cached_types) {
-    for (typename std::map<StringPiece, T>::iterator it = cached_types->begin();
+    for (typename std::map<StringPiece, T>::iterator it =
+             cached_types->begin();
          it != cached_types->end(); ++it) {
       if (it->second.ok()) {
         delete it->second.ValueOrDie();
@@ -146,8 +146,8 @@
       const google::protobuf::Field& field = type->fields(i);
       StringPiece name = field.name();
       StringPiece camel_case_name = field.json_name();
-      const StringPiece* existing =
-          InsertOrReturnExisting(camel_case_name_table, camel_case_name, name);
+      const StringPiece* existing = InsertOrReturnExisting(
+          camel_case_name_table, camel_case_name, name);
       if (existing && *existing != name) {
         GOOGLE_LOG(WARNING) << "Field '" << name << "' and '" << *existing
                      << "' map to the same camel case name '" << camel_case_name
diff --git a/src/google/protobuf/util/internal/type_info.h b/src/google/protobuf/util/internal/type_info.h
index d813317..38d5a3b 100644
--- a/src/google/protobuf/util/internal/type_info.h
+++ b/src/google/protobuf/util/internal/type_info.h
@@ -87,6 +87,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_TYPE_INFO_H__
diff --git a/src/google/protobuf/util/internal/type_info_test_helper.cc b/src/google/protobuf/util/internal/type_info_test_helper.cc
index 281a7f5..dfd86fa 100644
--- a/src/google/protobuf/util/internal/type_info_test_helper.cc
+++ b/src/google/protobuf/util/internal/type_info_test_helper.cc
@@ -33,6 +33,7 @@
 #include <memory>
 #include <vector>
 
+
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/descriptor.h>
diff --git a/src/google/protobuf/util/internal/type_info_test_helper.h b/src/google/protobuf/util/internal/type_info_test_helper.h
index 5a077e0..f1eac34 100644
--- a/src/google/protobuf/util/internal/type_info_test_helper.h
+++ b/src/google/protobuf/util/internal/type_info_test_helper.h
@@ -90,6 +90,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_TYPE_INFO_TEST_HELPER_H__
diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc
index b8d917c..4a3f2ed 100644
--- a/src/google/protobuf/util/internal/utility.cc
+++ b/src/google/protobuf/util/internal/utility.cc
@@ -43,13 +43,15 @@
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/mathlimits.h>
 
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 namespace util {
 namespace converter {
 
 bool GetBoolOptionOrDefault(
-    const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options,
+    const RepeatedPtrField<google::protobuf::Option>& options,
     const string& option_name, bool default_value) {
   const google::protobuf::Option* opt = FindOptionOrNull(options, option_name);
   if (opt == nullptr) {
@@ -59,7 +61,7 @@
 }
 
 int64 GetInt64OptionOrDefault(
-    const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options,
+    const RepeatedPtrField<google::protobuf::Option>& options,
     const string& option_name, int64 default_value) {
   const google::protobuf::Option* opt = FindOptionOrNull(options, option_name);
   if (opt == nullptr) {
@@ -69,7 +71,7 @@
 }
 
 double GetDoubleOptionOrDefault(
-    const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options,
+    const RepeatedPtrField<google::protobuf::Option>& options,
     const string& option_name, double default_value) {
   const google::protobuf::Option* opt = FindOptionOrNull(options, option_name);
   if (opt == nullptr) {
@@ -79,7 +81,7 @@
 }
 
 string GetStringOptionOrDefault(
-    const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options,
+    const RepeatedPtrField<google::protobuf::Option>& options,
     const string& option_name, const string& default_value) {
   const google::protobuf::Option* opt = FindOptionOrNull(options, option_name);
   if (opt == nullptr) {
@@ -136,7 +138,7 @@
 }
 
 const google::protobuf::Option* FindOptionOrNull(
-    const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options,
+    const RepeatedPtrField<google::protobuf::Option>& options,
     const string& option_name) {
   for (int i = 0; i < options.size(); ++i) {
     const google::protobuf::Option& opt = options.Get(i);
@@ -325,7 +327,7 @@
 }
 
 std::set<string>* well_known_types_ = NULL;
-GOOGLE_PROTOBUF_DECLARE_ONCE(well_known_types_init_);
+GOOGLE_PROTOBUF_NAMESPACE_ID::internal::once_flag well_known_types_init_;
 const char* well_known_types_name_array_[] = {
     "google.protobuf.Timestamp",   "google.protobuf.Duration",
     "google.protobuf.DoubleValue", "google.protobuf.FloatValue",
@@ -345,7 +347,8 @@
 }
 
 bool IsWellKnownType(const string& type_name) {
-  InitWellKnownTypes();
+  GOOGLE_PROTOBUF_NAMESPACE_ID::internal::call_once(well_known_types_init_,
+                                                     InitWellKnownTypes);
   return ContainsKey(*well_known_types_, type_name);
 }
 
diff --git a/src/google/protobuf/util/internal/utility.h b/src/google/protobuf/util/internal/utility.h
index d8e06a9..816987a 100644
--- a/src/google/protobuf/util/internal/utility.h
+++ b/src/google/protobuf/util/internal/utility.h
@@ -44,7 +44,6 @@
 #include <google/protobuf/stubs/status.h>
 #include <google/protobuf/stubs/statusor.h>
 
-
 namespace google {
 namespace protobuf {
 class Method;
@@ -56,8 +55,9 @@
 class Enum;
 class EnumValue;
 }  // namespace protobuf
+}  // namespace google
 
-
+namespace google {
 namespace protobuf {
 namespace util {
 namespace converter {
@@ -69,25 +69,25 @@
 // returns it.
 // When the option with the given name is not found, default_value is returned.
 LIBPROTOBUF_EXPORT bool GetBoolOptionOrDefault(
-    const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options,
+    const RepeatedPtrField<google::protobuf::Option>& options,
     const string& option_name, bool default_value);
 
 // Returns int64 option value. If the option isn't found, returns the
 // default_value.
 LIBPROTOBUF_EXPORT int64 GetInt64OptionOrDefault(
-    const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options,
+    const RepeatedPtrField<google::protobuf::Option>& options,
     const string& option_name, int64 default_value);
 
 // Returns double option value. If the option isn't found, returns the
 // default_value.
 LIBPROTOBUF_EXPORT double GetDoubleOptionOrDefault(
-    const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options,
+    const RepeatedPtrField<google::protobuf::Option>& options,
     const string& option_name, double default_value);
 
 // Returns string option value. If the option isn't found, returns the
 // default_value.
 LIBPROTOBUF_EXPORT string GetStringOptionOrDefault(
-    const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options,
+    const RepeatedPtrField<google::protobuf::Option>& options,
     const string& option_name, const string& default_value);
 
 // Returns a boolean value contained in Any type.
@@ -120,7 +120,7 @@
 // Finds and returns option identified by name and option_name within the
 // provided map. Returns nullptr if none found.
 const google::protobuf::Option* FindOptionOrNull(
-    const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options,
+    const RepeatedPtrField<google::protobuf::Option>& options,
     const string& option_name);
 
 // Finds and returns the field identified by field_name in the passed tech Type
@@ -209,6 +209,6 @@
 }  // namespace converter
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_CONVERTER_UTILITY_H__
diff --git a/src/google/protobuf/util/json_format.proto b/src/google/protobuf/util/json_format.proto
new file mode 100644
index 0000000..40b040e
--- /dev/null
+++ b/src/google/protobuf/util/json_format.proto
@@ -0,0 +1,109 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file we will use for unit testing.
+
+syntax = "proto2";
+package google.protobuf;
+
+
+message TestFlagsAndStrings {
+  required int32 A = 1;
+  repeated group RepeatedGroup = 2 {
+    required string f = 3;
+  }
+}
+
+message TestBase64ByteArrays {
+  required bytes a = 1;
+}
+
+message TestJavaScriptJSON {
+  optional int32 a = 1;
+  optional float final = 2;
+  optional string in = 3;
+  optional string Var = 4;
+}
+
+message TestJavaScriptOrderJSON1 {
+  optional int32 d = 1;
+  optional int32 c = 2;
+  optional bool x = 3;
+  optional int32 b = 4;
+  optional int32 a = 5;
+}
+
+message TestJavaScriptOrderJSON2 {
+  optional int32 d = 1;
+  optional int32 c = 2;
+  optional bool x = 3;
+  optional int32 b = 4;
+  optional int32 a = 5;
+  repeated TestJavaScriptOrderJSON1 z = 6;
+}
+
+message TestLargeInt {
+  required int64 a = 1;
+  required uint64 b = 2;
+}
+
+message TestNumbers {
+  enum MyType {
+    OK = 0;
+    WARNING = 1;
+    ERROR = 2;
+  }
+  optional MyType a = 1;
+  optional int32 b = 2;
+  optional float c = 3;
+  optional bool d = 4;
+  optional double e = 5;
+  optional uint32 f = 6;
+}
+
+
+message TestCamelCase {
+  optional string normal_field = 1;
+  optional int32 CAPITAL_FIELD = 2;
+  optional int32 CamelCaseField = 3;
+}
+
+message TestBoolMap {
+  map<bool, int32> bool_map = 1;
+}
+
+message TestRecursion {
+  optional int32 value = 1;
+  optional TestRecursion child = 2;
+}
diff --git a/src/google/protobuf/util/json_format_proto3.proto b/src/google/protobuf/util/json_format_proto3.proto
index cbc3f81..28e593d 100644
--- a/src/google/protobuf/util/json_format_proto3.proto
+++ b/src/google/protobuf/util/json_format_proto3.proto
@@ -182,8 +182,8 @@
   .protobuf_unittest.TestAllExtensions extensions = 1;
 }
 
-message TestEnumValue{
+message TestEnumValue {
   EnumType enum_value1 = 1;
   EnumType enum_value2 = 2;
   EnumType enum_value3 = 3;
-}
\ No newline at end of file
+}
diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc
index 7a7f299..bf82fa7 100644
--- a/src/google/protobuf/util/json_util.cc
+++ b/src/google/protobuf/util/json_util.cc
@@ -33,6 +33,7 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/once.h>
 #include <google/protobuf/util/internal/default_value_objectwriter.h>
 #include <google/protobuf/util/internal/error_listener.h>
 #include <google/protobuf/util/internal/json_objectwriter.h>
@@ -42,8 +43,12 @@
 #include <google/protobuf/util/type_resolver.h>
 #include <google/protobuf/util/type_resolver_util.h>
 #include <google/protobuf/stubs/bytestream.h>
+
+
 #include <google/protobuf/stubs/status_macros.h>
 
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 namespace util {
@@ -119,37 +124,51 @@
 namespace {
 class StatusErrorListener : public converter::ErrorListener {
  public:
-
   StatusErrorListener() {}
-  virtual ~StatusErrorListener() override {}
+  ~StatusErrorListener() override {}
 
   util::Status GetStatus() { return status_; }
 
   virtual void InvalidName(const converter::LocationTrackerInterface& loc,
-                   StringPiece unknown_name, StringPiece message) override {
-    status_ = util::Status(util::error::INVALID_ARGUMENT,
-                           loc.ToString() + ": invalid name " +
-                               string(unknown_name) + ": " + string(message));
+                           StringPiece unknown_name,
+                           StringPiece message) {
+    string loc_string = GetLocString(loc);
+    if (!loc_string.empty()) {
+      loc_string.append(" ");
+    }
+    status_ =
+        util::Status(util::error::INVALID_ARGUMENT,
+                       StrCat(loc_string, unknown_name, ": ", message));
   }
 
   virtual void InvalidValue(const converter::LocationTrackerInterface& loc,
-                    StringPiece type_name, StringPiece value) override {
-    status_ =
-        util::Status(util::error::INVALID_ARGUMENT,
-                       loc.ToString() + ": invalid value " + string(value) +
-                           " for type " + string(type_name));
+                            StringPiece type_name,
+                            StringPiece value) {
+    status_ = util::Status(
+        util::error::INVALID_ARGUMENT,
+        StrCat(GetLocString(loc), ": invalid value ", string(value),
+                     " for type ", string(type_name)));
   }
 
   virtual void MissingField(const converter::LocationTrackerInterface& loc,
-                    StringPiece missing_name) override {
-    status_ = util::Status(
-        util::error::INVALID_ARGUMENT,
-        loc.ToString() + ": missing field " + string(missing_name));
+                            StringPiece missing_name) {
+    status_ = util::Status(util::error::INVALID_ARGUMENT,
+                             StrCat(GetLocString(loc), ": missing field ",
+                                          string(missing_name)));
   }
 
  private:
   util::Status status_;
 
+  string GetLocString(const converter::LocationTrackerInterface& loc) {
+    string loc_string = loc.ToString();
+    StripWhitespace(&loc_string);
+    if (!loc_string.empty()) {
+      loc_string = StrCat("(", loc_string, ")");
+    }
+    return loc_string;
+  }
+
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StatusErrorListener);
 };
 }  // namespace
@@ -174,8 +193,8 @@
   int length;
   while (json_input->Next(&buffer, &length)) {
     if (length == 0) continue;
-    RETURN_IF_ERROR(
-        parser.Parse(StringPiece(static_cast<const char*>(buffer), length)));
+    RETURN_IF_ERROR(parser.Parse(
+        StringPiece(static_cast<const char*>(buffer), length)));
   }
   RETURN_IF_ERROR(parser.FinishParse());
 
@@ -184,7 +203,7 @@
 
 util::Status JsonToBinaryString(TypeResolver* resolver,
                                   const string& type_url,
-                                  const string& json_input,
+                                  StringPiece json_input,
                                   string* binary_output,
                                   const JsonParseOptions& options) {
   io::ArrayInputStream input_stream(json_input.data(), json_input.size());
@@ -196,7 +215,8 @@
 namespace {
 const char* kTypeUrlPrefix = "type.googleapis.com";
 TypeResolver* generated_type_resolver_ = NULL;
-GOOGLE_PROTOBUF_DECLARE_ONCE(generated_type_resolver_init_);
+GOOGLE_PROTOBUF_NAMESPACE_ID::internal::once_flag
+    generated_type_resolver_init_;
 
 string GetTypeUrl(const Message& message) {
   return string(kTypeUrlPrefix) + "/" + message.GetDescriptor()->full_name();
@@ -211,7 +231,8 @@
 }
 
 TypeResolver* GetGeneratedTypeResolver() {
-  ::google::protobuf::GoogleOnceInit(&generated_type_resolver_init_, &InitGeneratedTypeResolver);
+  GOOGLE_PROTOBUF_NAMESPACE_ID::internal::call_once(
+      generated_type_resolver_init_, InitGeneratedTypeResolver);
   return generated_type_resolver_;
 }
 }  // namespace
@@ -232,7 +253,7 @@
   return result;
 }
 
-util::Status JsonStringToMessage(const string& input, Message* message,
+util::Status JsonStringToMessage(StringPiece input, Message* message,
                                    const JsonParseOptions& options) {
   const DescriptorPool* pool = message->GetDescriptor()->file()->pool();
   TypeResolver* resolver =
diff --git a/src/google/protobuf/util/json_util.h b/src/google/protobuf/util/json_util.h
index e786830..96809a4 100644
--- a/src/google/protobuf/util/json_util.h
+++ b/src/google/protobuf/util/json_util.h
@@ -37,6 +37,7 @@
 #include <google/protobuf/util/type_resolver.h>
 #include <google/protobuf/stubs/bytestream.h>
 
+
 namespace google {
 namespace protobuf {
 namespace io {
@@ -77,9 +78,9 @@
 // DEPRECATED. Use JsonPrintOptions instead.
 typedef JsonPrintOptions JsonOptions;
 
-// Converts from protobuf message to JSON. This is a simple wrapper of
-// BinaryToJsonString(). It will use the DescriptorPool of the passed-in
-// message to resolve Any types.
+// Converts from protobuf message to JSON and appends it to |output|. This is a
+// simple wrapper of BinaryToJsonString(). It will use the DescriptorPool of the
+// passed-in message to resolve Any types.
 LIBPROTOBUF_EXPORT util::Status MessageToJsonString(const Message& message,
                                    string* output,
                                    const JsonOptions& options);
@@ -92,11 +93,10 @@
 // Converts from JSON to protobuf message. This is a simple wrapper of
 // JsonStringToBinary(). It will use the DescriptorPool of the passed-in
 // message to resolve Any types.
-LIBPROTOBUF_EXPORT util::Status JsonStringToMessage(const string& input,
-                                   Message* message,
+LIBPROTOBUF_EXPORT util::Status JsonStringToMessage(StringPiece input, Message* message,
                                    const JsonParseOptions& options);
 
-inline util::Status JsonStringToMessage(const string& input,
+inline util::Status JsonStringToMessage(StringPiece input,
                                           Message* message) {
   return JsonStringToMessage(input, message, JsonParseOptions());
 }
@@ -158,18 +158,16 @@
                             JsonParseOptions());
 }
 
-LIBPROTOBUF_EXPORT util::Status JsonToBinaryString(
-    TypeResolver* resolver,
-    const string& type_url,
-    const string& json_input,
-    string* binary_output,
-    const JsonParseOptions& options);
+LIBPROTOBUF_EXPORT util::Status JsonToBinaryString(TypeResolver* resolver,
+                                  const string& type_url,
+                                  StringPiece json_input,
+                                  string* binary_output,
+                                  const JsonParseOptions& options);
 
-inline util::Status JsonToBinaryString(
-    TypeResolver* resolver,
-    const string& type_url,
-    const string& json_input,
-    string* binary_output) {
+inline util::Status JsonToBinaryString(TypeResolver* resolver,
+                                         const string& type_url,
+                                         StringPiece json_input,
+                                         string* binary_output) {
   return JsonToBinaryString(resolver, type_url, json_input, binary_output,
                             JsonParseOptions());
 }
@@ -182,7 +180,7 @@
       : stream_(stream), buffer_(NULL), buffer_size_(0) {}
   ~ZeroCopyStreamByteSink();
 
-  virtual void Append(const char* bytes, size_t len) override;
+  void Append(const char* bytes, size_t len) override;
 
  private:
   io::ZeroCopyOutputStream* stream_;
@@ -195,6 +193,6 @@
 
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__
diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc
index a2a84b5..cbfc7ad 100644
--- a/src/google/protobuf/util/json_util_test.cc
+++ b/src/google/protobuf/util/json_util_test.cc
@@ -38,6 +38,7 @@
 #include <google/protobuf/descriptor_database.h>
 #include <google/protobuf/dynamic_message.h>
 #include <google/protobuf/util/internal/testdata/maps.pb.h>
+#include <google/protobuf/util/json_format.pb.h>
 #include <google/protobuf/util/json_format_proto3.pb.h>
 #include <google/protobuf/util/type_resolver.h>
 #include <google/protobuf/util/type_resolver_util.h>
@@ -49,12 +50,12 @@
 namespace {
 
 using google::protobuf::testing::MapIn;
-using proto3::FOO;
 using proto3::BAR;
-using proto3::TestMessage;
-using proto3::TestMap;
-using proto3::TestOneof;
+using proto3::FOO;
 using proto3::TestEnumValue;
+using proto3::TestMap;
+using proto3::TestMessage;
+using proto3::TestOneof;
 
 static const char kTypeUrlPrefix[] = "type.googleapis.com";
 
@@ -220,7 +221,7 @@
 
 TEST_F(JsonUtilTest, TestPrintEnumsAsIntsWithDefaultValue) {
   TestEnumValue orig;
-  //orig.set_enum_value1(proto3::FOO)
+  // orig.set_enum_value1(proto3::FOO)
   orig.set_enum_value2(proto3::FOO);
   orig.set_enum_value3(proto3::BAR);
 
@@ -238,7 +239,6 @@
   EXPECT_EQ(proto3::FOO, parsed.enum_value1());
   EXPECT_EQ(proto3::FOO, parsed.enum_value2());
   EXPECT_EQ(proto3::BAR, parsed.enum_value3());
-
 }
 
 TEST_F(JsonUtilTest, ParseMessage) {
@@ -357,30 +357,44 @@
   EXPECT_EQ(ToJson(generated, options), ToJson(*message, options));
 }
 
-TEST_F(JsonUtilTest, TestParsingUnknownEnumsAs0) {
+TEST_F(JsonUtilTest, TestParsingUnknownEnumsProto2) {
+  string input =
+      "{\n"
+      "  \"a\": \"UNKNOWN_VALUE\"\n"
+      "}";
+  TestNumbers m;
+  JsonParseOptions options;
+  EXPECT_FALSE(FromJson(input, &m, options));
+
+  options.ignore_unknown_fields = true;
+  EXPECT_TRUE(FromJson(input, &m, options));
+  EXPECT_FALSE(m.has_a());
+}
+
+TEST_F(JsonUtilTest, TestParsingUnknownEnumsProto3) {
   TestMessage m;
   {
     JsonParseOptions options;
     ASSERT_FALSE(options.ignore_unknown_fields);
     string input =
-      "{\n"
-      "  \"enum_value\":\"UNKNOWN_VALUE\"\n"
-      "}";
+        "{\n"
+        "  \"enum_value\":\"UNKNOWN_VALUE\"\n"
+        "}";
     m.set_enum_value(proto3::BAR);
     EXPECT_FALSE(FromJson(input, &m, options));
-    ASSERT_EQ(proto3::BAR, m.enum_value()); // Keep previous value
+    ASSERT_EQ(proto3::BAR, m.enum_value());  // Keep previous value
 
     options.ignore_unknown_fields = true;
     EXPECT_TRUE(FromJson(input, &m, options));
-    EXPECT_EQ(0, m.enum_value()); // Unknown enum value must be decoded as 0
+    EXPECT_EQ(0, m.enum_value());  // Unknown enum value must be decoded as 0
   }
   // Integer values are read as usual
   {
     JsonParseOptions options;
     string input =
-      "{\n"
-      "  \"enum_value\":12345\n"
-      "}";
+        "{\n"
+        "  \"enum_value\":12345\n"
+        "}";
     m.set_enum_value(proto3::BAR);
     EXPECT_TRUE(FromJson(input, &m, options));
     ASSERT_EQ(12345, m.enum_value());
@@ -390,25 +404,27 @@
     EXPECT_EQ(12345, m.enum_value());
   }
 
-  // Trying to pass an object as an enum field value is always treated as an error
+  // Trying to pass an object as an enum field value is always treated as an
+  // error
   {
     JsonParseOptions options;
     string input =
-      "{\n"
-      "  \"enum_value\":{}\n"
-      "}";
+        "{\n"
+        "  \"enum_value\":{}\n"
+        "}";
     options.ignore_unknown_fields = true;
     EXPECT_FALSE(FromJson(input, &m, options));
     options.ignore_unknown_fields = false;
     EXPECT_FALSE(FromJson(input, &m, options));
   }
-  // Trying to pass an array as an enum field value is always treated as an error
+  // Trying to pass an array as an enum field value is always treated as an
+  // error
   {
     JsonParseOptions options;
     string input =
-      "{\n"
-      "  \"enum_value\":[]\n"
-      "}";
+        "{\n"
+        "  \"enum_value\":[]\n"
+        "}";
     EXPECT_FALSE(FromJson(input, &m, options));
     options.ignore_unknown_fields = true;
     EXPECT_FALSE(FromJson(input, &m, options));
@@ -559,6 +575,13 @@
             util::error::INVALID_ARGUMENT);
 }
 
+TEST_F(JsonUtilTest, HtmlEscape) {
+  TestMessage m;
+  m.set_string_value("</script>");
+  JsonPrintOptions options;
+  EXPECT_EQ("{\"stringValue\":\"\\u003c/script\\u003e\"}", ToJson(m, options));
+}
+
 }  // namespace
 }  // namespace util
 }  // namespace protobuf
diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc
index 7d3976f..8a09400 100644
--- a/src/google/protobuf/util/message_differencer.cc
+++ b/src/google/protobuf/util/message_differencer.cc
@@ -31,10 +31,6 @@
 // Author: jschorr@google.com (Joseph Schorr)
 //  Based on original Protocol Buffers design by
 //  Sanjay Ghemawat, Jeff Dean, and others.
-//
-// This file defines static methods and classes for comparing Protocol
-// Messages (see //google/protobuf/util/message_differencer.h for more
-// information).
 
 #include <google/protobuf/util/message_differencer.h>
 
@@ -56,6 +52,7 @@
 #include <google/protobuf/util/field_comparator.h>
 #include <google/protobuf/stubs/strutil.h>
 
+
 namespace google {
 namespace protobuf {
 
@@ -87,10 +84,8 @@
     key_field_path.push_back(key);
     key_field_paths_.push_back(key_field_path);
   }
-  virtual bool IsMatch(
-      const Message& message1,
-      const Message& message2,
-      const std::vector<SpecificField>& parent_fields) const override {
+  bool IsMatch(const Message& message1, const Message& message2,
+               const std::vector<SpecificField>& parent_fields) const override {
     for (int i = 0; i < key_field_paths_.size(); ++i) {
       if (!IsMatchInternal(message1, message2, parent_fields,
                            key_field_paths_[i], 0)) {
@@ -99,6 +94,7 @@
     }
     return true;
   }
+
  private:
   bool IsMatchInternal(
       const Message& message1,
@@ -218,6 +214,7 @@
       map_entry_key_comparator_(this),
       report_matches_(false),
       report_moves_(true),
+      report_ignores_(true),
       output_string_(NULL) {}
 
 MessageDifferencer::~MessageDifferencer() {
@@ -533,9 +530,9 @@
   bool unknown_compare_result = true;
   // Ignore unknown fields in EQUIVALENT mode
   if (message_field_comparison_ != EQUIVALENT) {
-    const google::protobuf::UnknownFieldSet* unknown_field_set1 =
+    const UnknownFieldSet* unknown_field_set1 =
         &reflection1->GetUnknownFields(message1);
-    const google::protobuf::UnknownFieldSet* unknown_field_set2 =
+    const UnknownFieldSet* unknown_field_set2 =
         &reflection2->GetUnknownFields(message2);
     if (!CompareUnknownFields(message1, message2,
                               *unknown_field_set1, *unknown_field_set2,
@@ -660,7 +657,9 @@
           specific_field.field = field1;
 
           parent_fields->push_back(specific_field);
-          reporter_->ReportIgnored(message1, message2, *parent_fields);
+          if (report_ignores_) {
+            reporter_->ReportIgnored(message1, message2, *parent_fields);
+          }
           parent_fields->pop_back();
         }
         ++field_index1;
@@ -699,7 +698,9 @@
           specific_field.field = field2;
 
           parent_fields->push_back(specific_field);
-          reporter_->ReportIgnored(message1, message2, *parent_fields);
+          if (report_ignores_) {
+            reporter_->ReportIgnored(message1, message2, *parent_fields);
+          }
           parent_fields->pop_back();
         }
         ++field_index2;
@@ -739,7 +740,9 @@
         specific_field.field = field1;
 
         parent_fields->push_back(specific_field);
-        reporter_->ReportIgnored(message1, message2, *parent_fields);
+        if (report_ignores_) {
+          reporter_->ReportIgnored(message1, message2, *parent_fields);
+        }
         parent_fields->pop_back();
       }
 
@@ -1078,7 +1081,7 @@
     return false;
   }
 
-  const google::protobuf::Descriptor* desc =
+  const Descriptor* desc =
       any.GetDescriptor()->file()->pool()->FindMessageTypeByName(
           full_type_name);
   if (desc == NULL) {
@@ -1100,8 +1103,8 @@
 
 bool MessageDifferencer::CompareUnknownFields(
     const Message& message1, const Message& message2,
-    const google::protobuf::UnknownFieldSet& unknown_field_set1,
-    const google::protobuf::UnknownFieldSet& unknown_field_set2,
+    const UnknownFieldSet& unknown_field_set1,
+    const UnknownFieldSet& unknown_field_set2,
     std::vector<SpecificField>* parent_field) {
   // Ignore unknown fields in EQUIVALENT mode.
   if (message_field_comparison_ == EQUIVALENT) return true;
@@ -1434,6 +1437,13 @@
   match_list1->assign(count1, -1);
   match_list2->assign(count2, -1);
 
+  // Ensure that we don't report differences during the matching process. Since
+  // field comparators could potentially use this message differencer object to
+  // perform further comparisons, turn off reporting here and re-enable it
+  // before returning.
+  Reporter* reporter = reporter_;
+  reporter_ = NULL;
+
   bool success = true;
   // Find potential match if this is a special repeated field.
   if (key_comparator != NULL || IsTreatedAsSet(repeated_field)) {
@@ -1451,9 +1461,9 @@
                              match_list2);
       // If diff info is not needed, we should end the matching process as
       // soon as possible if not all items can be matched.
-      bool early_return = (reporter_ == NULL);
+      bool early_return = (reporter == NULL);
       int match_count = matcher.FindMaximumMatch(early_return);
-      if (match_count != count1 && reporter_ == NULL) return false;
+      if (match_count != count1 && reporter == NULL) return false;
       success = success && (match_count == count1);
     } else {
       int start_offset = 0;
@@ -1488,7 +1498,7 @@
             break;
           }
         }
-        if (!match && reporter_ == NULL) return false;
+        if (!match && reporter == NULL) return false;
         success = success && match;
       }
     }
@@ -1500,6 +1510,8 @@
     }
   }
 
+  reporter_ = reporter;
+
   return success;
 }
 
@@ -1567,13 +1579,16 @@
         continue;
       }
     } else {
-      printer_->PrintRaw(SimpleItoa(specific_field.unknown_field_number));
+      printer_->PrintRaw(
+          SimpleItoa(specific_field.unknown_field_number));
     }
     if (left_side && specific_field.index >= 0) {
-      printer_->Print("[$name$]", "name", SimpleItoa(specific_field.index));
+      printer_->Print("[$name$]", "name",
+                      SimpleItoa(specific_field.index));
     }
     if (!left_side && specific_field.new_index >= 0) {
-      printer_->Print("[$name$]", "name", SimpleItoa(specific_field.new_index));
+      printer_->Print("[$name$]", "name",
+                      SimpleItoa(specific_field.new_index));
     }
   }
 }
@@ -1631,12 +1646,12 @@
       output = SimpleItoa(unknown_field->varint());
       break;
     case UnknownField::TYPE_FIXED32:
-      output = StrCat("0x", strings::Hex(unknown_field->fixed32(),
-                                         strings::ZERO_PAD_8));
+      output = StrCat(
+          "0x", strings::Hex(unknown_field->fixed32(), strings::ZERO_PAD_8));
       break;
     case UnknownField::TYPE_FIXED64:
-      output = StrCat("0x", strings::Hex(unknown_field->fixed64(),
-                                         strings::ZERO_PAD_16));
+      output = StrCat(
+          "0x", strings::Hex(unknown_field->fixed64(), strings::ZERO_PAD_16));
       break;
     case UnknownField::TYPE_LENGTH_DELIMITED:
       output = StringPrintf("\"%s\"",
diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h
index b3e6551..0c2174b 100644
--- a/src/google/protobuf/util/message_differencer.h
+++ b/src/google/protobuf/util/message_differencer.h
@@ -60,7 +60,7 @@
 namespace io {
 class ZeroCopyOutputStream;
 class Printer;
-}
+}  // namespace io
 
 namespace util {
 
@@ -533,6 +533,12 @@
     report_moves_ = report_moves;
   }
 
+  // Tells the differencer whether or not to report ignored values. This method
+  // must be called before Compare. The default for a new differencer is true.
+  void set_report_ignores(bool report_ignores) {
+    report_ignores_ = report_ignores;
+  }
+
   // Sets the scope of the comparison (as defined in the Scope enumeration
   // above) that is used by this differencer when determining which fields to
   // compare between the messages.
@@ -597,7 +603,7 @@
    public:
     explicit StreamReporter(io::ZeroCopyOutputStream* output);
     explicit StreamReporter(io::Printer* printer);  // delimiter '$'
-    virtual ~StreamReporter() override;
+    ~StreamReporter() override;
 
     // When set to true, the stream reporter will also output aggregates nodes
     // (i.e. messages and groups) whose subfields have been modified. When
@@ -608,28 +614,23 @@
 
     // The following are implementations of the methods described above.
 
-    virtual void ReportAdded(const Message& message1, const Message& message2,
-                             const std::vector<SpecificField>& field_path) override;
+    void ReportAdded(const Message& message1, const Message& message2,
+                     const std::vector<SpecificField>& field_path) override;
 
-    virtual void ReportDeleted(const Message& message1,
-                               const Message& message2,
-                               const std::vector<SpecificField>& field_path) override;
+    void ReportDeleted(const Message& message1, const Message& message2,
+                       const std::vector<SpecificField>& field_path) override;
 
-    virtual void ReportModified(const Message& message1,
-                                const Message& message2,
-                                const std::vector<SpecificField>& field_path) override;
+    void ReportModified(const Message& message1, const Message& message2,
+                        const std::vector<SpecificField>& field_path) override;
 
-    virtual void ReportMoved(const Message& message1,
-                             const Message& message2,
-                             const std::vector<SpecificField>& field_path) override;
+    void ReportMoved(const Message& message1, const Message& message2,
+                     const std::vector<SpecificField>& field_path) override;
 
-    virtual void ReportMatched(const Message& message1,
-                               const Message& message2,
-                               const std::vector<SpecificField>& field_path) override;
+    void ReportMatched(const Message& message1, const Message& message2,
+                       const std::vector<SpecificField>& field_path) override;
 
-    virtual void ReportIgnored(const Message& message1,
-                               const Message& message2,
-                               const std::vector<SpecificField>& field_path) override;
+    void ReportIgnored(const Message& message1, const Message& message2,
+                       const std::vector<SpecificField>& field_path) override;
 
     void ReportUnknownFieldIgnored(
         const Message& message1, const Message& message2,
@@ -681,8 +682,9 @@
   class LIBPROTOBUF_EXPORT MapEntryKeyComparator : public MapKeyComparator {
    public:
     explicit MapEntryKeyComparator(MessageDifferencer* message_differencer);
-    virtual bool IsMatch(const Message& message1, const Message& message2,
-                         const std::vector<SpecificField>& parent_fields) const override;
+    bool IsMatch(
+        const Message& message1, const Message& message2,
+        const std::vector<SpecificField>& parent_fields) const override;
 
    private:
     MessageDifferencer* message_differencer_;
@@ -712,8 +714,7 @@
 
   // Compares all the unknown fields in two messages.
   bool CompareUnknownFields(const Message& message1, const Message& message2,
-                            const google::protobuf::UnknownFieldSet&,
-                            const google::protobuf::UnknownFieldSet&,
+                            const UnknownFieldSet&, const UnknownFieldSet&,
                             std::vector<SpecificField>* parent_fields);
 
   // Compares the specified messages for the requested field lists. The field
@@ -860,6 +861,7 @@
 
   bool report_matches_;
   bool report_moves_;
+  bool report_ignores_;
 
   string* output_string_;
 
@@ -883,8 +885,8 @@
   std::vector<MessageDifferencer::SpecificField>* parent_fields_;
 };
 
-}
-}
-
+}  // namespace util
+}  // namespace protobuf
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__
diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc
index a263d98..1f50ea2 100644
--- a/src/google/protobuf/util/message_differencer_unittest.cc
+++ b/src/google/protobuf/util/message_differencer_unittest.cc
@@ -1936,6 +1936,45 @@
   EXPECT_TRUE(differencer.CompareWithFields(msg1, msg2, fields, fields));
 }
 
+TEST(MessageDifferencerTest, IgnoreField_SetReportIgnoresFalse) {
+  protobuf_unittest::TestField msg1;
+  protobuf_unittest::TestField msg2;
+
+  msg1.set_a(1);
+  msg1.set_b(2);
+  msg1.set_c(3);
+  msg1.add_rc(1);
+  msg1.add_rc(2);
+
+  msg2.set_a(1);
+  msg2.set_b(1);
+
+  const FieldDescriptor* a = GetFieldDescriptor(msg1, "a");
+  const FieldDescriptor* b = GetFieldDescriptor(msg1, "b");
+  const FieldDescriptor* c = GetFieldDescriptor(msg1, "c");
+  const FieldDescriptor* rc = GetFieldDescriptor(msg1, "rc");
+
+  std::vector<const FieldDescriptor*> fields;
+  fields.push_back(a);
+  fields.push_back(b);
+  fields.push_back(c);
+  fields.push_back(rc);
+
+  string diff_report;
+  util::MessageDifferencer differencer;
+  differencer.set_report_ignores(false);
+  differencer.set_report_matches(true);
+  differencer.ReportDifferencesToString(&diff_report);
+  differencer.IgnoreField(c);
+  differencer.IgnoreField(rc);
+  differencer.set_scope(util::MessageDifferencer::FULL);
+  EXPECT_FALSE(differencer.CompareWithFields(msg1, msg2, fields, fields));
+
+  EXPECT_EQ(diff_report,
+            "matched: a : 1\n"
+            "modified: b: 2 -> 1\n");
+}
+
 
 // Test class to save a copy of the last field_context.parent_fields() vector
 // passed to the comparison function.
@@ -1943,12 +1982,11 @@
  public:
   ParentSavingFieldComparator() {}
 
-  virtual ComparisonResult Compare(
-      const google::protobuf::Message& message_1,
-      const google::protobuf::Message& message_2,
-      const google::protobuf::FieldDescriptor* field,
-      int index_1, int index_2,
-      const google::protobuf::util::FieldContext* field_context) {
+  virtual ComparisonResult Compare(const Message& message_1,
+                                   const Message& message_2,
+                                   const FieldDescriptor* field, int index_1,
+                                   int index_2,
+                                   const util::FieldContext* field_context) {
     if (field_context)
       parent_fields_ = *(field_context->parent_fields());
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
@@ -1958,12 +1996,12 @@
     }
   }
 
-  std::vector<google::protobuf::util::MessageDifferencer::SpecificField> parent_fields() {
+  std::vector<util::MessageDifferencer::SpecificField> parent_fields() {
     return parent_fields_;
   }
 
  private:
-  std::vector<google::protobuf::util::MessageDifferencer::SpecificField> parent_fields_;
+  std::vector<util::MessageDifferencer::SpecificField> parent_fields_;
 };
 
 // Tests if MessageDifferencer sends the parent fields in the FieldContext
@@ -2894,7 +2932,7 @@
 }
 
 TEST_F(ComparisonTest, MapRoundTripSyncTest) {
-  google::protobuf::TextFormat::Parser parser;
+  TextFormat::Parser parser;
   unittest::TestMap map_reflection1;
 
   // By setting via reflection, data exists in repeated field.
@@ -2910,7 +2948,7 @@
 }
 
 TEST_F(ComparisonTest, MapEntryPartialTest) {
-  google::protobuf::TextFormat::Parser parser;
+  TextFormat::Parser parser;
   unittest::TestMap map1;
   unittest::TestMap map2;
 
@@ -2932,7 +2970,7 @@
 }
 
 TEST_F(ComparisonTest, MapEntryPartialEmptyKeyTest) {
-  google::protobuf::TextFormat::Parser parser;
+  TextFormat::Parser parser;
   unittest::TestMap map1;
   unittest::TestMap map2;
   ASSERT_TRUE(parser.ParseFromString("map_int32_foreign_message {}", &map1));
@@ -2961,7 +2999,7 @@
 };
 
 TEST_F(ComparisonTest, MapEntryCustomMapKeyComparator) {
-  google::protobuf::TextFormat::Parser parser;
+  TextFormat::Parser parser;
   protobuf_unittest::TestMap msg1;
   protobuf_unittest::TestMap msg2;
 
diff --git a/src/google/protobuf/util/time_util.cc b/src/google/protobuf/util/time_util.cc
index d491283..9321a23 100644
--- a/src/google/protobuf/util/time_util.cc
+++ b/src/google/protobuf/util/time_util.cc
@@ -38,6 +38,8 @@
 #include <google/protobuf/timestamp.pb.h>
 
 
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 namespace util {
@@ -368,12 +370,13 @@
 
 }  // namespace util
 }  // namespace protobuf
+}  // namespace google
 
-
+namespace google {
 namespace protobuf {
 namespace {
-using google::protobuf::util::kNanosPerSecond;
-using google::protobuf::util::CreateNormalized;
+using ::GOOGLE_PROTOBUF_NAMESPACE_ID::util::CreateNormalized;
+using ::GOOGLE_PROTOBUF_NAMESPACE_ID::util::kNanosPerSecond;
 
 // Convert a Duration to uint128.
 void ToUint128(const Duration& value, uint128* result, bool* negative) {
@@ -389,7 +392,8 @@
 }
 
 void ToDuration(const uint128& value, bool negative, Duration* duration) {
-  int64 seconds = static_cast<int64>(Uint128Low64(value / kNanosPerSecond));
+  int64 seconds =
+      static_cast<int64>(Uint128Low64(value / kNanosPerSecond));
   int32 nanos = static_cast<int32>(Uint128Low64(value % kNanosPerSecond));
   if (negative) {
     seconds = -seconds;
@@ -501,5 +505,4 @@
                                     t1.nanos() - t2.nanos());
 }
 }  // namespace protobuf
-
 }  // namespace google
diff --git a/src/google/protobuf/util/time_util.h b/src/google/protobuf/util/time_util.h
index b884693..b0e1917 100644
--- a/src/google/protobuf/util/time_util.h
+++ b/src/google/protobuf/util/time_util.h
@@ -45,6 +45,8 @@
 #include <google/protobuf/duration.pb.h>
 #include <google/protobuf/timestamp.pb.h>
 
+#include <google/protobuf/port_def.inc>
+
 namespace google {
 namespace protobuf {
 namespace util {
@@ -156,8 +158,9 @@
 
 }  // namespace util
 }  // namespace protobuf
+}  // namespace google
 
-
+namespace google {
 namespace protobuf {
 // Overloaded operators for Duration.
 //
@@ -238,7 +241,7 @@
 }
 
 inline std::ostream& operator<<(std::ostream& out, const Duration& d) {
-  out << google::protobuf::util::TimeUtil::ToString(d);
+  out << ::GOOGLE_PROTOBUF_NAMESPACE_ID::util::TimeUtil::ToString(d);
   return out;
 }
 
@@ -285,12 +288,13 @@
 LIBPROTOBUF_EXPORT Duration operator-(const Timestamp& t1, const Timestamp& t2);
 
 inline std::ostream& operator<<(std::ostream& out, const Timestamp& t) {
-  out << google::protobuf::util::TimeUtil::ToString(t);
+  out << ::GOOGLE_PROTOBUF_NAMESPACE_ID::util::TimeUtil::ToString(t);
   return out;
 }
 
 }  // namespace protobuf
-
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
diff --git a/src/google/protobuf/util/type_resolver.h b/src/google/protobuf/util/type_resolver.h
index 959f3c7..9c9a744 100644
--- a/src/google/protobuf/util/type_resolver.h
+++ b/src/google/protobuf/util/type_resolver.h
@@ -38,14 +38,14 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/status.h>
 
-
 namespace google {
 namespace protobuf {
 class Type;
 class Enum;
 }  // namespace protobuf
+}  // namespace google
 
-
+namespace google {
 namespace protobuf {
 class DescriptorPool;
 namespace util {
@@ -72,6 +72,6 @@
 
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__
diff --git a/src/google/protobuf/util/type_resolver_util.cc b/src/google/protobuf/util/type_resolver_util.cc
index aa48ef6..3a3eba4 100644
--- a/src/google/protobuf/util/type_resolver_util.cc
+++ b/src/google/protobuf/util/type_resolver_util.cc
@@ -37,6 +37,7 @@
 #include <google/protobuf/util/internal/utility.h>
 #include <google/protobuf/util/type_resolver.h>
 #include <google/protobuf/stubs/strutil.h>
+
 #include <google/protobuf/stubs/status.h>
 
 namespace google {
@@ -179,9 +180,10 @@
 
   Status ParseTypeUrl(const string& type_url, string* type_name) {
     if (type_url.substr(0, url_prefix_.size() + 1) != url_prefix_ + "/") {
-      return Status(INVALID_ARGUMENT,
-                    StrCat("Invalid type URL, type URLs must be of the form '",
-                           url_prefix_, "/<typename>', got: ", type_url));
+      return Status(
+          INVALID_ARGUMENT,
+          StrCat("Invalid type URL, type URLs must be of the form '",
+                       url_prefix_, "/<typename>', got: ", type_url));
     }
     *type_name = type_url.substr(url_prefix_.size() + 1);
     return Status();
diff --git a/src/google/protobuf/util/type_resolver_util.h b/src/google/protobuf/util/type_resolver_util.h
index c17366f..c512e6f 100644
--- a/src/google/protobuf/util/type_resolver_util.h
+++ b/src/google/protobuf/util/type_resolver_util.h
@@ -49,6 +49,6 @@
 
 }  // namespace util
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__
diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc
index 3fdf84e..0342a10 100644
--- a/src/google/protobuf/wire_format.cc
+++ b/src/google/protobuf/wire_format.cc
@@ -48,13 +48,14 @@
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/dynamic_message.h>
 #include <google/protobuf/map_field.h>
+#include <google/protobuf/map_field_inl.h>
 #include <google/protobuf/unknown_field_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 
 
-namespace google {
 const size_t kMapEntryTagByteSize = 2;
 
+namespace google {
 namespace protobuf {
 namespace internal {
 
@@ -172,8 +173,8 @@
   io::CodedInputStream::Limit limit = input->PushLimit(length);
   while (input->BytesUntilLimit() > 0) {
     int value;
-    if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
-        int, WireFormatLite::TYPE_ENUM>(input, &value)) {
+    if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+            input, &value)) {
       return false;
     }
     if (is_valid == NULL || is_valid(value)) {
@@ -617,31 +618,10 @@
         int value;
         if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
                 input, &value)) return false;
-        if (message->GetDescriptor()->file()->syntax() ==
-            FileDescriptor::SYNTAX_PROTO3) {
-          if (field->is_repeated()) {
-            message_reflection->AddEnumValue(message, field, value);
-          } else {
-            message_reflection->SetEnumValue(message, field, value);
-          }
+        if (field->is_repeated()) {
+          message_reflection->AddEnumValue(message, field, value);
         } else {
-          const EnumValueDescriptor* enum_value =
-              field->enum_type()->FindValueByNumber(value);
-          if (enum_value != NULL) {
-            if (field->is_repeated()) {
-              message_reflection->AddEnum(message, field, enum_value);
-            } else {
-              message_reflection->SetEnum(message, field, enum_value);
-            }
-          } else {
-            // The enum value is not one of the known values.  Add it to the
-            // UnknownFieldSet.
-            int64 sign_extended_value = static_cast<int64>(value);
-            message_reflection->MutableUnknownFields(message)
-                              ->AddVarint(
-                                  WireFormatLite::GetTagFieldNumber(tag),
-                                  sign_extended_value);
-          }
+          message_reflection->SetEnumValue(message, field, value);
         }
         break;
       }
@@ -718,80 +698,23 @@
 bool WireFormat::ParseAndMergeMessageSetItem(
     io::CodedInputStream* input,
     Message* message) {
-  const Reflection* message_reflection = message->GetReflection();
-
-  // This method parses a group which should contain two fields:
-  //   required int32 type_id = 2;
-  //   required data message = 3;
-
-  uint32 last_type_id = 0;
-
-  // Once we see a type_id, we'll look up the FieldDescriptor for the
-  // extension.
-  const FieldDescriptor* field = NULL;
-
-  // If we see message data before the type_id, we'll append it to this so
-  // we can parse it later.
-  string message_data;
-
-  while (true) {
-    uint32 tag = input->ReadTag();
-    if (tag == 0) return false;
-
-    switch (tag) {
-      case WireFormatLite::kMessageSetTypeIdTag: {
-        uint32 type_id;
-        if (!input->ReadVarint32(&type_id)) return false;
-        last_type_id = type_id;
-        field = message_reflection->FindKnownExtensionByNumber(type_id);
-
-        if (!message_data.empty()) {
-          // We saw some message data before the type_id.  Have to parse it
-          // now.
-          io::ArrayInputStream raw_input(message_data.data(),
-                                         message_data.size());
-          io::CodedInputStream sub_input(&raw_input);
-          if (!ParseAndMergeMessageSetField(last_type_id, field, message,
-                                            &sub_input)) {
-            return false;
-          }
-          message_data.clear();
-        }
-
-        break;
-      }
-
-      case WireFormatLite::kMessageSetMessageTag: {
-        if (last_type_id == 0) {
-          // We haven't seen a type_id yet.  Append this data to message_data.
-          string temp;
-          uint32 length;
-          if (!input->ReadVarint32(&length)) return false;
-          if (!input->ReadString(&temp, length)) return false;
-          io::StringOutputStream output_stream(&message_data);
-          io::CodedOutputStream coded_output(&output_stream);
-          coded_output.WriteVarint32(length);
-          coded_output.WriteString(temp);
-        } else {
-          // Already saw type_id, so we can parse this directly.
-          if (!ParseAndMergeMessageSetField(last_type_id, field, message,
-                                            input)) {
-            return false;
-          }
-        }
-
-        break;
-      }
-
-      case WireFormatLite::kMessageSetItemEndTag: {
-        return true;
-      }
-
-      default: {
-        if (!SkipField(input, tag, NULL)) return false;
-      }
+  struct MSReflective {
+    bool ParseField(int type_id, io::CodedInputStream* input) {
+      const FieldDescriptor* field =
+          message_reflection->FindKnownExtensionByNumber(type_id);
+      return ParseAndMergeMessageSetField(type_id, field, message, input);
     }
-  }
+
+    bool SkipField(uint32 tag, io::CodedInputStream* input) {
+      return WireFormat::SkipField(input, tag, NULL);
+    }
+
+    const Reflection* message_reflection;
+    Message* message;
+  };
+
+  return ParseMessageSetItemImpl(
+      input, MSReflective{message->GetReflection(), message});
 }
 
 // ===================================================================
diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h
index 36f4a0b..5bdb127 100644
--- a/src/google/protobuf/wire_format.h
+++ b/src/google/protobuf/wire_format.h
@@ -44,16 +44,23 @@
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/message.h>
 #include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/stubs/casts.h>
+
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
 
 namespace google {
 namespace protobuf {
-  namespace io {
-    class CodedInputStream;      // coded_stream.h
-    class CodedOutputStream;     // coded_stream.h
-  }
-  class UnknownFieldSet;         // unknown_field_set.h
-}
+namespace io {
+class CodedInputStream;   // coded_stream.h
+class CodedOutputStream;  // coded_stream.h
+}  // namespace io
+class UnknownFieldSet;  // unknown_field_set.h
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace internal {
 
@@ -68,7 +75,6 @@
 // This class is really a namespace that contains only static methods
 class LIBPROTOBUF_EXPORT WireFormat {
  public:
-
   // Given a field return its WireType
   static inline WireFormatLite::WireType WireTypeForField(
       const FieldDescriptor* field);
@@ -107,9 +113,8 @@
   // a parameter to this procedure.
   //
   // These return false iff the underlying stream returns a write error.
-  static void SerializeWithCachedSizes(
-      const Message& message,
-      int size, io::CodedOutputStream* output);
+  static void SerializeWithCachedSizes(const Message& message, int size,
+                                       io::CodedOutputStream* output);
 
   // Implements Message::ByteSize() via reflection.  WARNING:  The result
   // of this method is *not* cached anywhere.  However, all embedded messages
@@ -127,13 +132,14 @@
   static bool SkipField(io::CodedInputStream* input, uint32 tag,
                         UnknownFieldSet* unknown_fields);
 
-  // Reads and ignores a message from the input.  If unknown_fields is non-NULL,
-  // the contents will be added to it.
+  // Reads and ignores a message from the input.  If unknown_fields is
+  // non-NULL, the contents will be added to it.
   static bool SkipMessage(io::CodedInputStream* input,
                           UnknownFieldSet* unknown_fields);
 
-  // Read a packed enum field. If the is_valid function is not NULL, values for
-  // which is_valid(value) returns false are appended to unknown_fields_stream.
+  // Read a packed enum field. If the is_valid function is not NULL, values
+  // for which is_valid(value) returns false are appended to
+  // unknown_fields_stream.
   static bool ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input,
                                              uint32 field_number,
                                              bool (*is_valid)(int),
@@ -149,22 +155,19 @@
   //
   // Returns a pointer past the last written byte.
   static uint8* SerializeUnknownFieldsToArray(
-      const UnknownFieldSet& unknown_fields,
-      uint8* target);
+      const UnknownFieldSet& unknown_fields, uint8* target);
 
   // Same thing except for messages that have the message_set_wire_format
   // option.
   static void SerializeUnknownMessageSetItems(
-      const UnknownFieldSet& unknown_fields,
-      io::CodedOutputStream* output);
+      const UnknownFieldSet& unknown_fields, io::CodedOutputStream* output);
   // Same as above, except writing directly to the provided buffer.
   // Requires that the buffer have sufficient capacity for
   // ComputeUnknownMessageSetItemsSize(unknown_fields).
   //
   // Returns a pointer past the last written byte.
   static uint8* SerializeUnknownMessageSetItemsToArray(
-      const UnknownFieldSet& unknown_fields,
-      uint8* target);
+      const UnknownFieldSet& unknown_fields, uint8* target);
 
   // Compute the size of the UnknownFieldSet on the wire.
   static size_t ComputeUnknownFieldsSize(const UnknownFieldSet& unknown_fields);
@@ -174,54 +177,47 @@
   static size_t ComputeUnknownMessageSetItemsSize(
       const UnknownFieldSet& unknown_fields);
 
-
   // Helper functions for encoding and decoding tags.  (Inlined below and in
   // _inl.h)
   //
-  // This is different from MakeTag(field->number(), field->type()) in the case
-  // of packed repeated fields.
+  // This is different from MakeTag(field->number(), field->type()) in the
+  // case of packed repeated fields.
   static uint32 MakeTag(const FieldDescriptor* field);
 
   // Parse a single field.  The input should start out positioned immediately
   // after the tag.
   static bool ParseAndMergeField(
       uint32 tag,
-      const FieldDescriptor* field,        // May be NULL for unknown
-      Message* message,
-      io::CodedInputStream* input);
+      const FieldDescriptor* field,  // May be NULL for unknown
+      Message* message, io::CodedInputStream* input);
 
   // Serialize a single field.
   static void SerializeFieldWithCachedSizes(
-      const FieldDescriptor* field,        // Cannot be NULL
-      const Message& message,
-      io::CodedOutputStream* output);
+      const FieldDescriptor* field,  // Cannot be NULL
+      const Message& message, io::CodedOutputStream* output);
 
   // Compute size of a single field.  If the field is a message type, this
   // will call ByteSize() for the embedded message, insuring that it caches
   // its size.
-  static size_t FieldByteSize(
-      const FieldDescriptor* field,        // Cannot be NULL
-      const Message& message);
+  static size_t FieldByteSize(const FieldDescriptor* field,  // Cannot be NULL
+                              const Message& message);
 
   // Parse/serialize a MessageSet::Item group.  Used with messages that use
   // opion message_set_wire_format = true.
-  static bool ParseAndMergeMessageSetItem(
-      io::CodedInputStream* input,
-      Message* message);
+  static bool ParseAndMergeMessageSetItem(io::CodedInputStream* input,
+                                          Message* message);
   static void SerializeMessageSetItemWithCachedSizes(
-      const FieldDescriptor* field,
-      const Message& message,
+      const FieldDescriptor* field, const Message& message,
       io::CodedOutputStream* output);
-  static size_t MessageSetItemByteSize(
-      const FieldDescriptor* field,
-      const Message& message);
+  static size_t MessageSetItemByteSize(const FieldDescriptor* field,
+                                       const Message& message);
 
   // Computes the byte size of a field, excluding tags. For packed fields, it
   // only includes the size of the raw data, and not the size of the total
   // length, but for other length-delimited types, the size of the length is
   // included.
   static size_t FieldDataOnlyByteSize(
-      const FieldDescriptor* field,        // Cannot be NULL
+      const FieldDescriptor* field,  // Cannot be NULL
       const Message& message);
 
   enum Operation {
@@ -235,10 +231,8 @@
   static void VerifyUTF8String(const char* data, int size, Operation op);
   // The NamedField variant takes a field name in order to produce an
   // informative error message if verification fails.
-  static void VerifyUTF8StringNamedField(const char* data,
-                                         int size,
-                                         Operation op,
-                                         const char* field_name);
+  static void VerifyUTF8StringNamedField(const char* data, int size,
+                                         Operation op, const char* field_name);
 
  private:
   // Skip a MessageSet field.
@@ -260,12 +254,12 @@
  public:
   UnknownFieldSetFieldSkipper(UnknownFieldSet* unknown_fields)
       : unknown_fields_(unknown_fields) {}
-  virtual ~UnknownFieldSetFieldSkipper() override {}
+  ~UnknownFieldSetFieldSkipper() override {}
 
   // implements FieldSkipper -----------------------------------------
-  virtual bool SkipField(io::CodedInputStream* input, uint32 tag) override;
-  virtual bool SkipMessage(io::CodedInputStream* input) override;
-  virtual void SkipUnknownEnum(int field_number, int value) override;
+  bool SkipField(io::CodedInputStream* input, uint32 tag) override;
+  bool SkipMessage(io::CodedInputStream* input) override;
+  void SkipUnknownEnum(int field_number, int value) override;
 
  protected:
   UnknownFieldSet* unknown_fields_;
@@ -287,8 +281,7 @@
   // Some compilers don't like enum -> enum casts, so we implicit_cast to
   // int first.
   return WireFormatLite::WireTypeForFieldType(
-      static_cast<WireFormatLite::FieldType>(
-        implicit_cast<int>(type)));
+      static_cast<WireFormatLite::FieldType>(::google::protobuf::implicit_cast<int>(type)));
 }
 
 inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) {
@@ -299,37 +292,58 @@
                                   FieldDescriptor::Type type) {
   // Some compilers don't like enum -> enum casts, so we implicit_cast to
   // int first.
-  return WireFormatLite::TagSize(field_number,
-      static_cast<WireFormatLite::FieldType>(
-        implicit_cast<int>(type)));
+  return WireFormatLite::TagSize(
+      field_number,
+      static_cast<WireFormatLite::FieldType>(::google::protobuf::implicit_cast<int>(type)));
 }
 
 inline void WireFormat::VerifyUTF8String(const char* data, int size,
-    WireFormat::Operation op) {
+                                         WireFormat::Operation op) {
 #ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
   WireFormatLite::VerifyUtf8String(
       data, size, static_cast<WireFormatLite::Operation>(op), NULL);
 #else
   // Avoid the compiler warning about unused variables.
-  (void)data; (void)size; (void)op;
+  (void)data;
+  (void)size;
+  (void)op;
 #endif
 }
 
-inline void WireFormat::VerifyUTF8StringNamedField(
-    const char* data, int size, WireFormat::Operation op,
-    const char* field_name) {
+inline void WireFormat::VerifyUTF8StringNamedField(const char* data, int size,
+                                                   WireFormat::Operation op,
+                                                   const char* field_name) {
 #ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
   WireFormatLite::VerifyUtf8String(
       data, size, static_cast<WireFormatLite::Operation>(op), field_name);
 #else
   // Avoid the compiler warning about unused variables.
-  (void)data; (void)size; (void)op; (void)field_name;
+  (void)data;
+  (void)size;
+  (void)op;
+  (void)field_name;
 #endif
 }
 
 
+inline void SerializeUnknownMessageSetItems(
+    const UnknownFieldSet& unknown_fields, io::CodedOutputStream* output) {
+  WireFormat::SerializeUnknownMessageSetItems(unknown_fields, output);
+}
+
+inline uint8* SerializeUnknownMessageSetItemsToArray(
+    const UnknownFieldSet& unknown_fields, uint8* target) {
+  return WireFormat::SerializeUnknownMessageSetItemsToArray(unknown_fields,
+                                                            target);
+}
+
+inline size_t ComputeUnknownMessageSetItemsSize(
+    const UnknownFieldSet& unknown_fields) {
+  return WireFormat::ComputeUnknownMessageSetItemsSize(unknown_fields);
+}
+
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_H__
diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc
index 1d8cda5..6b0190f 100644
--- a/src/google/protobuf/wire_format_lite.cc
+++ b/src/google/protobuf/wire_format_lite.cc
@@ -43,6 +43,7 @@
 #include <google/protobuf/io/coded_stream_inl.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/port_def.inc>
 
 
 namespace google {
@@ -301,8 +302,7 @@
   io::CodedInputStream::Limit limit = input->PushLimit(length);
   while (input->BytesUntilLimit() > 0) {
     int value;
-    if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
-        int, WireFormatLite::TYPE_ENUM>(input, &value)) {
+    if (!ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(input, &value)) {
       return false;
     }
     if (is_valid == NULL || is_valid(value)) {
@@ -324,8 +324,7 @@
   io::CodedInputStream::Limit limit = input->PushLimit(length);
   while (input->BytesUntilLimit() > 0) {
     int value;
-    if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
-        int, WireFormatLite::TYPE_ENUM>(input, &value)) {
+    if (!ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(input, &value)) {
       return false;
     }
     if (is_valid == NULL || is_valid(value)) {
@@ -597,7 +596,7 @@
 }
 
 bool WireFormatLite::ReadBytes(io::CodedInputStream* input, string** p) {
-  if (*p == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+  if (*p == &GetEmptyStringAlreadyInited()) {
     *p = new ::std::string();
   }
   return ReadBytesToString(input, *p);
diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h
index 2244b35..dc79ac4 100644
--- a/src/google/protobuf/wire_format_lite.h
+++ b/src/google/protobuf/wire_format_lite.h
@@ -45,7 +45,7 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/message_lite.h>
-#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/port.h>
 #include <google/protobuf/repeated_field.h>
 
 // Do UTF-8 validation on string type in Debug build only
@@ -55,25 +55,30 @@
 
 // Avoid conflict with iOS where <ConditionalMacros.h> #defines TYPE_BOOL.
 //
-// If some one needs the macro TYPE_BOOL in a file that includes this header, it's
-// possible to bring it back using push/pop_macro as follows.
+// If some one needs the macro TYPE_BOOL in a file that includes this header,
+// it's possible to bring it back using push/pop_macro as follows.
 //
 // #pragma push_macro("TYPE_BOOL")
 // #include this header and/or all headers that need the macro to be undefined.
 // #pragma pop_macro("TYPE_BOOL")
 #undef TYPE_BOOL
 
+
 namespace google {
-
 namespace protobuf {
-  template <typename T> class RepeatedField;  // repeated_field.h
-}
+template <typename T>
+class RepeatedField;  // repeated_field.h
+}  // namespace protobuf
+}  // namespace google
 
+namespace google {
 namespace protobuf {
 namespace internal {
 
 class StringPieceField;
 
+#include <google/protobuf/port_def.inc>
+
 // This class is for internal use by the protocol buffer library and by
 // protocol-complier-generated message classes.  It must not be called
 // directly by clients.
@@ -85,7 +90,6 @@
 // This class is really a namespace that contains only static methods.
 class LIBPROTOBUF_EXPORT WireFormatLite {
  public:
-
   // -----------------------------------------------------------------
   // Helper constants and functions related to the format.  These are
   // mostly meant for internal and generated code to use.
@@ -102,50 +106,50 @@
   // unrecognized fields for forwards compatibility.
 
   enum WireType {
-    WIRETYPE_VARINT           = 0,
-    WIRETYPE_FIXED64          = 1,
+    WIRETYPE_VARINT = 0,
+    WIRETYPE_FIXED64 = 1,
     WIRETYPE_LENGTH_DELIMITED = 2,
-    WIRETYPE_START_GROUP      = 3,
-    WIRETYPE_END_GROUP        = 4,
-    WIRETYPE_FIXED32          = 5,
+    WIRETYPE_START_GROUP = 3,
+    WIRETYPE_END_GROUP = 4,
+    WIRETYPE_FIXED32 = 5,
   };
 
   // Lite alternative to FieldDescriptor::Type.  Must be kept in sync.
   enum FieldType {
-    TYPE_DOUBLE         = 1,
-    TYPE_FLOAT          = 2,
-    TYPE_INT64          = 3,
-    TYPE_UINT64         = 4,
-    TYPE_INT32          = 5,
-    TYPE_FIXED64        = 6,
-    TYPE_FIXED32        = 7,
-    TYPE_BOOL           = 8,
-    TYPE_STRING         = 9,
-    TYPE_GROUP          = 10,
-    TYPE_MESSAGE        = 11,
-    TYPE_BYTES          = 12,
-    TYPE_UINT32         = 13,
-    TYPE_ENUM           = 14,
-    TYPE_SFIXED32       = 15,
-    TYPE_SFIXED64       = 16,
-    TYPE_SINT32         = 17,
-    TYPE_SINT64         = 18,
-    MAX_FIELD_TYPE      = 18,
+    TYPE_DOUBLE = 1,
+    TYPE_FLOAT = 2,
+    TYPE_INT64 = 3,
+    TYPE_UINT64 = 4,
+    TYPE_INT32 = 5,
+    TYPE_FIXED64 = 6,
+    TYPE_FIXED32 = 7,
+    TYPE_BOOL = 8,
+    TYPE_STRING = 9,
+    TYPE_GROUP = 10,
+    TYPE_MESSAGE = 11,
+    TYPE_BYTES = 12,
+    TYPE_UINT32 = 13,
+    TYPE_ENUM = 14,
+    TYPE_SFIXED32 = 15,
+    TYPE_SFIXED64 = 16,
+    TYPE_SINT32 = 17,
+    TYPE_SINT64 = 18,
+    MAX_FIELD_TYPE = 18,
   };
 
   // Lite alternative to FieldDescriptor::CppType.  Must be kept in sync.
   enum CppType {
-    CPPTYPE_INT32       = 1,
-    CPPTYPE_INT64       = 2,
-    CPPTYPE_UINT32      = 3,
-    CPPTYPE_UINT64      = 4,
-    CPPTYPE_DOUBLE      = 5,
-    CPPTYPE_FLOAT       = 6,
-    CPPTYPE_BOOL        = 7,
-    CPPTYPE_ENUM        = 8,
-    CPPTYPE_STRING      = 9,
-    CPPTYPE_MESSAGE     = 10,
-    MAX_CPPTYPE         = 10,
+    CPPTYPE_INT32 = 1,
+    CPPTYPE_INT64 = 2,
+    CPPTYPE_UINT32 = 3,
+    CPPTYPE_UINT64 = 4,
+    CPPTYPE_DOUBLE = 5,
+    CPPTYPE_FLOAT = 6,
+    CPPTYPE_BOOL = 7,
+    CPPTYPE_ENUM = 8,
+    CPPTYPE_STRING = 9,
+    CPPTYPE_MESSAGE = 10,
+    MAX_CPPTYPE = 10,
   };
 
   // Helper method to get the CppType for a particular Type.
@@ -165,8 +169,8 @@
   // Helper functions for encoding and decoding tags.  (Inlined below and in
   // _inl.h)
   //
-  // This is different from MakeTag(field->number(), field->type()) in the case
-  // of packed repeated fields.
+  // This is different from MakeTag(field->number(), field->type()) in the
+  // case of packed repeated fields.
   static uint32 MakeTag(int field_number, WireType type);
   static WireType GetTagWireType(uint32 tag);
   static int GetTagFieldNumber(uint32 tag);
@@ -177,9 +181,9 @@
                                WireFormatLite::FieldType type);
 
   // Skips a field value with the given tag.  The input should start
-  // positioned immediately after the tag.  Skipped values are simply discarded,
-  // not recorded anywhere.  See WireFormat::SkipField() for a version that
-  // records to an UnknownFieldSet.
+  // positioned immediately after the tag.  Skipped values are simply
+  // discarded, not recorded anywhere.  See WireFormat::SkipField() for a
+  // version that records to an UnknownFieldSet.
   static bool SkipField(io::CodedInputStream* input, uint32 tag);
 
   // Skips a field value with the given tag.  The input should start
@@ -198,14 +202,12 @@
   static bool SkipMessage(io::CodedInputStream* input,
                           io::CodedOutputStream* output);
 
-// This macro does the same thing as WireFormatLite::MakeTag(), but the
-// result is usable as a compile-time constant, which makes it usable
-// as a switch case or a template input.  WireFormatLite::MakeTag() is more
-// type-safe, though, so prefer it if possible.
-#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE)                  \
-  static_cast<uint32>(                                                   \
-    (static_cast<uint32>(FIELD_NUMBER) << ::google::protobuf::internal::WireFormatLite::kTagTypeBits) \
-      | (TYPE))
+  // This macro does the same thing as WireFormatLite::MakeTag(), but the
+  // result is usable as a compile-time constant, which makes it usable
+  // as a switch case or a template input.  WireFormatLite::MakeTag() is more
+  // type-safe, though, so prefer it if possible.
+#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \
+  static_cast<uint32>((static_cast<uint32>(FIELD_NUMBER) << 3) | (TYPE))
 
   // These are the tags for the old MessageSet format, which was defined as:
   //   message MessageSet {
@@ -217,18 +219,14 @@
   static const int kMessageSetItemNumber = 1;
   static const int kMessageSetTypeIdNumber = 2;
   static const int kMessageSetMessageNumber = 3;
-  static const int kMessageSetItemStartTag =
-    GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber,
-                                WireFormatLite::WIRETYPE_START_GROUP);
-  static const int kMessageSetItemEndTag =
-    GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber,
-                                WireFormatLite::WIRETYPE_END_GROUP);
-  static const int kMessageSetTypeIdTag =
-    GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetTypeIdNumber,
-                                WireFormatLite::WIRETYPE_VARINT);
-  static const int kMessageSetMessageTag =
-    GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetMessageNumber,
-                                WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+  static const int kMessageSetItemStartTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
+      kMessageSetItemNumber, WireFormatLite::WIRETYPE_START_GROUP);
+  static const int kMessageSetItemEndTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
+      kMessageSetItemNumber, WireFormatLite::WIRETYPE_END_GROUP);
+  static const int kMessageSetTypeIdTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
+      kMessageSetTypeIdNumber, WireFormatLite::WIRETYPE_VARINT);
+  static const int kMessageSetMessageTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
+      kMessageSetMessageNumber, WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
 
   // Byte size of all tags of a MessageSet::Item combined.
   static const size_t kMessageSetItemTagsSize;
@@ -248,9 +246,9 @@
   // the purpose of varint.  So, for the "sint32" and "sint64" field types,
   // we ZigZag-encode the values.
   static uint32 ZigZagEncode32(int32 n);
-  static int32  ZigZagDecode32(uint32 n);
+  static int32 ZigZagDecode32(uint32 n);
   static uint64 ZigZagEncode64(int64 n);
-  static int64  ZigZagDecode64(uint64 n);
+  static int64 ZigZagDecode64(uint64 n);
 
   // =================================================================
   // Methods for reading/writing individual field.  The implementations
@@ -296,8 +294,9 @@
   //
   // This is only implemented for the types with fixed wire size, e.g.
   // float, double, and the (s)fixed* types.
-  template <typename CType, enum FieldType DeclaredType> INL
-  static const uint8* ReadPrimitiveFromArray(const uint8* buffer, CType* value);
+  template <typename CType, enum FieldType DeclaredType>
+  INL static const uint8* ReadPrimitiveFromArray(const uint8* buffer,
+                                                 CType* value);
 
   // Reads a primitive packed field.
   //
@@ -342,8 +341,7 @@
   };
 
   // Returns true if the data is valid UTF-8.
-  static bool VerifyUtf8String(const char* data, int size,
-                               Operation op,
+  static bool VerifyUtf8String(const char* data, int size, Operation op,
                                const char* field_name);
 
   template <typename MessageType>
@@ -362,7 +360,7 @@
     return ReadGroup(field_number, input, value);
   }
 
-  template<typename MessageType>
+  template <typename MessageType>
   static inline bool ReadMessageNoVirtual(io::CodedInputStream* input,
                                           MessageType* value) {
     return ReadMessage(input, value);
@@ -494,43 +492,43 @@
   INL static uint8* WriteEnumNoTagToArray(int value, uint8* target);
 
   // Write fields, without tags.  These require that value.size() > 0.
-  template<typename T>
-  INL static uint8* WritePrimitiveNoTagToArray(
-      const RepeatedField<T>& value,
-      uint8* (*Writer)(T, uint8*), uint8* target);
-  template<typename T>
-  INL static uint8* WriteFixedNoTagToArray(
-      const RepeatedField<T>& value,
-      uint8* (*Writer)(T, uint8*), uint8* target);
+  template <typename T>
+  INL static uint8* WritePrimitiveNoTagToArray(const RepeatedField<T>& value,
+                                               uint8* (*Writer)(T, uint8*),
+                                               uint8* target);
+  template <typename T>
+  INL static uint8* WriteFixedNoTagToArray(const RepeatedField<T>& value,
+                                           uint8* (*Writer)(T, uint8*),
+                                           uint8* target);
 
-  INL static uint8* WriteInt32NoTagToArray(
-      const RepeatedField< int32>& value, uint8* output);
-  INL static uint8* WriteInt64NoTagToArray(
-      const RepeatedField< int64>& value, uint8* output);
-  INL static uint8* WriteUInt32NoTagToArray(
-      const RepeatedField<uint32>& value, uint8* output);
-  INL static uint8* WriteUInt64NoTagToArray(
-      const RepeatedField<uint64>& value, uint8* output);
-  INL static uint8* WriteSInt32NoTagToArray(
-      const RepeatedField< int32>& value, uint8* output);
-  INL static uint8* WriteSInt64NoTagToArray(
-      const RepeatedField< int64>& value, uint8* output);
-  INL static uint8* WriteFixed32NoTagToArray(
-      const RepeatedField<uint32>& value, uint8* output);
-  INL static uint8* WriteFixed64NoTagToArray(
-      const RepeatedField<uint64>& value, uint8* output);
-  INL static uint8* WriteSFixed32NoTagToArray(
-      const RepeatedField< int32>& value, uint8* output);
-  INL static uint8* WriteSFixed64NoTagToArray(
-      const RepeatedField< int64>& value, uint8* output);
-  INL static uint8* WriteFloatNoTagToArray(
-      const RepeatedField< float>& value, uint8* output);
-  INL static uint8* WriteDoubleNoTagToArray(
-      const RepeatedField<double>& value, uint8* output);
-  INL static uint8* WriteBoolNoTagToArray(
-      const RepeatedField<  bool>& value, uint8* output);
-  INL static uint8* WriteEnumNoTagToArray(
-      const RepeatedField<   int>& value, uint8* output);
+  INL static uint8* WriteInt32NoTagToArray(const RepeatedField<int32>& value,
+                                           uint8* output);
+  INL static uint8* WriteInt64NoTagToArray(const RepeatedField<int64>& value,
+                                           uint8* output);
+  INL static uint8* WriteUInt32NoTagToArray(const RepeatedField<uint32>& value,
+                                            uint8* output);
+  INL static uint8* WriteUInt64NoTagToArray(const RepeatedField<uint64>& value,
+                                            uint8* output);
+  INL static uint8* WriteSInt32NoTagToArray(const RepeatedField<int32>& value,
+                                            uint8* output);
+  INL static uint8* WriteSInt64NoTagToArray(const RepeatedField<int64>& value,
+                                            uint8* output);
+  INL static uint8* WriteFixed32NoTagToArray(const RepeatedField<uint32>& value,
+                                             uint8* output);
+  INL static uint8* WriteFixed64NoTagToArray(const RepeatedField<uint64>& value,
+                                             uint8* output);
+  INL static uint8* WriteSFixed32NoTagToArray(const RepeatedField<int32>& value,
+                                              uint8* output);
+  INL static uint8* WriteSFixed64NoTagToArray(const RepeatedField<int64>& value,
+                                              uint8* output);
+  INL static uint8* WriteFloatNoTagToArray(const RepeatedField<float>& value,
+                                           uint8* output);
+  INL static uint8* WriteDoubleNoTagToArray(const RepeatedField<double>& value,
+                                            uint8* output);
+  INL static uint8* WriteBoolNoTagToArray(const RepeatedField<bool>& value,
+                                          uint8* output);
+  INL static uint8* WriteEnumNoTagToArray(const RepeatedField<int>& value,
+                                          uint8* output);
 
   // Write fields, including tags.
   INL static uint8* WriteInt32ToArray(int field_number, int32 value,
@@ -562,40 +560,54 @@
   INL static uint8* WriteEnumToArray(int field_number, int value,
                                      uint8* target);
 
-  template<typename T>
-  INL static uint8* WritePrimitiveToArray(
-      int field_number,
-      const RepeatedField<T>& value,
-      uint8* (*Writer)(int, T, uint8*), uint8* target);
+  template <typename T>
+  INL static uint8* WritePrimitiveToArray(int field_number,
+                                          const RepeatedField<T>& value,
+                                          uint8* (*Writer)(int, T, uint8*),
+                                          uint8* target);
 
-  INL static uint8* WriteInt32ToArray(
-      int field_number, const RepeatedField< int32>& value, uint8* output);
-  INL static uint8* WriteInt64ToArray(
-      int field_number, const RepeatedField< int64>& value, uint8* output);
-  INL static uint8* WriteUInt32ToArray(
-      int field_number, const RepeatedField<uint32>& value, uint8* output);
-  INL static uint8* WriteUInt64ToArray(
-      int field_number, const RepeatedField<uint64>& value, uint8* output);
-  INL static uint8* WriteSInt32ToArray(
-      int field_number, const RepeatedField< int32>& value, uint8* output);
-  INL static uint8* WriteSInt64ToArray(
-      int field_number, const RepeatedField< int64>& value, uint8* output);
-  INL static uint8* WriteFixed32ToArray(
-      int field_number, const RepeatedField<uint32>& value, uint8* output);
-  INL static uint8* WriteFixed64ToArray(
-      int field_number, const RepeatedField<uint64>& value, uint8* output);
-  INL static uint8* WriteSFixed32ToArray(
-      int field_number, const RepeatedField< int32>& value, uint8* output);
-  INL static uint8* WriteSFixed64ToArray(
-      int field_number, const RepeatedField< int64>& value, uint8* output);
-  INL static uint8* WriteFloatToArray(
-      int field_number, const RepeatedField< float>& value, uint8* output);
-  INL static uint8* WriteDoubleToArray(
-      int field_number, const RepeatedField<double>& value, uint8* output);
-  INL static uint8* WriteBoolToArray(
-      int field_number, const RepeatedField<  bool>& value, uint8* output);
-  INL static uint8* WriteEnumToArray(
-      int field_number, const RepeatedField<   int>& value, uint8* output);
+  INL static uint8* WriteInt32ToArray(int field_number,
+                                      const RepeatedField<int32>& value,
+                                      uint8* output);
+  INL static uint8* WriteInt64ToArray(int field_number,
+                                      const RepeatedField<int64>& value,
+                                      uint8* output);
+  INL static uint8* WriteUInt32ToArray(int field_number,
+                                       const RepeatedField<uint32>& value,
+                                       uint8* output);
+  INL static uint8* WriteUInt64ToArray(int field_number,
+                                       const RepeatedField<uint64>& value,
+                                       uint8* output);
+  INL static uint8* WriteSInt32ToArray(int field_number,
+                                       const RepeatedField<int32>& value,
+                                       uint8* output);
+  INL static uint8* WriteSInt64ToArray(int field_number,
+                                       const RepeatedField<int64>& value,
+                                       uint8* output);
+  INL static uint8* WriteFixed32ToArray(int field_number,
+                                        const RepeatedField<uint32>& value,
+                                        uint8* output);
+  INL static uint8* WriteFixed64ToArray(int field_number,
+                                        const RepeatedField<uint64>& value,
+                                        uint8* output);
+  INL static uint8* WriteSFixed32ToArray(int field_number,
+                                         const RepeatedField<int32>& value,
+                                         uint8* output);
+  INL static uint8* WriteSFixed64ToArray(int field_number,
+                                         const RepeatedField<int64>& value,
+                                         uint8* output);
+  INL static uint8* WriteFloatToArray(int field_number,
+                                      const RepeatedField<float>& value,
+                                      uint8* output);
+  INL static uint8* WriteDoubleToArray(int field_number,
+                                       const RepeatedField<double>& value,
+                                       uint8* output);
+  INL static uint8* WriteBoolToArray(int field_number,
+                                     const RepeatedField<bool>& value,
+                                     uint8* output);
+  INL static uint8* WriteEnumToArray(int field_number,
+                                     const RepeatedField<int>& value,
+                                     uint8* output);
 
   INL static uint8* WriteStringToArray(int field_number, const string& value,
                                        uint8* target);
@@ -607,12 +619,12 @@
   // of serialization, the "ToArray" variants may be invoked.  But they don't
   // have a CodedOutputStream available, so they get an additional parameter
   // telling them whether to serialize deterministically.
-  template<typename MessageType>
+  template <typename MessageType>
   INL static uint8* InternalWriteGroupToArray(int field_number,
                                               const MessageType& value,
                                               bool deterministic,
                                               uint8* target);
-  template<typename MessageType>
+  template <typename MessageType>
   INL static uint8* InternalWriteMessageToArray(int field_number,
                                                 const MessageType& value,
                                                 bool deterministic,
@@ -663,45 +675,45 @@
   // the tag, so you must also call TagSize().  (This is because, for repeated
   // fields, you should only call TagSize() once and multiply it by the element
   // count, but you may have to call XxSize() for each individual element.)
-  static inline size_t Int32Size   ( int32 value);
-  static inline size_t Int64Size   ( int64 value);
-  static inline size_t UInt32Size  (uint32 value);
-  static inline size_t UInt64Size  (uint64 value);
-  static inline size_t SInt32Size  ( int32 value);
-  static inline size_t SInt64Size  ( int64 value);
-  static inline size_t EnumSize    (   int value);
+  static inline size_t Int32Size(int32 value);
+  static inline size_t Int64Size(int64 value);
+  static inline size_t UInt32Size(uint32 value);
+  static inline size_t UInt64Size(uint64 value);
+  static inline size_t SInt32Size(int32 value);
+  static inline size_t SInt64Size(int64 value);
+  static inline size_t EnumSize(int value);
 
-  static size_t Int32Size (const RepeatedField< int32>& value);
-  static size_t Int64Size (const RepeatedField< int64>& value);
+  static size_t Int32Size(const RepeatedField<int32>& value);
+  static size_t Int64Size(const RepeatedField<int64>& value);
   static size_t UInt32Size(const RepeatedField<uint32>& value);
   static size_t UInt64Size(const RepeatedField<uint64>& value);
-  static size_t SInt32Size(const RepeatedField< int32>& value);
-  static size_t SInt64Size(const RepeatedField< int64>& value);
-  static size_t EnumSize  (const RepeatedField<   int>& value);
+  static size_t SInt32Size(const RepeatedField<int32>& value);
+  static size_t SInt64Size(const RepeatedField<int64>& value);
+  static size_t EnumSize(const RepeatedField<int>& value);
 
   // These types always have the same size.
-  static const size_t kFixed32Size  = 4;
-  static const size_t kFixed64Size  = 8;
+  static const size_t kFixed32Size = 4;
+  static const size_t kFixed64Size = 8;
   static const size_t kSFixed32Size = 4;
   static const size_t kSFixed64Size = 8;
-  static const size_t kFloatSize    = 4;
-  static const size_t kDoubleSize   = 8;
-  static const size_t kBoolSize     = 1;
+  static const size_t kFloatSize = 4;
+  static const size_t kDoubleSize = 8;
+  static const size_t kBoolSize = 1;
 
   static inline size_t StringSize(const string& value);
-  static inline size_t BytesSize (const string& value);
+  static inline size_t BytesSize(const string& value);
 
-  template<typename MessageType>
-  static inline size_t GroupSize  (const MessageType& value);
-  template<typename MessageType>
+  template <typename MessageType>
+  static inline size_t GroupSize(const MessageType& value);
+  template <typename MessageType>
   static inline size_t MessageSize(const MessageType& value);
 
   // Like above, but de-virtualize the call to ByteSize().  The
   // pointer must point at an instance of MessageType, *not* a subclass (or
   // the subclass must not override ByteSize()).
-  template<typename MessageType>
-  static inline size_t GroupSizeNoVirtual  (const MessageType& value);
-  template<typename MessageType>
+  template <typename MessageType>
+  static inline size_t GroupSizeNoVirtual(const MessageType& value);
+  template <typename MessageType>
   static inline size_t MessageSizeNoVirtual(const MessageType& value);
 
   // Given the length of data, calculate the byte size of the data on the
@@ -713,18 +725,16 @@
   // optimizations for primitive types that have fixed size on the wire, and
   // can be read using potentially faster paths.
   template <typename CType, enum FieldType DeclaredType>
-  GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
-  static bool ReadRepeatedFixedSizePrimitive(
-      int tag_size,
-      uint32 tag,
-      google::protobuf::io::CodedInputStream* input,
-      RepeatedField<CType>* value);
+  GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static bool
+  ReadRepeatedFixedSizePrimitive(int tag_size, uint32 tag,
+                                 io::CodedInputStream* input,
+                                 RepeatedField<CType>* value);
 
   // Like ReadRepeatedFixedSizePrimitive but for packed primitive fields.
   template <typename CType, enum FieldType DeclaredType>
-  GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE
-  static bool ReadPackedFixedSizePrimitive(
-      google::protobuf::io::CodedInputStream* input, RepeatedField<CType>* value);
+  GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE static bool
+  ReadPackedFixedSizePrimitive(io::CodedInputStream* input,
+                               RepeatedField<CType>* value);
 
   static const CppType kFieldTypeToCppTypeMap[];
   static const WireFormatLite::WireType kWireTypeForFieldType[];
@@ -763,19 +773,18 @@
   virtual ~CodedOutputStreamFieldSkipper() {}
 
   // implements FieldSkipper -----------------------------------------
-  virtual bool SkipField(io::CodedInputStream* input, uint32 tag) override;
-  virtual bool SkipMessage(io::CodedInputStream* input) override;
-  virtual void SkipUnknownEnum(int field_number, int value) override;
+  bool SkipField(io::CodedInputStream* input, uint32 tag) override;
+  bool SkipMessage(io::CodedInputStream* input) override;
+  void SkipUnknownEnum(int field_number, int value) override;
 
  protected:
   io::CodedOutputStream* unknown_fields_;
 };
 
-
 // inline methods ====================================================
 
-inline WireFormatLite::CppType
-WireFormatLite::FieldTypeToCppType(FieldType type) {
+inline WireFormatLite::CppType WireFormatLite::FieldTypeToCppType(
+    FieldType type) {
   return kFieldTypeToCppTypeMap[type];
 }
 
@@ -794,7 +803,7 @@
 inline size_t WireFormatLite::TagSize(int field_number,
                                       WireFormatLite::FieldType type) {
   size_t result = io::CodedOutputStream::VarintSize32(
-    static_cast<uint32>(field_number << kTagTypeBits));
+      static_cast<uint32>(field_number << kTagTypeBits));
   if (type == TYPE_GROUP) {
     // Groups have both a start and an end tag.
     return result * 2;
@@ -804,25 +813,37 @@
 }
 
 inline uint32 WireFormatLite::EncodeFloat(float value) {
-  union {float f; uint32 i;};
+  union {
+    float f;
+    uint32 i;
+  };
   f = value;
   return i;
 }
 
 inline float WireFormatLite::DecodeFloat(uint32 value) {
-  union {float f; uint32 i;};
+  union {
+    float f;
+    uint32 i;
+  };
   i = value;
   return f;
 }
 
 inline uint64 WireFormatLite::EncodeDouble(double value) {
-  union {double f; uint64 i;};
+  union {
+    double f;
+    uint64 i;
+  };
   f = value;
   return i;
 }
 
 inline double WireFormatLite::DecodeDouble(uint64 value) {
-  union {double f; uint64 i;};
+  union {
+    double f;
+    uint64 i;
+  };
   i = value;
   return f;
 }
@@ -886,8 +907,25 @@
   return ReadBytes(input, p);
 }
 
+inline void SerializeUnknownMessageSetItems(const string& unknown_fields,
+                                            io::CodedOutputStream* output) {
+  output->WriteString(unknown_fields);
+}
+
+inline uint8* SerializeUnknownMessageSetItemsToArray(
+    const string& unknown_fields, uint8* target) {
+  return io::CodedOutputStream::WriteStringWithSizeToArray(unknown_fields,
+                                                           target);
+}
+
+inline size_t ComputeUnknownMessageSetItemsSize(const string& unknown_fields) {
+  return unknown_fields.size();
+}
+
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
+#include <google/protobuf/port_undef.inc>
+
 #endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h
index 6cd2c2f..2ee5d51 100644
--- a/src/google/protobuf/wire_format_lite_inl.h
+++ b/src/google/protobuf/wire_format_lite_inl.h
@@ -40,13 +40,17 @@
 #include <string>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arenastring.h>
 #include <google/protobuf/message_lite.h>
 #include <google/protobuf/repeated_field.h>
 #include <google/protobuf/wire_format_lite.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/arenastring.h>
 
 
+#ifdef SWIG
+#error "You cannot SWIG proto headers"
+#endif
+
 namespace google {
 namespace protobuf {
 namespace internal {
@@ -989,8 +993,78 @@
       static_cast<uint32>(length));
 }
 
+template <typename MS>
+bool ParseMessageSetItemImpl(io::CodedInputStream* input, MS ms) {
+  // This method parses a group which should contain two fields:
+  //   required int32 type_id = 2;
+  //   required data message = 3;
+
+  uint32 last_type_id = 0;
+
+  // If we see message data before the type_id, we'll append it to this so
+  // we can parse it later.
+  string message_data;
+
+  while (true) {
+    const uint32 tag = input->ReadTagNoLastTag();
+    if (tag == 0) return false;
+
+    switch (tag) {
+      case WireFormatLite::kMessageSetTypeIdTag: {
+        uint32 type_id;
+        if (!input->ReadVarint32(&type_id)) return false;
+        last_type_id = type_id;
+
+        if (!message_data.empty()) {
+          // We saw some message data before the type_id.  Have to parse it
+          // now.
+          io::CodedInputStream sub_input(
+              reinterpret_cast<const uint8*>(message_data.data()),
+              static_cast<int>(message_data.size()));
+          if (!ms.ParseField(last_type_id, &sub_input)) {
+            return false;
+          }
+          message_data.clear();
+        }
+
+        break;
+      }
+
+      case WireFormatLite::kMessageSetMessageTag: {
+        if (last_type_id == 0) {
+          // We haven't seen a type_id yet.  Append this data to message_data.
+          uint32 length;
+          if (!input->ReadVarint32(&length)) return false;
+          if (static_cast<int32>(length) < 0) return false;
+          uint32 size = static_cast<uint32>(length +
+              io::CodedOutputStream::VarintSize32(length));
+          message_data.resize(size);
+          auto ptr = reinterpret_cast<uint8*>(&message_data[0]);
+          ptr = io::CodedOutputStream::WriteVarint32ToArray(length, ptr);
+          if (!input->ReadRaw(ptr, length)) return false;
+        } else {
+          // Already saw type_id, so we can parse this directly.
+          if (!ms.ParseField(last_type_id, input)) {
+            return false;
+          }
+        }
+
+        break;
+      }
+
+      case WireFormatLite::kMessageSetItemEndTag: {
+        return true;
+      }
+
+      default: {
+        if (!ms.SkipField(tag, input)) return false;
+      }
+    }
+  }
+}
+
 }  // namespace internal
 }  // namespace protobuf
-
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc
index 736a128..9dfd13b 100644
--- a/src/google/protobuf/wire_format_unittest.cc
+++ b/src/google/protobuf/wire_format_unittest.cc
@@ -48,6 +48,7 @@
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
+#include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/stl_util.h>
 
 namespace google {
@@ -59,17 +60,16 @@
   // Verify that WireFormatLite::FieldType and WireFormatLite::CppType match
   // FieldDescriptor::Type and FieldDescriptor::CppType.
 
-  EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_TYPE),
-            implicit_cast<int>(WireFormatLite::MAX_FIELD_TYPE));
-  EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_CPPTYPE),
-            implicit_cast<int>(WireFormatLite::MAX_CPPTYPE));
+  EXPECT_EQ(::google::protobuf::implicit_cast<int>(FieldDescriptor::MAX_TYPE),
+            ::google::protobuf::implicit_cast<int>(WireFormatLite::MAX_FIELD_TYPE));
+  EXPECT_EQ(::google::protobuf::implicit_cast<int>(FieldDescriptor::MAX_CPPTYPE),
+            ::google::protobuf::implicit_cast<int>(WireFormatLite::MAX_CPPTYPE));
 
   for (int i = 1; i <= WireFormatLite::MAX_FIELD_TYPE; i++) {
-    EXPECT_EQ(
-      implicit_cast<int>(FieldDescriptor::TypeToCppType(
-        static_cast<FieldDescriptor::Type>(i))),
-      implicit_cast<int>(WireFormatLite::FieldTypeToCppType(
-        static_cast<WireFormatLite::FieldType>(i))));
+    EXPECT_EQ(::google::protobuf::implicit_cast<int>(FieldDescriptor::TypeToCppType(
+                  static_cast<FieldDescriptor::Type>(i))),
+              ::google::protobuf::implicit_cast<int>(WireFormatLite::FieldTypeToCppType(
+                  static_cast<WireFormatLite::FieldType>(i))));
   }
 }
 
@@ -485,14 +485,15 @@
 
   // Serialize to flat array
   {
-    uint8* target = reinterpret_cast<uint8*>(string_as_array(&flat_data));
+    uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&flat_data));
     uint8* end = message_set.SerializeWithCachedSizesToArray(target);
     EXPECT_EQ(size, end - target);
   }
 
   // Serialize to buffer
   {
-    io::ArrayOutputStream array_stream(string_as_array(&stream_data), size, 1);
+    io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&stream_data), size,
+                                       1);
     io::CodedOutputStream output_stream(&array_stream);
     message_set.SerializeWithCachedSizes(&output_stream);
     ASSERT_FALSE(output_stream.HadError());
@@ -745,8 +746,8 @@
   }
 
   // Make sure that we have a variety of tag sizes.
-  const google::protobuf::Descriptor* desc = msg1.GetDescriptor();
-  const google::protobuf::FieldDescriptor* field;
+  const Descriptor* desc = msg1.GetDescriptor();
+  const FieldDescriptor* field;
   field = desc->FindFieldByName("repeated_fixed32");
   ASSERT_TRUE(field != NULL);
   ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type()));
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc
index 8f254b8..5a1fb3d 100644
--- a/src/google/protobuf/wrappers.pb.cc
+++ b/src/google/protobuf/wrappers.pb.cc
@@ -6,8 +6,8 @@
 #include <algorithm>
 
 #include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
 #include <google/protobuf/wire_format_lite_inl.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
@@ -18,58 +18,49 @@
 #include "third_party/protobuf/version.h"
 #endif
 // @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
 
 namespace google {
 namespace protobuf {
 class DoubleValueDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<DoubleValue>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<DoubleValue> _instance;
 } _DoubleValue_default_instance_;
 class FloatValueDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<FloatValue>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<FloatValue> _instance;
 } _FloatValue_default_instance_;
 class Int64ValueDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Int64Value>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Int64Value> _instance;
 } _Int64Value_default_instance_;
 class UInt64ValueDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<UInt64Value>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<UInt64Value> _instance;
 } _UInt64Value_default_instance_;
 class Int32ValueDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<Int32Value>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<Int32Value> _instance;
 } _Int32Value_default_instance_;
 class UInt32ValueDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<UInt32Value>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<UInt32Value> _instance;
 } _UInt32Value_default_instance_;
 class BoolValueDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<BoolValue>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<BoolValue> _instance;
 } _BoolValue_default_instance_;
 class StringValueDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<StringValue>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<StringValue> _instance;
 } _StringValue_default_instance_;
 class BytesValueDefaultTypeInternal {
  public:
-  ::google::protobuf::internal::ExplicitlyConstructed<BytesValue>
-      _instance;
+  ::google::protobuf::internal::ExplicitlyConstructed<BytesValue> _instance;
 } _BytesValue_default_instance_;
 }  // namespace protobuf
 }  // namespace google
-namespace protobuf_google_2fprotobuf_2fwrappers_2eproto {
-static void InitDefaultsDoubleValue() {
+static void InitDefaultsDoubleValue_google_2fprotobuf_2fwrappers_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -80,10 +71,10 @@
   ::google::protobuf::DoubleValue::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_DoubleValue =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsDoubleValue}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_DoubleValue_google_2fprotobuf_2fwrappers_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsDoubleValue_google_2fprotobuf_2fwrappers_2eproto}, {}};
 
-static void InitDefaultsFloatValue() {
+static void InitDefaultsFloatValue_google_2fprotobuf_2fwrappers_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -94,10 +85,10 @@
   ::google::protobuf::FloatValue::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_FloatValue =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsFloatValue}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_FloatValue_google_2fprotobuf_2fwrappers_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsFloatValue_google_2fprotobuf_2fwrappers_2eproto}, {}};
 
-static void InitDefaultsInt64Value() {
+static void InitDefaultsInt64Value_google_2fprotobuf_2fwrappers_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -108,10 +99,10 @@
   ::google::protobuf::Int64Value::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Int64Value =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsInt64Value}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Int64Value_google_2fprotobuf_2fwrappers_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsInt64Value_google_2fprotobuf_2fwrappers_2eproto}, {}};
 
-static void InitDefaultsUInt64Value() {
+static void InitDefaultsUInt64Value_google_2fprotobuf_2fwrappers_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -122,10 +113,10 @@
   ::google::protobuf::UInt64Value::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_UInt64Value =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUInt64Value}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_UInt64Value_google_2fprotobuf_2fwrappers_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUInt64Value_google_2fprotobuf_2fwrappers_2eproto}, {}};
 
-static void InitDefaultsInt32Value() {
+static void InitDefaultsInt32Value_google_2fprotobuf_2fwrappers_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -136,10 +127,10 @@
   ::google::protobuf::Int32Value::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Int32Value =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsInt32Value}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Int32Value_google_2fprotobuf_2fwrappers_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsInt32Value_google_2fprotobuf_2fwrappers_2eproto}, {}};
 
-static void InitDefaultsUInt32Value() {
+static void InitDefaultsUInt32Value_google_2fprotobuf_2fwrappers_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -150,10 +141,10 @@
   ::google::protobuf::UInt32Value::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_UInt32Value =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUInt32Value}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_UInt32Value_google_2fprotobuf_2fwrappers_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUInt32Value_google_2fprotobuf_2fwrappers_2eproto}, {}};
 
-static void InitDefaultsBoolValue() {
+static void InitDefaultsBoolValue_google_2fprotobuf_2fwrappers_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -164,10 +155,10 @@
   ::google::protobuf::BoolValue::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_BoolValue =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsBoolValue}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_BoolValue_google_2fprotobuf_2fwrappers_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsBoolValue_google_2fprotobuf_2fwrappers_2eproto}, {}};
 
-static void InitDefaultsStringValue() {
+static void InitDefaultsStringValue_google_2fprotobuf_2fwrappers_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -178,10 +169,10 @@
   ::google::protobuf::StringValue::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_StringValue =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsStringValue}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_StringValue_google_2fprotobuf_2fwrappers_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsStringValue_google_2fprotobuf_2fwrappers_2eproto}, {}};
 
-static void InitDefaultsBytesValue() {
+static void InitDefaultsBytesValue_google_2fprotobuf_2fwrappers_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
   {
@@ -192,24 +183,26 @@
   ::google::protobuf::BytesValue::InitAsDefaultInstance();
 }
 
-LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_BytesValue =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsBytesValue}, {}};
+LIBPROTOBUF_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_BytesValue_google_2fprotobuf_2fwrappers_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsBytesValue_google_2fprotobuf_2fwrappers_2eproto}, {}};
 
-void InitDefaults() {
-  ::google::protobuf::internal::InitSCC(&scc_info_DoubleValue.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_FloatValue.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_Int64Value.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_UInt64Value.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_Int32Value.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_UInt32Value.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_BoolValue.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_StringValue.base);
-  ::google::protobuf::internal::InitSCC(&scc_info_BytesValue.base);
+void InitDefaults_google_2fprotobuf_2fwrappers_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_DoubleValue_google_2fprotobuf_2fwrappers_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_FloatValue_google_2fprotobuf_2fwrappers_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Int64Value_google_2fprotobuf_2fwrappers_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_UInt64Value_google_2fprotobuf_2fwrappers_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Int32Value_google_2fprotobuf_2fwrappers_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_UInt32Value_google_2fprotobuf_2fwrappers_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_BoolValue_google_2fprotobuf_2fwrappers_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_StringValue_google_2fprotobuf_2fwrappers_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_BytesValue_google_2fprotobuf_2fwrappers_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata[9];
+::google::protobuf::Metadata file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[9];
+constexpr ::google::protobuf::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr;
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fwrappers_2eproto = nullptr;
 
-const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+const ::google::protobuf::uint32 TableStruct_google_2fprotobuf_2fwrappers_2eproto::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
   ~0u,  // no _has_bits_
   GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::DoubleValue, _internal_metadata_),
   ~0u,  // no _extensions_
@@ -289,57 +282,39 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_BytesValue_default_instance_),
 };
 
-static void protobuf_AssignDescriptors() {
-  AddDescriptors();
-  AssignDescriptors(
-      "google/protobuf/wrappers.proto", schemas, file_default_instances, TableStruct::offsets,
-      file_level_metadata, NULL, NULL);
-}
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto = {
+  {}, AddDescriptors_google_2fprotobuf_2fwrappers_2eproto, "google/protobuf/wrappers.proto", schemas,
+  file_default_instances, TableStruct_google_2fprotobuf_2fwrappers_2eproto::offsets,
+  file_level_metadata_google_2fprotobuf_2fwrappers_2eproto, 9, file_level_enum_descriptors_google_2fprotobuf_2fwrappers_2eproto, file_level_service_descriptors_google_2fprotobuf_2fwrappers_2eproto,
+};
 
-static void protobuf_AssignDescriptorsOnce() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
-}
+::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fwrappers_2eproto = {
+  false, InitDefaults_google_2fprotobuf_2fwrappers_2eproto, 
+  "\n\036google/protobuf/wrappers.proto\022\017google"
+  ".protobuf\"\034\n\013DoubleValue\022\r\n\005value\030\001 \001(\001\""
+  "\033\n\nFloatValue\022\r\n\005value\030\001 \001(\002\"\033\n\nInt64Val"
+  "ue\022\r\n\005value\030\001 \001(\003\"\034\n\013UInt64Value\022\r\n\005valu"
+  "e\030\001 \001(\004\"\033\n\nInt32Value\022\r\n\005value\030\001 \001(\005\"\034\n\013"
+  "UInt32Value\022\r\n\005value\030\001 \001(\r\"\032\n\tBoolValue\022"
+  "\r\n\005value\030\001 \001(\010\"\034\n\013StringValue\022\r\n\005value\030\001"
+  " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014B|\n\023com"
+  ".google.protobufB\rWrappersProtoP\001Z*githu"
+  "b.com/golang/protobuf/ptypes/wrappers\370\001\001"
+  "\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypesb"
+  "\006proto3"
+,
+  "google/protobuf/wrappers.proto", &assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto, 447,
+};
 
-void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD;
-void protobuf_RegisterTypes(const ::std::string&) {
-  protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 9);
-}
-
-static void AddDescriptorsImpl() {
-  InitDefaults();
-  static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
-      "\n\036google/protobuf/wrappers.proto\022\017google"
-      ".protobuf\"\034\n\013DoubleValue\022\r\n\005value\030\001 \001(\001\""
-      "\033\n\nFloatValue\022\r\n\005value\030\001 \001(\002\"\033\n\nInt64Val"
-      "ue\022\r\n\005value\030\001 \001(\003\"\034\n\013UInt64Value\022\r\n\005valu"
-      "e\030\001 \001(\004\"\033\n\nInt32Value\022\r\n\005value\030\001 \001(\005\"\034\n\013"
-      "UInt32Value\022\r\n\005value\030\001 \001(\r\"\032\n\tBoolValue\022"
-      "\r\n\005value\030\001 \001(\010\"\034\n\013StringValue\022\r\n\005value\030\001"
-      " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014B|\n\023com"
-      ".google.protobufB\rWrappersProtoP\001Z*githu"
-      "b.com/golang/protobuf/ptypes/wrappers\370\001\001"
-      "\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypesb"
-      "\006proto3"
+void AddDescriptors_google_2fprotobuf_2fwrappers_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
   };
-  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 447);
-  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
-    "google/protobuf/wrappers.proto", &protobuf_RegisterTypes);
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fwrappers_2eproto, deps, 0);
 }
 
-void AddDescriptors() {
-  static ::google::protobuf::internal::once_flag once;
-  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);
-}
-// Force AddDescriptors() to be called at dynamic initialization time.
-struct StaticDescriptorInitializer {
-  StaticDescriptorInitializer() {
-    AddDescriptors();
-  }
-} static_descriptor_initializer;
-}  // namespace protobuf_google_2fprotobuf_2fwrappers_2eproto
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_google_2fprotobuf_2fwrappers_2eproto = []() { AddDescriptors_google_2fprotobuf_2fwrappers_2eproto(); return true; }();
 namespace google {
 namespace protobuf {
 
@@ -347,21 +322,22 @@
 
 void DoubleValue::InitAsDefaultInstance() {
 }
+class DoubleValue::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int DoubleValue::kValueFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 DoubleValue::DoubleValue()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_DoubleValue.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.DoubleValue)
 }
 DoubleValue::DoubleValue(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_DoubleValue.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.DoubleValue)
@@ -396,13 +372,8 @@
 void DoubleValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* DoubleValue::descriptor() {
-  ::protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const DoubleValue& DoubleValue::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_DoubleValue.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_DoubleValue_google_2fprotobuf_2fwrappers_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -417,9 +388,57 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* DoubleValue::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<DoubleValue*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // double value = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 9) goto handle_unusual;
+        double val;
+        ::std::memcpy(&val, ptr, 8);
+        ptr += 8;
+        msg->set_value(val);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool DoubleValue::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.DoubleValue)
   for (;;) {
@@ -429,8 +448,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // double value = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(9u /* 9 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (9 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
@@ -460,6 +478,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void DoubleValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -472,9 +491,9 @@
     ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->value(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.DoubleValue)
 }
@@ -491,9 +510,9 @@
     target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->value(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DoubleValue)
   return target;
@@ -503,11 +522,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.DoubleValue)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // double value = 1;
   if (this->value() != 0) {
     total_size += 1 + 8;
@@ -522,7 +545,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DoubleValue)
   GOOGLE_DCHECK_NE(&from, this);
   const DoubleValue* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const DoubleValue>(
+      ::google::protobuf::DynamicCastToGenerated<DoubleValue>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.DoubleValue)
@@ -584,13 +607,13 @@
 }
 void DoubleValue::InternalSwap(DoubleValue* other) {
   using std::swap;
-  swap(value_, other->value_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(value_, other->value_);
 }
 
 ::google::protobuf::Metadata DoubleValue::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[kIndexInFileMessages];
 }
 
 
@@ -598,21 +621,22 @@
 
 void FloatValue::InitAsDefaultInstance() {
 }
+class FloatValue::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int FloatValue::kValueFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 FloatValue::FloatValue()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_FloatValue.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.FloatValue)
 }
 FloatValue::FloatValue(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_FloatValue.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.FloatValue)
@@ -647,13 +671,8 @@
 void FloatValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* FloatValue::descriptor() {
-  ::protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const FloatValue& FloatValue::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_FloatValue.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_FloatValue_google_2fprotobuf_2fwrappers_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -668,9 +687,57 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* FloatValue::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<FloatValue*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // float value = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 13) goto handle_unusual;
+        float val;
+        std::memcpy(&val, ptr, 4);
+        ptr += 4;
+        msg->set_value(val);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool FloatValue::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.FloatValue)
   for (;;) {
@@ -680,8 +747,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // float value = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(13u /* 13 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (13 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
@@ -711,6 +777,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void FloatValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -723,9 +790,9 @@
     ::google::protobuf::internal::WireFormatLite::WriteFloat(1, this->value(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.FloatValue)
 }
@@ -742,9 +809,9 @@
     target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(1, this->value(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FloatValue)
   return target;
@@ -754,11 +821,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.FloatValue)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // float value = 1;
   if (this->value() != 0) {
     total_size += 1 + 4;
@@ -773,7 +844,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FloatValue)
   GOOGLE_DCHECK_NE(&from, this);
   const FloatValue* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const FloatValue>(
+      ::google::protobuf::DynamicCastToGenerated<FloatValue>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FloatValue)
@@ -835,13 +906,13 @@
 }
 void FloatValue::InternalSwap(FloatValue* other) {
   using std::swap;
-  swap(value_, other->value_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(value_, other->value_);
 }
 
 ::google::protobuf::Metadata FloatValue::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[kIndexInFileMessages];
 }
 
 
@@ -849,21 +920,22 @@
 
 void Int64Value::InitAsDefaultInstance() {
 }
+class Int64Value::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Int64Value::kValueFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Int64Value::Int64Value()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_Int64Value.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Int64Value)
 }
 Int64Value::Int64Value(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_Int64Value.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.Int64Value)
@@ -877,7 +949,7 @@
 }
 
 void Int64Value::SharedCtor() {
-  value_ = GOOGLE_LONGLONG(0);
+  value_ = GOOGLE_PROTOBUF_LONGLONG(0);
 }
 
 Int64Value::~Int64Value() {
@@ -898,13 +970,8 @@
 void Int64Value::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Int64Value::descriptor() {
-  ::protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Int64Value& Int64Value::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_Int64Value.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Int64Value_google_2fprotobuf_2fwrappers_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -915,13 +982,62 @@
   // Prevent compiler warnings about cached_has_bits being unused
   (void) cached_has_bits;
 
-  value_ = GOOGLE_LONGLONG(0);
+  value_ = GOOGLE_PROTOBUF_LONGLONG(0);
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Int64Value::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Int64Value*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // int64 value = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int64 value = val;
+        msg->set_value(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Int64Value::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Int64Value)
   for (;;) {
@@ -931,8 +1047,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // int64 value = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
@@ -962,6 +1077,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Int64Value::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -974,9 +1090,9 @@
     ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->value(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Int64Value)
 }
@@ -993,9 +1109,9 @@
     target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->value(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Int64Value)
   return target;
@@ -1005,11 +1121,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Int64Value)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // int64 value = 1;
   if (this->value() != 0) {
     total_size += 1 +
@@ -1026,7 +1146,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Int64Value)
   GOOGLE_DCHECK_NE(&from, this);
   const Int64Value* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Int64Value>(
+      ::google::protobuf::DynamicCastToGenerated<Int64Value>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Int64Value)
@@ -1088,13 +1208,13 @@
 }
 void Int64Value::InternalSwap(Int64Value* other) {
   using std::swap;
-  swap(value_, other->value_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(value_, other->value_);
 }
 
 ::google::protobuf::Metadata Int64Value::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[kIndexInFileMessages];
 }
 
 
@@ -1102,21 +1222,22 @@
 
 void UInt64Value::InitAsDefaultInstance() {
 }
+class UInt64Value::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int UInt64Value::kValueFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 UInt64Value::UInt64Value()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_UInt64Value.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.UInt64Value)
 }
 UInt64Value::UInt64Value(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_UInt64Value.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.UInt64Value)
@@ -1130,7 +1251,7 @@
 }
 
 void UInt64Value::SharedCtor() {
-  value_ = GOOGLE_ULONGLONG(0);
+  value_ = GOOGLE_PROTOBUF_ULONGLONG(0);
 }
 
 UInt64Value::~UInt64Value() {
@@ -1151,13 +1272,8 @@
 void UInt64Value::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* UInt64Value::descriptor() {
-  ::protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const UInt64Value& UInt64Value::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_UInt64Value.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_UInt64Value_google_2fprotobuf_2fwrappers_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -1168,13 +1284,62 @@
   // Prevent compiler warnings about cached_has_bits being unused
   (void) cached_has_bits;
 
-  value_ = GOOGLE_ULONGLONG(0);
+  value_ = GOOGLE_PROTOBUF_ULONGLONG(0);
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* UInt64Value::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<UInt64Value*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // uint64 value = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::uint64 value = val;
+        msg->set_value(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool UInt64Value::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.UInt64Value)
   for (;;) {
@@ -1184,8 +1349,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // uint64 value = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
@@ -1215,6 +1379,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void UInt64Value::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -1227,9 +1392,9 @@
     ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->value(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.UInt64Value)
 }
@@ -1246,9 +1411,9 @@
     target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->value(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UInt64Value)
   return target;
@@ -1258,11 +1423,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.UInt64Value)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // uint64 value = 1;
   if (this->value() != 0) {
     total_size += 1 +
@@ -1279,7 +1448,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UInt64Value)
   GOOGLE_DCHECK_NE(&from, this);
   const UInt64Value* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const UInt64Value>(
+      ::google::protobuf::DynamicCastToGenerated<UInt64Value>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.UInt64Value)
@@ -1341,13 +1510,13 @@
 }
 void UInt64Value::InternalSwap(UInt64Value* other) {
   using std::swap;
-  swap(value_, other->value_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(value_, other->value_);
 }
 
 ::google::protobuf::Metadata UInt64Value::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[kIndexInFileMessages];
 }
 
 
@@ -1355,21 +1524,22 @@
 
 void Int32Value::InitAsDefaultInstance() {
 }
+class Int32Value::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Int32Value::kValueFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Int32Value::Int32Value()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_Int32Value.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.Int32Value)
 }
 Int32Value::Int32Value(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_Int32Value.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.Int32Value)
@@ -1404,13 +1574,8 @@
 void Int32Value::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* Int32Value::descriptor() {
-  ::protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const Int32Value& Int32Value::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_Int32Value.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_Int32Value_google_2fprotobuf_2fwrappers_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -1425,9 +1590,58 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Int32Value::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Int32Value*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // int32 value = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::int32 value = val;
+        msg->set_value(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool Int32Value::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.Int32Value)
   for (;;) {
@@ -1437,8 +1651,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // int32 value = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
@@ -1468,6 +1681,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void Int32Value::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -1480,9 +1694,9 @@
     ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->value(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.Int32Value)
 }
@@ -1499,9 +1713,9 @@
     target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->value(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Int32Value)
   return target;
@@ -1511,11 +1725,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.Int32Value)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // int32 value = 1;
   if (this->value() != 0) {
     total_size += 1 +
@@ -1532,7 +1750,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Int32Value)
   GOOGLE_DCHECK_NE(&from, this);
   const Int32Value* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const Int32Value>(
+      ::google::protobuf::DynamicCastToGenerated<Int32Value>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Int32Value)
@@ -1594,13 +1812,13 @@
 }
 void Int32Value::InternalSwap(Int32Value* other) {
   using std::swap;
-  swap(value_, other->value_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(value_, other->value_);
 }
 
 ::google::protobuf::Metadata Int32Value::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[kIndexInFileMessages];
 }
 
 
@@ -1608,21 +1826,22 @@
 
 void UInt32Value::InitAsDefaultInstance() {
 }
+class UInt32Value::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int UInt32Value::kValueFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 UInt32Value::UInt32Value()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_UInt32Value.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.UInt32Value)
 }
 UInt32Value::UInt32Value(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_UInt32Value.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.UInt32Value)
@@ -1657,13 +1876,8 @@
 void UInt32Value::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* UInt32Value::descriptor() {
-  ::protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const UInt32Value& UInt32Value::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_UInt32Value.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_UInt32Value_google_2fprotobuf_2fwrappers_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -1678,9 +1892,58 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* UInt32Value::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<UInt32Value*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // uint32 value = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        ::google::protobuf::uint32 value = val;
+        msg->set_value(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool UInt32Value::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.UInt32Value)
   for (;;) {
@@ -1690,8 +1953,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // uint32 value = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
@@ -1721,6 +1983,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void UInt32Value::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -1733,9 +1996,9 @@
     ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->value(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.UInt32Value)
 }
@@ -1752,9 +2015,9 @@
     target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->value(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UInt32Value)
   return target;
@@ -1764,11 +2027,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.UInt32Value)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // uint32 value = 1;
   if (this->value() != 0) {
     total_size += 1 +
@@ -1785,7 +2052,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UInt32Value)
   GOOGLE_DCHECK_NE(&from, this);
   const UInt32Value* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const UInt32Value>(
+      ::google::protobuf::DynamicCastToGenerated<UInt32Value>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.UInt32Value)
@@ -1847,13 +2114,13 @@
 }
 void UInt32Value::InternalSwap(UInt32Value* other) {
   using std::swap;
-  swap(value_, other->value_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(value_, other->value_);
 }
 
 ::google::protobuf::Metadata UInt32Value::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[kIndexInFileMessages];
 }
 
 
@@ -1861,21 +2128,22 @@
 
 void BoolValue::InitAsDefaultInstance() {
 }
+class BoolValue::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int BoolValue::kValueFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 BoolValue::BoolValue()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_BoolValue.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.BoolValue)
 }
 BoolValue::BoolValue(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_BoolValue.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.BoolValue)
@@ -1910,13 +2178,8 @@
 void BoolValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* BoolValue::descriptor() {
-  ::protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const BoolValue& BoolValue::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_BoolValue.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_BoolValue_google_2fprotobuf_2fwrappers_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -1931,9 +2194,58 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* BoolValue::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<BoolValue*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // bool value = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val;
+        ptr = Varint::Parse64(ptr, &val);
+        if (!ptr) goto error;
+        bool value = val;
+        msg->set_value(value);
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool BoolValue::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.BoolValue)
   for (;;) {
@@ -1943,8 +2255,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // bool value = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
 
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
@@ -1974,6 +2285,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void BoolValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -1986,9 +2298,9 @@
     ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->value(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.BoolValue)
 }
@@ -2005,9 +2317,9 @@
     target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->value(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.BoolValue)
   return target;
@@ -2017,11 +2329,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.BoolValue)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // bool value = 1;
   if (this->value() != 0) {
     total_size += 1 + 1;
@@ -2036,7 +2352,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.BoolValue)
   GOOGLE_DCHECK_NE(&from, this);
   const BoolValue* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const BoolValue>(
+      ::google::protobuf::DynamicCastToGenerated<BoolValue>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.BoolValue)
@@ -2098,13 +2414,13 @@
 }
 void BoolValue::InternalSwap(BoolValue* other) {
   using std::swap;
-  swap(value_, other->value_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(value_, other->value_);
 }
 
 ::google::protobuf::Metadata BoolValue::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[kIndexInFileMessages];
 }
 
 
@@ -2112,21 +2428,22 @@
 
 void StringValue::InitAsDefaultInstance() {
 }
+class StringValue::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int StringValue::kValueFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 StringValue::StringValue()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_StringValue.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.StringValue)
 }
 StringValue::StringValue(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_StringValue.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.StringValue)
@@ -2144,6 +2461,8 @@
 }
 
 void StringValue::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_StringValue_google_2fprotobuf_2fwrappers_2eproto.base);
   value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 
@@ -2166,13 +2485,8 @@
 void StringValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* StringValue::descriptor() {
-  ::protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const StringValue& StringValue::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_StringValue.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_StringValue_google_2fprotobuf_2fwrappers_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -2187,9 +2501,64 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* StringValue::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<StringValue*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // string value = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        ctx->extra_parse_data().SetFieldName("google.protobuf.StringValue.value");
+        parser_till_end = ::google::protobuf::internal::StringParserUTF8;
+        ::std::string* str = msg->mutable_value();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool StringValue::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.StringValue)
   for (;;) {
@@ -2199,8 +2568,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // string value = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_value()));
           DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
@@ -2232,6 +2600,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void StringValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -2249,9 +2618,9 @@
       1, this->value(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.StringValue)
 }
@@ -2274,9 +2643,9 @@
         1, this->value(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.StringValue)
   return target;
@@ -2286,11 +2655,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.StringValue)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // string value = 1;
   if (this->value().size() > 0) {
     total_size += 1 +
@@ -2307,7 +2680,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.StringValue)
   GOOGLE_DCHECK_NE(&from, this);
   const StringValue* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const StringValue>(
+      ::google::protobuf::DynamicCastToGenerated<StringValue>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.StringValue)
@@ -2369,14 +2742,14 @@
 }
 void StringValue::InternalSwap(StringValue* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   value_.Swap(&other->value_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata StringValue::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[kIndexInFileMessages];
 }
 
 
@@ -2384,21 +2757,22 @@
 
 void BytesValue::InitAsDefaultInstance() {
 }
+class BytesValue::HasBitSetters {
+ public:
+};
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int BytesValue::kValueFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 BytesValue::BytesValue()
   : ::google::protobuf::Message(), _internal_metadata_(NULL) {
-  ::google::protobuf::internal::InitSCC(
-      &protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_BytesValue.base);
   SharedCtor();
   // @@protoc_insertion_point(constructor:google.protobuf.BytesValue)
 }
 BytesValue::BytesValue(::google::protobuf::Arena* arena)
   : ::google::protobuf::Message(),
   _internal_metadata_(arena) {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_BytesValue.base);
   SharedCtor();
   RegisterArenaDtor(arena);
   // @@protoc_insertion_point(arena_constructor:google.protobuf.BytesValue)
@@ -2416,6 +2790,8 @@
 }
 
 void BytesValue::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_BytesValue_google_2fprotobuf_2fwrappers_2eproto.base);
   value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 
@@ -2438,13 +2814,8 @@
 void BytesValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
 }
-const ::google::protobuf::Descriptor* BytesValue::descriptor() {
-  ::protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor;
-}
-
 const BytesValue& BytesValue::default_instance() {
-  ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fwrappers_2eproto::scc_info_BytesValue.base);
+  ::google::protobuf::internal::InitSCC(&::scc_info_BytesValue_google_2fprotobuf_2fwrappers_2eproto.base);
   return *internal_default_instance();
 }
 
@@ -2459,9 +2830,63 @@
   _internal_metadata_.Clear();
 }
 
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* BytesValue::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<BytesValue*>(object);
+  ::google::protobuf::uint32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ::google::protobuf::uint32 tag;
+    ptr = Varint::Parse32Inline(ptr, &tag);
+    if (!ptr) goto error;
+    switch (tag >> 3) {
+      case 0: goto error;
+      // bytes value = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = Varint::Parse32Inline(ptr, &size);
+        if (!ptr) goto error;
+        parser_till_end = ::google::protobuf::internal::StringParser;
+        ::std::string* str = msg->mutable_value();
+        str->clear();
+        object = str;
+        if (size > end - ptr) goto len_delim_till_end;
+        auto newend = ptr + size;
+        if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) goto error;
+        ptr = newend;
+        break;
+      }
+      default: {
+      handle_unusual: (void)&&handle_unusual;
+        if ((tag & 7) == 4) {
+          if (!ctx->ValidEndGroup(tag)) goto error;
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+error:
+  return nullptr;
+len_delim_till_end: (void)&&len_delim_till_end;
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                                 {parser_till_end, object}, size);
+group_continues: (void)&&group_continues;
+  GOOGLE_DCHECK(ptr >= end);
+  ctx->StoreGroup({_InternalParse, msg}, {parser_till_end, object}, depth);
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 bool BytesValue::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:google.protobuf.BytesValue)
   for (;;) {
@@ -2471,8 +2896,7 @@
     switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
       // bytes value = 1;
       case 1: {
-        if (static_cast< ::google::protobuf::uint8>(tag) ==
-            static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                 input, this->mutable_value()));
         } else {
@@ -2500,6 +2924,7 @@
   return false;
 #undef DO_
 }
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 
 void BytesValue::SerializeWithCachedSizes(
     ::google::protobuf::io::CodedOutputStream* output) const {
@@ -2513,9 +2938,9 @@
       1, this->value(), output);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), output);
+        _internal_metadata_.unknown_fields(), output);
   }
   // @@protoc_insertion_point(serialize_end:google.protobuf.BytesValue)
 }
@@ -2534,9 +2959,9 @@
         1, this->value(), target);
   }
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()), target);
+        _internal_metadata_.unknown_fields(), target);
   }
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.BytesValue)
   return target;
@@ -2546,11 +2971,15 @@
 // @@protoc_insertion_point(message_byte_size_start:google.protobuf.BytesValue)
   size_t total_size = 0;
 
-  if ((_internal_metadata_.have_unknown_fields() &&  ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())) {
+  if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        (::google::protobuf::internal::GetProto3PreserveUnknownsDefault()   ? _internal_metadata_.unknown_fields()   : _internal_metadata_.default_instance()));
+        _internal_metadata_.unknown_fields());
   }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
   // bytes value = 1;
   if (this->value().size() > 0) {
     total_size += 1 +
@@ -2567,7 +2996,7 @@
 // @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.BytesValue)
   GOOGLE_DCHECK_NE(&from, this);
   const BytesValue* source =
-      ::google::protobuf::internal::DynamicCastToGenerated<const BytesValue>(
+      ::google::protobuf::DynamicCastToGenerated<BytesValue>(
           &from);
   if (source == NULL) {
   // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.BytesValue)
@@ -2629,14 +3058,14 @@
 }
 void BytesValue::InternalSwap(BytesValue* other) {
   using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
   value_.Swap(&other->value_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
     GetArenaNoVirtual());
-  _internal_metadata_.Swap(&other->_internal_metadata_);
 }
 
 ::google::protobuf::Metadata BytesValue::GetMetadata() const {
-  protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce();
-  return ::protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages];
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_google_2fprotobuf_2fwrappers_2eproto);
+  return ::file_level_metadata_google_2fprotobuf_2fwrappers_2eproto[kIndexInFileMessages];
 }
 
 
diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h
index 82f5627..dcf4edf 100644
--- a/src/google/protobuf/wrappers.pb.h
+++ b/src/google/protobuf/wrappers.pb.h
@@ -4,18 +4,18 @@
 #ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2fwrappers_2eproto
 #define PROTOBUF_INCLUDED_google_2fprotobuf_2fwrappers_2eproto
 
+#include <limits>
 #include <string>
 
 #include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 3006001
+#if GOOGLE_PROTOBUF_VERSION < 3006000
 #error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please update
+#error incompatible with your Protocol Buffer headers. Please update
 #error your headers.
 #endif
 #if 3006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
 #error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers.  Please
+#error incompatible with your Protocol Buffer headers. Please
 #error regenerate this file with a newer version of protoc.
 #endif
 
@@ -31,20 +31,22 @@
 #include <google/protobuf/extension_set.h>  // IWYU pragma: export
 #include <google/protobuf/unknown_field_set.h>
 // @@protoc_insertion_point(includes)
-#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fwrappers_2eproto LIBPROTOBUF_EXPORT
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fwrappers_2eproto LIBPROTOBUF_EXPORT
 
-namespace protobuf_google_2fprotobuf_2fwrappers_2eproto {
 // Internal implementation detail -- do not use these members.
-struct LIBPROTOBUF_EXPORT TableStruct {
-  static const ::google::protobuf::internal::ParseTableField entries[];
-  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
-  static const ::google::protobuf::internal::ParseTable schema[9];
+struct LIBPROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fwrappers_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[9]
+    GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
   static const ::google::protobuf::uint32 offsets[];
 };
-void LIBPROTOBUF_EXPORT AddDescriptors();
-}  // namespace protobuf_google_2fprotobuf_2fwrappers_2eproto
+void LIBPROTOBUF_EXPORT AddDescriptors_google_2fprotobuf_2fwrappers_2eproto();
 namespace google {
 namespace protobuf {
 class BoolValue;
@@ -74,10 +76,6 @@
 class UInt64Value;
 class UInt64ValueDefaultTypeInternal;
 LIBPROTOBUF_EXPORT extern UInt64ValueDefaultTypeInternal _UInt64Value_default_instance_;
-}  // namespace protobuf
-}  // namespace google
-namespace google {
-namespace protobuf {
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::BoolValue* Arena::CreateMaybeMessage<::google::protobuf::BoolValue>(Arena*);
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::BytesValue* Arena::CreateMaybeMessage<::google::protobuf::BytesValue>(Arena*);
 template<> LIBPROTOBUF_EXPORT ::google::protobuf::DoubleValue* Arena::CreateMaybeMessage<::google::protobuf::DoubleValue>(Arena*);
@@ -126,7 +124,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const DoubleValue& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -160,8 +160,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -201,6 +206,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.DoubleValue)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -208,7 +214,7 @@
   typedef void DestructorSkippable_;
   double value_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -244,7 +250,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const FloatValue& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -278,8 +286,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -319,6 +332,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.FloatValue)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -326,7 +340,7 @@
   typedef void DestructorSkippable_;
   float value_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -362,7 +376,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Int64Value& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -396,8 +412,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -437,6 +458,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Int64Value)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -444,7 +466,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::int64 value_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -480,7 +502,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const UInt64Value& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -514,8 +538,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -555,6 +584,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.UInt64Value)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -562,7 +592,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::uint64 value_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -598,7 +628,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const Int32Value& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -632,8 +664,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -673,6 +710,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.Int32Value)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -680,7 +718,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::int32 value_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -716,7 +754,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const UInt32Value& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -750,8 +790,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -791,6 +836,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.UInt32Value)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -798,7 +844,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::uint32 value_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -834,7 +880,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const BoolValue& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -868,8 +916,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -909,6 +962,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.BoolValue)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -916,7 +970,7 @@
   typedef void DestructorSkippable_;
   bool value_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -952,7 +1006,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const StringValue& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -986,8 +1042,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -1032,11 +1093,11 @@
   ::std::string* mutable_value();
   ::std::string* release_value();
   void set_allocated_value(::std::string* value);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_value();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_value(
@@ -1044,6 +1105,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.StringValue)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -1051,7 +1113,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::internal::ArenaStringPtr value_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
 };
 // -------------------------------------------------------------------
 
@@ -1087,7 +1149,9 @@
   inline void* GetMaybeArenaPointer() const final {
     return MaybeArenaPtr();
   }
-  static const ::google::protobuf::Descriptor* descriptor();
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
   static const BytesValue& default_instance();
 
   static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
@@ -1121,8 +1185,13 @@
   bool IsInitialized() const final;
 
   size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
   bool MergePartialFromCodedStream(
       ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const final;
   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
@@ -1167,11 +1236,11 @@
   ::std::string* mutable_value();
   ::std::string* release_value();
   void set_allocated_value(::std::string* value);
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   ::std::string* unsafe_arena_release_value();
-  PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
+  GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for"
   "    string fields are deprecated and will be removed in a"
   "    future release.")
   void unsafe_arena_set_allocated_value(
@@ -1179,6 +1248,7 @@
 
   // @@protoc_insertion_point(class_scope:google.protobuf.BytesValue)
  private:
+  class HasBitSetters;
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   template <typename T> friend class ::google::protobuf::Arena::InternalHelper;
@@ -1186,7 +1256,7 @@
   typedef void DestructorSkippable_;
   ::google::protobuf::internal::ArenaStringPtr value_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
-  friend struct ::protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct;
+  friend struct ::TableStruct_google_2fprotobuf_2fwrappers_2eproto;
 };
 // ===================================================================
 
@@ -1237,7 +1307,7 @@
 
 // int64 value = 1;
 inline void Int64Value::clear_value() {
-  value_ = GOOGLE_LONGLONG(0);
+  value_ = GOOGLE_PROTOBUF_LONGLONG(0);
 }
 inline ::google::protobuf::int64 Int64Value::value() const {
   // @@protoc_insertion_point(field_get:google.protobuf.Int64Value.value)
@@ -1255,7 +1325,7 @@
 
 // uint64 value = 1;
 inline void UInt64Value::clear_value() {
-  value_ = GOOGLE_ULONGLONG(0);
+  value_ = GOOGLE_PROTOBUF_ULONGLONG(0);
 }
 inline ::google::protobuf::uint64 UInt64Value::value() const {
   // @@protoc_insertion_point(field_get:google.protobuf.UInt64Value.value)
@@ -1506,4 +1576,5 @@
 
 // @@protoc_insertion_point(global_scope)
 
+#include <google/protobuf/port_undef.inc>
 #endif  // PROTOBUF_INCLUDED_google_2fprotobuf_2fwrappers_2eproto
diff --git a/src/google/protobuf/wrappers.proto b/src/google/protobuf/wrappers.proto
index 0194763..1940fd1 100644
--- a/src/google/protobuf/wrappers.proto
+++ b/src/google/protobuf/wrappers.proto
@@ -32,6 +32,11 @@
 // for embedding primitives in the `google.protobuf.Any` type and for places
 // where we need to distinguish between the absence of a primitive
 // typed field and its default value.
+//
+// These wrappers have no meaningful use within repeated fields as they lack
+// the ability to detect presence on individual elements.
+// These wrappers have no meaningful use within a map or a oneof since individual
+// entries of a map or fields of a oneof can already detect presence.
 
 syntax = "proto3";
 
diff --git a/tests.sh b/tests.sh
index 5bb8ae3..f0c83f7 100755
--- a/tests.sh
+++ b/tests.sh
@@ -18,12 +18,12 @@
   ./autogen.sh
   ./configure CXXFLAGS="-fPIC"  # -fPIC is needed for python cpp test.
                                 # See python/setup.py for more details
-  make -j2
+  make -j4
 }
 
 build_cpp() {
   internal_build_cpp
-  make check -j2 || (cat src/test-suite.log; false)
+  make check -j4 || (cat src/test-suite.log; false)
   cd conformance && make test_cpp && cd ..
 
   # The benchmark code depends on cmake, so test if it is installed before
@@ -56,10 +56,10 @@
   # Check if every file exists in the dist tar file.
   FILES_MISSING=""
   for FILE in $(<../dist.lst); do
-    if ! file $FILE &>/dev/null; then
+    [ -f "$FILE" ] || {
       echo "$FILE is not found!"
       FILES_MISSING="$FILE $FILES_MISSING"
-    fi
+    }
   done
   cd ..
   if [ ! -z "$FILES_MISSING" ]; then
@@ -68,7 +68,7 @@
   fi
 
   # Do the regular dist-check for C++.
-  make distcheck -j2
+  make distcheck -j4
 }
 
 build_csharp() {