Merge branch '3.6.x' into merge-3-6-x
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..2f6d026
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,28 @@
+---
+name: Bug report
+about: Create a report to help us improve
+
+---
+
+**What version of protobuf and what language are you using?**
+Version: master/v3.6.0/v3.5.0 etc.
+Language: C++/Java/Python/C#/Ruby/PHP/Objective-C/Javascript
+
+**What operating system (Linux, Windows, ...) and version?**
+
+**What runtime / compiler are you using (e.g., python version or gcc version)**
+
+**What did you do?**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**What did you expect to see**
+
+**What did you see instead?**
+
+Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs).
+
+**Anything else we should know about your project / environment**
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..722db4c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,18 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+
+---
+
+**What language does this apply to?**
+If it's a proto syntax change, is it for proto2 or proto3?
+If it's about generated code change, what programming language?
+
+**Describe the problem you are trying to solve.**
+
+**Describe the solution you'd like**
+
+**Describe alternatives you've considered**
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md
new file mode 100644
index 0000000..bfa6dde
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/question.md
@@ -0,0 +1,7 @@
+---
+name: Question
+about: Questions and troubleshooting
+
+---
+
+
diff --git a/.gitignore b/.gitignore
index db8a893..f22ba00 100644
--- a/.gitignore
+++ b/.gitignore
@@ -186,3 +186,6 @@
 # Common build subdirectories.
 ./.build/
 ./_build/
+
+# Visual Studio 2017
+.vs
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 74d4ea7..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,90 +0,0 @@
-# Everything is driven by the test.sh, so the language doesn't really
-# matter, it just controls the default install/script/etc. steps on
-# travis.
-language: cpp
-script: ./tests.sh $CONFIG
-
-# The test matrix is manually built to cover a mix of linux and macOS
-# hosted setups; this lets some extra settings be done specific to each
-# host/language instead of forcing common values on all the tests.
-matrix:
-  include:
-    # -----------------------------------------------------------------
-    # macOS hosted tests for Objective-C
-
-    - os: osx
-      env: CONFIG=objectivec_osx
-      osx_image: xcode9.3
-      language: objective-c
-    # iOS build log was starting to choke travis UI, so split to cover the
-    # Xcode Debug and Release Configurations independently.
-    - os: osx
-      env: CONFIG=objectivec_ios_debug
-      osx_image: xcode9.3
-      language: objective-c
-    - os: osx
-      env: CONFIG=objectivec_ios_release
-      osx_image: xcode9.3
-      language: objective-c
-    - os: osx
-      env: CONFIG=objectivec_cocoapods_integration
-      osx_image: xcode9.3
-      language: objective-c
-
-    # -----------------------------------------------------------------
-    # macOS hosted tests for other languages.
-
-    - os: osx
-      env: CONFIG=cpp
-    - os: osx
-      env: CONFIG=cpp_distcheck
-    - os: osx
-      env: CONFIG=javascript
-    - os: osx
-      env: CONFIG=python
-    - os: osx
-      env: CONFIG=python_cpp
-    - os: osx
-      env: CONFIG=php5.6_mac
-    - os: osx
-      env: CONFIG=php7.0_mac
-
-    # -----------------------------------------------------------------
-    # Linux hosted tests
-
-    # The dotnet environment requires Ubuntu 14.04 or 16.04. This
-    # configuration is effectively an "extra" one, outside the
-    # autogenerated matrix.
-    - os: linux
-      env: CONFIG=csharp
-      language: csharp
-      dist: trusty
-      dotnet: 2.0.3
-      mono: none
-      # Install the .NET Core 1.0 runtime as that's what we test against
-      addons:
-        apt:
-          sources:
-          - sourceline: 'deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-trusty-prod trusty main'
-            key_url: 'https://packages.microsoft.com/keys/microsoft.asc'
-          packages:
-          - dotnet-sharedframework-microsoft.netcore.app-1.0.5
-    # This test is kept on travis because it doesn't play nicely with other
-    # tests on jenkins running in parallel.
-    - os: linux
-      env: CONFIG=cpp_distcheck
-    # The Java compatibility test currently only runs on Linux because it will
-    # fetch pre-built Linux protoc binaries in the test.
-    - os: linux
-      env: CONFIG=java_compatibility
-      sudo: required
-      dist: trusty
-    # The Python compatibility test currently only runs on Linux because it will
-    # fetch pre-built Linux protoc binaries in the test.
-    - os: linux
-      env: CONFIG=python_compatibility
-      sudo: required
-      dist: trusty
-
-notifications:
-  email: false
diff --git a/BUILD b/BUILD
index 19f07c5..884e32f 100644
--- a/BUILD
+++ b/BUILD
@@ -1,4 +1,4 @@
-# Bazel (http://bazel.io/) BUILD file for Protobuf.
+# Bazel (https://bazel.build/) BUILD file for Protobuf.
 
 licenses(["notice"])
 
@@ -22,7 +22,20 @@
 MSVC_COPTS = [
     "/DHAVE_PTHREAD",
     "/wd4018", # -Wno-sign-compare
+    "/wd4065", # switch statement contains 'default' but no 'case' labels
+    "/wd4146", # unary minus operator applied to unsigned type, result still unsigned
+    "/wd4244", # 'conversion' conversion from 'type1' to 'type2', possible loss of data
+    "/wd4251", # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2'
+    "/wd4267", # 'var' : conversion from 'size_t' to 'type', possible loss of data
+    "/wd4305", # 'identifier' : truncation from 'type1' to 'type2'
+    "/wd4307", # 'operator' : integral constant overflow
+    "/wd4309", # 'conversion' : truncation of constant value
+    "/wd4334", # 'operator' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
+    "/wd4355", # 'this' : used in base member initializer list
+    "/wd4506", # no definition for inline function 'function'
     "/wd4514", # -Wno-unused-function
+    "/wd4800", # 'type' : forcing value to bool 'true' or 'false' (performance warning)
+    "/wd4996", # The compiler encountered a deprecated declaration.
 ]
 
 COPTS = select({
@@ -30,12 +43,12 @@
     "//conditions:default": [
         "-DHAVE_PTHREAD",
         "-Wall",
-        "-Wwrite-strings",
         "-Woverloaded-virtual",
         "-Wno-sign-compare",
         "-Wno-unused-function",
         # Prevents ISO C++ const string assignment warnings for pyext sources.
         "-Wno-writable-strings",
+        "-Wno-write-strings",
     ],
 })
 
@@ -54,7 +67,10 @@
 # Android and MSVC builds do not need to link in a separate pthread library.
 LINK_OPTS = select({
     ":android": [],
-    ":msvc": [],
+    ":msvc": [
+        # Suppress linker warnings about files with no symbols defined.
+        "-ignore:4221",
+    ],
     "//conditions:default": ["-lpthread", "-lm"],
 })
 
@@ -306,8 +322,6 @@
         "src/google/protobuf/compiler/java/java_generator.cc",
         "src/google/protobuf/compiler/java/java_generator_factory.cc",
         "src/google/protobuf/compiler/java/java_helpers.cc",
-        "src/google/protobuf/compiler/java/java_lazy_message_field.cc",
-        "src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc",
         "src/google/protobuf/compiler/java/java_map_field.cc",
         "src/google/protobuf/compiler/java/java_map_field_lite.cc",
         "src/google/protobuf/compiler/java/java_message.cc",
@@ -347,7 +361,25 @@
     ],
     copts = COPTS,
     includes = ["src/"],
-    linkopts = LINK_OPTS,
+    linkopts = LINK_OPTS + select({
+        ":msvc": [
+            # Linking to setargv.obj makes the default command line argument
+            # parser expand wildcards, so the main method's argv will contain the
+            # expanded list instead of the wildcards.
+            #
+            # Adding dummy "-DEFAULTLIB:kernel32.lib", because:
+            # - Microsoft ships this object file next to default libraries
+            # - but this file is not a library, just a precompiled object
+            # - "-WHOLEARCHIVE" and "-DEFAULTLIB" only accept library,
+            #   not precompiled object.
+            # - Bazel would assume linkopt that does not start with "-" or "$"
+            #   as a label to a target, so we add a harmless "-DEFAULTLIB:kernel32.lib"
+            #   before "setargv.obj".
+            # See https://msdn.microsoft.com/en-us/library/8bch7bkk.aspx
+            "-DEFAULTLIB:kernel32.lib setargv.obj",
+        ],
+        "//conditions:default": [],
+    }),
     visibility = ["//visibility:public"],
     deps = [":protobuf"],
 )
@@ -610,6 +642,7 @@
     name = "python_srcs",
     srcs = glob(
         [
+            "python/google/__init__.py",
             "python/google/protobuf/*.py",
             "python/google/protobuf/**/*.py",
         ],
@@ -658,6 +691,7 @@
     linkstatic = 1,
     deps = [
         ":protobuf",
+        ":proto_api",
     ] + select({
         "//conditions:default": [],
         ":use_fast_cpp_protos": ["//external:python_headers"],
@@ -800,6 +834,15 @@
     deps = [":python_tests"],
 )
 
+cc_library(
+    name = "proto_api",
+    hdrs = ["python/google/protobuf/proto_api.h"],
+    deps = [
+        "//external:python_headers",
+    ],
+    visibility = ["//visibility:public"],
+)
+
 proto_lang_toolchain(
     name = "cc_toolchain",
     command_line = "--cpp_out=$(OUT)",
@@ -889,9 +932,41 @@
 objc_library(
     name = "objectivec",
     hdrs = OBJC_HDRS + OBJC_PRIVATE_HDRS,
+    copts = [
+        "-Wno-vla",
+    ],
     includes = [
         "objectivec",
     ],
     non_arc_srcs = OBJC_SRCS,
     visibility = ["//visibility:public"],
 )
+
+################################################################################
+# Test generated proto support
+################################################################################
+
+genrule(
+    name = "generated_protos",
+    srcs = ["src/google/protobuf/unittest_import.proto"],
+    outs = ["unittest_gen.proto"],
+    cmd = "cat $(SRCS) | sed 's|google/|src/google/|' >  $(OUTS)"
+)
+
+proto_library(
+    name = "generated_protos_proto",
+    srcs = [
+        "unittest_gen.proto",
+        "src/google/protobuf/unittest_import_public.proto",
+    ],
+)
+
+py_proto_library(
+    name = "generated_protos_py",
+    srcs = [
+        "unittest_gen.proto",
+        "src/google/protobuf/unittest_import_public.proto",
+    ],
+    default_runtime = "",
+    protoc = ":protoc",
+)
diff --git a/Makefile.am b/Makefile.am
index ae4ac85..24f520c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -51,6 +51,7 @@
 csharp_EXTRA_DIST=                                                           \
   csharp/.gitignore                                                          \
   csharp/CHANGES.txt                                                         \
+  csharp/Google.Protobuf.Tools.targets                                       \
   csharp/Google.Protobuf.Tools.nuspec                                        \
   csharp/README.md                                                           \
   csharp/build_packages.bat                                                  \
@@ -804,6 +805,7 @@
   python/google/protobuf/message.py                                          \
   python/google/protobuf/message_factory.py                                  \
   python/google/protobuf/python_protobuf.h                                   \
+  python/google/protobuf/proto_api.h                                         \
   python/google/protobuf/proto_builder.py                                    \
   python/google/protobuf/pyext/README                                        \
   python/google/protobuf/pyext/__init__.py                                   \
@@ -933,6 +935,7 @@
   js/commonjs/import_test.js                                           \
   js/commonjs/jasmine.json                                             \
   js/commonjs/rewrite_tests_for_commonjs.js                            \
+  js/commonjs/strict_test.js                                           \
   js/commonjs/test6/test6.proto                                        \
   js/commonjs/test7/test7.proto                                        \
   js/compatibility_tests/v3.0.0/binary/arith_test.js                   \
@@ -1004,6 +1007,8 @@
   js/test4.proto                                                       \
   js/test5.proto                                                       \
   js/test8.proto                                                       \
+  js/test9.proto                                                       \
+  js/test10.proto                                                      \
   js/test_bootstrap.js                                                 \
   js/testbinary.proto                                                  \
   js/testempty.proto
@@ -1036,6 +1041,7 @@
   cmake/protobuf.pc.cmake                \
   cmake/protoc.cmake                     \
   cmake/tests.cmake                      \
+  cmake/version.rc.in                    \
   editors/README.txt                     \
   editors/proto.vim                      \
   editors/protobuf-mode.el               \
diff --git a/README.md b/README.md
index 1a45ee6..f0f2e32 100644
--- a/README.md
+++ b/README.md
@@ -60,7 +60,7 @@
 | 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) | |
 | C#                                   | [csharp](csharp)                                            | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-csharp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fcsharp%2Fcontinuous) | | [![Build status](https://ci.appveyor.com/api/projects/status/73ctee6ua4w2ruin?svg=true)](https://ci.appveyor.com/project/protobuf/protobuf) |
 | JavaScript                           | [js](js)                                                    | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-javascript.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fjavascript%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-javascript.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fjavascript%2Fcontinuous) | |
-| Ruby                                 | [ruby](ruby)                                                | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby_all.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby_all%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby21.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby21%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby22.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby22%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-jruby.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fjruby%2Fcontinuous) | |
+| Ruby                                 | [ruby](ruby)                                                | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby_all.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby_all%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby21.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby21%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby22.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby22%2Fcontinuous) | |
 | Go                                   | [golang/protobuf](https://github.com/golang/protobuf)       | | | |
 | PHP                                  | [php](php)                                                  | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-php_all.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fphp_all%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-32-bit.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2F32-bit%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-php5.6_mac.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fphp5.6_mac%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-php7.0_mac.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fphp7.0_mac%2Fcontinuous) | |
 | Dart                                 | [dart-lang/protobuf](https://github.com/dart-lang/protobuf) | | | |
diff --git a/WORKSPACE b/WORKSPACE
index 06a8a84..f302084 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,16 +1,24 @@
 workspace(name = "com_google_protobuf")
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
 
 new_local_repository(
     name = "submodule_gmock",
     path = "third_party/googletest",
-    build_file = "third_party/googletest/BUILD.bazel"
+    build_file = "@//:third_party/googletest/BUILD.bazel"
 )
 
-new_http_archive(
+http_archive(
     name = "six_archive",
-    build_file = "six.BUILD",
+    build_file = "@//:six.BUILD",
     sha256 = "105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a",
-    url = "https://pypi.python.org/packages/source/s/six/six-1.10.0.tar.gz#md5=34eed507548117b2ab523ab14b2f8b55",
+    urls = ["https://pypi.python.org/packages/source/s/six/six-1.10.0.tar.gz#md5=34eed507548117b2ab523ab14b2f8b55"],
+)
+
+http_archive(
+    name = "bazel_skylib",
+    sha256 = "bbccf674aa441c266df9894182d80de104cabd19be98be002f6d478aaa31574d",
+    strip_prefix = "bazel-skylib-2169ae1c374aab4a09aa90e65efe1a3aad4e279b",
+    urls = ["https://github.com/bazelbuild/bazel-skylib/archive/2169ae1c374aab4a09aa90e65efe1a3aad4e279b.tar.gz"],
 )
 
 bind(
diff --git a/appveyor.bat b/appveyor.bat
index e59ebcc..29ec492 100644
--- a/appveyor.bat
+++ b/appveyor.bat
@@ -1,11 +1,23 @@
 setlocal
 
+IF %platform%==MinGW GOTO build_mingw
 IF %language%==cpp GOTO build_cpp
 IF %language%==csharp GOTO build_csharp
 
-echo Unsupported language %language%. Exiting.
+echo Unsupported language %language% and platform %platform%. Exiting.
 goto :error
 
+:build_mingw
+echo Building MinGW
+set PATH=C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH:C:\Program Files\Git\usr\bin;=%
+mkdir build_mingw
+cd build_mingw
+cmake -G "%generator%" -Dprotobuf_BUILD_SHARED_LIBS=%BUILD_DLL% -Dprotobuf_UNICODE=%UNICODE% -Dprotobuf_BUILD_TESTS=0 ../cmake
+mingw32-make -j8 all || goto error
+rem cd %configuration%
+rem tests.exe || goto error
+goto :EOF
+
 :build_cpp
 echo Building C++
 mkdir build_msvc
diff --git a/appveyor.yml b/appveyor.yml
index 9644e06..91f737a 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,22 +1,29 @@
-platform:
-  - Win64
-
 configuration:
   - Debug
 
 environment:
   matrix:
-    - language: cpp
+    # Only test few combinations: "Visual Studio 2015 (14) + Win64/MinGW + Debug + DLL". We can
+    # test more combinations but AppVeyor just takes too long to finish (each
+    # combination takes ~15mins).
+    - platform: MinGW
+      language: cpp
+      image: Visual Studio 2015
+
+    - platform: Win64
+      language: cpp
       image: Visual Studio 2015
       BUILD_DLL: ON
       UNICODE: ON
 
-    - language: cpp
+    - platform: Win64
+      language: cpp
       image: Visual Studio 2017
       BUILD_DLL: OFF
       UNICODE: ON
 
-    - language: csharp
+    - platform: Win64
+      language: csharp
       image: Visual Studio 2017
 
 # Our build scripts run tests automatically; we don't want AppVeyor
@@ -27,6 +34,7 @@
   - git submodule update --init --recursive
 
 before_build:
+  - if %platform%==MinGW set generator=MinGW Makefiles
   - if %platform%==Win32 set generator=Visual Studio 14
   - if %platform%==Win64 set generator=Visual Studio 14 Win64
   - if %platform%==Win32 set vcplatform=Win32
diff --git a/benchmarks/Makefile.am b/benchmarks/Makefile.am
index 3ae14ff..4f7df64 100644
--- a/benchmarks/Makefile.am
+++ b/benchmarks/Makefile.am
@@ -36,7 +36,7 @@
 	oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd/cpp --java_out=$$oldpwd/tmp/java/src/main/java --python_out=$$oldpwd/tmp $(benchmarks_protoc_inputs_proto2) )
 	touch protoc_middleman2
 
-all_data = $$(find $(srcdir) -type f -name "dataset.*.pb" -not -path "./tmp/*")
+all_data = $$(find $$(cd $(srcdir) && pwd) -type f -name "dataset.*.pb" -not -path "$$(cd $(srcdir) && pwd)/tmp/*")
 
 ############# CPP RULES ##############
 
@@ -90,8 +90,7 @@
 
 initialize_submodule:
 	oldpwd=`pwd`
-	cd $(top_srcdir)/third_party
-	git submodule update --init -r
+	cd $(top_srcdir) && git submodule update --init -r third_party/benchmark
 	cd $(top_srcdir)/third_party/benchmark && cmake -DCMAKE_BUILD_TYPE=Release && make
 	cd $$oldpwd
 	touch initialize_submodule
@@ -127,8 +126,10 @@
 	java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java
 
 javac_middleman: $(java_benchmark_testing_files) protoc_middleman protoc_middleman2
-	cp -r $(srcdir)/java tmp && cd tmp/java &&  mvn clean compile assembly:single
-	cd ../..
+	cp -r $(srcdir)/java tmp 
+	mkdir -p tmp/java/lib
+	cp $(top_srcdir)/java/core/target/*.jar tmp/java/lib/protobuf-java.jar
+	cd tmp/java && mvn clean compile assembly:single -Dprotobuf.version=$(PACKAGE_VERSION) && cd ../..
 	@touch javac_middleman
 
 java-benchmark: javac_middleman
@@ -138,10 +139,10 @@
 	@echo 'conf=()' >> java-benchmark
 	@echo 'data_files=""' >> java-benchmark
 	@echo 'for arg in $$@; do if [[ $${arg:0:1} == "-" ]]; then conf+=($$arg); else data_files+="$$arg,"; fi; done' >> java-benchmark
-	@echo 'java -cp '"tmp/java/target/*.jar"' com.google.caliper.runner.CaliperMain com.google.protobuf.ProtoCaliperBenchmark -i runtime '"\\"  >> java-benchmark
-	@echo '-b serializeToByteString,serializeToByteArray,serializeToMemoryStream,'"\\"  >> java-benchmark
-	@echo 'deserializeFromByteString,deserializeFromByteArray,deserializeFromMemoryStream '"\\" >> java-benchmark
-	@echo '-DdataFile=$${data_files:0:-1} $${conf[*]}' >> java-benchmark
+	@echo 'java -cp '\"tmp/java/target/*:$(top_srcdir)/java/core/target/*:$(top_srcdir)/java/util/target/*\"" \\" >>java-benchmark
+	@echo '   com.google.caliper.runner.CaliperMain com.google.protobuf.ProtoCaliperBenchmark -i runtime '"\\"  >> java-benchmark
+	@echo '   -b serializeToByteArray,serializeToMemoryStream,deserializeFromByteArray,deserializeFromMemoryStream '"\\" >> java-benchmark
+	@echo '   -DdataFile=$${data_files:0:-1} $${conf[*]}' >> java-benchmark
 	@chmod +x java-benchmark
 
 java: protoc_middleman protoc_middleman2 java-benchmark
@@ -180,8 +181,8 @@
 python-pure-python-benchmark: python_add_init
 	@echo "Writing shortcut script python-pure-python-benchmark..."
 	@echo '#! /bin/bash' > python-pure-python-benchmark
-	@echo export LD_LIBRARY_PATH=$(top_srcdir)/src/libprotobuf.la >> python-pure-python-benchmark
-	@echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/libprotobuf.la >> python-pure-python-benchmark
+	@echo export LD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-pure-python-benchmark
+	@echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-pure-python-benchmark
 	@echo export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=\'python\' >> python-pure-python-benchmark
 	@echo cp $(srcdir)/python/py_benchmark.py tmp >> python-pure-python-benchmark
 	@echo python tmp/py_benchmark.py '$$@' >> python-pure-python-benchmark
@@ -190,8 +191,8 @@
 python-cpp-reflection-benchmark: python_add_init
 	@echo "Writing shortcut script python-cpp-reflection-benchmark..."
 	@echo '#! /bin/bash' > python-cpp-reflection-benchmark
-	@echo export LD_LIBRARY_PATH=$(top_srcdir)/src/libprotobuf.la >> python-cpp-reflection-benchmark
-	@echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/libprotobuf.la >> python-cpp-reflection-benchmark
+	@echo export LD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-cpp-reflection-benchmark
+	@echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-cpp-reflection-benchmark
 	@echo export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=\'cpp\' >> python-cpp-reflection-benchmark
 	@echo cp $(srcdir)/python/py_benchmark.py tmp >> python-cpp-reflection-benchmark
 	@echo python tmp/py_benchmark.py '$$@' >> python-cpp-reflection-benchmark
@@ -200,8 +201,8 @@
 python-cpp-generated-code-benchmark: python_add_init libbenchmark_messages.la
 	@echo "Writing shortcut script python-cpp-generated-code-benchmark..."
 	@echo '#! /bin/bash' > python-cpp-generated-code-benchmark
-	@echo export LD_LIBRARY_PATH=$(top_srcdir)/src/libprotobuf.la >> python-cpp-generated-code-benchmark
-	@echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/libprotobuf.la >> python-cpp-generated-code-benchmark
+	@echo export LD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-cpp-generated-code-benchmark
+	@echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-cpp-generated-code-benchmark
 	@echo export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=\'cpp\' >> python-cpp-generated-code-benchmark
 	@echo cp $(srcdir)/python/py_benchmark.py tmp >> python-cpp-generated-code-benchmark
 	@echo python tmp/py_benchmark.py --cpp_generated '$$@' >> python-cpp-generated-code-benchmark
@@ -348,11 +349,11 @@
 	oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I$(srcdir) -I$(top_srcdir) --plugin=protoc-gen-gogoproto --gogoproto_out=$$oldpwd/tmp/gogo_proto $(benchmarks_protoc_inputs) $(benchmarks_protoc_inputs_benchmark_wrapper) $(benchmarks_protoc_inputs_proto2) )
 	touch gogo_proto_middleman
 
-new_data = $$(for data in $(all_data); do echo "tmp$${data\#$(srcdir)}"; done | xargs)
+gogo_data = $$(for data in $(all_data); do echo "tmp/gogo_data$${data\#$(srcdir)}"; done | xargs)
 
 generate_gogo_data: protoc_middleman protoc_middleman2 gogo-data-scrubber
-	mkdir -p `dirname $(new_data)`
-	./gogo-data-scrubber $(all_data) $(new_data)
+	mkdir -p `dirname $(gogo_data)`
+	./gogo-data-scrubber $(all_data) $(gogo_data)
 	touch generate_gogo_data
 	
 make_tmp_dir_gogo:
@@ -407,8 +408,6 @@
 	oldpwd=`pwd` && ( cd $(srcdir)/tmp/gogo_proto && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$$oldpwd/$(top_srcdir)/src --gogoslick_out=$$oldpwd/tmp/gogoslick $(benchmarks_protoc_inputs_proto2_message4) )
 	touch gogoslick_protoc_middleman
 
-gogo_data = $$(find . -type f -name "dataset.*.pb" -path "./tmp/*")
-
 generate-gogo-benchmark-code:
 	@echo '#! /bin/bash' > generate-gogo-benchmark-code
 	@echo 'cp $(srcdir)/go/go_benchmark_test.go tmp/$$1/benchmark_code/$$1_benchmark1_test.go' >> generate-gogo-benchmark-code
@@ -452,7 +451,7 @@
  
 ############ UTIL RULES BEGIN ############
 
-bin_PROGRAMS += protoc-gen-gogoproto gogo-data-scrubber
+bin_PROGRAMS += protoc-gen-gogoproto gogo-data-scrubber protoc-gen-proto2_to_proto3 proto3-data-stripper
 
 protoc_gen_gogoproto_LDADD = $(top_srcdir)/src/libprotobuf.la $(top_srcdir)/src/libprotoc.la
 protoc_gen_gogoproto_SOURCES = util/protoc-gen-gogoproto.cc
@@ -467,9 +466,86 @@
 	$(benchmarks_protoc_outputs_proto2)                                      \
 	$(benchmarks_protoc_outputs_proto2_header)                               \
 	$(benchmarks_protoc_outputs_header)
+
+protoc_gen_proto2_to_proto3_LDADD = $(top_srcdir)/src/libprotobuf.la $(top_srcdir)/src/libprotoc.la
+protoc_gen_proto2_to_proto3_SOURCES = util/protoc-gen-proto2_to_proto3.cc
+protoc_gen_proto2_to_proto3_CPPFLAGS = -I$(top_srcdir)/src -I$(srcdir)/cpp -I$(srcdir)/util
+
+proto3_data_stripper_LDADD = $(top_srcdir)/src/libprotobuf.la
+proto3_data_stripper_SOURCES = util/proto3_data_stripper.cc
+proto3_data_stripper_CPPFLAGS = -I$(top_srcdir)/src -I$(srcdir)/cpp -I$(srcdir)/util
+util/proto3_data_stripper-proto3_data_stripper.$(OBJEXT): $(benchmarks_protoc_outputs) $(benchmarks_protoc_outputs_proto2) $(benchmarks_protoc_outputs_header) $(benchmarks_protoc_outputs_proto2_header)
+nodist_proto3_data_stripper_SOURCES =                                      \
+	$(benchmarks_protoc_outputs)                                             \
+	$(benchmarks_protoc_outputs_proto2)                                      \
+	$(benchmarks_protoc_outputs_proto2_header)                               \
+	$(benchmarks_protoc_outputs_header)
+
 	
 ############ UTIL RULES END ############
 
+############ PROTO3 PREPARATION BEGIN #############
+
+proto3_proto_middleman: protoc-gen-proto2_to_proto3
+	mkdir -p "tmp/proto3_proto"
+	oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I$(srcdir) -I$(top_srcdir) --plugin=protoc-gen-proto2_to_proto3 --proto2_to_proto3_out=$$oldpwd/tmp/proto3_proto $(benchmarks_protoc_inputs) $(benchmarks_protoc_inputs_benchmark_wrapper) $(benchmarks_protoc_inputs_proto2) )
+	touch proto3_proto_middleman
+
+full_srcdir = $$(cd $(srcdir) && pwd)
+proto3_data = $$(for data in $(all_data); do echo $(full_srcdir)"/tmp/proto3_data$${data\#$(full_srcdir)}"; done | xargs)
+
+generate_proto3_data: protoc_middleman protoc_middleman2 proto3-data-stripper
+	mkdir -p `dirname $(proto3_data)`
+	./proto3-data-stripper $(all_data) $(proto3_data)
+	touch generate_proto3_data
+
+############ PROTO3 PREPARATION END #############
+
+############ PHP RULES BEGIN #################
+
+proto3_middleman_php: proto3_proto_middleman
+	mkdir -p "tmp/php"
+	oldpwd=`pwd` && ( cd tmp/proto3_proto && $$oldpwd/../src/protoc$(EXEEXT) -I$(srcdir) -I$(top_srcdir) --php_out=$$oldpwd/tmp/php $(benchmarks_protoc_inputs) $(benchmarks_protoc_inputs_benchmark_wrapper) $(benchmarks_protoc_inputs_proto2) )
+	touch proto3_middleman_php
+
+php-benchmark: proto3_middleman_php generate_proto3_data
+	mkdir -p "tmp/php/Google/Protobuf/Benchmark" && cp php/PhpBenchmark.php "tmp/php/Google/Protobuf/Benchmark"
+	cp php/autoload.php "tmp/php"  
+	@echo "Writing shortcut script php-benchmark..."
+	@echo '#! /bin/bash' > php-benchmark
+	@echo 'export PROTOBUF_PHP_SRCDIR="$$(cd $(top_srcdir) && pwd)/php/src"' >> php-benchmark
+	@echo 'cd tmp/php' >> php-benchmark
+	@echo 'export CURRENT_DIR=$$(pwd)' >> php-benchmark
+	@echo 'php -d auto_prepend_file="autoload.php" -d include_path="$$(pwd)" Google/Protobuf/Benchmark/PhpBenchmark.php $$@' >> php-benchmark
+	@echo 'cd ../..' >> php-benchmark
+	@chmod +x php-benchmark
+
+php: php-benchmark proto3_middleman_php
+	./php-benchmark $(proto3_data)
+
+php_c_extension:
+	cd $(top_srcdir)/php/ext/google/protobuf && ./configure CFLAGS='-O3' && make -j8
+
+php-c-benchmark: proto3_middleman_php generate_proto3_data php_c_extension php_c_extension
+	mkdir -p "tmp/php/Google/Protobuf/Benchmark" && cp php/PhpBenchmark.php "tmp/php/Google/Protobuf/Benchmark" 
+	cp php/autoload.php "tmp/php"  
+	@echo "Writing shortcut script php-c-benchmark..."
+	@echo '#! /bin/bash' > php-c-benchmark
+	@echo 'export PROTOBUF_PHP_SRCDIR="$$(cd $(top_srcdir) && pwd)/php/src"' >> php-c-benchmark
+	@echo 'export PROTOBUF_PHP_EXTDIR="$$PROTOBUF_PHP_SRCDIR/../ext/google/protobuf/modules"' >> php-c-benchmark
+	@echo 'echo "$$PROTOBUF_PHP_EXTDIR/protobuf.so"' >> php-c-benchmark
+	@echo 'cd tmp/php' >> php-c-benchmark
+	@echo 'export CURRENT_DIR=$$(pwd)' >> php-c-benchmark
+	@echo 'php -d auto_prepend_file="autoload.php" -d include_path="$$(pwd)" -d extension="$$PROTOBUF_PHP_EXTDIR/protobuf.so" Google/Protobuf/Benchmark/PhpBenchmark.php $$@' >> php-c-benchmark
+	@echo 'cd ../..' >> php-c-benchmark
+	@chmod +x php-c-benchmark
+
+php_c: php-c-benchmark proto3_middleman_php
+	./php-c-benchmark $(proto3_data)
+
+
+############ PHP RULES END #################
+
 MAINTAINERCLEANFILES =                                                     \
 	Makefile.in
 
@@ -512,8 +588,14 @@
 	gogoslick_protoc_middleman                                               \
 	gogoslick                                                                \
 	gogo-benchmark                                                           \
-	gogo/cpp_no_group/cpp_benchmark.* 
+	gogo/cpp_no_group/cpp_benchmark.*                                        \
+	proto3_proto_middleman                                                   \
+	generate_proto3_data                                                     \
+	php-benchmark                                                            \
+	php-c-benchmark                                                          \
+	proto3_middleman_php
 	
 
 clean-local:
 	-rm -rf tmp/*
+	
diff --git a/benchmarks/README.md b/benchmarks/README.md
index 21cd735..91b80a9 100644
--- a/benchmarks/README.md
+++ b/benchmarks/README.md
@@ -5,7 +5,7 @@
 can use to test a variety of performance scenarios against your
 protobuf language runtime. If you are looking for performance 
 numbers of officially support languages, see [here](
-https://github.com/google/protobuf/blob/master/docs/Performance.md)
+https://github.com/google/protobuf/blob/master/docs/performance.md)
 
 ## Prerequisite
 
@@ -58,6 +58,10 @@
 The first command installs `protoc-gen-go` into the `bin` directory in your local `GOPATH`.
 The second command adds the `bin` directory to your `PATH` so that `protoc` can locate the plugin later.
 
+### PHP
+PHP benchmark's requirement is the same as PHP protobuf's requirements. The benchmark will automaticly 
+include PHP protobuf's src and build the c extension if required.
+
 ### Big data
 
 There's some optional big testing data which is not included in the directory
@@ -120,6 +124,18 @@
 $ make go
 ```
 
+
+### PHP
+We have two version of php protobuf implemention: pure php, php with c extension. To run these version benchmark, you need to:
+#### Pure PHP
+```
+$ make php
+```
+#### PHP with c extension
+```
+$ make php_c
+```
+
 To run a specific dataset or run with specific options:
 
 ### Java:
@@ -167,6 +183,18 @@
 $ ./go-benchmark $(specific generated dataset file name) [go testing options]
 ```
 
+### PHP
+#### Pure PHP
+```
+$ make php-benchmark
+$ ./php-benchmark $(specific generated dataset file name)
+```
+#### PHP with c extension
+```
+$ make php-c-benchmark
+$ ./php-c-benchmark $(specific generated dataset file name)
+```
+
 
 ## Benchmark datasets
 
diff --git a/benchmarks/java/pom.xml b/benchmarks/java/pom.xml
old mode 100755
new mode 100644
index c2cd78a..570bd66
--- a/benchmarks/java/pom.xml
+++ b/benchmarks/java/pom.xml
@@ -14,7 +14,10 @@
     <dependency>
       <groupId>com.google.protobuf</groupId>
       <artifactId>protobuf-java</artifactId>
-      <version>3.5.0</version>
+      <version>${protobuf.version}</version>
+      <type>jar</type>
+      <scope>system</scope>
+      <systemPath>${project.basedir}/lib/protobuf-java.jar</systemPath>
     </dependency>
     <dependency>
       <groupId>com.google.caliper</groupId>
diff --git a/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java b/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java
old mode 100755
new mode 100644
index 94568ae..c766d74
--- a/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java
+++ b/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java
@@ -5,6 +5,7 @@
 import com.google.caliper.AfterExperiment;
 import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
+import com.google.caliper.api.VmOptions;
 import com.google.protobuf.ByteString;
 import com.google.protobuf.CodedOutputStream;
 import com.google.protobuf.ExtensionRegistry;
@@ -22,6 +23,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+// Caliper set CICompilerCount to 1 for making sure compilation doesn't run in parallel with itself,
+// This makes TieredCompilation not working. We just disable TieredCompilation by default. In master 
+// branch this has been disabled by default in caliper: 
+// https://github.com/google/caliper/blob/master/caliper-runner/src/main/java/com/google/caliper/runner/target/Jvm.java#L38:14
+// But this haven't been added into most recent release.
+@VmOptions("-XX:-TieredCompilation")
 public class ProtoCaliperBenchmark {
   public enum BenchmarkMessageType {
     GOOGLE_MESSAGE1_PROTO3 {
@@ -152,18 +159,6 @@
   
   
   @Benchmark
-  void serializeToByteString(int reps) throws IOException {
-    if (sampleMessageList.size() == 0) {
-      return;
-    }
-    for (int i = 0; i < reps; i++) {
-      for (int j = 0; j < sampleMessageList.size(); j++) {
-        sampleMessageList.get(j).toByteString();        
-      }
-    }
-  }
-  
-  @Benchmark
   void serializeToByteArray(int reps) throws IOException {
     if (sampleMessageList.size() == 0) {
       return;
@@ -189,19 +184,6 @@
   }
   
   @Benchmark
-  void deserializeFromByteString(int reps) throws IOException {
-    if (inputStringList.size() == 0) {
-      return;
-    }
-    for (int i = 0; i < reps; i++) {
-      for (int j = 0; j < inputStringList.size(); j++) {
-        benchmarkMessageType.getDefaultInstance().getParserForType().parseFrom(
-          inputStringList.get(j), extensions);
-      }
-    }
-  }
-  
-  @Benchmark
   void deserializeFromByteArray(int reps) throws IOException {
     if (inputDataList.size() == 0) {
       return;
diff --git a/benchmarks/php/PhpBenchmark.php b/benchmarks/php/PhpBenchmark.php
new file mode 100644
index 0000000..058940d
--- /dev/null
+++ b/benchmarks/php/PhpBenchmark.php
@@ -0,0 +1,157 @@
+<?php
+
+namespace Google\Protobuf\Benchmark;
+
+const NAME = "PhpBenchmark.php";
+
+function _require_all($dir, &$prefix) {
+    // require all php files
+    foreach (glob("$dir/*") as $path) {
+        if (preg_match('/\.php$/', $path) &&
+            substr($path, -strlen(NAME)) != NAME) {
+                require_once(substr($path, strlen($prefix) + 1));
+            } elseif (is_dir($path)) {
+                _require_all($path, $prefix);
+            }
+    }
+}
+// include all file
+foreach (explode(PATH_SEPARATOR, get_include_path()) as $one_include_path) {
+    _require_all($one_include_path, $one_include_path);
+}
+
+use Benchmarks\BenchmarkDataset;
+
+class BenchmarkMethod
+{
+    // $args[0]: dataset
+    // $args[1]: message class
+    static function parse(&$args) {
+        $payloads = $args[0]->getPayload();
+        for ($i = $payloads->count() - 1; $i >= 0; $i--) {
+            (new $args[1]())->mergeFromString($payloads->offsetGet($i));
+        }
+    }
+    
+    // $args: array of message
+    static function serialize(&$args) {
+        foreach ($args as &$temp_message) {
+            $temp_message->serializeToString();
+        }
+    }
+}
+
+class Benchmark
+{
+    private $benchmark_name;
+    private $args;
+    private $benchmark_time;
+    private $total_bytes;
+    private $coefficient;
+    
+    public function __construct($benchmark_name, $args, $total_bytes,
+        $benchmark_time = 5.0) {
+            $this->args = $args;
+            $this->benchmark_name = $benchmark_name;
+            $this->benchmark_time = $benchmark_time;
+            $this->total_bytes = $total_bytes;
+            $this->coefficient = pow (10, 0) / pow(2, 20);
+    }
+    
+    public function runBenchmark() {
+        $t = $this->runBenchmarkWithTimes(1);
+        $times = ceil($this->benchmark_time / $t);
+        return $this->total_bytes * $times /
+        $this->runBenchmarkWithTimes($times) *
+        $this->coefficient;
+    }
+    
+    private function runBenchmarkWithTimes($times) {
+        $st = microtime(true);
+        for ($i = 0; $i < $times; $i++) {
+            call_user_func_array($this->benchmark_name, array(&$this->args));
+        }
+        $en = microtime(true);
+        return $en - $st;
+    }
+}
+
+function getMessageName(&$dataset) {
+    switch ($dataset->getMessageName()) {
+        case "benchmarks.proto3.GoogleMessage1":
+            return "\Benchmarks\Proto3\GoogleMessage1";
+        case "benchmarks.proto2.GoogleMessage1":
+            return "\Benchmarks\Proto2\GoogleMessage1";
+        case "benchmarks.proto2.GoogleMessage2":
+            return "\Benchmarks\Proto2\GoogleMessage2";
+        case "benchmarks.google_message3.GoogleMessage3":
+            return "\Benchmarks\Google_message3\GoogleMessage3";
+        case "benchmarks.google_message4.GoogleMessage4":
+            return "\Benchmarks\Google_message4\GoogleMessage4";
+        default:
+            exit("Message " . $dataset->getMessageName() . " not found !");
+    }
+}
+
+function runBenchmark($file) {
+    $datafile = fopen($file, "r") or die("Unable to open file " . $file);
+    $bytes = fread($datafile, filesize($file));
+    $dataset = new BenchmarkDataset(NULL);
+    $dataset->mergeFromString($bytes);
+    $message_name = getMessageName($dataset);
+    $message_list = array();
+    $total_bytes = 0;
+    $payloads = $dataset->getPayload();
+    for ($i = $payloads->count() - 1; $i >= 0; $i--) {
+        $new_message = new $message_name();
+        $new_message->mergeFromString($payloads->offsetGet($i));
+        array_push($message_list, $new_message);
+        $total_bytes += strlen($payloads->offsetGet($i));
+    }
+    
+    $parse_benchmark = new Benchmark(
+        "\Google\Protobuf\Benchmark\BenchmarkMethod::parse",
+        array($dataset, $message_name), $total_bytes);
+    $serialize_benchmark = new Benchmark(
+        "\Google\Protobuf\Benchmark\BenchmarkMethod::serialize",
+        $message_list, $total_bytes);
+    
+    return array(
+        "filename" => $file,
+        "benchmarks" => array(
+            "parse_php" => $parse_benchmark->runBenchmark(),
+            "serailize_php" => $serialize_benchmark->runBenchmark()
+        ),
+        "message_name" => $dataset->getMessageName()
+    );
+}
+
+// main
+$json_output = false;
+$results = array();
+foreach ($argv as $index => $arg) {
+    if ($index == 0) {
+        continue;
+    }
+    if ($arg == "--json") {
+        $json_output = true;
+        continue;
+    } else {
+        array_push($results, runBenchmark($arg));
+    }
+}
+
+if ($json_output) {
+    print json_encode($results);
+} else {
+    print "PHP protobuf benchmark result:\n\n";
+    foreach ($results as $result) {
+        printf("result for test data file: %s\n", $result["filename"]);
+        foreach ($result["benchmarks"] as $benchmark => $throughput) {
+            printf("   Throughput for benchmark %s: %.2f MB/s\n",
+                $benchmark, $throughput);
+        }
+    }
+}
+
+?>
diff --git a/benchmarks/php/autoload.php b/benchmarks/php/autoload.php
new file mode 100644
index 0000000..52a8741
--- /dev/null
+++ b/benchmarks/php/autoload.php
@@ -0,0 +1,25 @@
+<?php
+
+define("GOOGLE_INTERNAL_NAMESPACE", "Google\\Protobuf\\Internal\\");
+define("GOOGLE_NAMESPACE", "Google\\Protobuf\\");
+define("GOOGLE_GPBMETADATA_NAMESPACE", "GPBMetadata\\Google\\Protobuf\\");
+define("BENCHMARK_NAMESPACE", "Benchmarks");
+define("BENCHMARK_GPBMETADATA_NAMESPACE", "GPBMetadata\\Benchmarks");
+
+function protobuf_autoloader_impl($class, $prefix, $include_path) {
+    $length = strlen($prefix);
+    if ((substr($class, 0, $length) === $prefix)) {
+        $path = $include_path . '/' . implode('/', array_map('ucwords', explode('\\', $class))) . '.php';
+        include_once $path;
+    }
+}
+
+function protobuf_autoloader($class) {
+    protobuf_autoloader_impl($class, GOOGLE_INTERNAL_NAMESPACE, getenv('PROTOBUF_PHP_SRCDIR'));
+    protobuf_autoloader_impl($class, GOOGLE_NAMESPACE, getenv('PROTOBUF_PHP_SRCDIR'));
+    protobuf_autoloader_impl($class, GOOGLE_GPBMETADATA_NAMESPACE, getenv('PROTOBUF_PHP_SRCDIR'));
+    protobuf_autoloader_impl($class, BENCHMARK_NAMESPACE, getenv('CURRENT_DIR'));
+    protobuf_autoloader_impl($class, BENCHMARK_GPBMETADATA_NAMESPACE, getenv('CURRENT_DIR'));
+}
+
+spl_autoload_register('protobuf_autoloader');
diff --git a/benchmarks/python/py_benchmark.py b/benchmarks/python/py_benchmark.py
index 6942d20..e86b61e 100755
--- a/benchmarks/python/py_benchmark.py
+++ b/benchmarks/python/py_benchmark.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import sys
 import os
 import timeit
@@ -138,15 +139,15 @@
     results.append(run_one_test(file))
   
   if args.json != "no":
-    print json.dumps(results)
+    print(json.dumps(results))
   else:
     for result in results:
-      print "Message %s of dataset file %s" % \
-          (result["message_name"], result["filename"])
-      print "Average time for parse_from_benchmark: %.2f ns" % \
+      print("Message %s of dataset file %s" % \
+          (result["message_name"], result["filename"]))
+      print("Average time for parse_from_benchmark: %.2f ns" % \
           (result["benchmarks"][ \
-                      args.behavior_prefix + "_parse_from_benchmark"])
-      print "Average time for serialize_to_benchmark: %.2f ns" % \
+                      args.behavior_prefix + "_parse_from_benchmark"]))
+      print("Average time for serialize_to_benchmark: %.2f ns" % \
           (result["benchmarks"][ \
-                      args.behavior_prefix + "_serialize_to_benchmark"])
-      print ""
+                      args.behavior_prefix + "_serialize_to_benchmark"]))
+      print("")
diff --git a/benchmarks/util/big_query_utils.py b/benchmarks/util/big_query_utils.py
index 14105aa..aea55bb 100755
--- a/benchmarks/util/big_query_utils.py
+++ b/benchmarks/util/big_query_utils.py
@@ -1,5 +1,6 @@
 #!/usr/bin/env python2.7
 
+from __future__ import print_function
 import argparse
 import json
 import uuid
@@ -37,11 +38,11 @@
         dataset_req.execute(num_retries=NUM_RETRIES)
     except HttpError as http_error:
         if http_error.resp.status == 409:
-            print 'Warning: The dataset %s already exists' % dataset_id
+            print('Warning: The dataset %s already exists' % dataset_id)
         else:
             # Note: For more debugging info, print "http_error.content"
-            print 'Error in creating dataset: %s. Err: %s' % (dataset_id,
-                                                              http_error)
+            print('Error in creating dataset: %s. Err: %s' % (dataset_id,
+                                                              http_error))
             is_success = False
     return is_success
 
@@ -109,13 +110,13 @@
         table_req = big_query.tables().insert(
             projectId=project_id, datasetId=dataset_id, body=body)
         res = table_req.execute(num_retries=NUM_RETRIES)
-        print 'Successfully created %s "%s"' % (res['kind'], res['id'])
+        print('Successfully created %s "%s"' % (res['kind'], res['id']))
     except HttpError as http_error:
         if http_error.resp.status == 409:
-            print 'Warning: Table %s already exists' % table_id
+            print('Warning: Table %s already exists' % table_id)
         else:
-            print 'Error in creating table: %s. Err: %s' % (table_id,
-                                                            http_error)
+            print('Error in creating table: %s. Err: %s' % (table_id,
+                                                            http_error))
             is_success = False
     return is_success
 
@@ -141,9 +142,9 @@
             tableId=table_id,
             body=body)
         res = table_req.execute(num_retries=NUM_RETRIES)
-        print 'Successfully patched %s "%s"' % (res['kind'], res['id'])
+        print('Successfully patched %s "%s"' % (res['kind'], res['id']))
     except HttpError as http_error:
-        print 'Error in creating table: %s. Err: %s' % (table_id, http_error)
+        print('Error in creating table: %s. Err: %s' % (table_id, http_error))
         is_success = False
     return is_success
 
@@ -159,10 +160,10 @@
             body=body)
         res = insert_req.execute(num_retries=NUM_RETRIES)
         if res.get('insertErrors', None):
-            print 'Error inserting rows! Response: %s' % res
+            print('Error inserting rows! Response: %s' % res)
             is_success = False
     except HttpError as http_error:
-        print 'Error inserting rows to the table %s' % table_id
+        print('Error inserting rows to the table %s' % table_id)
         is_success = False
 
     return is_success
@@ -176,8 +177,8 @@
             projectId=project_id,
             body=query_data).execute(num_retries=NUM_RETRIES)
     except HttpError as http_error:
-        print 'Query execute job failed with error: %s' % http_error
-        print http_error.content
+        print('Query execute job failed with error: %s' % http_error)
+        print(http_error.content)
     return query_job
 
 
diff --git a/benchmarks/util/data_proto2_to_proto3_util.h b/benchmarks/util/data_proto2_to_proto3_util.h
new file mode 100644
index 0000000..5eea850
--- /dev/null
+++ b/benchmarks/util/data_proto2_to_proto3_util.h
@@ -0,0 +1,64 @@
+#ifndef PROTOBUF_BENCHMARKS_UTIL_DATA_PROTO2_TO_PROTO3_UTIL_H_
+#define PROTOBUF_BENCHMARKS_UTIL_DATA_PROTO2_TO_PROTO3_UTIL_H_
+
+#include "google/protobuf/message.h"
+#include "google/protobuf/descriptor.h"
+
+using google::protobuf::FieldDescriptor;
+using google::protobuf::Message;
+using google::protobuf::Reflection;
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+class DataStripper {
+ public:
+  void StripMessage(Message *message) {
+    std::vector<const FieldDescriptor*> set_fields;
+    const Reflection* reflection = message->GetReflection();
+    reflection->ListFields(*message, &set_fields);
+
+    for (size_t i = 0; i < set_fields.size(); i++) {
+      const FieldDescriptor* field = set_fields[i];
+      if (ShouldBeClear(field)) {
+        reflection->ClearField(message, field);
+        continue;
+      }
+      if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
+        if (field->is_repeated()) {
+          for (int j = 0; j < reflection->FieldSize(*message, field); j++) {
+            StripMessage(reflection->MutableRepeatedMessage(message, field, j));
+          }
+        } else {
+          StripMessage(reflection->MutableMessage(message, field));
+        }
+      }
+    }
+
+    reflection->MutableUnknownFields(message)->Clear();
+  }
+ private:
+  virtual bool ShouldBeClear(const FieldDescriptor *field) = 0;
+};
+
+class GogoDataStripper : public DataStripper {
+ private:
+  virtual bool ShouldBeClear(const FieldDescriptor *field) {
+    return field->type() == FieldDescriptor::TYPE_GROUP;
+  }
+};
+
+class Proto3DataStripper : public DataStripper {
+ private:
+  virtual bool ShouldBeClear(const FieldDescriptor *field) {
+    return field->type() == FieldDescriptor::TYPE_GROUP ||
+           field->is_extension();
+  }
+};
+
+}  // namespace util
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // PROTOBUF_BENCHMARKS_UTIL_DATA_PROTO2_TO_PROTO3_UTIL_H_
diff --git a/benchmarks/util/gogo_data_scrubber.cc b/benchmarks/util/gogo_data_scrubber.cc
index fb9af6e..9ef57b0 100644
--- a/benchmarks/util/gogo_data_scrubber.cc
+++ b/benchmarks/util/gogo_data_scrubber.cc
@@ -4,43 +4,11 @@
 #include "datasets/google_message2/benchmark_message2.pb.h"
 #include "datasets/google_message3/benchmark_message3.pb.h"
 #include "datasets/google_message4/benchmark_message4.pb.h"
-
-#include "google/protobuf/message.h"
-#include "google/protobuf/descriptor.h"
+#include "data_proto2_to_proto3_util.h"
 
 #include <fstream>
 
-using google::protobuf::FieldDescriptor;
-using google::protobuf::Message;
-using google::protobuf::Reflection;
-
-
-class DataGroupStripper {
- public:
-  static void StripMessage(Message *message) {
-    std::vector<const FieldDescriptor*> set_fields;
-    const Reflection* reflection = message->GetReflection();
-    reflection->ListFields(*message, &set_fields);
-
-    for (size_t i = 0; i < set_fields.size(); i++) {
-      const FieldDescriptor* field = set_fields[i];
-      if (field->type() == FieldDescriptor::TYPE_GROUP) {
-        reflection->ClearField(message, field);
-      }
-      if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
-        if (field->is_repeated()) {
-          for (int j = 0; j < reflection->FieldSize(*message, field); j++) {
-            StripMessage(reflection->MutableRepeatedMessage(message, field, j));
-          }
-        } else {
-          StripMessage(reflection->MutableMessage(message, field));
-        }
-      }
-    }
-
-    reflection->MutableUnknownFields(message)->Clear();
-  }
-};
+using google::protobuf::util::GogoDataStripper;
 
 std::string ReadFile(const std::string& name) {
   std::ifstream file(name.c_str());
@@ -91,7 +59,8 @@
 
     for (int i = 0; i < dataset.payload_size(); i++) {
       message->ParseFromString(dataset.payload(i));
-      DataGroupStripper::StripMessage(message);
+      GogoDataStripper stripper;
+      stripper.StripMessage(message);
       dataset.set_payload(i, message->SerializeAsString());
     }
 
diff --git a/benchmarks/util/proto3_data_stripper.cc b/benchmarks/util/proto3_data_stripper.cc
new file mode 100644
index 0000000..3096c4c
--- /dev/null
+++ b/benchmarks/util/proto3_data_stripper.cc
@@ -0,0 +1,74 @@
+#include "benchmarks.pb.h"
+#include "datasets/google_message1/proto2/benchmark_message1_proto2.pb.h"
+#include "datasets/google_message1/proto3/benchmark_message1_proto3.pb.h"
+#include "datasets/google_message2/benchmark_message2.pb.h"
+#include "datasets/google_message3/benchmark_message3.pb.h"
+#include "datasets/google_message4/benchmark_message4.pb.h"
+#include "data_proto2_to_proto3_util.h"
+
+#include <fstream>
+
+using google::protobuf::util::Proto3DataStripper;
+
+std::string ReadFile(const std::string& name) {
+  std::ifstream file(name.c_str());
+  GOOGLE_CHECK(file.is_open()) << "Couldn't find file '"
+      << name
+      << "', please make sure you are running this command from the benchmarks"
+      << " directory.\n";
+  return std::string((std::istreambuf_iterator<char>(file)),
+                     std::istreambuf_iterator<char>());
+}
+
+int main(int argc, char *argv[]) {
+  if (argc % 2 == 0 || argc == 1) {
+    std::cerr << "Usage: [input_files] [output_file_names] where " <<
+        "input_files are one to one mapping to output_file_names." <<
+        std::endl;
+    return 1;
+  }
+
+  for (int i = argc / 2; i > 0; i--) {
+    const std::string &input_file = argv[i];
+    const std::string &output_file = argv[i + argc / 2];
+
+    std::cerr << "Generating " << input_file
+        << " to " << output_file << std::endl;
+    benchmarks::BenchmarkDataset dataset;
+    Message* message;
+    std::string dataset_payload = ReadFile(input_file);
+    GOOGLE_CHECK(dataset.ParseFromString(dataset_payload))
+      << "Can' t parse data file " << input_file;
+
+    if (dataset.message_name() == "benchmarks.proto3.GoogleMessage1") {
+      message = new benchmarks::proto3::GoogleMessage1;
+    } else if (dataset.message_name() == "benchmarks.proto2.GoogleMessage1") {
+      message = new benchmarks::proto2::GoogleMessage1;
+    } else if (dataset.message_name() == "benchmarks.proto2.GoogleMessage2") {
+      message = new benchmarks::proto2::GoogleMessage2;
+    } else if (dataset.message_name() ==
+        "benchmarks.google_message3.GoogleMessage3") {
+      message = new benchmarks::google_message3::GoogleMessage3;
+    } else if (dataset.message_name() ==
+        "benchmarks.google_message4.GoogleMessage4") {
+      message = new benchmarks::google_message4::GoogleMessage4;
+    } else {
+      std::cerr << "Unknown message type: " << dataset.message_name();
+      exit(1);
+    }
+
+    for (int i = 0; i < dataset.payload_size(); i++) {
+      message->ParseFromString(dataset.payload(i));
+      Proto3DataStripper stripper;
+      stripper.StripMessage(message);
+      dataset.set_payload(i, message->SerializeAsString());
+    }
+
+    std::ofstream ofs(output_file);
+    ofs << dataset.SerializeAsString();
+    ofs.close();
+  }
+
+
+  return 0;
+}
diff --git a/benchmarks/util/protoc-gen-gogoproto.cc b/benchmarks/util/protoc-gen-gogoproto.cc
index bfa6a5e..9c1b3d0 100644
--- a/benchmarks/util/protoc-gen-gogoproto.cc
+++ b/benchmarks/util/protoc-gen-gogoproto.cc
@@ -12,7 +12,7 @@
 using google::protobuf::DescriptorPool;
 using google::protobuf::io::Printer;
 using google::protobuf::util::SchemaGroupStripper;
-using google::protobuf::util::SchemaAddZeroEnumValue;
+using google::protobuf::util::EnumScrubber;
 
 namespace google {
 namespace protobuf {
@@ -74,7 +74,7 @@
     file->CopyTo(&new_file);
     SchemaGroupStripper::StripFile(file, &new_file);
 
-    SchemaAddZeroEnumValue enum_scrubber;
+    EnumScrubber enum_scrubber;
     enum_scrubber.ScrubFile(&new_file);
 
     string filename = file->name();
diff --git a/benchmarks/util/protoc-gen-proto2_to_proto3.cc b/benchmarks/util/protoc-gen-proto2_to_proto3.cc
new file mode 100644
index 0000000..d0a8902
--- /dev/null
+++ b/benchmarks/util/protoc-gen-proto2_to_proto3.cc
@@ -0,0 +1,115 @@
+#include "google/protobuf/compiler/code_generator.h"
+#include "google/protobuf/io/zero_copy_stream.h"
+#include "google/protobuf/io/printer.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/descriptor.pb.h"
+#include "schema_proto2_to_proto3_util.h"
+
+#include "google/protobuf/compiler/plugin.h"
+
+using google::protobuf::FileDescriptorProto;
+using google::protobuf::FileDescriptor;
+using google::protobuf::DescriptorPool;
+using google::protobuf::io::Printer;
+using google::protobuf::util::SchemaGroupStripper;
+using google::protobuf::util::EnumScrubber;
+using google::protobuf::util::ExtensionStripper;
+using google::protobuf::util::FieldScrubber;
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+namespace {
+
+string StripProto(string filename) {
+  return filename.substr(0, filename.rfind(".proto"));
+}
+
+DescriptorPool* GetPool() {
+  static DescriptorPool *pool = new DescriptorPool();
+  return pool;
+}
+
+}  // namespace
+
+class Proto2ToProto3Generator final : public CodeGenerator {
+ public:
+  bool GenerateAll(const std::vector<const FileDescriptor*>& files,
+                           const string& parameter,
+                           GeneratorContext* context,
+                           string* error) const {
+    for (int i = 0; i < files.size(); i++) {
+      for (auto file : files) {
+        if (CanGenerate(file)) {
+          Generate(file, parameter, context, error);
+          break;
+        }
+      }
+    }
+
+    return true;
+  }
+
+  bool Generate(const FileDescriptor* file,
+                        const string& parameter,
+                        GeneratorContext* context,
+                        string* error) const {
+    FileDescriptorProto new_file;
+    file->CopyTo(&new_file);
+    SchemaGroupStripper::StripFile(file, &new_file);
+
+    EnumScrubber enum_scrubber;
+    enum_scrubber.ScrubFile(&new_file);
+    ExtensionStripper::StripFile(&new_file);
+    FieldScrubber::ScrubFile(&new_file);
+    new_file.set_syntax("proto3");
+
+    string filename = file->name();
+    string basename = StripProto(filename);
+
+    std::vector<std::pair<string,string>> option_pairs;
+    ParseGeneratorParameter(parameter, &option_pairs);
+
+    std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
+        context->Open(basename + ".proto"));
+    string content = GetPool()->BuildFile(new_file)->DebugString();
+    Printer printer(output.get(), '$');
+    printer.WriteRaw(content.c_str(), content.size());
+
+    return true;
+  }
+ private:
+  bool CanGenerate(const FileDescriptor* file) const {
+    if (GetPool()->FindFileByName(file->name()) != nullptr) {
+      return false;
+    }
+    for (int j = 0; j < file->dependency_count(); j++) {
+      if (GetPool()->FindFileByName(file->dependency(j)->name()) == nullptr) {
+        return false;
+      }
+    }
+    for (int j = 0; j < file->public_dependency_count(); j++) {
+      if (GetPool()->FindFileByName(
+          file->public_dependency(j)->name()) == nullptr) {
+        return false;
+      }
+    }
+    for (int j = 0; j < file->weak_dependency_count(); j++) {
+      if (GetPool()->FindFileByName(
+          file->weak_dependency(j)->name()) == nullptr) {
+        return false;
+      }
+    }
+    return true;
+  }
+};
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
+
+int main(int argc, char* argv[]) {
+  google::protobuf::compiler::Proto2ToProto3Generator generator;
+  return google::protobuf::compiler::PluginMain(argc, argv, &generator);
+}
diff --git a/benchmarks/util/result_parser.py b/benchmarks/util/result_parser.py
new file mode 100755
index 0000000..a843923
--- /dev/null
+++ b/benchmarks/util/result_parser.py
@@ -0,0 +1,218 @@
+# This import depends on the automake rule protoc_middleman, please make sure
+# protoc_middleman has been built before run this file.
+import json
+import re
+import os.path
+# BEGIN OPENSOURCE
+import sys
+sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))
+# END OPENSOURCE
+import tmp.benchmarks_pb2 as benchmarks_pb2
+
+__file_size_map = {}
+
+def __get_data_size(filename):
+  if filename[0] != '/':
+    filename = os.path.dirname(os.path.abspath(__file__)) + "/../" + filename
+  if filename in __file_size_map:
+    return __file_size_map[filename]
+  benchmark_dataset = benchmarks_pb2.BenchmarkDataset()
+  benchmark_dataset.ParseFromString(
+      open(filename).read())
+  size = 0
+  count = 0
+  for payload in benchmark_dataset.payload:
+    size += len(payload)
+    count += 1
+  __file_size_map[filename] = (size, 1.0 * size / count)
+  return size, 1.0 * size / count
+
+
+def __extract_file_name(file_name):
+  name_list = re.split("[/\.]", file_name)
+  short_file_name = ""
+  for name in name_list:
+    if name[:14] == "google_message":
+      short_file_name = name
+  return short_file_name
+
+
+__results = []
+
+
+# CPP results example:
+# [
+#   "benchmarks": [
+#     {
+#       "bytes_per_second": int,
+#       "cpu_time": int,
+#       "name: string,
+#       "time_unit: string,
+#       ...
+#     },
+#     ...
+#   ],
+#   ...
+# ]
+def __parse_cpp_result(filename):
+  if filename == "":
+    return
+  if filename[0] != '/':
+    filename = os.path.dirname(os.path.abspath(__file__)) + '/' + filename
+  with open(filename) as f:
+    results = json.loads(f.read())
+    for benchmark in results["benchmarks"]:
+      data_filename = "".join(
+          re.split("(_parse_|_serialize)", benchmark["name"])[0])
+      behavior = benchmark["name"][len(data_filename) + 1:]
+      if data_filename[:2] == "BM":
+        data_filename = data_filename[3:]
+      __results.append({
+        "language": "cpp",
+        "dataFilename": data_filename,
+        "behavior": behavior,
+        "throughput": benchmark["bytes_per_second"] / 2.0 ** 20
+      })
+
+
+# Python results example:
+# [
+#   [
+#     {
+#       "filename": string,
+#       "benchmarks": {
+#         behavior: results,
+#         ...
+#       },
+#       "message_name": STRING
+#     },
+#     ...
+#   ], #pure-python
+#   ...
+# ]
+def __parse_python_result(filename):
+  if filename == "":
+    return
+  if filename[0] != '/':
+    filename = os.path.dirname(os.path.abspath(__file__)) + '/' + filename
+  with open(filename) as f:
+    results_list = json.loads(f.read())
+    for results in results_list:
+      for result in results:
+        _, avg_size = __get_data_size(result["filename"])
+        for behavior in result["benchmarks"]:
+          __results.append({
+            "language": "python",
+            "dataFilename": __extract_file_name(result["filename"]),
+            "behavior": behavior,
+            "throughput": avg_size /
+                          result["benchmarks"][behavior] * 1e9 / 2 ** 20
+          })
+
+
+# Java results example:
+# [
+#   {
+#     "id": string,
+#     "instrumentSpec": {...},
+#     "measurements": [
+#       {
+#         "weight": float,
+#         "value": {
+#           "magnitude": float,
+#           "unit": string
+#         },
+#         ...
+#       },
+#       ...
+#     ],
+#     "run": {...},
+#     "scenario": {
+#       "benchmarkSpec": {
+#         "methodName": string,
+#         "parameters": {
+#            defined parameters in the benchmark: parameters value
+#         },
+#         ...
+#       },
+#       ...
+#     }
+#
+#   },
+#   ...
+# ]
+def __parse_java_result(filename):
+  if filename == "":
+    return
+  if filename[0] != '/':
+    filename = os.path.dirname(os.path.abspath(__file__)) + '/' + filename
+  with open(filename) as f:
+    results = json.loads(f.read())
+    for result in results:
+      total_weight = 0
+      total_value = 0
+      for measurement in result["measurements"]:
+        total_weight += measurement["weight"]
+        total_value += measurement["value"]["magnitude"]
+      avg_time = total_value * 1.0 / total_weight
+      total_size, _ = __get_data_size(
+          result["scenario"]["benchmarkSpec"]["parameters"]["dataFile"])
+      __results.append({
+        "language": "java",
+        "throughput": total_size / avg_time * 1e9 / 2 ** 20,
+        "behavior": result["scenario"]["benchmarkSpec"]["methodName"],
+        "dataFilename": __extract_file_name(
+            result["scenario"]["benchmarkSpec"]["parameters"]["dataFile"])
+      })
+
+
+# Go benchmark results:
+#
+# goos: linux
+# goarch: amd64
+# Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Unmarshal-12               3000      705784 ns/op
+# Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Marshal-12                 2000      634648 ns/op
+# Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Size-12                    5000      244174 ns/op
+# Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Clone-12                    300     4120954 ns/op
+# Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Merge-12                    300     4108632 ns/op
+# PASS
+# ok    _/usr/local/google/home/yilunchong/mygit/protobuf/benchmarks  124.173s
+def __parse_go_result(filename):
+  if filename == "":
+    return
+  if filename[0] != '/':
+    filename = os.path.dirname(os.path.abspath(__file__)) + '/' + filename
+  with open(filename) as f:
+    for line in f:
+      result_list = re.split("[\ \t]+", line)
+      if result_list[0][:9] != "Benchmark":
+        continue
+      first_slash_index = result_list[0].find('/')
+      last_slash_index = result_list[0].rfind('/')
+      full_filename = result_list[0][first_slash_index+4:last_slash_index] # delete ../ prefix
+      total_bytes, _ = __get_data_size(full_filename)
+      behavior_with_suffix = result_list[0][last_slash_index+1:]
+      last_dash = behavior_with_suffix.rfind("-")
+      if last_dash == -1:
+        behavior = behavior_with_suffix
+      else:
+        behavior = behavior_with_suffix[:last_dash]
+      __results.append({
+        "dataFilename": __extract_file_name(full_filename),
+        "throughput": total_bytes / float(result_list[2]) * 1e9 / 2 ** 20,
+        "behavior": behavior,
+        "language": "go"
+      })
+
+def get_result_from_file(cpp_file="", java_file="", python_file="", go_file=""):
+  results = {}
+  if cpp_file != "":
+    __parse_cpp_result(cpp_file)
+  if java_file != "":
+    __parse_java_result(java_file)
+  if python_file != "":
+    __parse_python_result(python_file)
+  if go_file != "":
+    __parse_go_result(go_file)
+
+  return __results
\ No newline at end of file
diff --git a/benchmarks/util/result_uploader.py b/benchmarks/util/result_uploader.py
new file mode 100755
index 0000000..a667da0
--- /dev/null
+++ b/benchmarks/util/result_uploader.py
@@ -0,0 +1,94 @@
+from __future__ import print_function
+from __future__ import absolute_import
+import argparse
+import os
+import re
+import copy
+import uuid
+import calendar
+import time
+import datetime
+
+from util import big_query_utils
+from util import result_parser
+
+_PROJECT_ID = 'grpc-testing'
+_DATASET = 'protobuf_benchmark_result'
+_TABLE = 'opensource_result_v2'
+_NOW = "%d%02d%02d" % (datetime.datetime.now().year,
+                       datetime.datetime.now().month,
+                       datetime.datetime.now().day)
+
+_INITIAL_TIME = calendar.timegm(time.gmtime())
+
+def get_metadata():
+  build_number = os.getenv('BUILD_NUMBER')
+  build_url = os.getenv('BUILD_URL')
+  job_name = os.getenv('JOB_NAME')
+  git_commit = os.getenv('GIT_COMMIT')
+  # actual commit is the actual head of PR that is getting tested
+  git_actual_commit = os.getenv('ghprbActualCommit')
+
+  utc_timestamp = str(calendar.timegm(time.gmtime()))
+  metadata = {'created': utc_timestamp}
+
+  if build_number:
+    metadata['buildNumber'] = build_number
+  if build_url:
+    metadata['buildUrl'] = build_url
+  if job_name:
+    metadata['jobName'] = job_name
+  if git_commit:
+    metadata['gitCommit'] = git_commit
+  if git_actual_commit:
+    metadata['gitActualCommit'] = git_actual_commit
+
+  return metadata
+
+
+def upload_result(result_list, metadata):
+  for result in result_list:
+    new_result = {}
+    new_result["metric"] = "throughput"
+    new_result["value"] = result["throughput"]
+    new_result["unit"] = "MB/s"
+    new_result["test"] = "protobuf_benchmark"
+    new_result["product_name"] = "protobuf"
+    labels_string = ""
+    for key in result:
+      labels_string += ",|%s:%s|" % (key, result[key])
+    new_result["labels"] = labels_string[1:]
+    new_result["timestamp"] = _INITIAL_TIME
+
+    bq = big_query_utils.create_big_query()
+    row = big_query_utils.make_row(str(uuid.uuid4()), new_result)
+    if not big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET,
+                                       _TABLE + "$" + _NOW,
+                                       [row]):
+      print('Error when uploading result', new_result)
+
+
+if __name__ == "__main__":
+  parser = argparse.ArgumentParser()
+  parser.add_argument("-cpp", "--cpp_input_file",
+                      help="The CPP benchmark result file's name",
+                      default="")
+  parser.add_argument("-java", "--java_input_file",
+                      help="The Java benchmark result file's name",
+                      default="")
+  parser.add_argument("-python", "--python_input_file",
+                      help="The Python benchmark result file's name",
+                      default="")
+  parser.add_argument("-go", "--go_input_file",
+                      help="The golang benchmark result file's name",
+                      default="")
+  args = parser.parse_args()
+
+  metadata = get_metadata()
+  print("uploading results...")
+  upload_result(result_parser.get_result_from_file(
+      cpp_file=args.cpp_input_file,
+      java_file=args.java_input_file,
+      python_file=args.python_input_file,
+      go_file=args.go_input_file
+  ), metadata)
\ No newline at end of file
diff --git a/benchmarks/util/run_and_upload.py b/benchmarks/util/run_and_upload.py
deleted file mode 100755
index ae22a66..0000000
--- a/benchmarks/util/run_and_upload.py
+++ /dev/null
@@ -1,290 +0,0 @@
-import argparse
-import os
-import re
-import copy
-import uuid
-import calendar
-import time
-import big_query_utils
-import datetime
-import json
-# This import depends on the automake rule protoc_middleman, please make sure
-# protoc_middleman has been built before run this file.
-import os.path, sys
-sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))
-import tmp.benchmarks_pb2 as benchmarks_pb2
-from click.types import STRING
-
-_PROJECT_ID = 'grpc-testing'
-_DATASET = 'protobuf_benchmark_result'
-_TABLE = 'opensource_result_v1'
-_NOW = "%d%02d%02d" % (datetime.datetime.now().year,
-                       datetime.datetime.now().month,
-                       datetime.datetime.now().day)
-
-file_size_map = {}
-
-def get_data_size(file_name):
-  if file_name in file_size_map:
-    return file_size_map[file_name]
-  benchmark_dataset = benchmarks_pb2.BenchmarkDataset()
-  benchmark_dataset.ParseFromString(
-      open(os.path.dirname(os.path.abspath(__file__)) + "/../" + file_name).read())
-  size = 0
-  count = 0
-  for payload in benchmark_dataset.payload:
-    size += len(payload)
-    count += 1
-  file_size_map[file_name] = (size, 1.0 * size / count)
-  return size, 1.0 * size / count
-
-
-def extract_file_name(file_name):
-  name_list = re.split("[/\.]", file_name)
-  short_file_name = ""
-  for name in name_list:
-    if name[:14] == "google_message":
-      short_file_name = name
-  return short_file_name
-
-
-cpp_result = []
-python_result = []
-java_result = []
-go_result = []
-
-
-# CPP results example:
-# [ 
-#   "benchmarks": [ 
-#     {
-#       "bytes_per_second": int,
-#       "cpu_time": int,
-#       "name: string,
-#       "time_unit: string,
-#       ...
-#     },
-#     ... 
-#   ],
-#   ... 
-# ]
-def parse_cpp_result(filename):
-  global cpp_result
-  if filename == "":
-    return
-  if filename[0] != '/':
-    filename = os.path.dirname(os.path.abspath(__file__)) + '/' + filename
-  with open(filename) as f:
-    results = json.loads(f.read())
-    for benchmark in results["benchmarks"]:
-      data_filename = "".join(
-          re.split("(_parse_|_serialize)", benchmark["name"])[0])
-      behavior = benchmark["name"][len(data_filename) + 1:]
-      cpp_result.append({
-        "language": "cpp",
-        "dataFileName": data_filename,
-        "behavior": behavior,
-        "throughput": benchmark["bytes_per_second"] / 2.0 ** 20
-      })
-
-
-# Python results example:
-# [ 
-#   [ 
-#     {
-#       "filename": string,
-#       "benchmarks": {
-#         behavior: results, 
-#         ...
-#       },
-#       "message_name": STRING
-#     },
-#     ... 
-#   ], #pure-python
-#   ... 
-# ]
-def parse_python_result(filename):
-  global python_result
-  if filename == "":
-    return
-  if filename[0] != '/':
-    filename = os.path.dirname(os.path.abspath(__file__)) + '/' + filename
-  with open(filename) as f:
-    results_list = json.loads(f.read())
-    for results in results_list:
-      for result in results:
-        _, avg_size = get_data_size(result["filename"])
-        for behavior in result["benchmarks"]:
-          python_result.append({
-            "language": "python",
-            "dataFileName": extract_file_name(result["filename"]),
-            "behavior": behavior,
-            "throughput": avg_size /
-                          result["benchmarks"][behavior] * 1e9 / 2 ** 20
-          })
-
-
-# Java results example:
-# [ 
-#   {
-#     "id": string,
-#     "instrumentSpec": {...},
-#     "measurements": [
-#       {
-#         "weight": float,
-#         "value": {
-#           "magnitude": float,
-#           "unit": string
-#         },
-#         ...
-#       },
-#       ...
-#     ],
-#     "run": {...},
-#     "scenario": {
-#       "benchmarkSpec": {
-#         "methodName": string,
-#         "parameters": {
-#            defined parameters in the benchmark: parameters value
-#         },
-#         ...
-#       },
-#       ...
-#     }
-#     
-#   }, 
-#   ... 
-# ]
-def parse_java_result(filename):
-  global average_bytes_per_message, java_result
-  if filename == "":
-    return
-  if filename[0] != '/':
-    filename = os.path.dirname(os.path.abspath(__file__)) + '/' + filename
-  with open(filename) as f:
-    results = json.loads(f.read())
-    for result in results:
-      total_weight = 0
-      total_value = 0
-      for measurement in result["measurements"]:
-        total_weight += measurement["weight"]
-        total_value += measurement["value"]["magnitude"]
-      avg_time = total_value * 1.0 / total_weight
-      total_size, _ = get_data_size(
-          result["scenario"]["benchmarkSpec"]["parameters"]["dataFile"])
-      java_result.append({
-        "language": "java",
-        "throughput": total_size / avg_time * 1e9 / 2 ** 20,
-        "behavior": result["scenario"]["benchmarkSpec"]["methodName"],
-        "dataFileName": extract_file_name(
-            result["scenario"]["benchmarkSpec"]["parameters"]["dataFile"])
-      })
-
-
-# Go benchmark results:
-#
-# goos: linux
-# goarch: amd64
-# Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Unmarshal-12               3000      705784 ns/op
-# Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Marshal-12                 2000      634648 ns/op
-# Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Size-12                    5000      244174 ns/op
-# Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Clone-12                    300     4120954 ns/op
-# Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Merge-12                    300     4108632 ns/op
-# PASS
-# ok    _/usr/local/google/home/yilunchong/mygit/protobuf/benchmarks  124.173s
-def parse_go_result(filename):
-  global go_result
-  if filename == "":
-    return
-  if filename[0] != '/':
-    filename = os.path.dirname(os.path.abspath(__file__)) + '/' + filename
-  with open(filename) as f:
-    for line in f:
-      result_list = re.split("[\ \t]+", line)
-      if result_list[0][:9] != "Benchmark":
-        continue
-      first_slash_index = result_list[0].find('/')
-      last_slash_index = result_list[0].rfind('/')
-      full_filename = result_list[0][first_slash_index+4:last_slash_index] # delete ../ prefix
-      total_bytes, _ = get_data_size(full_filename)
-      behavior_with_suffix = result_list[0][last_slash_index+1:]
-      last_dash = behavior_with_suffix.rfind("-")
-      if last_dash == -1:
-        behavior = behavior_with_suffix
-      else:
-        behavior = behavior_with_suffix[:last_dash]
-      go_result.append({
-        "dataFilename": extract_file_name(full_filename),
-        "throughput": total_bytes / float(result_list[2]) * 1e9 / 2 ** 20,
-        "behavior": behavior,
-        "language": "go"
-      })
-
-
-def get_metadata():
-  build_number = os.getenv('BUILD_NUMBER')
-  build_url = os.getenv('BUILD_URL')
-  job_name = os.getenv('JOB_NAME')
-  git_commit = os.getenv('GIT_COMMIT')
-  # actual commit is the actual head of PR that is getting tested
-  git_actual_commit = os.getenv('ghprbActualCommit')
-
-  utc_timestamp = str(calendar.timegm(time.gmtime()))
-  metadata = {'created': utc_timestamp}
-
-  if build_number:
-    metadata['buildNumber'] = build_number
-  if build_url:
-    metadata['buildUrl'] = build_url
-  if job_name:
-    metadata['jobName'] = job_name
-  if git_commit:
-    metadata['gitCommit'] = git_commit
-  if git_actual_commit:
-    metadata['gitActualCommit'] = git_actual_commit
-
-  return metadata
-
-
-def upload_result(result_list, metadata):
-  for result in result_list:
-    new_result = copy.deepcopy(result)
-    new_result['metadata'] = metadata
-    bq = big_query_utils.create_big_query()
-    row = big_query_utils.make_row(str(uuid.uuid4()), new_result)
-    if not big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET,
-                                       _TABLE + "$" + _NOW,
-                                       [row]):
-      print 'Error when uploading result', new_result
-
-
-if __name__ == "__main__":
-  parser = argparse.ArgumentParser()
-  parser.add_argument("-cpp", "--cpp_input_file",
-                      help="The CPP benchmark result file's name",
-                      default="")
-  parser.add_argument("-java", "--java_input_file",
-                      help="The Java benchmark result file's name",
-                      default="")
-  parser.add_argument("-python", "--python_input_file",
-                      help="The Python benchmark result file's name",
-                      default="")
-  parser.add_argument("-go", "--go_input_file",
-                      help="The golang benchmark result file's name",
-                      default="")
-  args = parser.parse_args()
-
-  parse_cpp_result(args.cpp_input_file)
-  parse_python_result(args.python_input_file)
-  parse_java_result(args.java_input_file)
-  parse_go_result(args.go_input_file)
-
-  metadata = get_metadata()
-  print "uploading cpp results..."
-  upload_result(cpp_result, metadata)
-  print "uploading java results..."
-  upload_result(java_result, metadata)
-  print "uploading python results..."
-  upload_result(python_result, metadata)
-  print "uploading go results..."
-  upload_result(go_result, metadata)
diff --git a/benchmarks/util/schema_proto2_to_proto3_util.h b/benchmarks/util/schema_proto2_to_proto3_util.h
index 089012d..0079f6f 100644
--- a/benchmarks/util/schema_proto2_to_proto3_util.h
+++ b/benchmarks/util/schema_proto2_to_proto3_util.h
@@ -74,10 +74,10 @@
 
 };
 
-class SchemaAddZeroEnumValue {
+class EnumScrubber {
 
  public:
-  SchemaAddZeroEnumValue()
+  EnumScrubber()
       : total_added_(0) {
   }
 
@@ -130,6 +130,63 @@
   int total_added_;
 };
 
+class ExtensionStripper {
+ public:
+  static void StripFile(FileDescriptorProto *file) {
+    for (int i = 0; i < file->mutable_message_type()->size(); i++) {
+      StripMessage(file->mutable_message_type(i));
+    }
+    file->mutable_extension()->Clear();
+  }
+ private:
+  static void StripMessage(DescriptorProto *message_type) {
+    message_type->mutable_extension()->Clear();
+    message_type->clear_extension_range();
+    for (int i = 0; i < message_type->mutable_nested_type()->size(); i++) {
+      StripMessage(message_type->mutable_nested_type(i));
+    }
+  }
+};
+
+
+class FieldScrubber {
+ public:
+  static void ScrubFile(FileDescriptorProto *file) {
+    for (int i = 0; i < file->mutable_message_type()->size(); i++) {
+      ScrubMessage(file->mutable_message_type(i));
+    }
+    for (int i = 0; i < file->mutable_extension()->size(); i++) {
+      file->mutable_extension(i)->clear_default_value();
+      if (ShouldClearLabel(file->mutable_extension(i))) {
+        file->mutable_extension(i)->clear_label();
+      }
+    }
+  }
+ private:
+  static bool ShouldClearLabel(const FieldDescriptorProto *field) {
+    return field->label() == FieldDescriptorProto::LABEL_REQUIRED;
+  }
+
+  static void ScrubMessage(DescriptorProto *message_type) {
+    message_type->mutable_extension()->Clear();
+    for (int i = 0; i < message_type->mutable_extension()->size(); i++) {
+      message_type->mutable_extension(i)->clear_default_value();
+      if (ShouldClearLabel(message_type->mutable_extension(i))) {
+        message_type->mutable_extension(i)->clear_label();
+      }
+    }
+    for (int i = 0; i < message_type->mutable_field()->size(); i++) {
+      message_type->mutable_field(i)->clear_default_value();
+      if (ShouldClearLabel(message_type->mutable_field(i))) {
+        message_type->mutable_field(i)->clear_label();
+      }
+    }
+    for (int i = 0; i < message_type->mutable_nested_type()->size(); i++) {
+      ScrubMessage(message_type->mutable_nested_type(i));
+    }
+  }
+};
+
 }  // namespace util
 }  // namespace protobuf
 }  // namespace google
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index 02174e9..ece39f7 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -7,7 +7,11 @@
 
 # CMake policies
 cmake_policy(SET CMP0022 NEW)
-
+# On MacOS use @rpath/ for target's install name prefix path
+if (POLICY CMP0042)
+  cmake_policy(SET CMP0042 NEW)
+endif ()
+# Clear VERSION variables when no VERSION is given to project()
 if(POLICY CMP0048)
   cmake_policy(SET CMP0048 NEW)
 endif()
@@ -166,12 +170,23 @@
   add_definitions(/bigobj)
   string(REPLACE "/" "\\" PROTOBUF_SOURCE_WIN32_PATH ${protobuf_SOURCE_DIR})
   string(REPLACE "/" "\\" PROTOBUF_BINARY_WIN32_PATH ${protobuf_BINARY_DIR})
+  string(REPLACE "." ","  protobuf_RC_FILEVERSION "${protobuf_VERSION}")
   configure_file(extract_includes.bat.in extract_includes.bat)
 
   # Suppress linker warnings about files with no symbols defined.
   set(CMAKE_STATIC_LINKER_FLAGS /ignore:4221)
+
+  # Configure Resource Compiler
+  enable_language(RC)
+  # use English language (0x409) in resource compiler
+  set(rc_flags "/l0x409")
+  # fix rc.exe invocations because of usage of add_definitions()
+  set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> ${rc_flags} <DEFINES> /fo<OBJECT> <SOURCE>")
+
+  configure_file(version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY)
 endif (MSVC)
 
+
 get_filename_component(protobuf_source_dir ${protobuf_SOURCE_DIR} PATH)
 
 include_directories(
diff --git a/cmake/install.cmake b/cmake/install.cmake
index 82036cb..9b2ae93 100644
--- a/cmake/install.cmake
+++ b/cmake/install.cmake
@@ -15,6 +15,13 @@
     PROPERTY INTERFACE_INCLUDE_DIRECTORIES
     $<BUILD_INTERFACE:${protobuf_source_dir}/src>
     $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
+  if (UNIX AND NOT APPLE)
+    set_property(TARGET ${_library}
+      PROPERTY INSTALL_RPATH "$ORIGIN")
+  elseif (APPLE)
+    set_property(TARGET ${_library}
+      PROPERTY INSTALL_RPATH "@loader_path")
+  endif()
   install(TARGETS ${_library} EXPORT protobuf-targets
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${_library}
     LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${_library}
@@ -24,6 +31,13 @@
 if (protobuf_BUILD_PROTOC_BINARIES)
   install(TARGETS protoc EXPORT protobuf-targets
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc)
+  if (UNIX AND NOT APPLE)
+    set_property(TARGET protoc
+      PROPERTY INSTALL_RPATH "$ORIGIN/../lib")
+  elseif (APPLE)
+    set_property(TARGET protoc
+      PROPERTY INSTALL_RPATH "@loader_path/../lib")
+  endif()
 endif (protobuf_BUILD_PROTOC_BINARIES)
 
 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/protobuf.pc ${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake
index 911fce5..1d0b0b8 100644
--- a/cmake/libprotobuf-lite.cmake
+++ b/cmake/libprotobuf-lite.cmake
@@ -48,8 +48,14 @@
   ${protobuf_source_dir}/src/google/protobuf/wire_format_lite.h
 )
 
+if (MSVC)
+set(libprotobuf_lite_rc_files
+  ${CMAKE_CURRENT_BINARY_DIR}/version.rc
+)
+endif()
+
 add_library(libprotobuf-lite ${protobuf_SHARED_OR_STATIC}
-  ${libprotobuf_lite_files} ${libprotobuf_lite_includes})
+  ${libprotobuf_lite_files} ${libprotobuf_lite_includes} ${libprotobuf_lite_rc_files})
 target_link_libraries(libprotobuf-lite ${CMAKE_THREAD_LIBS_INIT})
 target_include_directories(libprotobuf-lite PUBLIC ${protobuf_source_dir}/src)
 if(MSVC AND protobuf_BUILD_SHARED_LIBS)
diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake
index 65d05c1..bd570be 100644
--- a/cmake/libprotobuf.cmake
+++ b/cmake/libprotobuf.cmake
@@ -112,8 +112,14 @@
   ${protobuf_source_dir}/src/google/protobuf/wrappers.pb.h
 )
 
+if (MSVC)
+set(libprotobuf_rc_files
+  ${CMAKE_CURRENT_BINARY_DIR}/version.rc
+)
+endif()
+
 add_library(libprotobuf ${protobuf_SHARED_OR_STATIC}
-  ${libprotobuf_lite_files} ${libprotobuf_files} ${libprotobuf_includes})
+  ${libprotobuf_lite_files} ${libprotobuf_files} ${libprotobuf_includes} ${libprotobuf_rc_files})
 target_link_libraries(libprotobuf ${CMAKE_THREAD_LIBS_INIT})
 if(protobuf_WITH_ZLIB)
     target_link_libraries(libprotobuf ${ZLIB_LIBRARIES})
diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake
index 58568bb..a9f5c36 100644
--- a/cmake/libprotoc.cmake
+++ b/cmake/libprotoc.cmake
@@ -44,8 +44,6 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator_factory.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_helpers.cc
-  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_lazy_message_field.cc
-  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_map_field.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_map_field_lite.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message.cc
@@ -128,8 +126,6 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_file.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator_factory.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_helpers.h
-  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_lazy_message_field.h
-  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_map_field.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_map_field_lite.h
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message.h
@@ -168,7 +164,7 @@
 endif()
 
 add_library(libprotoc ${protobuf_SHARED_OR_STATIC}
-  ${libprotoc_files} ${libprotoc_headers})
+  ${libprotoc_files} ${libprotoc_headers} ${libprotoc_rc_files})
 target_link_libraries(libprotoc libprotobuf)
 if(MSVC AND protobuf_BUILD_SHARED_LIBS)
   target_compile_definitions(libprotoc
diff --git a/cmake/protobuf-config.cmake.in b/cmake/protobuf-config.cmake.in
index acedcc7..69d63e3 100644
--- a/cmake/protobuf-config.cmake.in
+++ b/cmake/protobuf-config.cmake.in
@@ -11,7 +11,7 @@
   include(CMakeParseArguments)
 
   set(_options APPEND_PATH)
-  set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO)
+  set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR)
   if(COMMAND target_sources)
     list(APPEND _singleargs TARGET)
   endif()
@@ -34,15 +34,19 @@
   endif()
   string(TOLOWER ${protobuf_generate_LANGUAGE} protobuf_generate_LANGUAGE)
 
+  if(NOT protobuf_generate_PROTOC_OUT_DIR)
+    set(protobuf_generate_PROTOC_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
+  endif()
+  
   if(protobuf_generate_EXPORT_MACRO AND protobuf_generate_LANGUAGE STREQUAL cpp)
     set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}:")
   endif()
 
-  if(NOT protobuf_GENERATE_EXTENSIONS)
+  if(NOT protobuf_generate_GENERATE_EXTENSIONS)
     if(protobuf_generate_LANGUAGE STREQUAL cpp)
-      set(protobuf_GENERATE_EXTENSIONS .pb.h .pb.cc)
+      set(protobuf_generate_GENERATE_EXTENSIONS .pb.h .pb.cc)
     elseif(protobuf_generate_LANGUAGE STREQUAL python)
-      set(protobuf_GENERATE_EXTENSIONS _pb2.py)
+      set(protobuf_generate_GENERATE_EXTENSIONS _pb2.py)
     else()
       message(SEND_ERROR "Error: protobuf_generate given unknown Language ${LANGUAGE}, please provide a value for GENERATE_EXTENSIONS")
       return()
@@ -88,19 +92,21 @@
   set(_generated_srcs_all)
   foreach(_proto ${protobuf_generate_PROTOS})
     get_filename_component(_abs_file ${_proto} ABSOLUTE)
+    get_filename_component(_abs_dir ${_abs_file} DIRECTORY)
     get_filename_component(_basename ${_proto} NAME_WE)
+    file(RELATIVE_PATH _rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_abs_dir})
 
     set(_generated_srcs)
-    foreach(_ext ${protobuf_GENERATE_EXTENSIONS})
-      list(APPEND _generated_srcs "${CMAKE_CURRENT_BINARY_DIR}/${_basename}${_ext}")
+    foreach(_ext ${protobuf_generate_GENERATE_EXTENSIONS})
+      list(APPEND _generated_srcs "${protobuf_generate_PROTOC_OUT_DIR}/${_rel_dir}/${_basename}${_ext}")
     endforeach()
     list(APPEND _generated_srcs_all ${_generated_srcs})
 
     add_custom_command(
       OUTPUT ${_generated_srcs}
       COMMAND  protobuf::protoc
-      ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${_abs_file}
-      DEPENDS ${ABS_FIL} protobuf::protoc
+      ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR}/${_rel_dir} ${_protobuf_include_path} ${_abs_file}
+      DEPENDS ${_abs_file} protobuf::protoc
       COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}"
       VERBATIM )
   endforeach()
diff --git a/cmake/protoc.cmake b/cmake/protoc.cmake
index 5777b16..bb160f4 100644
--- a/cmake/protoc.cmake
+++ b/cmake/protoc.cmake
@@ -2,6 +2,15 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/main.cc
 )
 
-add_executable(protoc ${protoc_files})
+if (MSVC)
+set(protoc_rc_files
+  ${CMAKE_CURRENT_BINARY_DIR}/version.rc
+)
+endif()
+
+add_executable(protoc ${protoc_files} ${protoc_rc_files})
 target_link_libraries(protoc libprotobuf libprotoc)
 add_executable(protobuf::protoc ALIAS protoc)
+
+set_target_properties(protoc PROPERTIES
+    VERSION ${protobuf_VERSION})
diff --git a/cmake/tests.cmake b/cmake/tests.cmake
index ec790e3..603d7e9 100644
--- a/cmake/tests.cmake
+++ b/cmake/tests.cmake
@@ -204,6 +204,17 @@
   add_compile_options(-DGOOGLE_PROTOBUF_TEST_PLUGIN_PATH="$<TARGET_FILE:test_plugin>")
 endif()
 
+if(MINGW)
+  set_source_files_properties(${tests_files} PROPERTIES COMPILE_FLAGS "-Wno-narrowing")
+
+  # required for tests on MinGW Win64
+  if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--stack,16777216")
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj")
+  endif()
+
+endif()
+
 add_executable(tests ${tests_files} ${common_test_files} ${tests_proto_files} ${lite_test_proto_files})
 target_link_libraries(tests libprotoc libprotobuf gmock_main)
 
diff --git a/cmake/version.rc.in b/cmake/version.rc.in
new file mode 100644
index 0000000..cbce1e5
--- /dev/null
+++ b/cmake/version.rc.in
@@ -0,0 +1,45 @@
+#define VS_FF_DEBUG 0x1L
+#define VS_VERSION_INFO 0x1L
+#define VS_FFI_FILEFLAGSMASK 0x17L
+#define VER_PRIVATEBUILD 0x0L
+#define VER_PRERELEASE 0x0L
+#define VOS__WINDOWS32 0x4L
+#define VFT_DLL 0x2L
+#define VFT2_UNKNOWN 0x0L
+
+#ifndef DEBUG
+#define VER_DEBUG 0
+#else
+#define VER_DEBUG VS_FF_DEBUG
+#endif
+
+
+VS_VERSION_INFO VERSIONINFO
+  FILEVERSION    @protobuf_RC_FILEVERSION@,0
+  PRODUCTVERSION @protobuf_RC_FILEVERSION@,0
+  FILEFLAGSMASK  VS_FFI_FILEFLAGSMASK
+  FILEFLAGS      VER_DEBUG
+  FILEOS         VOS__WINDOWS32
+  FILETYPE       VFT_DLL
+BEGIN
+    BLOCK "VarFileInfo"
+    BEGIN 
+        // English language (0x409) and the Windows Unicode codepage (1200)
+        VALUE "Translation", 0x409, 1200
+    END
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "FileDescription", "Compiled with @CMAKE_CXX_COMPILER_ID@ @CMAKE_CXX_COMPILER_VERSION@\0"
+            VALUE "ProductVersion", "@protobuf_VERSION@\0"
+            VALUE "FileVersion", "@protobuf_VERSION@\0"
+            VALUE "InternalName", "protobuf\0"
+            VALUE "ProductName", "Protocol Buffers - Google's Data Interchange Format\0"
+            VALUE "CompanyName", "Google Inc.\0"
+            VALUE "LegalCopyright", "Copyright 2008 Google Inc.  All rights reserved.\0"
+            VALUE "Licence", "BSD\0"
+            VALUE "Info", "https://developers.google.com/protocol-buffers/\0"
+        END
+    END
+END
diff --git a/configure.ac b/configure.ac
index 7d66827..8e1c308 100644
--- a/configure.ac
+++ b/configure.ac
@@ -190,7 +190,7 @@
 AC_CXX_STL_HASH
 
 case "$target_os" in
-  mingw* | cygwin* | win* | aix*)
+  mingw* | cygwin* | win* | aix* | *android* )
     ;;
   *)
     # Need to link against rt on Solaris
diff --git a/conformance/ConformanceJava.java b/conformance/ConformanceJava.java
index 596d113..dcdc27e 100644
--- a/conformance/ConformanceJava.java
+++ b/conformance/ConformanceJava.java
@@ -235,8 +235,12 @@
         try {
           TestMessagesProto3.TestAllTypesProto3.Builder builder = 
               TestMessagesProto3.TestAllTypesProto3.newBuilder();
-          JsonFormat.parser().usingTypeRegistry(typeRegistry)
-              .merge(request.getJsonPayload(), builder);
+          JsonFormat.Parser parser = JsonFormat.parser().usingTypeRegistry(typeRegistry);
+          if (request.getTestCategory()
+              == Conformance.TestCategory.JSON_IGNORE_UNKNOWN_PARSING_TEST) {
+            parser = parser.ignoringUnknownFields();
+          }
+          parser.merge(request.getJsonPayload(), builder);
           testMessage = builder.build();
         } catch (InvalidProtocolBufferException e) {
           return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
diff --git a/conformance/README.md b/conformance/README.md
index 971fe8f..a5419bf 100644
--- a/conformance/README.md
+++ b/conformance/README.md
@@ -1,8 +1,6 @@
 Protocol Buffers - Google's data interchange format
 ===================================================
 
-[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf)
-
 Copyright 2008 Google Inc.
 
 This directory contains conformance tests for testing completeness and
diff --git a/conformance/conformance.proto b/conformance/conformance.proto
index 525140e..d838e57 100644
--- a/conformance/conformance.proto
+++ b/conformance/conformance.proto
@@ -57,6 +57,17 @@
   JSON = 2;
 }
 
+enum TestCategory {
+  BINARY_TEST = 0;  // Test binary wire format.
+  JSON_TEST = 1;  // 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;  
+}
+
 // Represents a single test case's input.  The testee should:
 //
 //   1. parse this proto (which should always succeed)
@@ -82,6 +93,11 @@
   // protobuf_test_messages.proto3.TestAllTypesProto3 or
   // 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.
+  TestCategory test_category = 5;
 }
 
 // Represents a single test case's output.
diff --git a/conformance/conformance_cpp.cc b/conformance/conformance_cpp.cc
index 97ae1a7..ac2f6de 100644
--- a/conformance/conformance_cpp.cc
+++ b/conformance/conformance_cpp.cc
@@ -46,6 +46,7 @@
 using google::protobuf::Message;
 using google::protobuf::MessageFactory;
 using google::protobuf::util::BinaryToJsonString;
+using google::protobuf::util::JsonParseOptions;
 using google::protobuf::util::JsonToBinaryString;
 using google::protobuf::util::NewTypeResolverForDescriptorPool;
 using google::protobuf::util::Status;
@@ -112,8 +113,13 @@
 
     case ConformanceRequest::kJsonPayload: {
       string proto_binary;
+      JsonParseOptions options;
+      options.ignore_unknown_fields =
+          (request.test_category() ==
+              conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST);
       Status status = JsonToBinaryString(type_resolver, *type_url,
-                                         request.json_payload(), &proto_binary);
+                                         request.json_payload(), &proto_binary,
+                                         options);
       if (!status.ok()) {
         response->set_parse_error(string("Parse error: ") +
                                   status.error_message().as_string());
diff --git a/conformance/conformance_php.php b/conformance/conformance_php.php
index 85fe3d0..799cc3e 100755
--- a/conformance/conformance_php.php
+++ b/conformance/conformance_php.php
@@ -3,6 +3,7 @@
 require_once("Conformance/WireFormat.php");
 require_once("Conformance/ConformanceResponse.php");
 require_once("Conformance/ConformanceRequest.php");
+require_once("Conformance/TestCategory.php");
 require_once("Protobuf_test_messages/Proto3/ForeignMessage.php");
 require_once("Protobuf_test_messages/Proto3/ForeignEnum.php");
 require_once("Protobuf_test_messages/Proto3/TestAllTypesProto3.php");
@@ -12,6 +13,7 @@
 require_once("GPBMetadata/Conformance.php");
 require_once("GPBMetadata/Google/Protobuf/TestMessagesProto3.php");
 
+use  \Conformance\TestCategory;
 use  \Conformance\WireFormat;
 
 if (!ini_get("date.timezone")) {
@@ -39,8 +41,12 @@
         trigger_error("Protobuf request doesn't have specific payload type", E_USER_ERROR);
       }
     } elseif ($request->getPayload() == "json_payload") {
+      $ignore_json_unknown =
+          ($request->getTestCategory() ==
+              TestCategory::JSON_IGNORE_UNKNOWN_PARSING_TEST);
       try {
-          $test_message->mergeFromJsonString($request->getJsonPayload());
+          $test_message->mergeFromJsonString($request->getJsonPayload(),
+                                             $ignore_json_unknown);
       } catch (Exception $e) {
           $response->setParseError($e->getMessage());
           return $response;
diff --git a/conformance/conformance_python.py b/conformance/conformance_python.py
index c5ba246..876642b 100755
--- a/conformance/conformance_python.py
+++ b/conformance/conformance_python.py
@@ -78,7 +78,11 @@
       
     elif request.WhichOneof('payload') == 'json_payload':
       try:
-        json_format.Parse(request.json_payload, test_message)
+        ignore_unknown_fields = \
+            request.test_category == \
+                conformance_pb2.JSON_IGNORE_UNKNOWN_PARSING_TEST
+        json_format.Parse(request.json_payload, test_message,
+                          ignore_unknown_fields)
       except Exception as e:
         response.parse_error = str(e)
         return response
diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc
index 22bbbfb..74342b6 100644
--- a/conformance/conformance_test.cc
+++ b/conformance/conformance_test.cc
@@ -191,6 +191,81 @@
 namespace google {
 namespace protobuf {
 
+ConformanceTestSuite::ConformanceRequestSetting::ConformanceRequestSetting(
+    ConformanceLevel level, conformance::WireFormat input_format,
+    conformance::WireFormat output_format,
+    conformance::TestCategory test_category,
+    bool is_proto3,
+    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";
+
+  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;
+    }
+
+    default:
+      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_requested_output_format(output_format);
+}
+
+Message* ConformanceTestSuite::ConformanceRequestSetting::GetTestMessage() const {
+  if (is_proto3_) {
+    return new TestAllTypesProto3();
+  } else {
+    return new TestAllTypesProto2();
+  }
+}
+
 void ConformanceTestSuite::ReportSuccess(const string& test_name) {
   if (expected_to_fail_.erase(test_name) != 0) {
     StringAppendF(&output_,
@@ -273,75 +348,36 @@
 }
 
 void ConformanceTestSuite::RunValidInputTest(
-    const string& test_name, ConformanceLevel level, const string& input,
-    WireFormat input_format, const string& equivalent_text_format,
-    WireFormat requested_output, bool isProto3) {
-  auto newTestMessage = [&isProto3]() {
-    Message* newMessage;
-    if (isProto3) {
-      newMessage = new TestAllTypesProto3;
-    } else {
-      newMessage = new TestAllTypesProto2;
-    }
-    return newMessage;
-  };
-  Message* reference_message = newTestMessage();
+    const ConformanceRequestSetting& setting,
+    const string& equivalent_text_format) {
+  Message* reference_message = setting.GetTestMessage();
   GOOGLE_CHECK(
       TextFormat::ParseFromString(equivalent_text_format, reference_message))
-          << "Failed to parse data for test case: " << test_name
+          << "Failed to parse data for test case: " << setting.GetTestName()
           << ", data: " << equivalent_text_format;
   const string equivalent_wire_format = reference_message->SerializeAsString();
-  RunValidBinaryInputTest(test_name, level, input, input_format,
-                          equivalent_wire_format, requested_output, isProto3);
+  RunValidBinaryInputTest(setting, equivalent_wire_format);
 }
 
 void ConformanceTestSuite::RunValidBinaryInputTest(
-    const string& test_name, ConformanceLevel level, const string& input,
-    WireFormat input_format, const string& equivalent_wire_format,
-    WireFormat requested_output, bool isProto3) {
-  auto newTestMessage = [&isProto3]() {
-    Message* newMessage;
-    if (isProto3) {
-      newMessage = new TestAllTypesProto3;
-    } else {
-      newMessage = new TestAllTypesProto2;
-    }
-    return newMessage;
-  };
-  Message* reference_message = newTestMessage();
+    const ConformanceRequestSetting& setting,
+    const string& equivalent_wire_format) {
+  const string& test_name = setting.GetTestName();
+  ConformanceLevel level = setting.GetLevel();
+
+  Message* reference_message = setting.GetTestMessage();
   GOOGLE_CHECK(
       reference_message->ParseFromString(equivalent_wire_format))
           << "Failed to parse wire data for test case: " << test_name;
 
-  ConformanceRequest request;
+  const ConformanceRequest& request = setting.GetRequest();
   ConformanceResponse response;
 
-  switch (input_format) {
-    case conformance::PROTOBUF: {
-      request.set_protobuf_payload(input);
-      if (isProto3) {
-        request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3");
-      } else {
-        request.set_message_type("protobuf_test_messages.proto2.TestAllTypesProto2");
-      }
-      break;
-    }
-
-    case conformance::JSON: {
-      request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3");
-      request.set_json_payload(input);
-      break;
-    }
-
-    default:
-      GOOGLE_LOG(FATAL) << "Unspecified input format";
-  }
-
-  request.set_requested_output_format(requested_output);
-
   RunTest(test_name, request, &response);
 
-  Message *test_message = newTestMessage();
+  Message* test_message = setting.GetTestMessage();
+
+  WireFormat requested_output = request.requested_output_format();
 
   switch (response.result_case()) {
     case ConformanceResponse::RESULT_NOT_SET:
@@ -432,6 +468,7 @@
   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 {
@@ -476,56 +513,66 @@
 void ConformanceTestSuite::RunValidJsonTest(
     const string& test_name, ConformanceLevel level, const string& input_json,
     const string& equivalent_text_format) {
-  RunValidInputTest(
-      ConformanceLevelToString(level) + ".Proto3.JsonInput." + test_name +
-      ".ProtobufOutput", level, input_json, conformance::JSON,
-      equivalent_text_format, conformance::PROTOBUF, true);
-  RunValidInputTest(
-      ConformanceLevelToString(level) + ".Proto3.JsonInput." + test_name +
-      ".JsonOutput", level, input_json, conformance::JSON,
-      equivalent_text_format, conformance::JSON, true);
+  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) {
-  RunValidInputTest(
-      ConformanceLevelToString(level) + ".Proto3" + ".ProtobufInput." + test_name +
-      ".JsonOutput", level, input.SerializeAsString(), conformance::PROTOBUF,
-      equivalent_text_format, conformance::JSON, true);
+  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) {
-  string rname = ".Proto3";
-  if (!isProto3) {
-    rname = ".Proto2";
-  }
-  RunValidInputTest(
-      ConformanceLevelToString(level) + rname + ".ProtobufInput." + test_name +
-      ".ProtobufOutput", level, input_protobuf, conformance::PROTOBUF,
-      equivalent_text_format, conformance::PROTOBUF, isProto3);
+  ConformanceRequestSetting setting1(
+      level, conformance::PROTOBUF, conformance::PROTOBUF,
+      conformance::BINARY_TEST,
+      isProto3, test_name, input_protobuf);
+  RunValidInputTest(setting1, equivalent_text_format);
+
   if (isProto3) {
-    RunValidInputTest(
-        ConformanceLevelToString(level) + rname + ".ProtobufInput." +  test_name +
-        ".JsonOutput", level, input_protobuf, conformance::PROTOBUF,
-        equivalent_text_format, conformance::JSON, 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) {
-  string rname = ".Proto3";
-  if (!isProto3) {
-    rname = ".Proto2";
-  }
-  RunValidBinaryInputTest(
-      ConformanceLevelToString(level) + rname + ".ProtobufInput." + test_name +
-      ".ProtobufOutput", level, input_protobuf, conformance::PROTOBUF,
-      input_protobuf, conformance::PROTOBUF, isProto3);
+  ConformanceRequestSetting setting(
+      level, conformance::PROTOBUF, conformance::PROTOBUF,
+      conformance::BINARY_TEST,
+      isProto3, test_name, input_protobuf);
+  RunValidBinaryInputTest(setting, input_protobuf);
 }
 
 void ConformanceTestSuite::RunValidProtobufTestWithMessage(
@@ -2535,6 +2582,43 @@
         }
       )");
 
+  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}
+      })",
+      "");
+
   bool ok = true;
   if (!CheckSetEmpty(expected_to_fail_, "nonexistent_tests.txt",
                      "These tests were listed in the failure list, but they "
diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h
index 2649f8b..2044896 100644
--- a/conformance/conformance_test.h
+++ b/conformance/conformance_test.h
@@ -44,6 +44,7 @@
 #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 {
@@ -146,7 +147,38 @@
     REQUIRED = 0,
     RECOMMENDED = 1,
   };
-  string ConformanceLevelToString(ConformanceLevel level);
+
+  class ConformanceRequestSetting {
+   public:
+    ConformanceRequestSetting(
+        ConformanceLevel level, conformance::WireFormat input_format,
+        conformance::WireFormat output_format,
+        conformance::TestCategory test_category,
+        bool is_proto3,
+        const string& test_name, const string& input);
+
+   Message* GetTestMessage() const;
+
+   const string& GetTestName() const {
+     return test_name_;
+   }
+
+   const conformance::ConformanceRequest& GetRequest() const {
+     return request_;
+   }
+
+   const ConformanceLevel GetLevel() const {
+     return level_;
+   }
+
+   private:
+    ConformanceLevel level_;
+    bool is_proto3_;
+    string test_name_;
+    conformance::ConformanceRequest request_;
+  };
+
+  static string ConformanceLevelToString(ConformanceLevel level);
 
   void ReportSuccess(const std::string& test_name);
   void ReportFailure(const string& test_name,
@@ -160,24 +192,17 @@
   void RunTest(const std::string& test_name,
                const conformance::ConformanceRequest& request,
                conformance::ConformanceResponse* response);
-  void RunValidInputTest(const string& test_name,
-                         ConformanceLevel level,
-                         const string& input,
-                         conformance::WireFormat input_format,
-                         const string& equivalent_text_format,
-                         conformance::WireFormat requested_output,
-                         bool isProto3);
-  void RunValidBinaryInputTest(const string& test_name,
-                               ConformanceLevel level,
-                               const string& input,
-                               conformance::WireFormat input_format,
-                               const string& equivalent_wire_format,
-                               conformance::WireFormat requested_output,
-                               bool isProto3);
+  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,
diff --git a/conformance/failure_list_php_c.txt b/conformance/failure_list_php_c.txt
index 088708e..5f7c0c8 100644
--- a/conformance/failure_list_php_c.txt
+++ b/conformance/failure_list_php_c.txt
@@ -1,8 +1,8 @@
 Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
 Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
 Recommended.FieldMaskTooManyUnderscore.JsonOutput
-Recommended.Proto3.JsonInput.BoolFieldIntegerOne
-Recommended.Proto3.JsonInput.BoolFieldIntegerZero
+Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput
+Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput
 Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator
 Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator
 Recommended.Proto3.JsonInput.DurationHas9FractionalDigits.Validator
@@ -10,20 +10,19 @@
 Recommended.Proto3.JsonInput.Int64FieldBeString.Validator
 Recommended.Proto3.JsonInput.MapFieldValueIsNull
 Recommended.Proto3.JsonInput.OneofZeroBytes.JsonOutput
-Recommended.Proto3.JsonInput.OneofZeroBytes.ProtobufOutput
-Recommended.Proto3.JsonInput.OneofZeroString.JsonOutput
-Recommended.Proto3.JsonInput.OneofZeroString.ProtobufOutput
 Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull
 Recommended.Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull
 Recommended.Proto3.JsonInput.StringEndsWithEscapeChar
 Recommended.Proto3.JsonInput.StringFieldSurrogateInWrongOrder
 Recommended.Proto3.JsonInput.StringFieldUnpairedHighSurrogate
 Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate
+Recommended.Proto3.JsonInput.TimestampHas3FractionalDigits.Validator
+Recommended.Proto3.JsonInput.TimestampHas6FractionalDigits.Validator
+Recommended.Proto3.JsonInput.TimestampHas9FractionalDigits.Validator
+Recommended.Proto3.JsonInput.TimestampHasZeroFractionalDigit.Validator
+Recommended.Proto3.JsonInput.TimestampZeroNormalized.Validator
 Recommended.Proto3.JsonInput.Uint64FieldBeString.Validator
 Recommended.Proto3.ProtobufInput.OneofZeroBytes.JsonOutput
-Recommended.Proto3.ProtobufInput.OneofZeroBytes.ProtobufOutput
-Recommended.Proto3.ProtobufInput.OneofZeroString.JsonOutput
-Recommended.Proto3.ProtobufInput.OneofZeroString.ProtobufOutput
 Required.DurationProtoInputTooLarge.JsonOutput
 Required.DurationProtoInputTooSmall.JsonOutput
 Required.Proto3.JsonInput.Any.JsonOutput
@@ -47,63 +46,23 @@
 Required.Proto3.JsonInput.AnyWithValueForJsonObject.JsonOutput
 Required.Proto3.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
 Required.Proto3.JsonInput.BoolMapField.JsonOutput
-Required.Proto3.JsonInput.DoubleFieldInfinity.JsonOutput
-Required.Proto3.JsonInput.DoubleFieldInfinity.ProtobufOutput
 Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
 Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
-Required.Proto3.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
-Required.Proto3.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
-Required.Proto3.JsonInput.DoubleFieldMinNegativeValue.JsonOutput
-Required.Proto3.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
 Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
 Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
 Required.Proto3.JsonInput.DoubleFieldNan.JsonOutput
-Required.Proto3.JsonInput.DoubleFieldNan.ProtobufOutput
-Required.Proto3.JsonInput.DoubleFieldNegativeInfinity.JsonOutput
-Required.Proto3.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
-Required.Proto3.JsonInput.DoubleFieldQuotedValue.JsonOutput
-Required.Proto3.JsonInput.DoubleFieldQuotedValue.ProtobufOutput
 Required.Proto3.JsonInput.DurationMaxValue.JsonOutput
 Required.Proto3.JsonInput.DurationMaxValue.ProtobufOutput
 Required.Proto3.JsonInput.DurationMinValue.JsonOutput
 Required.Proto3.JsonInput.DurationMinValue.ProtobufOutput
 Required.Proto3.JsonInput.DurationRepeatedValue.JsonOutput
 Required.Proto3.JsonInput.DurationRepeatedValue.ProtobufOutput
-Required.Proto3.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
-Required.Proto3.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
-Required.Proto3.JsonInput.EnumFieldNumericValueZero.JsonOutput
-Required.Proto3.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
-Required.Proto3.JsonInput.EnumFieldUnknownValue.Validator
 Required.Proto3.JsonInput.FieldMask.JsonOutput
 Required.Proto3.JsonInput.FieldMask.ProtobufOutput
 Required.Proto3.JsonInput.FloatFieldInfinity.JsonOutput
-Required.Proto3.JsonInput.FloatFieldInfinity.ProtobufOutput
 Required.Proto3.JsonInput.FloatFieldNan.JsonOutput
-Required.Proto3.JsonInput.FloatFieldNan.ProtobufOutput
 Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput
-Required.Proto3.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
-Required.Proto3.JsonInput.FloatFieldQuotedValue.JsonOutput
-Required.Proto3.JsonInput.FloatFieldQuotedValue.ProtobufOutput
-Required.Proto3.JsonInput.FloatFieldTooLarge
-Required.Proto3.JsonInput.FloatFieldTooSmall
-Required.Proto3.JsonInput.Int32FieldExponentialFormat.JsonOutput
-Required.Proto3.JsonInput.Int32FieldExponentialFormat.ProtobufOutput
-Required.Proto3.JsonInput.Int32FieldFloatTrailingZero.JsonOutput
-Required.Proto3.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
-Required.Proto3.JsonInput.Int32FieldMaxFloatValue.JsonOutput
-Required.Proto3.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
-Required.Proto3.JsonInput.Int32FieldMinFloatValue.JsonOutput
-Required.Proto3.JsonInput.Int32FieldMinFloatValue.ProtobufOutput
-Required.Proto3.JsonInput.Int32FieldStringValue.JsonOutput
-Required.Proto3.JsonInput.Int32FieldStringValue.ProtobufOutput
-Required.Proto3.JsonInput.Int32FieldStringValueEscaped.JsonOutput
-Required.Proto3.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
-Required.Proto3.JsonInput.Int64FieldMaxValue.JsonOutput
-Required.Proto3.JsonInput.Int64FieldMaxValue.ProtobufOutput
-Required.Proto3.JsonInput.Int64FieldMinValue.JsonOutput
-Required.Proto3.JsonInput.Int64FieldMinValue.ProtobufOutput
-Required.Proto3.JsonInput.MessageField.JsonOutput
-Required.Proto3.JsonInput.MessageField.ProtobufOutput
+Required.Proto3.JsonInput.OneofFieldDuplicate
 Required.Proto3.JsonInput.OptionalBoolWrapper.JsonOutput
 Required.Proto3.JsonInput.OptionalBoolWrapper.ProtobufOutput
 Required.Proto3.JsonInput.OptionalBytesWrapper.JsonOutput
@@ -130,8 +89,6 @@
 Required.Proto3.JsonInput.RepeatedBytesWrapper.ProtobufOutput
 Required.Proto3.JsonInput.RepeatedDoubleWrapper.JsonOutput
 Required.Proto3.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
-Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt
-Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
 Required.Proto3.JsonInput.RepeatedFloatWrapper.JsonOutput
 Required.Proto3.JsonInput.RepeatedFloatWrapper.ProtobufOutput
 Required.Proto3.JsonInput.RepeatedInt32Wrapper.JsonOutput
@@ -146,7 +103,6 @@
 Required.Proto3.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
 Required.Proto3.JsonInput.StringFieldEscape.JsonOutput
 Required.Proto3.JsonInput.StringFieldEscape.ProtobufOutput
-Required.Proto3.JsonInput.StringFieldNotAString
 Required.Proto3.JsonInput.StringFieldSurrogatePair.JsonOutput
 Required.Proto3.JsonInput.StringFieldSurrogatePair.ProtobufOutput
 Required.Proto3.JsonInput.StringFieldUnicodeEscape.JsonOutput
@@ -155,10 +111,16 @@
 Required.Proto3.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput
 Required.Proto3.JsonInput.Struct.JsonOutput
 Required.Proto3.JsonInput.Struct.ProtobufOutput
-Required.Proto3.JsonInput.Uint32FieldMaxFloatValue.JsonOutput
-Required.Proto3.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
-Required.Proto3.JsonInput.Uint64FieldMaxValue.JsonOutput
-Required.Proto3.JsonInput.Uint64FieldMaxValue.ProtobufOutput
+Required.Proto3.JsonInput.TimestampMaxValue.JsonOutput
+Required.Proto3.JsonInput.TimestampMaxValue.ProtobufOutput
+Required.Proto3.JsonInput.TimestampMinValue.JsonOutput
+Required.Proto3.JsonInput.TimestampMinValue.ProtobufOutput
+Required.Proto3.JsonInput.TimestampRepeatedValue.JsonOutput
+Required.Proto3.JsonInput.TimestampRepeatedValue.ProtobufOutput
+Required.Proto3.JsonInput.TimestampWithNegativeOffset.JsonOutput
+Required.Proto3.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
+Required.Proto3.JsonInput.TimestampWithPositiveOffset.JsonOutput
+Required.Proto3.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
 Required.Proto3.JsonInput.ValueAcceptBool.JsonOutput
 Required.Proto3.JsonInput.ValueAcceptBool.ProtobufOutput
 Required.Proto3.JsonInput.ValueAcceptFloat.JsonOutput
@@ -167,6 +129,8 @@
 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
diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt
index b268337..2d09acd 100644
--- a/conformance/failure_list_ruby.txt
+++ b/conformance/failure_list_ruby.txt
@@ -135,3 +135,9 @@
 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/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec
index 8a0d61e..901d5ce 100644
--- a/csharp/Google.Protobuf.Tools.nuspec
+++ b/csharp/Google.Protobuf.Tools.nuspec
@@ -33,5 +33,7 @@
     <file src="..\src\google\protobuf\timestamp.proto" target="tools\google\protobuf" />
     <file src="..\src\google\protobuf\type.proto" target="tools\google\protobuf" />
     <file src="..\src\google\protobuf\wrappers.proto" target="tools\google\protobuf" />
+    <file src="Google.Protobuf.Tools.targets" target="buildCrossTargeting" />
+    <file src="Google.Protobuf.Tools.targets" target="build" />
   </files>
 </package>
diff --git a/csharp/Google.Protobuf.Tools.targets b/csharp/Google.Protobuf.Tools.targets
new file mode 100644
index 0000000..682e11b
--- /dev/null
+++ b/csharp/Google.Protobuf.Tools.targets
@@ -0,0 +1,11 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+    <PropertyGroup>

+        <protoc_tools>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)/../tools/'))</protoc_tools>

+        <protoc_linux64>$([System.IO.Path]::GetFullPath('$(protoc_tools)/linux_x64/protoc'))</protoc_linux64>

+        <protoc_linux86>$([System.IO.Path]::GetFullPath('$(protoc_tools)/linux_x86/protoc'))</protoc_linux86>

+        <protoc_macosx64>$([System.IO.Path]::GetFullPath('$(protoc_tools)/macosx_x64/protoc'))</protoc_macosx64>

+        <protoc_macosx86>$([System.IO.Path]::GetFullPath('$(protoc_tools)/macosx_x86/protoc'))</protoc_macosx86>

+        <protoc_windows64>$([System.IO.Path]::GetFullPath('$(protoc_tools)/windows_x64/protoc.exe'))</protoc_windows64>

+        <protoc_windows86>$([System.IO.Path]::GetFullPath('$(protoc_tools)/windows_x86/protoc.exe'))</protoc_windows86>

+    </PropertyGroup>

+</Project>

diff --git a/csharp/build_packages.bat b/csharp/build_packages.bat
index d720565..8157bba 100644
--- a/csharp/build_packages.bat
+++ b/csharp/build_packages.bat
@@ -1,7 +1,7 @@
 @rem Builds Google.Protobuf NuGet packages
 
 dotnet restore src/Google.Protobuf.sln
-dotnet pack -c Release src/Google.Protobuf.sln || goto :error
+dotnet pack -c Release src/Google.Protobuf.sln /p:SourceLinkCreate=true || goto :error
 
 goto :EOF
 
diff --git a/csharp/global.json b/csharp/global.json
index 5ab775b..080dcb9 100644
--- a/csharp/global.json
+++ b/csharp/global.json
@@ -1,5 +1,5 @@
 {
   "sdk": {
-    "version": "2.0.3"
+    "version": "2.1.3"
   }
 }
diff --git a/csharp/src/Google.Protobuf.Conformance/Conformance.cs b/csharp/src/Google.Protobuf.Conformance/Conformance.cs
index f6118ea..6ca52c3 100644
--- a/csharp/src/Google.Protobuf.Conformance/Conformance.cs
+++ b/csharp/src/Google.Protobuf.Conformance/Conformance.cs
@@ -24,21 +24,24 @@
     static ConformanceReflection() {
       byte[] descriptorData = global::System.Convert.FromBase64String(
           string.Concat(
-            "ChFjb25mb3JtYW5jZS5wcm90bxILY29uZm9ybWFuY2UiowEKEkNvbmZvcm1h",
+            "ChFjb25mb3JtYW5jZS5wcm90bxILY29uZm9ybWFuY2Ui1QEKEkNvbmZvcm1h",
             "bmNlUmVxdWVzdBIaChBwcm90b2J1Zl9wYXlsb2FkGAEgASgMSAASFgoManNv",
             "bl9wYXlsb2FkGAIgASgJSAASOAoXcmVxdWVzdGVkX291dHB1dF9mb3JtYXQY",
             "AyABKA4yFy5jb25mb3JtYW5jZS5XaXJlRm9ybWF0EhQKDG1lc3NhZ2VfdHlw",
-            "ZRgEIAEoCUIJCgdwYXlsb2FkIrEBChNDb25mb3JtYW5jZVJlc3BvbnNlEhUK",
-            "C3BhcnNlX2Vycm9yGAEgASgJSAASGQoPc2VyaWFsaXplX2Vycm9yGAYgASgJ",
-            "SAASFwoNcnVudGltZV9lcnJvchgCIAEoCUgAEhoKEHByb3RvYnVmX3BheWxv",
-            "YWQYAyABKAxIABIWCgxqc29uX3BheWxvYWQYBCABKAlIABIRCgdza2lwcGVk",
-            "GAUgASgJSABCCAoGcmVzdWx0KjUKCldpcmVGb3JtYXQSDwoLVU5TUEVDSUZJ",
-            "RUQQABIMCghQUk9UT0JVRhABEggKBEpTT04QAkIhCh9jb20uZ29vZ2xlLnBy",
-            "b3RvYnVmLmNvbmZvcm1hbmNlYgZwcm90bzM="));
+            "ZRgEIAEoCRIwCg10ZXN0X2NhdGVnb3J5GAUgASgOMhkuY29uZm9ybWFuY2Uu",
+            "VGVzdENhdGVnb3J5QgkKB3BheWxvYWQisQEKE0NvbmZvcm1hbmNlUmVzcG9u",
+            "c2USFQoLcGFyc2VfZXJyb3IYASABKAlIABIZCg9zZXJpYWxpemVfZXJyb3IY",
+            "BiABKAlIABIXCg1ydW50aW1lX2Vycm9yGAIgASgJSAASGgoQcHJvdG9idWZf",
+            "cGF5bG9hZBgDIAEoDEgAEhYKDGpzb25fcGF5bG9hZBgEIAEoCUgAEhEKB3Nr",
+            "aXBwZWQYBSABKAlIAEIICgZyZXN1bHQqNQoKV2lyZUZvcm1hdBIPCgtVTlNQ",
+            "RUNJRklFRBAAEgwKCFBST1RPQlVGEAESCAoESlNPThACKlQKDFRlc3RDYXRl",
+            "Z29yeRIPCgtCSU5BUllfVEVTVBAAEg0KCUpTT05fVEVTVBABEiQKIEpTT05f",
+            "SUdOT1JFX1VOS05PV05fUEFSU0lOR19URVNUEAJCIQofY29tLmdvb2dsZS5w",
+            "cm90b2J1Zi5jb25mb3JtYW5jZWIGcHJvdG8z"));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
-          new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Conformance.WireFormat), }, new pbr::GeneratedClrTypeInfo[] {
-            new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceRequest), global::Conformance.ConformanceRequest.Parser, new[]{ "ProtobufPayload", "JsonPayload", "RequestedOutputFormat", "MessageType" }, new[]{ "Payload" }, null, null),
+          new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Conformance.WireFormat), typeof(global::Conformance.TestCategory), }, new pbr::GeneratedClrTypeInfo[] {
+            new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceRequest), global::Conformance.ConformanceRequest.Parser, new[]{ "ProtobufPayload", "JsonPayload", "RequestedOutputFormat", "MessageType", "TestCategory" }, new[]{ "Payload" }, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceResponse), global::Conformance.ConformanceResponse.Parser, new[]{ "ParseError", "SerializeError", "RuntimeError", "ProtobufPayload", "JsonPayload", "Skipped" }, new[]{ "Result" }, null, null)
           }));
     }
@@ -52,6 +55,25 @@
     [pbr::OriginalName("JSON")] Json = 2,
   }
 
+  public enum TestCategory {
+    /// <summary>
+    /// Test binary wire format.
+    /// </summary>
+    [pbr::OriginalName("BINARY_TEST")] BinaryTest = 0,
+    /// <summary>
+    /// Test json wire format.
+    /// </summary>
+    [pbr::OriginalName("JSON_TEST")] JsonTest = 1,
+    /// <summary>
+    /// 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.
+    /// </summary>
+    [pbr::OriginalName("JSON_IGNORE_UNKNOWN_PARSING_TEST")] JsonIgnoreUnknownParsingTest = 2,
+  }
+
   #endregion
 
   #region Messages
@@ -89,6 +111,7 @@
     public ConformanceRequest(ConformanceRequest other) : this() {
       requestedOutputFormat_ = other.requestedOutputFormat_;
       messageType_ = other.messageType_;
+      testCategory_ = other.testCategory_;
       switch (other.PayloadCase) {
         case PayloadOneofCase.ProtobufPayload:
           ProtobufPayload = other.ProtobufPayload;
@@ -158,6 +181,22 @@
       }
     }
 
+    /// <summary>Field number for the "test_category" field.</summary>
+    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.
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Conformance.TestCategory TestCategory {
+      get { return testCategory_; }
+      set {
+        testCategory_ = value;
+      }
+    }
+
     private object payload_;
     /// <summary>Enum of possible cases for the "payload" oneof.</summary>
     public enum PayloadOneofCase {
@@ -194,6 +233,7 @@
       if (JsonPayload != other.JsonPayload) return false;
       if (RequestedOutputFormat != other.RequestedOutputFormat) return false;
       if (MessageType != other.MessageType) return false;
+      if (TestCategory != other.TestCategory) return false;
       if (PayloadCase != other.PayloadCase) return false;
       return Equals(_unknownFields, other._unknownFields);
     }
@@ -205,6 +245,7 @@
       if (payloadCase_ == PayloadOneofCase.JsonPayload) hash ^= JsonPayload.GetHashCode();
       if (RequestedOutputFormat != 0) hash ^= RequestedOutputFormat.GetHashCode();
       if (MessageType.Length != 0) hash ^= MessageType.GetHashCode();
+      if (TestCategory != 0) hash ^= TestCategory.GetHashCode();
       hash ^= (int) payloadCase_;
       if (_unknownFields != null) {
         hash ^= _unknownFields.GetHashCode();
@@ -235,6 +276,10 @@
         output.WriteRawTag(34);
         output.WriteString(MessageType);
       }
+      if (TestCategory != 0) {
+        output.WriteRawTag(40);
+        output.WriteEnum((int) TestCategory);
+      }
       if (_unknownFields != null) {
         _unknownFields.WriteTo(output);
       }
@@ -255,6 +300,9 @@
       if (MessageType.Length != 0) {
         size += 1 + pb::CodedOutputStream.ComputeStringSize(MessageType);
       }
+      if (TestCategory != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) TestCategory);
+      }
       if (_unknownFields != null) {
         size += _unknownFields.CalculateSize();
       }
@@ -272,6 +320,9 @@
       if (other.MessageType.Length != 0) {
         MessageType = other.MessageType;
       }
+      if (other.TestCategory != 0) {
+        TestCategory = other.TestCategory;
+      }
       switch (other.PayloadCase) {
         case PayloadOneofCase.ProtobufPayload:
           ProtobufPayload = other.ProtobufPayload;
@@ -308,6 +359,10 @@
             MessageType = input.ReadString();
             break;
           }
+          case 40: {
+            testCategory_ = (global::Conformance.TestCategory) input.ReadEnum();
+            break;
+          }
         }
       }
     }
diff --git a/csharp/src/Google.Protobuf.Conformance/Program.cs b/csharp/src/Google.Protobuf.Conformance/Program.cs
index 96dc354..1eac00b 100644
--- a/csharp/src/Google.Protobuf.Conformance/Program.cs
+++ b/csharp/src/Google.Protobuf.Conformance/Program.cs
@@ -87,6 +87,9 @@
                 switch (request.PayloadCase)
                 {
                     case ConformanceRequest.PayloadOneofCase.JsonPayload:
+                        if (request.TestCategory == global::Conformance.TestCategory.JsonIgnoreUnknownParsingTest) {
+                            return new ConformanceResponse { Skipped = "CSharp doesn't support skipping unknown fields in json parsing." };
+                        }
                         var parser = new JsonParser(new JsonParser.Settings(20, typeRegistry));
                         message = parser.Parse<ProtobufTestMessages.Proto3.TestAllTypesProto3>(request.JsonPayload);
                         break;
diff --git a/csharp/src/Google.Protobuf.Test/ByteStringTest.cs b/csharp/src/Google.Protobuf.Test/ByteStringTest.cs
old mode 100755
new mode 100644
diff --git a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
old mode 100755
new mode 100644
diff --git a/csharp/src/Google.Protobuf.Test/Compatibility/StreamExtensionsTest.cs b/csharp/src/Google.Protobuf.Test/Compatibility/StreamExtensionsTest.cs
old mode 100755
new mode 100644
diff --git a/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs b/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
old mode 100755
new mode 100644
diff --git a/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs b/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs
old mode 100755
new mode 100644
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
index 9ecd24c..b8c07ef 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
@@ -111,5 +111,106 @@
             var duration = new Timestamp { Seconds = 1, Nanos = -1 };
             Assert.AreEqual("{ \"@warning\": \"Invalid Timestamp\", \"seconds\": \"1\", \"nanos\": -1 }", duration.ToString());
         }
+
+        [Test]
+        public void Comparability()
+        {
+            Timestamp
+                a = null,
+                b = new Timestamp { Seconds = 1, Nanos = 1 },
+                c = new Timestamp { Seconds = 1, Nanos = 10 },
+                d = new Timestamp { Seconds = 10, Nanos = 1 },
+                e = new Timestamp { Seconds = 10, Nanos = 10 };
+
+            Assert.IsTrue(b.CompareTo(a) > 0); // null is always first (according to default behavior of Array.Sort)
+            Assert.IsTrue(b.CompareTo(b) == 0);
+            Assert.IsTrue(b.CompareTo(b.Clone()) == 0);
+            Assert.IsTrue(b.CompareTo(c) < 0);
+            Assert.IsTrue(b.CompareTo(d) < 0);
+            Assert.IsTrue(b.CompareTo(e) < 0);
+
+            Assert.IsTrue(c.CompareTo(a) > 0);
+            Assert.IsTrue(c.CompareTo(b) > 0);
+            Assert.IsTrue(c.CompareTo(c) == 0);
+            Assert.IsTrue(c.CompareTo(c.Clone()) == 0);
+            Assert.IsTrue(c.CompareTo(d) < 0);
+            Assert.IsTrue(c.CompareTo(e) < 0);
+
+            Assert.IsTrue(d.CompareTo(a) > 0);
+            Assert.IsTrue(d.CompareTo(b) > 0);
+            Assert.IsTrue(d.CompareTo(c) > 0);
+            Assert.IsTrue(d.CompareTo(d) == 0);
+            Assert.IsTrue(d.CompareTo(d.Clone()) == 0);
+            Assert.IsTrue(d.CompareTo(e) < 0);
+
+            Assert.IsTrue(e.CompareTo(a) > 0);
+            Assert.IsTrue(e.CompareTo(b) > 0);
+            Assert.IsTrue(e.CompareTo(c) > 0);
+            Assert.IsTrue(e.CompareTo(d) > 0);
+            Assert.IsTrue(e.CompareTo(e) == 0);
+            Assert.IsTrue(e.CompareTo(e.Clone()) == 0);
+        }
+
+
+        [Test]
+        public void ComparabilityOperators()
+        {
+            Timestamp
+                a = null,
+                b = new Timestamp { Seconds = 1, Nanos = 1 },
+                c = new Timestamp { Seconds = 1, Nanos = 10 },
+                d = new Timestamp { Seconds = 10, Nanos = 1 },
+                e = new Timestamp { Seconds = 10, Nanos = 10 };
+
+#pragma warning disable CS1718 // Comparison made to same variable
+            Assert.IsTrue(b > a);
+            Assert.IsTrue(b == b);
+            Assert.IsTrue(b == b.Clone());
+            Assert.IsTrue(b < c);
+            Assert.IsTrue(b < d);
+            Assert.IsTrue(b < e);
+
+            Assert.IsTrue(c > a);
+            Assert.IsTrue(c > b);
+            Assert.IsTrue(c == c);
+            Assert.IsTrue(c == c.Clone());
+            Assert.IsTrue(c < d);
+            Assert.IsTrue(c < e);
+
+            Assert.IsTrue(d > a);
+            Assert.IsTrue(d > b);
+            Assert.IsTrue(d > c);
+            Assert.IsTrue(d == d);
+            Assert.IsTrue(d == d.Clone());
+            Assert.IsTrue(d < e);
+
+            Assert.IsTrue(e > a);
+            Assert.IsTrue(e > b);
+            Assert.IsTrue(e > c);
+            Assert.IsTrue(e > d);
+            Assert.IsTrue(e == e);
+            Assert.IsTrue(e == e.Clone());
+            
+            Assert.IsTrue(b >= a);
+            Assert.IsTrue(b <= c);
+            Assert.IsTrue(b <= d);
+            Assert.IsTrue(b <= e);
+
+            Assert.IsTrue(c >= a);
+            Assert.IsTrue(c >= b);
+            Assert.IsTrue(c <= d);
+            Assert.IsTrue(c <= e);
+
+            Assert.IsTrue(d >= a);
+            Assert.IsTrue(d >= b);
+            Assert.IsTrue(d >= c);
+            Assert.IsTrue(d <= e);
+
+            Assert.IsTrue(e >= a);
+            Assert.IsTrue(e >= b);
+            Assert.IsTrue(e >= c);
+            Assert.IsTrue(e >= d);
+#pragma warning restore CS1718 // Comparison made to same variable
+        }
     }
 }
diff --git a/csharp/src/Google.Protobuf/ByteString.cs b/csharp/src/Google.Protobuf/ByteString.cs
old mode 100755
new mode 100644
diff --git a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs
old mode 100755
new mode 100644
diff --git a/csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs b/csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs
old mode 100755
new mode 100644
diff --git a/csharp/src/Google.Protobuf/Compatibility/StreamExtensions.cs b/csharp/src/Google.Protobuf/Compatibility/StreamExtensions.cs
old mode 100755
new mode 100644
diff --git a/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs b/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs
old mode 100755
new mode 100644
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
index 11bc03d..a056b43 100644
--- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj
+++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
@@ -17,8 +17,6 @@
     <PackageLicenseUrl>https://github.com/google/protobuf/blob/master/LICENSE</PackageLicenseUrl>
     <RepositoryType>git</RepositoryType>
     <RepositoryUrl>https://github.com/google/protobuf.git</RepositoryUrl>
-    <IncludeSymbols>true</IncludeSymbols>
-    <IncludeSource>true</IncludeSource>
   </PropertyGroup>
 
   <!-- 
@@ -30,4 +28,8 @@
     <TargetFrameworks>netstandard1.0</TargetFrameworks>
   </PropertyGroup>
 
+  <ItemGroup>
+    <PackageReference Include="SourceLink.Create.CommandLine" Version="2.7.6" PrivateAssets="All" /> 
+  </ItemGroup>
+
 </Project>
diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs
old mode 100755
new mode 100644
diff --git a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
old mode 100755
new mode 100644
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
old mode 100755
new mode 100644
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs
index aa40347..a925197 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs
@@ -36,7 +36,7 @@
 
 namespace Google.Protobuf.WellKnownTypes
 {
-    public partial class Timestamp : ICustomDiagnosticMessage
+    public partial class Timestamp : ICustomDiagnosticMessage, IComparable<Timestamp>
     {
         private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
         // Constants determined programmatically, but then hard-coded so they can be constant expressions.
@@ -223,6 +223,109 @@
         }
 
         /// <summary>
+        /// Given another timestamp, returns 0 if the timestamps are equivalent, -1 if this timestamp precedes the other, and 1 otherwise
+        /// </summary>
+        /// <remarks>
+        /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
+        /// </remarks>
+        /// <param name="other">Timestamp to compare</param>
+        /// <returns>an integer indicating whether this timestamp precedes or follows the other</returns>
+        public int CompareTo(Timestamp other)
+        {
+            return other == null ? 1
+                : Seconds < other.Seconds ? -1
+                : Seconds > other.Seconds ? 1
+                : Nanos < other.Nanos ? -1
+                : Nanos > other.Nanos ? 1
+                : 0;
+        }
+
+        /// <summary>
+        /// Compares two timestamps and returns whether the first is less than (chronologically precedes) the second
+        /// </summary>
+        /// <remarks>
+        /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
+        /// </remarks>
+        /// <param name="a"></param>
+        /// <param name="b"></param>
+        /// <returns>true if a precedes b</returns>
+        public static bool operator <(Timestamp a, Timestamp b)
+        {
+            return a.CompareTo(b) < 0;
+        }
+
+        /// <summary>
+        /// Compares two timestamps and returns whether the first is greater than (chronologically follows) the second
+        /// </summary>
+        /// <remarks>
+        /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
+        /// </remarks>
+        /// <param name="a"></param>
+        /// <param name="b"></param>
+        /// <returns>true if a follows b</returns>
+        public static bool operator >(Timestamp a, Timestamp b)
+        {
+            return a.CompareTo(b) > 0;
+        }
+
+        /// <summary>
+        /// Compares two timestamps and returns whether the first is less than (chronologically precedes) the second
+        /// </summary>
+        /// <remarks>
+        /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
+        /// </remarks>
+        /// <param name="a"></param>
+        /// <param name="b"></param>
+        /// <returns>true if a precedes b</returns>
+        public static bool operator <=(Timestamp a, Timestamp b)
+        {
+            return a.CompareTo(b) <= 0;
+        }
+
+        /// <summary>
+        /// Compares two timestamps and returns whether the first is greater than (chronologically follows) the second
+        /// </summary>
+        /// <remarks>
+        /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
+        /// </remarks>
+        /// <param name="a"></param>
+        /// <param name="b"></param>
+        /// <returns>true if a follows b</returns>
+        public static bool operator >=(Timestamp a, Timestamp b)
+        {
+            return a.CompareTo(b) >= 0;
+        }
+
+
+        /// <summary>
+        /// Returns whether two timestamps are equivalent
+        /// </summary>
+        /// <remarks>
+        /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
+        /// </remarks>
+        /// <param name="a"></param>
+        /// <param name="b"></param>
+        /// <returns>true if the two timestamps refer to the same nanosecond</returns>
+        public static bool operator ==(Timestamp a, Timestamp b)
+        {
+            return ReferenceEquals(a, b) || (a is null ? (b is null ? true : false) : a.Equals(b));
+        }
+
+        /// <summary>
+        /// Returns whether two timestamps differ
+        /// </summary>
+        /// <remarks>
+        /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results.
+        /// </remarks>
+        /// <param name="a"></param>
+        /// <param name="b"></param>
+        /// <returns>true if the two timestamps differ</returns>
+        public static bool operator !=(Timestamp a, Timestamp b)
+        {
+            return !(a == b);
+        }
+
+        /// <summary>
         /// Returns a string representation of this <see cref="Timestamp"/> for diagnostic purposes.
         /// </summary>
         /// <remarks>
diff --git a/docs/options.md b/docs/options.md
new file mode 100644
index 0000000..529cce5
--- /dev/null
+++ b/docs/options.md
@@ -0,0 +1,190 @@
+# Protobuf Global Extension Registry
+
+This file contains a global registry of known extensions for descriptor.proto,
+so that any developer who wishes to use multiple 3rd party projects, each with
+their own extensions, can be confident that there won't be collisions in
+extension numbers.
+
+If you need an extension number for your custom option (see [custom options](
+https://developers.google.com/protocol-buffers/docs/proto#customoptions)),
+please [send us a pull request](https://github.com/google/protobuf/pulls) to
+add an entry to this doc, or [create an issue](https://github.com/google/protobuf/issues)
+with info about your project (name and website) so we can add an entry for you.
+
+## Existing Registered Extensions
+
+1. C# port of protocol buffers
+   * Website: http://github.com/jskeet/dotnet-protobufs
+   * Extensions: 1000
+
+1. Perl/XS port of protocol buffers
+   * Website: http://code.google.com/p/protobuf-perlxs
+   * Extensions: 1001
+
+1. Objective-C port of protocol buffers
+   * Website: http://code.google.com/p/protobuf-objc
+   * Extensions: 1002
+
+1. Google Wave Federation Protocol open-source release (FedOne)
+   * Website: http://code.google.com/p/wave-protocol
+   * Extensions: 1003
+
+1. PHP code generator plugin
+   * Website: ???
+   * Extensions: 1004
+
+1. GWT code generator plugin (third-party!)
+   * Website: http://code.google.com/p/protobuf-gwt/
+   * Extensions: 1005
+
+1. Unix Domain RPC code generator plugin
+   * Website: http://go/udrpc
+   * Extensions: 1006
+
+1. Object-C generator plugin (Plausible Labs)
+   * Website: http://www.plausible.coop
+   * Extensions: 1007
+
+1. TBD (code42.com)
+   * Website: ???
+   * Extensions: 1008
+
+1. Goby Underwater Autonomy Project
+   * Website: https://launchpad.net/goby
+   * Extensions: 1009
+
+1. Nanopb
+   * Website: http://kapsi.fi/~jpa/nanopb
+   * Extensions: 1010
+
+1. Bluefin AUV Communication Extensions
+   * Website: http://www.bluefinrobotics.com
+   * Extensions: 1011
+
+1. Dynamic Compact Control Language
+   * Website: https://launchpad.net/dccl
+   * Extensions: 1012
+
+1. ScaleOut StateServer® Native C++ API
+   * Website: http://www.scaleoutsoftware.com
+   * Extensions: 1013
+
+1. FoundationDB SQL Layer
+   * Website: https://github.com/FoundationDB/sql-layer
+   * Extensions: 1014
+
+1. Fender
+   * Website: https://github.com/hassox/fender
+   * Extensions: 1015
+
+1. Vortex
+   * Website: http://www.prismtech.com/vortex
+   * Extensions: 1016
+
+1. tresorit
+   * Website: https://tresorit.com/
+   * Extensions: 1017
+
+1. CRIU (Checkpoint Restore In Userspace)
+   * Website: http://criu.org/Main_Page
+   * Extensions: 1018
+
+1. protobuf-c
+   * Website: https://github.com/protobuf-c/protobuf-c
+   * Extensions: 1019
+
+1. ScalePB
+   * Website: http://trueaccord.github.io/ScalaPB/
+   * Extensions: 1020
+
+1. protoc-gen-bq-schema
+   * Website: https://github.com/GoogleCloudPlatform/protoc-gen-bq-schema
+   * Extensions: 1021
+
+1. grpc-gateway
+   * Website: https://github.com/gengo/grpc-gateway
+   * Extensions: 1022
+
+1. Certificate Transparency
+   * Website: https://github.com/google/certificate-transparency
+   * Extensions: 1023
+
+1. JUNOS Router Telemetry
+   * Website: http://www.juniper.net
+   * Extensions: 1024
+
+1. Spine Event Engine
+   * Website: https://github.com/SpineEventEngine/core-java
+   * Extensions: 1025
+
+1. Aruba cloud platform
+   * Website: ???
+   * Extensions: 1026 -> 1030
+
+1. Voltha
+   * Website: ???
+   * Extensions: 1031 -> 1033
+
+1. gator
+   * Website: ???
+   * Extensions: 1034
+
+1. protoc-gen-flowtypes
+   * Website: https://github.com/tmc/grpcutil/tree/master/protoc-gen-flowtypes
+   * Extensions: 1035
+
+1. ProfaneDB
+   * Website: https://gitlab.com/ProfaneDB/ProfaneDB
+   * Extensions: 1036
+
+1. protobuf-net
+   * Website: https://github.com/mgravell/protobuf-net
+   * Extensions: 1037
+
+1. FICO / StreamEngine
+   * Website: http://www.fico.com/
+   * Extensions: 1038
+
+1. GopherJS
+   * Website: https://github.com/johanbrandhorst/protobuf
+   * Extensions: 1039
+
+1. ygot
+   * Website: https://github.com/openconfig/ygot
+   * Extensions: 1040
+
+1. go-grpcmw
+   * Website: https://github.com/MarquisIO/go-grpcmw
+   * Extensions: 1041
+
+1. grpc-gateway protoc-gen-swagger
+   * Website: https://github.com/grpc-ecosystem/grpc-gateway
+   * Extensions: 1042
+
+1. AN Message
+   * Website: TBD
+   * Extensions: 1043
+
+1. protofire
+   * Website: https://github.com/ribrdb/protofire
+   * Extensions: 1044
+
+1. Gravity
+   * Website: https://github.com/aphysci/gravity
+   * Extensions: 1045
+
+1. SEMI Standards – I&C Technical Committee
+   * Website: http://downloads.semi.org/web/wstdsbal.nsf/9c2b317e76523cca88257641005a47f5/88a5863a580e323088256e7b00707489!OpenDocument
+   * Extensions: 1046
+
+1. Elixir plugin
+   * Website: https://github.com/tony612/grpc-elixir
+   * Extensions: 1047
+
+1. API client generators
+   * Website: ???
+   * Extensions: 1048-1056
+
+1. Netifi Proteus
+   * Website: https://github.com/netifi-proteus
+   * Extensions: 1057
diff --git a/docs/performance.md b/docs/performance.md
index 6a5316c..3bca58a 100644
--- a/docs/performance.md
+++ b/docs/performance.md
@@ -1,4 +1,4 @@
-# Protobuf Perforamcne
+# Protobuf Performance
 This benchmark result is tested on workstation with processor of Intel® Xeon® Processor E5-2630 and 32GB RAM
 
 This table contains 3 languages' results:
diff --git a/docs/third_party.md b/docs/third_party.md
index 3f267dd..f710b51 100644
--- a/docs/third_party.md
+++ b/docs/third_party.md
@@ -23,8 +23,10 @@
 * C#: https://silentorbit.com/protobuf/
 * C#/.NET/WCF/VB: http://code.google.com/p/protobuf-net/
 * Clojure: http://github.com/ninjudd/clojure-protobuf
+* Clojure: https://github.com/clojusc/protobuf
 * Common Lisp: http://github.com/ndantam/s-protobuf
 * Common Lisp: http://github.com/brown/protobuf
+* D: https://github.com/dcarp/protobuf-d
 * D: https://github.com/msoucy/dproto
 * D: http://256.makerslocal.org/wiki/index.php/ProtocolBuffer
 * D: https://github.com/opticron/ProtocolBuffer
@@ -39,6 +41,7 @@
 * Erlang: https://code.google.com/p/protoc-gen-erl/
 * Erlang: https://github.com/basho/erlang_protobuffs
 * Erlang: https://github.com/tomas-abrahamsson/gpb
+* GDScript: https://github.com/oniksan/godobuf (Godot v3 engine plugin)
 * Go: https://github.com/golang/protobuf (Google-official implementation)
 * Go: https://github.com/akunspy/gopbuf
 * Go: https://github.com/gogo/protobuf
@@ -87,7 +90,7 @@
 * Scala: http://github.com/jeffplaisance/scala-protobuf
 * Scala: http://code.google.com/p/protobuf-scala
 * Scala: https://github.com/SandroGrzicic/ScalaBuff
-* Scala: http://trueaccord.github.io/ScalaPB/
+* Scala: https://scalapb.github.io
 * Swift: https://github.com/alexeyxo/protobuf-swift
 * Swift: https://github.com/apple/swift-protobuf/
 * Vala: https://launchpad.net/protobuf-vala
@@ -125,6 +128,8 @@
 * https://github.com/johanbrandhorst/protobuf (GopherJS)
 * https://github.com/awakesecurity/gRPC-haskell (Haskell)
 * https://github.com/Yeolar/raster (C++)
+* https://github.com/jnordberg/wsrpc (JavaScript Node.js/Browser)
+* https://github.com/ppissias/xsrpcj (Java)
 
 ## Other Utilities
 
diff --git a/generate_changelog.py b/generate_changelog.py
index d90a9b7..8e5bf42 100755
--- a/generate_changelog.py
+++ b/generate_changelog.py
@@ -20,11 +20,10 @@
   ]),
   Language("Java", [
       "java",
-      "javanano",
-      "src/google/protobuf/compiler/cpp",
+      "src/google/protobuf/compiler/java",
   ]),
   Language("Python", [
-      "javanano",
+      "python",
       "src/google/protobuf/compiler/python",
   ]),
   Language("JavaScript", [
diff --git a/java/core/pom.xml b/java/core/pom.xml
index 067749c..0c0fd8f 100644
--- a/java/core/pom.xml
+++ b/java/core/pom.xml
@@ -135,6 +135,7 @@
             <Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
             <Bundle-SymbolicName>com.google.protobuf</Bundle-SymbolicName>
             <Export-Package>com.google.protobuf;version=${project.version}</Export-Package>
+            <Import-Package>sun.misc;resolution:=optional,*</Import-Package>
           </instructions>
         </configuration>
       </plugin>
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 df01547..1e122d1 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -1407,7 +1407,7 @@
 
   /**
    * A serialized (serializable) form of the generated message.  Stores the
-   * message as a class name and a byte array.
+   * message as a class and a byte array.
    */
   protected static final class SerializedForm implements Serializable {
 
@@ -1417,6 +1417,9 @@
 
     private static final long serialVersionUID = 0L;
 
+    // since v3.6.1
+    private final Class<?> messageClass;
+    // only included for backwards compatibility before messageClass was added
     private final String messageClassName;
     private final byte[] asBytes;
 
@@ -1425,7 +1428,8 @@
      * @param regularForm the message to serialize
      */
     SerializedForm(MessageLite regularForm) {
-      messageClassName = regularForm.getClass().getName();
+      messageClass = regularForm.getClass();
+      messageClassName = messageClass.getName();
       asBytes = regularForm.toByteArray();
     }
 
@@ -1437,7 +1441,7 @@
     @SuppressWarnings("unchecked")
     protected Object readResolve() throws ObjectStreamException {
       try {
-        Class<?> messageClass = Class.forName(messageClassName);
+        Class<?> messageClass = resolveMessageClass();
         java.lang.reflect.Field defaultInstanceField =
             messageClass.getDeclaredField("DEFAULT_INSTANCE");
         defaultInstanceField.setAccessible(true);
@@ -1464,7 +1468,7 @@
     @Deprecated
     private Object readResolveFallback() throws ObjectStreamException {
       try {
-        Class<?> messageClass = Class.forName(messageClassName);
+        Class<?> messageClass = resolveMessageClass();
         java.lang.reflect.Field defaultInstanceField =
             messageClass.getDeclaredField("defaultInstance");
         defaultInstanceField.setAccessible(true);
@@ -1484,6 +1488,10 @@
         throw new RuntimeException("Unable to understand proto buffer", e);
       }
     }
+
+    private Class<?> resolveMessageClass() throws ClassNotFoundException {
+      return messageClass != null ? messageClass : Class.forName(messageClassName);
+    }
   }
 
   /**
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 c9e2904..d84ef3c 100644
--- a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
+++ b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
@@ -33,7 +33,6 @@
 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;
@@ -72,8 +71,6 @@
 
   private static final long BUFFER_ADDRESS_OFFSET = fieldOffset(bufferAddressField());
 
-  private static final long STRING_VALUE_OFFSET = fieldOffset(stringValueField());
-
   private UnsafeUtil() {}
 
   static boolean hasUnsafeArrayOperations() {
@@ -149,10 +146,6 @@
     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);
   }
@@ -262,26 +255,6 @@
     return MEMORY_ACCESSOR.getLong(buffer, BUFFER_ADDRESS_OFFSET);
   }
 
-  /**
-   * Returns a new {@link String} backed by the given {@code chars}. The char array should not
-   * be mutated any more after calling this function.
-   */
-  static String moveToString(char[] chars) {
-    if (STRING_VALUE_OFFSET == -1) {
-      // In the off-chance that this JDK does not implement String as we'd expect, just do a copy.
-      return new String(chars);
-    }
-    final String str;
-    try {
-      str = (String) UNSAFE.allocateInstance(String.class);
-    } catch (InstantiationException e) {
-      // This should never happen, but return a copy as a fallback just in case.
-      return new String(chars);
-    }
-    putObject(str, STRING_VALUE_OFFSET, chars);
-    return str;
-  }
-
   static Object getStaticObject(Field field) {
     return MEMORY_ACCESSOR.getStaticObject(field);
   }
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 6968abb..de75fe6 100644
--- a/java/core/src/main/java/com/google/protobuf/Utf8.java
+++ b/java/core/src/main/java/com/google/protobuf/Utf8.java
@@ -1474,10 +1474,7 @@
         }
       }
 
-      if (resultPos < resultArr.length) {
-        resultArr = Arrays.copyOf(resultArr, resultPos);
-      }
-      return UnsafeUtil.moveToString(resultArr);
+      return new String(resultArr, 0, resultPos);
     }
 
     @Override
@@ -1553,10 +1550,7 @@
         }
       }
 
-      if (resultPos < resultArr.length) {
-        resultArr = Arrays.copyOf(resultArr, resultPos);
-      }
-      return UnsafeUtil.moveToString(resultArr);
+      return new String(resultArr, 0, resultPos);
     }
 
     @Override
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 c9ebe7f..4021f5a 100644
--- a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
+++ b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -32,6 +32,7 @@
 
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Int32Value;
 import com.google.protobuf.test.UnittestImport;
 import protobuf_unittest.EnumWithNoOuter;
 import protobuf_unittest.MessageWithNoOuter;
@@ -853,6 +854,75 @@
     assertEquals(expected, actual);
   }
 
+  public void testDeserializeWithoutClassField() throws Exception {
+    // serialized form for version <=3.6.0
+    // just includes messageClassName and asBytes
+
+    // Int32Value.newBuilder().setValue(123).build()
+    byte[] int32ValueBytes = new byte[]{
+        -84, -19, 0, 5, 115, 114, 0, 55, 99, 111, 109, 46, 103, 111, 111,
+        103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 71,
+        101, 110, 101, 114, 97, 116, 101, 100, 77, 101, 115, 115, 97, 103,
+        101, 76, 105, 116, 101, 36, 83, 101, 114, 105, 97, 108, 105, 122,
+        101, 100, 70, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 91,
+        0, 7, 97, 115, 66, 121, 116, 101, 115, 116, 0, 2, 91, 66, 76, 0,
+        16, 109, 101, 115, 115, 97, 103, 101, 67, 108, 97, 115, 115, 78,
+        97, 109, 101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110,
+        103, 47, 83, 116, 114, 105, 110, 103, 59, 120, 112, 117, 114, 0,
+        2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32, 2, 0, 0, 120, 112, 0,
+        0, 0, 2, 8, 123, 116, 0, 30, 99, 111, 109, 46, 103, 111, 111, 103,
+        108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 73, 110,
+        116, 51, 50, 86, 97, 108, 117, 101
+    };
+
+    ByteArrayInputStream bais = new ByteArrayInputStream(int32ValueBytes);
+    ObjectInputStream in = new ObjectInputStream(bais);
+    Int32Value int32Value = (Int32Value) in.readObject();
+    assertEquals(123, int32Value.getValue());
+  }
+
+  public void testDeserializeWithClassField() throws Exception {
+    // serialized form for version > 3.6.0
+    // includes messageClass, messageClassName (for compatibility), and asBytes
+
+    // Int32Value.newBuilder().setValue(123).build()
+    byte[] int32ValueBytes = new byte[]{
+        -84, -19, 0, 5, 115, 114, 0, 55, 99, 111, 109, 46, 103, 111, 111,
+        103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 71,
+        101, 110, 101, 114, 97, 116, 101, 100, 77, 101, 115, 115, 97, 103,
+        101, 76, 105, 116, 101, 36, 83, 101, 114, 105, 97, 108, 105, 122,
+        101, 100, 70, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 91,
+        0, 7, 97, 115, 66, 121, 116, 101, 115, 116, 0, 2, 91, 66, 76, 0,
+        12, 109, 101, 115, 115, 97, 103, 101, 67, 108, 97, 115, 115, 116,
+        0, 17, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108,
+        97, 115, 115, 59, 76, 0, 16, 109, 101, 115, 115, 97, 103, 101, 67,
+        108, 97, 115, 115, 78, 97, 109, 101, 116, 0, 18, 76, 106, 97, 118,
+        97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59,
+        120, 112, 117, 114, 0, 2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32,
+        2, 0, 0, 120, 112, 0, 0, 0, 2, 8, 123, 118, 114, 0, 30, 99, 111,
+        109, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111,
+        98, 117, 102, 46, 73, 110, 116, 51, 50, 86, 97, 108, 117, 101, 0, 0,
+        0, 0, 0, 0, 0, 0, 2, 0, 2, 66, 0, 21, 109, 101, 109, 111, 105, 122,
+        101, 100, 73, 115, 73, 110, 105, 116, 105, 97, 108, 105, 122, 101,
+        100, 73, 0, 6, 118, 97, 108, 117, 101, 95, 120, 114, 0, 38, 99, 111,
+        109, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111,
+        98, 117, 102, 46, 71, 101, 110, 101, 114, 97, 116, 101, 100, 77,
+        101, 115, 115, 97, 103, 101, 86, 51, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0,
+        1, 76, 0, 13, 117, 110, 107, 110, 111, 119, 110, 70, 105, 101, 108,
+        100, 115, 116, 0, 37, 76, 99, 111, 109, 47, 103, 111, 111, 103, 108,
+        101, 47, 112, 114, 111, 116, 111, 98, 117, 102, 47, 85, 110, 107,
+        110, 111, 119, 110, 70, 105, 101, 108, 100, 83, 101, 116, 59, 120,
+        112, 116, 0, 30, 99, 111, 109, 46, 103, 111, 111, 103, 108, 101, 46,
+        112, 114, 111, 116, 111, 98, 117, 102, 46, 73, 110, 116, 51, 50, 86,
+        97, 108, 117, 101
+    };
+
+    ByteArrayInputStream bais = new ByteArrayInputStream(int32ValueBytes);
+    ObjectInputStream in = new ObjectInputStream(bais);
+    Int32Value int32Value = (Int32Value) in.readObject();
+    assertEquals(123, int32Value.getValue());
+  }
+
   public void testEnumValues() {
     assertEquals(TestAllTypes.NestedEnum.BAR_VALUE, TestAllTypes.NestedEnum.BAR.getNumber());
     assertEquals(TestAllTypes.NestedEnum.BAZ_VALUE, TestAllTypes.NestedEnum.BAZ.getNumber());
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 7f69ee6..a1e2d9c 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
@@ -50,6 +50,7 @@
 import com.google.protobuf.Descriptors.EnumDescriptor;
 import com.google.protobuf.Descriptors.EnumValueDescriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor.Type;
 import com.google.protobuf.Descriptors.FileDescriptor;
 import com.google.protobuf.Descriptors.OneofDescriptor;
 import com.google.protobuf.DoubleValue;
@@ -1539,7 +1540,11 @@
         Object key = parseFieldValue(keyField, new JsonPrimitive(entry.getKey()), entryBuilder);
         Object value = parseFieldValue(valueField, entry.getValue(), entryBuilder);
         if (value == null) {
-          throw new InvalidProtocolBufferException("Map value cannot be null.");
+          if(ignoringUnknownFields && valueField.getType() == Type.ENUM) {
+            continue;
+          } else {
+            throw new InvalidProtocolBufferException("Map value cannot be null.");
+          }
         }
         entryBuilder.setField(keyField, key);
         entryBuilder.setField(valueField, value);
@@ -1557,8 +1562,12 @@
       for (int i = 0; i < array.size(); ++i) {
         Object value = parseFieldValue(field, array.get(i), builder);
         if (value == null) {
-          throw new InvalidProtocolBufferException(
-              "Repeated field elements cannot be null in field: " + field.getFullName());
+          if(ignoringUnknownFields && field.getType() == Type.ENUM) {
+            continue;
+          } else {
+            throw new InvalidProtocolBufferException(
+                  "Repeated field elements cannot be null in field: " + field.getFullName());
+          }
         }
         builder.addRepeatedField(field, value);
       }
@@ -1748,7 +1757,7 @@
           // an exception later.
         }
 
-        if (result == null) {
+        if (result == null && !ignoringUnknownFields) {
           throw new InvalidProtocolBufferException(
               "Invalid enum value: " + value + " for enum type: " + enumDescriptor.getFullName());
         }
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 6ef0850..ede8de7 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
@@ -70,7 +70,6 @@
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Locale;
 import java.util.Set;
@@ -162,6 +161,10 @@
     JsonFormat.parser().merge(json, builder);
   }
 
+  private void mergeFromJsonIgnoringUnknownFields(String json, Message.Builder builder) throws IOException {
+    JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
+  }
+
   public void testAllFields() throws Exception {
     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
     setAllFields(builder);
@@ -669,10 +672,22 @@
               + "}",
           builder);
       fail();
+        
     } catch (InvalidProtocolBufferException e) {
       // Exception expected.
     }
   }
+  
+  public void testMapEnumNullValueIsIgnored() throws Exception {
+    TestMap.Builder builder = TestMap.newBuilder();
+    mergeFromJsonIgnoringUnknownFields(
+        "{\n"
+            + "  \"int32ToEnumMap\": {\"1\": null}\n"
+            + "}",
+        builder);
+      TestMap map = builder.build();
+      assertEquals(0, map.getInt32ToEnumMapMap().entrySet().size());
+ }
 
   public void testParserAcceptNonQuotedObjectKey() throws Exception {
     TestMap.Builder builder = TestMap.newBuilder();
@@ -1173,7 +1188,40 @@
     String json = "{\n" + "  \"unknownField\": \"XXX\"\n" + "}";
     JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
   }
-
+  
+  public void testParserIgnoringUnknownEnums() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    String json = "{\n" + "  \"optionalNestedEnum\": \"XXX\"\n" + "}";
+    JsonFormat.parser().ignoringUnknownFields().merge(json, builder);
+    assertEquals(0, builder.getOptionalNestedEnumValue());
+  }
+  
+  public void testUnknownEnumMap() throws Exception {
+    TestMap.Builder builder = TestMap.newBuilder();
+    JsonFormat.parser().ignoringUnknownFields().merge(
+      "{\n"
+      + "  \"int32ToEnumMap\": {1: XXX, 2: FOO}"
+      + "}",
+      builder);
+        
+      assertEquals(NestedEnum.FOO, builder.getInt32ToEnumMapMap().get(2));
+      assertEquals(1, builder.getInt32ToEnumMapMap().size());
+  }
+  
+  public void testRepeatedUnknownEnum() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    JsonFormat.parser().ignoringUnknownFields().merge(
+      "{\n"
+      + "  \"repeatedNestedEnum\": [XXX, FOO, BAR, BAZ]"
+      + "}",
+      builder);
+          
+    assertEquals(NestedEnum.FOO, builder.getRepeatedNestedEnum(0));
+    assertEquals(NestedEnum.BAR, builder.getRepeatedNestedEnum(1));
+    assertEquals(NestedEnum.BAZ, builder.getRepeatedNestedEnum(2));
+    assertEquals(3, builder.getRepeatedNestedEnumList().size());
+  }
+  
   public void testParserIntegerEnumValue() throws Exception {
     TestAllTypes.Builder actualBuilder = TestAllTypes.newBuilder();
     mergeFromJson("{\n" + "  \"optionalNestedEnum\": 2\n" + "}", actualBuilder);
diff --git a/js/README.md b/js/README.md
index ef0d4b1..97fa7e2 100644
--- a/js/README.md
+++ b/js/README.md
@@ -1,7 +1,7 @@
 Protocol Buffers - Google's data interchange format
 ===================================================
 
-[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf)
+[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-javascript.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fjavascript%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-javascript.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fjavascript%2Fcontinuous)
 
 Copyright 2008 Google Inc.
 
@@ -144,6 +144,7 @@
   The `import_style` option is left to the default, which is `closure`.
 - `--js_out=import_style=commonjs,binary:protos`: this contains the options
   `import_style=commonjs` and `binary` and outputs to the directory `protos`.
+  `import_style=commonjs_strict` doesn't expose the output on the global scope.
 
 API
 ===
diff --git a/js/commonjs/strict_test.js b/js/commonjs/strict_test.js
new file mode 100644
index 0000000..46458c1
--- /dev/null
+++ b/js/commonjs/strict_test.js
@@ -0,0 +1,67 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+// Test suite is written using Jasmine -- see http://jasmine.github.io/
+
+
+
+var googleProtobuf = require('google-protobuf');
+var asserts = require('closure_asserts_commonjs');
+var global = Function('return this')();
+
+// Bring asserts into the global namespace.
+googleProtobuf.object.extend(global, asserts);
+
+var test9_pb = require('./test9_pb');
+var test10_pb = require('./test10_pb');
+
+describe('Strict test suite', function() {
+  it('testImportedMessage', function() {
+    var simple1 = new test9_pb.jspb.exttest.strict.nine.Simple9()
+    var simple2 = new test9_pb.jspb.exttest.strict.nine.Simple9()
+    assertObjectEquals(simple1.toObject(), simple2.toObject());
+  });
+
+  it('testGlobalScopePollution', function() {
+    assertObjectEquals(global.jspb.exttest, undefined);
+  });
+
+  describe('with imports', function() {
+    it('testImportedMessage', function() {
+      var simple1 = new test10_pb.jspb.exttest.strict.ten.Simple10()
+      var simple2 = new test10_pb.jspb.exttest.strict.ten.Simple10()
+      assertObjectEquals(simple1.toObject(), simple2.toObject());
+    });
+
+    it('testGlobalScopePollution', function() {
+      assertObjectEquals(global.jspb.exttest, undefined);
+    });
+  });
+});
diff --git a/js/gulpfile.js b/js/gulpfile.js
index fc9559f..709c5cf 100644
--- a/js/gulpfile.js
+++ b/js/gulpfile.js
@@ -41,6 +41,12 @@
   'commonjs/test7/test7.proto',
 ];
 
+var group3Protos = [
+  'test9.proto',
+  'test10.proto'
+];
+
+
 gulp.task('genproto_well_known_types_closure', function (cb) {
   exec(protoc + ' --js_out=one_output_file_per_input_file,binary:. -I ../src -I . ' + wellKnownTypes.join(' '),
        function (err, stdout, stderr) {
@@ -112,6 +118,15 @@
     cb(err);
   });
 });
+gulp.task('genproto_group3_commonjs_strict', function (cb) {
+  exec('mkdir -p commonjs_out && ' + protoc + ' --js_out=import_style=commonjs_strict,binary:commonjs_out -I ../src -I commonjs -I . ' + group3Protos.join(' '),
+       function (err, stdout, stderr) {
+    console.log(stdout);
+    console.log(stderr);
+    cb(err);
+  });
+});
+
 
 function getClosureBuilderCommand(exportsFile, outputFile) {
   return './node_modules/google-closure-library/closure/bin/build/closurebuilder.py ' +
@@ -159,7 +174,7 @@
   });
 });
 
-gulp.task('make_commonjs_out', ['dist', 'genproto_well_known_types_commonjs', 'genproto_group1_commonjs', 'genproto_group2_commonjs', 'genproto_commonjs_wellknowntypes', 'commonjs_asserts', 'commonjs_testdeps'], function (cb) {
+gulp.task('make_commonjs_out', ['dist', 'genproto_well_known_types_commonjs', 'genproto_group1_commonjs', 'genproto_group2_commonjs', 'genproto_commonjs_wellknowntypes', 'commonjs_asserts', 'commonjs_testdeps', 'genproto_group3_commonjs_strict'], function (cb) {
   // TODO(haberman): minify this more aggressively.
   // Will require proper externs/exports.
   var cmd = "mkdir -p commonjs_out/binary && mkdir -p commonjs_out/test_node_modules && ";
@@ -174,6 +189,7 @@
   exec(cmd +
        'cp commonjs/jasmine.json commonjs_out/jasmine.json && ' +
        'cp google-protobuf.js commonjs_out/test_node_modules && ' +
+       'cp commonjs/strict_test.js commonjs_out/strict_test.js &&' +
        'cp commonjs/import_test.js commonjs_out/import_test.js',
        function (err, stdout, stderr) {
     console.log(stdout);
diff --git a/src/google/protobuf/compiler/js/well_known_types/timestamp.js b/js/test10.proto
similarity index 70%
rename from src/google/protobuf/compiler/js/well_known_types/timestamp.js
rename to js/test10.proto
index b7e43f1..9fa5256 100644
--- a/src/google/protobuf/compiler/js/well_known_types/timestamp.js
+++ b/js/test10.proto
@@ -28,26 +28,12 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-/* This code will be inserted into generated code for
- * google/protobuf/timestamp.proto. */
+syntax = "proto3";
 
-/**
- * Returns a JavaScript 'Date' object corresponding to this Timestamp.
- * @return {!Date}
- */
-proto.google.protobuf.Timestamp.prototype.toDate = function() {
-  var seconds = this.getSeconds();
-  var nanos = this.getNanos();
+package jspb.exttest.strict.ten;
 
-  return new Date((seconds * 1000) + (nanos / 1000000));
-};
+import "test9.proto";
 
-
-/**
- * Sets the value of this Timestamp object to be the given Date.
- * @param {!Date} value The value to set.
- */
-proto.google.protobuf.Timestamp.prototype.fromDate = function(value) {
-  this.setSeconds(Math.floor(value.getTime() / 1000));
-  this.setNanos(value.getMilliseconds() * 1000000);
-};
+message Simple10 {
+    jspb.exttest.strict.nine.Simple9 a = 1;
+}
diff --git a/src/google/protobuf/compiler/js/well_known_types/timestamp.js b/js/test9.proto
similarity index 70%
copy from src/google/protobuf/compiler/js/well_known_types/timestamp.js
copy to js/test9.proto
index b7e43f1..9f68085 100644
--- a/src/google/protobuf/compiler/js/well_known_types/timestamp.js
+++ b/js/test9.proto
@@ -28,26 +28,12 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-/* This code will be inserted into generated code for
- * google/protobuf/timestamp.proto. */
+syntax = "proto2";
 
-/**
- * Returns a JavaScript 'Date' object corresponding to this Timestamp.
- * @return {!Date}
- */
-proto.google.protobuf.Timestamp.prototype.toDate = function() {
-  var seconds = this.getSeconds();
-  var nanos = this.getNanos();
+package jspb.exttest.strict.nine;
 
-  return new Date((seconds * 1000) + (nanos / 1000000));
-};
-
-
-/**
- * Sets the value of this Timestamp object to be the given Date.
- * @param {!Date} value The value to set.
- */
-proto.google.protobuf.Timestamp.prototype.fromDate = function(value) {
-  this.setSeconds(Math.floor(value.getTime() / 1000));
-  this.setNanos(value.getMilliseconds() * 1000000);
-};
+message Simple9 {
+  required string a_string = 1;
+  repeated string a_repeated_string = 2;
+  optional bool a_boolean = 3;
+}
diff --git a/kokoro/linux/benchmark/build.sh b/kokoro/linux/benchmark/build.sh
index 750c3e5..3463ba9 100755
--- a/kokoro/linux/benchmark/build.sh
+++ b/kokoro/linux/benchmark/build.sh
@@ -27,8 +27,8 @@
 ./configure CXXFLAGS="-fPIC -O2"
 make -j8
 cd python
-python setup.py -q build --cpp_implementation
-pip install .
+python setup.py build --cpp_implementation
+pip install . --user
 
 
 # build and run Python benchmark
@@ -41,10 +41,10 @@
 ./python-pure-python-benchmark --json --behavior_prefix="pure-python-benchmark" $datasets  >> tmp/python_result.json
 echo "," >> "tmp/python_result.json"
 echo "benchmarking python cpp reflection..."
-env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" ./python-cpp-reflection-benchmark --json --behavior_prefix="cpp-reflection-benchmark" $datasets  >> tmp/python_result.json
+env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" LD_LIBRARY_PATH="$oldpwd/src/.libs" ./python-cpp-reflection-benchmark --json --behavior_prefix="cpp-reflection-benchmark" $datasets  >> tmp/python_result.json
 echo "," >> "tmp/python_result.json"
 echo "benchmarking python cpp generated code..."
-env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" ./python-cpp-generated-code-benchmark --json --behavior_prefix="cpp-generated-code-benchmark" $datasets >> tmp/python_result.json
+env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" LD_LIBRARY_PATH="$oldpwd/src/.libs" ./python-cpp-generated-code-benchmark --json --behavior_prefix="cpp-generated-code-benchmark" $datasets >> tmp/python_result.json
 echo "]" >> "tmp/python_result.json"
 cd $oldpwd
 
@@ -52,6 +52,11 @@
 ./configure
 make clean && make -j8
 
+# build Java protobuf
+cd java
+mvn package
+cd ..
+
 # build CPP benchmark
 cd benchmarks
 mv tmp/python_result.json . && make clean && make -j8 cpp-benchmark && mv python_result.json tmp
@@ -81,7 +86,7 @@
 
 # upload result to bq
 make python_add_init
-python util/run_and_upload.py -cpp="../tmp/cpp_result.json" -java="../tmp/java_result.json" \
+env LD_LIBRARY_PATH="$oldpwd/src/.libs" python -m util.result_uploader -cpp="../tmp/cpp_result.json" -java="../tmp/java_result.json" \
     -python="../tmp/python_result.json" -go="../tmp/go_result.txt"
 
 cd $oldpwd
diff --git a/kokoro/linux/prepare_build_linux_rc b/kokoro/linux/prepare_build_linux_rc
index f64ea95..d9b3bec 100644
--- a/kokoro/linux/prepare_build_linux_rc
+++ b/kokoro/linux/prepare_build_linux_rc
@@ -7,7 +7,7 @@
 sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EB3E94ADBE1229CF
 sudo apt-get update
 # We use the .NET Core SDK 2.x to build...
-sudo apt-get install -y dotnet-sdk-2.0.3
+sudo apt-get install -y dotnet-sdk-2.1.3
 # But we also need the 1.x framework to test against, as we
 # target netstandard1.x
 sudo apt-get install -y dotnet-sharedframework-microsoft.netcore.app-1.0.5
diff --git a/kokoro/macos/jruby/build.sh b/kokoro/macos/jruby/build.sh
deleted file mode 100755
index c82eaeb..0000000
--- a/kokoro/macos/jruby/build.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-#
-# Build file to set up and run tests
-
-# Change to repo root
-cd $(dirname $0)/../../..
-
-# Prepare worker environment to run tests
-source kokoro/macos/prepare_build_macos_rc
-
-./tests.sh jruby
diff --git a/kokoro/macos/jruby/continuous.cfg b/kokoro/macos/jruby/continuous.cfg
deleted file mode 100644
index f1310fd..0000000
--- a/kokoro/macos/jruby/continuous.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-# Config file for running tests in Kokoro
-
-# Location of the build script in repository
-build_file: "protobuf/kokoro/macos/jruby/build.sh"
-timeout_mins: 1440
diff --git a/kokoro/macos/jruby/presubmit.cfg b/kokoro/macos/jruby/presubmit.cfg
deleted file mode 100644
index f1310fd..0000000
--- a/kokoro/macos/jruby/presubmit.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-# Config file for running tests in Kokoro
-
-# Location of the build script in repository
-build_file: "protobuf/kokoro/macos/jruby/build.sh"
-timeout_mins: 1440
diff --git a/kokoro/release/csharp/windows/build_nuget.bat b/kokoro/release/csharp/windows/build_nuget.bat
new file mode 100644
index 0000000..5da1e13
--- /dev/null
+++ b/kokoro/release/csharp/windows/build_nuget.bat
@@ -0,0 +1,5 @@
+@rem enter repo root
+cd /d %~dp0\..\..\..\..
+
+cd csharp
+call build_packages.bat
diff --git a/kokoro/release/csharp/windows/release.cfg b/kokoro/release/csharp/windows/release.cfg
new file mode 100644
index 0000000..f508c65
--- /dev/null
+++ b/kokoro/release/csharp/windows/release.cfg
@@ -0,0 +1,11 @@
+# Config file for running tests in Kokoro
+
+# Location of the build script in repository
+build_file: "protobuf/kokoro/release/csharp/windows/build_nuget.bat"
+timeout_mins: 60
+
+action {
+  define_artifacts {
+    regex: "**/*.nupkg"
+  }
+}
diff --git a/objectivec/GPBDescriptor.h b/objectivec/GPBDescriptor.h
index 651f4de..292bce1 100644
--- a/objectivec/GPBDescriptor.h
+++ b/objectivec/GPBDescriptor.h
@@ -223,9 +223,12 @@
 /**
  * Returns the enum value name for the given raw enum.
  *
+ * Note that there can be more than one name corresponding to a given value
+ * if the allow_alias option is used.
+ *
  * @param number The raw enum value.
  *
- * @return The name of the enum value passed, or nil if not valid.
+ * @return The first name that matches the enum value passed, or nil if not valid.
  **/
 - (nullable NSString *)enumNameForValue:(int32_t)number;
 
@@ -244,7 +247,7 @@
  *
  * @param number The raw enum value.
  *
- * @return The text format name for the raw enum value, or nil if not valid.
+ * @return The first text format name which matches the enum value, or nil if not valid.
  **/
 - (nullable NSString *)textFormatNameForValue:(int32_t)number;
 
@@ -258,6 +261,33 @@
  **/
 - (BOOL)getValue:(nullable int32_t *)outValue forEnumTextFormatName:(NSString *)textFormatName;
 
+/**
+ * Gets the number of defined enum names.
+ *
+ * @return Count of the number of enum names, including any aliases.
+ */
+@property(nonatomic, readonly) uint32_t enumNameCount;
+
+/**
+ * Gets the enum name corresponding to the given index.
+ *
+ * @param index Index into the available names.  The defined range is from 0
+ *              to self.enumNameCount - 1.
+ *
+ * @returns The enum name at the given index, or nil if the index is out of range.
+ */
+- (nullable NSString *)getEnumNameForIndex:(uint32_t)index;
+
+/**
+ * Gets the enum text format name corresponding to the given index.
+ *
+ * @param index Index into the available names.  The defined range is from 0
+ *              to self.enumNameCount - 1.
+ *
+ * @returns The text format name at the given index, or nil if the index is out of range.
+ */
+- (nullable NSString *)getEnumTextFormatNameForIndex:(uint32_t)index;
+
 @end
 
 /**
diff --git a/objectivec/GPBDescriptor.m b/objectivec/GPBDescriptor.m
index 4b39c63..ad46ef4 100644
--- a/objectivec/GPBDescriptor.m
+++ b/objectivec/GPBDescriptor.m
@@ -830,13 +830,9 @@
 }
 
 - (NSString *)enumNameForValue:(int32_t)number {
-  if (nameOffsets_ == NULL) [self calcValueNameOffsets];
-
   for (uint32_t i = 0; i < valueCount_; ++i) {
     if (values_[i] == number) {
-      const char *valueName = valueNames_ + nameOffsets_[i];
-      NSString *fullName = [NSString stringWithFormat:@"%@_%s", name_, valueName];
-      return fullName;
+      return [self getEnumNameForIndex:i];
     }
   }
   return nil;
@@ -886,8 +882,6 @@
 }
 
 - (NSString *)textFormatNameForValue:(int32_t)number {
-  if (nameOffsets_ == NULL) [self calcValueNameOffsets];
-
   // Find the EnumValue descriptor and its index.
   BOOL foundIt = NO;
   uint32_t valueDescriptorIndex;
@@ -902,16 +896,39 @@
   if (!foundIt) {
     return nil;
   }
+  return [self getEnumTextFormatNameForIndex:valueDescriptorIndex];
+}
 
+- (uint32_t)enumNameCount {
+  return valueCount_;
+}
+
+- (NSString *)getEnumNameForIndex:(uint32_t)index {
+  if (nameOffsets_ == NULL) [self calcValueNameOffsets];
+
+  if (index >= valueCount_) {
+    return nil;
+  }
+  const char *valueName = valueNames_ + nameOffsets_[index];
+  NSString *fullName = [NSString stringWithFormat:@"%@_%s", name_, valueName];
+  return fullName;
+}
+
+- (NSString *)getEnumTextFormatNameForIndex:(uint32_t)index {
+  if (nameOffsets_ == NULL) [self calcValueNameOffsets];
+
+  if (index >= valueCount_) {
+    return nil;
+  }
   NSString *result = nil;
   // Naming adds an underscore between enum name and value name, skip that also.
-  const char *valueName = valueNames_ + nameOffsets_[valueDescriptorIndex];
+  const char *valueName = valueNames_ + nameOffsets_[index];
   NSString *shortName = @(valueName);
 
   // See if it is in the map of special format handling.
   if (extraTextFormatInfo_) {
     result = GPBDecodeTextFormatName(extraTextFormatInfo_,
-                                     (int32_t)valueDescriptorIndex, shortName);
+                                     (int32_t)index, shortName);
   }
   // Logic here needs to match what objectivec_enum.cc does in the proto
   // compiler.
diff --git a/objectivec/README.md b/objectivec/README.md
index a02df33..528f547 100644
--- a/objectivec/README.md
+++ b/objectivec/README.md
@@ -1,7 +1,7 @@
 Protocol Buffers - Google's data interchange format
 ===================================================
 
-[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf)
+[![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) [![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) [![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) [![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)
 
 Copyright 2008 Google Inc.
 
@@ -20,9 +20,10 @@
 Installation
 ------------
 
-The full distribution pulled from github includes the sources for both the
-compiler (protoc) and the runtime (this directory). To build the compiler
-and run the runtime tests, you can use:
+The distribution pulled from github includes the sources for both the
+compiler (protoc) and the runtime (this directory). After cloning the distribution
+and needed submodules ([see the src directory's README](../src/README.md)),
+to build the compiler and run the runtime tests, you can use:
 
      $ objectivec/DevTools/full_mac_build.sh
 
diff --git a/objectivec/Tests/GPBDescriptorTests.m b/objectivec/Tests/GPBDescriptorTests.m
index 199ea65..d47cc30 100644
--- a/objectivec/Tests/GPBDescriptorTests.m
+++ b/objectivec/Tests/GPBDescriptorTests.m
@@ -190,6 +190,63 @@
   XCTAssertFalse([descriptor getValue:&value forEnumTextFormatName:@"Unknown"]);
 }
 
+- (void)testEnumDescriptorIntrospection {
+  GPBEnumDescriptor *descriptor = TestAllTypes_NestedEnum_EnumDescriptor();
+
+  XCTAssertEqual(descriptor.enumNameCount, 4U);
+  XCTAssertEqualObjects([descriptor getEnumNameForIndex:0],
+                        @"TestAllTypes_NestedEnum_Foo");
+  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:0], @"FOO");
+  XCTAssertEqualObjects([descriptor getEnumNameForIndex:1],
+                 @"TestAllTypes_NestedEnum_Bar");
+  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:1], @"BAR");
+  XCTAssertEqualObjects([descriptor getEnumNameForIndex:2],
+                 @"TestAllTypes_NestedEnum_Baz");
+  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:2], @"BAZ");
+  XCTAssertEqualObjects([descriptor getEnumNameForIndex:3],
+                 @"TestAllTypes_NestedEnum_Neg");
+  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:3], @"NEG");
+}
+
+- (void)testEnumDescriptorIntrospectionWithAlias {
+  GPBEnumDescriptor *descriptor = TestEnumWithDupValue_EnumDescriptor();
+  NSString *enumName;
+  int32_t value;
+
+  XCTAssertEqual(descriptor.enumNameCount, 5U);
+
+  enumName = [descriptor getEnumNameForIndex:0];
+  XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Foo1");
+  XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]);
+  XCTAssertEqual(value, 1);
+  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:0], @"FOO1");
+
+  enumName = [descriptor getEnumNameForIndex:1];
+  XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Bar1");
+  XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]);
+  XCTAssertEqual(value, 2);
+  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:1], @"BAR1");
+
+  enumName = [descriptor getEnumNameForIndex:2];
+  XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Baz");
+  XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]);
+  XCTAssertEqual(value, 3);
+  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:2], @"BAZ");
+
+  enumName = [descriptor getEnumNameForIndex:3];
+  XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Foo2");
+  XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]);
+  XCTAssertEqual(value, 1);
+  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:3], @"FOO2");
+
+  enumName = [descriptor getEnumNameForIndex:4];
+  XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Bar2");
+  XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]);
+  XCTAssertEqual(value, 2);
+  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:4], @"BAR2");
+
+}
+
 - (void)testEnumValueValidator {
   GPBDescriptor *descriptor = [TestAllTypes descriptor];
   GPBFieldDescriptor *fieldDescriptor =
diff --git a/objectivec/Tests/GPBTestUtilities.m b/objectivec/Tests/GPBTestUtilities.m
index ebccaac..0362bdd 100644
--- a/objectivec/Tests/GPBTestUtilities.m
+++ b/objectivec/Tests/GPBTestUtilities.m
@@ -85,7 +85,7 @@
   NSLog(@"Wrote data file to %@", path);
 #else
   // Kill off the unused variable warning.
-  dataToWrite = dataToWrite;
+  (void)dataToWrite;
 #endif
   return data;
 }
diff --git a/php/README.md b/php/README.md
index da7884e..967250a 100644
--- a/php/README.md
+++ b/php/README.md
@@ -36,7 +36,7 @@
 
 On Ubuntu, you can install them with:
 ```
-sudo apt-get install php-pear php5-dev autoconf automake libtool make gcc
+sudo apt-get install -y php-pear php5-dev autoconf automake libtool make gcc
 ```
 On other platforms, please use the corresponding package managing tool to
 install them before proceeding.
diff --git a/php/composer.json b/php/composer.json
index 34e0447..20f6a45 100644
--- a/php/composer.json
+++ b/php/composer.json
@@ -9,13 +9,20 @@
     "php": ">=5.5.0"
   },
   "require-dev": {
-    "phpunit/phpunit": ">=4.8.0"
+    "phpunit/phpunit": "^5|^4.8.0"
   },
   "autoload": {
     "psr-4": {
       "Google\\Protobuf\\": "src/Google/Protobuf",
-      "GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf",
+      "GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf"
+    }
+  },
+  "autoload-dev": {
+    "psr-4": {
       "": "tests/generated"
     }
+  },
+  "scripts": {
+    "test": "(cd tests && rm -rf generated && mkdir -p generated && ../../src/protoc --php_out=generated proto/empty/echo.proto proto/test.proto proto/test_include.proto proto/test_no_namespace.proto proto/test_prefix.proto proto/test_php_namespace.proto proto/test_empty_php_namespace.proto proto/test_reserved_enum_lower.proto proto/test_reserved_enum_upper.proto proto/test_reserved_enum_value_lower.proto proto/test_reserved_enum_value_upper.proto proto/test_reserved_message_lower.proto proto/test_reserved_message_upper.proto proto/test_service.proto proto/test_service_namespace.proto proto/test_descriptors.proto) && (cd ../src && ./protoc --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto) && vendor/bin/phpunit"
   }
 }
diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c
index de13dfa..899b99f 100644
--- a/php/ext/google/protobuf/encode_decode.c
+++ b/php/ext/google/protobuf/encode_decode.c
@@ -1587,8 +1587,11 @@
 
   char *data = NULL;
   PHP_PROTO_SIZE data_len;
+  zend_bool ignore_json_unknown = false;
 
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) ==
+  if (zend_parse_parameters(
+          ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &data, &data_len,
+          &ignore_json_unknown) ==
       FAILURE) {
     return;
   }
@@ -1607,7 +1610,7 @@
     stackenv_init(&se, "Error occurred during parsing: %s");
 
     upb_sink_reset(&sink, get_fill_handlers(desc), msg);
-    parser = upb_json_parser_create(&se.env, method, &sink);
+    parser = upb_json_parser_create(&se.env, method, &sink, ignore_json_unknown);
     upb_bufsrc_putbuf(data, data_len, upb_json_parser_input(parser));
 
     stackenv_uninit(&se);
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index 76b97ee..0efe090 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -30,6 +30,7 @@
 
 #include <php.h>
 #include <stdlib.h>
+#include <inttypes.h>
 
 #include "protobuf.h"
 #include "utf8.h"
@@ -1251,28 +1252,62 @@
     return;
   }
 
-  // Get timestamp from Datetime object.
-  zval retval;
-  zval function_name;
-  int64_t timestamp;
+  int64_t timestamp_seconds;
+  {
+    zval retval;
+    zval function_name;
 
 #if PHP_MAJOR_VERSION < 7
-  INIT_ZVAL(retval);
-  INIT_ZVAL(function_name);
+    INIT_ZVAL(retval);
+    INIT_ZVAL(function_name);
 #endif
 
-  PHP_PROTO_ZVAL_STRING(&function_name, "date_timestamp_get", 1);
+    PHP_PROTO_ZVAL_STRING(&function_name, "date_timestamp_get", 1);
 
-  if (call_user_function(EG(function_table), NULL, &function_name, &retval, 1,
-          ZVAL_PTR_TO_CACHED_PTR(datetime) TSRMLS_CC) == FAILURE) {
-    zend_error(E_ERROR, "Cannot get timestamp from DateTime.");
-    return;
+    if (call_user_function(EG(function_table), NULL, &function_name, &retval, 1,
+            ZVAL_PTR_TO_CACHED_PTR(datetime) TSRMLS_CC) == FAILURE) {
+      zend_error(E_ERROR, "Cannot get timestamp from DateTime.");
+      return;
+    }
+
+    protobuf_convert_to_int64(&retval, &timestamp_seconds);
+
+    zval_dtor(&retval);
+    zval_dtor(&function_name);
   }
 
-  protobuf_convert_to_int64(&retval, &timestamp);
+  int64_t timestamp_micros;
+  {
+    zval retval;
+    zval function_name;
+    zval format_string;
 
-  zval_dtor(&retval);
-  zval_dtor(&function_name);
+#if PHP_MAJOR_VERSION < 7
+    INIT_ZVAL(retval);
+    INIT_ZVAL(function_name);
+    INIT_ZVAL(format_string);
+#endif
+
+    PHP_PROTO_ZVAL_STRING(&function_name, "date_format", 1);
+    PHP_PROTO_ZVAL_STRING(&format_string, "u", 1);
+
+    CACHED_VALUE params[2] = {
+      ZVAL_PTR_TO_CACHED_VALUE(datetime),
+      ZVAL_TO_CACHED_VALUE(format_string),
+    };
+
+    if (call_user_function(EG(function_table), NULL, &function_name, &retval,
+            ARRAY_SIZE(params), params TSRMLS_CC) == FAILURE) {
+      zend_error(E_ERROR, "Cannot format DateTime.");
+      return;
+    }
+
+    protobuf_convert_to_int64(&retval, &timestamp_micros);
+
+    zval_dtor(&retval);
+    zval_dtor(&function_name);
+    zval_dtor(&format_string);
+  }
 
   // Set seconds
   MessageHeader* self = UNBOX(MessageHeader, getThis());
@@ -1280,13 +1315,13 @@
       upb_msgdef_ntofz(self->descriptor->msgdef, "seconds");
   void* storage = message_data(self);
   void* memory = slot_memory(self->descriptor->layout, storage, field);
-  *(int64_t*)memory = timestamp;
+  *(int64_t*)memory = timestamp_seconds;
 
   // Set nanos
   field = upb_msgdef_ntofz(self->descriptor->msgdef, "nanos");
   storage = message_data(self);
   memory = slot_memory(self->descriptor->layout, storage, field);
-  *(int32_t*)memory = 0;
+  *(int32_t*)memory = timestamp_micros * 1000;
 
   RETURN_NULL();
 }
@@ -1305,38 +1340,41 @@
   memory = slot_memory(self->descriptor->layout, storage, field);
   int32_t nanos = *(int32_t*)memory;
 
-  // Get formated time string.
-  char formated_time[50];
-  time_t raw_time = seconds;
-  struct tm *utc_time = gmtime(&raw_time);
-  strftime(formated_time, sizeof(formated_time), "%Y-%m-%dT%H:%M:%SUTC",
-           utc_time);
+  // Get formatted time string.
+  char formatted_time[32];
+  snprintf(formatted_time, sizeof(formatted_time), "%" PRId64 ".%06" PRId32,
+           seconds, nanos / 1000);
 
   // Create Datetime object.
   zval datetime;
-  zval formated_time_php;
   zval function_name;
-  int64_t timestamp = 0;
+  zval format_string;
+  zval formatted_time_php;
 
 #if PHP_MAJOR_VERSION < 7
   INIT_ZVAL(function_name);
-  INIT_ZVAL(formated_time_php);
+  INIT_ZVAL(format_string);
+  INIT_ZVAL(formatted_time_php);
 #endif
 
-  PHP_PROTO_ZVAL_STRING(&function_name, "date_create", 1);
-  PHP_PROTO_ZVAL_STRING(&formated_time_php, formated_time, 1);
+  PHP_PROTO_ZVAL_STRING(&function_name, "date_create_from_format", 1);
+  PHP_PROTO_ZVAL_STRING(&format_string, "U.u", 1);
+  PHP_PROTO_ZVAL_STRING(&formatted_time_php, formatted_time, 1);
 
-  CACHED_VALUE params[1] = {ZVAL_TO_CACHED_VALUE(formated_time_php)};
+  CACHED_VALUE params[2] = {
+    ZVAL_TO_CACHED_VALUE(format_string),
+    ZVAL_TO_CACHED_VALUE(formatted_time_php),
+  };
 
-  if (call_user_function(EG(function_table), NULL,
-                         &function_name, &datetime, 1,
-                         params TSRMLS_CC) == FAILURE) {
+  if (call_user_function(EG(function_table), NULL, &function_name, &datetime,
+          ARRAY_SIZE(params), params TSRMLS_CC) == FAILURE) {
     zend_error(E_ERROR, "Cannot create DateTime.");
     return;
   }
 
-  zval_dtor(&formated_time_php);
   zval_dtor(&function_name);
+  zval_dtor(&format_string);
+  zval_dtor(&formatted_time_php);
 
 #if PHP_MAJOR_VERSION < 7
   zval* datetime_ptr = &datetime;
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
index 48072a4..9cb36dc 100644
--- a/php/ext/google/protobuf/protobuf.h
+++ b/php/ext/google/protobuf/protobuf.h
@@ -42,6 +42,10 @@
 #define MAX_LENGTH_OF_INT64 20
 #define SIZEOF_INT64 8
 
+/* From Chromium. */
+#define ARRAY_SIZE(x) \
+    ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
+
 // -----------------------------------------------------------------------------
 // PHP7 Wrappers
 // ----------------------------------------------------------------------------
diff --git a/php/ext/google/protobuf/upb.c b/php/ext/google/protobuf/upb.c
index e01f3bf..4644430 100644
--- a/php/ext/google/protobuf/upb.c
+++ b/php/ext/google/protobuf/upb.c
@@ -14344,6 +14344,9 @@
 
   /* Intermediate result of parsing a unicode escape sequence. */
   uint32_t digit;
+
+  /* Whether to proceed if unknown field is met. */
+  bool ignore_json_unknown;
 };
 
 struct upb_json_parsermethod {
@@ -14864,6 +14867,11 @@
     return false;
   }
 
+  if (p->top->f == NULL) {
+    multipart_end(p);
+    return true;
+  }
+
   return parse_number(p, false);
 }
 
@@ -15016,6 +15024,10 @@
 static bool parser_putbool(upb_json_parser *p, bool val) {
   bool ok;
 
+  if (p->top->f == NULL) {
+    return true;
+  }
+
   if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL) {
     upb_status_seterrf(&p->status,
                        "Boolean value specified for non-bool field: %s",
@@ -15031,7 +15043,10 @@
 }
 
 static bool start_stringval(upb_json_parser *p) {
-  UPB_ASSERT(p->top->f);
+  if (p->top->f == NULL) {
+    multipart_startaccum(p);
+    return true;
+  }
 
   if (upb_fielddef_isstring(p->top->f)) {
     upb_jsonparser_frame *inner;
@@ -15082,6 +15097,11 @@
 static bool end_stringval(upb_json_parser *p) {
   bool ok = true;
 
+  if (p->top->f == NULL) {
+    multipart_end(p);
+    return true;
+  }
+
   switch (upb_fielddef_type(p->top->f)) {
     case UPB_TYPE_BYTES:
       if (!base64_push(p, getsel_for_handlertype(p, UPB_HANDLER_STRING),
@@ -15273,6 +15293,10 @@
 static bool end_membername(upb_json_parser *p) {
   UPB_ASSERT(!p->top->f);
 
+  if (!p->top->m) {
+    return true;
+  }
+
   if (p->top->is_map) {
     return handle_mapentry(p);
   } else {
@@ -15285,9 +15309,10 @@
       multipart_end(p);
 
       return true;
+    } else if (p->ignore_json_unknown) {
+      multipart_end(p);
+      return true;
     } else {
-      /* TODO(haberman): Ignore unknown fields if requested/configured to do
-       * so. */
       upb_status_seterrf(&p->status, "No such field: %.*s\n", (int)len, buf);
       upb_env_reporterror(p->env, &p->status);
       return false;
@@ -15319,7 +15344,18 @@
 }
 
 static bool start_subobject(upb_json_parser *p) {
-  UPB_ASSERT(p->top->f);
+  if (p->top->f == NULL) {
+    upb_jsonparser_frame *inner;
+    if (!check_stack(p)) return false;
+
+    inner = p->top + 1;
+    inner->m = NULL;
+    inner->f = NULL;
+    inner->is_map = false;
+    inner->is_mapentry = false;
+    p->top = inner;
+    return true;
+  }
 
   if (upb_fielddef_ismap(p->top->f)) {
     upb_jsonparser_frame *inner;
@@ -15378,9 +15414,12 @@
     upb_sink_endseq(&p->top->sink, sel);
   } else {
     upb_selector_t sel;
+    bool is_unknown = p->top->m == NULL;
     p->top--;
-    sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG);
-    upb_sink_endsubmsg(&p->top->sink, sel);
+    if (!is_unknown) {
+      sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG);
+      upb_sink_endsubmsg(&p->top->sink, sel);
+    }
   }
 }
 
@@ -15462,11 +15501,11 @@
  * final state once, when the closing '"' is seen. */
 
 
-#line 1310 "upb/json/parser.rl"
+#line 1349 "upb/json/parser.rl"
 
 
 
-#line 1222 "upb/json/parser.c"
+#line 1261 "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, 
@@ -15615,7 +15654,7 @@
 static const int json_en_main = 1;
 
 
-#line 1313 "upb/json/parser.rl"
+#line 1352 "upb/json/parser.rl"
 
 size_t parse(void *closure, const void *hd, const char *buf, size_t size,
              const upb_bufhandle *handle) {
@@ -15637,7 +15676,7 @@
   capture_resume(parser, buf);
 
   
-#line 1393 "upb/json/parser.c"
+#line 1432 "upb/json/parser.c"
 	{
 	int _klen;
 	unsigned int _trans;
@@ -15712,118 +15751,118 @@
 		switch ( *_acts++ )
 		{
 	case 0:
-#line 1225 "upb/json/parser.rl"
+#line 1264 "upb/json/parser.rl"
 	{ p--; {cs = stack[--top]; goto _again;} }
 	break;
 	case 1:
-#line 1226 "upb/json/parser.rl"
+#line 1265 "upb/json/parser.rl"
 	{ p--; {stack[top++] = cs; cs = 10; goto _again;} }
 	break;
 	case 2:
-#line 1230 "upb/json/parser.rl"
+#line 1269 "upb/json/parser.rl"
 	{ start_text(parser, p); }
 	break;
 	case 3:
-#line 1231 "upb/json/parser.rl"
+#line 1270 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_text(parser, p)); }
 	break;
 	case 4:
-#line 1237 "upb/json/parser.rl"
+#line 1276 "upb/json/parser.rl"
 	{ start_hex(parser); }
 	break;
 	case 5:
-#line 1238 "upb/json/parser.rl"
+#line 1277 "upb/json/parser.rl"
 	{ hexdigit(parser, p); }
 	break;
 	case 6:
-#line 1239 "upb/json/parser.rl"
+#line 1278 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_hex(parser)); }
 	break;
 	case 7:
-#line 1245 "upb/json/parser.rl"
+#line 1284 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(escape(parser, p)); }
 	break;
 	case 8:
-#line 1251 "upb/json/parser.rl"
+#line 1290 "upb/json/parser.rl"
 	{ p--; {cs = stack[--top]; goto _again;} }
 	break;
 	case 9:
-#line 1254 "upb/json/parser.rl"
+#line 1293 "upb/json/parser.rl"
 	{ {stack[top++] = cs; cs = 19; goto _again;} }
 	break;
 	case 10:
-#line 1256 "upb/json/parser.rl"
+#line 1295 "upb/json/parser.rl"
 	{ p--; {stack[top++] = cs; cs = 27; goto _again;} }
 	break;
 	case 11:
-#line 1261 "upb/json/parser.rl"
+#line 1300 "upb/json/parser.rl"
 	{ start_member(parser); }
 	break;
 	case 12:
-#line 1262 "upb/json/parser.rl"
+#line 1301 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_membername(parser)); }
 	break;
 	case 13:
-#line 1265 "upb/json/parser.rl"
+#line 1304 "upb/json/parser.rl"
 	{ end_member(parser); }
 	break;
 	case 14:
-#line 1271 "upb/json/parser.rl"
+#line 1310 "upb/json/parser.rl"
 	{ start_object(parser); }
 	break;
 	case 15:
-#line 1274 "upb/json/parser.rl"
+#line 1313 "upb/json/parser.rl"
 	{ end_object(parser); }
 	break;
 	case 16:
-#line 1280 "upb/json/parser.rl"
+#line 1319 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(start_array(parser)); }
 	break;
 	case 17:
-#line 1284 "upb/json/parser.rl"
+#line 1323 "upb/json/parser.rl"
 	{ end_array(parser); }
 	break;
 	case 18:
-#line 1289 "upb/json/parser.rl"
+#line 1328 "upb/json/parser.rl"
 	{ start_number(parser, p); }
 	break;
 	case 19:
-#line 1290 "upb/json/parser.rl"
+#line 1329 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_number(parser, p)); }
 	break;
 	case 20:
-#line 1292 "upb/json/parser.rl"
+#line 1331 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(start_stringval(parser)); }
 	break;
 	case 21:
-#line 1293 "upb/json/parser.rl"
+#line 1332 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(end_stringval(parser)); }
 	break;
 	case 22:
-#line 1295 "upb/json/parser.rl"
+#line 1334 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(parser_putbool(parser, true)); }
 	break;
 	case 23:
-#line 1297 "upb/json/parser.rl"
+#line 1336 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(parser_putbool(parser, false)); }
 	break;
 	case 24:
-#line 1299 "upb/json/parser.rl"
+#line 1338 "upb/json/parser.rl"
 	{ /* null value */ }
 	break;
 	case 25:
-#line 1301 "upb/json/parser.rl"
+#line 1340 "upb/json/parser.rl"
 	{ CHECK_RETURN_TOP(start_subobject(parser)); }
 	break;
 	case 26:
-#line 1302 "upb/json/parser.rl"
+#line 1341 "upb/json/parser.rl"
 	{ end_subobject(parser); }
 	break;
 	case 27:
-#line 1307 "upb/json/parser.rl"
+#line 1346 "upb/json/parser.rl"
 	{ p--; {cs = stack[--top]; goto _again;} }
 	break;
-#line 1579 "upb/json/parser.c"
+#line 1618 "upb/json/parser.c"
 		}
 	}
 
@@ -15836,7 +15875,7 @@
 	_out: {}
 	}
 
-#line 1334 "upb/json/parser.rl"
+#line 1373 "upb/json/parser.rl"
 
   if (p != pe) {
     upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p);
@@ -15877,13 +15916,13 @@
 
   /* Emit Ragel initialization of the parser. */
   
-#line 1633 "upb/json/parser.c"
+#line 1672 "upb/json/parser.c"
 	{
 	cs = json_start;
 	top = 0;
 	}
 
-#line 1374 "upb/json/parser.rl"
+#line 1413 "upb/json/parser.rl"
   p->current_state = cs;
   p->parser_top = top;
   accumulate_clear(p);
@@ -15970,7 +16009,8 @@
 
 upb_json_parser *upb_json_parser_create(upb_env *env,
                                         const upb_json_parsermethod *method,
-                                        upb_sink *output) {
+                                        upb_sink *output,
+                                        bool ignore_json_unknown) {
 #ifndef NDEBUG
   const size_t size_before = upb_env_bytesallocated(env);
 #endif
@@ -15989,6 +16029,8 @@
   p->top->m = upb_handlers_msgdef(output->handlers);
   set_name_table(p, p->top);
 
+  p->ignore_json_unknown = ignore_json_unknown;
+
   /* If this fails, uncomment and increase the value in parser.h. */
   /* fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before); */
   UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(env) - size_before <=
diff --git a/php/ext/google/protobuf/upb.h b/php/ext/google/protobuf/upb.h
index a263db3..180f471 100644
--- a/php/ext/google/protobuf/upb.h
+++ b/php/ext/google/protobuf/upb.h
@@ -9457,7 +9457,7 @@
 class upb::json::Parser {
  public:
   static Parser* Create(Environment* env, const ParserMethod* method,
-                        Sink* output);
+                        Sink* output, bool ignore_json_unknown);
 
   BytesSink* input();
 
@@ -9491,7 +9491,8 @@
 
 upb_json_parser* upb_json_parser_create(upb_env* e,
                                         const upb_json_parsermethod* m,
-                                        upb_sink* output);
+                                        upb_sink* output,
+                                        bool ignore_json_unknown);
 upb_bytessink *upb_json_parser_input(upb_json_parser *p);
 
 upb_json_parsermethod* upb_json_parsermethod_new(const upb_msgdef* md,
@@ -9511,8 +9512,8 @@
 namespace upb {
 namespace json {
 inline Parser* Parser::Create(Environment* env, const ParserMethod* method,
-                              Sink* output) {
-  return upb_json_parser_create(env, method, output);
+                              Sink* output, bool ignore_json_unknown) {
+  return upb_json_parser_create(env, method, output, ignore_json_unknown);
 }
 inline BytesSink* Parser::input() {
   return upb_json_parser_input(this);
diff --git a/php/src/Google/Protobuf/Internal/GPBJsonWire.php b/php/src/Google/Protobuf/Internal/GPBJsonWire.php
index 9ae57ab..43f4745 100644
--- a/php/src/Google/Protobuf/Internal/GPBJsonWire.php
+++ b/php/src/Google/Protobuf/Internal/GPBJsonWire.php
@@ -226,7 +226,7 @@
                 $output->writeRaw("\"", 1);
                 break;
             case GPBType::STRING:
-                $value = json_encode($value);
+                $value = json_encode($value, JSON_UNESCAPED_UNICODE);
                 $output->writeRaw($value, strlen($value));
                 break;
             //    case GPBType::GROUP:
diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php
index 73ac375..8ff141c 100644
--- a/php/src/Google/Protobuf/Internal/Message.php
+++ b/php/src/Google/Protobuf/Internal/Message.php
@@ -1563,7 +1563,7 @@
                 }
                 break;
             case GPBType::STRING:
-                $value = json_encode($value);
+                $value = json_encode($value, JSON_UNESCAPED_UNICODE);
                 $size += strlen($value);
                 break;
             case GPBType::BYTES:
diff --git a/php/src/Google/Protobuf/Timestamp.php b/php/src/Google/Protobuf/Timestamp.php
index e21f323..6d26f6c 100644
--- a/php/src/Google/Protobuf/Timestamp.php
+++ b/php/src/Google/Protobuf/Timestamp.php
@@ -55,7 +55,9 @@
  * {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
  * seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
  * are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
- * is required, though only UTC (as indicated by "Z") is presently supported.
+ * is required. A proto3 JSON serializer should always use UTC (as indicated by
+ * "Z") when printing the Timestamp type and a proto3 JSON parser should be
+ * able to accept both UTC and other timezones (as indicated by an offset).
  * For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
  * 01:30 UTC on January 15, 2017.
  * In JavaScript, one can convert a Date object to this format using the
@@ -64,8 +66,8 @@
  * to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime)
  * with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
  * can use the Joda Time's [`ISODateTimeFormat.dateTime()`](
- * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--)
- * to obtain a formatter capable of generating timestamps in this format.
+ * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--
+ * ) to obtain a formatter capable of generating timestamps in this format.
  *
  * Generated from protobuf message <code>google.protobuf.Timestamp</code>
  */
@@ -180,18 +182,19 @@
      */
     public function fromDateTime(\DateTime $datetime)
     {
-        $this->seconds = $datetime->format('U');
-        $this->nanos = 0;
+        $this->seconds = $datetime->getTimestamp();
+        $this->nanos = 1000 * $datetime->format('u');
     }
 
     /**
-     * Converts Timestamp to PHP DateTime. Nano second is ignored.
+     * Converts Timestamp to PHP DateTime.
      *
      * @return \DateTime $datetime
      */
     public function toDateTime()
     {
-        return \DateTime::createFromFormat('U', $this->seconds);
+        $time = sprintf('%s.%06d', $this->seconds, $this->nanos / 1000);
+        return \DateTime::createFromFormat('U.u', $time);
     }
 }
 
diff --git a/php/tests/compatibility_test.sh b/php/tests/compatibility_test.sh
index b377d85..c4d6325 100755
--- a/php/tests/compatibility_test.sh
+++ b/php/tests/compatibility_test.sh
@@ -124,6 +124,7 @@
 sed -i.bak '/generated_phpdoc_test.php/d' phpunit.xml
 sed -i.bak 's/generated_phpdoc_test.php//g' tests/test.sh
 sed -i.bak '/memory_leak_test.php/d' tests/test.sh
+sed -i.bak '/^    public function testTimestamp()$/,/^    }$/d' tests/well_known_test.php
 for t in "${tests[@]}"
 do
   remove_error_test tests/$t
diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php
index 4e3874b..f3bcb96 100644
--- a/php/tests/memory_leak_test.php
+++ b/php/tests/memory_leak_test.php
@@ -152,7 +152,7 @@
 $from = new DateTime('2011-01-01T15:03:01.012345UTC');
 $timestamp->fromDateTime($from);
 assert($from->format('U') == $timestamp->getSeconds());
-assert(0 == $timestamp->getNanos());
+assert(1000 * $from->format('u') == $timestamp->getNanos());
 
 $to = $timestamp->toDateTime();
 assert(\DateTime::class == get_class($to));
diff --git a/php/tests/undefined_test.php b/php/tests/undefined_test.php
index f844457..935d8be 100644
--- a/php/tests/undefined_test.php
+++ b/php/tests/undefined_test.php
@@ -909,7 +909,7 @@
     /**
      * @expectedException PHPUnit_Framework_Error
      */
-    public function testMessageSetNullFail()
+    public function testMessageSetNullFailMap()
     {
        $arr =
            new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class);
diff --git a/php/tests/well_known_test.php b/php/tests/well_known_test.php
index 1e8c4f4..9f2661f 100644
--- a/php/tests/well_known_test.php
+++ b/php/tests/well_known_test.php
@@ -312,11 +312,12 @@
         $from = new DateTime('2011-01-01T15:03:01.012345UTC');
         $timestamp->fromDateTime($from);
         $this->assertEquals($from->format('U'), $timestamp->getSeconds());
-        $this->assertSame(0, $timestamp->getNanos());
+        $this->assertEquals(1000 * $from->format('u'), $timestamp->getNanos());
 
         $to = $timestamp->toDateTime();
         $this->assertSame(\DateTime::class, get_class($to));
         $this->assertSame($from->format('U'), $to->format('U'));
+        $this->assertSame($from->format('u'), $to->format('u'));
     }
 
     public function testType()
diff --git a/protobuf.bzl b/protobuf.bzl
index 78f19c6..67d61d7 100644
--- a/protobuf.bzl
+++ b/protobuf.bzl
@@ -1,3 +1,5 @@
+load("@bazel_skylib//:lib.bzl", "versions")
+
 def _GetPath(ctx, path):
   if ctx.label.workspace_root:
     return ctx.label.workspace_root + '/' + path
@@ -72,7 +74,7 @@
   deps = []
   deps += ctx.files.srcs
   source_dir = _SourceDir(ctx)
-  gen_dir = _GenDir(ctx)
+  gen_dir = _GenDir(ctx).rstrip('/')
   if source_dir:
     import_flags = ["-I" + source_dir, "-I" + gen_dir]
   else:
@@ -82,37 +84,83 @@
     import_flags += dep.proto.import_flags
     deps += dep.proto.deps
 
-  args = []
-  if ctx.attr.gen_cc:
-    args += ["--cpp_out=" + gen_dir]
-  if ctx.attr.gen_py:
-    args += ["--python_out=" + gen_dir]
+  if not ctx.attr.gen_cc and not ctx.attr.gen_py and not ctx.executable.plugin:
+    return struct(
+        proto=struct(
+            srcs=srcs,
+            import_flags=import_flags,
+            deps=deps,
+        ),  
+    )   
 
-  inputs = srcs + deps
-  if ctx.executable.plugin:
-    plugin = ctx.executable.plugin
-    lang = ctx.attr.plugin_language
-    if not lang and plugin.basename.startswith('protoc-gen-'):
-      lang = plugin.basename[len('protoc-gen-'):]
-    if not lang:
-      fail("cannot infer the target language of plugin", "plugin_language")
+  for src in srcs:
+    args = []
 
-    outdir = gen_dir
-    if ctx.attr.plugin_options:
-      outdir = ",".join(ctx.attr.plugin_options) + ":" + outdir
-    args += ["--plugin=protoc-gen-%s=%s" % (lang, plugin.path)]
-    args += ["--%s_out=%s" % (lang, outdir)]
-    inputs += [plugin]
+    in_gen_dir = src.root.path == gen_dir
+    if in_gen_dir:
+      import_flags_real = []
+      for f in depset(import_flags):
+        path = f.replace('-I', '') 
+        import_flags_real.append('-I$(realpath -s %s)' % path)
 
-  if args:
-    ctx.action(
-        inputs=inputs,
-        outputs=ctx.outputs.outs,
-        arguments=args + import_flags + [s.path for s in srcs],
-        executable=ctx.executable.protoc,
-        mnemonic="ProtoCompile",
-        use_default_shell_env=True,
-    )
+    outs = []
+    use_grpc_plugin = (ctx.attr.plugin_language == "grpc" and ctx.attr.plugin)
+    path_tpl = "$(realpath %s)" if in_gen_dir else "%s"
+    if ctx.attr.gen_cc:
+      args += [("--cpp_out=" + path_tpl) % gen_dir]
+      outs.extend(_CcOuts([src.basename], use_grpc_plugin=use_grpc_plugin))
+    if ctx.attr.gen_py:
+      args += [("--python_out=" + path_tpl) % gen_dir]
+      outs.extend(_PyOuts([src.basename], use_grpc_plugin=use_grpc_plugin))
+
+    outs = [ctx.actions.declare_file(out, sibling=src) for out in outs]
+    inputs = [src] + deps
+    if ctx.executable.plugin:
+      plugin = ctx.executable.plugin
+      lang = ctx.attr.plugin_language
+      if not lang and plugin.basename.startswith('protoc-gen-'):
+        lang = plugin.basename[len('protoc-gen-'):]
+      if not lang:
+        fail("cannot infer the target language of plugin", "plugin_language")
+
+      outdir = "." if in_gen_dir else gen_dir
+
+      if ctx.attr.plugin_options:
+        outdir = ",".join(ctx.attr.plugin_options) + ":" + outdir
+      args += [("--plugin=protoc-gen-%s=" + path_tpl) % (lang, plugin.path)]
+      args += ["--%s_out=%s" % (lang, outdir)]
+      inputs += [plugin]
+
+    if not in_gen_dir:
+      ctx.action(
+          inputs=inputs,
+          outputs=outs,
+          arguments=args + import_flags + [src.path],
+          executable=ctx.executable.protoc,
+          mnemonic="ProtoCompile",
+          use_default_shell_env=True,
+      )
+    else:
+      for out in outs:
+        orig_command = " ".join(
+            ["$(realpath %s)" % ctx.executable.protoc.path] + args +
+            import_flags_real + ["-I.", src.basename])
+        command = ";".join([
+            'CMD="%s"' % orig_command,
+            "cd %s" % src.dirname,
+            "${CMD}",
+            "cd -",
+        ])
+        generated_out = '/'.join([gen_dir,  out.basename])
+        if generated_out != out.path:
+            command += ";mv %s %s" % (generated_out, out.path)
+        ctx.action(
+            inputs=inputs + [ctx.executable.protoc],
+            outputs=[out],
+            command=command,
+            mnemonic="ProtoCompile",
+            use_default_shell_env=True,
+        )
 
   return struct(
       proto=struct(
@@ -266,8 +314,8 @@
   Args:
     srcs: the well known protos
   """
-  root = Label("%s//protobuf_java" % (REPOSITORY_NAME)).workspace_root
-  pkg = PACKAGE_NAME + "/" if PACKAGE_NAME else ""
+  root = Label("%s//protobuf_java" % (native.repository_name())).workspace_root
+  pkg = native.package_name() + "/" if native.package_name() else ""
   if root == "":
     include = " -I%ssrc " % pkg
   else:
@@ -411,7 +459,4 @@
   This ensures bazel supports our approach to proto_library() depending on a
   copied filegroup. (Fixed in bazel 0.5.4)
   """
-  expected = apple_common.dotted_version("0.5.4")
-  current = apple_common.dotted_version(native.bazel_version)
-  if current.compare_to(expected) < 0:
-    fail("Bazel must be newer than 0.5.4")
+  versions.check(minimum_bazel_version = "0.5.4")
diff --git a/protoc-artifacts/README.md b/protoc-artifacts/README.md
index 9b14889..1131a89 100644
--- a/protoc-artifacts/README.md
+++ b/protoc-artifacts/README.md
@@ -119,7 +119,9 @@
           protoc.exe
         + x86_32
           protoc.exe
-      + macos
+        + aarch_64
+          protoc.exe
+      + osx
         + x86_64
           protoc.exe
         + x86_32
@@ -137,7 +139,7 @@
 staging repository.
 
 ```
-$ mvn clean deploy -P release
+$ mvn deploy -P release
 ```
 
 It creates a new staging repository. Go to
diff --git a/python/README.md b/python/README.md
index 4c19429..3eb78e5 100644
--- a/python/README.md
+++ b/python/README.md
@@ -1,7 +1,7 @@
 Protocol Buffers - Google's data interchange format
 ===================================================
 
-[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf)
+[![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) [![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) [![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) [![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)
 
 Copyright 2008 Google Inc.
 
@@ -30,7 +30,7 @@
 Installation
 ============
 
-1) Make sure you have Python 2.6 or newer.  If in doubt, run:
+1) Make sure you have Python 2.7 or newer.  If in doubt, run:
 
        $ python -V
 
diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py
index d891dce..7f64940 100644
--- a/python/google/protobuf/internal/json_format_test.py
+++ b/python/google/protobuf/internal/json_format_test.py
@@ -791,9 +791,6 @@
     json_format.Parse(text, parsed_message, ignore_unknown_fields=True)
 
   def testDuplicateField(self):
-    # Duplicate key check is not supported for python2.6
-    if sys.version_info < (2, 7):
-      return
     self.CheckError('{"int32Value": 1,\n"int32Value":2}',
                     'Failed to load JSON: duplicate key int32Value.')
 
diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py
index 8d338d3..58c94a4 100644
--- a/python/google/protobuf/json_format.py
+++ b/python/google/protobuf/json_format.py
@@ -396,11 +396,7 @@
   """
   if not isinstance(text, six.text_type): text = text.decode('utf-8')
   try:
-    if sys.version_info < (2, 7):
-      # object_pair_hook is not supported before python2.7
-      js = json.loads(text)
-    else:
-      js = json.loads(text, object_pairs_hook=_DuplicateChecker)
+    js = json.loads(text, object_pairs_hook=_DuplicateChecker)
   except ValueError as e:
     raise ParseError('Failed to load JSON: {0}.'.format(str(e)))
   return ParseDict(js, message, ignore_unknown_fields)
diff --git a/python/google/protobuf/proto_api.h b/python/google/protobuf/proto_api.h
new file mode 100644
index 0000000..5c076d2
--- /dev/null
+++ b/python/google/protobuf/proto_api.h
@@ -0,0 +1,92 @@
+// 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.
+
+// This file can be included by other C++ libraries, typically extension modules
+// which want to interact with the Python Messages coming from the "cpp"
+// implementation of protocol buffers.
+//
+// Usage:
+// Declare a (probably static) variable to hold the API:
+//    const PyProto_API* py_proto_api;
+// In some initialization function, write:
+//    py_proto_api = static_cast<const PyProto_API*>(PyCapsule_Import(
+//        PyProtoAPICapsuleName(), 0));
+//    if (!py_proto_api) { ...handle ImportError... }
+// 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__
+
+#include <Python.h>
+
+namespace google {
+namespace protobuf {
+
+class Message;
+
+namespace python {
+
+// Note on the implementation:
+// This API is designed after
+// https://docs.python.org/3/extending/extending.html#providing-a-c-api-for-an-extension-module
+// The class below contains no mutable state, and all methods are "const";
+// we use a C++ class instead of a C struct with functions pointers just because
+// the code looks more readable.
+struct PyProto_API {
+  // The API object is created at initialization time and never freed.
+  // This destructor is never called.
+  virtual ~PyProto_API() {}
+
+  // Operations on Messages.
+
+  // If the passed object is a Python Message, returns its internal pointer.
+  // Otherwise, returns NULL with an exception set.
+  virtual const Message* GetMessagePointer(PyObject* msg) const = 0;
+
+  // If the passed object is a Python Message, returns a mutable pointer.
+  // Otherwise, returns NULL with an exception set.
+  // This function will succeed only if there are no other Python objects
+  // pointing to the message, like submessages or repeated containers.
+  // With the current implementation, only empty messages are in this case.
+  virtual Message* GetMutableMessagePointer(PyObject* msg) const = 0;
+};
+
+inline const char* PyProtoAPICapsuleName() {
+  static const char kCapsuleName[] =
+      "google.protobuf.pyext._message.proto_API";
+  return kCapsuleName;
+}
+
+}  // namespace python
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // PYTHON_GOOGLE_PROTOBUF_PROTO_API_H__
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc
index 8af0cb1..19a1c38 100644
--- a/python/google/protobuf/pyext/descriptor.cc
+++ b/python/google/protobuf/pyext/descriptor.cc
@@ -56,7 +56,7 @@
   #endif
   #define PyString_AsStringAndSize(ob, charpp, sizep) \
     (PyUnicode_Check(ob)? \
-       ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
+       ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \
        PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
 #endif
 
diff --git a/python/google/protobuf/pyext/descriptor_containers.cc b/python/google/protobuf/pyext/descriptor_containers.cc
index bc007f7..0153664 100644
--- a/python/google/protobuf/pyext/descriptor_containers.cc
+++ b/python/google/protobuf/pyext/descriptor_containers.cc
@@ -66,7 +66,7 @@
   #endif
   #define PyString_AsStringAndSize(ob, charpp, sizep) \
     (PyUnicode_Check(ob)? \
-       ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
+       ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \
        PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
 #endif
 
diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc
index 95882ae..962accc 100644
--- a/python/google/protobuf/pyext/descriptor_pool.cc
+++ b/python/google/protobuf/pyext/descriptor_pool.cc
@@ -48,7 +48,7 @@
   #endif
   #define PyString_AsStringAndSize(ob, charpp, sizep) \
     (PyUnicode_Check(ob)? \
-       ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
+       ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \
        PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
 #endif
 
diff --git a/python/google/protobuf/pyext/extension_dict.cc b/python/google/protobuf/pyext/extension_dict.cc
index 018b5c2..174c547 100644
--- a/python/google/protobuf/pyext/extension_dict.cc
+++ b/python/google/protobuf/pyext/extension_dict.cc
@@ -53,7 +53,7 @@
   #endif
   #define PyString_AsStringAndSize(ob, charpp, sizep) \
     (PyUnicode_Check(ob)? \
-       ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
+       ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \
        PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
 #endif
 
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index 5893533..b298450 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -79,7 +79,7 @@
     (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AsString(ob))
   #define PyString_AsStringAndSize(ob, charpp, sizep) \
     (PyUnicode_Check(ob)? \
-       ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
+       ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \
        PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
   #endif
 #endif
@@ -1529,7 +1529,7 @@
     return NULL;
   }
 #else
-  field_name = PyUnicode_AsUTF8AndSize(arg, &size);
+  field_name = const_cast<char*>(PyUnicode_AsUTF8AndSize(arg, &size));
   if (!field_name) {
     return NULL;
   }
@@ -2866,17 +2866,38 @@
 Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg);
 
 static const Message* GetCProtoInsidePyProtoImpl(PyObject* msg) {
+  const Message* message = PyMessage_GetMessagePointer(msg);
+  if (message == NULL) {
+    PyErr_Clear();
+    return NULL;
+  }
+  return message;
+}
+
+static Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) {
+  Message* message = PyMessage_GetMutableMessagePointer(msg);
+  if (message == NULL) {
+    PyErr_Clear();
+    return NULL;
+  }
+  return message;
+}
+
+const Message* PyMessage_GetMessagePointer(PyObject* msg) {
   if (!PyObject_TypeCheck(msg, &CMessage_Type)) {
+    PyErr_SetString(PyExc_TypeError, "Not a Message instance");
     return NULL;
   }
   CMessage* cmsg = reinterpret_cast<CMessage*>(msg);
   return cmsg->message;
 }
 
-static Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) {
+Message* PyMessage_GetMutableMessagePointer(PyObject* msg) {
   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 &&
@@ -2885,6 +2906,9 @@
     // the underlying C++ message back to the CMessage (e.g. removed repeated
     // composite containers). We only allow direct mutation of the underlying
     // C++ message if there is no child data in the CMessage.
+    PyErr_SetString(PyExc_ValueError,
+                    "Cannot reliably get a mutable pointer "
+                    "to a message with extra references");
     return NULL;
   }
   cmessage::AssureWritable(cmsg);
diff --git a/python/google/protobuf/pyext/message.h b/python/google/protobuf/pyext/message.h
index 72bcfa8..d754e62 100644
--- a/python/google/protobuf/pyext/message.h
+++ b/python/google/protobuf/pyext/message.h
@@ -341,6 +341,9 @@
 
 extern PyObject* PickleError_class;
 
+const Message* PyMessage_GetMessagePointer(PyObject* msg);
+Message* PyMessage_GetMutableMessagePointer(PyObject* msg);
+
 bool InitProto2MessageModule(PyObject *m);
 
 #if LANG_CXX11
diff --git a/python/google/protobuf/pyext/message_module.cc b/python/google/protobuf/pyext/message_module.cc
index 7c4df47..8c93386 100644
--- a/python/google/protobuf/pyext/message_module.cc
+++ b/python/google/protobuf/pyext/message_module.cc
@@ -31,9 +31,26 @@
 #include <Python.h>
 
 #include <google/protobuf/pyext/message.h>
+#include <google/protobuf/proto_api.h>
 
 #include <google/protobuf/message_lite.h>
 
+namespace {
+
+// 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 {
+    return google::protobuf::python::PyMessage_GetMessagePointer(msg);
+  }
+  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()) {
@@ -113,6 +130,15 @@
       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;
diff --git a/python/setup.py b/python/setup.py
index a9df075..5ec4dcb 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -44,6 +44,7 @@
 
   with open(os.path.join('google', 'protobuf', '__init__.py')) as version_file:
     exec(version_file.read(), globals())
+    global __version__
     return __version__
 
 
@@ -148,10 +149,9 @@
 class test_conformance(_build_py):
   target = 'test_python'
   def run(self):
-    if sys.version_info >= (2, 7):
-      # Python 2.6 dodges these extra failures.
-      os.environ["CONFORMANCE_PYTHON_EXTRA_FAILURES"] = (
-          "--failure_list failure_list_python-post26.txt")
+    # Python 2.6 dodges these extra failures.
+    os.environ["CONFORMANCE_PYTHON_EXTRA_FAILURES"] = (
+        "--failure_list failure_list_python-post26.txt")
     cmd = 'cd ../conformance && make %s' % (test_conformance.target)
     status = subprocess.check_call(cmd, shell=True)
 
@@ -185,6 +185,7 @@
         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('-std=c++11')
 
     # https://github.com/Theano/Theano/issues/4926
     if sys.platform == 'win32':
@@ -201,12 +202,6 @@
     if "clang" in os.popen('$CC --version 2> /dev/null').read():
       extra_compile_args.append('-Wno-shorten-64-to-32')
 
-    v, _, _ = platform.mac_ver()
-    if v:
-      extra_compile_args.append('-std=c++11')
-    elif os.getenv('KOKORO_BUILD_NUMBER') or os.getenv('KOKORO_BUILD_ID'):
-      extra_compile_args.append('-std=c++11')
-
     if warnings_as_errors in sys.argv:
       extra_compile_args.append('-Werror')
       sys.argv.remove(warnings_as_errors)
diff --git a/python/stubout.py b/python/stubout.py
index aee4f2d..ba39104 100755
--- a/python/stubout.py
+++ b/python/stubout.py
@@ -17,6 +17,9 @@
 # This file is used for testing.  The original is at:
 #   http://code.google.com/p/pymox/
 
+import inspect
+
+
 class StubOutForTesting:
   """Sample Usage:
      You want os.path.exists() to always return true during testing.
diff --git a/ruby/ext/google/protobuf_c/defs.c b/ruby/ext/google/protobuf_c/defs.c
index d9d2eba..9fe0450 100644
--- a/ruby/ext/google/protobuf_c/defs.c
+++ b/ruby/ext/google/protobuf_c/defs.c
@@ -812,7 +812,7 @@
   upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
   const char* str = get_str(value);
   if (!upb_fielddef_hassubdef(self->fielddef)) {
-    rb_raise(rb_eTypeError, "FieldDescriptor does not have subdef.");
+    rb_raise(cTypeError, "FieldDescriptor does not have subdef.");
   }
   CHECK_UPB(upb_fielddef_setsubdefname(mut_def, str, &status),
             "Error setting submessage name");
@@ -854,7 +854,7 @@
   MessageHeader* msg;
   TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
   if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
-    rb_raise(rb_eTypeError, "get method called on wrong message type");
+    rb_raise(cTypeError, "get method called on wrong message type");
   }
   return layout_get(msg->descriptor->layout, Message_data(msg), self->fielddef);
 }
@@ -872,7 +872,7 @@
   MessageHeader* msg;
   TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
   if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
-    rb_raise(rb_eTypeError, "set method called on wrong message type");
+    rb_raise(cTypeError, "set method called on wrong message type");
   }
   layout_set(msg->descriptor->layout, Message_data(msg), self->fielddef, value);
   return Qnil;
@@ -1713,7 +1713,7 @@
        upb_msg_field_next(&it)) {
     const upb_fielddef* field = upb_msg_iter_field(&it);
     if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) {
-      rb_raise(rb_eTypeError, "Required fields are unsupported in proto3.");
+      rb_raise(cTypeError, "Required fields are unsupported in proto3.");
     }
   }
 }
@@ -1723,7 +1723,7 @@
   // value.)
   const char* lookup = upb_enumdef_iton(enumdef, 0);
   if (lookup == NULL) {
-    rb_raise(rb_eTypeError,
+    rb_raise(cTypeError,
              "Enum definition does not contain a value for '0'.");
   }
 }
diff --git a/ruby/ext/google/protobuf_c/encode_decode.c b/ruby/ext/google/protobuf_c/encode_decode.c
index 9fa4bfd..d584205 100644
--- a/ruby/ext/google/protobuf_c/encode_decode.c
+++ b/ruby/ext/google/protobuf_c/encode_decode.c
@@ -963,13 +963,15 @@
 
   if (ary == Qnil) return;
 
+  size = NUM2INT(RepeatedField_length(ary));
+  if (size == 0 && !emit_defaults) return;
+
   upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
 
   if (upb_fielddef_isprimitive(f)) {
     sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
   }
 
-  size = NUM2INT(RepeatedField_length(ary));
   for (int i = 0; i < size; i++) {
     void* memory = RepeatedField_index_native(ary, i);
     switch (type) {
diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c
index 63a61ba..721c111 100644
--- a/ruby/ext/google/protobuf_c/message.c
+++ b/ruby/ext/google/protobuf_c/message.c
@@ -256,6 +256,10 @@
              "Unknown field name '%s' in initialization map entry.", name);
   }
 
+  if (TYPE(val) == T_NIL) {
+    return 0;
+  }
+
   if (is_map_field(f)) {
     VALUE map;
 
@@ -631,7 +635,7 @@
     const char* name = upb_enum_iter_name(&it);
     int32_t value = upb_enum_iter_number(&it);
     if (name[0] < 'A' || name[0] > 'Z') {
-      rb_raise(rb_eTypeError,
+      rb_raise(cTypeError,
                "Enum value '%s' does not start with an uppercase letter "
                "as is required for Ruby constants.",
                name);
diff --git a/ruby/ext/google/protobuf_c/protobuf.c b/ruby/ext/google/protobuf_c/protobuf.c
index db69642..fe6bb40 100644
--- a/ruby/ext/google/protobuf_c/protobuf.c
+++ b/ruby/ext/google/protobuf_c/protobuf.c
@@ -41,6 +41,7 @@
 
 VALUE cError;
 VALUE cParseError;
+VALUE cTypeError;
 
 void add_def_obj(const void* def, VALUE value) {
   rb_hash_aset(upb_def_to_ruby_obj_map, ULL2NUM((intptr_t)def), value);
@@ -102,6 +103,7 @@
 
   cError = rb_const_get(protobuf, rb_intern("Error"));
   cParseError = rb_const_get(protobuf, rb_intern("ParseError"));
+  cTypeError = rb_const_get(protobuf, rb_intern("TypeError"));
 
   rb_define_singleton_method(protobuf, "discard_unknown",
                              Google_Protobuf_discard_unknown, 1);
diff --git a/ruby/ext/google/protobuf_c/protobuf.h b/ruby/ext/google/protobuf_c/protobuf.h
index 5266aa8..3e5c052 100644
--- a/ruby/ext/google/protobuf_c/protobuf.h
+++ b/ruby/ext/google/protobuf_c/protobuf.h
@@ -161,6 +161,7 @@
 
 extern VALUE cError;
 extern VALUE cParseError;
+extern VALUE cTypeError;
 
 // We forward-declare all of the Ruby method implementations here because we
 // sometimes call the methods directly across .c files, rather than going
diff --git a/ruby/ext/google/protobuf_c/storage.c b/ruby/ext/google/protobuf_c/storage.c
index 5d842b7..163b2f8 100644
--- a/ruby/ext/google/protobuf_c/storage.c
+++ b/ruby/ext/google/protobuf_c/storage.c
@@ -96,7 +96,7 @@
 
 void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE val) {
   if (!is_ruby_num(val)) {
-    rb_raise(rb_eTypeError, "Expected number type for integral field.");
+    rb_raise(cTypeError, "Expected number type for integral field.");
   }
 
   // NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper
@@ -153,13 +153,13 @@
   switch (type) {
     case UPB_TYPE_FLOAT:
       if (!is_ruby_num(value)) {
-        rb_raise(rb_eTypeError, "Expected number type for float field.");
+        rb_raise(cTypeError, "Expected number type for float field.");
       }
       DEREF(memory, float) = NUM2DBL(value);
       break;
     case UPB_TYPE_DOUBLE:
       if (!is_ruby_num(value)) {
-        rb_raise(rb_eTypeError, "Expected number type for double field.");
+        rb_raise(cTypeError, "Expected number type for double field.");
       }
       DEREF(memory, double) = NUM2DBL(value);
       break;
@@ -170,7 +170,7 @@
       } else if (value == Qfalse) {
         val = 0;
       } else {
-        rb_raise(rb_eTypeError, "Invalid argument for boolean field.");
+        rb_raise(cTypeError, "Invalid argument for boolean field.");
       }
       DEREF(memory, int8_t) = val;
       break;
@@ -179,7 +179,7 @@
       if (CLASS_OF(value) == rb_cSymbol) {
         value = rb_funcall(value, rb_intern("to_s"), 0);
       } else if (CLASS_OF(value) != rb_cString) {
-        rb_raise(rb_eTypeError, "Invalid argument for string field.");
+        rb_raise(cTypeError, "Invalid argument for string field.");
       }
 
       DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
@@ -187,7 +187,7 @@
 
     case UPB_TYPE_BYTES: {
       if (CLASS_OF(value) != rb_cString) {
-        rb_raise(rb_eTypeError, "Invalid argument for string field.");
+        rb_raise(cTypeError, "Invalid argument for string field.");
       }
 
       DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
@@ -197,7 +197,7 @@
       if (CLASS_OF(value) == CLASS_OF(Qnil)) {
         value = Qnil;
       } else if (CLASS_OF(value) != type_class) {
-        rb_raise(rb_eTypeError,
+        rb_raise(cTypeError,
                  "Invalid type %s to assign to submessage field.",
                  rb_class2name(CLASS_OF(value)));
       }
@@ -209,7 +209,7 @@
       if (TYPE(value) == T_STRING) {
         value = rb_funcall(value, rb_intern("to_sym"), 0);
       } else if (!is_ruby_num(value) && TYPE(value) != T_SYMBOL) {
-        rb_raise(rb_eTypeError,
+        rb_raise(cTypeError,
                  "Expected number or symbol type for enum field.");
       }
       if (TYPE(value) == T_SYMBOL) {
@@ -598,18 +598,18 @@
 
   if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
       RTYPEDDATA_TYPE(val) != &RepeatedField_type) {
-    rb_raise(rb_eTypeError, "Expected repeated field array");
+    rb_raise(cTypeError, "Expected repeated field array");
   }
 
   self = ruby_to_RepeatedField(val);
   if (self->field_type != upb_fielddef_type(field)) {
-    rb_raise(rb_eTypeError, "Repeated field array has wrong element type");
+    rb_raise(cTypeError, "Repeated field array has wrong element type");
   }
 
-  if (self->field_type == UPB_TYPE_MESSAGE) { 
+  if (self->field_type == UPB_TYPE_MESSAGE) {
     if (self->field_type_class !=
         Descriptor_msgclass(get_def_obj(upb_fielddef_subdef(field)))) {
-      rb_raise(rb_eTypeError,
+      rb_raise(cTypeError,
                "Repeated field array has wrong message class");
     }
   }
@@ -618,7 +618,7 @@
   if (self->field_type == UPB_TYPE_ENUM) {
     if (self->field_type_class !=
         EnumDescriptor_enummodule(get_def_obj(upb_fielddef_subdef(field)))) {
-      rb_raise(rb_eTypeError,
+      rb_raise(cTypeError,
                "Repeated field array has wrong enum class");
     }
   }
@@ -631,21 +631,21 @@
 
   if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
       RTYPEDDATA_TYPE(val) != &Map_type) {
-    rb_raise(rb_eTypeError, "Expected Map instance");
+    rb_raise(cTypeError, "Expected Map instance");
   }
 
   self = ruby_to_Map(val);
   if (self->key_type != upb_fielddef_type(key_field)) {
-    rb_raise(rb_eTypeError, "Map key type does not match field's key type");
+    rb_raise(cTypeError, "Map key type does not match field's key type");
   }
   if (self->value_type != upb_fielddef_type(value_field)) {
-    rb_raise(rb_eTypeError, "Map value type does not match field's value type");
+    rb_raise(cTypeError, "Map value type does not match field's value type");
   }
   if (upb_fielddef_type(value_field) == UPB_TYPE_MESSAGE ||
       upb_fielddef_type(value_field) == UPB_TYPE_ENUM) {
     if (self->value_type_class !=
         get_def_obj(upb_fielddef_subdef(value_field))) {
-      rb_raise(rb_eTypeError,
+      rb_raise(cTypeError,
                "Map value type has wrong message/enum class");
     }
   }
diff --git a/ruby/lib/google/protobuf.rb b/ruby/lib/google/protobuf.rb
index 4a805e8..e20a584 100644
--- a/ruby/lib/google/protobuf.rb
+++ b/ruby/lib/google/protobuf.rb
@@ -37,6 +37,7 @@
   module Protobuf
     class Error < StandardError; end
     class ParseError < Error; end
+    class TypeError < ::TypeError; end
   end
 end
 
diff --git a/ruby/lib/google/protobuf/well_known_types.rb b/ruby/lib/google/protobuf/well_known_types.rb
index 921ddbc..2ee65bc 100644
--- a/ruby/lib/google/protobuf/well_known_types.rb
+++ b/ruby/lib/google/protobuf/well_known_types.rb
@@ -39,6 +39,12 @@
   module Protobuf
 
     Any.class_eval do
+      def self.pack(msg, type_url_prefix='type.googleapis.com/')
+        any = self.new
+        any.pack(msg, type_url_prefix)
+        any
+      end
+
       def pack(msg, type_url_prefix='type.googleapis.com/')
         if type_url_prefix.empty? or type_url_prefix[-1] != '/' then
           self.type_url = "#{type_url_prefix}/#{msg.class.descriptor.name}"
@@ -149,6 +155,8 @@
     Struct.class_eval do
       def [](key)
         self.fields[key].to_ruby
+      rescue NoMethodError
+        nil
       end
 
       def []=(key, value)
@@ -170,6 +178,10 @@
         hash.each { |key, val| ret[key] = val }
         ret
       end
+
+      def has_key?(key)
+        self.fields.has_key?(key)
+      end
     end
 
     ListValue.class_eval do
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
index 07558fb..c3a0d81 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
@@ -86,6 +86,8 @@
                         throw runtime.newTypeError("Expected string or symbols as hash keys in initialization map.");
                     final Descriptors.FieldDescriptor fieldDescriptor = findField(context, key);
 
+                    if (value.isNil()) return;
+
                     if (Utils.isMapEntry(fieldDescriptor)) {
                         if (!(value instanceof RubyHash))
                             throw runtime.newArgumentError("Expected Hash object as initializer value for map field '" +  key.asJavaString() + "'.");
diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb
index d151022..f174402 100644
--- a/ruby/tests/basic.rb
+++ b/ruby/tests/basic.rb
@@ -212,6 +212,15 @@
       assert_equal ['foo', 'bar'], m.repeated_string
     end
 
+    def test_ctor_nil_args
+      m = TestMessage.new(:optional_enum => nil, :optional_int32 => nil, :optional_string => nil, :optional_msg => nil)
+
+      assert_equal :Default, m.optional_enum
+      assert_equal 0, m.optional_int32
+      assert_equal "", m.optional_string
+      assert_nil m.optional_msg
+    end
+
     def test_embeddedmsg_hash_init
       m = TestEmbeddedMessageParent.new(:child_msg => {sub_child: {optional_int32: 1}},
                                         :number => 2,
@@ -283,31 +292,36 @@
 
     def test_type_errors
       m = TestMessage.new
-      assert_raise TypeError do
+      e = assert_raise Google::Protobuf::TypeError do
         m.optional_int32 = "hello"
       end
-      assert_raise TypeError do
+
+      # Google::Protobuf::TypeError should inherit from TypeError for backwards compatibility
+      # TODO: This can be removed when we can safely migrate to Google::Protobuf::TypeError
+      assert_true e.is_a?(::TypeError)
+
+      assert_raise Google::Protobuf::TypeError do
         m.optional_string = 42
       end
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m.optional_string = nil
       end
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m.optional_bool = 42
       end
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m.optional_msg = TestMessage.new  # expects TestMessage2
       end
 
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m.repeated_int32 = []  # needs RepeatedField
       end
 
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m.repeated_int32.push "hello"
       end
 
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m.repeated_msg.push TestMessage.new
       end
     end
@@ -375,7 +389,7 @@
       assert l.pop == 9
       assert l == [5, 2, 3, 4, 7, 8]
 
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m = TestMessage.new
         l.push m
       end
@@ -425,10 +439,10 @@
       l = Google::Protobuf::RepeatedField.new(:message, TestMessage)
       l.push TestMessage.new
       assert l.count == 1
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         l.push TestMessage2.new
       end
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         l.push 42
       end
 
@@ -577,7 +591,7 @@
       assert_raise RangeError do
         m[0x8000_0000] = 1
       end
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m["asdf"] = 1
       end
 
@@ -586,7 +600,7 @@
       assert_raise RangeError do
         m[0x1_0000_0000_0000_0000] = 1
       end
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m["asdf"] = 1
       end
 
@@ -611,10 +625,10 @@
       m = Google::Protobuf::Map.new(:bool, :int32)
       m[true] = 1
       m[false] = 2
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m[1] = 1
       end
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m["asdf"] = 1
       end
 
@@ -641,7 +655,7 @@
     def test_map_msg_enum_valuetypes
       m = Google::Protobuf::Map.new(:string, :message, TestMessage)
       m["asdf"] = TestMessage.new
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m["jkl;"] = TestMessage2.new
       end
 
@@ -708,17 +722,17 @@
       m.map_string_msg.delete("c")
       assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
 
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m.map_string_msg["e"] = TestMessage.new # wrong value type
       end
       # ensure nothing was added by the above
       assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
 
       m.map_string_int32 = Google::Protobuf::Map.new(:string, :int32)
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m.map_string_int32 = Google::Protobuf::Map.new(:string, :int64)
       end
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         m.map_string_int32 = {}
       end
 
@@ -1017,7 +1031,7 @@
 
     def test_def_errors
       s = Google::Protobuf::DescriptorPool.new
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         s.build do
           # enum with no default (integer value 0)
           add_enum "MyEnum" do
@@ -1025,7 +1039,7 @@
           end
         end
       end
-      assert_raise TypeError do
+      assert_raise Google::Protobuf::TypeError do
         s.build do
           # message with required field (unsupported in proto3)
           add_message "MyMessage" do
@@ -1261,6 +1275,10 @@
       Foo.encode_json(Foo.new(bar: bar, baz: [baz1, baz2]))
     end
 
+    def test_json_empty
+      assert TestMessage.encode_json(TestMessage.new) == '{}'
+    end
+
     def test_json_emit_defaults
       # TODO: Fix JSON in JRuby version.
       return if RUBY_PLATFORM == "java"
diff --git a/ruby/tests/well_known_types_test.rb b/ruby/tests/well_known_types_test.rb
index bd24c32..f35f7b1 100644
--- a/ruby/tests/well_known_types_test.rb
+++ b/ruby/tests/well_known_types_test.rb
@@ -60,6 +60,9 @@
     assert_equal(Google::Protobuf::ListValue.from_a(sublist),
                  struct["sublist"])
 
+    assert_equal true, struct.has_key?("null")
+    assert_equal false, struct.has_key?("missing_key")
+
     should_equal = {
       "number" => 12345,
       "boolean-true" => true,
@@ -82,6 +85,9 @@
     # to_h returns a fully-flattened Ruby structure (Hash and Array).
     assert_equal(should_equal, struct.to_h)
 
+    # Test that we can safely access a missing key
+    assert_equal(nil, struct["missing_key"])
+
     # Test that we can assign Struct and ListValue directly.
     struct["substruct"] = Google::Protobuf::Struct.from_hash(substruct)
     struct["sublist"] = Google::Protobuf::ListValue.from_a(sublist)
@@ -120,11 +126,17 @@
   end
 
   def test_any
-    any = Google::Protobuf::Any.new
     ts = Google::Protobuf::Timestamp.new(seconds: 12345, nanos: 6789)
+
+    any = Google::Protobuf::Any.new
     any.pack(ts)
 
     assert any.is(Google::Protobuf::Timestamp)
     assert_equal ts, any.unpack(Google::Protobuf::Timestamp)
+
+    any = Google::Protobuf::Any.pack(ts)
+
+    assert any.is(Google::Protobuf::Timestamp)
+    assert_equal ts, any.unpack(Google::Protobuf::Timestamp)
   end
 end
diff --git a/src/Makefile.am b/src/Makefile.am
index 4bb7745..9f829bf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -367,10 +367,6 @@
   google/protobuf/compiler/java/java_generator_factory.h       \
   google/protobuf/compiler/java/java_helpers.cc                \
   google/protobuf/compiler/java/java_helpers.h                 \
-  google/protobuf/compiler/java/java_lazy_message_field.cc     \
-  google/protobuf/compiler/java/java_lazy_message_field.h      \
-  google/protobuf/compiler/java/java_lazy_message_field_lite.cc\
-  google/protobuf/compiler/java/java_lazy_message_field_lite.h \
   google/protobuf/compiler/java/java_map_field.cc              \
   google/protobuf/compiler/java/java_map_field.h               \
   google/protobuf/compiler/java/java_map_field_lite.cc         \
@@ -876,7 +872,7 @@
 
 no_warning_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la
 no_warning_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_DEF) $(ZLIB_DEF) \
-                           -Wall -Wextra -Werror -Wno-unused-parameter
+                           -Wall -Wextra -Werror -Wno-unused-parameter -Og
 nodist_no_warning_test_SOURCES = no_warning_test.cc $(protoc_outputs)
 
 TESTS = protobuf-test protobuf-lazy-descriptor-test protobuf-lite-test \
diff --git a/src/README.md b/src/README.md
index 3cbeb3e..4ca9a02 100644
--- a/src/README.md
+++ b/src/README.md
@@ -1,7 +1,7 @@
 Protocol Buffers - Google's data interchange format
 ===================================================
 
-[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf) [![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/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.pb.cc b/src/google/protobuf/any.pb.cc
index 9d632ef..d0fc290 100644
--- a/src/google/protobuf/any.pb.cc
+++ b/src/google/protobuf/any.pb.cc
@@ -66,14 +66,14 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Any_default_instance_),
 };
 
-void protobuf_AssignDescriptors() {
+static void protobuf_AssignDescriptors() {
   AddDescriptors();
   AssignDescriptors(
       "google/protobuf/any.proto", schemas, file_default_instances, TableStruct::offsets,
       file_level_metadata, NULL, NULL);
 }
 
-void protobuf_AssignDescriptorsOnce() {
+static void protobuf_AssignDescriptorsOnce() {
   static ::google::protobuf::internal::once_flag once;
   ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
 }
@@ -84,7 +84,7 @@
   ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
 }
 
-void AddDescriptorsImpl() {
+static void AddDescriptorsImpl() {
   InitDefaults();
   static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
       "\n\031google/protobuf/any.proto\022\017google.prot"
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index e0a249d..273307c 100644
--- a/src/google/protobuf/api.pb.cc
+++ b/src/google/protobuf/api.pb.cc
@@ -149,14 +149,14 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Mixin_default_instance_),
 };
 
-void protobuf_AssignDescriptors() {
+static void protobuf_AssignDescriptors() {
   AddDescriptors();
   AssignDescriptors(
       "google/protobuf/api.proto", schemas, file_default_instances, TableStruct::offsets,
       file_level_metadata, NULL, NULL);
 }
 
-void protobuf_AssignDescriptorsOnce() {
+static void protobuf_AssignDescriptorsOnce() {
   static ::google::protobuf::internal::once_flag once;
   ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
 }
@@ -167,7 +167,7 @@
   ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 3);
 }
 
-void AddDescriptorsImpl() {
+static void AddDescriptorsImpl() {
   InitDefaults();
   static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
       "\n\031google/protobuf/api.proto\022\017google.prot"
@@ -414,7 +414,7 @@
       case 7: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) {
-          int value;
+          int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
@@ -947,7 +947,7 @@
       case 7: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) {
-          int value;
+          int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc
old mode 100755
new mode 100644
diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h
old mode 100755
new mode 100644
diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
index 4e150fe..24f1fe4 100644
--- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -95,7 +95,7 @@
 
     string actual_contents;
     GOOGLE_CHECK_OK(
-        File::GetContents(TestSourceDir() + "/" + physical_filename,
+        File::GetContentsAsText(TestSourceDir() + "/" + physical_filename,
                           &actual_contents, true));
     EXPECT_TRUE(actual_contents == *expected_contents)
         << physical_filename
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index 50c7b5f..828d0be 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -128,7 +128,7 @@
 void EnumFieldGenerator::
 GenerateMergeFromCodedStream(io::Printer* printer) const {
   printer->Print(variables_,
-    "int value;\n"
+    "int value = 0;\n"
     "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
     "         int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
     "       input, &value)));\n");
@@ -334,7 +334,7 @@
 GenerateMergeFromCodedStream(io::Printer* printer) const {
   // Don't use ReadRepeatedPrimitive here so that the enum can be validated.
   printer->Print(variables_,
-    "int value;\n"
+    "int value = 0;\n"
     "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
     "         int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
     "       input, &value)));\n");
@@ -399,7 +399,7 @@
       "::google::protobuf::io::CodedInputStream::Limit limit = "
           "input->PushLimit(static_cast<int>(length));\n"
       "while (input->BytesUntilLimit() > 0) {\n"
-      "  int value;\n"
+      "  int value = 0;\n"
       "  DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
       "         int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
       "       input, &value)));\n");
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 4252568..02f360b 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -791,7 +791,7 @@
   // AssignDescriptors().  All later times, waits for the first call to
   // complete and then returns.
     printer->Print(
-        "void protobuf_AssignDescriptors() {\n"
+        "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
@@ -812,7 +812,7 @@
     printer->Print(
         "}\n"
         "\n"
-        "void protobuf_AssignDescriptorsOnce() {\n"
+        "static void protobuf_AssignDescriptorsOnce() {\n"
         "  static ::google::protobuf::internal::once_flag once;\n"
         "  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);\n"
         "}\n"
@@ -850,7 +850,7 @@
 
     // Now generate the AddDescriptors() function.
     printer->Print(
-        "void AddDescriptorsImpl() {\n"
+        "static void AddDescriptorsImpl() {\n"
         "  InitDefaults();\n");
     printer->Indent();
 
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 8c2336a..778fc40 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -2280,7 +2280,7 @@
         "classname", classname_);
   } else {
     printer->Print(
-        "void $classname$::RegisterArenaDtor(::google::protobuf::Arena* arena) {\n"
+        "void $classname$::RegisterArenaDtor(::google::protobuf::Arena*) {\n"
         "}\n",
         "classname", classname_);
   }
diff --git a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc
index 8c38e52..33c5619 100644
--- a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc
@@ -90,7 +90,7 @@
 
     string actual_contents;
     GOOGLE_CHECK_OK(
-        File::GetContents(TestSourceDir() + "/" + physical_filename,
+        File::GetContentsAsText(TestSourceDir() + "/" + physical_filename,
                           &actual_contents, true))
         << "Unable to get " << physical_filename;
     EXPECT_TRUE(actual_contents == *expected_contents)
diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc
index 5bca1ff..04b6107 100644
--- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc
@@ -169,7 +169,7 @@
     }
   }
   // Add a trailing "_" if the name should be altered.
-  if (input[input.size() - 1] == '#') {
+  if (input.size() > 0 && input[input.size() - 1] == '#') {
     result += '_';
   }
   return result;
diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc
index c3831e7..58498aa 100644
--- a/src/google/protobuf/compiler/importer.cc
+++ b/src/google/protobuf/compiler/importer.cc
@@ -103,7 +103,7 @@
   bool had_errors() { return had_errors_; }
 
   // implements ErrorCollector ---------------------------------------
-  void AddError(int line, int column, const string& message) {
+  void AddError(int line, int column, const string& message) override {
     if (multi_file_error_collector_ != NULL) {
       multi_file_error_collector_->AddError(filename_, line, column, message);
     }
diff --git a/src/google/protobuf/compiler/importer.h b/src/google/protobuf/compiler/importer.h
index a4ffcf8..bf6d3de 100644
--- a/src/google/protobuf/compiler/importer.h
+++ b/src/google/protobuf/compiler/importer.h
@@ -96,12 +96,13 @@
   }
 
   // implements DescriptorDatabase -----------------------------------
-  bool FindFileByName(const string& filename, FileDescriptorProto* output);
+  bool FindFileByName(const string& filename,
+                      FileDescriptorProto* output) override;
   bool FindFileContainingSymbol(const string& symbol_name,
-                                FileDescriptorProto* output);
+                                FileDescriptorProto*output) override;
   bool FindFileContainingExtension(const string& containing_type,
                                    int field_number,
-                                   FileDescriptorProto* output);
+                                   FileDescriptorProto* output) override;
 
  private:
   class SingleFileErrorCollector;
@@ -119,13 +120,13 @@
                   const string& element_name,
                   const Message* descriptor,
                   ErrorLocation location,
-                  const string& message);
+                  const string& message) override;
 
     virtual void AddWarning(const string& filename,
                             const string& element_name,
                             const Message* descriptor,
                             ErrorLocation location,
-                            const string& message);
+                            const string& message) override;
 
    private:
     SourceTreeDescriptorDatabase* owner_;
@@ -293,9 +294,9 @@
   bool VirtualFileToDiskFile(const string& virtual_file, string* disk_file);
 
   // implements SourceTree -------------------------------------------
-  virtual io::ZeroCopyInputStream* Open(const string& filename);
+  virtual io::ZeroCopyInputStream* Open(const string& filename) override;
 
-  virtual string GetLastErrorMessage();
+  virtual string GetLastErrorMessage() override;
 
  private:
   struct Mapping {
diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc
index 0686ea0..ef64d88 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field.cc
@@ -305,11 +305,15 @@
   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_lazy_message_field.cc b/src/google/protobuf/compiler/java/java_lazy_message_field.cc
deleted file mode 100644
index abf8e55..0000000
--- a/src/google/protobuf/compiler/java/java_lazy_message_field.cc
+++ /dev/null
@@ -1,814 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: niwasaki@google.com (Naoki Iwasaki)
-//  Based on original Protocol Buffers design by
-//  Sanjay Ghemawat, Jeff Dean, and others.
-
-#include <google/protobuf/compiler/java/java_context.h>
-#include <google/protobuf/compiler/java/java_lazy_message_field.h>
-#include <google/protobuf/compiler/java/java_doc_comment.h>
-#include <google/protobuf/compiler/java/java_helpers.h>
-#include <google/protobuf/io/printer.h>
-
-namespace google {
-namespace protobuf {
-namespace compiler {
-namespace java {
-
-ImmutableLazyMessageFieldGenerator::
-ImmutableLazyMessageFieldGenerator(
-    const FieldDescriptor* descriptor,
-    int messageBitIndex,
-    int builderBitIndex,
-    Context* context)
-    : ImmutableMessageFieldGenerator(
-          descriptor, messageBitIndex, builderBitIndex, context) {
-}
-
-ImmutableLazyMessageFieldGenerator::~ImmutableLazyMessageFieldGenerator() {}
-
-void ImmutableLazyMessageFieldGenerator::
-GenerateMembers(io::Printer* printer) const {
-  printer->Print(variables_,
-    "private com.google.protobuf.LazyFieldLite $name$_ =\n"
-    "    new com.google.protobuf.LazyFieldLite();\n");
-
-  PrintExtraFieldInfo(variables_, printer);
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public boolean has$capitalized_name$() {\n"
-    "  return $get_has_field_bit_message$;\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-
-  printer->Print(variables_,
-    "$deprecation$public $type$ get$capitalized_name$() {\n"
-    "  return ($type$) $name$_.getValue($type$.getDefaultInstance());\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
-    "  return $name$_;\n"
-    "}\n");
-}
-
-void ImmutableLazyMessageFieldGenerator::
-GenerateBuilderMembers(io::Printer* printer) const {
-  // When using nested-builders, the code initially works just like the
-  // non-nested builder case. It only creates a nested builder lazily on
-  // demand and then forever delegates to it after creation.
-
-  printer->Print(variables_,
-    "private com.google.protobuf.LazyFieldLite $name$_ =\n"
-    "    new com.google.protobuf.LazyFieldLite();\n");
-
-  printer->Print(variables_,
-    // If this builder is non-null, it is used and the other fields are
-    // ignored.
-    "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
-    "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
-    "\n");
-
-  // The comments above the methods below are based on a hypothetical
-  // field of type "Field" called "Field".
-
-  // boolean hasField()
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public boolean has$capitalized_name$() {\n"
-    "  return $get_has_field_bit_builder$;\n"
-    "}\n");
-
-    printer->Print(variables_,
-      "$deprecation$public $type$ get$capitalized_name$() {\n"
-      "  return ($type$) $name$_.getValue($type$.getDefaultInstance());\n"
-      "}\n");
-
-  // Field.Builder setField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder set$capitalized_name$($type$ value)",
-
-    "if (value == null) {\n"
-    "  throw new NullPointerException();\n"
-    "}\n"
-    "$name$_.setValue(value);\n"
-    "$on_changed$\n",
-
-     NULL,  // Lazy fields are supported only for lite-runtime.
-
-    "$set_has_field_bit_builder$;\n"
-    "return this;\n");
-
-  // Field.Builder setField(Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder set$capitalized_name$(\n"
-    "    $type$.Builder builderForValue)",
-
-    "$name$_.setValue(builderForValue.build());\n"
-    "$on_changed$\n",
-
-    NULL,
-
-    "$set_has_field_bit_builder$;\n"
-    "return this;\n");
-
-  // Field.Builder mergeField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder merge$capitalized_name$($type$ value)",
-
-    "if ($get_has_field_bit_builder$ &&\n"
-    "    !$name$_.containsDefaultInstance()) {\n"
-    "  $name$_.setValue(\n"
-    "    $type$.newBuilder(\n"
-    "        get$capitalized_name$()).mergeFrom(value).buildPartial());\n"
-    "} else {\n"
-    "  $name$_.setValue(value);\n"
-    "}\n"
-    "$on_changed$\n",
-
-    NULL,
-
-    "$set_has_field_bit_builder$;\n"
-    "return this;\n");
-
-  // Field.Builder clearField()
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder clear$capitalized_name$()",
-
-    "$name$_.clear();\n"
-    "$on_changed$\n",
-
-    NULL,
-
-    "$clear_has_field_bit_builder$;\n"
-    "return this;\n");
-
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n"
-    "  $set_has_field_bit_builder$;\n"
-    "  $on_changed$\n"
-    "  return get$capitalized_name$FieldBuilder().getBuilder();\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
-    "  if ($name$Builder_ != null) {\n"
-    "    return $name$Builder_.getMessageOrBuilder();\n"
-    "  } else {\n"
-    "    return $name$_;\n"
-    "  }\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
-    "    $type$, $type$.Builder, $type$OrBuilder> \n"
-    "    get$capitalized_name$FieldBuilder() {\n"
-    "  if ($name$Builder_ == null) {\n"
-    "    $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
-    "        $type$, $type$.Builder, $type$OrBuilder>(\n"
-    "            $name$_,\n"
-    "            getParentForChildren(),\n"
-    "            isClean());\n"
-    "    $name$_ = null;\n"
-    "  }\n"
-    "  return $name$Builder_;\n"
-    "}\n");
-}
-
-
-void ImmutableLazyMessageFieldGenerator::
-GenerateInitializationCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.clear();\n");
-}
-
-void ImmutableLazyMessageFieldGenerator::
-GenerateBuilderClearCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_.clear();\n");
-  printer->Print(variables_, "$clear_has_field_bit_builder$;\n");
-}
-
-void ImmutableLazyMessageFieldGenerator::
-GenerateMergingCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "if (other.has$capitalized_name$()) {\n"
-    "  $name$_.merge(other.$name$_);\n"
-    "  $set_has_field_bit_builder$;\n"
-    "}\n");
-}
-
-void ImmutableLazyMessageFieldGenerator::
-GenerateBuildingCode(io::Printer* printer) const {
-  printer->Print(variables_,
-      "if ($get_has_field_bit_from_local$) {\n"
-      "  $set_has_field_bit_to_local$;\n"
-      "}\n");
-
-  printer->Print(variables_,
-      "result.$name$_.set(\n"
-      "    $name$_);\n");
-}
-
-void ImmutableLazyMessageFieldGenerator::
-GenerateParsingCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "$name$_.setByteString(input.readBytes(), extensionRegistry);\n");
-  printer->Print(variables_,
-    "$set_has_field_bit_message$;\n");
-}
-
-void ImmutableLazyMessageFieldGenerator::
-GenerateSerializationCode(io::Printer* printer) const {
-  // Do not de-serialize lazy fields.
-  printer->Print(variables_,
-    "if ($get_has_field_bit_message$) {\n"
-    "  output.writeBytes($number$, $name$_.toByteString());\n"
-    "}\n");
-}
-
-void ImmutableLazyMessageFieldGenerator::
-GenerateSerializedSizeCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "if ($get_has_field_bit_message$) {\n"
-    "  size += com.google.protobuf.CodedOutputStream\n"
-    "    .computeLazyFieldSize($number$, $name$_);\n"
-    "}\n");
-}
-
-// ===================================================================
-
-ImmutableLazyMessageOneofFieldGenerator::
-ImmutableLazyMessageOneofFieldGenerator(const FieldDescriptor* descriptor,
-                                        int messageBitIndex,
-                                        int builderBitIndex,
-                                        Context* context)
-    : ImmutableLazyMessageFieldGenerator(
-          descriptor, messageBitIndex, builderBitIndex, context) {
-  const OneofGeneratorInfo* info =
-      context->GetOneofGeneratorInfo(descriptor->containing_oneof());
-  SetCommonOneofVariables(descriptor, info, &variables_);
-  variables_["lazy_type"] = "com.google.protobuf.LazyFieldLite";
-}
-
-ImmutableLazyMessageOneofFieldGenerator::
-~ImmutableLazyMessageOneofFieldGenerator() {}
-
-void ImmutableLazyMessageOneofFieldGenerator::
-GenerateMembers(io::Printer* printer) const {
-  PrintExtraFieldInfo(variables_, printer);
-  WriteFieldDocComment(printer, descriptor_);
-
-  printer->Print(variables_,
-    "$deprecation$public boolean has$capitalized_name$() {\n"
-    "  return $has_oneof_case_message$;\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-
-  printer->Print(variables_,
-    "$deprecation$public $type$ get$capitalized_name$() {\n"
-    "  if ($has_oneof_case_message$) {\n"
-    "    return ($type$) (($lazy_type$) $oneof_name$_).getValue(\n"
-    "        $type$.getDefaultInstance());\n"
-    "  }\n"
-    "  return $type$.getDefaultInstance();\n"
-    "}\n");
-}
-
-void ImmutableLazyMessageOneofFieldGenerator::
-GenerateBuilderMembers(io::Printer* printer) const {
-  // boolean hasField()
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public boolean has$capitalized_name$() {\n"
-    "  return $has_oneof_case_message$;\n"
-    "}\n");
-
-  printer->Print(variables_,
-    "$deprecation$public $type$ get$capitalized_name$() {\n"
-    "  if ($has_oneof_case_message$) {\n"
-    "    return ($type$) (($lazy_type$) $oneof_name$_).getValue(\n"
-    "        $type$.getDefaultInstance());\n"
-    "  }\n"
-    "  return $type$.getDefaultInstance();\n"
-    "}\n");
-
-  // Field.Builder setField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder set$capitalized_name$($type$ value)",
-
-    "if (value == null) {\n"
-    "  throw new NullPointerException();\n"
-    "}\n"
-    "if (!($has_oneof_case_message$)) {\n"
-    "  $oneof_name$_ = new $lazy_type$();\n"
-    "  $set_oneof_case_message$;\n"
-    "}\n"
-    "(($lazy_type$) $oneof_name$_).setValue(value);\n"
-    "$on_changed$\n",
-
-     NULL,  // Lazy fields are supported only for lite-runtime.
-
-    "return this;\n");
-
-  // Field.Builder setField(Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder set$capitalized_name$(\n"
-    "    $type$.Builder builderForValue)",
-
-    "if (!($has_oneof_case_message$)) {\n"
-    "  $oneof_name$_ = new $lazy_type$();\n"
-    "  $set_oneof_case_message$;\n"
-    "}\n"
-    "(($lazy_type$) $oneof_name$_).setValue(builderForValue.build());\n"
-    "$on_changed$\n",
-
-    NULL,
-
-    "return this;\n");
-
-  // Field.Builder mergeField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder merge$capitalized_name$($type$ value)",
-
-    "if ($has_oneof_case_message$ &&\n"
-    "    !(($lazy_type$) $oneof_name$_).containsDefaultInstance()) {\n"
-    "  (($lazy_type$) $oneof_name$_).setValue(\n"
-    "    $type$.newBuilder(\n"
-    "        get$capitalized_name$()).mergeFrom(value).buildPartial());\n"
-    "} else {\n"
-    "  if (!($has_oneof_case_message$)) {\n"
-    "    $oneof_name$_ = new $lazy_type$();\n"
-    "    $set_oneof_case_message$;\n"
-    "  }\n"
-    "  (($lazy_type$) $oneof_name$_).setValue(value);\n"
-    "}\n"
-    "$on_changed$\n",
-
-    NULL,
-
-    "return this;\n");
-
-  // Field.Builder clearField()
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder clear$capitalized_name$()",
-
-    "if ($has_oneof_case_message$) {\n"
-    "  $clear_oneof_case_message$;\n"
-    "  $oneof_name$_ = null;\n"
-    "  $on_changed$\n"
-    "}\n",
-
-    NULL,
-
-    "return this;\n");
-}
-
-void ImmutableLazyMessageOneofFieldGenerator::
-GenerateMergingCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "if (!($has_oneof_case_message$)) {\n"
-    "  $oneof_name$_ = new $lazy_type$();\n"
-    "}\n"
-    "(($lazy_type$) $oneof_name$_).merge(\n"
-    "    ($lazy_type$) other.$oneof_name$_);\n"
-    "$set_oneof_case_message$;\n");
-}
-
-void ImmutableLazyMessageOneofFieldGenerator::
-GenerateBuildingCode(io::Printer* printer) const {
-  printer->Print(variables_,
-                 "if ($has_oneof_case_message$) {\n");
-  printer->Indent();
-
-  printer->Print(variables_,
-      "result.$oneof_name$_ = new $lazy_type$();\n"
-      "(($lazy_type$) result.$oneof_name$_).set(\n"
-      "    (($lazy_type$) $oneof_name$_));\n");
-  printer->Outdent();
-  printer->Print("}\n");
-}
-
-void ImmutableLazyMessageOneofFieldGenerator::
-GenerateParsingCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "if (!($has_oneof_case_message$)) {\n"
-    "  $oneof_name$_ = new $lazy_type$();\n"
-    "}\n"
-    "(($lazy_type$) $oneof_name$_).setByteString(\n"
-    "    input.readBytes(), extensionRegistry);\n"
-    "$set_oneof_case_message$;\n");
-}
-
-void ImmutableLazyMessageOneofFieldGenerator::
-GenerateSerializationCode(io::Printer* printer) const {
-  // Do not de-serialize lazy fields.
-  printer->Print(variables_,
-    "if ($has_oneof_case_message$) {\n"
-    "  output.writeBytes(\n"
-    "      $number$, (($lazy_type$) $oneof_name$_).toByteString());\n"
-    "}\n");
-}
-
-void ImmutableLazyMessageOneofFieldGenerator::
-GenerateSerializedSizeCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "if ($has_oneof_case_message$) {\n"
-    "  size += com.google.protobuf.CodedOutputStream\n"
-    "    .computeLazyFieldSize($number$, ($lazy_type$) $oneof_name$_);\n"
-    "}\n");
-}
-
-// ===================================================================
-
-RepeatedImmutableLazyMessageFieldGenerator::
-RepeatedImmutableLazyMessageFieldGenerator(
-    const FieldDescriptor* descriptor,
-    int messageBitIndex,
-    int builderBitIndex,
-    Context* context)
-    : RepeatedImmutableMessageFieldGenerator(
-          descriptor, messageBitIndex, builderBitIndex, context) {
-}
-
-
-RepeatedImmutableLazyMessageFieldGenerator::
-~RepeatedImmutableLazyMessageFieldGenerator() {}
-
-void RepeatedImmutableLazyMessageFieldGenerator::
-GenerateMembers(io::Printer* printer) const {
-  printer->Print(variables_,
-    "private java.util.List<com.google.protobuf.LazyFieldLite> $name$_;\n");
-  PrintExtraFieldInfo(variables_, printer);
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public java.util.List<$type$>\n"
-    "    get$capitalized_name$List() {\n"
-    "  java.util.List<$type$> list =\n"
-    "      new java.util.ArrayList<$type$>($name$_.size());\n"
-    "  for (com.google.protobuf.LazyFieldLite lf : $name$_) {\n"
-    "    list.add(($type$) lf.getValue($type$.getDefaultInstance()));\n"
-    "  }\n"
-    "  return list;\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public java.util.List<? extends $type$OrBuilder>\n"
-    "    get$capitalized_name$OrBuilderList() {\n"
-    "  return get$capitalized_name$List();\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public int get$capitalized_name$Count() {\n"
-    "  return $name$_.size();\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
-    "  return ($type$)\n"
-    "      $name$_.get(index).getValue($type$.getDefaultInstance());\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
-    "    int index) {\n"
-    "  return ($type$OrBuilder)\n"
-    "      $name$_.get(index).getValue($type$.getDefaultInstance());\n"
-    "}\n");
-}
-
-void RepeatedImmutableLazyMessageFieldGenerator::
-GenerateBuilderMembers(io::Printer* printer) const {
-  // When using nested-builders, the code initially works just like the
-  // non-nested builder case. It only creates a nested builder lazily on
-  // demand and then forever delegates to it after creation.
-
-  printer->Print(variables_,
-    "private java.util.List<com.google.protobuf.LazyFieldLite> $name$_ =\n"
-    "  java.util.Collections.emptyList();\n"
-
-    "private void ensure$capitalized_name$IsMutable() {\n"
-    "  if (!$get_mutable_bit_builder$) {\n"
-    "    $name$_ =\n"
-    "        new java.util.ArrayList<com.google.protobuf.LazyFieldLite>(\n"
-    "            $name$_);\n"
-    "    $set_mutable_bit_builder$;\n"
-    "   }\n"
-    "}\n"
-    "\n");
-
-  printer->Print(variables_,
-    // If this builder is non-null, it is used and the other fields are
-    // ignored.
-    "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
-    "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
-    "\n");
-
-  // The comments above the methods below are based on a hypothetical
-  // repeated field of type "Field" called "RepeatedField".
-
-  // List<Field> getRepeatedFieldList()
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public java.util.List<$type$> get$capitalized_name$List()",
-
-    "java.util.List<$type$> list =\n"
-    "    new java.util.ArrayList<$type$>($name$_.size());\n"
-    "for (com.google.protobuf.LazyFieldLite lf : $name$_) {\n"
-    "  list.add(($type$) lf.getValue($type$.getDefaultInstance()));\n"
-    "}\n"
-    "return java.util.Collections.unmodifiableList(list);\n",
-
-    "return $name$Builder_.getMessageList();\n",
-
-    NULL);
-
-  // int getRepeatedFieldCount()
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public int get$capitalized_name$Count()",
-
-    "return $name$_.size();\n",
-    "return $name$Builder_.getCount();\n",
-
-    NULL);
-
-  // Field getRepeatedField(int index)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public $type$ get$capitalized_name$(int index)",
-
-    "return ($type$) $name$_.get(index).getValue(\n"
-    "    $type$.getDefaultInstance());\n",
-
-    "return $name$Builder_.getMessage(index);\n",
-
-    NULL);
-
-  // Builder setRepeatedField(int index, Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder set$capitalized_name$(\n"
-    "    int index, $type$ value)",
-    "if (value == null) {\n"
-    "  throw new NullPointerException();\n"
-    "}\n"
-    "ensure$capitalized_name$IsMutable();\n"
-    "$name$_.set(index, com.google.protobuf.LazyFieldLite.fromValue(value));\n"
-    "$on_changed$\n",
-    "$name$Builder_.setMessage(index, value);\n",
-    "return this;\n");
-
-  // Builder setRepeatedField(int index, Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder set$capitalized_name$(\n"
-    "    int index, $type$.Builder builderForValue)",
-
-    "ensure$capitalized_name$IsMutable();\n"
-    "$name$_.set(index, com.google.protobuf.LazyFieldLite.fromValue(\n"
-    "    builderForValue.build()));\n"
-    "$on_changed$\n",
-
-    "$name$Builder_.setMessage(index, builderForValue.build());\n",
-
-    "return this;\n");
-
-  // Builder addRepeatedField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder add$capitalized_name$($type$ value)",
-
-    "if (value == null) {\n"
-    "  throw new NullPointerException();\n"
-    "}\n"
-    "ensure$capitalized_name$IsMutable();\n"
-    "$name$_.add(com.google.protobuf.LazyFieldLite.fromValue(value));\n"
-
-    "$on_changed$\n",
-
-    "$name$Builder_.addMessage(value);\n",
-
-    "return this;\n");
-
-  // Builder addRepeatedField(int index, Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder add$capitalized_name$(\n"
-    "    int index, $type$ value)",
-
-    "if (value == null) {\n"
-    "  throw new NullPointerException();\n"
-    "}\n"
-    "ensure$capitalized_name$IsMutable();\n"
-    "$name$_.add(index, com.google.protobuf.LazyFieldLite.fromValue(value));\n"
-    "$on_changed$\n",
-
-    "$name$Builder_.addMessage(index, value);\n",
-
-    "return this;\n");
-
-  // Builder addRepeatedField(Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder add$capitalized_name$(\n"
-    "    $type$.Builder builderForValue)",
-
-    "ensure$capitalized_name$IsMutable();\n"
-    "$name$_.add(com.google.protobuf.LazyFieldLite.fromValue(\n"
-    "    builderForValue.build()));\n"
-    "$on_changed$\n",
-
-    "$name$Builder_.addMessage(builderForValue.build());\n",
-
-    "return this;\n");
-
-  // Builder addRepeatedField(int index, Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder add$capitalized_name$(\n"
-    "    int index, $type$.Builder builderForValue)",
-
-    "ensure$capitalized_name$IsMutable();\n"
-    "$name$_.add(index, com.google.protobuf.LazyFieldLite.fromValue(\n"
-    "    builderForValue.build()));\n"
-    "$on_changed$\n",
-
-    "$name$Builder_.addMessage(index, builderForValue.build());\n",
-
-    "return this;\n");
-
-  // Builder addAllRepeatedField(Iterable<Field> values)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder addAll$capitalized_name$(\n"
-    "    java.lang.Iterable<? extends $type$> values)",
-
-    "ensure$capitalized_name$IsMutable();\n"
-    "for (com.google.protobuf.MessageLite v : values) {\n"
-    "  $name$_.add(com.google.protobuf.LazyFieldLite.fromValue(v));\n"
-    "}\n"
-    "$on_changed$\n",
-
-    "$name$Builder_.addAllMessages(values);\n",
-
-    "return this;\n");
-
-  // Builder clearAllRepeatedField()
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder clear$capitalized_name$()",
-
-    "$name$_ = java.util.Collections.emptyList();\n"
-    "$clear_mutable_bit_builder$;\n"
-    "$on_changed$\n",
-
-    "$name$Builder_.clear();\n",
-
-    "return this;\n");
-
-  // Builder removeRepeatedField(int index)
-  WriteFieldDocComment(printer, descriptor_);
-  PrintNestedBuilderFunction(printer,
-    "$deprecation$public Builder remove$capitalized_name$(int index)",
-
-    "ensure$capitalized_name$IsMutable();\n"
-    "$name$_.remove(index);\n"
-    "$on_changed$\n",
-
-    "$name$Builder_.remove(index);\n",
-
-    "return this;\n");
-
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public $type$.Builder get$capitalized_name$Builder(\n"
-    "    int index) {\n"
-    "  return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
-    "}\n");
-
-  WriteFieldDocComment(printer, descriptor_);
-      printer->Print(variables_,
-    "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
-    "    int index) {\n"
-    "  if ($name$Builder_ == null) {\n"
-    "    return $name$_.get(index);"
-    "  } else {\n"
-    "    return $name$Builder_.getMessageOrBuilder(index);\n"
-    "  }\n"
-    "}\n");
-
-  WriteFieldDocComment(printer, descriptor_);
-      printer->Print(variables_,
-    "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
-    "     get$capitalized_name$OrBuilderList() {\n"
-    "  if ($name$Builder_ != null) {\n"
-    "    return $name$Builder_.getMessageOrBuilderList();\n"
-    "  } else {\n"
-    "    return java.util.Collections.unmodifiableList($name$_);\n"
-    "  }\n"
-    "}\n");
-
-  WriteFieldDocComment(printer, descriptor_);
-      printer->Print(variables_,
-    "$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n"
-    "  return get$capitalized_name$FieldBuilder().addBuilder(\n"
-    "      $type$.getDefaultInstance());\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-      printer->Print(variables_,
-    "$deprecation$public $type$.Builder add$capitalized_name$Builder(\n"
-    "    int index) {\n"
-    "  return get$capitalized_name$FieldBuilder().addBuilder(\n"
-    "      index, $type$.getDefaultInstance());\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-      printer->Print(variables_,
-    "$deprecation$public java.util.List<$type$.Builder> \n"
-    "     get$capitalized_name$BuilderList() {\n"
-    "  return get$capitalized_name$FieldBuilder().getBuilderList();\n"
-    "}\n"
-    "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
-    "    $type$, $type$.Builder, $type$OrBuilder> \n"
-    "    get$capitalized_name$FieldBuilder() {\n"
-    "  if ($name$Builder_ == null) {\n"
-    "    $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
-    "        $type$, $type$.Builder, $type$OrBuilder>(\n"
-    "            $name$_,\n"
-    "            $get_mutable_bit_builder$,\n"
-    "            getParentForChildren(),\n"
-    "            isClean());\n"
-    "    $name$_ = null;\n"
-    "  }\n"
-    "  return $name$Builder_;\n"
-    "}\n");
-}
-
-void RepeatedImmutableLazyMessageFieldGenerator::
-GenerateParsingCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "if (!$get_mutable_bit_parser$) {\n"
-    "  $name$_ =\n"
-    "      new java.util.ArrayList<com.google.protobuf.LazyFieldLite>();\n"
-    "  $set_mutable_bit_parser$;\n"
-    "}\n"
-    "$name$_.add(new com.google.protobuf.LazyFieldLite(\n"
-    "    extensionRegistry, input.readBytes()));\n");
-}
-
-void RepeatedImmutableLazyMessageFieldGenerator::
-GenerateSerializationCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "for (int i = 0; i < $name$_.size(); i++) {\n"
-    "  output.writeBytes($number$, $name$_.get(i).toByteString());\n"
-    "}\n");
-}
-
-void RepeatedImmutableLazyMessageFieldGenerator::
-GenerateSerializedSizeCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "for (int i = 0; i < $name$_.size(); i++) {\n"
-    "  size += com.google.protobuf.CodedOutputStream\n"
-    "    .computeLazyFieldSize($number$, $name$_.get(i));\n"
-    "}\n");
-}
-
-}  // namespace java
-}  // namespace compiler
-}  // namespace protobuf
-}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field.h b/src/google/protobuf/compiler/java/java_lazy_message_field.h
deleted file mode 100644
index b1b7f28..0000000
--- a/src/google/protobuf/compiler/java/java_lazy_message_field.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: niwasaki@google.com (Naoki Iwasaki)
-//  Based on original Protocol Buffers design by
-//  Sanjay Ghemawat, Jeff Dean, and others.
-
-#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_H__
-#define GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_H__
-
-#include <google/protobuf/compiler/java/java_field.h>
-#include <google/protobuf/compiler/java/java_message_field.h>
-
-namespace google {
-namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;  // context.h
-    }
-  }
-}
-
-namespace protobuf {
-namespace compiler {
-namespace java {
-
-class ImmutableLazyMessageFieldGenerator
-    : public ImmutableMessageFieldGenerator {
- public:
-  explicit ImmutableLazyMessageFieldGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
-  ~ImmutableLazyMessageFieldGenerator();
-
-  // overroads ImmutableMessageFieldGenerator ---------------------------------
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
-  void GenerateInitializationCode(io::Printer* printer) const;
-  void GenerateBuilderClearCode(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateBuildingCode(io::Printer* printer) const;
-  void GenerateParsingCode(io::Printer* printer) const;
-  void GenerateSerializationCode(io::Printer* printer) const;
-  void GenerateSerializedSizeCode(io::Printer* printer) const;
-
- private:
-  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageFieldGenerator);
-};
-
-class ImmutableLazyMessageOneofFieldGenerator
-    : public ImmutableLazyMessageFieldGenerator {
- public:
-  ImmutableLazyMessageOneofFieldGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
-  ~ImmutableLazyMessageOneofFieldGenerator();
-
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
-  void GenerateMergingCode(io::Printer* printer) const;
-  void GenerateBuildingCode(io::Printer* printer) const;
-  void GenerateParsingCode(io::Printer* printer) const;
-  void GenerateSerializationCode(io::Printer* printer) const;
-  void GenerateSerializedSizeCode(io::Printer* printer) const;
-
- private:
-  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageOneofFieldGenerator);
-};
-
-class RepeatedImmutableLazyMessageFieldGenerator
-    : public RepeatedImmutableMessageFieldGenerator {
- public:
-  explicit RepeatedImmutableLazyMessageFieldGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
-  ~RepeatedImmutableLazyMessageFieldGenerator();
-
-  // overroads RepeatedImmutableMessageFieldGenerator -------------------------
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
-  void GenerateParsingCode(io::Printer* printer) const;
-  void GenerateSerializationCode(io::Printer* printer) const;
-  void GenerateSerializedSizeCode(io::Printer* printer) const;
-
- private:
-  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableLazyMessageFieldGenerator);
-};
-
-}  // namespace java
-}  // namespace compiler
-}  // namespace protobuf
-
-}  // namespace google
-#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_H__
diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc
deleted file mode 100644
index 51bb11f..0000000
--- a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc
+++ /dev/null
@@ -1,725 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: niwasaki@google.com (Naoki Iwasaki)
-//  Based on original Protocol Buffers design by
-//  Sanjay Ghemawat, Jeff Dean, and others.
-
-#include <google/protobuf/compiler/java/java_context.h>
-#include <google/protobuf/compiler/java/java_lazy_message_field_lite.h>
-#include <google/protobuf/compiler/java/java_doc_comment.h>
-#include <google/protobuf/compiler/java/java_helpers.h>
-#include <google/protobuf/io/printer.h>
-
-namespace google {
-namespace protobuf {
-namespace compiler {
-namespace java {
-
-ImmutableLazyMessageFieldLiteGenerator::
-ImmutableLazyMessageFieldLiteGenerator(
-    const FieldDescriptor* descriptor,
-    int messageBitIndex,
-    int builderBitIndex,
-    Context* context)
-    : ImmutableMessageFieldLiteGenerator(
-          descriptor, messageBitIndex, builderBitIndex, context) {
-}
-
-ImmutableLazyMessageFieldLiteGenerator::
-~ImmutableLazyMessageFieldLiteGenerator() {}
-
-void ImmutableLazyMessageFieldLiteGenerator::
-GenerateMembers(io::Printer* printer) const {
-  printer->Print(variables_,
-    "private com.google.protobuf.LazyFieldLite $name$_;");
-
-  PrintExtraFieldInfo(variables_, printer);
-  WriteFieldDocComment(printer, descriptor_);
-  if (SupportFieldPresence(descriptor_->file())) {
-    printer->Print(variables_,
-      "$deprecation$public boolean has$capitalized_name$() {\n"
-      "  return $get_has_field_bit_message$;\n"
-      "}\n");
-  } else {
-    printer->Print(variables_,
-      "$deprecation$public boolean has$capitalized_name$() {\n"
-      "  return $name$_ != null;\n"
-      "}\n");
-  }
-
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public $type$ get$capitalized_name$() {\n"
-    "  if ($name$_ == null) {\n"
-    "    return $type$.getDefaultInstance();\n"
-    "  }\n"
-    "  return ($type$) $name$_.getValue($type$.getDefaultInstance());\n"
-   "}\n");
-
-  // Field.Builder setField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void set$capitalized_name$($type$ value) {\n"
-    "  if (value == null) {\n"
-    "    throw new NullPointerException();\n"
-    "  }\n"
-    "  if ($name$_ == null) {\n"
-    "    $name$_ = new com.google.protobuf.LazyFieldLite();\n"
-    "  }\n"
-    "  $name$_.setValue(value);\n"
-    "  $set_has_field_bit_message$\n"
-    "}\n");
-
-  // Field.Builder setField(Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void set$capitalized_name$(\n"
-    "    $type$.Builder builderForValue) {\n"
-    "  if ($name$_ == null) {\n"
-    "    $name$_ = new com.google.protobuf.LazyFieldLite();\n"
-    "  }\n"
-    "  $name$_.setValue(builderForValue.build());\n"
-    "  $set_has_field_bit_message$\n"
-    "}\n");
-
-  // Field.Builder mergeField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void merge$capitalized_name$($type$ value) {\n"
-    "  if (has$capitalized_name$() &&\n"
-    "      !$name$_.containsDefaultInstance()) {\n"
-    "    $name$_.setValue(\n"
-    "      $type$.newBuilder(\n"
-    "          get$capitalized_name$()).mergeFrom(value).buildPartial());\n"
-    "  } else {\n"
-    "    if ($name$_ == null) {\n"
-    "      $name$_ = new com.google.protobuf.LazyFieldLite();\n"
-    "    }\n"
-    "    $name$_.setValue(value);\n"
-    "    $set_has_field_bit_message$\n"
-    "  }\n"
-    "}\n");
-
-  // Field.Builder clearField()
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void clear$capitalized_name$() {\n"
-    "  $name$_ = null;\n"
-    "  $clear_has_field_bit_message$;\n"
-    "}\n");
-}
-
-void ImmutableLazyMessageFieldLiteGenerator::
-GenerateBuilderMembers(io::Printer* printer) const {
-  // The comments above the methods below are based on a hypothetical
-  // field of type "Field" called "Field".
-
-  // boolean hasField()
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public boolean has$capitalized_name$() {\n"
-    "  return instance.has$capitalized_name$();\n"
-    "}\n");
-
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public $type$ get$capitalized_name$() {\n"
-    "  return instance.get$capitalized_name$();\n"
-    "}\n");
-
-  // Field.Builder setField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
-    "  copyOnWrite();\n"
-    "  instance.set$capitalized_name$(value);\n"
-    "  return this;\n"
-    "}\n");
-
-  // Field.Builder setField(Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder set$capitalized_name$(\n"
-    "    $type$.Builder builderForValue) {\n"
-    "  copyOnWrite();\n"
-    "  instance.set$capitalized_name$(builderForValue);\n"
-    "  return this;\n"
-    "}\n");
-
-  // Field.Builder mergeField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder merge$capitalized_name$($type$ value) {\n"
-    "  copyOnWrite();\n"
-    "  instance.merge$capitalized_name$(value);\n"
-    "  return this;\n"
-    "}\n");
-
-  // Field.Builder clearField()
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder clear$capitalized_name$() {\n"
-    "  copyOnWrite();\n"
-    "  instance.clear$capitalized_name$();\n"
-    "  return this;\n"
-    "}\n");
-}
-
-
-void ImmutableLazyMessageFieldLiteGenerator::
-GenerateInitializationCode(io::Printer* printer) const {}
-
-void ImmutableLazyMessageFieldLiteGenerator::
-GenerateVisitCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "$name$_ = visitor.visitLazyMessage($name$_, other.$name$_);\n");
-}
-
-void ImmutableLazyMessageFieldLiteGenerator::
-GenerateParsingCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "if ($name$_ == null) {\n"
-    "  $name$_ = new com.google.protobuf.LazyFieldLite();\n"
-    "}\n"
-    "$name$_.mergeFrom(input, extensionRegistry);\n");
-  printer->Print(variables_,
-    "$set_has_field_bit_message$\n");
-}
-
-void ImmutableLazyMessageFieldLiteGenerator::
-GenerateSerializationCode(io::Printer* printer) const {
-  // Do not de-serialize lazy fields.
-  printer->Print(variables_,
-    "if (has$capitalized_name$()) {\n"
-    "  output.writeBytes($number$, $name$_.toByteString());\n"
-    "}\n");
-}
-
-void ImmutableLazyMessageFieldLiteGenerator::
-GenerateSerializedSizeCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "if (has$capitalized_name$()) {\n"
-    "  size += com.google.protobuf.CodedOutputStream\n"
-    "    .computeLazyFieldSize($number$, $name$_);\n"
-    "}\n");
-}
-
-
-// ===================================================================
-
-ImmutableLazyMessageOneofFieldLiteGenerator::
-ImmutableLazyMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
-                                            int messageBitIndex,
-                                            int builderBitIndex,
-                                            Context* context)
-    : ImmutableLazyMessageFieldLiteGenerator(
-          descriptor, messageBitIndex, builderBitIndex, context) {
-  const OneofGeneratorInfo* info =
-      context->GetOneofGeneratorInfo(descriptor->containing_oneof());
-  SetCommonOneofVariables(descriptor, info, &variables_);
-  variables_["lazy_type"] = "com.google.protobuf.LazyFieldLite";
-}
-
-ImmutableLazyMessageOneofFieldLiteGenerator::
-~ImmutableLazyMessageOneofFieldLiteGenerator() {}
-
-void ImmutableLazyMessageOneofFieldLiteGenerator::
-GenerateMembers(io::Printer* printer) const {
-  PrintExtraFieldInfo(variables_, printer);
-  WriteFieldDocComment(printer, descriptor_);
-
-  printer->Print(variables_,
-    "$deprecation$public boolean has$capitalized_name$() {\n"
-    "  return $has_oneof_case_message$;\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-
-  printer->Print(variables_,
-    "$deprecation$public $type$ get$capitalized_name$() {\n"
-    "  if ($has_oneof_case_message$) {\n"
-    "    return ($type$) (($lazy_type$) $oneof_name$_).getValue(\n"
-    "        $type$.getDefaultInstance());\n"
-    "  }\n"
-    "  return $type$.getDefaultInstance();\n"
-    "}\n");
-
-  // Field.Builder setField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void set$capitalized_name$($type$ value) {\n"
-    "  if (value == null) {\n"
-    "    throw new NullPointerException();\n"
-    "  }\n"
-    "  if (!($has_oneof_case_message$)) {\n"
-    "    $oneof_name$_ = new $lazy_type$();\n"
-    "    $set_oneof_case_message$;\n"
-    "  }\n"
-    "  (($lazy_type$) $oneof_name$_).setValue(value);\n"
-    "}\n");
-
-  // Field.Builder setField(Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void set$capitalized_name$(\n"
-    "    $type$.Builder builderForValue) {\n"
-    "  if (!($has_oneof_case_message$)) {\n"
-    "    $oneof_name$_ = new $lazy_type$();\n"
-    "    $set_oneof_case_message$;\n"
-    "  }\n"
-    "  (($lazy_type$) $oneof_name$_).setValue(builderForValue.build());\n"
-    "}\n");
-
-  // Field.Builder mergeField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void merge$capitalized_name$($type$ value) {\n"
-    "  if ($has_oneof_case_message$ &&\n"
-    "      !(($lazy_type$) $oneof_name$_).containsDefaultInstance()) {\n"
-    "    (($lazy_type$) $oneof_name$_).setValue(\n"
-    "       $type$.newBuilder(\n"
-    "          get$capitalized_name$()).mergeFrom(value).buildPartial());\n"
-    "  } else {\n"
-    "    if (!($has_oneof_case_message$)) {\n"
-    "      $oneof_name$_ = new $lazy_type$();\n"
-    "      $set_oneof_case_message$;\n"
-    "    }\n"
-    "    (($lazy_type$) $oneof_name$_).setValue(value);\n"
-    "  }\n"
-    "}\n");
-
-  // Field.Builder clearField()
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void clear$capitalized_name$() {\n"
-    "  if ($has_oneof_case_message$) {\n"
-    "    $clear_oneof_case_message$;\n"
-    "    $oneof_name$_ = null;\n"
-    "  }\n"
-    "}\n");
-}
-
-void ImmutableLazyMessageOneofFieldLiteGenerator::
-GenerateBuilderMembers(io::Printer* printer) const {
-  // boolean hasField()
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public boolean has$capitalized_name$() {\n"
-    "  return instance.has$capitalized_name$();\n"
-    "}\n");
-
-  printer->Print(variables_,
-    "$deprecation$public $type$ get$capitalized_name$() {\n"
-    "  return instance.get$capitalized_name$();\n"
-    "}\n");
-
-  // Field.Builder setField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
-    "  copyOnWrite();\n"
-    "  instance.set$capitalized_name$(value);\n"
-    "  return this;\n"
-    "}\n");
-
-  // Field.Builder setField(Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder set$capitalized_name$(\n"
-    "    $type$.Builder builderForValue) {\n"
-    "  copyOnWrite();\n"
-    "  instance.set$capitalized_name$(builderForValue);\n"
-    "  return this;\n"
-    "}\n");
-
-  // Field.Builder mergeField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder merge$capitalized_name$($type$ value) {\n"
-    "  copyOnWrite();\n"
-    "  instance.merge$capitalized_name$(value);\n"
-    "  return this;\n"
-    "}\n");
-
-  // Field.Builder clearField()
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder clear$capitalized_name$() {\n"
-    "  copyOnWrite();\n"
-    "  instance.clear$capitalized_name$();\n"
-    "  return this;\n"
-    "}\n");
-}
-
-void ImmutableLazyMessageOneofFieldLiteGenerator::
-GenerateVisitCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "$oneof_name$_ = visitor.visitOneofLazyMessage(\n"
-    "    $has_oneof_case_message$,\n"
-    "    ($lazy_type$) $oneof_name$_,\n"
-    "    ($lazy_type$) other.$oneof_name$_);\n");
-}
-
-void ImmutableLazyMessageOneofFieldLiteGenerator::
-GenerateParsingCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "if (!($has_oneof_case_message$)) {\n"
-    "  $oneof_name$_ = new $lazy_type$();\n"
-    "}\n"
-    "(($lazy_type$) $oneof_name$_).mergeFrom(input, extensionRegistry);\n"
-    "$set_oneof_case_message$;\n");
-}
-
-void ImmutableLazyMessageOneofFieldLiteGenerator::
-GenerateSerializationCode(io::Printer* printer) const {
-  // Do not de-serialize lazy fields.
-  printer->Print(variables_,
-    "if ($has_oneof_case_message$) {\n"
-    "  output.writeBytes(\n"
-    "      $number$, (($lazy_type$) $oneof_name$_).toByteString());\n"
-    "}\n");
-}
-
-void ImmutableLazyMessageOneofFieldLiteGenerator::
-GenerateSerializedSizeCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "if ($has_oneof_case_message$) {\n"
-    "  size += com.google.protobuf.CodedOutputStream\n"
-    "    .computeLazyFieldSize($number$, ($lazy_type$) $oneof_name$_);\n"
-    "}\n");
-}
-
-
-// ===================================================================
-
-RepeatedImmutableLazyMessageFieldLiteGenerator::
-RepeatedImmutableLazyMessageFieldLiteGenerator(
-    const FieldDescriptor* descriptor,
-    int messageBitIndex,
-    int builderBitIndex,
-    Context* context)
-    : RepeatedImmutableMessageFieldLiteGenerator(
-          descriptor, messageBitIndex, builderBitIndex, context) {
-}
-
-
-RepeatedImmutableLazyMessageFieldLiteGenerator::
-~RepeatedImmutableLazyMessageFieldLiteGenerator() {}
-
-void RepeatedImmutableLazyMessageFieldLiteGenerator::
-GenerateMembers(io::Printer* printer) const {
-  printer->Print(variables_,
-    "private com.google.protobuf.Internal.ProtobufList<\n"
-    "    com.google.protobuf.LazyFieldLite> $name$_;\n");
-  PrintExtraFieldInfo(variables_, printer);
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public java.util.List<$type$>\n"
-    "    get$capitalized_name$List() {\n"
-    "  java.util.List<$type$> list =\n"
-    "      new java.util.ArrayList<$type$>($name$_.size());\n"
-    "  for (com.google.protobuf.LazyFieldLite lf : $name$_) {\n"
-    "    list.add(($type$) lf.getValue($type$.getDefaultInstance()));\n"
-    "  }\n"
-    "  return java.util.Collections.unmodifiableList(list);\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public java.util.List<? extends $type$OrBuilder>\n"
-    "    get$capitalized_name$OrBuilderList() {\n"
-    "  return get$capitalized_name$List();\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public int get$capitalized_name$Count() {\n"
-    "  return $name$_.size();\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
-    "  return ($type$)\n"
-    "      $name$_.get(index).getValue($type$.getDefaultInstance());\n"
-    "}\n");
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
-    "    int index) {\n"
-    "  return ($type$OrBuilder)\n"
-    "      $name$_.get(index).getValue($type$.getDefaultInstance());\n"
-    "}\n");
-
-  printer->Print(variables_,
-    "private void ensure$capitalized_name$IsMutable() {\n"
-    "  if (!$is_mutable$) {\n"
-    "    $name$_ =\n"
-    "        com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
-    "   }\n"
-    "}\n"
-    "\n");
-
-  // Builder setRepeatedField(int index, Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void set$capitalized_name$(\n"
-    "    int index, $type$ value) {\n"
-    "  if (value == null) {\n"
-    "    throw new NullPointerException();\n"
-    "  }\n"
-    "  ensure$capitalized_name$IsMutable();\n"
-    "  $name$_.set(\n"
-    "      index, com.google.protobuf.LazyFieldLite.fromValue(value));\n"
-    "}\n");
-
-  // Builder setRepeatedField(int index, Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void set$capitalized_name$(\n"
-    "    int index, $type$.Builder builderForValue) {\n"
-    "  ensure$capitalized_name$IsMutable();\n"
-    "  $name$_.set(index, com.google.protobuf.LazyFieldLite.fromValue(\n"
-    "      builderForValue.build()));\n"
-    "}\n");
-
-  // Builder addRepeatedField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void add$capitalized_name$($type$ value) {\n"
-    "  if (value == null) {\n"
-    "    throw new NullPointerException();\n"
-    "  }\n"
-    "  ensure$capitalized_name$IsMutable();\n"
-    "  $name$_.add(com.google.protobuf.LazyFieldLite.fromValue(value));\n"
-    "}\n");
-
-  // Builder addRepeatedField(int index, Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void add$capitalized_name$(\n"
-    "    int index, $type$ value) {\n"
-    "  if (value == null) {\n"
-    "    throw new NullPointerException();\n"
-    "  }\n"
-    "  ensure$capitalized_name$IsMutable();\n"
-    "  $name$_.add(\n"
-    "      index, com.google.protobuf.LazyFieldLite.fromValue(value));\n"
-    "}\n");
-
-  // Builder addRepeatedField(Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void add$capitalized_name$(\n"
-    "    $type$.Builder builderForValue) {\n"
-    "  ensure$capitalized_name$IsMutable();\n"
-    "  $name$_.add(com.google.protobuf.LazyFieldLite.fromValue(\n"
-    "      builderForValue.build()));\n"
-    "}\n");
-
-  // Builder addRepeatedField(int index, Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void add$capitalized_name$(\n"
-    "    int index, $type$.Builder builderForValue) {\n"
-    "  ensure$capitalized_name$IsMutable();\n"
-    "  $name$_.add(index, com.google.protobuf.LazyFieldLite.fromValue(\n"
-    "      builderForValue.build()));\n"
-    "}\n");
-
-  // Builder addAllRepeatedField(Iterable<Field> values)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void addAll$capitalized_name$(\n"
-    "    java.lang.Iterable<? extends $type$> values) {\n"
-    "  ensure$capitalized_name$IsMutable();\n"
-    "  for (com.google.protobuf.MessageLite v : values) {\n"
-    "    $name$_.add(com.google.protobuf.LazyFieldLite.fromValue(v));\n"
-    "  }\n"
-    "}\n");
-
-  // Builder clearAllRepeatedField()
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void clear$capitalized_name$() {\n"
-    "  $name$_ = emptyProtobufList();\n"
-    "}\n");
-
-  // Builder removeRepeatedField(int index)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "private void remove$capitalized_name$(int index) {\n"
-    "  ensure$capitalized_name$IsMutable();\n"
-    "  $name$_.remove(index);\n"
-    "}\n");
-}
-
-void RepeatedImmutableLazyMessageFieldLiteGenerator::
-GenerateBuilderMembers(io::Printer* printer) const {
-  // List<Field> getRepeatedFieldList()
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
-    "  return java.util.Collections.unmodifiableList(\n"
-    "      instance.get$capitalized_name$List());\n"
-    "}\n");
-
-  // int getRepeatedFieldCount()
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public int get$capitalized_name$Count() {\n"
-    "  return instance.get$capitalized_name$Count();\n"
-    "}\n");
-
-  // Field getRepeatedField(int index)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
-    "  return instance.get$capitalized_name$(index);\n"
-    "}\n");
-
-  // Builder setRepeatedField(int index, Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder set$capitalized_name$(\n"
-    "    int index, $type$ value) {\n"
-    "  copyOnWrite();\n"
-    "  instance.set$capitalized_name$(index, value);\n"
-    "  return this;\n"
-    "}\n");
-
-  // Builder setRepeatedField(int index, Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder set$capitalized_name$(\n"
-    "    int index, $type$.Builder builderForValue) {\n"
-    "  copyOnWrite();\n"
-    "  instance.set$capitalized_name$(index, builderForValue);\n"
-    "  return this;\n"
-    "}\n");
-
-  // Builder addRepeatedField(Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
-    "  copyOnWrite();\n"
-    "  instance.add$capitalized_name$(value);\n"
-    "  return this;\n"
-    "}\n");
-
-  // Builder addRepeatedField(int index, Field value)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder add$capitalized_name$(\n"
-    "    int index, $type$ value) {\n"
-    "  copyOnWrite();\n"
-    "  instance.add$capitalized_name$(index, value);\n"
-    "  return this;\n"
-    "}\n");
-
-  // Builder addRepeatedField(Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder add$capitalized_name$(\n"
-    "    $type$.Builder builderForValue) {\n"
-    "  copyOnWrite();\n"
-    "  instance.add$capitalized_name$(builderForValue);\n"
-    "  return this;\n"
-    "}\n");
-
-  // Builder addRepeatedField(int index, Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder add$capitalized_name$(\n"
-    "    int index, $type$.Builder builderForValue) {\n"
-    "  copyOnWrite();\n"
-    "  instance.add$capitalized_name$(index, builderForValue);\n"
-    "  return this;\n"
-    "}\n");
-
-  // Builder addAllRepeatedField(Iterable<Field> values)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder addAll$capitalized_name$(\n"
-    "    java.lang.Iterable<? extends $type$> values) {\n"
-    "  copyOnWrite();\n"
-    "  instance.addAll$capitalized_name$(values);\n"
-    "  return this;\n"
-    "}\n");
-
-  // Builder clearAllRepeatedField()
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder clear$capitalized_name$() {\n"
-    "  copyOnWrite();\n"
-    "  instance.clear$capitalized_name$();\n"
-    "  return this;\n"
-    "}\n");
-
-  // Builder removeRepeatedField(int index)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-    "$deprecation$public Builder remove$capitalized_name$(int index) {\n"
-    "  copyOnWrite();\n"
-    "  instance.remove$capitalized_name$(index);\n"
-    "  return this;\n"
-    "}\n");
-}
-
-void RepeatedImmutableLazyMessageFieldLiteGenerator::
-GenerateParsingCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "if (!$is_mutable$) {\n"
-    "  $name$_ =\n"
-    "      com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
-    "}\n"
-    "$name$_.add(new com.google.protobuf.LazyFieldLite(\n"
-    "    extensionRegistry, input.readBytes()));\n");
-}
-
-void RepeatedImmutableLazyMessageFieldLiteGenerator::
-GenerateSerializationCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "for (int i = 0; i < $name$_.size(); i++) {\n"
-    "  output.writeBytes($number$, $name$_.get(i).toByteString());\n"
-    "}\n");
-}
-
-void RepeatedImmutableLazyMessageFieldLiteGenerator::
-GenerateSerializedSizeCode(io::Printer* printer) const {
-  printer->Print(variables_,
-    "for (int i = 0; i < $name$_.size(); i++) {\n"
-    "  size += com.google.protobuf.CodedOutputStream\n"
-    "    .computeLazyFieldSize($number$, $name$_.get(i));\n"
-    "}\n");
-}
-
-
-}  // namespace java
-}  // namespace compiler
-}  // namespace protobuf
-}  // namespace google
diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h
deleted file mode 100644
index 65b84fb..0000000
--- a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: niwasaki@google.com (Naoki Iwasaki)
-//  Based on original Protocol Buffers design by
-//  Sanjay Ghemawat, Jeff Dean, and others.
-
-#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_LITE_H__
-#define GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_LITE_H__
-
-#include <google/protobuf/compiler/java/java_field.h>
-#include <google/protobuf/compiler/java/java_message_field_lite.h>
-
-namespace google {
-namespace protobuf {
-  namespace compiler {
-    namespace java {
-      class Context;  // context.h
-    }
-  }
-}
-
-namespace protobuf {
-namespace compiler {
-namespace java {
-
-class ImmutableLazyMessageFieldLiteGenerator
-    : public ImmutableMessageFieldLiteGenerator {
- public:
-  explicit ImmutableLazyMessageFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
-  ~ImmutableLazyMessageFieldLiteGenerator();
-
-  // overroads ImmutableMessageFieldLiteGenerator ------------------------------
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
-  void GenerateInitializationCode(io::Printer* printer) const;
-  void GenerateVisitCode(io::Printer* printer) const;
-  void GenerateParsingCode(io::Printer* printer) const;
-  void GenerateSerializationCode(io::Printer* printer) const;
-  void GenerateSerializedSizeCode(io::Printer* printer) const;
-
-
- private:
-  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageFieldLiteGenerator);
-};
-
-class ImmutableLazyMessageOneofFieldLiteGenerator
-    : public ImmutableLazyMessageFieldLiteGenerator {
- public:
-  ImmutableLazyMessageOneofFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
-  ~ImmutableLazyMessageOneofFieldLiteGenerator();
-
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
-  void GenerateVisitCode(io::Printer* printer) const;
-  void GenerateParsingCode(io::Printer* printer) const;
-  void GenerateSerializationCode(io::Printer* printer) const;
-  void GenerateSerializedSizeCode(io::Printer* printer) const;
-
-
- private:
-  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageOneofFieldLiteGenerator);
-};
-
-class RepeatedImmutableLazyMessageFieldLiteGenerator
-    : public RepeatedImmutableMessageFieldLiteGenerator {
- public:
-  explicit RepeatedImmutableLazyMessageFieldLiteGenerator(
-      const FieldDescriptor* descriptor, int messageBitIndex,
-      int builderBitIndex, Context* context);
-  ~RepeatedImmutableLazyMessageFieldLiteGenerator();
-
-  // overroads RepeatedImmutableMessageFieldLiteGenerator ----------------------
-  void GenerateMembers(io::Printer* printer) const;
-  void GenerateBuilderMembers(io::Printer* printer) const;
-  void GenerateParsingCode(io::Printer* printer) const;
-  void GenerateSerializationCode(io::Printer* printer) const;
-  void GenerateSerializedSizeCode(io::Printer* printer) const;
-
-
- private:
-  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableLazyMessageFieldLiteGenerator);
-};
-
-}  // namespace java
-}  // namespace compiler
-}  // namespace protobuf
-
-}  // namespace google
-#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_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 baa7f87..bda4fcc 100644
--- a/src/google/protobuf/compiler/java/java_message_field.cc
+++ b/src/google/protobuf/compiler/java/java_message_field.cc
@@ -255,7 +255,7 @@
   bool support_field_presence = SupportFieldPresence(descriptor_->file());
 
   printer->Print(variables_,
-    "private $type$ $name$_ = null;\n");
+    "private $type$ $name$_;\n");
 
   printer->Print(variables_,
       // If this builder is non-null, it is used and the other fields are
@@ -444,15 +444,20 @@
 GenerateBuildingCode(io::Printer* printer) const {
   if (SupportFieldPresence(descriptor_->file())) {
     printer->Print(variables_,
-        "if ($get_has_field_bit_from_local$) {\n"
-        "  $set_has_field_bit_to_local$;\n"
-        "}\n");
+      "if ($get_has_field_bit_from_local$) {\n");
+    printer->Indent();
+    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");
+  } 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");
 }
 
 void ImmutableMessageFieldGenerator::
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc
index 71ee099..e6ce69c 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -264,7 +264,9 @@
 
 void ImmutablePrimitiveFieldGenerator::
 GenerateInitializationCode(io::Printer* printer) const {
-  printer->Print(variables_, "$name$_ = $default$;\n");
+  if (!IsDefaultValueJavaDefault(descriptor_)) {
+    printer->Print(variables_, "$name$_ = $default$;\n");
+  }
 }
 
 void ImmutablePrimitiveFieldGenerator::
@@ -294,11 +296,21 @@
   if (SupportFieldPresence(descriptor_->file())) {
     printer->Print(variables_,
       "if ($get_has_field_bit_from_local$) {\n"
-      "  $set_has_field_bit_to_local$;\n"
-      "}\n");
+      "  result.$name$_ = $name$_;\n"
+      "  $set_has_field_bit_to_local$;\n");
+    if (IsDefaultValueJavaDefault(descriptor_)) {
+      printer->Print(variables_,
+        "}\n");
+    } else {
+      printer->Print(variables_,
+        "} else {\n"
+        "  result.$name$_ = $default$;\n"
+        "}\n");
+    }
+  } else {
+    printer->Print(variables_,
+      "result.$name$_ = $name$_;\n");
   }
-  printer->Print(variables_,
-    "result.$name$_ = $name$_;\n");
 }
 
 void ImmutablePrimitiveFieldGenerator::
diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc
index 2b6e938..b08febc 100644
--- a/src/google/protobuf/compiler/java/java_string_field.cc
+++ b/src/google/protobuf/compiler/java/java_string_field.cc
@@ -405,11 +405,15 @@
   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/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc
old mode 100755
new mode 100644
index b5771f2..45b906f
--- a/src/google/protobuf/compiler/js/js_generator.cc
+++ b/src/google/protobuf/compiler/js/js_generator.cc
@@ -276,7 +276,8 @@
 string MaybeCrossFileRef(const GeneratorOptions& options,
                          const FileDescriptor* from_file,
                          const Descriptor* to_message) {
-  if (options.import_style == GeneratorOptions::kImportCommonJs &&
+  if ((options.import_style == GeneratorOptions::kImportCommonJs ||
+       options.import_style == GeneratorOptions::kImportCommonJsStrict) &&
       from_file != to_message->file()) {
     // Cross-file ref in CommonJS needs to use the module alias instead of
     // the global name.
@@ -1675,8 +1676,19 @@
       //
       //   // Later generated code expects foo.bar = {} to exist:
       //   foo.bar.Baz = function() { /* ... */ }
-      printer->Print("goog.exportSymbol('$name$', null, global);\n", "name",
-                     *it);
+
+      // Do not use global scope in strict mode
+      if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
+        string namespaceObject = *it;
+        // Remove "proto." from the namespace object
+        GOOGLE_CHECK(namespaceObject.compare(0, 6, "proto.") == 0);
+        namespaceObject.erase(0, 6);
+        printer->Print("goog.exportSymbol('$name$', null, proto);\n", "name",
+                namespaceObject);
+      } else {
+        printer->Print("goog.exportSymbol('$name$', null, global);\n", "name",
+                *it);
+      }
     }
   }
 }
@@ -3325,6 +3337,8 @@
         import_style = kImportClosure;
       } else if (options[i].second == "commonjs") {
         import_style = kImportCommonJs;
+      } else if (options[i].second == "commonjs_strict") {
+        import_style = kImportCommonJsStrict;
       } else if (options[i].second == "browser") {
         import_style = kImportBrowser;
       } else if (options[i].second == "es6") {
@@ -3434,15 +3448,23 @@
   GenerateHeader(options, printer);
 
   // Generate "require" statements.
-  if (options.import_style == GeneratorOptions::kImportCommonJs) {
+  if ((options.import_style == GeneratorOptions::kImportCommonJs ||
+       options.import_style == GeneratorOptions::kImportCommonJsStrict)) {
     printer->Print("var jspb = require('google-protobuf');\n");
     printer->Print("var goog = jspb;\n");
-    printer->Print("var global = Function('return this')();\n\n");
+
+    // Do not use global scope in strict mode
+    if (options.import_style == GeneratorOptions::kImportCommonJsStrict) {
+      printer->Print("var proto = {};\n\n");
+    } else {
+      printer->Print("var global = Function('return this')();\n\n");
+    }
 
     for (int i = 0; i < file->dependency_count(); i++) {
       const string& name = file->dependency(i)->name();
       printer->Print(
-          "var $alias$ = require('$file$');\n",
+          "var $alias$ = require('$file$');\n"
+          "goog.object.extend(proto, $alias$);\n",
           "alias", ModuleAlias(name),
           "file",
           GetRootPath(file->name(), name) + GetJSFilename(options, name));
@@ -3481,9 +3503,13 @@
     GenerateExtension(options, printer, *it);
   }
 
-  if (options.import_style == GeneratorOptions::kImportCommonJs) {
+  // if provided is empty, do not export anything
+  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));
   }
 
   // Emit well-known type methods.
diff --git a/src/google/protobuf/compiler/js/js_generator.h b/src/google/protobuf/compiler/js/js_generator.h
old mode 100755
new mode 100644
index 3cc60e2..b50ef7f
--- a/src/google/protobuf/compiler/js/js_generator.h
+++ b/src/google/protobuf/compiler/js/js_generator.h
@@ -63,10 +63,11 @@
   bool binary;
   // What style of imports should be used.
   enum ImportStyle {
-    kImportClosure,   // goog.require()
-    kImportCommonJs,  // require()
-    kImportBrowser,   // no import statements
-    kImportEs6,       // import { member } from ''
+    kImportClosure,         // goog.require()
+    kImportCommonJs,        // require()
+    kImportCommonJsStrict,  // require() with no global export
+    kImportBrowser,         // no import statements
+    kImportEs6,             // import { member } from ''
   } import_style;
 
   GeneratorOptions()
diff --git a/src/google/protobuf/compiler/js/well_known_types/any.js b/src/google/protobuf/compiler/js/well_known_types/any.js
deleted file mode 100644
index d7ca6e3..0000000
--- a/src/google/protobuf/compiler/js/well_known_types/any.js
+++ /dev/null
@@ -1,80 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/* This code will be inserted into generated code for
- * google/protobuf/any.proto. */
-
-/**
- * Returns the type name contained in this instance, if any.
- * @return {string|undefined}
- */
-proto.google.protobuf.Any.prototype.getTypeName = function() {
-  return this.getTypeUrl().split('/').pop();
-};
-
-
-/**
- * Packs the given message instance into this Any.
- * @param {!Uint8Array} serialized The serialized data to pack.
- * @param {string} name The type name of this message object.
- * @param {string=} opt_typeUrlPrefix the type URL prefix.
- */
-proto.google.protobuf.Any.prototype.pack = function(serialized, name,
-                                                    opt_typeUrlPrefix) {
-  if (!opt_typeUrlPrefix) {
-    opt_typeUrlPrefix = 'type.googleapis.com/';
-  }
-
-  if (opt_typeUrlPrefix.substr(-1) != '/') {
-    this.setTypeUrl(opt_typeUrlPrefix + '/' + name);
-  } else {
-    this.setTypeUrl(opt_typeUrlPrefix + name);
-  }
-
-  this.setValue(serialized);
-};
-
-
-/**
- * @template T
- * Unpacks this Any into the given message object.
- * @param {function(Uint8Array):T} deserialize Function that will deserialize
- *     the binary data properly.
- * @param {string} name The expected type name of this message object.
- * @return {?T} If the name matched the expected name, returns the deserialized
- *     object, otherwise returns null.
- */
-proto.google.protobuf.Any.prototype.unpack = function(deserialize, name) {
-  if (this.getTypeName() == name) {
-    return deserialize(this.getValue_asU8());
-  } else {
-    return null;
-  }
-};
diff --git a/src/google/protobuf/compiler/js/well_known_types/struct.js b/src/google/protobuf/compiler/js/well_known_types/struct.js
deleted file mode 100644
index 30e3d02..0000000
--- a/src/google/protobuf/compiler/js/well_known_types/struct.js
+++ /dev/null
@@ -1,168 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/* This code will be inserted into generated code for
- * google/protobuf/struct.proto. */
-
-/**
- * Typedef representing plain JavaScript values that can go into a
- *     Struct.
- * @typedef {null|number|string|boolean|Array|Object}
- */
-proto.google.protobuf.JavaScriptValue;
-
-
-/**
- * Converts this Value object to a plain JavaScript value.
- * @return {?proto.google.protobuf.JavaScriptValue} a plain JavaScript
- *     value representing this Struct.
- */
-proto.google.protobuf.Value.prototype.toJavaScript = function() {
-  var kindCase = proto.google.protobuf.Value.KindCase;
-  switch (this.getKindCase()) {
-    case kindCase.NULL_VALUE:
-      return null;
-    case kindCase.NUMBER_VALUE:
-      return this.getNumberValue();
-    case kindCase.STRING_VALUE:
-      return this.getStringValue();
-    case kindCase.BOOL_VALUE:
-      return this.getBoolValue();
-    case kindCase.STRUCT_VALUE:
-      return this.getStructValue().toJavaScript();
-    case kindCase.LIST_VALUE:
-      return this.getListValue().toJavaScript();
-    default:
-      throw new Error('Unexpected struct type');
-  }
-};
-
-
-/**
- * Converts this JavaScript value to a new Value proto.
- * @param {!proto.google.protobuf.JavaScriptValue} value The value to
- *     convert.
- * @return {!proto.google.protobuf.Value} The newly constructed value.
- */
-proto.google.protobuf.Value.fromJavaScript = function(value) {
-  var ret = new proto.google.protobuf.Value();
-  switch (goog.typeOf(value)) {
-    case 'string':
-      ret.setStringValue(/** @type {string} */ (value));
-      break;
-    case 'number':
-      ret.setNumberValue(/** @type {number} */ (value));
-      break;
-    case 'boolean':
-      ret.setBoolValue(/** @type {boolean} */ (value));
-      break;
-    case 'null':
-      ret.setNullValue(proto.google.protobuf.NullValue.NULL_VALUE);
-      break;
-    case 'array':
-      ret.setListValue(proto.google.protobuf.ListValue.fromJavaScript(
-          /** @type{!Array} */ (value)));
-      break;
-    case 'object':
-      ret.setStructValue(proto.google.protobuf.Struct.fromJavaScript(
-          /** @type{!Object} */ (value)));
-      break;
-    default:
-      throw new Error('Unexpected struct type.');
-  }
-
-  return ret;
-};
-
-
-/**
- * Converts this ListValue object to a plain JavaScript array.
- * @return {!Array} a plain JavaScript array representing this List.
- */
-proto.google.protobuf.ListValue.prototype.toJavaScript = function() {
-  var ret = [];
-  var values = this.getValuesList();
-
-  for (var i = 0; i < values.length; i++) {
-    ret[i] = values[i].toJavaScript();
-  }
-
-  return ret;
-};
-
-
-/**
- * Constructs a ListValue protobuf from this plain JavaScript array.
- * @param {!Array} array a plain JavaScript array
- * @return {proto.google.protobuf.ListValue} a new ListValue object
- */
-proto.google.protobuf.ListValue.fromJavaScript = function(array) {
-  var ret = new proto.google.protobuf.ListValue();
-
-  for (var i = 0; i < array.length; i++) {
-    ret.addValues(proto.google.protobuf.Value.fromJavaScript(array[i]));
-  }
-
-  return ret;
-};
-
-
-/**
- * Converts this Struct object to a plain JavaScript object.
- * @return {!Object<string, !proto.google.protobuf.JavaScriptValue>} a plain
- *     JavaScript object representing this Struct.
- */
-proto.google.protobuf.Struct.prototype.toJavaScript = function() {
-  var ret = {};
-
-  this.getFieldsMap().forEach(function(value, key) {
-    ret[key] = value.toJavaScript();
-  });
-
-  return ret;
-};
-
-
-/**
- * Constructs a Struct protobuf from this plain JavaScript object.
- * @param {!Object} obj a plain JavaScript object
- * @return {proto.google.protobuf.Struct} a new Struct object
- */
-proto.google.protobuf.Struct.fromJavaScript = function(obj) {
-  var ret = new proto.google.protobuf.Struct();
-  var map = ret.getFieldsMap();
-
-  for (var property in obj) {
-    var val = obj[property];
-    map.set(property, proto.google.protobuf.Value.fromJavaScript(val));
-  }
-
-  return ret;
-};
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index ef52def..20aa82c 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -183,14 +183,14 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::compiler::_CodeGeneratorResponse_default_instance_),
 };
 
-void protobuf_AssignDescriptors() {
+static void protobuf_AssignDescriptors() {
   AddDescriptors();
   AssignDescriptors(
       "google/protobuf/compiler/plugin.proto", schemas, file_default_instances, TableStruct::offsets,
       file_level_metadata, NULL, NULL);
 }
 
-void protobuf_AssignDescriptorsOnce() {
+static void protobuf_AssignDescriptorsOnce() {
   static ::google::protobuf::internal::once_flag once;
   ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
 }
@@ -201,7 +201,7 @@
   ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 4);
 }
 
-void AddDescriptorsImpl() {
+static void AddDescriptorsImpl() {
   InitDefaults();
   static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
       "\n%google/protobuf/compiler/plugin.proto\022"
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
index 1aabe8a..8454a5c 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
+++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
@@ -90,12 +90,12 @@
 
   // Load the generated output and compare to the expected result.
   string output;
-  GOOGLE_CHECK_OK(File::GetContents(
+  GOOGLE_CHECK_OK(File::GetContentsAsText(
       TestTempDir() + "/ruby_generated_code_pb.rb",
       &output,
       true));
   string expected_output;
-  GOOGLE_CHECK_OK(File::GetContents(
+  GOOGLE_CHECK_OK(File::GetContentsAsText(
       ruby_tests + "/ruby_generated_code_pb.rb",
       &expected_output,
       true));
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index fc3a9c7..fd00399 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -406,9 +406,10 @@
 template<typename PairType>
 struct PointerIntegerPairHash {
   size_t operator()(const PairType& p) const {
-    // FIXME(kenton):  What is the best way to compute this hash?  I have
-    // no idea!  This seems a bit better than an XOR.
-    return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second;
+    static const size_t prime1 = 16777499;
+    static const size_t prime2 = 16777619;
+    return reinterpret_cast<size_t>(p.first) * prime1 ^
+           static_cast<size_t>(p.second) * prime2;
   }
 
 #ifdef _MSC_VER
@@ -424,11 +425,10 @@
 
 struct PointerStringPairHash {
   size_t operator()(const PointerStringPair& p) const {
-    // FIXME(kenton):  What is the best way to compute this hash?  I have
-    // no idea!  This seems a bit better than an XOR.
+    static const size_t prime = 16777619;
     hash<const char*> cstring_hash;
-    return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) +
-           cstring_hash(p.second);
+    return reinterpret_cast<size_t>(p.first) * prime ^
+           static_cast<size_t>(cstring_hash(p.second));
   }
 
 #ifdef _MSC_VER
@@ -6906,7 +6906,7 @@
   DescriptorBuilder* builder_;
 
   virtual const FieldDescriptor* FindExtension(
-      Message* message, const string& name) const {
+      Message* message, const string& name) const override {
     assert_mutex_held(builder_->pool_);
     const Descriptor* descriptor = message->GetDescriptor();
     Symbol result = builder_->LookupSymbolNoPlaceholder(
@@ -6944,7 +6944,7 @@
   string error_;
 
   virtual void AddError(int /* line */, int /* column */,
-                        const string& message) {
+                const string& message) override {
     if (!error_.empty()) {
       error_ += "; ";
     }
@@ -6952,7 +6952,7 @@
   }
 
   virtual void AddWarning(int /* line */, int /* column */,
-                          const string& /* message */) {
+                  const string& /* message */) override {
     // Ignore warnings
   }
 };
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index 59b04ab..f3522ec 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -1077,14 +1077,14 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_GeneratedCodeInfo_default_instance_),
 };
 
-void protobuf_AssignDescriptors() {
+static void protobuf_AssignDescriptors() {
   AddDescriptors();
   AssignDescriptors(
       "google/protobuf/descriptor.proto", schemas, file_default_instances, TableStruct::offsets,
       file_level_metadata, file_level_enum_descriptors, NULL);
 }
 
-void protobuf_AssignDescriptorsOnce() {
+static void protobuf_AssignDescriptorsOnce() {
   static ::google::protobuf::internal::once_flag once;
   ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
 }
@@ -1095,7 +1095,7 @@
   ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 27);
 }
 
-void AddDescriptorsImpl() {
+static void AddDescriptorsImpl() {
   InitDefaults();
   static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
       "\n google/protobuf/descriptor.proto\022\017goog"
@@ -1487,7 +1487,7 @@
   FileDescriptorSet* _this = reinterpret_cast< FileDescriptorSet* >(object);
   (void)_this;
 }
-void FileDescriptorSet::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void FileDescriptorSet::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void FileDescriptorSet::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -1840,7 +1840,7 @@
   FileDescriptorProto* _this = reinterpret_cast< FileDescriptorProto* >(object);
   (void)_this;
 }
-void FileDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void FileDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void FileDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -2642,7 +2642,7 @@
   DescriptorProto_ExtensionRange* _this = reinterpret_cast< DescriptorProto_ExtensionRange* >(object);
   (void)_this;
 }
-void DescriptorProto_ExtensionRange::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void DescriptorProto_ExtensionRange::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void DescriptorProto_ExtensionRange::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -2994,7 +2994,7 @@
   DescriptorProto_ReservedRange* _this = reinterpret_cast< DescriptorProto_ReservedRange* >(object);
   (void)_this;
 }
-void DescriptorProto_ReservedRange::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void DescriptorProto_ReservedRange::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void DescriptorProto_ReservedRange::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -3350,7 +3350,7 @@
   DescriptorProto* _this = reinterpret_cast< DescriptorProto* >(object);
   (void)_this;
 }
-void DescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void DescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void DescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -4032,7 +4032,7 @@
   ExtensionRangeOptions* _this = reinterpret_cast< ExtensionRangeOptions* >(object);
   (void)_this;
 }
-void ExtensionRangeOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void ExtensionRangeOptions::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void ExtensionRangeOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -4390,7 +4390,7 @@
   FieldDescriptorProto* _this = reinterpret_cast< FieldDescriptorProto* >(object);
   (void)_this;
 }
-void FieldDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void FieldDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void FieldDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -4507,7 +4507,7 @@
       case 4: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) {
-          int value;
+          int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
@@ -4527,7 +4527,7 @@
       case 5: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
-          int value;
+          int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
@@ -5120,7 +5120,7 @@
   OneofDescriptorProto* _this = reinterpret_cast< OneofDescriptorProto* >(object);
   (void)_this;
 }
-void OneofDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void OneofDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void OneofDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -5450,7 +5450,7 @@
   EnumDescriptorProto_EnumReservedRange* _this = reinterpret_cast< EnumDescriptorProto_EnumReservedRange* >(object);
   (void)_this;
 }
-void EnumDescriptorProto_EnumReservedRange::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void EnumDescriptorProto_EnumReservedRange::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void EnumDescriptorProto_EnumReservedRange::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -5791,7 +5791,7 @@
   EnumDescriptorProto* _this = reinterpret_cast< EnumDescriptorProto* >(object);
   (void)_this;
 }
-void EnumDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void EnumDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void EnumDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -6283,7 +6283,7 @@
   EnumValueDescriptorProto* _this = reinterpret_cast< EnumValueDescriptorProto* >(object);
   (void)_this;
 }
-void EnumValueDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void EnumValueDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void EnumValueDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -6676,7 +6676,7 @@
   ServiceDescriptorProto* _this = reinterpret_cast< ServiceDescriptorProto* >(object);
   (void)_this;
 }
-void ServiceDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void ServiceDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void ServiceDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -7096,7 +7096,7 @@
   MethodDescriptorProto* _this = reinterpret_cast< MethodDescriptorProto* >(object);
   (void)_this;
 }
-void MethodDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void MethodDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void MethodDescriptorProto::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -7694,7 +7694,7 @@
   FileOptions* _this = reinterpret_cast< FileOptions* >(object);
   (void)_this;
 }
-void FileOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void FileOptions::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void FileOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -7814,7 +7814,7 @@
       case 9: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(72u /* 72 & 0xFF */)) {
-          int value;
+          int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
@@ -8885,7 +8885,7 @@
   MessageOptions* _this = reinterpret_cast< MessageOptions* >(object);
   (void)_this;
 }
-void MessageOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void MessageOptions::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void MessageOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -9329,7 +9329,7 @@
   FieldOptions* _this = reinterpret_cast< FieldOptions* >(object);
   (void)_this;
 }
-void FieldOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void FieldOptions::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void FieldOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -9377,7 +9377,7 @@
       case 1: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
-          int value;
+          int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
@@ -9439,7 +9439,7 @@
       case 6: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) {
-          int value;
+          int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
@@ -9848,7 +9848,7 @@
   OneofOptions* _this = reinterpret_cast< OneofOptions* >(object);
   (void)_this;
 }
-void OneofOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void OneofOptions::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void OneofOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -10145,7 +10145,7 @@
   EnumOptions* _this = reinterpret_cast< EnumOptions* >(object);
   (void)_this;
 }
-void EnumOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void EnumOptions::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void EnumOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -10514,7 +10514,7 @@
   EnumValueOptions* _this = reinterpret_cast< EnumValueOptions* >(object);
   (void)_this;
 }
-void EnumValueOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void EnumValueOptions::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void EnumValueOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -10842,7 +10842,7 @@
   ServiceOptions* _this = reinterpret_cast< ServiceOptions* >(object);
   (void)_this;
 }
-void ServiceOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void ServiceOptions::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void ServiceOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -11175,7 +11175,7 @@
   MethodOptions* _this = reinterpret_cast< MethodOptions* >(object);
   (void)_this;
 }
-void MethodOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void MethodOptions::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void MethodOptions::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -11237,7 +11237,7 @@
       case 34: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(16u /* 272 & 0xFF */)) {
-          int value;
+          int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
@@ -11559,7 +11559,7 @@
   UninterpretedOption_NamePart* _this = reinterpret_cast< UninterpretedOption_NamePart* >(object);
   (void)_this;
 }
-void UninterpretedOption_NamePart::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void UninterpretedOption_NamePart::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void UninterpretedOption_NamePart::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -11924,7 +11924,7 @@
   UninterpretedOption* _this = reinterpret_cast< UninterpretedOption* >(object);
   (void)_this;
 }
-void UninterpretedOption::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void UninterpretedOption::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void UninterpretedOption::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -12473,7 +12473,7 @@
   SourceCodeInfo_Location* _this = reinterpret_cast< SourceCodeInfo_Location* >(object);
   (void)_this;
 }
-void SourceCodeInfo_Location::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void SourceCodeInfo_Location::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void SourceCodeInfo_Location::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -12979,7 +12979,7 @@
   SourceCodeInfo* _this = reinterpret_cast< SourceCodeInfo* >(object);
   (void)_this;
 }
-void SourceCodeInfo::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void SourceCodeInfo::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void SourceCodeInfo::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -13258,7 +13258,7 @@
   GeneratedCodeInfo_Annotation* _this = reinterpret_cast< GeneratedCodeInfo_Annotation* >(object);
   (void)_this;
 }
-void GeneratedCodeInfo_Annotation::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void GeneratedCodeInfo_Annotation::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void GeneratedCodeInfo_Annotation::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -13676,7 +13676,7 @@
   GeneratedCodeInfo* _this = reinterpret_cast< GeneratedCodeInfo* >(object);
   (void)_this;
 }
-void GeneratedCodeInfo::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void GeneratedCodeInfo::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void GeneratedCodeInfo::SetCachedSize(int size) const {
   _cached_size_.Set(size);
diff --git a/src/google/protobuf/descriptor_database.h b/src/google/protobuf/descriptor_database.h
index d61f2a6..0752366 100644
--- a/src/google/protobuf/descriptor_database.h
+++ b/src/google/protobuf/descriptor_database.h
@@ -142,7 +142,7 @@
 class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
  public:
   SimpleDescriptorDatabase();
-  ~SimpleDescriptorDatabase();
+  ~SimpleDescriptorDatabase() override;
 
   // Adds the FileDescriptorProto to the database, making a copy.  The object
   // can be deleted after Add() returns.  Returns false if the file conflicted
@@ -155,14 +155,14 @@
 
   // implements DescriptorDatabase -----------------------------------
   bool FindFileByName(const string& filename,
-                      FileDescriptorProto* output);
+                      FileDescriptorProto* output) override;
   bool FindFileContainingSymbol(const string& symbol_name,
-                                FileDescriptorProto* output);
+                                FileDescriptorProto* output) override;
   bool FindFileContainingExtension(const string& containing_type,
                                    int field_number,
-                                   FileDescriptorProto* output);
+                                   FileDescriptorProto* output) override;
   bool FindAllExtensionNumbers(const string& extendee_type,
-                               std::vector<int>* output);
+                               std::vector<int>* output) override;
 
  private:
   // So that it can use DescriptorIndex.
@@ -280,7 +280,7 @@
 class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase {
  public:
   EncodedDescriptorDatabase();
-  ~EncodedDescriptorDatabase();
+  ~EncodedDescriptorDatabase() override;
 
   // Adds the FileDescriptorProto to the database.  The descriptor is provided
   // in encoded form.  The database does not make a copy of the bytes, nor
@@ -300,14 +300,14 @@
 
   // implements DescriptorDatabase -----------------------------------
   bool FindFileByName(const string& filename,
-                      FileDescriptorProto* output);
+                      FileDescriptorProto* output) override;
   bool FindFileContainingSymbol(const string& symbol_name,
-                                FileDescriptorProto* output);
+                                FileDescriptorProto* output) override;
   bool FindFileContainingExtension(const string& containing_type,
                                    int field_number,
-                                   FileDescriptorProto* output);
+                                   FileDescriptorProto* output) override;
   bool FindAllExtensionNumbers(const string& extendee_type,
-                               std::vector<int>* output);
+                               std::vector<int>* output) override;
 
  private:
   SimpleDescriptorDatabase::DescriptorIndex<std::pair<const void*, int> >
@@ -326,18 +326,18 @@
 class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase {
  public:
   explicit DescriptorPoolDatabase(const DescriptorPool& pool);
-  ~DescriptorPoolDatabase();
+  ~DescriptorPoolDatabase() override;
 
   // implements DescriptorDatabase -----------------------------------
   bool FindFileByName(const string& filename,
-                      FileDescriptorProto* output);
+                      FileDescriptorProto* output) override;
   bool FindFileContainingSymbol(const string& symbol_name,
-                                FileDescriptorProto* output);
+                                FileDescriptorProto* output) override;
   bool FindFileContainingExtension(const string& containing_type,
                                    int field_number,
-                                   FileDescriptorProto* output);
+                                   FileDescriptorProto* output) override;
   bool FindAllExtensionNumbers(const string& extendee_type,
-                               std::vector<int>* output);
+                               std::vector<int>* output) override;
 
  private:
   const DescriptorPool& pool_;
@@ -356,20 +356,20 @@
   // DescriptorDatabases need to stick around.
   explicit MergedDescriptorDatabase(
       const std::vector<DescriptorDatabase*>& sources);
-  ~MergedDescriptorDatabase();
+  ~MergedDescriptorDatabase() override;
 
   // implements DescriptorDatabase -----------------------------------
   bool FindFileByName(const string& filename,
-                      FileDescriptorProto* output);
+                      FileDescriptorProto* output) override;
   bool FindFileContainingSymbol(const string& symbol_name,
-                                FileDescriptorProto* output);
+                                FileDescriptorProto* output) override;
   bool FindFileContainingExtension(const string& containing_type,
                                    int field_number,
-                                   FileDescriptorProto* output);
+                                   FileDescriptorProto* output) override;
   // Merges the results of calling all databases. Returns true iff any
   // of the databases returned true.
   bool FindAllExtensionNumbers(const string& extendee_type,
-                               std::vector<int>* output);
+                               std::vector<int>* output) override;
 
 
  private:
diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc
index ddc063d..e8417a7 100644
--- a/src/google/protobuf/duration.pb.cc
+++ b/src/google/protobuf/duration.pb.cc
@@ -66,14 +66,14 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Duration_default_instance_),
 };
 
-void protobuf_AssignDescriptors() {
+static void protobuf_AssignDescriptors() {
   AddDescriptors();
   AssignDescriptors(
       "google/protobuf/duration.proto", schemas, file_default_instances, TableStruct::offsets,
       file_level_metadata, NULL, NULL);
 }
 
-void protobuf_AssignDescriptorsOnce() {
+static void protobuf_AssignDescriptorsOnce() {
   static ::google::protobuf::internal::once_flag once;
   ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
 }
@@ -84,7 +84,7 @@
   ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
 }
 
-void AddDescriptorsImpl() {
+static void AddDescriptorsImpl() {
   InitDefaults();
   static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
       "\n\036google/protobuf/duration.proto\022\017google"
@@ -167,7 +167,7 @@
   Duration* _this = reinterpret_cast< Duration* >(object);
   (void)_this;
 }
-void Duration::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void Duration::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void Duration::SetCachedSize(int size) const {
   _cached_size_.Set(size);
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc
index ceedf50..8ad112c 100644
--- a/src/google/protobuf/dynamic_message.cc
+++ b/src/google/protobuf/dynamic_message.cc
@@ -258,14 +258,14 @@
 
   // implements Message ----------------------------------------------
 
-  Message* New() const;
-  Message* New(::google::protobuf::Arena* arena) const;
-  ::google::protobuf::Arena* GetArena() const { return arena_; }
+  Message* New() const override;
+  Message* New(::google::protobuf::Arena* arena) const override;
+  ::google::protobuf::Arena* GetArena() const override { return arena_; }
 
-  int GetCachedSize() const;
-  void SetCachedSize(int size) const;
+  int GetCachedSize() const override;
+  void SetCachedSize(int size) const override;
 
-  Metadata GetMetadata() const;
+  Metadata GetMetadata() const override;
 
   // We actually allocate more memory than sizeof(*this) when this
   // class's memory is allocated via the global operator new. Thus, we need to
diff --git a/src/google/protobuf/dynamic_message.h b/src/google/protobuf/dynamic_message.h
index d84cc8a..940d5e1 100644
--- a/src/google/protobuf/dynamic_message.h
+++ b/src/google/protobuf/dynamic_message.h
@@ -115,7 +115,7 @@
   // outlive the DynamicMessageFactory.
   //
   // The method is thread-safe.
-  const Message* GetPrototype(const Descriptor* type);
+  const Message* GetPrototype(const Descriptor* type) override;
 
  private:
   const DescriptorPool* pool_;
diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc
index 9b53c54..163a4f6 100644
--- a/src/google/protobuf/empty.pb.cc
+++ b/src/google/protobuf/empty.pb.cc
@@ -64,14 +64,14 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Empty_default_instance_),
 };
 
-void protobuf_AssignDescriptors() {
+static void protobuf_AssignDescriptors() {
   AddDescriptors();
   AssignDescriptors(
       "google/protobuf/empty.proto", schemas, file_default_instances, TableStruct::offsets,
       file_level_metadata, NULL, NULL);
 }
 
-void protobuf_AssignDescriptorsOnce() {
+static void protobuf_AssignDescriptorsOnce() {
   static ::google::protobuf::internal::once_flag once;
   ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
 }
@@ -82,7 +82,7 @@
   ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
 }
 
-void AddDescriptorsImpl() {
+static void AddDescriptorsImpl() {
   InitDefaults();
   static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
       "\n\033google/protobuf/empty.proto\022\017google.pr"
@@ -156,7 +156,7 @@
   Empty* _this = reinterpret_cast< Empty* >(object);
   (void)_this;
 }
-void Empty::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void Empty::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void Empty::SetCachedSize(int size) const {
   _cached_size_.Set(size);
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index a1535ba..04d0e62 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -134,7 +134,7 @@
   virtual ~GeneratedExtensionFinder() {}
 
   // Returns true and fills in *output if found, otherwise returns false.
-  virtual bool Find(int number, ExtensionInfo* output);
+  virtual bool Find(int number, ExtensionInfo* output) override;
 
  private:
   const MessageLite* containing_type_;
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc
index a3c8416..372aea5 100644
--- a/src/google/protobuf/extension_set_heavy.cc
+++ b/src/google/protobuf/extension_set_heavy.cc
@@ -85,9 +85,9 @@
                                 MessageFactory* factory,
                                 const Descriptor* containing_type)
       : pool_(pool), factory_(factory), containing_type_(containing_type) {}
-  virtual ~DescriptorPoolExtensionFinder() {}
+  virtual ~DescriptorPoolExtensionFinder() override {}
 
-  virtual bool Find(int number, ExtensionInfo* output);
+  virtual bool Find(int number, ExtensionInfo* output) override;
 
  private:
   const DescriptorPool* pool_;
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index 000fa8d..2ce061d 100644
--- a/src/google/protobuf/field_mask.pb.cc
+++ b/src/google/protobuf/field_mask.pb.cc
@@ -65,14 +65,14 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_FieldMask_default_instance_),
 };
 
-void protobuf_AssignDescriptors() {
+static void protobuf_AssignDescriptors() {
   AddDescriptors();
   AssignDescriptors(
       "google/protobuf/field_mask.proto", schemas, file_default_instances, TableStruct::offsets,
       file_level_metadata, NULL, NULL);
 }
 
-void protobuf_AssignDescriptorsOnce() {
+static void protobuf_AssignDescriptorsOnce() {
   static ::google::protobuf::internal::once_flag once;
   ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
 }
@@ -83,7 +83,7 @@
   ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
 }
 
-void AddDescriptorsImpl() {
+static void AddDescriptorsImpl() {
   InitDefaults();
   static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
       "\n google/protobuf/field_mask.proto\022\017goog"
diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h
index 31f249b..28a023b 100644
--- a/src/google/protobuf/generated_message_reflection.h
+++ b/src/google/protobuf/generated_message_reflection.h
@@ -304,199 +304,208 @@
                              const DescriptorPool* pool,
                              MessageFactory* factory);
 
-  ~GeneratedMessageReflection();
+
+  ~GeneratedMessageReflection() override;
 
   // implements Reflection -------------------------------------------
 
-  const UnknownFieldSet& GetUnknownFields(const Message& message) const;
-  UnknownFieldSet* MutableUnknownFields(Message* message) const;
+  const UnknownFieldSet& GetUnknownFields(
+      const Message& message) const override;
+  UnknownFieldSet* MutableUnknownFields(Message* message) const override;
 
-  size_t SpaceUsedLong(const Message& message) const;
+  size_t SpaceUsedLong(const Message& message) const override;
 
-  bool HasField(const Message& message, const FieldDescriptor* field) const;
-  int FieldSize(const Message& message, const FieldDescriptor* field) const;
-  void ClearField(Message* message, const FieldDescriptor* field) const;
+  bool HasField(const Message& message,
+                const FieldDescriptor* field) const override;
+  int FieldSize(const Message& message,
+                const FieldDescriptor* field) const override;
+  void ClearField(Message* message,
+                  const FieldDescriptor* field) const override;
   bool HasOneof(const Message& message,
-                const OneofDescriptor* oneof_descriptor) const;
-  void ClearOneof(Message* message, const OneofDescriptor* field) const;
-  void RemoveLast(Message* message, const FieldDescriptor* field) const;
-  Message* ReleaseLast(Message* message, const FieldDescriptor* field) const;
-  void Swap(Message* message1, Message* message2) const;
+                const OneofDescriptor* oneof_descriptor) const override;
+  void ClearOneof(Message* message,
+                  const OneofDescriptor* field) 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;
+                  const std::vector<const FieldDescriptor*>& fields) const override;
   void SwapElements(Message* message, const FieldDescriptor* field,
-                    int index1, int index2) const;
+                    int index1, int index2) const override;
   void ListFields(const Message& message,
-                  std::vector<const FieldDescriptor*>* output) const;
-
+                  std::vector<const FieldDescriptor*>* output) const override;
   int32  GetInt32 (const Message& message,
-                   const FieldDescriptor* field) const;
+                   const FieldDescriptor* field) const override;
   int64  GetInt64 (const Message& message,
-                   const FieldDescriptor* field) const;
+                   const FieldDescriptor* field) const override;
   uint32 GetUInt32(const Message& message,
-                   const FieldDescriptor* field) const;
+                   const FieldDescriptor* field) const override;
   uint64 GetUInt64(const Message& message,
-                   const FieldDescriptor* field) const;
+                   const FieldDescriptor* field) const override;
   float  GetFloat (const Message& message,
-                   const FieldDescriptor* field) const;
+                   const FieldDescriptor* field) const override;
   double GetDouble(const Message& message,
-                   const FieldDescriptor* field) const;
+                   const FieldDescriptor* field) const override;
   bool   GetBool  (const Message& message,
-                   const FieldDescriptor* field) const;
+                   const FieldDescriptor* field) const override;
   string GetString(const Message& message,
-                   const FieldDescriptor* field) const;
+                   const FieldDescriptor* field) const override;
   const string& GetStringReference(const Message& message,
                                    const FieldDescriptor* field,
-                                   string* scratch) const;
-  const EnumValueDescriptor* GetEnum(const Message& message,
-                                     const FieldDescriptor* field) const;
+                                   string* scratch) const override;
+  const EnumValueDescriptor* GetEnum(
+      const Message& message, const FieldDescriptor* field) const override;
   int GetEnumValue(const Message& message,
-                   const FieldDescriptor* field) const;
+                   const FieldDescriptor* field) const override;
   const Message& GetMessage(const Message& message,
                             const FieldDescriptor* field,
-                            MessageFactory* factory = NULL) const;
+                            MessageFactory* factory = NULL) const override;
 
   const FieldDescriptor* GetOneofFieldDescriptor(
       const Message& message,
-      const OneofDescriptor* oneof_descriptor) const;
+      const OneofDescriptor* oneof_descriptor) const override;
 
  private:
   bool ContainsMapKey(const Message& message,
                       const FieldDescriptor* field,
-                      const MapKey& key) const;
+                      const MapKey& key) const override;
   bool InsertOrLookupMapValue(Message* message,
                               const FieldDescriptor* field,
                               const MapKey& key,
-                              MapValueRef* val) const;
+                              MapValueRef* val) const override;
   bool DeleteMapValue(Message* message,
                       const FieldDescriptor* field,
-                      const MapKey& key) const;
+                      const MapKey& key) const override;
   MapIterator MapBegin(
       Message* message,
-      const FieldDescriptor* field) const;
+      const FieldDescriptor* field) const override;
   MapIterator MapEnd(
       Message* message,
-      const FieldDescriptor* field) const;
-  int MapSize(const Message& message, const FieldDescriptor* field) const;
+      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;
+                 const FieldDescriptor* field, int32  value) const override;
   void SetInt64 (Message* message,
-                 const FieldDescriptor* field, int64  value) const;
+                 const FieldDescriptor* field, int64  value) const override;
   void SetUInt32(Message* message,
-                 const FieldDescriptor* field, uint32 value) const;
+                 const FieldDescriptor* field, uint32 value) const override;
   void SetUInt64(Message* message,
-                 const FieldDescriptor* field, uint64 value) const;
+                 const FieldDescriptor* field, uint64 value) const override;
   void SetFloat (Message* message,
-                 const FieldDescriptor* field, float  value) const;
+                 const FieldDescriptor* field, float  value) const override;
   void SetDouble(Message* message,
-                 const FieldDescriptor* field, double value) const;
+                 const FieldDescriptor* field, double value) const override;
   void SetBool  (Message* message,
-                 const FieldDescriptor* field, bool   value) const;
+                 const FieldDescriptor* field, bool   value) const override;
   void SetString(Message* message,
                  const FieldDescriptor* field,
-                 const string& value) const;
+                 const string& value) const override;
   void SetEnum  (Message* message, const FieldDescriptor* field,
-                 const EnumValueDescriptor* value) const;
+                 const EnumValueDescriptor* value) const override;
   void SetEnumValue(Message* message, const FieldDescriptor* field,
-                    int value) const;
+                    int value) const override;
   Message* MutableMessage(Message* message, const FieldDescriptor* field,
-                          MessageFactory* factory = NULL) const;
+                          MessageFactory* factory = NULL) const override;
   void SetAllocatedMessage(Message* message,
                            Message* sub_message,
-                           const FieldDescriptor* field) const;
+                           const FieldDescriptor* field) const override;
   Message* ReleaseMessage(Message* message, const FieldDescriptor* field,
-                          MessageFactory* factory = NULL) const;
+                          MessageFactory* factory = NULL) const override;
 
-  int32  GetRepeatedInt32 (const Message& message,
-                           const FieldDescriptor* field, int index) const;
-  int64  GetRepeatedInt64 (const Message& message,
-                           const FieldDescriptor* field, int index) const;
-  uint32 GetRepeatedUInt32(const Message& message,
-                           const FieldDescriptor* field, int index) const;
-  uint64 GetRepeatedUInt64(const Message& message,
-                           const FieldDescriptor* field, int index) const;
-  float  GetRepeatedFloat (const Message& message,
-                           const FieldDescriptor* field, int index) const;
-  double GetRepeatedDouble(const Message& message,
-                           const FieldDescriptor* field, int index) const;
-  bool   GetRepeatedBool  (const Message& message,
-                           const FieldDescriptor* field, int index) const;
-  string GetRepeatedString(const Message& message,
-                           const FieldDescriptor* field, int index) const;
-  const string& GetRepeatedStringReference(const Message& message,
+  int32 GetRepeatedInt32(const Message& message, const FieldDescriptor* field,
+                         int index) const override;
+  int64 GetRepeatedInt64(const Message& message, const FieldDescriptor* field,
+                         int index) const override;
+  uint32 GetRepeatedUInt32(const Message& message, const FieldDescriptor* field,
+                           int index) const override;
+  uint64 GetRepeatedUInt64(const Message& message, const FieldDescriptor* field,
+                           int index) const override;
+  float GetRepeatedFloat(const Message& message, const FieldDescriptor* field,
+                         int index) const override;
+  double GetRepeatedDouble(const Message& message, const FieldDescriptor* field,
+                           int index) const override;
+  bool GetRepeatedBool(const Message& message, const FieldDescriptor* field,
+                       int index) const override;
+  string GetRepeatedString(const Message& message, const FieldDescriptor* field,
+                           int index) const override;
+  const string &GetRepeatedStringReference(const Message& message,
                                            const FieldDescriptor* field,
-                                           int index, string* scratch) const;
+                                           int index,
+                                           string* scratch) const override;
   const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
                                              const FieldDescriptor* field,
-                                             int index) const;
-  int GetRepeatedEnumValue(const Message& message,
-                           const FieldDescriptor* field,
-                           int index) const;
-  const Message& GetRepeatedMessage(const Message& message,
+                                             int index) const override;
+  int GetRepeatedEnumValue(const Message& message, const FieldDescriptor* field,
+                           int index) const override;
+  const Message &GetRepeatedMessage(const Message& message,
                                     const FieldDescriptor* field,
-                                    int index) const;
+                                    int index) const override;
 
   // Set the value of a field.
-  void SetRepeatedInt32 (Message* message,
-                         const FieldDescriptor* field, int index, int32  value) const;
-  void SetRepeatedInt64 (Message* message,
-                         const FieldDescriptor* field, int index, int64  value) const;
-  void SetRepeatedUInt32(Message* message,
-                         const FieldDescriptor* field, int index, uint32 value) const;
-  void SetRepeatedUInt64(Message* message,
-                         const FieldDescriptor* field, int index, uint64 value) const;
-  void SetRepeatedFloat (Message* message,
-                         const FieldDescriptor* field, int index, float  value) const;
-  void SetRepeatedDouble(Message* message,
-                         const FieldDescriptor* field, int index, double value) const;
-  void SetRepeatedBool  (Message* message,
-                         const FieldDescriptor* field, int index, bool   value) const;
-  void SetRepeatedString(Message* message,
-                         const FieldDescriptor* field, int index,
-                         const string& value) const;
+  void SetRepeatedInt32(Message* message, const FieldDescriptor* field,
+                        int index, int32 value) const override;
+  void SetRepeatedInt64(Message* message, const FieldDescriptor* field,
+                        int index, int64 value) const override;
+  void SetRepeatedUInt32(Message* message, const FieldDescriptor* field,
+                         int index, uint32 value) const override;
+  void SetRepeatedUInt64(Message* message, const FieldDescriptor* field,
+                         int index, uint64 value) const override;
+  void SetRepeatedFloat(Message* message, const FieldDescriptor* field,
+                        int index, float value) const override;
+  void SetRepeatedDouble(Message* message, const FieldDescriptor* field,
+                         int index, double value) const override;
+  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;
   void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
-                       int index, const EnumValueDescriptor* value) const;
+                       int index,
+                       const EnumValueDescriptor* value) const override;
   void SetRepeatedEnumValue(Message* message, const FieldDescriptor* field,
-                            int index, int value) const;
+                            int index, int value) const override;
   // Get a mutable pointer to a field with a message type.
   Message* MutableRepeatedMessage(Message* message,
                                   const FieldDescriptor* field,
-                                  int index) const;
+                                  int index) const override;
 
   void AddInt32 (Message* message,
-                 const FieldDescriptor* field, int32  value) const;
+                 const FieldDescriptor* field, int32  value) const override;
   void AddInt64 (Message* message,
-                 const FieldDescriptor* field, int64  value) const;
+                 const FieldDescriptor* field, int64  value) const override;
   void AddUInt32(Message* message,
-                 const FieldDescriptor* field, uint32 value) const;
+                 const FieldDescriptor* field, uint32 value) const override;
   void AddUInt64(Message* message,
-                 const FieldDescriptor* field, uint64 value) const;
+                 const FieldDescriptor* field, uint64 value) const override;
   void AddFloat (Message* message,
-                 const FieldDescriptor* field, float  value) const;
+                 const FieldDescriptor* field, float  value) const override;
   void AddDouble(Message* message,
-                 const FieldDescriptor* field, double value) const;
+                 const FieldDescriptor* field, double value) const override;
   void AddBool  (Message* message,
-                 const FieldDescriptor* field, bool   value) const;
-  void AddString(Message* message,
-                 const FieldDescriptor* field, const string& value) const;
+                 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,
-               const EnumValueDescriptor* value) const;
+               const EnumValueDescriptor* value) const override;
   void AddEnumValue(Message* message,
                     const FieldDescriptor* field,
-                    int value) const;
+                    int value) const override;
   Message* AddMessage(Message* message, const FieldDescriptor* field,
-                      MessageFactory* factory = NULL) const;
+                      MessageFactory* factory = NULL) const override;
   void AddAllocatedMessage(
       Message* message, const FieldDescriptor* field,
-      Message* new_entry) const;
+      Message* new_entry) const override;
 
-  const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
-  const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
+  const FieldDescriptor* FindKnownExtensionByName(
+      const string& name) const override;
+  const FieldDescriptor* FindKnownExtensionByNumber(int number) const override;
 
-  bool SupportsUnknownEnumValues() const;
+  bool SupportsUnknownEnumValues() const override;
 
   // This value for arena_offset_ indicates that there is no arena pointer in
   // this message (e.g., old generated code).
@@ -514,19 +523,19 @@
  protected:
   void* MutableRawRepeatedField(
       Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
-      int ctype, const Descriptor* desc) const;
+      int ctype, const Descriptor* desc) const override;
 
   const void* GetRawRepeatedField(
       const Message& message, const FieldDescriptor* field,
       FieldDescriptor::CppType, int ctype,
-      const Descriptor* desc) const;
+      const Descriptor* desc) const override;
 
-  virtual MessageFactory* GetMessageFactory() const;
+  virtual MessageFactory* GetMessageFactory() const override;
 
   virtual void* RepeatedFieldData(
       Message* message, const FieldDescriptor* field,
       FieldDescriptor::CppType cpp_type,
-      const Descriptor* message_type) const;
+      const Descriptor* message_type) const override;
 
  private:
   friend class google::protobuf::flat::MetadataBuilder;
@@ -661,7 +670,7 @@
                                       const FieldDescriptor* field) const;
 
   internal::MapFieldBase* MapData(
-      Message* message, const FieldDescriptor* field) const;
+      Message* message, const FieldDescriptor* field) const override;
 
   friend inline  // inline so nobody can call this function.
       void
diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h
index 04f68a6..76b8124 100644
--- a/src/google/protobuf/generated_message_util.h
+++ b/src/google/protobuf/generated_message_util.h
@@ -206,7 +206,7 @@
 };
 
 LIBPROTOBUF_EXPORT void SerializeInternal(const uint8* base, const FieldMetadata* table,
-                       int num_fields, ::google::protobuf::io::CodedOutputStream* output);
+                       int32 num_fields, ::google::protobuf::io::CodedOutputStream* output);
 
 inline void TableSerialize(const ::google::protobuf::MessageLite& msg,
                            const SerializationTable* table,
@@ -224,7 +224,7 @@
 }
 
 uint8* SerializeInternalToArray(const uint8* base, const FieldMetadata* table,
-                                int num_fields, bool is_deterministic,
+                                int32 num_fields, bool is_deterministic,
                                 uint8* buffer);
 
 inline uint8* TableSerializeToArray(const ::google::protobuf::MessageLite& msg,
diff --git a/src/google/protobuf/io/gzip_stream.h b/src/google/protobuf/io/gzip_stream.h
index 15b02fe..df1a446 100644
--- a/src/google/protobuf/io/gzip_stream.h
+++ b/src/google/protobuf/io/gzip_stream.h
@@ -118,7 +118,7 @@
     ZLIB = 2,
   };
 
-  struct Options {
+  struct LIBPROTOBUF_EXPORT Options {
     // Defaults to GZIP.
     Format format;
 
diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h
index ea978bf..ef9fc9d 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl.h
+++ b/src/google/protobuf/io/zero_copy_stream_impl.h
@@ -87,24 +87,24 @@
   int GetErrno() { return copying_input_.GetErrno(); }
 
   // implements ZeroCopyInputStream ----------------------------------
-  bool Next(const void** data, int* size);
-  void BackUp(int count);
-  bool Skip(int count);
-  int64 ByteCount() const;
+  bool Next(const void** data, int* size) override;
+  void BackUp(int count) override;
+  bool Skip(int count) override;
+  int64 ByteCount() const override;
 
  private:
   class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream {
    public:
     CopyingFileInputStream(int file_descriptor);
-    ~CopyingFileInputStream();
+    ~CopyingFileInputStream() override;
 
     bool Close();
     void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
     int GetErrno() { return errno_; }
 
     // implements CopyingInputStream ---------------------------------
-    int Read(void* buffer, int size);
-    int Skip(int count);
+    int Read(void* buffer, int size) override;
+    int Skip(int count) override;
 
    private:
     // The file descriptor.
@@ -144,7 +144,7 @@
   // that should be returned by Next().  Otherwise, a reasonable default
   // is used.
   explicit FileOutputStream(int file_descriptor, int block_size = -1);
-  ~FileOutputStream();
+  ~FileOutputStream() override;
 
   // Flushes any buffers and closes the underlying file.  Returns false if
   // an error occurs during the process; use GetErrno() to examine the error.
@@ -170,22 +170,22 @@
   int GetErrno() { return copying_output_.GetErrno(); }
 
   // implements ZeroCopyOutputStream ---------------------------------
-  bool Next(void** data, int* size);
-  void BackUp(int count);
-  int64 ByteCount() const;
+  bool Next(void** data, int* size) override;
+  void BackUp(int count) override;
+  int64 ByteCount() const override;
 
  private:
   class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream {
    public:
     CopyingFileOutputStream(int file_descriptor);
-    ~CopyingFileOutputStream();
+    ~CopyingFileOutputStream() override;
 
     bool Close();
     void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
     int GetErrno() { return errno_; }
 
     // implements CopyingOutputStream --------------------------------
-    bool Write(const void* buffer, int size);
+    bool Write(const void* buffer, int size) override;
 
    private:
     // The file descriptor.
@@ -220,19 +220,19 @@
   explicit IstreamInputStream(std::istream* stream, int block_size = -1);
 
   // implements ZeroCopyInputStream ----------------------------------
-  bool Next(const void** data, int* size);
-  void BackUp(int count);
-  bool Skip(int count);
-  int64 ByteCount() const;
+  bool Next(const void** data, int* size) override;
+  void BackUp(int count) override;
+  bool Skip(int count) override;
+  int64 ByteCount() const override;
 
  private:
   class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream {
    public:
     CopyingIstreamInputStream(std::istream* input);
-    ~CopyingIstreamInputStream();
+    ~CopyingIstreamInputStream() override;
 
     // implements CopyingInputStream ---------------------------------
-    int Read(void* buffer, int size);
+    int Read(void* buffer, int size) override;
     // (We use the default implementation of Skip().)
 
    private:
@@ -261,21 +261,21 @@
   // that should be returned by Next().  Otherwise, a reasonable default
   // is used.
   explicit OstreamOutputStream(std::ostream* stream, int block_size = -1);
-  ~OstreamOutputStream();
+  ~OstreamOutputStream() override;
 
   // implements ZeroCopyOutputStream ---------------------------------
-  bool Next(void** data, int* size);
-  void BackUp(int count);
-  int64 ByteCount() const;
+  bool Next(void** data, int* size) override;
+  void BackUp(int count) override;
+  int64 ByteCount() const override;
 
  private:
   class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream {
    public:
     CopyingOstreamOutputStream(std::ostream* output);
-    ~CopyingOstreamOutputStream();
+    ~CopyingOstreamOutputStream() override;
 
     // implements CopyingOutputStream --------------------------------
-    bool Write(const void* buffer, int size);
+    bool Write(const void* buffer, int size) override;
 
    private:
     // The stream.
@@ -304,12 +304,13 @@
   // All streams passed in as well as the array itself must remain valid
   // until the ConcatenatingInputStream is destroyed.
   ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count);
+  ~ConcatenatingInputStream() override = default;
 
   // implements ZeroCopyInputStream ----------------------------------
-  bool Next(const void** data, int* size);
-  void BackUp(int count);
-  bool Skip(int count);
-  int64 ByteCount() const;
+  bool Next(const void** data, int* size) override;
+  void BackUp(int count) override;
+  bool Skip(int count) override;
+  int64 ByteCount() const override;
 
 
  private:
@@ -329,13 +330,13 @@
 class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream {
  public:
   LimitingInputStream(ZeroCopyInputStream* input, int64 limit);
-  ~LimitingInputStream();
+  ~LimitingInputStream() override;
 
   // implements ZeroCopyInputStream ----------------------------------
-  bool Next(const void** data, int* size);
-  void BackUp(int count);
-  bool Skip(int count);
-  int64 ByteCount() const;
+  bool Next(const void** data, int* size) override;
+  void BackUp(int count) override;
+  bool Skip(int count) override;
+  int64 ByteCount() const override;
 
 
  private:
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 29f63bf..38b6cde 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h
+++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h
@@ -70,12 +70,13 @@
   // useful for testing; in production you would probably never want to set
   // it.
   ArrayInputStream(const void* data, int size, int block_size = -1);
+  ~ArrayInputStream() override = default;
 
   // implements ZeroCopyInputStream ----------------------------------
-  bool Next(const void** data, int* size);
-  void BackUp(int count);
-  bool Skip(int count);
-  int64 ByteCount() const;
+  bool Next(const void** data, int* size) override;
+  void BackUp(int count) override;
+  bool Skip(int count) override;
+  int64 ByteCount() const override;
 
 
  private:
@@ -103,11 +104,12 @@
   // useful for testing; in production you would probably never want to set
   // it.
   ArrayOutputStream(void* data, int size, int block_size = -1);
+  ~ArrayOutputStream() override = default;
 
   // implements ZeroCopyOutputStream ---------------------------------
-  bool Next(void** data, int* size);
-  void BackUp(int count);
-  int64 ByteCount() const;
+  bool Next(void** data, int* size) override;
+  void BackUp(int count) override;
+  int64 ByteCount() const override;
 
  private:
   uint8* const data_;        // The byte array.
@@ -136,11 +138,12 @@
   //   the first call to Next() will return at least n bytes of buffer
   //   space.
   explicit StringOutputStream(string* target);
+  ~StringOutputStream() override = default;
 
   // implements ZeroCopyOutputStream ---------------------------------
-  bool Next(void** data, int* size);
-  void BackUp(int count);
-  int64 ByteCount() const;
+  bool Next(void** data, int* size) override;
+  void BackUp(int count) override;
+  int64 ByteCount() const override;
 
  protected:
   void SetString(string* target);
@@ -205,17 +208,17 @@
   // copying_stream unless SetOwnsCopyingStream(true) is called.
   explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream,
                                      int block_size = -1);
-  ~CopyingInputStreamAdaptor();
+  ~CopyingInputStreamAdaptor() override;
 
   // Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to
   // delete the underlying CopyingInputStream when it is destroyed.
   void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
 
   // implements ZeroCopyInputStream ----------------------------------
-  bool Next(const void** data, int* size);
-  void BackUp(int count);
-  bool Skip(int count);
-  int64 ByteCount() const;
+  bool Next(const void** data, int* size) override;
+  void BackUp(int count) override;
+  bool Skip(int count) override;
+  int64 ByteCount() const override;
 
  private:
   // Insures that buffer_ is not NULL.
@@ -288,7 +291,7 @@
   // is used.
   explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream,
                                       int block_size = -1);
-  ~CopyingOutputStreamAdaptor();
+  ~CopyingOutputStreamAdaptor() override;
 
   // Writes all pending data to the underlying stream.  Returns false if a
   // write error occurred on the underlying stream.  (The underlying
@@ -300,9 +303,9 @@
   void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
 
   // implements ZeroCopyOutputStream ---------------------------------
-  bool Next(void** data, int* size);
-  void BackUp(int count);
-  int64 ByteCount() const;
+  bool Next(void** data, int* size) override;
+  void BackUp(int count) override;
+  int64 ByteCount() const override;
 
  private:
   // Write the current buffer, if it is present.
diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h
index 801def9..f170f97 100644
--- a/src/google/protobuf/map_entry.h
+++ b/src/google/protobuf/map_entry.h
@@ -95,6 +95,19 @@
   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>::ValueTypeHandler ValueTypeHandler;
+  size_t SpaceUsedLong() const override {
+    size_t size = sizeof(Derived);
+    size += KeyTypeHandler::SpaceUsedInMapEntryLong(this->key_);
+    size += ValueTypeHandler::SpaceUsedInMapEntryLong(this->value_);
+    return size;
+  }
+
   InternalMetadataWithArena _internal_metadata_;
 
  private:
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index 85a0bed..01c734b 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -177,13 +177,13 @@
 
   // MapEntryImpl is for implementation only and this function isn't called
   // anywhere. Just provide a fake implementation here for MessageLite.
-  string GetTypeName() const { return ""; }
+  string GetTypeName() const override { return ""; }
 
-  void CheckTypeAndMergeFrom(const MessageLite& other) {
+  void CheckTypeAndMergeFrom(const MessageLite& other) override {
     MergeFromInternal(*::google::protobuf::down_cast<const Derived*>(&other));
   }
 
-  bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
+  bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) override {
     uint32 tag;
 
     for (;;) {
@@ -224,7 +224,7 @@
     }
   }
 
-  size_t ByteSizeLong() const {
+  size_t ByteSizeLong() const override {
     size_t size = 0;
     size += has_key() ?
         kTagSize + static_cast<size_t>(KeyTypeHandler::ByteSize(key())) : 0;
@@ -233,13 +233,13 @@
     return size;
   }
 
-  void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const {
+  void SerializeWithCachedSizes(::google::protobuf::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 {
+                                                   ::google::protobuf::uint8* output) const override {
     output = KeyTypeHandler::InternalWriteToArray(kKeyFieldNumber, key(),
                                                   deterministic, output);
     output = ValueTypeHandler::InternalWriteToArray(kValueFieldNumber, value(),
@@ -249,7 +249,7 @@
 
   // Don't override SerializeWithCachedSizesToArray.  Use MessageLite's.
 
-  int GetCachedSize() const {
+  int GetCachedSize() const override {
     int size = 0;
     size += has_key()
         ? static_cast<int>(kTagSize) + KeyTypeHandler::GetCachedSize(key())
@@ -260,25 +260,18 @@
     return size;
   }
 
-  bool IsInitialized() const { return ValueTypeHandler::IsInitialized(value_); }
+  bool IsInitialized() const override { return ValueTypeHandler::IsInitialized(value_); }
 
-  Base* New() const {
+  Base* New() const override {
     Derived* entry = new Derived;
     return entry;
   }
 
-  Base* New(Arena* arena) const {
+  Base* New(Arena* arena) const override {
     Derived* entry = Arena::CreateMessage<Derived>(arena);
     return entry;
   }
 
-  size_t SpaceUsedLong() const {
-    size_t size = sizeof(Derived);
-    size += KeyTypeHandler::SpaceUsedInMapEntryLong(key_);
-    size += ValueTypeHandler::SpaceUsedInMapEntryLong(value_);
-    return size;
-  }
-
  protected:
   // We can't declare this function directly here as it would hide the other
   // overload (const Message&).
@@ -298,7 +291,7 @@
   }
 
  public:
-  void Clear() {
+  void Clear() override {
     KeyTypeHandler::Clear(&key_, GetArenaNoVirtual());
     ValueTypeHandler::ClearMaybeByDefaultEnum(
         &value_, GetArenaNoVirtual(), default_enum_value);
@@ -312,7 +305,7 @@
     ValueTypeHandler::AssignDefaultValue(&d->value_);
   }
 
-  Arena* GetArena() const {
+  Arena* GetArena() const override {
     return GetArenaNoVirtual();
   }
 
@@ -466,8 +459,8 @@
       BaseClass::set_has_key();
       BaseClass::set_has_value();
     }
-    inline const KeyMapEntryAccessorType& key() const { return key_; }
-    inline const ValueMapEntryAccessorType& value() const { return value_; }
+    inline const KeyMapEntryAccessorType &key() const override { return key_; }
+    inline const ValueMapEntryAccessorType& value() const override { return value_; }
 
    private:
     const Key& key_;
diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h
index 494401e..44ca29b 100644
--- a/src/google/protobuf/map_field.h
+++ b/src/google/protobuf/map_field.h
@@ -181,10 +181,10 @@
  public:
   TypeDefinedMapFieldBase() {}
   explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
-  ~TypeDefinedMapFieldBase() {}
-  void MapBegin(MapIterator* map_iter) const;
-  void MapEnd(MapIterator* map_iter) const;
-  bool EqualIterator(const MapIterator& a, const MapIterator& b) const;
+  ~TypeDefinedMapFieldBase() override {}
+  void MapBegin(MapIterator* map_iter) const override;
+  void MapEnd(MapIterator* map_iter) const override;
+  bool EqualIterator(const MapIterator& a, const MapIterator& b) const override;
 
   virtual const Map<Key, T>& GetMap() const = 0;
   virtual Map<Key, T>* MutableMap() = 0;
@@ -194,11 +194,11 @@
       const MapIterator* map_iter) const;
 
  private:
-  void InitializeIterator(MapIterator* map_iter) const;
-  void DeleteIterator(MapIterator* map_iter) const;
+  void InitializeIterator(MapIterator* map_iter) const override;
+  void DeleteIterator(MapIterator* map_iter) const override;
   void CopyIterator(MapIterator* this_iteratorm,
-                    const MapIterator& that_iterator) const;
-  void IncreaseIterator(MapIterator* map_iter) const;
+                    const MapIterator& that_iterator) const override;
+  void IncreaseIterator(MapIterator* map_iter) const override;
 
   virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0;
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeDefinedMapFieldBase);
@@ -243,16 +243,16 @@
       : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {}
 
   // Implement MapFieldBase
-  bool ContainsMapKey(const MapKey& map_key) const;
-  bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val);
-  bool DeleteMapValue(const MapKey& map_key);
+  bool ContainsMapKey(const MapKey& map_key) const override;
+  bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
+  bool DeleteMapValue(const MapKey& map_key) override;
 
-  const Map<Key, T>& GetMap() const {
+  const Map<Key, T>& GetMap() const override {
     MapFieldBase::SyncMapWithRepeatedField();
     return impl_.GetMap();
   }
 
-  Map<Key, T>* MutableMap() {
+  Map<Key, T>* MutableMap() override {
     MapFieldBase::SyncMapWithRepeatedField();
     Map<Key, T>* result = impl_.MutableMap();
     MapFieldBase::SetMapDirty();
@@ -260,7 +260,7 @@
   }
 
   // Convenient methods for generated message implementation.
-  int size() const;
+  int size() const override;
   void Clear();
   void MergeFrom(const MapField& other);
   void Swap(MapField* other);
@@ -285,12 +285,13 @@
   typedef void InternalArenaConstructable_;
   typedef void DestructorSkippable_;
 
-  // Implements MapFieldBase
-  void SyncRepeatedFieldWithMapNoLock() const;
-  void SyncMapWithRepeatedFieldNoLock() const;
-  size_t SpaceUsedExcludingSelfNoLock() const;
 
-  void SetMapIteratorValue(MapIterator* map_iter) const;
+  // Implements MapFieldBase
+  void SyncRepeatedFieldWithMapNoLock() const override;
+  void SyncMapWithRepeatedFieldNoLock() const override;
+  size_t SpaceUsedExcludingSelfNoLock() const override;
+
+  void SetMapIteratorValue(MapIterator* map_iter) const override;
 
   friend class ::google::protobuf::Arena;
   friend class MapFieldStateTest;  // For testing, it needs raw access to impl_
@@ -311,27 +312,27 @@
  public:
   explicit DynamicMapField(const Message* default_entry);
   DynamicMapField(const Message* default_entry, Arena* arena);
-  ~DynamicMapField();
+  ~DynamicMapField() override;
 
   // Implement MapFieldBase
-  bool ContainsMapKey(const MapKey& map_key) const;
-  bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val);
-  bool DeleteMapValue(const MapKey& map_key);
+  bool ContainsMapKey(const MapKey& map_key) const override;
+  bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
+  bool DeleteMapValue(const MapKey& map_key) override;
 
-  const Map<MapKey, MapValueRef>& GetMap() const;
-  Map<MapKey, MapValueRef>* MutableMap();
+  const Map<MapKey, MapValueRef>& GetMap() const override;
+  Map<MapKey, MapValueRef>* MutableMap() override;
 
-  int size() const;
+  int size() const override;
 
  private:
   Map<MapKey, MapValueRef> map_;
   const Message* default_entry_;
 
   // Implements MapFieldBase
-  void SyncRepeatedFieldWithMapNoLock() const;
-  void SyncMapWithRepeatedFieldNoLock() const;
-  size_t SpaceUsedExcludingSelfNoLock() const;
-  void SetMapIteratorValue(MapIterator* map_iter) const;
+  void SyncRepeatedFieldWithMapNoLock() const override;
+  void SyncMapWithRepeatedFieldNoLock() const override;
+  size_t SpaceUsedExcludingSelfNoLock() const override;
+  void SetMapIteratorValue(MapIterator* map_iter) const override;
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMapField);
 };
 
diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc
index 829a60f..51fde2c 100644
--- a/src/google/protobuf/map_test.cc
+++ b/src/google/protobuf/map_test.cc
@@ -3183,7 +3183,7 @@
   tester.SetMapFieldsViaReflection(&message);
 
   string expected_text;
-  GOOGLE_CHECK_OK(File::GetContents(
+  GOOGLE_CHECK_OK(File::GetContentsAsText(
       TestSourceDir() +
           "/google/protobuf/"
           "testdata/map_test_data.txt",
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index 9b75808..a536615 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -269,7 +269,7 @@
   void RegisterType(const Descriptor* descriptor, const Message* prototype);
 
   // implements MessageFactory ---------------------------------------
-  const Message* GetPrototype(const Descriptor* type);
+  const Message* GetPrototype(const Descriptor* type) override;
 
  private:
   // Only written at static init time, so does not require locking.
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index f3d1a58..4bdda3a 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -196,12 +196,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 = 0;
+  virtual 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 {
+  virtual Message* New(::google::protobuf::Arena* arena) const override {
     Message* message = New();
     if (arena != NULL) {
       arena->Own(message);
@@ -233,7 +233,7 @@
 
   // Like FindInitializationErrors, but joins all the strings, delimited by
   // commas, and returns them.
-  string InitializationErrorString() const;
+  string InitializationErrorString() const override;
 
   // Clears all unknown fields from this message and all embedded messages.
   // Normally, if unknown tag numbers are encountered when parsing a message,
@@ -305,13 +305,13 @@
   // These methods are pure-virtual in MessageLite, but Message provides
   // reflection-based default implementations.
 
-  virtual string GetTypeName() const;
-  virtual void Clear();
-  virtual bool IsInitialized() const;
-  virtual void CheckTypeAndMergeFrom(const MessageLite& other);
-  virtual bool MergePartialFromCodedStream(io::CodedInputStream* input);
-  virtual size_t ByteSizeLong() const;
-  virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const;
+  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;
 
  private:
   // This is called only by the default implementation of ByteSize(), to
diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc
index 123b142..65af7ce 100644
--- a/src/google/protobuf/message_lite.cc
+++ b/src/google/protobuf/message_lite.cc
@@ -316,7 +316,11 @@
 }
 
 bool MessageLite::SerializePartialToArray(void* data, int size) const {
-  int byte_size = ByteSizeLong();
+  size_t byte_size = ByteSizeLong();
+  if (byte_size > INT_MAX) {
+    GOOGLE_LOG(ERROR) << "Exceeded maximum protobuf size of 2GB: " << size;
+    return false;
+  }
   if (size < byte_size) return false;
   uint8* start = reinterpret_cast<uint8*>(data);
   uint8* end = SerializeWithCachedSizesToArray(start);
diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h
old mode 100755
new mode 100644
diff --git a/src/google/protobuf/reflection_internal.h b/src/google/protobuf/reflection_internal.h
index fcb4247..840d611 100644
--- a/src/google/protobuf/reflection_internal.h
+++ b/src/google/protobuf/reflection_internal.h
@@ -43,32 +43,32 @@
 // corresponding random-access methods.
 class RandomAccessRepeatedFieldAccessor : public RepeatedFieldAccessor {
  public:
-  virtual ~RandomAccessRepeatedFieldAccessor() {}
+  virtual ~RandomAccessRepeatedFieldAccessor() override {}
 
-  virtual Iterator* BeginIterator(const Field* data) const {
+  virtual Iterator* BeginIterator(const Field* data) const override {
     return PositionToIterator(0);
   }
-  virtual Iterator* EndIterator(const Field* data) const {
+  virtual Iterator* EndIterator(const Field* data) const override {
     return PositionToIterator(this->Size(data));
   }
   virtual Iterator* CopyIterator(const Field* data,
-                                 const Iterator* iterator) const {
+                         const Iterator* iterator) const override {
     return const_cast<Iterator*>(iterator);
   }
   virtual Iterator* AdvanceIterator(const Field* data,
-                                    Iterator* iterator) const {
+                            Iterator* iterator) const override {
     return PositionToIterator(IteratorToPosition(iterator) + 1);
   }
   virtual bool EqualsIterator(const Field* data,
-                              const Iterator* a,
-                              const Iterator* b) const {
+                      const Iterator* a,
+                      const Iterator* b) const override {
     return a == b;
   }
-  virtual void DeleteIterator(const Field* data, Iterator* iterator) const {
+  virtual void DeleteIterator(const Field* data, Iterator* iterator) const override {
   }
   virtual const Value* GetIteratorValue(const Field* data,
-                                        const Iterator* iterator,
-                                        Value* scratch_space) const {
+                                const Iterator* iterator,
+                                Value* scratch_space) const override {
     return Get(data, static_cast<int>(IteratorToPosition(iterator)),
                scratch_space);
   }
@@ -88,30 +88,30 @@
 class RepeatedFieldWrapper : public RandomAccessRepeatedFieldAccessor {
  public:
   RepeatedFieldWrapper() {}
-  virtual ~RepeatedFieldWrapper() {}
-  virtual bool IsEmpty(const Field* data) const {
+  virtual ~RepeatedFieldWrapper() override {}
+  virtual bool IsEmpty(const Field* data) const override {
     return GetRepeatedField(data)->empty();
   }
-  virtual int Size(const Field* data) const {
+  virtual int Size(const Field* data) const override {
     return GetRepeatedField(data)->size();
   }
   virtual const Value* Get(const Field* data, int index,
-                          Value* scratch_space) const {
+                   Value* scratch_space) const override {
     return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space);
   }
-  virtual void Clear(Field* data) const {
+  virtual void Clear(Field* data) const override {
     MutableRepeatedField(data)->Clear();
   }
-  virtual void Set(Field* data, int index, const Value* value) const {
+  virtual 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 {
+  virtual void Add(Field* data, const Value* value) const override {
     MutableRepeatedField(data)->Add(ConvertToT(value));
   }
-  virtual void RemoveLast(Field* data) const {
+  virtual void RemoveLast(Field* data) const override {
     MutableRepeatedField(data)->RemoveLast();
   }
-  virtual void SwapElements(Field* data, int index1, int index2) const {
+  virtual void SwapElements(Field* data, int index1, int index2) const override {
     MutableRepeatedField(data)->SwapElements(index1, index2);
   }
 
@@ -144,31 +144,31 @@
  public:
   RepeatedPtrFieldWrapper() {}
   virtual ~RepeatedPtrFieldWrapper() {}
-  virtual bool IsEmpty(const Field* data) const {
+  virtual bool IsEmpty(const Field* data) const override {
     return GetRepeatedField(data)->empty();
   }
-  virtual int Size(const Field* data) const {
+  virtual int Size(const Field* data) const override {
     return GetRepeatedField(data)->size();
   }
   virtual const Value* Get(const Field* data, int index,
-                           Value* scratch_space) const {
+                   Value* scratch_space) const override {
     return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space);
   }
-  virtual void Clear(Field* data) const {
+  virtual void Clear(Field* data) const override {
     MutableRepeatedField(data)->Clear();
   }
-  virtual void Set(Field* data, int index, const Value* value) const {
+  virtual 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 {
+  virtual 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 {
+  virtual void RemoveLast(Field* data) const override {
     MutableRepeatedField(data)->RemoveLast();
   }
-  virtual void SwapElements(Field* data, int index1, int index2) const {
+  virtual void SwapElements(Field* data, int index1, int index2) const override {
     MutableRepeatedField(data)->SwapElements(index1, index2);
   }
 
@@ -205,38 +205,38 @@
 class MapFieldAccessor : public RandomAccessRepeatedFieldAccessor {
  public:
   MapFieldAccessor() {}
-  virtual ~MapFieldAccessor() {}
-  virtual bool IsEmpty(const Field* data) const {
+  virtual ~MapFieldAccessor() override {}
+  virtual bool IsEmpty(const Field* data) const override {
     return GetRepeatedField(data)->empty();
   }
-  virtual int Size(const Field* data) const {
+  virtual int Size(const Field* data) const override {
     return GetRepeatedField(data)->size();
   }
   virtual const Value* Get(const Field* data, int index,
-                           Value* scratch_space) const {
+                   Value* scratch_space) const override {
     return ConvertFromEntry(GetRepeatedField(data)->Get(index), scratch_space);
   }
-  virtual void Clear(Field* data) const {
+  virtual void Clear(Field* data) const override {
     MutableRepeatedField(data)->Clear();
   }
-  virtual void Set(Field* data, int index, const Value* value) const {
+  virtual 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 {
+  virtual 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 {
+  virtual void RemoveLast(Field* data) const override {
     MutableRepeatedField(data)->RemoveLast();
   }
-  virtual void SwapElements(Field* data, int index1, int index2) const {
+  virtual 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 {
+      Field* other_data) const override {
     GOOGLE_CHECK(this == other_mutator);
     MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
   }
@@ -276,11 +276,11 @@
 
  public:
   RepeatedFieldPrimitiveAccessor() {}
-  virtual ~RepeatedFieldPrimitiveAccessor() {}
+  virtual ~RepeatedFieldPrimitiveAccessor() override {}
   virtual void Swap(
       Field* data,
       const internal::RepeatedFieldAccessor* other_mutator,
-      Field* other_data) const {
+      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,11 +289,11 @@
   }
 
  protected:
-  virtual T ConvertToT(const Value* value) const {
+  virtual T ConvertToT(const Value* value) const override {
     return *static_cast<const T*>(value);
   }
   virtual const Value* ConvertFromT(const T& value,
-                                    Value* scratch_space) const {
+                            Value* scratch_space) const override {
     return static_cast<const Value*>(&value);
   }
 };
@@ -307,11 +307,11 @@
 
  public:
   RepeatedPtrFieldStringAccessor() {}
-  virtual ~RepeatedPtrFieldStringAccessor() {}
+  virtual ~RepeatedPtrFieldStringAccessor() override {}
   virtual void Swap(
       Field* data,
       const internal::RepeatedFieldAccessor* other_mutator,
-      Field* other_data) const {
+      Field* other_data) const override {
     if (this == other_mutator) {
       MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
     } else {
@@ -330,14 +330,14 @@
   }
 
  protected:
-  virtual string* New(const Value*) const {
+  virtual string* New(const Value*) const override {
     return new string();
   }
-  virtual void ConvertToT(const Value* value, string* result) const {
+  virtual void ConvertToT(const Value* value, string* result) const override {
     *result = *static_cast<const string*>(value);
   }
   virtual const Value* ConvertFromT(const string& value,
-                                    Value* scratch_space) const {
+                            Value* scratch_space) const override {
     return static_cast<const Value*>(&value);
   }
 };
@@ -350,24 +350,24 @@
 
  public:
   RepeatedPtrFieldMessageAccessor() {}
-  virtual ~RepeatedPtrFieldMessageAccessor() {}
+  virtual ~RepeatedPtrFieldMessageAccessor() override {}
   virtual void Swap(
       Field* data,
       const internal::RepeatedFieldAccessor* other_mutator,
-      Field* other_data) const {
+      Field* other_data) const override {
     GOOGLE_CHECK(this == other_mutator);
     MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
   }
 
  protected:
-  virtual Message* New(const Value* value) const {
+  virtual Message* New(const Value* value) const override {
     return static_cast<const Message*>(value)->New();
   }
-  virtual void ConvertToT(const Value* value, Message* result) const {
+  virtual void ConvertToT(const Value* value, Message* result) const override {
     result->CopyFrom(*static_cast<const Message*>(value));
   }
   virtual const Value* ConvertFromT(const Message& value,
-                                    Value* scratch_space) const {
+                            Value* scratch_space) const override {
     return static_cast<const Value*>(&value);
   }
 };
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index b47ea99..79682b6 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -466,7 +466,7 @@
  protected:
   template <typename TypeHandler>
   void Add(typename TypeHandler::Type&& value,
-           std::enable_if<TypeHandler::Moveable>* dummy = NULL);
+           typename std::enable_if<TypeHandler::Moveable>::type* dummy = NULL);
 
   template <typename TypeHandler>
   void RemoveLast();
@@ -705,13 +705,13 @@
 // 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<>                                                                 \
+    template<> LIBPROTOBUF_EXPORT                                              \
     TypeName* GenericTypeHandler<TypeName>::NewFromPrototype(                  \
         const TypeName* prototype, google::protobuf::Arena* arena);                      \
-    template<>                                                                 \
+    template<> LIBPROTOBUF_EXPORT                                              \
     google::protobuf::Arena* GenericTypeHandler<TypeName>::GetArena(                     \
         TypeName* value);                                                      \
-    template<>                                                                 \
+    template<> LIBPROTOBUF_EXPORT                                              \
     void* GenericTypeHandler<TypeName>::GetMaybeArenaPointer(                  \
         TypeName* value);
 
@@ -1541,7 +1541,7 @@
 template <typename TypeHandler>
 inline void RepeatedPtrFieldBase::Add(
     typename TypeHandler::Type&& value,
-    std::enable_if<TypeHandler::Moveable>*) {
+    typename std::enable_if<TypeHandler::Moveable>::type*) {
   if (rep_ != NULL && current_size_ < rep_->allocated_size) {
     *cast<TypeHandler>(rep_->elements[current_size_++]) = std::move(value);
     return;
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc
index 739172f..af93e6b 100644
--- a/src/google/protobuf/source_context.pb.cc
+++ b/src/google/protobuf/source_context.pb.cc
@@ -65,14 +65,14 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_SourceContext_default_instance_),
 };
 
-void protobuf_AssignDescriptors() {
+static void protobuf_AssignDescriptors() {
   AddDescriptors();
   AssignDescriptors(
       "google/protobuf/source_context.proto", schemas, file_default_instances, TableStruct::offsets,
       file_level_metadata, NULL, NULL);
 }
 
-void protobuf_AssignDescriptorsOnce() {
+static void protobuf_AssignDescriptorsOnce() {
   static ::google::protobuf::internal::once_flag once;
   ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
 }
@@ -83,7 +83,7 @@
   ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
 }
 
-void AddDescriptorsImpl() {
+static void AddDescriptorsImpl() {
   InitDefaults();
   static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
       "\n$google/protobuf/source_context.proto\022\017"
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc
index 8f2d484..ead8168 100644
--- a/src/google/protobuf/struct.pb.cc
+++ b/src/google/protobuf/struct.pb.cc
@@ -140,14 +140,14 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_ListValue_default_instance_),
 };
 
-void protobuf_AssignDescriptors() {
+static void protobuf_AssignDescriptors() {
   AddDescriptors();
   AssignDescriptors(
       "google/protobuf/struct.proto", schemas, file_default_instances, TableStruct::offsets,
       file_level_metadata, file_level_enum_descriptors, NULL);
 }
 
-void protobuf_AssignDescriptorsOnce() {
+static void protobuf_AssignDescriptorsOnce() {
   static ::google::protobuf::internal::once_flag once;
   ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
 }
@@ -158,7 +158,7 @@
   ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 4);
 }
 
-void AddDescriptorsImpl() {
+static void AddDescriptorsImpl() {
   InitDefaults();
   static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
       "\n\034google/protobuf/struct.proto\022\017google.p"
@@ -277,7 +277,7 @@
   Struct* _this = reinterpret_cast< Struct* >(object);
   (void)_this;
 }
-void Struct::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void Struct::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void Struct::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -730,7 +730,7 @@
   Value* _this = reinterpret_cast< Value* >(object);
   (void)_this;
 }
-void Value::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void Value::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void Value::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -810,7 +810,7 @@
       case 1: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
-          int value;
+          int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
@@ -1225,7 +1225,7 @@
   ListValue* _this = reinterpret_cast< ListValue* >(object);
   (void)_this;
 }
-void ListValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void ListValue::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void ListValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
diff --git a/src/google/protobuf/stubs/bytestream.h b/src/google/protobuf/stubs/bytestream.h
index 86510d1..cfa19f2 100644
--- a/src/google/protobuf/stubs/bytestream.h
+++ b/src/google/protobuf/stubs/bytestream.h
@@ -57,7 +57,6 @@
 #include <google/protobuf/stubs/stringpiece.h>
 
 class CordByteSink;
-class MemBlock;
 
 namespace google {
 namespace protobuf {
@@ -162,7 +161,7 @@
 class LIBPROTOBUF_EXPORT UncheckedArrayByteSink : public ByteSink {
  public:
   explicit UncheckedArrayByteSink(char* dest) : dest_(dest) {}
-  virtual void Append(const char* data, size_t n);
+  virtual void Append(const char* data, size_t n) override;
 
   // Returns the current output pointer so that a caller can see how many bytes
   // were produced.
@@ -190,7 +189,7 @@
 class LIBPROTOBUF_EXPORT CheckedArrayByteSink : public ByteSink {
  public:
   CheckedArrayByteSink(char* outbuf, size_t capacity);
-  virtual void Append(const char* bytes, size_t n);
+  virtual void Append(const char* bytes, size_t n) override;
 
   // Returns the number of bytes actually written to the sink.
   size_t NumberOfBytesWritten() const { return size_; }
@@ -227,7 +226,7 @@
  public:
   explicit GrowingArrayByteSink(size_t estimated_size);
   virtual ~GrowingArrayByteSink();
-  virtual void Append(const char* bytes, size_t n);
+  virtual void Append(const char* bytes, size_t n) override;
 
   // Returns the allocated buffer, and sets nbytes to its size. The caller takes
   // ownership of the buffer and must delete it with delete[].
@@ -256,7 +255,7 @@
 class LIBPROTOBUF_EXPORT StringByteSink : public ByteSink {
  public:
   explicit StringByteSink(string* dest) : dest_(dest) {}
-  virtual void Append(const char* data, size_t n);
+  virtual void Append(const char* data, size_t n) override;
 
  private:
   string* dest_;
@@ -273,7 +272,7 @@
 class LIBPROTOBUF_EXPORT NullByteSink : public ByteSink {
  public:
   NullByteSink() {}
-  virtual void Append(const char *data, size_t n) {}
+  virtual void Append(const char *data, size_t n) override {}
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(NullByteSink);
@@ -296,9 +295,9 @@
  public:
   explicit ArrayByteSource(StringPiece s) : input_(s) {}
 
-  virtual size_t Available() const;
-  virtual StringPiece Peek();
-  virtual void Skip(size_t n);
+  virtual size_t Available() const override;
+  virtual StringPiece Peek() override;
+  virtual void Skip(size_t n) override;
 
  private:
   StringPiece   input_;
@@ -328,13 +327,13 @@
   // Returns at most "limit" bytes from "source".
   LimitByteSource(ByteSource* source, size_t limit);
 
-  virtual size_t Available() const;
-  virtual StringPiece Peek();
-  virtual void Skip(size_t n);
+  virtual size_t Available() const override;
+  virtual StringPiece Peek() override;
+  virtual void Skip(size_t n) override;
 
   // We override CopyTo so that we can forward to the underlying source, in
   // case it has an efficient implementation of CopyTo.
-  virtual void CopyTo(ByteSink* sink, size_t n);
+  virtual void CopyTo(ByteSink* sink, size_t n) override;
 
  private:
   ByteSource* source_;
diff --git a/src/google/protobuf/stubs/callback.h b/src/google/protobuf/stubs/callback.h
index 6888f13..dae972f 100644
--- a/src/google/protobuf/stubs/callback.h
+++ b/src/google/protobuf/stubs/callback.h
@@ -125,7 +125,7 @@
     : function_(function), self_deleting_(self_deleting) {}
   ~FunctionClosure0();
 
-  void Run() {
+  void Run() override {
     bool needs_delete = self_deleting_;  // read in case callback deletes
     function_();
     if (needs_delete) delete this;
@@ -145,7 +145,7 @@
     : object_(object), method_(method), self_deleting_(self_deleting) {}
   ~MethodClosure0() {}
 
-  void Run() {
+  void Run() override {
     bool needs_delete = self_deleting_;  // read in case callback deletes
     (object_->*method_)();
     if (needs_delete) delete this;
@@ -168,7 +168,7 @@
       arg1_(arg1) {}
   ~FunctionClosure1() {}
 
-  void Run() {
+  void Run() override {
     bool needs_delete = self_deleting_;  // read in case callback deletes
     function_(arg1_);
     if (needs_delete) delete this;
@@ -191,7 +191,7 @@
       arg1_(arg1) {}
   ~MethodClosure1() {}
 
-  void Run() {
+  void Run() override {
     bool needs_delete = self_deleting_;  // read in case callback deletes
     (object_->*method_)(arg1_);
     if (needs_delete) delete this;
@@ -215,7 +215,7 @@
       arg1_(arg1), arg2_(arg2) {}
   ~FunctionClosure2() {}
 
-  void Run() {
+  void Run() override {
     bool needs_delete = self_deleting_;  // read in case callback deletes
     function_(arg1_, arg2_);
     if (needs_delete) delete this;
@@ -239,7 +239,7 @@
       arg1_(arg1), arg2_(arg2) {}
   ~MethodClosure2() {}
 
-  void Run() {
+  void Run() override {
     bool needs_delete = self_deleting_;  // read in case callback deletes
     (object_->*method_)(arg1_, arg2_);
     if (needs_delete) delete this;
@@ -262,7 +262,7 @@
       : function_(function), self_deleting_(self_deleting) {}
   ~FunctionResultCallback_0_0() {}
 
-  R Run() {
+  R Run() override {
     bool needs_delete = self_deleting_;  // read in case callback deletes
     R result = function_();
     if (needs_delete) delete this;
@@ -284,7 +284,7 @@
       : function_(function), self_deleting_(self_deleting), p1_(p1) {}
   ~FunctionResultCallback_1_0() {}
 
-  R Run() {
+  R Run() override {
     bool needs_delete = self_deleting_;  // read in case callback deletes
     R result = function_(p1_);
     if (needs_delete) delete this;
@@ -306,7 +306,7 @@
       : function_(function), self_deleting_(self_deleting) {}
   ~FunctionResultCallback_0_1() {}
 
-  R Run(Arg1 a1) {
+  R Run(Arg1 a1) override {
     bool needs_delete = self_deleting_;  // read in case callback deletes
     R result = function_(a1);
     if (needs_delete) delete this;
@@ -328,7 +328,7 @@
       : function_(function), self_deleting_(self_deleting), p1_(p1) {}
   ~FunctionResultCallback_1_1() {}
 
-  R Run(A1 a1) {
+  R Run(A1 a1) override {
     bool needs_delete = self_deleting_;  // read in case callback deletes
     R result = function_(p1_, a1);
     if (needs_delete) delete this;
@@ -387,7 +387,7 @@
         p5_(p5) {}
   ~MethodResultCallback_5_2() {}
 
-  R Run(A1 a1, A2 a2) {
+  R Run(A1 a1, A2 a2) override {
     bool needs_delete = self_deleting_;
     R result = (object_->*method_)(p1_, p2_, p3_, p4_, p5_, a1, a2);
     if (needs_delete) delete this;
diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc
old mode 100755
new mode 100644
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index d35377a..585e012 100644
--- a/src/google/protobuf/stubs/common.h
+++ b/src/google/protobuf/stubs/common.h
@@ -206,7 +206,7 @@
 
 template <typename T>
 T* OnShutdownDelete(T* p) {
-  OnShutdownRun([](const void* p) { delete static_cast<const T*>(p); }, p);
+  OnShutdownRun([](const void* pp) { delete static_cast<const T*>(pp); }, p);
   return p;
 }
 
diff --git a/src/google/protobuf/stubs/int128.cc b/src/google/protobuf/stubs/int128.cc
index a509080..7b993e8 100644
--- a/src/google/protobuf/stubs/int128.cc
+++ b/src/google/protobuf/stubs/int128.cc
@@ -76,52 +76,36 @@
   return Fls64(Uint128Low64(n));
 }
 
-// Long division/modulo for uint128 implemented using the shift-subtract
-// division algorithm adapted from:
-// http://stackoverflow.com/questions/5386377/division-without-using
 void uint128::DivModImpl(uint128 dividend, uint128 divisor,
                          uint128* quotient_ret, uint128* remainder_ret) {
   if (divisor == 0) {
     GOOGLE_LOG(FATAL) << "Division or mod by zero: dividend.hi=" << dividend.hi_
                       << ", lo=" << dividend.lo_;
-  }
-
-  if (divisor > dividend) {
+  } else if (dividend < divisor) {
     *quotient_ret = 0;
     *remainder_ret = dividend;
     return;
-  }
-
-  if (divisor == dividend) {
-    *quotient_ret = 1;
-    *remainder_ret = 0;
-    return;
-  }
-
-  uint128 denominator = divisor;
-  uint128 position = 1;
-  uint128 quotient = 0;
-
-  // Left aligns the MSB of the denominator and the dividend.
-  int shift = Fls128(dividend) - Fls128(denominator);
-  denominator <<= shift;
-  position <<= shift;
-
-  // Uses shift-subtract algorithm to divide dividend by denominator. The
-  // remainder will be left in dividend.
-  while (position > 0) {
-    if (dividend >= denominator) {
-      dividend -= denominator;
-      quotient |= position;
+  } else {
+    int dividend_bit_length = Fls128(dividend);
+    int divisor_bit_length = Fls128(divisor);
+    int difference = dividend_bit_length - divisor_bit_length;
+    uint128 quotient = 0;
+    while (difference >= 0) {
+      quotient <<= 1;
+      uint128 shifted_divisor = divisor << difference;
+      if (shifted_divisor <= dividend) {
+        dividend -= shifted_divisor;
+        quotient += 1;
+      }
+      difference -= 1;
     }
-    position >>= 1;
-    denominator >>= 1;
+    //record the final quotient and remainder
+    *quotient_ret = quotient;
+    *remainder_ret = dividend;
   }
-
-  *quotient_ret = quotient;
-  *remainder_ret = dividend;
 }
 
+
 uint128& uint128::operator/=(const uint128& divisor) {
   uint128 quotient = 0;
   uint128 remainder = 0;
diff --git a/src/google/protobuf/stubs/mutex.h b/src/google/protobuf/stubs/mutex.h
index b9b7d2e..47edb7a 100644
--- a/src/google/protobuf/stubs/mutex.h
+++ b/src/google/protobuf/stubs/mutex.h
@@ -34,6 +34,18 @@
 
 #include <google/protobuf/stubs/macros.h>
 
+// Define thread-safety annotations for use below, if we are building with
+// Clang.
+#if defined(__clang__) && !defined(SWIG)
+#define GOOGLE_PROTOBUF_ACQUIRE(...) \
+  __attribute__((acquire_capability(__VA_ARGS__)))
+#define GOOGLE_PROTOBUF_RELEASE(...) \
+  __attribute__((release_capability(__VA_ARGS__)))
+#else
+#define GOOGLE_PROTOBUF_ACQUIRE(...)
+#define GOOGLE_PROTOBUF_RELEASE(...)
+#endif
+
 // ===================================================================
 // emulates google3/base/mutex.h
 namespace google {
@@ -48,8 +60,8 @@
 class LIBPROTOBUF_EXPORT WrappedMutex {
  public:
   WrappedMutex() = default;
-  void Lock() { mu_.lock(); }
-  void Unlock() { mu_.unlock(); }
+  void Lock() GOOGLE_PROTOBUF_ACQUIRE() { mu_.lock(); }
+  void Unlock() GOOGLE_PROTOBUF_RELEASE() { mu_.unlock(); }
   // Crash if this Mutex is not held exclusively by this thread.
   // May fail to crash when it should; will never crash when it should not.
   void AssertHeld() const {}
@@ -123,8 +135,10 @@
 using internal::WriterMutexLock;
 using internal::MutexLockMaybe;
 
-
 }  // namespace protobuf
 }  // namespace google
 
+#undef GOOGLE_PROTOBUF_ACQUIRE
+#undef GOOGLE_PROTOBUF_RELEASE
+
 #endif  // GOOGLE_PROTOBUF_STUBS_MUTEX_H_
diff --git a/src/google/protobuf/stubs/platform_macros.h b/src/google/protobuf/stubs/platform_macros.h
index c3a64dd..ce1b1e3 100644
--- a/src/google/protobuf/stubs/platform_macros.h
+++ b/src/google/protobuf/stubs/platform_macros.h
@@ -56,7 +56,7 @@
 #elif defined(__aarch64__)
 #define GOOGLE_PROTOBUF_ARCH_AARCH64 1
 #define GOOGLE_PROTOBUF_ARCH_64_BIT 1
-#elif defined(__MIPSEL__)
+#elif defined(__mips__)
 #if defined(__LP64__)
 #define GOOGLE_PROTOBUF_ARCH_MIPS64 1
 #define GOOGLE_PROTOBUF_ARCH_64_BIT 1
@@ -99,6 +99,7 @@
 
 #if defined(__APPLE__)
 #define GOOGLE_PROTOBUF_OS_APPLE
+#include <Availability.h>
 #include <TargetConditionals.h>
 #if TARGET_OS_IPHONE
 #define GOOGLE_PROTOBUF_OS_IPHONE
@@ -125,4 +126,9 @@
 #define GOOGLE_PROTOBUF_NO_THREADLOCAL
 #endif
 
+#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1070
+// __thread keyword requires at least 10.7
+#define GOOGLE_PROTOBUF_NO_THREADLOCAL
+#endif
+
 #endif  // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h
index 6b52305..3aa6403 100644
--- a/src/google/protobuf/stubs/port.h
+++ b/src/google/protobuf/stubs/port.h
@@ -382,10 +382,14 @@
 
 #elif !defined(__GLIBC__) && !defined(__BIONIC__) && !defined(__CYGWIN__)
 
+#ifndef bswap_16
 static inline uint16 bswap_16(uint16 x) {
   return static_cast<uint16>(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8));
 }
 #define bswap_16(x) bswap_16(x)
+#endif
+
+#ifndef bswap_32
 static inline uint32 bswap_32(uint32 x) {
   return (((x & 0xFF) << 24) |
           ((x & 0xFF00) << 8) |
@@ -393,6 +397,9 @@
           ((x & 0xFF000000) >> 24));
 }
 #define bswap_32(x) bswap_32(x)
+#endif
+
+#ifndef bswap_64
 static inline uint64 bswap_64(uint64 x) {
   return (((x & GOOGLE_ULONGLONG(0xFF)) << 56) |
           ((x & GOOGLE_ULONGLONG(0xFF00)) << 40) |
@@ -404,6 +411,7 @@
           ((x & GOOGLE_ULONGLONG(0xFF00000000000000)) >> 56));
 }
 #define bswap_64(x) bswap_64(x)
+#endif
 
 #endif
 
diff --git a/src/google/protobuf/testing/file.cc b/src/google/protobuf/testing/file.cc
index 26cb0a6..def92a0 100644
--- a/src/google/protobuf/testing/file.cc
+++ b/src/google/protobuf/testing/file.cc
@@ -69,9 +69,9 @@
   return access(name.c_str(), F_OK) == 0;
 }
 
-bool File::ReadFileToString(const string& name, string* output) {
+bool File::ReadFileToString(const string& name, string* output, bool text_mode) {
   char buffer[1024];
-  FILE* file = fopen(name.c_str(), "rb");
+  FILE* file = fopen(name.c_str(), text_mode ? "rt" : "rb");
   if (file == NULL) return false;
 
   while (true) {
diff --git a/src/google/protobuf/testing/file.h b/src/google/protobuf/testing/file.h
index 2f63f80..4598996 100644
--- a/src/google/protobuf/testing/file.h
+++ b/src/google/protobuf/testing/file.h
@@ -50,7 +50,7 @@
 
   // Read an entire file to a string.  Return true if successful, false
   // otherwise.
-  static bool ReadFileToString(const string& name, string* output);
+  static bool ReadFileToString(const string& name, string* output, bool text_mode = false);
 
   // Same as above, but crash on failure.
   static void ReadFileToStringOrDie(const string& name, string* output);
@@ -85,6 +85,11 @@
     return ReadFileToString(name, output);
   }
 
+  static bool GetContentsAsText(
+      const string& name, string* output, bool /*is_default*/) {
+    return ReadFileToString(name, output, true);
+  }
+
   static bool SetContents(
       const string& name, const string& contents, bool /*is_default*/) {
     return WriteStringToFile(contents, name);
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
index 0965fd7..a9c062e 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -1138,13 +1138,13 @@
     explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) :
         parser_(parser) { }
 
-    virtual ~ParserErrorCollector() { }
+    ~ParserErrorCollector() override { }
 
-    virtual void AddError(int line, int column, const string& message) {
+    void AddError(int line, int column, const string& message) override {
       parser_->ReportError(line, column, message);
     }
 
-    virtual void AddWarning(int line, int column, const string& message) {
+    void AddWarning(int line, int column, const string& message) override {
       parser_->ReportWarning(line, column, message);
     }
 
@@ -1444,7 +1444,7 @@
 // A BaseTextGenerator that writes to a string.
 class StringBaseTextGenerator : public TextFormat::BaseTextGenerator {
  public:
-  void Print(const char* text, size_t size) { 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,37 +1642,37 @@
     delegate_.reset(delegate);
   }
 
-  void PrintBool(bool val, TextFormat::BaseTextGenerator* generator) const {
+  void PrintBool(bool val, TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintBool(val));
   }
-  void PrintInt32(int32 val, TextFormat::BaseTextGenerator* generator) const {
+  void PrintInt32(int32 val, TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintInt32(val));
   }
-  void PrintUInt32(uint32 val, TextFormat::BaseTextGenerator* generator) const {
+  void PrintUInt32(uint32 val, TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintUInt32(val));
   }
-  void PrintInt64(int64 val, TextFormat::BaseTextGenerator* generator) const {
+  void PrintInt64(int64 val, TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintInt64(val));
   }
-  void PrintUInt64(uint64 val, TextFormat::BaseTextGenerator* generator) const {
+  void PrintUInt64(uint64 val, TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintUInt64(val));
   }
-  void PrintFloat(float val, TextFormat::BaseTextGenerator* generator) const {
+  void PrintFloat(float val, TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintFloat(val));
   }
-  void PrintDouble(double val, TextFormat::BaseTextGenerator* generator) const {
+  void PrintDouble(double val, TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintDouble(val));
   }
   void PrintString(const string& val,
-                   TextFormat::BaseTextGenerator* generator) const {
+                   TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintString(val));
   }
   void PrintBytes(const string& val,
-                  TextFormat::BaseTextGenerator* generator) const {
+                  TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintBytes(val));
   }
   void PrintEnum(int32 val, const string& name,
-                 TextFormat::BaseTextGenerator* generator) const {
+                 TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintEnum(val, name));
   }
   void PrintFieldName(const Message& message, int field_index, int field_count,
@@ -1684,19 +1684,19 @@
   }
   void PrintFieldName(const Message& message, const Reflection* reflection,
                       const FieldDescriptor* field,
-                      TextFormat::BaseTextGenerator* generator) const {
+                      TextFormat::BaseTextGenerator* generator) const override {
     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 {
+                         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 {
+                       TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintString(delegate_->PrintMessageEnd(
         message, field_index, field_count, single_line_mode));
   }
@@ -1710,13 +1710,13 @@
     : public TextFormat::FastFieldValuePrinter {
  public:
   void PrintString(const string& val,
-                   TextFormat::BaseTextGenerator* generator) const {
+                   TextFormat::BaseTextGenerator* generator) const override {
     generator->PrintLiteral("\"");
     generator->PrintString(strings::Utf8SafeCEscape(val));
     generator->PrintLiteral("\"");
   }
   void PrintBytes(const string& val,
-                  TextFormat::BaseTextGenerator* generator) const {
+                  TextFormat::BaseTextGenerator* generator) const override {
     return FastFieldValuePrinter::PrintString(val, generator);
   }
 };
diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc
index 544c37e..b0ea578 100644
--- a/src/google/protobuf/text_format_unittest.cc
+++ b/src/google/protobuf/text_format_unittest.cc
@@ -77,7 +77,7 @@
 class TextFormatTest : public testing::Test {
  public:
   static void SetUpTestCase() {
-    GOOGLE_CHECK_OK(File::GetContents(
+    GOOGLE_CHECK_OK(File::GetContentsAsText(
         TestSourceDir() +
             "/google/protobuf/"
             "testdata/text_format_unittest_data_oneof_implemented.txt",
@@ -99,7 +99,7 @@
 class TextFormatExtensionsTest : public testing::Test {
  public:
   static void SetUpTestCase() {
-    GOOGLE_CHECK_OK(File::GetContents(TestSourceDir() +
+    GOOGLE_CHECK_OK(File::GetContentsAsText(TestSourceDir() +
                                    "/google/protobuf/testdata/"
                                    "text_format_unittest_extensions_data.txt",
                                &static_proto_debug_string_, true));
@@ -574,6 +574,11 @@
       generator->PrintString(field->name());
     }
   }
+  // To prevent compiler complaining about Woverloaded-virtual
+  void PrintFieldName(const Message& message,
+                      const Reflection* reflection,
+                      const FieldDescriptor* field,
+                      TextFormat::BaseTextGenerator* generator) const override {}
   void PrintMessageStart(
       const Message& message, int field_index, int field_count,
       bool single_line_mode,
diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc
index 8e6b5f2..4269031 100644
--- a/src/google/protobuf/timestamp.pb.cc
+++ b/src/google/protobuf/timestamp.pb.cc
@@ -66,14 +66,14 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Timestamp_default_instance_),
 };
 
-void protobuf_AssignDescriptors() {
+static void protobuf_AssignDescriptors() {
   AddDescriptors();
   AssignDescriptors(
       "google/protobuf/timestamp.proto", schemas, file_default_instances, TableStruct::offsets,
       file_level_metadata, NULL, NULL);
 }
 
-void protobuf_AssignDescriptorsOnce() {
+static void protobuf_AssignDescriptorsOnce() {
   static ::google::protobuf::internal::once_flag once;
   ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
 }
@@ -84,7 +84,7 @@
   ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1);
 }
 
-void AddDescriptorsImpl() {
+static void AddDescriptorsImpl() {
   InitDefaults();
   static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
       "\n\037google/protobuf/timestamp.proto\022\017googl"
@@ -167,7 +167,7 @@
   Timestamp* _this = reinterpret_cast< Timestamp* >(object);
   (void)_this;
 }
-void Timestamp::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void Timestamp::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void Timestamp::SetCachedSize(int size) const {
   _cached_size_.Set(size);
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc
index 130af52..72679df 100644
--- a/src/google/protobuf/type.pb.cc
+++ b/src/google/protobuf/type.pb.cc
@@ -219,14 +219,14 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Option_default_instance_),
 };
 
-void protobuf_AssignDescriptors() {
+static void protobuf_AssignDescriptors() {
   AddDescriptors();
   AssignDescriptors(
       "google/protobuf/type.proto", schemas, file_default_instances, TableStruct::offsets,
       file_level_metadata, file_level_enum_descriptors, NULL);
 }
 
-void protobuf_AssignDescriptorsOnce() {
+static void protobuf_AssignDescriptorsOnce() {
   static ::google::protobuf::internal::once_flag once;
   ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
 }
@@ -237,7 +237,7 @@
   ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 5);
 }
 
-void AddDescriptorsImpl() {
+static void AddDescriptorsImpl() {
   InitDefaults();
   static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
       "\n\032google/protobuf/type.proto\022\017google.pro"
@@ -492,7 +492,7 @@
   Type* _this = reinterpret_cast< Type* >(object);
   (void)_this;
 }
-void Type::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void Type::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void Type::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -609,7 +609,7 @@
       case 6: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) {
-          int value;
+          int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
@@ -1014,7 +1014,7 @@
   Field* _this = reinterpret_cast< Field* >(object);
   (void)_this;
 }
-void Field::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void Field::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void Field::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -1061,7 +1061,7 @@
       case 1: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) {
-          int value;
+          int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
@@ -1076,7 +1076,7 @@
       case 2: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) {
-          int value;
+          int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
@@ -1698,7 +1698,7 @@
   Enum* _this = reinterpret_cast< Enum* >(object);
   (void)_this;
 }
-void Enum::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void Enum::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void Enum::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -1797,7 +1797,7 @@
       case 5: {
         if (static_cast< ::google::protobuf::uint8>(tag) ==
             static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) {
-          int value;
+          int value = 0;
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
@@ -2140,7 +2140,7 @@
   EnumValue* _this = reinterpret_cast< EnumValue* >(object);
   (void)_this;
 }
-void EnumValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void EnumValue::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void EnumValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -2520,7 +2520,7 @@
   Option* _this = reinterpret_cast< Option* >(object);
   (void)_this;
 }
-void Option::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void Option::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void Option::SetCachedSize(int size) const {
   _cached_size_.Set(size);
diff --git a/src/google/protobuf/util/field_comparator.h b/src/google/protobuf/util/field_comparator.h
index 27ef4c7..63e89fb 100644
--- a/src/google/protobuf/util/field_comparator.h
+++ b/src/google/protobuf/util/field_comparator.h
@@ -110,14 +110,14 @@
   // Creates new comparator with float comparison set to EXACT.
   DefaultFieldComparator();
 
-  virtual ~DefaultFieldComparator();
+  ~DefaultFieldComparator() override;
 
-  virtual ComparisonResult Compare(
+  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);
+      const google::protobuf::util::FieldContext* field_context) override;
 
   void set_float_comparison(FloatComparison float_comparison) {
     float_comparison_ = float_comparison;
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h
index 6e71f9c..7d245c9 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.h
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.h
@@ -83,37 +83,37 @@
   virtual ~DefaultValueObjectWriter();
 
   // ObjectWriter methods.
-  virtual DefaultValueObjectWriter* StartObject(StringPiece name);
+  virtual DefaultValueObjectWriter* StartObject(StringPiece name) override;
 
-  virtual DefaultValueObjectWriter* EndObject();
+  virtual DefaultValueObjectWriter* EndObject() override;
 
-  virtual DefaultValueObjectWriter* StartList(StringPiece name);
+  virtual DefaultValueObjectWriter* StartList(StringPiece name) override;
 
-  virtual DefaultValueObjectWriter* EndList();
+  virtual DefaultValueObjectWriter* EndList() override;
 
-  virtual DefaultValueObjectWriter* RenderBool(StringPiece name, bool value);
+  virtual DefaultValueObjectWriter* RenderBool(StringPiece name, bool value) override;
 
-  virtual DefaultValueObjectWriter* RenderInt32(StringPiece name, int32 value);
+  virtual DefaultValueObjectWriter* RenderInt32(StringPiece name, int32 value) override;
 
   virtual DefaultValueObjectWriter* RenderUint32(StringPiece name,
-                                                 uint32 value);
+                                         uint32 value) override;
 
-  virtual DefaultValueObjectWriter* RenderInt64(StringPiece name, int64 value);
+  virtual DefaultValueObjectWriter* RenderInt64(StringPiece name, int64 value) override;
 
   virtual DefaultValueObjectWriter* RenderUint64(StringPiece name,
-                                                 uint64 value);
+                                         uint64 value) override;
 
   virtual DefaultValueObjectWriter* RenderDouble(StringPiece name,
-                                                 double value);
+                                         double value) override;
 
-  virtual DefaultValueObjectWriter* RenderFloat(StringPiece name, float value);
+  virtual DefaultValueObjectWriter* RenderFloat(StringPiece name, float value) override;
 
   virtual DefaultValueObjectWriter* RenderString(StringPiece name,
-                                                 StringPiece value);
+                                         StringPiece value) override;
   virtual DefaultValueObjectWriter* RenderBytes(StringPiece name,
-                                                StringPiece value);
+                                        StringPiece value) override;
 
-  virtual DefaultValueObjectWriter* RenderNull(StringPiece name);
+  virtual DefaultValueObjectWriter* RenderNull(StringPiece name) override;
 
   // Register the callback for scrubbing of fields. Owership of
   // field_scrub_callback pointer is also transferred to this class
diff --git a/src/google/protobuf/util/internal/error_listener.h b/src/google/protobuf/util/internal/error_listener.h
index a19bd3f..e3baa22 100644
--- a/src/google/protobuf/util/internal/error_listener.h
+++ b/src/google/protobuf/util/internal/error_listener.h
@@ -76,16 +76,16 @@
 class LIBPROTOBUF_EXPORT NoopErrorListener : public ErrorListener {
  public:
   NoopErrorListener() {}
-  virtual ~NoopErrorListener() {}
+  virtual ~NoopErrorListener() override {}
 
   virtual void InvalidName(const LocationTrackerInterface& loc,
-                           StringPiece invalid_name, StringPiece message) {}
+                           StringPiece invalid_name, StringPiece message) override {}
 
-  virtual void InvalidValue(const LocationTrackerInterface& loc,
-                            StringPiece type_name, StringPiece value) {}
+  virtual void InvalidValue(const LocationTrackerInterface &loc, StringPiece type_name,
+                    StringPiece value) override {}
 
-  virtual void MissingField(const LocationTrackerInterface& loc,
-                            StringPiece missing_name) {}
+  virtual void MissingField(const LocationTrackerInterface &loc,
+                    StringPiece missing_name) override {}
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(NoopErrorListener);
diff --git a/src/google/protobuf/util/internal/json_objectwriter.h b/src/google/protobuf/util/internal/json_objectwriter.h
index 81644da..4c25b46 100644
--- a/src/google/protobuf/util/internal/json_objectwriter.h
+++ b/src/google/protobuf/util/internal/json_objectwriter.h
@@ -94,20 +94,20 @@
   virtual ~JsonObjectWriter();
 
   // ObjectWriter methods.
-  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* 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* RenderNullAsEmpty(StringPiece name);
 
   void set_use_websafe_base64_for_bytes(bool value) {
@@ -143,17 +143,17 @@
     GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(Element);
   };
 
-  virtual Element* element() { return element_.get(); }
+  Element* element() override { return element_.get(); }
 
  private:
   class LIBPROTOBUF_EXPORT ByteSinkWrapper : public strings::ByteSink {
    public:
     explicit ByteSinkWrapper(google::protobuf::io::CodedOutputStream* stream)
         : stream_(stream) {}
-    virtual ~ByteSinkWrapper() {}
+    ~ByteSinkWrapper() override {}
 
     // ByteSink methods.
-    virtual void Append(const char* bytes, size_t n) {
+    void Append(const char* bytes, size_t n) override {
       stream_->WriteRaw(bytes, n);
     }
 
diff --git a/src/google/protobuf/util/internal/object_location_tracker.h b/src/google/protobuf/util/internal/object_location_tracker.h
index 8586cec..f9b90bc 100644
--- a/src/google/protobuf/util/internal/object_location_tracker.h
+++ b/src/google/protobuf/util/internal/object_location_tracker.h
@@ -47,10 +47,10 @@
   // Creates an empty location tracker.
   ObjectLocationTracker() {}
 
-  virtual ~ObjectLocationTracker() {}
+  ~ObjectLocationTracker() override {}
 
   // Returns empty because nothing is tracked.
-  virtual string ToString() const { return ""; }
+  string ToString() const override { return ""; }
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjectLocationTracker);
diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h
index 2849696..5bdafcc 100644
--- a/src/google/protobuf/util/internal/proto_writer.h
+++ b/src/google/protobuf/util/internal/proto_writer.h
@@ -78,7 +78,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();
+  virtual ~ProtoWriter() override;
 
   // ObjectWriter methods.
   ProtoWriter* StartObject(StringPiece name) override;
@@ -110,7 +110,7 @@
     return RenderDataPiece(name,
                            DataPiece(value, use_strict_base64_decoding()));
   }
-  virtual ProtoWriter* RenderBytes(StringPiece name, StringPiece value) {
+  ProtoWriter* RenderBytes(StringPiece name, StringPiece value) override {
     return RenderDataPiece(
         name, DataPiece(value, false, use_strict_base64_decoding()));
   }
@@ -163,7 +163,7 @@
     ProtoElement(ProtoElement* parent, const google::protobuf::Field* field,
                  const google::protobuf::Type& type, bool is_list);
 
-    virtual ~ProtoElement() {}
+    virtual ~ProtoElement() override {}
 
     // Called just before the destructor for clean up:
     //   - reports any missing required fields
@@ -183,9 +183,9 @@
     void RegisterField(const google::protobuf::Field* field);
 
     // To report location on error messages.
-    virtual string ToString() const;
+    virtual string ToString() const override;
 
-    virtual ProtoElement* parent() const {
+    virtual ProtoElement* parent() const override {
       return static_cast<ProtoElement*>(BaseElement::parent());
     }
 
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc
index 56e6db1..b0d86c1 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource.cc
@@ -648,6 +648,13 @@
   // using a nested ProtoStreamObjectSource using our nested type information.
   ProtoStreamObjectSource nested_os(&in_stream, os->typeinfo_, *nested_type);
 
+  // TODO(htuch): This is somewhat fragile, since new options may be omitted.
+  // We should probably do this via the constructor or some object grouping
+  // options.
+  nested_os.set_use_lower_camel_for_enums(os->use_lower_camel_for_enums_);
+  nested_os.set_use_ints_for_enums(os->use_ints_for_enums_);
+  nested_os.set_preserve_proto_field_names(os->preserve_proto_field_names_);
+
   // We manually call start and end object here so we can inject the @type.
   ow->StartObject(field_name);
   ow->RenderString("@type", type_url);
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h
index b56efdf..acd081d 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.h
+++ b/src/google/protobuf/util/internal/protostream_objectsource.h
@@ -78,9 +78,9 @@
                           TypeResolver* type_resolver,
                           const google::protobuf::Type& type);
 
-  virtual ~ProtoStreamObjectSource();
+  virtual ~ProtoStreamObjectSource() override;
 
-  virtual util::Status NamedWriteTo(StringPiece name, ObjectWriter* ow) const;
+  virtual 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.
diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
index df79072..4d86b85 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
@@ -100,6 +100,7 @@
         ow_(&mock_),
         use_lower_camel_for_enums_(false),
         use_ints_for_enums_(false),
+        use_preserve_proto_field_names_(false),
         add_trailing_zeros_(false),
         render_unknown_enum_values_(true) {
     helper_.ResetTypeInfo(Book::descriptor(), Proto3Message::descriptor());
@@ -123,6 +124,7 @@
         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);
     os->set_max_recursion_depth(64);
     return os->WriteTo(&mock_);
   }
@@ -272,6 +274,8 @@
 
   void UseIntsForEnums() { use_ints_for_enums_ = true; }
 
+  void UsePreserveProtoFieldNames() { use_preserve_proto_field_names_ = true; }
+
   void AddTrailingZeros() { add_trailing_zeros_ = true; }
 
   void SetRenderUnknownEnumValues(bool value) {
@@ -284,6 +288,7 @@
   ExpectingObjectWriter ow_;
   bool use_lower_camel_for_enums_;
   bool use_ints_for_enums_;
+  bool use_preserve_proto_field_names_;
   bool add_trailing_zeros_;
   bool render_unknown_enum_values_;
 };
@@ -536,6 +541,16 @@
   DoTest(book, Book::descriptor());
 }
 
+TEST_P(ProtostreamObjectSourceTest, UsePreserveProtoFieldNames) {
+  Book book;
+  book.set_snake_field("foo");
+
+  UsePreserveProtoFieldNames();
+
+  ow_.StartObject("")->RenderString("snake_field", "foo")->EndObject();
+  DoTest(book, Book::descriptor());
+}
+
 TEST_P(ProtostreamObjectSourceTest,
        UnknownEnumAreDroppedWhenRenderUnknownEnumValuesIsUnset) {
   Proto3Message message;
@@ -769,6 +784,69 @@
   DoTest(out, AnyOut::descriptor());
 }
 
+TEST_P(ProtostreamObjectSourceAnysTest, LowerCamelEnumOutputSnakeCase) {
+  AnyOut out;
+  ::google::protobuf::Any* any = out.mutable_any();
+
+  Book book;
+  book.set_type(Book::arts_and_photography);
+  any->PackFrom(book);
+
+  UseLowerCamelForEnums();
+
+  ow_.StartObject("")
+      ->StartObject("any")
+      ->RenderString("@type",
+                     "type.googleapis.com/google.protobuf.testing.Book")
+      ->RenderString("type", "artsAndPhotography")
+      ->EndObject()
+      ->EndObject();
+
+  DoTest(out, AnyOut::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceAnysTest, UseIntsForEnumsTest) {
+  AnyOut out;
+  ::google::protobuf::Any* any = out.mutable_any();
+
+  Book book;
+  book.set_type(Book::ACTION_AND_ADVENTURE);
+  any->PackFrom(book);
+
+  UseIntsForEnums();
+
+  ow_.StartObject("")
+      ->StartObject("any")
+      ->RenderString("@type",
+                     "type.googleapis.com/google.protobuf.testing.Book")
+      ->RenderInt32("type", 3)
+      ->EndObject()
+      ->EndObject();
+
+  DoTest(out, AnyOut::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceAnysTest, UsePreserveProtoFieldNames) {
+  AnyOut out;
+  ::google::protobuf::Any* any = out.mutable_any();
+
+  Book book;
+  book.set_snake_field("foo");
+  any->PackFrom(book);
+
+  UsePreserveProtoFieldNames();
+
+  ow_.StartObject("")
+      ->StartObject("any")
+      ->RenderString("@type",
+                     "type.googleapis.com/google.protobuf.testing.Book")
+      ->RenderString("snake_field", "foo")
+      ->EndObject()
+      ->EndObject();
+
+  DoTest(out, AnyOut::descriptor());
+}
+
 TEST_P(ProtostreamObjectSourceAnysTest, RecursiveAny) {
   AnyOut out;
   ::google::protobuf::Any* any = out.mutable_any();
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc
index 2edfd07..a1a7030 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -534,7 +534,7 @@
     Push("", Item::MESSAGE, false, false);
     ProtoWriter::RenderDataPiece("key",
                                  DataPiece(name, use_strict_base64_decoding()));
-    Push("value", 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;
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h
index c33a463..d9bb432 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.h
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.h
@@ -112,18 +112,18 @@
                           strings::ByteSink* output, ErrorListener* listener,
                           const ProtoStreamObjectWriter::Options& options =
                               ProtoStreamObjectWriter::Options::Defaults());
-  virtual ~ProtoStreamObjectWriter();
+  virtual ~ProtoStreamObjectWriter() override;
 
   // ObjectWriter methods.
-  virtual ProtoStreamObjectWriter* StartObject(StringPiece name);
-  virtual ProtoStreamObjectWriter* EndObject();
-  virtual ProtoStreamObjectWriter* StartList(StringPiece name);
-  virtual ProtoStreamObjectWriter* EndList();
+  virtual ProtoStreamObjectWriter* StartObject(StringPiece name) override;
+  virtual ProtoStreamObjectWriter* EndObject() override;
+  virtual ProtoStreamObjectWriter* StartList(StringPiece name) override;
+  virtual 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);
+                                           const DataPiece& value) override;
 
  protected:
   // Function that renders a well known type with modified behavior.
@@ -263,7 +263,7 @@
     // Constructor for a field of a message.
     Item(Item* parent, ItemType item_type, bool is_placeholder, bool is_list);
 
-    virtual ~Item() {}
+    virtual ~Item() override {}
 
     // These functions return true if the element type is corresponding to the
     // type in function name.
@@ -272,7 +272,7 @@
 
     AnyWriter* any() const { return any_.get(); }
 
-    virtual Item* parent() const {
+    virtual Item* parent() const override {
       return static_cast<Item*>(BaseElement::parent());
     }
 
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
index 7f0df56..9c50e7d 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
@@ -1679,6 +1679,22 @@
       ->EndObject();
 }
 
+TEST_P(ProtoStreamObjectWriterMapTest, AnyInMap) {
+  MapIn mm;
+  google::protobuf::DoubleValue d;
+  d.set_value(40.2);
+  (*mm.mutable_map_any())["foo"].PackFrom(d);
+  ow_->StartObject("")
+      ->StartObject("map_any")
+      ->StartObject("foo")
+      ->RenderString("@type", "type.googleapis.com/google.protobuf.DoubleValue")
+      ->RenderDouble("value", 40.2)
+      ->EndObject()
+      ->EndObject()
+      ->EndObject();
+  CheckOutput(mm);
+}
+
 class ProtoStreamObjectWriterAnyTest : public BaseProtoStreamObjectWriterTest {
  protected:
   ProtoStreamObjectWriterAnyTest() {
diff --git a/src/google/protobuf/util/internal/testdata/books.proto b/src/google/protobuf/util/internal/testdata/books.proto
index 5630cc7..5e08a29 100644
--- a/src/google/protobuf/util/internal/testdata/books.proto
+++ b/src/google/protobuf/util/internal/testdata/books.proto
@@ -69,6 +69,9 @@
   }
   optional Type type = 11;
 
+  // Useful for testing JSON snake/camel-case conversions.
+  optional string snake_field = 12;
+
   extensions 200 to 499;
 }
 
diff --git a/src/google/protobuf/util/internal/testdata/maps.proto b/src/google/protobuf/util/internal/testdata/maps.proto
index 0f381b3..765254e 100644
--- a/src/google/protobuf/util/internal/testdata/maps.proto
+++ b/src/google/protobuf/util/internal/testdata/maps.proto
@@ -32,6 +32,8 @@
 
 package google.protobuf.testing;
 
+import "google/protobuf/any.proto";
+
 // Top-level test cases proto used by MarshallingTest. See description
 // at the top of the class MarshallingTest for details on how to write
 // test cases.
@@ -103,6 +105,7 @@
   string other = 1;
   repeated string things = 2;
   map<string, string> map_input = 3;
+  map<string, google.protobuf.Any> map_any = 4;
 }
 
 message MapOut {
diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc
index 3847b17..e32e71d 100644
--- a/src/google/protobuf/util/internal/type_info.cc
+++ b/src/google/protobuf/util/internal/type_info.cc
@@ -59,7 +59,7 @@
   }
 
   virtual util::StatusOr<const google::protobuf::Type*> ResolveTypeUrl(
-      StringPiece type_url) const {
+      StringPiece type_url) const override {
     std::map<StringPiece, StatusOrType>::iterator it =
         cached_types_.find(type_url);
     if (it != cached_types_.end()) {
@@ -79,13 +79,13 @@
   }
 
   virtual const google::protobuf::Type* GetTypeByTypeUrl(
-      StringPiece type_url) const {
+      StringPiece type_url) const override {
     StatusOrType result = ResolveTypeUrl(type_url);
     return result.ok() ? result.ValueOrDie() : NULL;
   }
 
   virtual const google::protobuf::Enum* GetEnumByTypeUrl(
-      StringPiece type_url) const {
+      StringPiece type_url) const override {
     std::map<StringPiece, StatusOrEnum>::iterator it =
         cached_enums_.find(type_url);
     if (it != cached_enums_.end()) {
@@ -105,8 +105,10 @@
     return result.ok() ? result.ValueOrDie() : NULL;
   }
 
+
   virtual const google::protobuf::Field* FindField(
-      const google::protobuf::Type* type, StringPiece camel_case_name) const {
+      const google::protobuf::Type* type,
+      StringPiece camel_case_name) const override {
     std::map<const google::protobuf::Type*, CamelCaseNameTable>::const_iterator
         it = indexed_types_.find(type);
     const CamelCaseNameTable& camel_case_name_table =
diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc
index f81a7a3..7a7f299 100644
--- a/src/google/protobuf/util/json_util.cc
+++ b/src/google/protobuf/util/json_util.cc
@@ -119,19 +119,21 @@
 namespace {
 class StatusErrorListener : public converter::ErrorListener {
  public:
+
   StatusErrorListener() {}
-  virtual ~StatusErrorListener() {}
+  virtual ~StatusErrorListener() override {}
 
   util::Status GetStatus() { return status_; }
 
   virtual void InvalidName(const converter::LocationTrackerInterface& loc,
-                           StringPiece unknown_name, StringPiece message) {
+                   StringPiece unknown_name, StringPiece message) override {
     status_ = util::Status(util::error::INVALID_ARGUMENT,
-                             loc.ToString() + ": " + string(message));
+                           loc.ToString() + ": invalid name " +
+                               string(unknown_name) + ": " + string(message));
   }
 
   virtual void InvalidValue(const converter::LocationTrackerInterface& loc,
-                            StringPiece type_name, StringPiece value) {
+                    StringPiece type_name, StringPiece value) override {
     status_ =
         util::Status(util::error::INVALID_ARGUMENT,
                        loc.ToString() + ": invalid value " + string(value) +
@@ -139,7 +141,7 @@
   }
 
   virtual void MissingField(const converter::LocationTrackerInterface& loc,
-                            StringPiece missing_name) {
+                    StringPiece missing_name) override {
     status_ = util::Status(
         util::error::INVALID_ARGUMENT,
         loc.ToString() + ": missing field " + string(missing_name));
diff --git a/src/google/protobuf/util/json_util.h b/src/google/protobuf/util/json_util.h
index b1c6981..e786830 100644
--- a/src/google/protobuf/util/json_util.h
+++ b/src/google/protobuf/util/json_util.h
@@ -182,7 +182,7 @@
       : stream_(stream), buffer_(NULL), buffer_size_(0) {}
   ~ZeroCopyStreamByteSink();
 
-  virtual void Append(const char* bytes, size_t len);
+  virtual void Append(const char* bytes, size_t len) override;
 
  private:
   io::ZeroCopyOutputStream* stream_;
diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc
index ed9092d..a2a84b5 100644
--- a/src/google/protobuf/util/json_util_test.cc
+++ b/src/google/protobuf/util/json_util_test.cc
@@ -284,7 +284,7 @@
   JsonPrintOptions print_options;
   print_options.always_print_primitive_fields = true;
   JsonParseOptions parse_options;
-  EXPECT_EQ("{\"other\":\"\",\"things\":[],\"mapInput\":{}}",
+  EXPECT_EQ("{\"other\":\"\",\"things\":[],\"mapInput\":{},\"mapAny\":{}}",
             ToJson(message, print_options));
   MapIn other;
   ASSERT_TRUE(FromJson(ToJson(message, print_options), &other, parse_options));
diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc
index 9842f64..7d3976f 100644
--- a/src/google/protobuf/util/message_differencer.cc
+++ b/src/google/protobuf/util/message_differencer.cc
@@ -90,7 +90,7 @@
   virtual bool IsMatch(
       const Message& message1,
       const Message& message2,
-      const std::vector<SpecificField>& parent_fields) const {
+      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)) {
diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h
index bbcf849..b3e6551 100644
--- a/src/google/protobuf/util/message_differencer.h
+++ b/src/google/protobuf/util/message_differencer.h
@@ -597,7 +597,7 @@
    public:
     explicit StreamReporter(io::ZeroCopyOutputStream* output);
     explicit StreamReporter(io::Printer* printer);  // delimiter '$'
-    virtual ~StreamReporter();
+    virtual ~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
@@ -607,32 +607,33 @@
     }
 
     // The following are implementations of the methods described above.
+
     virtual void ReportAdded(const Message& message1, const Message& message2,
-                             const std::vector<SpecificField>& field_path);
+                             const std::vector<SpecificField>& field_path) override;
 
     virtual void ReportDeleted(const Message& message1,
                                const Message& message2,
-                               const std::vector<SpecificField>& field_path);
+                               const std::vector<SpecificField>& field_path) override;
 
     virtual void ReportModified(const Message& message1,
                                 const Message& message2,
-                                const std::vector<SpecificField>& field_path);
+                                const std::vector<SpecificField>& field_path) override;
 
     virtual void ReportMoved(const Message& message1,
                              const Message& message2,
-                             const std::vector<SpecificField>& field_path);
+                             const std::vector<SpecificField>& field_path) override;
 
     virtual void ReportMatched(const Message& message1,
                                const Message& message2,
-                               const std::vector<SpecificField>& field_path);
+                               const std::vector<SpecificField>& field_path) override;
 
     virtual void ReportIgnored(const Message& message1,
                                const Message& message2,
-                               const std::vector<SpecificField>& field_path);
+                               const std::vector<SpecificField>& field_path) override;
 
-    virtual void ReportUnknownFieldIgnored(
+    void ReportUnknownFieldIgnored(
         const Message& message1, const Message& message2,
-        const std::vector<SpecificField>& field_path);
+        const std::vector<SpecificField>& field_path) override;
 
    protected:
     // Prints the specified path of fields to the buffer.  message is used to
@@ -681,7 +682,7 @@
    public:
     explicit MapEntryKeyComparator(MessageDifferencer* message_differencer);
     virtual bool IsMatch(const Message& message1, const Message& message2,
-                         const std::vector<SpecificField>& parent_fields) const;
+                         const std::vector<SpecificField>& parent_fields) const override;
 
    private:
     MessageDifferencer* message_differencer_;
diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc
old mode 100755
new mode 100644
diff --git a/src/google/protobuf/util/type_resolver_util.cc b/src/google/protobuf/util/type_resolver_util.cc
index a69ed58..aa48ef6 100644
--- a/src/google/protobuf/util/type_resolver_util.cc
+++ b/src/google/protobuf/util/type_resolver_util.cc
@@ -60,7 +60,7 @@
                              const DescriptorPool* pool)
       : url_prefix_(url_prefix), pool_(pool) {}
 
-  Status ResolveMessageType(const string& type_url, Type* type) {
+  Status ResolveMessageType(const string& type_url, Type* type) override {
     string type_name;
     Status status = ParseTypeUrl(type_url, &type_name);
     if (!status.ok()) {
@@ -75,7 +75,7 @@
     return Status();
   }
 
-  Status ResolveEnumType(const string& type_url, Enum* enum_type) {
+  Status ResolveEnumType(const string& type_url, Enum* enum_type) override {
     string type_name;
     Status status = ParseTypeUrl(type_url, &type_name);
     if (!status.ok()) {
diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h
index d602d21..36f4a0b 100644
--- a/src/google/protobuf/wire_format.h
+++ b/src/google/protobuf/wire_format.h
@@ -260,12 +260,12 @@
  public:
   UnknownFieldSetFieldSkipper(UnknownFieldSet* unknown_fields)
       : unknown_fields_(unknown_fields) {}
-  virtual ~UnknownFieldSetFieldSkipper() {}
+  virtual ~UnknownFieldSetFieldSkipper() override {}
 
   // implements FieldSkipper -----------------------------------------
-  virtual bool SkipField(io::CodedInputStream* input, uint32 tag);
-  virtual bool SkipMessage(io::CodedInputStream* input);
-  virtual void SkipUnknownEnum(int field_number, int value);
+  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;
 
  protected:
   UnknownFieldSet* unknown_fields_;
diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h
index 77eaa9a..2244b35 100644
--- a/src/google/protobuf/wire_format_lite.h
+++ b/src/google/protobuf/wire_format_lite.h
@@ -763,9 +763,9 @@
   virtual ~CodedOutputStreamFieldSkipper() {}
 
   // implements FieldSkipper -----------------------------------------
-  virtual bool SkipField(io::CodedInputStream* input, uint32 tag);
-  virtual bool SkipMessage(io::CodedInputStream* input);
-  virtual void SkipUnknownEnum(int field_number, int value);
+  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;
 
  protected:
   io::CodedOutputStream* unknown_fields_;
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc
index ffd905f..8f254b8 100644
--- a/src/google/protobuf/wrappers.pb.cc
+++ b/src/google/protobuf/wrappers.pb.cc
@@ -289,14 +289,14 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_BytesValue_default_instance_),
 };
 
-void protobuf_AssignDescriptors() {
+static void protobuf_AssignDescriptors() {
   AddDescriptors();
   AssignDescriptors(
       "google/protobuf/wrappers.proto", schemas, file_default_instances, TableStruct::offsets,
       file_level_metadata, NULL, NULL);
 }
 
-void protobuf_AssignDescriptorsOnce() {
+static void protobuf_AssignDescriptorsOnce() {
   static ::google::protobuf::internal::once_flag once;
   ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);
 }
@@ -307,7 +307,7 @@
   ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 9);
 }
 
-void AddDescriptorsImpl() {
+static void AddDescriptorsImpl() {
   InitDefaults();
   static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
       "\n\036google/protobuf/wrappers.proto\022\017google"
@@ -391,7 +391,7 @@
   DoubleValue* _this = reinterpret_cast< DoubleValue* >(object);
   (void)_this;
 }
-void DoubleValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void DoubleValue::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void DoubleValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -642,7 +642,7 @@
   FloatValue* _this = reinterpret_cast< FloatValue* >(object);
   (void)_this;
 }
-void FloatValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void FloatValue::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void FloatValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -893,7 +893,7 @@
   Int64Value* _this = reinterpret_cast< Int64Value* >(object);
   (void)_this;
 }
-void Int64Value::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void Int64Value::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void Int64Value::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -1146,7 +1146,7 @@
   UInt64Value* _this = reinterpret_cast< UInt64Value* >(object);
   (void)_this;
 }
-void UInt64Value::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void UInt64Value::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void UInt64Value::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -1399,7 +1399,7 @@
   Int32Value* _this = reinterpret_cast< Int32Value* >(object);
   (void)_this;
 }
-void Int32Value::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void Int32Value::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void Int32Value::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -1652,7 +1652,7 @@
   UInt32Value* _this = reinterpret_cast< UInt32Value* >(object);
   (void)_this;
 }
-void UInt32Value::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void UInt32Value::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void UInt32Value::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -1905,7 +1905,7 @@
   BoolValue* _this = reinterpret_cast< BoolValue* >(object);
   (void)_this;
 }
-void BoolValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void BoolValue::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void BoolValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -2161,7 +2161,7 @@
   StringValue* _this = reinterpret_cast< StringValue* >(object);
   (void)_this;
 }
-void StringValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void StringValue::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void StringValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
@@ -2433,7 +2433,7 @@
   BytesValue* _this = reinterpret_cast< BytesValue* >(object);
   (void)_this;
 }
-void BytesValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+void BytesValue::RegisterArenaDtor(::google::protobuf::Arena*) {
 }
 void BytesValue::SetCachedSize(int size) const {
   _cached_size_.Set(size);
diff --git a/tests.sh b/tests.sh
index 73be5c1..5bb8ae3 100755
--- a/tests.sh
+++ b/tests.sh
@@ -507,18 +507,21 @@
   phpunit
   popd
   pushd conformance
-  # TODO(teboring): Add it back
-  # make test_php
+  make test_php
   popd
 }
 
 build_php7.1_c() {
+  ENABLE_CONFORMANCE_TEST=$1
   use_php 7.1
   wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 7.1 && cd ../..
-  pushd conformance
-  # make test_php_c
-  popd
+  if [ "$ENABLE_CONFORMANCE_TEST" = "true" ]
+  then
+    pushd conformance
+    make test_php_c
+    popd
+  fi
 }
 
 build_php7.1_zts_c() {
@@ -538,7 +541,7 @@
   build_php5.5_c
   build_php5.6_c
   build_php7.0_c
-  build_php7.1_c
+  build_php7.1_c $1
   build_php5.5_zts_c
   build_php5.6_zts_c
   build_php7.0_zts_c
@@ -546,7 +549,7 @@
 }
 
 build_php_all() {
-  build_php_all_32
+  build_php_all_32 true
   build_php_compatibility
 }