Merge branch 'master' of github.com:google/protobuf

Change-Id: If3fb07754a734bae610d95124528e073515ac525
diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in
index 853332a..eaf9758 100644
--- a/cmake/extract_includes.bat.in
+++ b/cmake/extract_includes.bat.in
@@ -110,8 +110,10 @@
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\type.pb.h include\google\protobuf\type.pb.h
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\unknown_field_set.h include\google\protobuf\unknown_field_set.h
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_comparator.h include\google\protobuf\util\field_comparator.h
+copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_mask_util.h include\google\protobuf\util\field_mask_util.h
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\json_util.h include\google\protobuf\util\json_util.h
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\message_differencer.h include\google\protobuf\util\message_differencer.h
+copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\time_util.h include\google\protobuf\util\time_util.h
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver.h include\google\protobuf\util\type_resolver.h
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver_util.h include\google\protobuf\util\type_resolver_util.h
 copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format.h include\google\protobuf\wire_format.h
diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake
index e323840..e2cec9d 100644
--- a/cmake/libprotobuf-lite.cmake
+++ b/cmake/libprotobuf-lite.cmake
@@ -12,6 +12,7 @@
   ${protobuf_source_dir}/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
   ${protobuf_source_dir}/src/google/protobuf/stubs/bytestream.cc
   ${protobuf_source_dir}/src/google/protobuf/stubs/common.cc
+  ${protobuf_source_dir}/src/google/protobuf/stubs/int128.cc
   ${protobuf_source_dir}/src/google/protobuf/stubs/once.cc
   ${protobuf_source_dir}/src/google/protobuf/stubs/status.cc
   ${protobuf_source_dir}/src/google/protobuf/stubs/statusor.cc
diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake
index 31fb1fb..f25e8c0 100644
--- a/cmake/libprotobuf.cmake
+++ b/cmake/libprotobuf.cmake
@@ -32,6 +32,7 @@
   ${protobuf_source_dir}/src/google/protobuf/type.pb.cc
   ${protobuf_source_dir}/src/google/protobuf/unknown_field_set.cc
   ${protobuf_source_dir}/src/google/protobuf/util/field_comparator.cc
+  ${protobuf_source_dir}/src/google/protobuf/util/field_mask_util.cc
   ${protobuf_source_dir}/src/google/protobuf/util/internal/datapiece.cc
   ${protobuf_source_dir}/src/google/protobuf/util/internal/default_value_objectwriter.cc
   ${protobuf_source_dir}/src/google/protobuf/util/internal/error_listener.cc
@@ -47,6 +48,7 @@
   ${protobuf_source_dir}/src/google/protobuf/util/internal/utility.cc
   ${protobuf_source_dir}/src/google/protobuf/util/json_util.cc
   ${protobuf_source_dir}/src/google/protobuf/util/message_differencer.cc
+  ${protobuf_source_dir}/src/google/protobuf/util/time_util.cc
   ${protobuf_source_dir}/src/google/protobuf/util/type_resolver_util.cc
   ${protobuf_source_dir}/src/google/protobuf/wire_format.cc
   ${protobuf_source_dir}/src/google/protobuf/wrappers.pb.cc
diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake
index f8fa7ad..7aa92ee 100644
--- a/cmake/libprotoc.cmake
+++ b/cmake/libprotoc.cmake
@@ -34,6 +34,7 @@
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field_lite.cc
+  ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_lite.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_extension.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_field.cc
   ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_file.cc
diff --git a/cmake/tests.cmake b/cmake/tests.cmake
index 16c9493..9215108 100644
--- a/cmake/tests.cmake
+++ b/cmake/tests.cmake
@@ -21,6 +21,7 @@
   google/protobuf/unittest_import_lite.proto
   google/protobuf/unittest_import_public_lite.proto
   google/protobuf/unittest_lite.proto
+  google/protobuf/unittest_no_arena_lite.proto
 )
 
 set(tests_protos
@@ -40,6 +41,7 @@
   google/protobuf/unittest_import_public.proto
   google/protobuf/unittest_lite_imports_nonlite.proto
   google/protobuf/unittest_mset.proto
+  google/protobuf/unittest_mset_wire_format.proto
   google/protobuf/unittest_no_arena.proto
   google/protobuf/unittest_no_arena_import.proto
   google/protobuf/unittest_no_field_presence.proto
@@ -55,6 +57,7 @@
   google/protobuf/util/internal/testdata/default_value_test.proto
   google/protobuf/util/internal/testdata/field_mask.proto
   google/protobuf/util/internal/testdata/maps.proto
+  google/protobuf/util/internal/testdata/oneofs.proto
   google/protobuf/util/internal/testdata/struct.proto
   google/protobuf/util/internal/testdata/timestamp_duration.proto
   google/protobuf/util/json_format_proto3.proto
@@ -134,6 +137,7 @@
   ${protobuf_source_dir}/src/google/protobuf/repeated_field_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/stubs/bytestream_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/stubs/common_unittest.cc
+  ${protobuf_source_dir}/src/google/protobuf/stubs/int128_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/stubs/once_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/stubs/status_test.cc
   ${protobuf_source_dir}/src/google/protobuf/stubs/statusor_test.cc
@@ -147,6 +151,7 @@
   ${protobuf_source_dir}/src/google/protobuf/text_format_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/unknown_field_set_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/util/field_comparator_test.cc
+  ${protobuf_source_dir}/src/google/protobuf/util/field_mask_util_test.cc
   ${protobuf_source_dir}/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
   ${protobuf_source_dir}/src/google/protobuf/util/internal/json_objectwriter_test.cc
   ${protobuf_source_dir}/src/google/protobuf/util/internal/json_stream_parser_test.cc
@@ -154,6 +159,7 @@
   ${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
   ${protobuf_source_dir}/src/google/protobuf/util/internal/type_info_test_helper.cc
   ${protobuf_source_dir}/src/google/protobuf/util/json_util_test.cc
+  ${protobuf_source_dir}/src/google/protobuf/util/time_util_test.cc
   ${protobuf_source_dir}/src/google/protobuf/util/type_resolver_util_test.cc
   ${protobuf_source_dir}/src/google/protobuf/well_known_types_unittest.cc
   ${protobuf_source_dir}/src/google/protobuf/wire_format_unittest.cc
diff --git a/java/pom.xml b/java/pom.xml
index 6877ac2..fb7e416 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -114,6 +114,7 @@
                   <arg value="../src/google/protobuf/unittest_import.proto" />
                   <arg value="../src/google/protobuf/unittest_import_public.proto" />
                   <arg value="../src/google/protobuf/unittest_mset.proto" />
+                  <arg value="../src/google/protobuf/unittest_mset_wire_format.proto" />
                   <arg value="src/test/java/com/google/protobuf/lazy_fields_lite.proto" />
                   <arg value="src/test/java/com/google/protobuf/lite_equals_and_hash.proto" />
                   <arg
diff --git a/python/google/protobuf/internal/message_set_extensions.proto b/python/google/protobuf/internal/message_set_extensions.proto
new file mode 100644
index 0000000..702c8d0
--- /dev/null
+++ b/python/google/protobuf/internal/message_set_extensions.proto
@@ -0,0 +1,66 @@
+// 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 contains messages that extend MessageSet.
+
+syntax = "proto2";
+package google.protobuf.internal;
+
+
+// A message with message_set_wire_format.
+message TestMessageSet {
+  option message_set_wire_format = true;
+  extensions 4 to max;
+}
+
+message TestMessageSetExtension1 {
+  extend TestMessageSet {
+    optional TestMessageSetExtension1 message_set_extension = 98418603;
+  }
+  optional int32 i = 15;
+}
+
+message TestMessageSetExtension2 {
+  extend TestMessageSet {
+    optional TestMessageSetExtension2 message_set_extension = 98418634;
+  }
+  optional string str = 25;
+}
+
+// This message was used to generate
+// //net/proto2/python/internal/testdata/message_set_message, but is commented
+// out since it must not actually exist in code, to simulate an "unknown"
+// extension.
+// message TestMessageSetUnknownExtension {
+//   extend TestMessageSet {
+//     optional TestMessageSetUnknownExtension message_set_extension = 56141421;
+//   }
+//   optional int64 a = 1;
+// }
diff --git a/python/google/protobuf/internal/packed_field_test.proto b/python/google/protobuf/internal/packed_field_test.proto
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/python/google/protobuf/internal/packed_field_test.proto
diff --git a/python/setup.py b/python/setup.py
index f53ad5f..78b43c2 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -91,11 +91,15 @@
 
 def GenerateUnittestProtos():
   generate_proto("../src/google/protobuf/map_unittest.proto", False)
+  generate_proto("../src/google/protobuf/unittest_arena.proto", False)
+  generate_proto("../src/google/protobuf/unittest_no_arena.proto", False)
+  generate_proto("../src/google/protobuf/unittest_no_arena_import.proto", False)
   generate_proto("../src/google/protobuf/unittest.proto", False)
   generate_proto("../src/google/protobuf/unittest_custom_options.proto", False)
   generate_proto("../src/google/protobuf/unittest_import.proto", False)
   generate_proto("../src/google/protobuf/unittest_import_public.proto", False)
   generate_proto("../src/google/protobuf/unittest_mset.proto", False)
+  generate_proto("../src/google/protobuf/unittest_mset_wire_format.proto", False)
   generate_proto("../src/google/protobuf/unittest_no_generic_services.proto", False)
   generate_proto("../src/google/protobuf/unittest_proto3_arena.proto", False)
   generate_proto("google/protobuf/internal/descriptor_pool_test1.proto", False)
@@ -105,9 +109,11 @@
   generate_proto("google/protobuf/internal/import_test_package/inner.proto", False)
   generate_proto("google/protobuf/internal/import_test_package/outer.proto", False)
   generate_proto("google/protobuf/internal/missing_enum_values.proto", False)
+  generate_proto("google/protobuf/internal/message_set_extensions.proto", False)
   generate_proto("google/protobuf/internal/more_extensions.proto", False)
   generate_proto("google/protobuf/internal/more_extensions_dynamic.proto", False)
   generate_proto("google/protobuf/internal/more_messages.proto", False)
+  generate_proto("google/protobuf/internal/packed_field_test.proto", False)
   generate_proto("google/protobuf/internal/test_bad_identifiers.proto", False)
   generate_proto("google/protobuf/pyext/python.proto", False)
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 584bcd2..4c8919d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -158,9 +158,11 @@
   google/protobuf/compiler/csharp/csharp_generator.h            \
   google/protobuf/compiler/csharp/csharp_names.h                \
   google/protobuf/util/type_resolver.h                          \
-  google/protobuf/util/type_resolver_util.h                     \
-  google/protobuf/util/json_util.h                              \
   google/protobuf/util/field_comparator.h                       \
+  google/protobuf/util/field_mask_util.h                        \
+  google/protobuf/util/json_util.h                              \
+  google/protobuf/util/time_util.h                              \
+  google/protobuf/util/type_resolver_util.h                     \
   google/protobuf/util/message_differencer.h
 
 lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la
@@ -174,6 +176,8 @@
   google/protobuf/stubs/bytestream.h                           \
   google/protobuf/stubs/common.cc                              \
   google/protobuf/stubs/hash.h                                 \
+  google/protobuf/stubs/int128.cc                              \
+  google/protobuf/stubs/int128.h                               \
   google/protobuf/stubs/map_util.h                             \
   google/protobuf/stubs/mathutil.h                             \
   google/protobuf/stubs/once.cc                                \
@@ -209,8 +213,8 @@
   $(libprotobuf_lite_la_SOURCES)                               \
   google/protobuf/any.pb.cc                                    \
   google/protobuf/api.pb.cc                                    \
-  google/protobuf/stubs/mathlimits.h                           \
   google/protobuf/stubs/mathlimits.cc                          \
+  google/protobuf/stubs/mathlimits.h                           \
   google/protobuf/any.cc                                       \
   google/protobuf/descriptor.cc                                \
   google/protobuf/descriptor_database.cc                       \
@@ -245,6 +249,7 @@
   google/protobuf/compiler/importer.cc                         \
   google/protobuf/compiler/parser.cc                           \
   google/protobuf/util/field_comparator.cc                     \
+  google/protobuf/util/field_mask_util.cc                      \
   google/protobuf/util/internal/constants.h                    \
   google/protobuf/util/internal/datapiece.cc                   \
   google/protobuf/util/internal/datapiece.h                    \
@@ -281,8 +286,10 @@
   google/protobuf/util/internal/utility.cc                     \
   google/protobuf/util/internal/utility.h                      \
   google/protobuf/util/json_util.cc                            \
-  google/protobuf/util/type_resolver_util.cc                   \
-  google/protobuf/util/message_differencer.cc
+  google/protobuf/util/message_differencer.cc                  \
+  google/protobuf/util/time_util.cc                            \
+  google/protobuf/util/type_resolver_util.cc
+
 nodist_libprotobuf_la_SOURCES = $(nodist_libprotobuf_lite_la_SOURCES)
 
 libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la
@@ -325,11 +332,13 @@
   google/protobuf/compiler/java/java_context.cc                \
   google/protobuf/compiler/java/java_context.h                 \
   google/protobuf/compiler/java/java_enum.cc                   \
+  google/protobuf/compiler/java/java_enum_lite.cc              \
   google/protobuf/compiler/java/java_enum_field.cc             \
   google/protobuf/compiler/java/java_enum_field.h              \
   google/protobuf/compiler/java/java_enum_field_lite.cc        \
   google/protobuf/compiler/java/java_enum_field_lite.h         \
   google/protobuf/compiler/java/java_enum.h                    \
+  google/protobuf/compiler/java/java_enum_lite.h               \
   google/protobuf/compiler/java/java_extension.cc              \
   google/protobuf/compiler/java/java_extension.h               \
   google/protobuf/compiler/java/java_field.cc                  \
@@ -480,6 +489,8 @@
   google/protobuf/unittest_lite_imports_nonlite.proto             \
   google/protobuf/unittest_lite.proto                             \
   google/protobuf/unittest_mset.proto                             \
+  google/protobuf/unittest_mset_wire_format.proto                 \
+  google/protobuf/unittest_no_arena_lite.proto                    \
   google/protobuf/unittest_no_arena_import.proto                  \
   google/protobuf/unittest_no_arena.proto                         \
   google/protobuf/unittest_no_field_presence.proto                \
@@ -496,6 +507,7 @@
   google/protobuf/util/internal/testdata/default_value_test.proto \
   google/protobuf/util/internal/testdata/field_mask.proto         \
   google/protobuf/util/internal/testdata/maps.proto               \
+  google/protobuf/util/internal/testdata/oneofs.proto             \
   google/protobuf/util/internal/testdata/struct.proto             \
   google/protobuf/util/internal/testdata/timestamp_duration.proto \
   google/protobuf/util/json_format_proto3.proto                   \
@@ -530,6 +542,8 @@
   google/protobuf/map_lite_unittest.pb.h                       \
   google/protobuf/unittest_lite.pb.cc                          \
   google/protobuf/unittest_lite.pb.h                           \
+  google/protobuf/unittest_no_arena_lite.pb.cc                 \
+  google/protobuf/unittest_no_arena_lite.pb.h                  \
   google/protobuf/unittest_import_lite.pb.cc                   \
   google/protobuf/unittest_import_lite.pb.h                    \
   google/protobuf/unittest_import_public_lite.pb.cc            \
@@ -567,6 +581,8 @@
   google/protobuf/unittest_lite_imports_nonlite.pb.h              \
   google/protobuf/unittest_mset.pb.cc                             \
   google/protobuf/unittest_mset.pb.h                              \
+  google/protobuf/unittest_mset_wire_format.pb.cc                 \
+  google/protobuf/unittest_mset_wire_format.pb.h                  \
   google/protobuf/unittest_no_arena_import.pb.cc                  \
   google/protobuf/unittest_no_arena_import.pb.h                   \
   google/protobuf/unittest_no_arena.pb.cc                         \
@@ -599,6 +615,8 @@
   google/protobuf/util/internal/testdata/field_mask.pb.h          \
   google/protobuf/util/internal/testdata/maps.pb.cc               \
   google/protobuf/util/internal/testdata/maps.pb.h                \
+  google/protobuf/util/internal/testdata/oneofs.pb.cc             \
+  google/protobuf/util/internal/testdata/oneofs.pb.h              \
   google/protobuf/util/internal/testdata/struct.pb.cc             \
   google/protobuf/util/internal/testdata/struct.pb.h              \
   google/protobuf/util/internal/testdata/timestamp_duration.pb.cc \
@@ -655,6 +673,7 @@
 protobuf_test_SOURCES =                                        \
   google/protobuf/stubs/bytestream_unittest.cc                 \
   google/protobuf/stubs/common_unittest.cc                     \
+  google/protobuf/stubs/int128_unittest.cc                     \
   google/protobuf/stubs/once_unittest.cc                       \
   google/protobuf/stubs/statusor_test.cc                       \
   google/protobuf/stubs/status_test.cc                         \
@@ -707,6 +726,7 @@
   google/protobuf/compiler/ruby/ruby_generator_unittest.cc     \
   google/protobuf/compiler/csharp/csharp_generator_unittest.cc \
   google/protobuf/util/field_comparator_test.cc                \
+  google/protobuf/util/field_mask_util_test.cc                 \
   google/protobuf/util/internal/default_value_objectwriter_test.cc \
   google/protobuf/util/internal/json_objectwriter_test.cc      \
   google/protobuf/util/internal/json_stream_parser_test.cc     \
@@ -714,6 +734,7 @@
   google/protobuf/util/internal/protostream_objectwriter_test.cc \
   google/protobuf/util/internal/type_info_test_helper.cc       \
   google/protobuf/util/json_util_test.cc                       \
+  google/protobuf/util/time_util_test.cc                       \
   google/protobuf/util/type_resolver_util_test.cc              \
   $(COMMON_TEST_SOURCES)
 
diff --git a/src/google/protobuf/any.proto b/src/google/protobuf/any.proto
index d3ad3ac..423699b 100644
--- a/src/google/protobuf/any.proto
+++ b/src/google/protobuf/any.proto
@@ -42,10 +42,8 @@
 // `Any` contains an arbitrary serialized message along with a URL
 // that describes the type of the serialized message.
 //
-// The proto runtimes and/or compiler will eventually
-//  provide utilities to pack/unpack Any values (projected Q1/15).
-//
-// # JSON
+// JSON
+// ====
 // The JSON representation of an `Any` value uses the regular
 // representation of the deserialized, embedded message, with an
 // additional field `@type` which contains the type URL. Example:
@@ -93,10 +91,6 @@
   // Schemas other than `http`, `https` (or the empty schema) might be
   // used with implementation specific semantics.
   //
-  // Types originating from the `google.*` package
-  // namespace should use `type.googleapis.com/full.type.name` (without
-  // schema and path). A type service will eventually become available which
-  // serves those URLs (projected Q2/15).
   string type_url = 1;
 
   // Must be valid serialized data of the above specified type.
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index 0feddb3..671eaca 100644
--- a/src/google/protobuf/api.pb.cc
+++ b/src/google/protobuf/api.pb.cc
@@ -27,6 +27,9 @@
 const ::google::protobuf::Descriptor* Method_descriptor_ = NULL;
 const ::google::protobuf::internal::GeneratedMessageReflection*
   Method_reflection_ = NULL;
+const ::google::protobuf::Descriptor* Mixin_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  Mixin_reflection_ = NULL;
 
 }  // namespace
 
@@ -38,12 +41,14 @@
       "google/protobuf/api.proto");
   GOOGLE_CHECK(file != NULL);
   Api_descriptor_ = file->message_type(0);
-  static const int Api_offsets_[5] = {
+  static const int Api_offsets_[7] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, name_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, methods_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, options_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, version_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, source_context_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, mixins_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, syntax_),
   };
   Api_reflection_ =
     ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -57,13 +62,14 @@
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, _internal_metadata_),
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, _is_default_instance_));
   Method_descriptor_ = file->message_type(1);
-  static const int Method_offsets_[6] = {
+  static const int Method_offsets_[7] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, name_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, request_type_url_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, request_streaming_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, response_type_url_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, response_streaming_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, options_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, syntax_),
   };
   Method_reflection_ =
     ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -76,6 +82,22 @@
       sizeof(Method),
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, _internal_metadata_),
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, _is_default_instance_));
+  Mixin_descriptor_ = file->message_type(2);
+  static const int Mixin_offsets_[2] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, name_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, root_),
+  };
+  Mixin_reflection_ =
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+      Mixin_descriptor_,
+      Mixin::default_instance_,
+      Mixin_offsets_,
+      -1,
+      -1,
+      -1,
+      sizeof(Mixin),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, _is_default_instance_));
 }
 
 namespace {
@@ -92,6 +114,8 @@
       Api_descriptor_, &Api::default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
       Method_descriptor_, &Method::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      Mixin_descriptor_, &Mixin::default_instance());
 }
 
 }  // namespace
@@ -101,6 +125,8 @@
   delete Api_reflection_;
   delete Method::default_instance_;
   delete Method_reflection_;
+  delete Mixin::default_instance_;
+  delete Mixin_reflection_;
 }
 
 void protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto() {
@@ -114,24 +140,30 @@
   ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
     "\n\031google/protobuf/api.proto\022\017google.prot"
     "obuf\032$google/protobuf/source_context.pro"
-    "to\032\032google/protobuf/type.proto\"\260\001\n\003Api\022\014"
+    "to\032\032google/protobuf/type.proto\"\201\002\n\003Api\022\014"
     "\n\004name\030\001 \001(\t\022(\n\007methods\030\002 \003(\0132\027.google.p"
     "rotobuf.Method\022(\n\007options\030\003 \003(\0132\027.google"
     ".protobuf.Option\022\017\n\007version\030\004 \001(\t\0226\n\016sou"
     "rce_context\030\005 \001(\0132\036.google.protobuf.Sour"
-    "ceContext\"\254\001\n\006Method\022\014\n\004name\030\001 \001(\t\022\030\n\020re"
-    "quest_type_url\030\002 \001(\t\022\031\n\021request_streamin"
-    "g\030\003 \001(\010\022\031\n\021response_type_url\030\004 \001(\t\022\032\n\022re"
-    "sponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\0132"
-    "\027.google.protobuf.OptionBH\n\023com.google.p"
-    "rotobufB\010ApiProtoP\001\242\002\003GPB\252\002\036Google.Proto"
-    "buf.WellKnownTypesb\006proto3", 546);
+    "ceContext\022&\n\006mixins\030\006 \003(\0132\026.google.proto"
+    "buf.Mixin\022\'\n\006syntax\030\007 \001(\0162\027.google.proto"
+    "buf.Syntax\"\325\001\n\006Method\022\014\n\004name\030\001 \001(\t\022\030\n\020r"
+    "equest_type_url\030\002 \001(\t\022\031\n\021request_streami"
+    "ng\030\003 \001(\010\022\031\n\021response_type_url\030\004 \001(\t\022\032\n\022r"
+    "esponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\013"
+    "2\027.google.protobuf.Option\022\'\n\006syntax\030\007 \001("
+    "\0162\027.google.protobuf.Syntax\"#\n\005Mixin\022\014\n\004n"
+    "ame\030\001 \001(\t\022\014\n\004root\030\002 \001(\tBK\n\023com.google.pr"
+    "otobufB\010ApiProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Pro"
+    "tobuf.WellKnownTypesb\006proto3", 708);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "google/protobuf/api.proto", &protobuf_RegisterTypes);
   Api::default_instance_ = new Api();
   Method::default_instance_ = new Method();
+  Mixin::default_instance_ = new Mixin();
   Api::default_instance_->InitAsDefaultInstance();
   Method::default_instance_->InitAsDefaultInstance();
+  Mixin::default_instance_->InitAsDefaultInstance();
   ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto);
 }
 
@@ -160,6 +192,8 @@
 const int Api::kOptionsFieldNumber;
 const int Api::kVersionFieldNumber;
 const int Api::kSourceContextFieldNumber;
+const int Api::kMixinsFieldNumber;
+const int Api::kSyntaxFieldNumber;
 #endif  // !_MSC_VER
 
 Api::Api()
@@ -188,6 +222,7 @@
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   version_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   source_context_ = NULL;
+  syntax_ = 0;
 }
 
 Api::~Api() {
@@ -233,8 +268,10 @@
   version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
   source_context_ = NULL;
+  syntax_ = 0;
   methods_.Clear();
   options_.Clear();
+  mixins_.Clear();
 }
 
 bool Api::MergePartialFromCodedStream(
@@ -322,6 +359,39 @@
         } else {
           goto handle_unusual;
         }
+        if (input->ExpectTag(50)) goto parse_mixins;
+        break;
+      }
+
+      // repeated .google.protobuf.Mixin mixins = 6;
+      case 6: {
+        if (tag == 50) {
+         parse_mixins:
+          DO_(input->IncrementRecursionDepth());
+         parse_loop_mixins:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+                input, add_mixins()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(50)) goto parse_loop_mixins;
+        input->UnsafeDecrementRecursionDepth();
+        if (input->ExpectTag(56)) goto parse_syntax;
+        break;
+      }
+
+      // optional .google.protobuf.Syntax syntax = 7;
+      case 7: {
+        if (tag == 56) {
+         parse_syntax:
+          int value;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_syntax(static_cast< ::google::protobuf::Syntax >(value));
+        } else {
+          goto handle_unusual;
+        }
         if (input->ExpectAtEnd()) goto success;
         break;
       }
@@ -388,6 +458,18 @@
       5, *this->source_context_, output);
   }
 
+  // repeated .google.protobuf.Mixin mixins = 6;
+  for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      6, this->mixins(i), output);
+  }
+
+  // optional .google.protobuf.Syntax syntax = 7;
+  if (this->syntax() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      7, this->syntax(), output);
+  }
+
   // @@protoc_insertion_point(serialize_end:google.protobuf.Api)
 }
 
@@ -437,6 +519,19 @@
         5, *this->source_context_, target);
   }
 
+  // repeated .google.protobuf.Mixin mixins = 6;
+  for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        6, this->mixins(i), target);
+  }
+
+  // optional .google.protobuf.Syntax syntax = 7;
+  if (this->syntax() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      7, this->syntax(), target);
+  }
+
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Api)
   return target;
 }
@@ -465,6 +560,12 @@
         *this->source_context_);
   }
 
+  // optional .google.protobuf.Syntax syntax = 7;
+  if (this->syntax() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
+  }
+
   // repeated .google.protobuf.Method methods = 2;
   total_size += 1 * this->methods_size();
   for (int i = 0; i < this->methods_size(); i++) {
@@ -481,6 +582,14 @@
         this->options(i));
   }
 
+  // repeated .google.protobuf.Mixin mixins = 6;
+  total_size += 1 * this->mixins_size();
+  for (int i = 0; i < this->mixins_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->mixins(i));
+  }
+
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -503,6 +612,7 @@
   if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
   methods_.MergeFrom(from.methods_);
   options_.MergeFrom(from.options_);
+  mixins_.MergeFrom(from.mixins_);
   if (from.name().size() > 0) {
 
     name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
@@ -514,6 +624,9 @@
   if (from.has_source_context()) {
     mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context());
   }
+  if (from.syntax() != 0) {
+    set_syntax(from.syntax());
+  }
 }
 
 void Api::CopyFrom(const ::google::protobuf::Message& from) {
@@ -543,6 +656,8 @@
   options_.UnsafeArenaSwap(&other->options_);
   version_.Swap(&other->version_);
   std::swap(source_context_, other->source_context_);
+  mixins_.UnsafeArenaSwap(&other->mixins_);
+  std::swap(syntax_, other->syntax_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
 }
@@ -741,6 +856,50 @@
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.source_context)
 }
 
+// repeated .google.protobuf.Mixin mixins = 6;
+int Api::mixins_size() const {
+  return mixins_.size();
+}
+void Api::clear_mixins() {
+  mixins_.Clear();
+}
+ const ::google::protobuf::Mixin& Api::mixins(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Api.mixins)
+  return mixins_.Get(index);
+}
+ ::google::protobuf::Mixin* Api::mutable_mixins(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.Api.mixins)
+  return mixins_.Mutable(index);
+}
+ ::google::protobuf::Mixin* Api::add_mixins() {
+  // @@protoc_insertion_point(field_add:google.protobuf.Api.mixins)
+  return mixins_.Add();
+}
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >&
+Api::mixins() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.Api.mixins)
+  return mixins_;
+}
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >*
+Api::mutable_mixins() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.mixins)
+  return &mixins_;
+}
+
+// optional .google.protobuf.Syntax syntax = 7;
+void Api::clear_syntax() {
+  syntax_ = 0;
+}
+ ::google::protobuf::Syntax Api::syntax() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Api.syntax)
+  return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+ void Api::set_syntax(::google::protobuf::Syntax value) {
+  
+  syntax_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.Api.syntax)
+}
+
 #endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
@@ -752,6 +911,7 @@
 const int Method::kResponseTypeUrlFieldNumber;
 const int Method::kResponseStreamingFieldNumber;
 const int Method::kOptionsFieldNumber;
+const int Method::kSyntaxFieldNumber;
 #endif  // !_MSC_VER
 
 Method::Method()
@@ -781,6 +941,7 @@
   request_streaming_ = false;
   response_type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   response_streaming_ = false;
+  syntax_ = 0;
 }
 
 Method::~Method() {
@@ -830,7 +991,7 @@
            ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
 } while (0)
 
-  ZR_(request_streaming_, response_streaming_);
+  ZR_(request_streaming_, syntax_);
   name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   request_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   response_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -944,6 +1105,22 @@
         }
         if (input->ExpectTag(50)) goto parse_loop_options;
         input->UnsafeDecrementRecursionDepth();
+        if (input->ExpectTag(56)) goto parse_syntax;
+        break;
+      }
+
+      // optional .google.protobuf.Syntax syntax = 7;
+      case 7: {
+        if (tag == 56) {
+         parse_syntax:
+          int value;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_syntax(static_cast< ::google::protobuf::Syntax >(value));
+        } else {
+          goto handle_unusual;
+        }
         if (input->ExpectAtEnd()) goto success;
         break;
       }
@@ -1018,6 +1195,12 @@
       6, this->options(i), output);
   }
 
+  // optional .google.protobuf.Syntax syntax = 7;
+  if (this->syntax() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      7, this->syntax(), output);
+  }
+
   // @@protoc_insertion_point(serialize_end:google.protobuf.Method)
 }
 
@@ -1074,6 +1257,12 @@
         6, this->options(i), target);
   }
 
+  // optional .google.protobuf.Syntax syntax = 7;
+  if (this->syntax() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      7, this->syntax(), target);
+  }
+
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Method)
   return target;
 }
@@ -1112,6 +1301,12 @@
     total_size += 1 + 1;
   }
 
+  // optional .google.protobuf.Syntax syntax = 7;
+  if (this->syntax() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
+  }
+
   // repeated .google.protobuf.Option options = 6;
   total_size += 1 * this->options_size();
   for (int i = 0; i < this->options_size(); i++) {
@@ -1159,6 +1354,9 @@
   if (from.response_streaming() != 0) {
     set_response_streaming(from.response_streaming());
   }
+  if (from.syntax() != 0) {
+    set_syntax(from.syntax());
+  }
 }
 
 void Method::CopyFrom(const ::google::protobuf::Message& from) {
@@ -1189,6 +1387,7 @@
   response_type_url_.Swap(&other->response_type_url_);
   std::swap(response_streaming_, other->response_streaming_);
   options_.UnsafeArenaSwap(&other->options_);
+  std::swap(syntax_, other->syntax_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
 }
@@ -1391,6 +1590,388 @@
   return &options_;
 }
 
+// optional .google.protobuf.Syntax syntax = 7;
+void Method::clear_syntax() {
+  syntax_ = 0;
+}
+ ::google::protobuf::Syntax Method::syntax() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Method.syntax)
+  return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+ void Method::set_syntax(::google::protobuf::Syntax value) {
+  
+  syntax_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.Method.syntax)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int Mixin::kNameFieldNumber;
+const int Mixin::kRootFieldNumber;
+#endif  // !_MSC_VER
+
+Mixin::Mixin()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.Mixin)
+}
+
+void Mixin::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
+}
+
+Mixin::Mixin(const Mixin& from)
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin)
+}
+
+void Mixin::SharedCtor() {
+    _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  root_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+Mixin::~Mixin() {
+  // @@protoc_insertion_point(destructor:google.protobuf.Mixin)
+  SharedDtor();
+}
+
+void Mixin::SharedDtor() {
+  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  root_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != default_instance_) {
+  }
+}
+
+void Mixin::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* Mixin::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return Mixin_descriptor_;
+}
+
+const Mixin& Mixin::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
+  return *default_instance_;
+}
+
+Mixin* Mixin::default_instance_ = NULL;
+
+Mixin* Mixin::New(::google::protobuf::Arena* arena) const {
+  Mixin* n = new Mixin;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void Mixin::Clear() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  root_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+bool Mixin::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.Mixin)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string name = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->name().data(), this->name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "google.protobuf.Mixin.name");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_root;
+        break;
+      }
+
+      // optional string root = 2;
+      case 2: {
+        if (tag == 18) {
+         parse_root:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_root()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->root().data(), this->root().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "google.protobuf.Mixin.root");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.Mixin)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.Mixin)
+  return false;
+#undef DO_
+}
+
+void Mixin::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.Mixin)
+  // optional string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.Mixin.name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // optional string root = 2;
+  if (this->root().size() > 0) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->root().data(), this->root().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.Mixin.root");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      2, this->root(), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:google.protobuf.Mixin)
+}
+
+::google::protobuf::uint8* Mixin::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Mixin)
+  // optional string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.Mixin.name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // optional string root = 2;
+  if (this->root().size() > 0) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->root().data(), this->root().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.Mixin.root");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        2, this->root(), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Mixin)
+  return target;
+}
+
+int Mixin::ByteSize() const {
+  int total_size = 0;
+
+  // optional string name = 1;
+  if (this->name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->name());
+  }
+
+  // optional string root = 2;
+  if (this->root().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->root());
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void Mixin::MergeFrom(const ::google::protobuf::Message& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const Mixin* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const Mixin>(
+          &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void Mixin::MergeFrom(const Mixin& from) {
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  if (from.name().size() > 0) {
+
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  if (from.root().size() > 0) {
+
+    root_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.root_);
+  }
+}
+
+void Mixin::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Mixin::CopyFrom(const Mixin& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Mixin::IsInitialized() const {
+
+  return true;
+}
+
+void Mixin::Swap(Mixin* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Mixin::InternalSwap(Mixin* other) {
+  name_.Swap(&other->name_);
+  root_.Swap(&other->root_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata Mixin::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = Mixin_descriptor_;
+  metadata.reflection = Mixin_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// Mixin
+
+// optional string name = 1;
+void Mixin::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& Mixin::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Mixin.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Mixin::set_name(const ::std::string& value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.Mixin.name)
+}
+ void Mixin::set_name(const char* value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name)
+}
+ void Mixin::set_name(const char* value, size_t size) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.name)
+}
+ ::std::string* Mixin::mutable_name() {
+  
+  // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* Mixin::release_name() {
+  
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Mixin::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    
+  } else {
+    
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name)
+}
+
+// optional string root = 2;
+void Mixin::clear_root() {
+  root_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& Mixin::root() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Mixin.root)
+  return root_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Mixin::set_root(const ::std::string& value) {
+  
+  root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.Mixin.root)
+}
+ void Mixin::set_root(const char* value) {
+  
+  root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root)
+}
+ void Mixin::set_root(const char* value, size_t size) {
+  
+  root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.root)
+}
+ ::std::string* Mixin::mutable_root() {
+  
+  // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.root)
+  return root_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* Mixin::release_root() {
+  
+  return root_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Mixin::set_allocated_root(::std::string* root) {
+  if (root != NULL) {
+    
+  } else {
+    
+  }
+  root_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), root);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root)
+}
+
 #endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // @@protoc_insertion_point(namespace_scope)
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h
index 985adc5..414734a 100644
--- a/src/google/protobuf/api.pb.h
+++ b/src/google/protobuf/api.pb.h
@@ -41,6 +41,7 @@
 
 class Api;
 class Method;
+class Mixin;
 
 // ===================================================================
 
@@ -155,6 +156,24 @@
   ::google::protobuf::SourceContext* release_source_context();
   void set_allocated_source_context(::google::protobuf::SourceContext* source_context);
 
+  // repeated .google.protobuf.Mixin mixins = 6;
+  int mixins_size() const;
+  void clear_mixins();
+  static const int kMixinsFieldNumber = 6;
+  const ::google::protobuf::Mixin& mixins(int index) const;
+  ::google::protobuf::Mixin* mutable_mixins(int index);
+  ::google::protobuf::Mixin* add_mixins();
+  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >&
+      mixins() const;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >*
+      mutable_mixins();
+
+  // optional .google.protobuf.Syntax syntax = 7;
+  void clear_syntax();
+  static const int kSyntaxFieldNumber = 7;
+  ::google::protobuf::Syntax syntax() const;
+  void set_syntax(::google::protobuf::Syntax value);
+
   // @@protoc_insertion_point(class_scope:google.protobuf.Api)
  private:
 
@@ -165,6 +184,8 @@
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
   ::google::protobuf::internal::ArenaStringPtr version_;
   ::google::protobuf::SourceContext* source_context_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin > mixins_;
+  int syntax_;
   mutable int _cached_size_;
   friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
   friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto();
@@ -288,6 +309,12 @@
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
       mutable_options();
 
+  // optional .google.protobuf.Syntax syntax = 7;
+  void clear_syntax();
+  static const int kSyntaxFieldNumber = 7;
+  ::google::protobuf::Syntax syntax() const;
+  void set_syntax(::google::protobuf::Syntax value);
+
   // @@protoc_insertion_point(class_scope:google.protobuf.Method)
  private:
 
@@ -296,9 +323,10 @@
   ::google::protobuf::internal::ArenaStringPtr name_;
   ::google::protobuf::internal::ArenaStringPtr request_type_url_;
   ::google::protobuf::internal::ArenaStringPtr response_type_url_;
-  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
   bool request_streaming_;
   bool response_streaming_;
+  int syntax_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
   mutable int _cached_size_;
   friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
   friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto();
@@ -307,6 +335,101 @@
   void InitAsDefaultInstance();
   static Method* default_instance_;
 };
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message {
+ public:
+  Mixin();
+  virtual ~Mixin();
+
+  Mixin(const Mixin& from);
+
+  inline Mixin& operator=(const Mixin& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const Mixin& default_instance();
+
+  void Swap(Mixin* other);
+
+  // implements Message ----------------------------------------------
+
+  inline Mixin* New() const { return New(NULL); }
+
+  Mixin* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const Mixin& from);
+  void MergeFrom(const Mixin& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(Mixin* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string name = 1;
+  void clear_name();
+  static const int kNameFieldNumber = 1;
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
+
+  // optional string root = 2;
+  void clear_root();
+  static const int kRootFieldNumber = 2;
+  const ::std::string& root() const;
+  void set_root(const ::std::string& value);
+  void set_root(const char* value);
+  void set_root(const char* value, size_t size);
+  ::std::string* mutable_root();
+  ::std::string* release_root();
+  void set_allocated_root(::std::string* root);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.Mixin)
+ private:
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr name_;
+  ::google::protobuf::internal::ArenaStringPtr root_;
+  mutable int _cached_size_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto();
+
+  void InitAsDefaultInstance();
+  static Mixin* default_instance_;
+};
 // ===================================================================
 
 
@@ -498,6 +621,50 @@
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.source_context)
 }
 
+// repeated .google.protobuf.Mixin mixins = 6;
+inline int Api::mixins_size() const {
+  return mixins_.size();
+}
+inline void Api::clear_mixins() {
+  mixins_.Clear();
+}
+inline const ::google::protobuf::Mixin& Api::mixins(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Api.mixins)
+  return mixins_.Get(index);
+}
+inline ::google::protobuf::Mixin* Api::mutable_mixins(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.Api.mixins)
+  return mixins_.Mutable(index);
+}
+inline ::google::protobuf::Mixin* Api::add_mixins() {
+  // @@protoc_insertion_point(field_add:google.protobuf.Api.mixins)
+  return mixins_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >&
+Api::mixins() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.Api.mixins)
+  return mixins_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >*
+Api::mutable_mixins() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.mixins)
+  return &mixins_;
+}
+
+// optional .google.protobuf.Syntax syntax = 7;
+inline void Api::clear_syntax() {
+  syntax_ = 0;
+}
+inline ::google::protobuf::Syntax Api::syntax() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Api.syntax)
+  return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+inline void Api::set_syntax(::google::protobuf::Syntax value) {
+  
+  syntax_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.Api.syntax)
+}
+
 // -------------------------------------------------------------------
 
 // Method
@@ -689,9 +856,115 @@
   return &options_;
 }
 
+// optional .google.protobuf.Syntax syntax = 7;
+inline void Method::clear_syntax() {
+  syntax_ = 0;
+}
+inline ::google::protobuf::Syntax Method::syntax() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Method.syntax)
+  return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+inline void Method::set_syntax(::google::protobuf::Syntax value) {
+  
+  syntax_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.Method.syntax)
+}
+
+// -------------------------------------------------------------------
+
+// Mixin
+
+// optional string name = 1;
+inline void Mixin::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Mixin::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Mixin.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Mixin::set_name(const ::std::string& value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.Mixin.name)
+}
+inline void Mixin::set_name(const char* value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name)
+}
+inline void Mixin::set_name(const char* value, size_t size) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.name)
+}
+inline ::std::string* Mixin::mutable_name() {
+  
+  // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Mixin::release_name() {
+  
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Mixin::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    
+  } else {
+    
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name)
+}
+
+// optional string root = 2;
+inline void Mixin::clear_root() {
+  root_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Mixin::root() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Mixin.root)
+  return root_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Mixin::set_root(const ::std::string& value) {
+  
+  root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.Mixin.root)
+}
+inline void Mixin::set_root(const char* value) {
+  
+  root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root)
+}
+inline void Mixin::set_root(const char* value, size_t size) {
+  
+  root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.root)
+}
+inline ::std::string* Mixin::mutable_root() {
+  
+  // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.root)
+  return root_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Mixin::release_root() {
+  
+  return root_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Mixin::set_allocated_root(::std::string* root) {
+  if (root != NULL) {
+    
+  } else {
+    
+  }
+  root_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), root);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root)
+}
+
 #endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS
 // -------------------------------------------------------------------
 
+// -------------------------------------------------------------------
+
 
 // @@protoc_insertion_point(namespace_scope)
 
diff --git a/src/google/protobuf/api.proto b/src/google/protobuf/api.proto
index d6c2a8b..597a649 100644
--- a/src/google/protobuf/api.proto
+++ b/src/google/protobuf/api.proto
@@ -34,15 +34,16 @@
 import "google/protobuf/source_context.proto";
 import "google/protobuf/type.proto";
 
-option java_multiple_files = true;
-option java_outer_classname = "ApiProto";
 option java_package = "com.google.protobuf";
+option java_outer_classname = "ApiProto";
+option java_multiple_files = true;
+option java_generate_equals_and_hash = true;
 option csharp_namespace = "Google.Protobuf.WellKnownTypes";
 option objc_class_prefix = "GPB";
 
-
 // Api is a light-weight descriptor for a protocol buffer service.
 message Api {
+
   // The fully qualified name of this api, including package name
   // followed by the api's simple name.
   string name = 1;
@@ -74,18 +75,22 @@
   // be omitted. Zero major versions must only be used for
   // experimental, none-GA apis.
   //
-  // See also: [design doc](http://go/api-versioning).
-  //
-  //
   string version = 4;
 
   // Source context for the protocol buffer service represented by this
   // message.
   SourceContext source_context = 5;
+
+  // Included APIs. See [Mixin][].
+  repeated Mixin mixins = 6;
+
+  // The source syntax of the service.
+  Syntax syntax = 7;
 }
 
 // Method represents a method of an api.
 message Method {
+
   // The simple name of this method.
   string name = 1;
 
@@ -103,4 +108,94 @@
 
   // Any metadata attached to the method.
   repeated Option options = 6;
+
+  // The source syntax of this method.
+  Syntax syntax = 7;
+}
+
+// Declares an API to be included in this API. The including API must
+// redeclare all the methods from the included API, but documentation
+// and options are inherited as follows:
+//
+// - If after comment and whitespace stripping, the documentation
+//   string of the redeclared method is empty, it will be inherited
+//   from the original method.
+//
+// - Each annotation belonging to the service config (http,
+//   visibility) which is not set in the redeclared method will be
+//   inherited.
+//
+// - If an http annotation is inherited, the path pattern will be
+//   modified as follows. Any version prefix will be replaced by the
+//   version of the including API plus the [root][] path if specified.
+//
+// Example of a simple mixin:
+//
+//     package google.acl.v1;
+//     service AccessControl {
+//       // Get the underlying ACL object.
+//       rpc GetAcl(GetAclRequest) returns (Acl) {
+//         option (google.api.http).get = "/v1/{resource=**}:getAcl";
+//       }
+//     }
+//
+//     package google.storage.v2;
+//     service Storage {
+//       // (-- see AccessControl.GetAcl --)
+//       rpc GetAcl(GetAclRequest) returns (Acl);
+//
+//       // Get a data record.
+//       rpc GetData(GetDataRequest) returns (Data) {
+//         option (google.api.http).get = "/v2/{resource=**}";
+//       }
+//     }
+//
+// Example of a mixin configuration:
+//
+//     apis:
+//     - name: google.storage.v2.Storage
+//       mixins:
+//       - name: google.acl.v1.AccessControl
+//
+// The mixin construct implies that all methods in `AccessControl` are
+// also declared with same name and request/response types in
+// `Storage`. A documentation generator or annotation processor will
+// see the effective `Storage.GetAcl` method after inherting
+// documentation and annotations as follows:
+//
+//     service Storage {
+//       // Get the underlying ACL object.
+//       rpc GetAcl(GetAclRequest) returns (Acl) {
+//         option (google.api.http).get = "/v2/{resource=**}:getAcl";
+//       }
+//       ...
+//     }
+//
+// Note how the version in the path pattern changed from `v1` to `v2`.
+//
+// If the `root` field in the mixin is specified, it should be a
+// relative path under which inherited HTTP paths are placed. Example:
+//
+//     apis:
+//     - name: google.storage.v2.Storage
+//       mixins:
+//       - name: google.acl.v1.AccessControl
+//         root: acls
+//
+// This implies the following inherited HTTP annotation:
+//
+//     service Storage {
+//       // Get the underlying ACL object.
+//       rpc GetAcl(GetAclRequest) returns (Acl) {
+//         option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
+//       }
+//       ...
+//     }
+message Mixin {
+  // The fully qualified name of the API which is included.
+  string name = 1;
+
+  // If non-empty specifies a path under which inherited HTTP paths
+  // are rooted.
+  string root = 2;
 }
diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_enum_lite.cc
diff --git a/src/google/protobuf/compiler/java/java_enum_lite.h b/src/google/protobuf/compiler/java/java_enum_lite.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_enum_lite.h
diff --git a/src/google/protobuf/duration.proto b/src/google/protobuf/duration.proto
index 0762c3c..7f172aa 100644
--- a/src/google/protobuf/duration.proto
+++ b/src/google/protobuf/duration.proto
@@ -80,6 +80,7 @@
 //     }
 //
 message Duration {
+
   // Signed seconds of the span of time. Must be from -315,576,000,000
   // to +315,576,000,000 inclusive.
   int64 seconds = 1;
diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc
index 1e1c2c8..50cbd9a 100644
--- a/src/google/protobuf/empty.pb.cc
+++ b/src/google/protobuf/empty.pb.cc
@@ -79,9 +79,9 @@
 
   ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
     "\n\033google/protobuf/empty.proto\022\017google.pr"
-    "otobuf\"\007\n\005EmptyBJ\n\023com.google.protobufB\n"
-    "EmptyProtoP\001\242\002\003GPB\252\002\036Google.Protobuf.Wel"
-    "lKnownTypesb\006proto3", 139);
+    "otobuf\"\007\n\005EmptyBM\n\023com.google.protobufB\n"
+    "EmptyProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Protobuf."
+    "WellKnownTypesb\006proto3", 142);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "google/protobuf/empty.proto", &protobuf_RegisterTypes);
   Empty::default_instance_ = new Empty();
diff --git a/src/google/protobuf/empty.proto b/src/google/protobuf/empty.proto
index 363ec17..9dddc6c 100644
--- a/src/google/protobuf/empty.proto
+++ b/src/google/protobuf/empty.proto
@@ -34,10 +34,10 @@
 option java_multiple_files = true;
 option java_outer_classname = "EmptyProto";
 option java_package = "com.google.protobuf";
+option java_generate_equals_and_hash = true;
 option csharp_namespace = "Google.Protobuf.WellKnownTypes";
 option objc_class_prefix = "GPB";
 
-
 // A generic empty message that you can re-use to avoid defining duplicated
 // empty messages in your APIs. A typical example is to use it as the request
 // or the response type of an API method. For instance:
@@ -46,6 +46,5 @@
 //       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
 //     }
 //
-message Empty {
-
-}
+// The JSON representation for `Empty` is empty JSON object `{}`.
+message Empty {}
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index 88020ef..0537057 100644
--- a/src/google/protobuf/field_mask.pb.cc
+++ b/src/google/protobuf/field_mask.pb.cc
@@ -81,9 +81,9 @@
   ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
     "\n google/protobuf/field_mask.proto\022\017goog"
     "le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB"
-    "N\n\023com.google.protobufB\016FieldMaskProtoP\001"
-    "\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypesb"
-    "\006proto3", 167);
+    "Q\n\023com.google.protobufB\016FieldMaskProtoP\001"
+    "\240\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTyp"
+    "esb\006proto3", 170);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "google/protobuf/field_mask.proto", &protobuf_RegisterTypes);
   FieldMask::default_instance_ = new FieldMask();
diff --git a/src/google/protobuf/field_mask.proto b/src/google/protobuf/field_mask.proto
index c19f441..8b21c69 100644
--- a/src/google/protobuf/field_mask.proto
+++ b/src/google/protobuf/field_mask.proto
@@ -31,13 +31,13 @@
 
 package google.protobuf;
 
+option java_generate_equals_and_hash = true;
 option java_multiple_files = true;
 option java_outer_classname = "FieldMaskProto";
 option java_package = "com.google.protobuf";
 option csharp_namespace = "Google.Protobuf.WellKnownTypes";
 option objc_class_prefix = "GPB";
 
-
 // `FieldMask` represents a set of symbolic field paths, for example:
 //
 //     paths: "f.a"
@@ -52,6 +52,7 @@
 // Field masks also have a custom JSON encoding (see below).
 //
 // # Field Masks in Projections
+//
 // When used in the context of a projection, a response message or
 // sub-message is filtered by the API to only contain those fields as
 // specified in the mask. For example, if the mask in the previous
@@ -97,6 +98,7 @@
 // behavior for APIs.
 //
 // # Field Masks in Update Operations
+//
 // A field mask in update operations specifies which fields of the
 // targeted resource are going to be updated. The API is required
 // to only change the values of the fields as specified in the mask
@@ -124,11 +126,13 @@
 // required to be honored by the API.
 //
 // ## Considerations for HTTP REST
+//
 // The HTTP kind of an update operation which uses a field mask must
 // be set to PATCH instead of PUT in order to satisfy HTTP semantics
 // (PUT must only be used for full updates).
 //
 // # JSON Encoding of Field Masks
+//
 // In JSON, a field mask is encoded as a single string where paths are
 // separated by a comma. Fields name in each path are converted
 // to/from lower-camel naming conventions.
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc
index 5c88363..3369e47 100644
--- a/src/google/protobuf/source_context.pb.cc
+++ b/src/google/protobuf/source_context.pb.cc
@@ -81,9 +81,9 @@
   ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
     "\n$google/protobuf/source_context.proto\022\017"
     "google.protobuf\"\"\n\rSourceContext\022\021\n\tfile"
-    "_name\030\001 \001(\tBR\n\023com.google.protobufB\022Sour"
-    "ceContextProtoP\001\242\002\003GPB\252\002\036Google.Protobuf"
-    ".WellKnownTypesb\006proto3", 183);
+    "_name\030\001 \001(\tBU\n\023com.google.protobufB\022Sour"
+    "ceContextProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Proto"
+    "buf.WellKnownTypesb\006proto3", 186);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "google/protobuf/source_context.proto", &protobuf_RegisterTypes);
   SourceContext::default_instance_ = new SourceContext();
diff --git a/src/google/protobuf/source_context.proto b/src/google/protobuf/source_context.proto
index 98d4920..e9a27d6 100644
--- a/src/google/protobuf/source_context.proto
+++ b/src/google/protobuf/source_context.proto
@@ -34,10 +34,10 @@
 option java_multiple_files = true;
 option java_outer_classname = "SourceContextProto";
 option java_package = "com.google.protobuf";
+option java_generate_equals_and_hash = true;
 option csharp_namespace = "Google.Protobuf.WellKnownTypes";
 option objc_class_prefix = "GPB";
 
-
 // `SourceContext` represents information about the source of a
 // protobuf element, like the file in which it is defined.
 message SourceContext {
diff --git a/src/google/protobuf/struct.proto b/src/google/protobuf/struct.proto
index 4ff10cd..b3e9e69 100644
--- a/src/google/protobuf/struct.proto
+++ b/src/google/protobuf/struct.proto
@@ -45,6 +45,8 @@
 // scripting languages like JS a struct is represented as an
 // object. The details of that representation are described together
 // with the proto support for the language.
+//
+// The JSON representation for `Struct` is JSON object.
 message Struct {
   // Map of dynamically typed values.
   map<string, Value> fields = 1;
@@ -54,37 +56,39 @@
 // null, a number, a string, a boolean, a recursive struct value, or a
 // list of values. A producer of value is expected to set one of that
 // variants, absence of any variant indicates an error.
+//
+// The JSON representation for `Value` is JSON value.
 message Value {
+  // The kind of value.
   oneof kind {
     // Represents a null value.
     NullValue null_value = 1;
-
     // Represents a double value.
     double number_value = 2;
-
     // Represents a string value.
     string string_value = 3;
-
     // Represents a boolean value.
     bool bool_value = 4;
-
     // Represents a structured value.
     Struct struct_value = 5;
-
     // Represents a repeated `Value`.
     ListValue list_value = 6;
   }
 }
 
-// `ListValue` is a wrapper around a repeated field of values.
-message ListValue {
-  // Repeated field of dynamically typed values.
-  repeated Value values = 1;
-}
-
-// `NullValue` is a singleton enumeration to represent the null
-// value for the `Value` type union.
+// `NullValue` is a singleton enumeration to represent the null value for the
+// `Value` type union.
+//
+//  The JSON representation for `NullValue` is JSON `null`.
 enum NullValue {
   // Null value.
   NULL_VALUE = 0;
 }
+
+// `ListValue` is a wrapper around a repeated field of values.
+//
+// The JSON representation for `ListValue` is JSON array.
+message ListValue {
+  // Repeated field of dynamically typed values.
+  repeated Value values = 1;
+}
diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc
index d470fc7..54dbafab 100644
--- a/src/google/protobuf/stubs/common.cc
+++ b/src/google/protobuf/stubs/common.cc
@@ -35,8 +35,10 @@
 #include <google/protobuf/stubs/status.h>
 #include <google/protobuf/stubs/stringpiece.h>
 #include <google/protobuf/stubs/strutil.h>
-#include <stdio.h>
+#include <google/protobuf/stubs/int128.h>
 #include <errno.h>
+#include <sstream>
+#include <stdio.h>
 #include <vector>
 
 #ifdef _WIN32
@@ -48,6 +50,9 @@
 #else
 #error "No suitable threading library available."
 #endif
+#if defined(__ANDROID__)
+#include <android/log.h>
+#endif
 
 namespace google {
 namespace protobuf {
@@ -104,7 +109,43 @@
 // emulates google3/base/logging.cc
 
 namespace internal {
+#if defined(__ANDROID__)
+inline void DefaultLogHandler(LogLevel level, const char* filename, int line,
+                              const string& message) {
+#ifdef GOOGLE_PROTOBUF_MIN_LOG_LEVEL
+  if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) {
+    return;
+  }
+  static const char* level_names[] = {"INFO", "WARNING", "ERROR", "FATAL"};
 
+  static const int android_log_levels[] = {
+      ANDROID_LOG_INFO,   // LOG(INFO),
+      ANDROID_LOG_WARN,   // LOG(WARNING)
+      ANDROID_LOG_ERROR,  // LOG(ERROR)
+      ANDROID_LOG_FATAL,  // LOG(FATAL)
+  };
+
+  // Bound the logging level.
+  const int android_log_level = android_log_levels[level];
+  ::std::ostringstream ostr;
+  ostr << "[libprotobuf " << level_names[level] << " " << filename << ":"
+       << line << "] " << message.c_str();
+
+  // Output the log string the Android log at the appropriate level.
+  __android_log_write(android_log_level, "libprotobuf-native",
+                      ostr.str().c_str());
+  // Also output to std::cerr.
+  fprintf(stderr, "%s", ostr.str().c_str());
+  fflush(stderr);
+
+  // Indicate termination if needed.
+  if (android_log_level == ANDROID_LOG_FATAL) {
+    __android_log_write(ANDROID_LOG_FATAL, "libprotobuf-native",
+                        "terminating.\n");
+  }
+#endif
+}
+#else
 void DefaultLogHandler(LogLevel level, const char* filename, int line,
                        const string& message) {
   static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" };
@@ -115,6 +156,7 @@
           level_names[level], filename, line, message.c_str());
   fflush(stderr);  // Needed on MSVC.
 }
+#endif
 
 void NullLogHandler(LogLevel /* level */, const char* /* filename */,
                     int /* line */, const string& /* message */) {
@@ -154,22 +196,19 @@
   return *this;
 }
 
-LogMessage& LogMessage::operator<<(long long value) {
-  message_ += SimpleItoa(value);
-  return *this;
-}
-
-LogMessage& LogMessage::operator<<(unsigned long long value) {
-  message_ += SimpleItoa(value);
-  return *this;
-}
-
 LogMessage& LogMessage::operator<<(
     const ::google::protobuf::util::Status& status) {
   message_ += status.ToString();
   return *this;
 }
 
+LogMessage& LogMessage::operator<<(const uint128& value) {
+  std::ostringstream str;
+  str << value;
+  message_ += str.str();
+  return *this;
+}
+
 // Since this is just for logging, we don't care if the current locale changes
 // the results -- in fact, we probably prefer that.  So we use snprintf()
 // instead of Simple*toa().
@@ -194,6 +233,8 @@
 DECLARE_STREAM_OPERATOR(unsigned long, "%lu")
 DECLARE_STREAM_OPERATOR(double       , "%g" )
 DECLARE_STREAM_OPERATOR(void*        , "%p" )
+DECLARE_STREAM_OPERATOR(long long         , "%" GOOGLE_LL_FORMAT "d")
+DECLARE_STREAM_OPERATOR(unsigned long long, "%" GOOGLE_LL_FORMAT "u")
 #undef DECLARE_STREAM_OPERATOR
 
 LogMessage::LogMessage(LogLevel level, const char* filename, int line)
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index de866e1..88e7084 100644
--- a/src/google/protobuf/stubs/common.h
+++ b/src/google/protobuf/stubs/common.h
@@ -35,6 +35,7 @@
 #ifndef GOOGLE_PROTOBUF_COMMON_H__
 #define GOOGLE_PROTOBUF_COMMON_H__
 
+#include <string>
 
 #include <google/protobuf/stubs/port.h>
 #include <google/protobuf/stubs/macros.h>
@@ -137,12 +138,35 @@
 // ===================================================================
 // from google3/util/utf8/public/unilib.h
 
+class StringPiece;
 namespace internal {
 
 // Checks if the buffer contains structurally-valid UTF-8.  Implemented in
 // structurally_valid.cc.
 LIBPROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len);
 
+inline bool IsStructurallyValidUTF8(const std::string& str) {
+  return IsStructurallyValidUTF8(str.data(), str.length());
+}
+
+// Returns initial number of bytes of structually valid UTF-8.
+LIBPROTOBUF_EXPORT int UTF8SpnStructurallyValid(const StringPiece& str);
+
+// Coerce UTF-8 byte string in src_str to be
+// a structurally-valid equal-length string by selectively
+// overwriting illegal bytes with replace_char (typically ' ' or '?').
+// replace_char must be legal printable 7-bit Ascii 0x20..0x7e.
+// src_str is read-only.
+//
+// Returns pointer to output buffer, src_str.data() if no changes were made,
+//  or idst if some bytes were changed. idst is allocated by the caller
+//  and must be at least as big as src_str
+//
+// Optimized for: all structurally valid and no byte copying is done.
+//
+LIBPROTOBUF_EXPORT char* UTF8CoerceToStructurallyValid(
+    const StringPiece& str, char* dst, char replace_char);
+
 }  // namespace internal
 
 
diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h
index 9a6b217..0d94ad8 100755
--- a/src/google/protobuf/stubs/hash.h
+++ b/src/google/protobuf/stubs/hash.h
@@ -143,6 +143,21 @@
 # define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
 #endif
 
+#ifndef GOOGLE_PROTOBUF_HASH_NAMESPACE
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END
+#elif !defined(GOOGLE_PROTOBUF_HAS_CXX11_HASH) &&       \
+  defined(GOOGLE_PROTOBUF_HAS_TR1)
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START       \
+  namespace std {                                               \
+  namespace tr1 {
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END }}
+#else
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START       \
+  namespace GOOGLE_PROTOBUF_HASH_NAMESPACE {
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END }
+#endif
+
 #undef GOOGLE_PROTOBUF_HAS_CXX11_HASH
 #undef GOOGLE_PROTOBUF_HAS_TR1
 
diff --git a/src/google/protobuf/stubs/int128.cc b/src/google/protobuf/stubs/int128.cc
new file mode 100644
index 0000000..9f4fb82
--- /dev/null
+++ b/src/google/protobuf/stubs/int128.cc
@@ -0,0 +1,200 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/stubs/int128.h>
+
+#include <iomanip>
+#include <iostream>  // NOLINT(readability/streams)
+#include <sstream>
+
+namespace google {
+namespace protobuf {
+
+const uint128_pod kuint128max = {
+    static_cast<uint64>(GOOGLE_LONGLONG(0xFFFFFFFFFFFFFFFF)),
+    static_cast<uint64>(GOOGLE_LONGLONG(0xFFFFFFFFFFFFFFFF))
+};
+
+// Returns the 0-based position of the last set bit (i.e., most significant bit)
+// in the given uint64. The argument may not be 0.
+//
+// For example:
+//   Given: 5 (decimal) == 101 (binary)
+//   Returns: 2
+#define STEP(T, n, pos, sh)                   \
+  do {                                        \
+    if ((n) >= (static_cast<T>(1) << (sh))) { \
+      (n) = (n) >> (sh);                      \
+      (pos) |= (sh);                          \
+    }                                         \
+  } while (0)
+static inline int Fls64(uint64 n) {
+  GOOGLE_DCHECK_NE(0, n);
+  int pos = 0;
+  STEP(uint64, n, pos, 0x20);
+  uint32 n32 = n;
+  STEP(uint32, n32, pos, 0x10);
+  STEP(uint32, n32, pos, 0x08);
+  STEP(uint32, n32, pos, 0x04);
+  return pos + ((GOOGLE_ULONGLONG(0x3333333322221100) >> (n32 << 2)) & 0x3);
+}
+#undef STEP
+
+// Like Fls64() above, but returns the 0-based position of the last set bit
+// (i.e., most significant bit) in the given uint128. The argument may not be 0.
+static inline int Fls128(uint128 n) {
+  if (uint64 hi = Uint128High64(n)) {
+    return Fls64(hi) + 64;
+  }
+  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) {
+    *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;
+    }
+    position >>= 1;
+    denominator >>= 1;
+  }
+
+  *quotient_ret = quotient;
+  *remainder_ret = dividend;
+}
+
+uint128& uint128::operator/=(const uint128& divisor) {
+  uint128 quotient = 0;
+  uint128 remainder = 0;
+  DivModImpl(*this, divisor, &quotient, &remainder);
+  *this = quotient;
+  return *this;
+}
+uint128& uint128::operator%=(const uint128& divisor) {
+  uint128 quotient = 0;
+  uint128 remainder = 0;
+  DivModImpl(*this, divisor, &quotient, &remainder);
+  *this = remainder;
+  return *this;
+}
+
+std::ostream& operator<<(std::ostream& o, const uint128& b) {
+  std::ios_base::fmtflags flags = o.flags();
+
+  // Select a divisor which is the largest power of the base < 2^64.
+  uint128 div;
+  std::streamsize div_base_log;
+  switch (flags & std::ios::basefield) {
+    case std::ios::hex:
+      div = GOOGLE_ULONGLONG(0x1000000000000000);  // 16^15
+      div_base_log = 15;
+      break;
+    case std::ios::oct:
+      div = GOOGLE_ULONGLONG(01000000000000000000000);  // 8^21
+      div_base_log = 21;
+      break;
+    default:  // std::ios::dec
+      div = GOOGLE_ULONGLONG(10000000000000000000);  // 10^19
+      div_base_log = 19;
+      break;
+  }
+
+  // Now piece together the uint128 representation from three chunks of
+  // the original value, each less than "div" and therefore representable
+  // as a uint64.
+  std::ostringstream os;
+  std::ios_base::fmtflags copy_mask =
+      std::ios::basefield | std::ios::showbase | std::ios::uppercase;
+  os.setf(flags & copy_mask, copy_mask);
+  uint128 high = b;
+  uint128 low;
+  uint128::DivModImpl(high, div, &high, &low);
+  uint128 mid;
+  uint128::DivModImpl(high, div, &high, &mid);
+  if (high.lo_ != 0) {
+    os << high.lo_;
+    os << std::noshowbase << std::setfill('0') << std::setw(div_base_log);
+    os << mid.lo_;
+    os << std::setw(div_base_log);
+  } else if (mid.lo_ != 0) {
+    os << mid.lo_;
+    os << std::noshowbase << std::setfill('0') << std::setw(div_base_log);
+  }
+  os << low.lo_;
+  std::string rep = os.str();
+
+  // Add the requisite padding.
+  std::streamsize width = o.width(0);
+  if (width > rep.size()) {
+    if ((flags & std::ios::adjustfield) == std::ios::left) {
+      rep.append(width - rep.size(), o.fill());
+    } else {
+      rep.insert(0, width - rep.size(), o.fill());
+    }
+  }
+
+  // Stream the final representation in a single "<<" call.
+  return o << rep;
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/stubs/int128.h b/src/google/protobuf/stubs/int128.h
new file mode 100644
index 0000000..1e63037
--- /dev/null
+++ b/src/google/protobuf/stubs/int128.h
@@ -0,0 +1,381 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#ifndef GOOGLE_PROTOBUF_STUBS_INT128_H_
+#define GOOGLE_PROTOBUF_STUBS_INT128_H_
+
+#include <google/protobuf/stubs/common.h>
+
+#include <iosfwd>
+
+namespace google {
+namespace protobuf {
+
+struct uint128_pod;
+
+// TODO(xiaofeng): Define GOOGLE_PROTOBUF_HAS_CONSTEXPR when constexpr is
+// available.
+#ifdef GOOGLE_PROTOBUF_HAS_CONSTEXPR
+# define UINT128_CONSTEXPR constexpr
+#else
+# define UINT128_CONSTEXPR
+#endif
+
+// An unsigned 128-bit integer type. Thread-compatible.
+class uint128 {
+ public:
+  UINT128_CONSTEXPR uint128();  // Sets to 0, but don't trust on this behavior.
+  UINT128_CONSTEXPR uint128(uint64 top, uint64 bottom);
+#ifndef SWIG
+  UINT128_CONSTEXPR uint128(int bottom);
+  UINT128_CONSTEXPR uint128(uint32 bottom);   // Top 96 bits = 0
+#endif
+  UINT128_CONSTEXPR uint128(uint64 bottom);   // hi_ = 0
+  UINT128_CONSTEXPR uint128(const uint128_pod &val);
+
+  // Trivial copy constructor, assignment operator and destructor.
+
+  void Initialize(uint64 top, uint64 bottom);
+
+  // Arithmetic operators.
+  uint128& operator+=(const uint128& b);
+  uint128& operator-=(const uint128& b);
+  uint128& operator*=(const uint128& b);
+  // Long division/modulo for uint128.
+  uint128& operator/=(const uint128& b);
+  uint128& operator%=(const uint128& b);
+  uint128 operator++(int);
+  uint128 operator--(int);
+  uint128& operator<<=(int);
+  uint128& operator>>=(int);
+  uint128& operator&=(const uint128& b);
+  uint128& operator|=(const uint128& b);
+  uint128& operator^=(const uint128& b);
+  uint128& operator++();
+  uint128& operator--();
+
+  friend uint64 Uint128Low64(const uint128& v);
+  friend uint64 Uint128High64(const uint128& v);
+
+  // We add "std::" to avoid including all of port.h.
+  friend std::ostream& operator<<(std::ostream& o, const uint128& b);
+
+ private:
+  static void DivModImpl(uint128 dividend, uint128 divisor,
+                         uint128* quotient_ret, uint128* remainder_ret);
+
+  // Little-endian memory order optimizations can benefit from
+  // having lo_ first, hi_ last.
+  // See util/endian/endian.h and Load128/Store128 for storing a uint128.
+  uint64        lo_;
+  uint64        hi_;
+
+  // Not implemented, just declared for catching automatic type conversions.
+  uint128(uint8);
+  uint128(uint16);
+  uint128(float v);
+  uint128(double v);
+};
+
+// This is a POD form of uint128 which can be used for static variables which
+// need to be operated on as uint128.
+struct uint128_pod {
+  // Note: The ordering of fields is different than 'class uint128' but the
+  // same as its 2-arg constructor.  This enables more obvious initialization
+  // of static instances, which is the primary reason for this struct in the
+  // first place.  This does not seem to defeat any optimizations wrt
+  // operations involving this struct.
+  uint64 hi;
+  uint64 lo;
+};
+
+extern const uint128_pod kuint128max;
+
+// allow uint128 to be logged
+extern std::ostream& operator<<(std::ostream& o, const uint128& b);
+
+// Methods to access low and high pieces of 128-bit value.
+// Defined externally from uint128 to facilitate conversion
+// to native 128-bit types when compilers support them.
+inline uint64 Uint128Low64(const uint128& v) { return v.lo_; }
+inline uint64 Uint128High64(const uint128& v) { return v.hi_; }
+
+// TODO: perhaps it would be nice to have int128, a signed 128-bit type?
+
+// --------------------------------------------------------------------------
+//                      Implementation details follow
+// --------------------------------------------------------------------------
+inline bool operator==(const uint128& lhs, const uint128& rhs) {
+  return (Uint128Low64(lhs) == Uint128Low64(rhs) &&
+          Uint128High64(lhs) == Uint128High64(rhs));
+}
+inline bool operator!=(const uint128& lhs, const uint128& rhs) {
+  return !(lhs == rhs);
+}
+
+inline UINT128_CONSTEXPR uint128::uint128() : lo_(0), hi_(0) {}
+inline UINT128_CONSTEXPR uint128::uint128(uint64 top, uint64 bottom)
+    : lo_(bottom), hi_(top) {}
+inline UINT128_CONSTEXPR uint128::uint128(const uint128_pod& v)
+    : lo_(v.lo), hi_(v.hi) {}
+inline UINT128_CONSTEXPR uint128::uint128(uint64 bottom)
+    : lo_(bottom), hi_(0) {}
+#ifndef SWIG
+inline UINT128_CONSTEXPR uint128::uint128(uint32 bottom)
+    : lo_(bottom), hi_(0) {}
+inline UINT128_CONSTEXPR uint128::uint128(int bottom)
+    : lo_(bottom), hi_(static_cast<int64>((bottom < 0) ? -1 : 0)) {}
+#endif
+
+#undef UINT128_CONSTEXPR
+
+inline void uint128::Initialize(uint64 top, uint64 bottom) {
+  hi_ = top;
+  lo_ = bottom;
+}
+
+// Comparison operators.
+
+#define CMP128(op)                                                \
+inline bool operator op(const uint128& lhs, const uint128& rhs) { \
+  return (Uint128High64(lhs) == Uint128High64(rhs)) ?             \
+      (Uint128Low64(lhs) op Uint128Low64(rhs)) :                  \
+      (Uint128High64(lhs) op Uint128High64(rhs));                 \
+}
+
+CMP128(<)
+CMP128(>)
+CMP128(>=)
+CMP128(<=)
+
+#undef CMP128
+
+// Unary operators
+
+inline uint128 operator-(const uint128& val) {
+  const uint64 hi_flip = ~Uint128High64(val);
+  const uint64 lo_flip = ~Uint128Low64(val);
+  const uint64 lo_add = lo_flip + 1;
+  if (lo_add < lo_flip) {
+    return uint128(hi_flip + 1, lo_add);
+  }
+  return uint128(hi_flip, lo_add);
+}
+
+inline bool operator!(const uint128& val) {
+  return !Uint128High64(val) && !Uint128Low64(val);
+}
+
+// Logical operators.
+
+inline uint128 operator~(const uint128& val) {
+  return uint128(~Uint128High64(val), ~Uint128Low64(val));
+}
+
+#define LOGIC128(op)                                                 \
+inline uint128 operator op(const uint128& lhs, const uint128& rhs) { \
+  return uint128(Uint128High64(lhs) op Uint128High64(rhs),           \
+                 Uint128Low64(lhs) op Uint128Low64(rhs));            \
+}
+
+LOGIC128(|)
+LOGIC128(&)
+LOGIC128(^)
+
+#undef LOGIC128
+
+#define LOGICASSIGN128(op)                                   \
+inline uint128& uint128::operator op(const uint128& other) { \
+  hi_ op other.hi_;                                          \
+  lo_ op other.lo_;                                          \
+  return *this;                                              \
+}
+
+LOGICASSIGN128(|=)
+LOGICASSIGN128(&=)
+LOGICASSIGN128(^=)
+
+#undef LOGICASSIGN128
+
+// Shift operators.
+
+inline uint128 operator<<(const uint128& val, int amount) {
+  // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+  if (amount < 64) {
+    if (amount == 0) {
+      return val;
+    }
+    uint64 new_hi = (Uint128High64(val) << amount) |
+                    (Uint128Low64(val) >> (64 - amount));
+    uint64 new_lo = Uint128Low64(val) << amount;
+    return uint128(new_hi, new_lo);
+  } else if (amount < 128) {
+    return uint128(Uint128Low64(val) << (amount - 64), 0);
+  } else {
+    return uint128(0, 0);
+  }
+}
+
+inline uint128 operator>>(const uint128& val, int amount) {
+  // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+  if (amount < 64) {
+    if (amount == 0) {
+      return val;
+    }
+    uint64 new_hi = Uint128High64(val) >> amount;
+    uint64 new_lo = (Uint128Low64(val) >> amount) |
+                    (Uint128High64(val) << (64 - amount));
+    return uint128(new_hi, new_lo);
+  } else if (amount < 128) {
+    return uint128(0, Uint128High64(val) >> (amount - 64));
+  } else {
+    return uint128(0, 0);
+  }
+}
+
+inline uint128& uint128::operator<<=(int amount) {
+  // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+  if (amount < 64) {
+    if (amount != 0) {
+      hi_ = (hi_ << amount) | (lo_ >> (64 - amount));
+      lo_ = lo_ << amount;
+    }
+  } else if (amount < 128) {
+    hi_ = lo_ << (amount - 64);
+    lo_ = 0;
+  } else {
+    hi_ = 0;
+    lo_ = 0;
+  }
+  return *this;
+}
+
+inline uint128& uint128::operator>>=(int amount) {
+  // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+  if (amount < 64) {
+    if (amount != 0) {
+      lo_ = (lo_ >> amount) | (hi_ << (64 - amount));
+      hi_ = hi_ >> amount;
+    }
+  } else if (amount < 128) {
+    lo_ = hi_ >> (amount - 64);
+    hi_ = 0;
+  } else {
+    lo_ = 0;
+    hi_ = 0;
+  }
+  return *this;
+}
+
+inline uint128 operator+(const uint128& lhs, const uint128& rhs) {
+  return uint128(lhs) += rhs;
+}
+
+inline uint128 operator-(const uint128& lhs, const uint128& rhs) {
+  return uint128(lhs) -= rhs;
+}
+
+inline uint128 operator*(const uint128& lhs, const uint128& rhs) {
+  return uint128(lhs) *= rhs;
+}
+
+inline uint128 operator/(const uint128& lhs, const uint128& rhs) {
+  return uint128(lhs) /= rhs;
+}
+
+inline uint128 operator%(const uint128& lhs, const uint128& rhs) {
+  return uint128(lhs) %= rhs;
+}
+
+inline uint128& uint128::operator+=(const uint128& b) {
+  hi_ += b.hi_;
+  uint64 lolo = lo_ + b.lo_;
+  if (lolo < lo_)
+    ++hi_;
+  lo_ = lolo;
+  return *this;
+}
+
+inline uint128& uint128::operator-=(const uint128& b) {
+  hi_ -= b.hi_;
+  if (b.lo_ > lo_)
+    --hi_;
+  lo_ -= b.lo_;
+  return *this;
+}
+
+inline uint128& uint128::operator*=(const uint128& b) {
+  uint64 a96 = hi_ >> 32;
+  uint64 a64 = hi_ & 0xffffffffu;
+  uint64 a32 = lo_ >> 32;
+  uint64 a00 = lo_ & 0xffffffffu;
+  uint64 b96 = b.hi_ >> 32;
+  uint64 b64 = b.hi_ & 0xffffffffu;
+  uint64 b32 = b.lo_ >> 32;
+  uint64 b00 = b.lo_ & 0xffffffffu;
+  // multiply [a96 .. a00] x [b96 .. b00]
+  // terms higher than c96 disappear off the high side
+  // terms c96 and c64 are safe to ignore carry bit
+  uint64 c96 = a96 * b00 + a64 * b32 + a32 * b64 + a00 * b96;
+  uint64 c64 = a64 * b00 + a32 * b32 + a00 * b64;
+  this->hi_ = (c96 << 32) + c64;
+  this->lo_ = 0;
+  // add terms after this one at a time to capture carry
+  *this += uint128(a32 * b00) << 32;
+  *this += uint128(a00 * b32) << 32;
+  *this += a00 * b00;
+  return *this;
+}
+
+inline uint128 uint128::operator++(int) {
+  uint128 tmp(*this);
+  *this += 1;
+  return tmp;
+}
+
+inline uint128 uint128::operator--(int) {
+  uint128 tmp(*this);
+  *this -= 1;
+  return tmp;
+}
+
+inline uint128& uint128::operator++() {
+  *this += 1;
+  return *this;
+}
+
+inline uint128& uint128::operator--() {
+  *this -= 1;
+  return *this;
+}
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_STUBS_INT128_H_
diff --git a/src/google/protobuf/stubs/int128_unittest.cc b/src/google/protobuf/stubs/int128_unittest.cc
new file mode 100644
index 0000000..5d33292
--- /dev/null
+++ b/src/google/protobuf/stubs/int128_unittest.cc
@@ -0,0 +1,513 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/stubs/int128.h>
+
+#include <algorithm>
+#include <sstream>
+#include <utility>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+TEST(Int128, AllTests) {
+  uint128 zero(0);
+  uint128 one(1);
+  uint128 one_2arg(0, 1);
+  uint128 two(0, 2);
+  uint128 three(0, 3);
+  uint128 big(2000, 2);
+  uint128 big_minus_one(2000, 1);
+  uint128 bigger(2001, 1);
+  uint128 biggest(kuint128max);
+  uint128 high_low(1, 0);
+  uint128 low_high(0, kuint64max);
+  EXPECT_LT(one, two);
+  EXPECT_GT(two, one);
+  EXPECT_LT(one, big);
+  EXPECT_LT(one, big);
+  EXPECT_EQ(one, one_2arg);
+  EXPECT_NE(one, two);
+  EXPECT_GT(big, one);
+  EXPECT_GE(big, two);
+  EXPECT_GE(big, big_minus_one);
+  EXPECT_GT(big, big_minus_one);
+  EXPECT_LT(big_minus_one, big);
+  EXPECT_LE(big_minus_one, big);
+  EXPECT_NE(big_minus_one, big);
+  EXPECT_LT(big, biggest);
+  EXPECT_LE(big, biggest);
+  EXPECT_GT(biggest, big);
+  EXPECT_GE(biggest, big);
+  EXPECT_EQ(big, ~~big);
+  EXPECT_EQ(one, one | one);
+  EXPECT_EQ(big, big | big);
+  EXPECT_EQ(one, one | zero);
+  EXPECT_EQ(one, one & one);
+  EXPECT_EQ(big, big & big);
+  EXPECT_EQ(zero, one & zero);
+  EXPECT_EQ(zero, big & ~big);
+  EXPECT_EQ(zero, one ^ one);
+  EXPECT_EQ(zero, big ^ big);
+  EXPECT_EQ(one, one ^ zero);
+
+  // Shift operators.
+  EXPECT_EQ(big, big << 0);
+  EXPECT_EQ(big, big >> 0);
+  EXPECT_GT(big << 1, big);
+  EXPECT_LT(big >> 1, big);
+  EXPECT_EQ(big, (big << 10) >> 10);
+  EXPECT_EQ(big, (big >> 1) << 1);
+  EXPECT_EQ(one, (one << 80) >> 80);
+  EXPECT_EQ(zero, (one >> 80) << 80);
+  EXPECT_EQ(zero, big >> 128);
+  EXPECT_EQ(zero, big << 128);
+
+  // Shift assignments.
+  uint128 big_copy = big;
+  EXPECT_EQ(big << 0, big_copy <<= 0);
+  big_copy = big;
+  EXPECT_EQ(big >> 0, big_copy >>= 0);
+  big_copy = big;
+  EXPECT_EQ(big << 1, big_copy <<= 1);
+  big_copy = big;
+  EXPECT_EQ(big >> 1, big_copy >>= 1);
+  big_copy = big;
+  EXPECT_EQ(big << 10, big_copy <<= 10);
+  big_copy = big;
+  EXPECT_EQ(big >> 10, big_copy >>= 10);
+  big_copy = big;
+  EXPECT_EQ(big << 64, big_copy <<= 64);
+  big_copy = big;
+  EXPECT_EQ(big >> 64, big_copy >>= 64);
+  big_copy = big;
+  EXPECT_EQ(big << 73, big_copy <<= 73);
+  big_copy = big;
+  EXPECT_EQ(big >> 73, big_copy >>= 73);
+  big_copy = big;
+  EXPECT_EQ(big << 128, big_copy <<= 128);
+  big_copy = big;
+  EXPECT_EQ(big >> 128, big_copy >>= 128);
+
+  EXPECT_EQ(Uint128High64(biggest), kuint64max);
+  EXPECT_EQ(Uint128Low64(biggest), kuint64max);
+  EXPECT_EQ(zero + one, one);
+  EXPECT_EQ(one + one, two);
+  EXPECT_EQ(big_minus_one + one, big);
+  EXPECT_EQ(one - one, zero);
+  EXPECT_EQ(one - zero, one);
+  EXPECT_EQ(zero - one, biggest);
+  EXPECT_EQ(big - big, zero);
+  EXPECT_EQ(big - one, big_minus_one);
+  EXPECT_EQ(big + kuint64max, bigger);
+  EXPECT_EQ(biggest + 1, zero);
+  EXPECT_EQ(zero - 1, biggest);
+  EXPECT_EQ(high_low - one, low_high);
+  EXPECT_EQ(low_high + one, high_low);
+  EXPECT_EQ(Uint128High64((uint128(1) << 64) - 1), 0);
+  EXPECT_EQ(Uint128Low64((uint128(1) << 64) - 1), kuint64max);
+  EXPECT_TRUE(!!one);
+  EXPECT_TRUE(!!high_low);
+  EXPECT_FALSE(!!zero);
+  EXPECT_FALSE(!one);
+  EXPECT_FALSE(!high_low);
+  EXPECT_TRUE(!zero);
+  EXPECT_TRUE(zero == 0);
+  EXPECT_FALSE(zero != 0);
+  EXPECT_FALSE(one == 0);
+  EXPECT_TRUE(one != 0);
+
+  uint128 test = zero;
+  EXPECT_EQ(++test, one);
+  EXPECT_EQ(test, one);
+  EXPECT_EQ(test++, one);
+  EXPECT_EQ(test, two);
+  EXPECT_EQ(test -= 2, zero);
+  EXPECT_EQ(test, zero);
+  EXPECT_EQ(test += 2, two);
+  EXPECT_EQ(test, two);
+  EXPECT_EQ(--test, one);
+  EXPECT_EQ(test, one);
+  EXPECT_EQ(test--, one);
+  EXPECT_EQ(test, zero);
+  EXPECT_EQ(test |= three, three);
+  EXPECT_EQ(test &= one, one);
+  EXPECT_EQ(test ^= three, two);
+  EXPECT_EQ(test >>= 1, one);
+  EXPECT_EQ(test <<= 1, two);
+
+  EXPECT_EQ(big, -(-big));
+  EXPECT_EQ(two, -((-one) - 1));
+  EXPECT_EQ(kuint128max, -one);
+  EXPECT_EQ(zero, -zero);
+
+  GOOGLE_LOG(INFO) << one;
+  GOOGLE_LOG(INFO) << big_minus_one;
+}
+
+TEST(Int128, PodTests) {
+  uint128_pod pod = { 12345, 67890 };
+  uint128 from_pod(pod);
+  EXPECT_EQ(12345, Uint128High64(from_pod));
+  EXPECT_EQ(67890, Uint128Low64(from_pod));
+
+  uint128 zero(0);
+  uint128_pod zero_pod = {0, 0};
+  uint128 one(1);
+  uint128_pod one_pod = {0, 1};
+  uint128 two(2);
+  uint128_pod two_pod = {0, 2};
+  uint128 three(3);
+  uint128_pod three_pod = {0, 3};
+  uint128 big(1, 0);
+  uint128_pod big_pod = {1, 0};
+
+  EXPECT_EQ(zero, zero_pod);
+  EXPECT_EQ(zero_pod, zero);
+  EXPECT_EQ(zero_pod, zero_pod);
+  EXPECT_EQ(one, one_pod);
+  EXPECT_EQ(one_pod, one);
+  EXPECT_EQ(one_pod, one_pod);
+  EXPECT_EQ(two, two_pod);
+  EXPECT_EQ(two_pod, two);
+  EXPECT_EQ(two_pod, two_pod);
+
+  EXPECT_NE(one, two_pod);
+  EXPECT_NE(one_pod, two);
+  EXPECT_NE(one_pod, two_pod);
+
+  EXPECT_LT(one, two_pod);
+  EXPECT_LT(one_pod, two);
+  EXPECT_LT(one_pod, two_pod);
+  EXPECT_LE(one, one_pod);
+  EXPECT_LE(one_pod, one);
+  EXPECT_LE(one_pod, one_pod);
+  EXPECT_LE(one, two_pod);
+  EXPECT_LE(one_pod, two);
+  EXPECT_LE(one_pod, two_pod);
+
+  EXPECT_GT(two, one_pod);
+  EXPECT_GT(two_pod, one);
+  EXPECT_GT(two_pod, one_pod);
+  EXPECT_GE(two, two_pod);
+  EXPECT_GE(two_pod, two);
+  EXPECT_GE(two_pod, two_pod);
+  EXPECT_GE(two, one_pod);
+  EXPECT_GE(two_pod, one);
+  EXPECT_GE(two_pod, one_pod);
+
+  EXPECT_EQ(three, one | two_pod);
+  EXPECT_EQ(three, one_pod | two);
+  EXPECT_EQ(three, one_pod | two_pod);
+  EXPECT_EQ(one, three & one_pod);
+  EXPECT_EQ(one, three_pod & one);
+  EXPECT_EQ(one, three_pod & one_pod);
+  EXPECT_EQ(two, three ^ one_pod);
+  EXPECT_EQ(two, three_pod ^ one);
+  EXPECT_EQ(two, three_pod ^ one_pod);
+  EXPECT_EQ(two, three & (~one));
+  EXPECT_EQ(three, ~~three);
+
+  EXPECT_EQ(two, two_pod << 0);
+  EXPECT_EQ(two, one_pod << 1);
+  EXPECT_EQ(big, one_pod << 64);
+  EXPECT_EQ(zero, one_pod << 128);
+  EXPECT_EQ(two, two_pod >> 0);
+  EXPECT_EQ(one, two_pod >> 1);
+  EXPECT_EQ(one, big_pod >> 64);
+
+  EXPECT_EQ(one, zero + one_pod);
+  EXPECT_EQ(one, zero_pod + one);
+  EXPECT_EQ(one, zero_pod + one_pod);
+  EXPECT_EQ(one, two - one_pod);
+  EXPECT_EQ(one, two_pod - one);
+  EXPECT_EQ(one, two_pod - one_pod);
+}
+
+TEST(Int128, OperatorAssignReturnRef) {
+  uint128 v(1);
+  (v += 4) -= 3;
+  EXPECT_EQ(2, v);
+}
+
+TEST(Int128, Multiply) {
+  uint128 a, b, c;
+
+  // Zero test.
+  a = 0;
+  b = 0;
+  c = a * b;
+  EXPECT_EQ(0, c);
+
+  // Max carries.
+  a = uint128(0) - 1;
+  b = uint128(0) - 1;
+  c = a * b;
+  EXPECT_EQ(1, c);
+
+  // Self-operation with max carries.
+  c = uint128(0) - 1;
+  c *= c;
+  EXPECT_EQ(1, c);
+
+  // 1-bit x 1-bit.
+  for (int i = 0; i < 64; ++i) {
+    for (int j = 0; j < 64; ++j) {
+      a = uint128(1) << i;
+      b = uint128(1) << j;
+      c = a * b;
+      EXPECT_EQ(uint128(1) << (i+j), c);
+    }
+  }
+
+  // Verified with dc.
+  a = uint128(GOOGLE_ULONGLONG(0xffffeeeeddddcccc),
+              GOOGLE_ULONGLONG(0xbbbbaaaa99998888));
+  b = uint128(GOOGLE_ULONGLONG(0x7777666655554444),
+              GOOGLE_ULONGLONG(0x3333222211110000));
+  c = a * b;
+  EXPECT_EQ(uint128(GOOGLE_ULONGLONG(0x530EDA741C71D4C3),
+                    GOOGLE_ULONGLONG(0xBF25975319080000)), c);
+  EXPECT_EQ(0, c - b * a);
+  EXPECT_EQ(a*a - b*b, (a+b) * (a-b));
+
+  // Verified with dc.
+  a = uint128(GOOGLE_ULONGLONG(0x0123456789abcdef),
+              GOOGLE_ULONGLONG(0xfedcba9876543210));
+  b = uint128(GOOGLE_ULONGLONG(0x02468ace13579bdf),
+              GOOGLE_ULONGLONG(0xfdb97531eca86420));
+  c = a * b;
+  EXPECT_EQ(uint128(GOOGLE_ULONGLONG(0x97a87f4f261ba3f2),
+                    GOOGLE_ULONGLONG(0x342d0bbf48948200)), c);
+  EXPECT_EQ(0, c - b * a);
+  EXPECT_EQ(a*a - b*b, (a+b) * (a-b));
+}
+
+TEST(Int128, AliasTests) {
+  uint128 x1(1, 2);
+  uint128 x2(2, 4);
+  x1 += x1;
+  EXPECT_EQ(x2, x1);
+
+  uint128 x3(1, static_cast<uint64>(1) << 63);
+  uint128 x4(3, 0);
+  x3 += x3;
+  EXPECT_EQ(x4, x3);
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+TEST(Int128, DivideByZeroCheckFails) {
+  uint128 a = 0;
+  uint128 b = 0;
+  EXPECT_DEATH(a / b, "Division or mod by zero:");
+  a = 123;
+  EXPECT_DEATH(a / b, "Division or mod by zero:");
+}
+
+TEST(Int128, ModByZeroCheckFails) {
+  uint128 a = 0;
+  uint128 b = 0;
+  EXPECT_DEATH(a % b, "Division or mod by zero:");
+  a = 123;
+  EXPECT_DEATH(a % b, "Division or mod by zero:");
+}
+#endif  // PROTOBUF_HAS_DEATH_TEST
+
+TEST(Int128, DivideAndMod) {
+  // a := q * b + r
+  uint128 a, b, q, r;
+
+  // Zero test.
+  a = 0;
+  b = 123;
+  q = a / b;
+  r = a % b;
+  EXPECT_EQ(0, q);
+  EXPECT_EQ(0, r);
+
+  a = uint128(GOOGLE_ULONGLONG(0x530eda741c71d4c3),
+              GOOGLE_ULONGLONG(0xbf25975319080000));
+  q = uint128(GOOGLE_ULONGLONG(0x4de2cab081),
+              GOOGLE_ULONGLONG(0x14c34ab4676e4bab));
+  b = uint128(0x1110001);
+  r = uint128(0x3eb455);
+  ASSERT_EQ(a, q * b + r);  // Sanity-check.
+
+  uint128 result_q, result_r;
+  result_q = a / b;
+  result_r = a % b;
+  EXPECT_EQ(q, result_q);
+  EXPECT_EQ(r, result_r);
+
+  // Try the other way around.
+  swap(q, b);
+  result_q = a / b;
+  result_r = a % b;
+  EXPECT_EQ(q, result_q);
+  EXPECT_EQ(r, result_r);
+  // Restore.
+  swap(b, q);
+
+  // Dividend < divisor; result should be q:0 r:<dividend>.
+  swap(a, b);
+  result_q = a / b;
+  result_r = a % b;
+  EXPECT_EQ(0, result_q);
+  EXPECT_EQ(a, result_r);
+  // Try the other way around.
+  swap(a, q);
+  result_q = a / b;
+  result_r = a % b;
+  EXPECT_EQ(0, result_q);
+  EXPECT_EQ(a, result_r);
+  // Restore.
+  swap(q, a);
+  swap(b, a);
+
+  // Try a large remainder.
+  b = a / 2 + 1;
+  uint128 expected_r(GOOGLE_ULONGLONG(0x29876d3a0e38ea61),
+                     GOOGLE_ULONGLONG(0xdf92cba98c83ffff));
+  // Sanity checks.
+  ASSERT_EQ(a / 2 - 1, expected_r);
+  ASSERT_EQ(a, b + expected_r);
+  result_q = a / b;
+  result_r = a % b;
+  EXPECT_EQ(1, result_q);
+  EXPECT_EQ(expected_r, result_r);
+}
+
+static uint64 RandomUint64() {
+  uint64 v1 = rand();
+  uint64 v2 = rand();
+  uint64 v3 = rand();
+  return v1 * v2 + v3;
+}
+
+TEST(Int128, DivideAndModRandomInputs) {
+  const int kNumIters = 1 << 18;
+  for (int i = 0; i < kNumIters; ++i) {
+    const uint128 a(RandomUint64(), RandomUint64());
+    const uint128 b(RandomUint64(), RandomUint64());
+    if (b == 0) {
+      continue;  // Avoid a div-by-zero.
+    }
+    const uint128 q = a / b;
+    const uint128 r = a % b;
+    ASSERT_EQ(a, b * q + r);
+  }
+}
+
+#ifdef GOOGLE_PROTOBUF_HAS_CONSTEXPR
+TEST(Int128, ConstexprTest) {
+  constexpr uint128 zero;
+  constexpr uint128 one = 1;
+  constexpr uint128_pod pod = {2, 3};
+  constexpr uint128 from_pod = pod;
+  constexpr uint128 minus_two = -2;
+  EXPECT_EQ(one, uint128(1));
+  EXPECT_EQ(from_pod, uint128(2, 3));
+  EXPECT_EQ(minus_two, uint128(-1ULL, -2ULL));
+}
+
+TEST(Int128, Traits) {
+  EXPECT_TRUE(std::is_trivially_copy_constructible<uint128>::value);
+  EXPECT_TRUE(std::is_trivially_copy_assignable<uint128>::value);
+  EXPECT_TRUE(std::is_trivially_destructible<uint128>::value);
+}
+#endif  // GOOGLE_PROTOBUF_HAS_CONSTEXPR
+
+TEST(Int128, OStream) {
+  struct {
+    uint128 val;
+    std::ios_base::fmtflags flags;
+    std::streamsize width;
+    char fill;
+    const char* rep;
+  } cases[] = {
+        // zero with different bases
+        {uint128(0), std::ios::dec, 0, '_', "0"},
+        {uint128(0), std::ios::oct, 0, '_', "0"},
+        {uint128(0), std::ios::hex, 0, '_', "0"},
+        // crossover between lo_ and hi_
+        {uint128(0, -1), std::ios::dec, 0, '_', "18446744073709551615"},
+        {uint128(0, -1), std::ios::oct, 0, '_', "1777777777777777777777"},
+        {uint128(0, -1), std::ios::hex, 0, '_', "ffffffffffffffff"},
+        {uint128(1, 0), std::ios::dec, 0, '_', "18446744073709551616"},
+        {uint128(1, 0), std::ios::oct, 0, '_', "2000000000000000000000"},
+        {uint128(1, 0), std::ios::hex, 0, '_', "10000000000000000"},
+        // just the top bit
+        {uint128(GOOGLE_ULONGLONG(0x8000000000000000), 0), std::ios::dec, 0, '_',
+         "170141183460469231731687303715884105728"},
+        {uint128(GOOGLE_ULONGLONG(0x8000000000000000), 0), std::ios::oct, 0, '_',
+         "2000000000000000000000000000000000000000000"},
+        {uint128(GOOGLE_ULONGLONG(0x8000000000000000), 0), std::ios::hex, 0, '_',
+         "80000000000000000000000000000000"},
+        // maximum uint128 value
+        {uint128(-1, -1), std::ios::dec, 0, '_',
+         "340282366920938463463374607431768211455"},
+        {uint128(-1, -1), std::ios::oct, 0, '_',
+         "3777777777777777777777777777777777777777777"},
+        {uint128(-1, -1), std::ios::hex, 0, '_',
+         "ffffffffffffffffffffffffffffffff"},
+        // uppercase
+        {uint128(-1, -1), std::ios::hex | std::ios::uppercase, 0, '_',
+         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"},
+        // showbase
+        {uint128(1), std::ios::dec | std::ios::showbase, 0, '_', "1"},
+        {uint128(1), std::ios::oct | std::ios::showbase, 0, '_', "01"},
+        {uint128(1), std::ios::hex | std::ios::showbase, 0, '_', "0x1"},
+        // showbase does nothing on zero
+        {uint128(0), std::ios::dec | std::ios::showbase, 0, '_', "0"},
+        {uint128(0), std::ios::oct | std::ios::showbase, 0, '_', "0"},
+        {uint128(0), std::ios::hex | std::ios::showbase, 0, '_', "0"},
+        // showpos does nothing on unsigned types
+        {uint128(1), std::ios::dec | std::ios::showpos, 0, '_', "1"},
+        // padding
+        {uint128(9), std::ios::dec, 6, '_', "_____9"},
+        {uint128(12345), std::ios::dec, 6, '_', "_12345"},
+        // left adjustment
+        {uint128(9), std::ios::dec | std::ios::left, 6, '_', "9_____"},
+        {uint128(12345), std::ios::dec | std::ios::left, 6, '_', "12345_"},
+  };
+  for (size_t i = 0; i < GOOGLE_ARRAYSIZE(cases); ++i) {
+    ostringstream os;
+    os.flags(cases[i].flags);
+    os.width(cases[i].width);
+    os.fill(cases[i].fill);
+    os << cases[i].val;
+    EXPECT_EQ(cases[i].rep, os.str());
+  }
+}
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/stubs/logging.h b/src/google/protobuf/stubs/logging.h
index 330d33d..3108db8 100644
--- a/src/google/protobuf/stubs/logging.h
+++ b/src/google/protobuf/stubs/logging.h
@@ -65,6 +65,7 @@
 namespace util {
 class Status;
 }
+class uint128;
 namespace internal {
 
 class LogFinisher;
@@ -78,7 +79,7 @@
   LogMessage& operator<<(const char* value);
   LogMessage& operator<<(char value);
   LogMessage& operator<<(int value);
-  LogMessage& operator<<(unsigned int value);
+  LogMessage& operator<<(uint value);
   LogMessage& operator<<(long value);
   LogMessage& operator<<(unsigned long value);
   LogMessage& operator<<(long long value);
@@ -87,6 +88,7 @@
   LogMessage& operator<<(void* value);
   LogMessage& operator<<(const StringPiece& value);
   LogMessage& operator<<(const ::google::protobuf::util::Status& status);
+  LogMessage& operator<<(const uint128& value);
 
  private:
   friend class LogFinisher;
diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h
index 8a5d1a1..5ba04c7 100644
--- a/src/google/protobuf/stubs/port.h
+++ b/src/google/protobuf/stubs/port.h
@@ -100,20 +100,12 @@
 typedef signed char  int8;
 typedef short int16;
 typedef int int32;
-// NOTE: This should be "long long" for consistency with upstream, but
-// something is stacked against this particular type for 64bit hashing.
-// Switching it causes an obvious missing hash function (with an unobvious
-// cause) when building the tests.
-typedef int64_t int64;
+typedef long long int64;
 
 typedef unsigned char  uint8;
 typedef unsigned short uint16;
 typedef unsigned int uint32;
-// NOTE: This should be "unsigned long long" for consistency with upstream, but
-// something is stacked against this particular type for 64bit hashing.
-// Switching it causes an obvious missing hash function (with an unobvious
-// cause) when building the tests.
-typedef uint64_t uint64;
+typedef unsigned long long uint64;
 #endif
 
 // long long macros to be used because gcc and vc++ use different suffixes,
diff --git a/src/google/protobuf/stubs/structurally_valid.cc b/src/google/protobuf/stubs/structurally_valid.cc
index 0f6afe6..d79a6ee 100644
--- a/src/google/protobuf/stubs/structurally_valid.cc
+++ b/src/google/protobuf/stubs/structurally_valid.cc
@@ -3,6 +3,8 @@
 
 #include <google/protobuf/stubs/common.h>
 
+#include <google/protobuf/stubs/stringpiece.h>
+
 namespace google {
 namespace protobuf {
 namespace internal {
@@ -531,6 +533,56 @@
   return (bytes_consumed == len);
 }
 
+int UTF8SpnStructurallyValid(const StringPiece& str) {
+  if (!module_initialized_) return str.size();
+
+  int bytes_consumed = 0;
+  UTF8GenericScanFastAscii(&utf8acceptnonsurrogates_obj,
+                           str.data(), str.size(), &bytes_consumed);
+  return bytes_consumed;
+}
+
+// Coerce UTF-8 byte string in src_str to be
+// a structurally-valid equal-length string by selectively
+// overwriting illegal bytes with replace_char (typically blank).
+// replace_char must be legal printable 7-bit Ascii 0x20..0x7e.
+// src_str is read-only. If any overwriting is needed, a modified byte string
+// is created in idst, length isrclen.
+//
+// Returns pointer to output buffer, isrc if no changes were made,
+//  or idst if some bytes were changed.
+//
+// Fast case: all is structurally valid and no byte copying is done.
+//
+char* UTF8CoerceToStructurallyValid(const StringPiece& src_str,
+                                    char* idst,
+                                    const char replace_char) {
+  const char* isrc = src_str.data();
+  const int len = src_str.length();
+  int n = UTF8SpnStructurallyValid(src_str);
+  if (n == len) {               // Normal case -- all is cool, return
+    return const_cast<char*>(isrc);
+  } else {                      // Unusual case -- copy w/o bad bytes
+    const char* src = isrc;
+    const char* srclimit = isrc + len;
+    char* dst = idst;
+    memmove(dst, src, n);       // Copy initial good chunk
+    src += n;
+    dst += n;
+    while (src < srclimit) {    // src points to bogus byte or is off the end
+      dst[0] = replace_char;                    // replace one bad byte
+      src++;
+      dst++;
+      StringPiece str2(src, srclimit - src);
+      n = UTF8SpnStructurallyValid(str2);       // scan the remainder
+      memmove(dst, src, n);                     // copy next good chunk
+      src += n;
+      dst += n;
+    }
+  }
+  return idst;
+}
+
 }  // namespace internal
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/timestamp.proto b/src/google/protobuf/timestamp.proto
index 11f258d..06b60e6 100644
--- a/src/google/protobuf/timestamp.proto
+++ b/src/google/protobuf/timestamp.proto
@@ -38,7 +38,6 @@
 option csharp_namespace = "Google.Protobuf.WellKnownTypes";
 option objc_class_prefix = "GPB";
 
-
 // A Timestamp represents a point in time independent of any time zone
 // or calendar, represented as seconds and fractions of seconds at
 // nanosecond resolution in UTC Epoch time. It is encoded using the
@@ -85,14 +84,16 @@
 //     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
 //         .setNanos((int) ((millis % 1000) * 1000000)).build();
 //
-// Example 5: Compute Timestamp from Python `datetime.datetime`.
 //
-//     now = datetime.datetime.utcnow()
-//     seconds = int(time.mktime(now.timetuple()))
-//     nanos = now.microsecond * 1000
+// Example 5: Compute Timestamp from current time in Python.
+//
+//     now = time.time()
+//     seconds = int(now)
+//     nanos = int((now - seconds) * 10**9)
 //     timestamp = Timestamp(seconds=seconds, nanos=nanos)
 //
 message Timestamp {
+
   // Represents seconds of UTC time since Unix epoch
   // 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
   // 9999-12-31T23:59:59Z inclusive.
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc
index 029a72c..395553c 100644
--- a/src/google/protobuf/type.pb.cc
+++ b/src/google/protobuf/type.pb.cc
@@ -38,6 +38,7 @@
 const ::google::protobuf::Descriptor* Option_descriptor_ = NULL;
 const ::google::protobuf::internal::GeneratedMessageReflection*
   Option_reflection_ = NULL;
+const ::google::protobuf::EnumDescriptor* Syntax_descriptor_ = NULL;
 
 }  // namespace
 
@@ -49,12 +50,13 @@
       "google/protobuf/type.proto");
   GOOGLE_CHECK(file != NULL);
   Type_descriptor_ = file->message_type(0);
-  static const int Type_offsets_[5] = {
+  static const int Type_offsets_[6] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, name_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, fields_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, oneofs_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, options_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, source_context_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, syntax_),
   };
   Type_reflection_ =
     ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -68,7 +70,7 @@
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _internal_metadata_),
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _is_default_instance_));
   Field_descriptor_ = file->message_type(1);
-  static const int Field_offsets_[8] = {
+  static const int Field_offsets_[9] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, kind_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, cardinality_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, number_),
@@ -77,6 +79,7 @@
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, oneof_index_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, packed_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, options_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, json_name_),
   };
   Field_reflection_ =
     ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -92,11 +95,12 @@
   Field_Kind_descriptor_ = Field_descriptor_->enum_type(0);
   Field_Cardinality_descriptor_ = Field_descriptor_->enum_type(1);
   Enum_descriptor_ = file->message_type(2);
-  static const int Enum_offsets_[4] = {
+  static const int Enum_offsets_[5] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, name_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, enumvalue_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, options_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, source_context_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, syntax_),
   };
   Enum_reflection_ =
     ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -142,6 +146,7 @@
       sizeof(Option),
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, _internal_metadata_),
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, _is_default_instance_));
+  Syntax_descriptor_ = file->enum_type(0);
 }
 
 namespace {
@@ -192,38 +197,43 @@
   ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
     "\n\032google/protobuf/type.proto\022\017google.pro"
     "tobuf\032\031google/protobuf/any.proto\032$google"
-    "/protobuf/source_context.proto\"\256\001\n\004Type\022"
+    "/protobuf/source_context.proto\"\327\001\n\004Type\022"
     "\014\n\004name\030\001 \001(\t\022&\n\006fields\030\002 \003(\0132\026.google.p"
     "rotobuf.Field\022\016\n\006oneofs\030\003 \003(\t\022(\n\007options"
     "\030\004 \003(\0132\027.google.protobuf.Option\0226\n\016sourc"
     "e_context\030\005 \001(\0132\036.google.protobuf.Source"
-    "Context\"\233\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.google"
-    ".protobuf.Field.Kind\0227\n\013cardinality\030\002 \001("
-    "\0162\".google.protobuf.Field.Cardinality\022\016\n"
-    "\006number\030\003 \001(\005\022\014\n\004name\030\004 \001(\t\022\020\n\010type_url\030"
-    "\006 \001(\t\022\023\n\013oneof_index\030\007 \001(\005\022\016\n\006packed\030\010 \001"
-    "(\010\022(\n\007options\030\t \003(\0132\027.google.protobuf.Op"
-    "tion\"\270\002\n\004Kind\022\020\n\014TYPE_UNKNOWN\020\000\022\017\n\013TYPE_"
-    "DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003"
-    "\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYP"
-    "E_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_BO"
-    "OL\020\010\022\017\n\013TYPE_STRING\020\t\022\020\n\014TYPE_MESSAGE\020\013\022"
-    "\016\n\nTYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE"
-    "_ENUM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXE"
-    "D64\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\""
-    "t\n\013Cardinality\022\027\n\023CARDINALITY_UNKNOWN\020\000\022"
-    "\030\n\024CARDINALITY_OPTIONAL\020\001\022\030\n\024CARDINALITY"
-    "_REQUIRED\020\002\022\030\n\024CARDINALITY_REPEATED\020\003\"\245\001"
-    "\n\004Enum\022\014\n\004name\030\001 \001(\t\022-\n\tenumvalue\030\002 \003(\0132"
-    "\032.google.protobuf.EnumValue\022(\n\007options\030\003"
-    " \003(\0132\027.google.protobuf.Option\0226\n\016source_"
-    "context\030\004 \001(\0132\036.google.protobuf.SourceCo"
-    "ntext\"S\n\tEnumValue\022\014\n\004name\030\001 \001(\t\022\016\n\006numb"
-    "er\030\002 \001(\005\022(\n\007options\030\003 \003(\0132\027.google.proto"
-    "buf.Option\";\n\006Option\022\014\n\004name\030\001 \001(\t\022#\n\005va"
-    "lue\030\002 \001(\0132\024.google.protobuf.AnyBI\n\023com.g"
-    "oogle.protobufB\tTypeProtoP\001\242\002\003GPB\252\002\036Goog"
-    "le.Protobuf.WellKnownTypesb\006proto3", 1354);
+    "Context\022\'\n\006syntax\030\006 \001(\0162\027.google.protobu"
+    "f.Syntax\"\276\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.googl"
+    "e.protobuf.Field.Kind\0227\n\013cardinality\030\002 \001"
+    "(\0162\".google.protobuf.Field.Cardinality\022\016"
+    "\n\006number\030\003 \001(\005\022\014\n\004name\030\004 \001(\t\022\020\n\010type_url"
+    "\030\006 \001(\t\022\023\n\013oneof_index\030\007 \001(\005\022\016\n\006packed\030\010 "
+    "\001(\010\022(\n\007options\030\t \003(\0132\027.google.protobuf.O"
+    "ption\022\021\n\tjson_name\030\n \001(\t\"\310\002\n\004Kind\022\020\n\014TYP"
+    "E_UNKNOWN\020\000\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FLO"
+    "AT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n"
+    "\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE_"
+    "FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING\020"
+    "\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nT"
+    "YPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_ENU"
+    "M\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020"
+    "\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"t\n\013C"
+    "ardinality\022\027\n\023CARDINALITY_UNKNOWN\020\000\022\030\n\024C"
+    "ARDINALITY_OPTIONAL\020\001\022\030\n\024CARDINALITY_REQ"
+    "UIRED\020\002\022\030\n\024CARDINALITY_REPEATED\020\003\"\316\001\n\004En"
+    "um\022\014\n\004name\030\001 \001(\t\022-\n\tenumvalue\030\002 \003(\0132\032.go"
+    "ogle.protobuf.EnumValue\022(\n\007options\030\003 \003(\013"
+    "2\027.google.protobuf.Option\0226\n\016source_cont"
+    "ext\030\004 \001(\0132\036.google.protobuf.SourceContex"
+    "t\022\'\n\006syntax\030\005 \001(\0162\027.google.protobuf.Synt"
+    "ax\"S\n\tEnumValue\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030"
+    "\002 \001(\005\022(\n\007options\030\003 \003(\0132\027.google.protobuf"
+    ".Option\";\n\006Option\022\014\n\004name\030\001 \001(\t\022#\n\005value"
+    "\030\002 \001(\0132\024.google.protobuf.Any*.\n\006Syntax\022\021"
+    "\n\rSYNTAX_PROTO2\020\000\022\021\n\rSYNTAX_PROTO3\020\001BL\n\023"
+    "com.google.protobufB\tTypeProtoP\001\240\001\001\242\002\003GP"
+    "B\252\002\036Google.Protobuf.WellKnownTypesb\006prot"
+    "o3", 1522);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "google/protobuf/type.proto", &protobuf_RegisterTypes);
   Type::default_instance_ = new Type();
@@ -245,6 +255,20 @@
     protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
   }
 } static_descriptor_initializer_google_2fprotobuf_2ftype_2eproto_;
+const ::google::protobuf::EnumDescriptor* Syntax_descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return Syntax_descriptor_;
+}
+bool Syntax_IsValid(int value) {
+  switch(value) {
+    case 0:
+    case 1:
+      return true;
+    default:
+      return false;
+  }
+}
+
 
 namespace {
 
@@ -264,6 +288,7 @@
 const int Type::kOneofsFieldNumber;
 const int Type::kOptionsFieldNumber;
 const int Type::kSourceContextFieldNumber;
+const int Type::kSyntaxFieldNumber;
 #endif  // !_MSC_VER
 
 Type::Type()
@@ -291,6 +316,7 @@
   _cached_size_ = 0;
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   source_context_ = NULL;
+  syntax_ = 0;
 }
 
 Type::~Type() {
@@ -334,6 +360,7 @@
   name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
   source_context_ = NULL;
+  syntax_ = 0;
   fields_.Clear();
   oneofs_.Clear();
   options_.Clear();
@@ -427,6 +454,22 @@
         } else {
           goto handle_unusual;
         }
+        if (input->ExpectTag(48)) goto parse_syntax;
+        break;
+      }
+
+      // optional .google.protobuf.Syntax syntax = 6;
+      case 6: {
+        if (tag == 48) {
+         parse_syntax:
+          int value;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_syntax(static_cast< ::google::protobuf::Syntax >(value));
+        } else {
+          goto handle_unusual;
+        }
         if (input->ExpectAtEnd()) goto success;
         break;
       }
@@ -493,6 +536,12 @@
       5, *this->source_context_, output);
   }
 
+  // optional .google.protobuf.Syntax syntax = 6;
+  if (this->syntax() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      6, this->syntax(), output);
+  }
+
   // @@protoc_insertion_point(serialize_end:google.protobuf.Type)
 }
 
@@ -541,6 +590,12 @@
         5, *this->source_context_, target);
   }
 
+  // optional .google.protobuf.Syntax syntax = 6;
+  if (this->syntax() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      6, this->syntax(), target);
+  }
+
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Type)
   return target;
 }
@@ -562,6 +617,12 @@
         *this->source_context_);
   }
 
+  // optional .google.protobuf.Syntax syntax = 6;
+  if (this->syntax() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
+  }
+
   // repeated .google.protobuf.Field fields = 2;
   total_size += 1 * this->fields_size();
   for (int i = 0; i < this->fields_size(); i++) {
@@ -615,6 +676,9 @@
   if (from.has_source_context()) {
     mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context());
   }
+  if (from.syntax() != 0) {
+    set_syntax(from.syntax());
+  }
 }
 
 void Type::CopyFrom(const ::google::protobuf::Message& from) {
@@ -644,6 +708,7 @@
   oneofs_.UnsafeArenaSwap(&other->oneofs_);
   options_.UnsafeArenaSwap(&other->options_);
   std::swap(source_context_, other->source_context_);
+  std::swap(syntax_, other->syntax_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
 }
@@ -853,6 +918,20 @@
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context)
 }
 
+// optional .google.protobuf.Syntax syntax = 6;
+void Type::clear_syntax() {
+  syntax_ = 0;
+}
+ ::google::protobuf::Syntax Type::syntax() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Type.syntax)
+  return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+ void Type::set_syntax(::google::protobuf::Syntax value) {
+  
+  syntax_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.Type.syntax)
+}
+
 #endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
@@ -873,6 +952,7 @@
     case 7:
     case 8:
     case 9:
+    case 10:
     case 11:
     case 12:
     case 13:
@@ -898,6 +978,7 @@
 const Field_Kind Field::TYPE_FIXED32;
 const Field_Kind Field::TYPE_BOOL;
 const Field_Kind Field::TYPE_STRING;
+const Field_Kind Field::TYPE_GROUP;
 const Field_Kind Field::TYPE_MESSAGE;
 const Field_Kind Field::TYPE_BYTES;
 const Field_Kind Field::TYPE_UINT32;
@@ -944,6 +1025,7 @@
 const int Field::kOneofIndexFieldNumber;
 const int Field::kPackedFieldNumber;
 const int Field::kOptionsFieldNumber;
+const int Field::kJsonNameFieldNumber;
 #endif  // !_MSC_VER
 
 Field::Field()
@@ -975,6 +1057,7 @@
   type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   oneof_index_ = 0;
   packed_ = false;
+  json_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 
 Field::~Field() {
@@ -985,6 +1068,7 @@
 void Field::SharedDtor() {
   name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   type_url_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  json_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   if (this != default_instance_) {
   }
 }
@@ -1028,6 +1112,7 @@
   name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   packed_ = false;
+  json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 
 #undef ZR_HELPER_
 #undef ZR_
@@ -1168,6 +1253,23 @@
         }
         if (input->ExpectTag(74)) goto parse_loop_options;
         input->UnsafeDecrementRecursionDepth();
+        if (input->ExpectTag(82)) goto parse_json_name;
+        break;
+      }
+
+      // optional string json_name = 10;
+      case 10: {
+        if (tag == 82) {
+         parse_json_name:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_json_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->json_name().data(), this->json_name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "google.protobuf.Field.json_name");
+        } else {
+          goto handle_unusual;
+        }
         if (input->ExpectAtEnd()) goto success;
         break;
       }
@@ -1249,6 +1351,16 @@
       9, this->options(i), output);
   }
 
+  // optional string json_name = 10;
+  if (this->json_name().size() > 0) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->json_name().data(), this->json_name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.Field.json_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      10, this->json_name(), output);
+  }
+
   // @@protoc_insertion_point(serialize_end:google.protobuf.Field)
 }
 
@@ -1311,6 +1423,17 @@
         9, this->options(i), target);
   }
 
+  // optional string json_name = 10;
+  if (this->json_name().size() > 0) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->json_name().data(), this->json_name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.Field.json_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        10, this->json_name(), target);
+  }
+
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Field)
   return target;
 }
@@ -1363,6 +1486,13 @@
     total_size += 1 + 1;
   }
 
+  // optional string json_name = 10;
+  if (this->json_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->json_name());
+  }
+
   // repeated .google.protobuf.Option options = 9;
   total_size += 1 * this->options_size();
   for (int i = 0; i < this->options_size(); i++) {
@@ -1415,6 +1545,10 @@
   if (from.packed() != 0) {
     set_packed(from.packed());
   }
+  if (from.json_name().size() > 0) {
+
+    json_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.json_name_);
+  }
 }
 
 void Field::CopyFrom(const ::google::protobuf::Message& from) {
@@ -1447,6 +1581,7 @@
   std::swap(oneof_index_, other->oneof_index_);
   std::swap(packed_, other->packed_);
   options_.UnsafeArenaSwap(&other->options_);
+  json_name_.Swap(&other->json_name_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
 }
@@ -1648,6 +1783,49 @@
   return &options_;
 }
 
+// optional string json_name = 10;
+void Field::clear_json_name() {
+  json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& Field::json_name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Field.json_name)
+  return json_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Field::set_json_name(const ::std::string& value) {
+  
+  json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name)
+}
+ void Field::set_json_name(const char* value) {
+  
+  json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.Field.json_name)
+}
+ void Field::set_json_name(const char* value, size_t size) {
+  
+  json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.json_name)
+}
+ ::std::string* Field::mutable_json_name() {
+  
+  // @@protoc_insertion_point(field_mutable:google.protobuf.Field.json_name)
+  return json_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* Field::release_json_name() {
+  
+  return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Field::set_allocated_json_name(::std::string* json_name) {
+  if (json_name != NULL) {
+    
+  } else {
+    
+  }
+  json_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), json_name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name)
+}
+
 #endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
@@ -1657,6 +1835,7 @@
 const int Enum::kEnumvalueFieldNumber;
 const int Enum::kOptionsFieldNumber;
 const int Enum::kSourceContextFieldNumber;
+const int Enum::kSyntaxFieldNumber;
 #endif  // !_MSC_VER
 
 Enum::Enum()
@@ -1684,6 +1863,7 @@
   _cached_size_ = 0;
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   source_context_ = NULL;
+  syntax_ = 0;
 }
 
 Enum::~Enum() {
@@ -1727,6 +1907,7 @@
   name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
   source_context_ = NULL;
+  syntax_ = 0;
   enumvalue_.Clear();
   options_.Clear();
 }
@@ -1799,6 +1980,22 @@
         } else {
           goto handle_unusual;
         }
+        if (input->ExpectTag(40)) goto parse_syntax;
+        break;
+      }
+
+      // optional .google.protobuf.Syntax syntax = 5;
+      case 5: {
+        if (tag == 40) {
+         parse_syntax:
+          int value;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_syntax(static_cast< ::google::protobuf::Syntax >(value));
+        } else {
+          goto handle_unusual;
+        }
         if (input->ExpectAtEnd()) goto success;
         break;
       }
@@ -1855,6 +2052,12 @@
       4, *this->source_context_, output);
   }
 
+  // optional .google.protobuf.Syntax syntax = 5;
+  if (this->syntax() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      5, this->syntax(), output);
+  }
+
   // @@protoc_insertion_point(serialize_end:google.protobuf.Enum)
 }
 
@@ -1893,6 +2096,12 @@
         4, *this->source_context_, target);
   }
 
+  // optional .google.protobuf.Syntax syntax = 5;
+  if (this->syntax() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      5, this->syntax(), target);
+  }
+
   // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Enum)
   return target;
 }
@@ -1914,6 +2123,12 @@
         *this->source_context_);
   }
 
+  // optional .google.protobuf.Syntax syntax = 5;
+  if (this->syntax() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
+  }
+
   // repeated .google.protobuf.EnumValue enumvalue = 2;
   total_size += 1 * this->enumvalue_size();
   for (int i = 0; i < this->enumvalue_size(); i++) {
@@ -1959,6 +2174,9 @@
   if (from.has_source_context()) {
     mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context());
   }
+  if (from.syntax() != 0) {
+    set_syntax(from.syntax());
+  }
 }
 
 void Enum::CopyFrom(const ::google::protobuf::Message& from) {
@@ -1987,6 +2205,7 @@
   enumvalue_.UnsafeArenaSwap(&other->enumvalue_);
   options_.UnsafeArenaSwap(&other->options_);
   std::swap(source_context_, other->source_context_);
+  std::swap(syntax_, other->syntax_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
 }
@@ -2142,6 +2361,20 @@
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context)
 }
 
+// optional .google.protobuf.Syntax syntax = 5;
+void Enum::clear_syntax() {
+  syntax_ = 0;
+}
+ ::google::protobuf::Syntax Enum::syntax() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Enum.syntax)
+  return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+ void Enum::set_syntax(::google::protobuf::Syntax value) {
+  
+  syntax_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.Enum.syntax)
+}
+
 #endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h
index c9952ef..0d0aa2f 100644
--- a/src/google/protobuf/type.pb.h
+++ b/src/google/protobuf/type.pb.h
@@ -57,6 +57,7 @@
   Field_Kind_TYPE_FIXED32 = 7,
   Field_Kind_TYPE_BOOL = 8,
   Field_Kind_TYPE_STRING = 9,
+  Field_Kind_TYPE_GROUP = 10,
   Field_Kind_TYPE_MESSAGE = 11,
   Field_Kind_TYPE_BYTES = 12,
   Field_Kind_TYPE_UINT32 = 13,
@@ -106,6 +107,27 @@
   return ::google::protobuf::internal::ParseNamedEnum<Field_Cardinality>(
     Field_Cardinality_descriptor(), name, value);
 }
+enum Syntax {
+  SYNTAX_PROTO2 = 0,
+  SYNTAX_PROTO3 = 1,
+  Syntax_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,
+  Syntax_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
+};
+LIBPROTOBUF_EXPORT bool Syntax_IsValid(int value);
+const Syntax Syntax_MIN = SYNTAX_PROTO2;
+const Syntax Syntax_MAX = SYNTAX_PROTO3;
+const int Syntax_ARRAYSIZE = Syntax_MAX + 1;
+
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Syntax_descriptor();
+inline const ::std::string& Syntax_Name(Syntax value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    Syntax_descriptor(), value);
+}
+inline bool Syntax_Parse(
+    const ::std::string& name, Syntax* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<Syntax>(
+    Syntax_descriptor(), name, value);
+}
 // ===================================================================
 
 class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message {
@@ -224,6 +246,12 @@
   ::google::protobuf::SourceContext* release_source_context();
   void set_allocated_source_context(::google::protobuf::SourceContext* source_context);
 
+  // optional .google.protobuf.Syntax syntax = 6;
+  void clear_syntax();
+  static const int kSyntaxFieldNumber = 6;
+  ::google::protobuf::Syntax syntax() const;
+  void set_syntax(::google::protobuf::Syntax value);
+
   // @@protoc_insertion_point(class_scope:google.protobuf.Type)
  private:
 
@@ -234,6 +262,7 @@
   ::google::protobuf::RepeatedPtrField< ::std::string> oneofs_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
   ::google::protobuf::SourceContext* source_context_;
+  int syntax_;
   mutable int _cached_size_;
   friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
   friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto();
@@ -309,6 +338,7 @@
   static const Kind TYPE_FIXED32 = Field_Kind_TYPE_FIXED32;
   static const Kind TYPE_BOOL = Field_Kind_TYPE_BOOL;
   static const Kind TYPE_STRING = Field_Kind_TYPE_STRING;
+  static const Kind TYPE_GROUP = Field_Kind_TYPE_GROUP;
   static const Kind TYPE_MESSAGE = Field_Kind_TYPE_MESSAGE;
   static const Kind TYPE_BYTES = Field_Kind_TYPE_BYTES;
   static const Kind TYPE_UINT32 = Field_Kind_TYPE_UINT32;
@@ -430,6 +460,17 @@
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
       mutable_options();
 
+  // optional string json_name = 10;
+  void clear_json_name();
+  static const int kJsonNameFieldNumber = 10;
+  const ::std::string& json_name() const;
+  void set_json_name(const ::std::string& value);
+  void set_json_name(const char* value);
+  void set_json_name(const char* value, size_t size);
+  ::std::string* mutable_json_name();
+  ::std::string* release_json_name();
+  void set_allocated_json_name(::std::string* json_name);
+
   // @@protoc_insertion_point(class_scope:google.protobuf.Field)
  private:
 
@@ -442,6 +483,7 @@
   ::google::protobuf::int32 oneof_index_;
   ::google::protobuf::internal::ArenaStringPtr type_url_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
+  ::google::protobuf::internal::ArenaStringPtr json_name_;
   bool packed_;
   mutable int _cached_size_;
   friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
@@ -553,6 +595,12 @@
   ::google::protobuf::SourceContext* release_source_context();
   void set_allocated_source_context(::google::protobuf::SourceContext* source_context);
 
+  // optional .google.protobuf.Syntax syntax = 5;
+  void clear_syntax();
+  static const int kSyntaxFieldNumber = 5;
+  ::google::protobuf::Syntax syntax() const;
+  void set_syntax(::google::protobuf::Syntax value);
+
   // @@protoc_insertion_point(class_scope:google.protobuf.Enum)
  private:
 
@@ -562,6 +610,7 @@
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue > enumvalue_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
   ::google::protobuf::SourceContext* source_context_;
+  int syntax_;
   mutable int _cached_size_;
   friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
   friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto();
@@ -968,6 +1017,20 @@
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context)
 }
 
+// optional .google.protobuf.Syntax syntax = 6;
+inline void Type::clear_syntax() {
+  syntax_ = 0;
+}
+inline ::google::protobuf::Syntax Type::syntax() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Type.syntax)
+  return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+inline void Type::set_syntax(::google::protobuf::Syntax value) {
+  
+  syntax_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.Type.syntax)
+}
+
 // -------------------------------------------------------------------
 
 // Field
@@ -1158,6 +1221,49 @@
   return &options_;
 }
 
+// optional string json_name = 10;
+inline void Field::clear_json_name() {
+  json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Field::json_name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Field.json_name)
+  return json_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Field::set_json_name(const ::std::string& value) {
+  
+  json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name)
+}
+inline void Field::set_json_name(const char* value) {
+  
+  json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.Field.json_name)
+}
+inline void Field::set_json_name(const char* value, size_t size) {
+  
+  json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.json_name)
+}
+inline ::std::string* Field::mutable_json_name() {
+  
+  // @@protoc_insertion_point(field_mutable:google.protobuf.Field.json_name)
+  return json_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Field::release_json_name() {
+  
+  return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Field::set_allocated_json_name(::std::string* json_name) {
+  if (json_name != NULL) {
+    
+  } else {
+    
+  }
+  json_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), json_name);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name)
+}
+
 // -------------------------------------------------------------------
 
 // Enum
@@ -1302,6 +1408,20 @@
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context)
 }
 
+// optional .google.protobuf.Syntax syntax = 5;
+inline void Enum::clear_syntax() {
+  syntax_ = 0;
+}
+inline ::google::protobuf::Syntax Enum::syntax() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.Enum.syntax)
+  return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+inline void Enum::set_syntax(::google::protobuf::Syntax value) {
+  
+  syntax_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.Enum.syntax)
+}
+
 // -------------------------------------------------------------------
 
 // EnumValue
@@ -1506,6 +1626,11 @@
 inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::Field_Cardinality>() {
   return ::google::protobuf::Field_Cardinality_descriptor();
 }
+template <> struct is_proto_enum< ::google::protobuf::Syntax> : ::google::protobuf::internal::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::Syntax>() {
+  return ::google::protobuf::Syntax_descriptor();
+}
 
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/type.proto b/src/google/protobuf/type.proto
index ce22d33..4df9576 100644
--- a/src/google/protobuf/type.proto
+++ b/src/google/protobuf/type.proto
@@ -34,30 +34,27 @@
 import "google/protobuf/any.proto";
 import "google/protobuf/source_context.proto";
 
-option java_multiple_files = true;
-option java_outer_classname = "TypeProto";
 option java_package = "com.google.protobuf";
+option java_outer_classname = "TypeProto";
+option java_multiple_files = true;
+option java_generate_equals_and_hash = true;
 option csharp_namespace = "Google.Protobuf.WellKnownTypes";
 option objc_class_prefix = "GPB";
 
-
 // A light-weight descriptor for a proto message type.
 message Type {
   // The fully qualified message name.
   string name = 1;
-
   // The list of fields.
   repeated Field fields = 2;
-
   // The list of oneof definitions.
-  // The list of oneofs declared in this Type
-  repeated string oneofs = 3;
-
+  repeated string oneofs = 3;  // The list of oneofs declared in this Type
   // The proto options.
   repeated Option options = 4;
-
   // The source context.
   SourceContext source_context = 5;
+  // The source syntax.
+  Syntax syntax = 6;
 }
 
 // Field represents a single field of a message type.
@@ -65,125 +62,99 @@
   // Kind represents a basic field type.
   enum Kind {
     // Field type unknown.
-    TYPE_UNKNOWN = 0;
-
+    TYPE_UNKNOWN        = 0;
     // Field type double.
-    TYPE_DOUBLE = 1;
-
+    TYPE_DOUBLE         = 1;
     // Field type float.
-    TYPE_FLOAT = 2;
-
+    TYPE_FLOAT          = 2;
     // Field type int64.
-    TYPE_INT64 = 3;
-
+    TYPE_INT64          = 3;
     // Field type uint64.
-    TYPE_UINT64 = 4;
-
+    TYPE_UINT64         = 4;
     // Field type int32.
-    TYPE_INT32 = 5;
-
+    TYPE_INT32          = 5;
     // Field type fixed64.
-    TYPE_FIXED64 = 6;
-
+    TYPE_FIXED64        = 6;
     // Field type fixed32.
-    TYPE_FIXED32 = 7;
-
+    TYPE_FIXED32        = 7;
     // Field type bool.
-    TYPE_BOOL = 8;
-
+    TYPE_BOOL           = 8;
     // Field type string.
-    TYPE_STRING = 9;
-
+    TYPE_STRING         = 9;
+    // Field type group (deprecated proto2 type)
+    TYPE_GROUP          = 10;
     // Field type message.
-    TYPE_MESSAGE = 11;
-
+    TYPE_MESSAGE        = 11;
     // Field type bytes.
-    TYPE_BYTES = 12;
-
+    TYPE_BYTES          = 12;
     // Field type uint32.
-    TYPE_UINT32 = 13;
-
+    TYPE_UINT32         = 13;
     // Field type enum.
-    TYPE_ENUM = 14;
-
+    TYPE_ENUM           = 14;
     // Field type sfixed32.
-    TYPE_SFIXED32 = 15;
-
+    TYPE_SFIXED32       = 15;
     // Field type sfixed64.
-    TYPE_SFIXED64 = 16;
-
+    TYPE_SFIXED64       = 16;
     // Field type sint32.
-    TYPE_SINT32 = 17;
-
+    TYPE_SINT32         = 17;
     // Field type sint64.
-    TYPE_SINT64 = 18;
-  }
+    TYPE_SINT64         = 18;
+  };
 
   // Cardinality represents whether a field is optional, required, or
   // repeated.
   enum Cardinality {
     // The field cardinality is unknown. Typically an error condition.
     CARDINALITY_UNKNOWN = 0;
-
     // For optional fields.
     CARDINALITY_OPTIONAL = 1;
-
     // For required fields. Not used for proto3.
     CARDINALITY_REQUIRED = 2;
-
     // For repeated fields.
     CARDINALITY_REPEATED = 3;
-  }
+  };
 
   // The field kind.
   Kind kind = 1;
-
   // The field cardinality, i.e. optional/required/repeated.
   Cardinality cardinality = 2;
-
   // The proto field number.
   int32 number = 3;
-
   // The field name.
   string name = 4;
-
   // The type URL (without the scheme) when the type is MESSAGE or ENUM,
   // such as `type.googleapis.com/google.protobuf.Empty`.
   string type_url = 6;
-
   // Index in Type.oneofs. Starts at 1. Zero means no oneof mapping.
   int32 oneof_index = 7;
-
   // Whether to use alternative packed wire representation.
   bool packed = 8;
-
   // The proto options.
   repeated Option options = 9;
+  // The JSON name for this field.
+  string json_name = 10;
 }
 
 // Enum type definition.
 message Enum {
   // Enum type name.
   string name = 1;
-
   // Enum value definitions.
   repeated EnumValue enumvalue = 2;
-
   // Proto options for the enum type.
   repeated Option options = 3;
-
   // The source context.
   SourceContext source_context = 4;
+  // The source syntax.
+  Syntax syntax = 5;
 }
 
 // Enum value definition.
 message EnumValue {
   // Enum value name.
   string name = 1;
-
   // Enum value number.
   int32 number = 2;
-
   // Proto options for the enum value.
   repeated Option options = 3;
 }
@@ -192,7 +163,14 @@
 message Option {
   // Proto option name.
   string name = 1;
-
   // Proto option value.
   Any value = 2;
 }
+
+// Syntax specifies the syntax in which a service element was defined.
+enum Syntax {
+  // Syntax "proto2"
+  SYNTAX_PROTO2 = 0;
+  // Syntax "proto3"
+  SYNTAX_PROTO3 = 1;
+}
diff --git a/src/google/protobuf/unittest_mset_wire_format.proto b/src/google/protobuf/unittest_mset_wire_format.proto
new file mode 100644
index 0000000..04e4352
--- /dev/null
+++ b/src/google/protobuf/unittest_mset_wire_format.proto
@@ -0,0 +1,52 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains messages for testing message_set_wire_format.
+
+syntax = "proto2";
+package proto2_wireformat_unittest;
+
+option cc_enable_arenas = true;
+option optimize_for = SPEED;
+option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
+
+// A message with message_set_wire_format.
+message TestMessageSet {
+  option message_set_wire_format = true;
+  extensions 4 to max;
+}
+
+message TestMessageSetWireFormatContainer {
+  optional TestMessageSet message_set = 1;
+}
diff --git a/src/google/protobuf/unittest_no_arena_lite.proto b/src/google/protobuf/unittest_no_arena_lite.proto
new file mode 100644
index 0000000..34c7b7c
--- /dev/null
+++ b/src/google/protobuf/unittest_no_arena_lite.proto
@@ -0,0 +1,42 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest_no_arena;
+
+message ForeignMessageLite {
+  optional int32 c = 1;
+}
diff --git a/src/google/protobuf/util/field_mask_util.cc b/src/google/protobuf/util/field_mask_util.cc
new file mode 100644
index 0000000..82034bd
--- /dev/null
+++ b/src/google/protobuf/util/field_mask_util.cc
@@ -0,0 +1,418 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/util/field_mask_util.h>
+
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/map_util.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+using google::protobuf::FieldMask;
+
+string FieldMaskUtil::ToString(const FieldMask& mask) {
+  return Join(mask.paths(), ",");
+}
+
+void FieldMaskUtil::FromString(const string& str, FieldMask* out) {
+  out->Clear();
+  vector<string> paths = Split(str, ",");
+  for (int i = 0; i < paths.size(); ++i) {
+    if (paths[i].empty()) continue;
+    out->add_paths(paths[i]);
+  }
+}
+
+bool FieldMaskUtil::InternalIsValidPath(const Descriptor* descriptor,
+                                        const string& path) {
+  vector<string> parts = Split(path, ".");
+  for (int i = 0; i < parts.size(); ++i) {
+    const string& field_name = parts[i];
+    if (descriptor == NULL) {
+      return false;
+    }
+    const FieldDescriptor* field = descriptor->FindFieldByName(field_name);
+    if (field == NULL) {
+      return false;
+    }
+    if (!field->is_repeated() &&
+        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      descriptor = field->message_type();
+    } else {
+      descriptor = NULL;
+    }
+  }
+  return true;
+}
+
+void FieldMaskUtil::InternalGetFieldMaskForAllFields(
+    const Descriptor* descriptor, FieldMask* out) {
+  for (int i = 0; i < descriptor->field_count(); ++i) {
+    out->add_paths(descriptor->field(i)->name());
+  }
+}
+
+namespace {
+// A FieldMaskTree represents a FieldMask in a tree structure. For example,
+// given a FieldMask "foo.bar,foo.baz,bar.baz", the FieldMaskTree will be:
+//
+//   [root] -+- foo -+- bar
+//           |       |
+//           |       +- baz
+//           |
+//           +- bar --- baz
+//
+// In the tree, each leaf node represents a field path.
+class FieldMaskTree {
+ public:
+  FieldMaskTree();
+  ~FieldMaskTree();
+
+  void MergeFromFieldMask(const FieldMask& mask);
+  void MergeToFieldMask(FieldMask* mask);
+
+  // Add a field path into the tree. In a FieldMask, each field path matches
+  // the specified field and also all its sub-fields. If the field path to
+  // add is a sub-path of an existing field path in the tree (i.e., a leaf
+  // node), it means the tree already matchesthe the given path so nothing will
+  // be added to the tree. If the path matches an existing non-leaf node in the
+  // tree, that non-leaf node will be turned into a leaf node with all its
+  // children removed because the path matches all the node's children.
+  void AddPath(const string& path);
+
+  // Calculate the intersection part of a field path with this tree and add
+  // the intersection field path into out.
+  void IntersectPath(const string& path, FieldMaskTree* out);
+
+  // Merge all fields specified by this tree from one message to another.
+  void MergeMessage(const Message& source,
+                    const FieldMaskUtil::MergeOptions& options,
+                    Message* destination) {
+    // Do nothing if the tree is empty.
+    if (root_.children.empty()) {
+      return;
+    }
+    MergeMessage(&root_, source, options, destination);
+  }
+
+ private:
+  struct Node {
+    Node() {}
+
+    ~Node() { ClearChildren(); }
+
+    void ClearChildren() {
+      for (map<string, Node*>::iterator it = children.begin();
+           it != children.end(); ++it) {
+        delete it->second;
+      }
+      children.clear();
+    }
+
+    map<string, Node*> children;
+
+   private:
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node);
+  };
+
+  // Merge a sub-tree to mask. This method adds the field paths represented
+  // by all leaf nodes descended from "node" to mask.
+  void MergeToFieldMask(const string& prefix, const Node* node, FieldMask* out);
+
+  // Merge all leaf nodes of a sub-tree to another tree.
+  void MergeLeafNodesToTree(const string& prefix, const Node* node,
+                            FieldMaskTree* out);
+
+  // Merge all fields specified by a sub-tree from one message to another.
+  void MergeMessage(const Node* node, const Message& source,
+                    const FieldMaskUtil::MergeOptions& options,
+                    Message* destination);
+
+  Node root_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldMaskTree);
+};
+
+FieldMaskTree::FieldMaskTree() {}
+
+FieldMaskTree::~FieldMaskTree() {}
+
+void FieldMaskTree::MergeFromFieldMask(const FieldMask& mask) {
+  for (int i = 0; i < mask.paths_size(); ++i) {
+    AddPath(mask.paths(i));
+  }
+}
+
+void FieldMaskTree::MergeToFieldMask(FieldMask* mask) {
+  MergeToFieldMask("", &root_, mask);
+}
+
+void FieldMaskTree::MergeToFieldMask(const string& prefix, const Node* node,
+                                     FieldMask* out) {
+  if (node->children.empty()) {
+    if (prefix.empty()) {
+      // This is the root node.
+      return;
+    }
+    out->add_paths(prefix);
+    return;
+  }
+  for (map<string, Node*>::const_iterator it = node->children.begin();
+       it != node->children.end(); ++it) {
+    string current_path = prefix.empty() ? it->first : prefix + "." + it->first;
+    MergeToFieldMask(current_path, it->second, out);
+  }
+}
+
+void FieldMaskTree::AddPath(const string& path) {
+  vector<string> parts = Split(path, ".");
+  if (parts.empty()) {
+    return;
+  }
+  bool new_branch = false;
+  Node* node = &root_;
+  for (int i = 0; i < parts.size(); ++i) {
+    if (!new_branch && node != &root_ && node->children.empty()) {
+      // Path matches an existing leaf node. This means the path is already
+      // coverred by this tree (for example, adding "foo.bar.baz" to a tree
+      // which already contains "foo.bar").
+      return;
+    }
+    const string& node_name = parts[i];
+    Node*& child = node->children[node_name];
+    if (child == NULL) {
+      new_branch = true;
+      child = new Node();
+    }
+    node = child;
+  }
+  if (!node->children.empty()) {
+    node->ClearChildren();
+  }
+}
+
+void FieldMaskTree::IntersectPath(const string& path, FieldMaskTree* out) {
+  vector<string> parts = Split(path, ".");
+  if (parts.empty()) {
+    return;
+  }
+  const Node* node = &root_;
+  for (int i = 0; i < parts.size(); ++i) {
+    if (node->children.empty()) {
+      if (node != &root_) {
+        out->AddPath(path);
+      }
+      return;
+    }
+    const string& node_name = parts[i];
+    const Node* result = FindPtrOrNull(node->children, node_name);
+    if (result == NULL) {
+      // No intersection found.
+      return;
+    }
+    node = result;
+  }
+  // Now we found a matching node with the given path. Add all leaf nodes
+  // to out.
+  MergeLeafNodesToTree(path, node, out);
+}
+
+void FieldMaskTree::MergeLeafNodesToTree(const string& prefix, const Node* node,
+                                         FieldMaskTree* out) {
+  if (node->children.empty()) {
+    out->AddPath(prefix);
+  }
+  for (map<string, Node*>::const_iterator it = node->children.begin();
+       it != node->children.end(); ++it) {
+    string current_path = prefix.empty() ? it->first : prefix + "." + it->first;
+    MergeLeafNodesToTree(current_path, it->second, out);
+  }
+}
+
+void FieldMaskTree::MergeMessage(const Node* node, const Message& source,
+                                 const FieldMaskUtil::MergeOptions& options,
+                                 Message* destination) {
+  GOOGLE_DCHECK(!node->children.empty());
+  const Reflection* source_reflection = source.GetReflection();
+  const Reflection* destination_reflection = destination->GetReflection();
+  const Descriptor* descriptor = source.GetDescriptor();
+  for (map<string, Node*>::const_iterator it = node->children.begin();
+       it != node->children.end(); ++it) {
+    const string& field_name = it->first;
+    const Node* child = it->second;
+    const FieldDescriptor* field = descriptor->FindFieldByName(field_name);
+    if (field == NULL) {
+      GOOGLE_LOG(ERROR) << "Cannot find field \"" << field_name << "\" in message "
+                 << descriptor->full_name();
+      continue;
+    }
+    if (!child->children.empty()) {
+      // Sub-paths are only allowed for singular message fields.
+      if (field->is_repeated() ||
+          field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+        GOOGLE_LOG(ERROR) << "Field \"" << field_name << "\" in message "
+                   << descriptor->full_name()
+                   << " is not a singular message field and cannot "
+                   << "have sub-fields.";
+        continue;
+      }
+      MergeMessage(child, source_reflection->GetMessage(source, field), options,
+                   destination_reflection->MutableMessage(destination, field));
+      continue;
+    }
+    if (!field->is_repeated()) {
+      switch (field->cpp_type()) {
+#define COPY_VALUE(TYPE, Name)                                            \
+  case FieldDescriptor::CPPTYPE_##TYPE: {                                 \
+    destination_reflection->Set##Name(                                    \
+        destination, field, source_reflection->Get##Name(source, field)); \
+    break;                                                                \
+  }
+        COPY_VALUE(BOOL, Bool)
+        COPY_VALUE(INT32, Int32)
+        COPY_VALUE(INT64, Int64)
+        COPY_VALUE(UINT32, UInt32)
+        COPY_VALUE(UINT64, UInt64)
+        COPY_VALUE(FLOAT, Float)
+        COPY_VALUE(DOUBLE, Double)
+        COPY_VALUE(ENUM, Enum)
+        COPY_VALUE(STRING, String)
+#undef COPY_VALUE
+        case FieldDescriptor::CPPTYPE_MESSAGE: {
+          if (options.replace_message_fields()) {
+            destination_reflection->ClearField(destination, field);
+          }
+          if (source_reflection->HasField(source, field)) {
+            destination_reflection->MutableMessage(destination, field)
+                ->MergeFrom(source_reflection->GetMessage(source, field));
+          }
+          break;
+        }
+      }
+    } else {
+      if (options.replace_repeated_fields()) {
+        destination_reflection->ClearField(destination, field);
+      }
+      switch (field->cpp_type()) {
+#define COPY_REPEATED_VALUE(TYPE, Name)                            \
+  case FieldDescriptor::CPPTYPE_##TYPE: {                          \
+    int size = source_reflection->FieldSize(source, field);        \
+    for (int i = 0; i < size; ++i) {                               \
+      destination_reflection->Add##Name(                           \
+          destination, field,                                      \
+          source_reflection->GetRepeated##Name(source, field, i)); \
+    }                                                              \
+    break;                                                         \
+  }
+        COPY_REPEATED_VALUE(BOOL, Bool)
+        COPY_REPEATED_VALUE(INT32, Int32)
+        COPY_REPEATED_VALUE(INT64, Int64)
+        COPY_REPEATED_VALUE(UINT32, UInt32)
+        COPY_REPEATED_VALUE(UINT64, UInt64)
+        COPY_REPEATED_VALUE(FLOAT, Float)
+        COPY_REPEATED_VALUE(DOUBLE, Double)
+        COPY_REPEATED_VALUE(ENUM, Enum)
+        COPY_REPEATED_VALUE(STRING, String)
+#undef COPY_REPEATED_VALUE
+        case FieldDescriptor::CPPTYPE_MESSAGE: {
+          int size = source_reflection->FieldSize(source, field);
+          for (int i = 0; i < size; ++i) {
+            destination_reflection->AddMessage(destination, field)
+                ->MergeFrom(
+                    source_reflection->GetRepeatedMessage(source, field, i));
+          }
+          break;
+        }
+      }
+    }
+  }
+}
+
+}  // namespace
+
+void FieldMaskUtil::ToCanonicalForm(const FieldMask& mask, FieldMask* out) {
+  FieldMaskTree tree;
+  tree.MergeFromFieldMask(mask);
+  out->Clear();
+  tree.MergeToFieldMask(out);
+}
+
+void FieldMaskUtil::Union(const FieldMask& mask1, const FieldMask& mask2,
+                          FieldMask* out) {
+  FieldMaskTree tree;
+  tree.MergeFromFieldMask(mask1);
+  tree.MergeFromFieldMask(mask2);
+  out->Clear();
+  tree.MergeToFieldMask(out);
+}
+
+void FieldMaskUtil::Intersect(const FieldMask& mask1, const FieldMask& mask2,
+                              FieldMask* out) {
+  FieldMaskTree tree, intersection;
+  tree.MergeFromFieldMask(mask1);
+  for (int i = 0; i < mask2.paths_size(); ++i) {
+    tree.IntersectPath(mask2.paths(i), &intersection);
+  }
+  out->Clear();
+  intersection.MergeToFieldMask(out);
+}
+
+bool FieldMaskUtil::IsPathInFieldMask(const string& path,
+                                      const FieldMask& mask) {
+  for (int i = 0; i < mask.paths_size(); ++i) {
+    const string& mask_path = mask.paths(i);
+    if (path == mask_path) {
+      return true;
+    } else if (mask_path.length() < path.length()) {
+      // Also check whether mask.paths(i) is a prefix of path.
+      if (path.compare(0, mask_path.length() + 1, mask_path + ".") == 0) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+void FieldMaskUtil::MergeMessageTo(const Message& source, const FieldMask& mask,
+                                   const MergeOptions& options,
+                                   Message* destination) {
+  GOOGLE_CHECK(source.GetDescriptor() == destination->GetDescriptor());
+  // Build a FieldMaskTree and walk through the tree to merge all specified
+  // fields.
+  FieldMaskTree tree;
+  tree.MergeFromFieldMask(mask);
+  tree.MergeMessage(source, options, destination);
+}
+
+}  // namespace util
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/util/field_mask_util.h b/src/google/protobuf/util/field_mask_util.h
new file mode 100644
index 0000000..c99c34f
--- /dev/null
+++ b/src/google/protobuf/util/field_mask_util.h
@@ -0,0 +1,146 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
+#define GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
+
+#include <string>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/field_mask.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+class LIBPROTOBUF_EXPORT FieldMaskUtil {
+  typedef google::protobuf::FieldMask FieldMask;
+
+ public:
+  // Converts FieldMask to/from string, formatted according to proto3 JSON
+  // spec for FieldMask (e.g., "foo,bar,baz.quz").
+  static string ToString(const FieldMask& mask);
+  static void FromString(const string& str, FieldMask* out);
+
+  // Checks whether the given path is valid for type T.
+  template <typename T>
+  static bool IsValidPath(const string& path) {
+    return InternalIsValidPath(T::descriptor(), path);
+  }
+
+  // Checks whether the given FieldMask is valid for type T.
+  template <typename T>
+  static bool IsValidFieldMask(const FieldMask& mask) {
+    for (int i = 0; i < mask.paths_size(); ++i) {
+      if (!InternalIsValidPath(T::descriptor(), mask.paths(i))) return false;
+    }
+    return true;
+  }
+
+  // Adds a path to FieldMask after checking whether the given path is valid.
+  // This method check-fails if the path is not a valid path for type T.
+  template <typename T>
+  static void AddPathToFieldMask(const string& path, FieldMask* mask) {
+    GOOGLE_CHECK(IsValidPath<T>(path));
+    mask->add_paths(path);
+  }
+
+  // Creates a FieldMask with all fields of type T. This FieldMask only
+  // contains fields of T but not any sub-message fields.
+  template <typename T>
+  static void GetFieldMaskForAllFields(FieldMask* out) {
+    InternalGetFieldMaskForAllFields(T::descriptor(), out);
+  }
+
+  // Converts a FieldMask to the canonical form. It will:
+  //   1. Remove paths that are covered by another path. For example,
+  //      "foo.bar" is covered by "foo" and will be removed if "foo"
+  //      is also in the FieldMask.
+  //   2. Sort all paths in alphabetical order.
+  static void ToCanonicalForm(const FieldMask& mask, FieldMask* out);
+
+  // Creates an union of two FieldMasks.
+  static void Union(const FieldMask& mask1, const FieldMask& mask2,
+                    FieldMask* out);
+
+  // Creates an intersection of two FieldMasks.
+  static void Intersect(const FieldMask& mask1, const FieldMask& mask2,
+                        FieldMask* out);
+
+  // Returns true if path is covered by the given FieldMask. Note that path
+  // "foo.bar" covers all paths like "foo.bar.baz", "foo.bar.quz.x", etc.
+  static bool IsPathInFieldMask(const string& path, const FieldMask& mask);
+
+  class MergeOptions;
+  // Merges fields specified in a FieldMask into another message.
+  static void MergeMessageTo(const Message& source, const FieldMask& mask,
+                             const MergeOptions& options, Message* destination);
+
+ private:
+  static bool InternalIsValidPath(const Descriptor* descriptor,
+                                  const string& path);
+
+  static void InternalGetFieldMaskForAllFields(const Descriptor* descriptor,
+                                               FieldMask* out);
+};
+
+class LIBPROTOBUF_EXPORT FieldMaskUtil::MergeOptions {
+ public:
+  MergeOptions()
+      : replace_message_fields_(false), replace_repeated_fields_(false) {}
+  // When merging message fields, the default behavior is to merge the
+  // content of two message fields together. If you instead want to use
+  // the field from the source message to replace the corresponding field
+  // in the destination message, set this flag to true. When this flag is set,
+  // specified submessage fields that are missing in source will be cleared in
+  // destination.
+  void set_replace_message_fields(bool value) {
+    replace_message_fields_ = value;
+  }
+  bool replace_message_fields() const { return replace_message_fields_; }
+  // The default merging behavior will append entries from the source
+  // repeated field to the destination repeated field. If you only want
+  // to keep the entries from the source repeated field, set this flag
+  // to true.
+  void set_replace_repeated_fields(bool value) {
+    replace_repeated_fields_ = value;
+  }
+  bool replace_repeated_fields() const { return replace_repeated_fields_; }
+
+ private:
+  bool replace_message_fields_;
+  bool replace_repeated_fields_;
+};
+
+}  // namespace util
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
diff --git a/src/google/protobuf/util/field_mask_util_test.cc b/src/google/protobuf/util/field_mask_util_test.cc
new file mode 100644
index 0000000..a952325
--- /dev/null
+++ b/src/google/protobuf/util/field_mask_util_test.cc
@@ -0,0 +1,395 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/util/field_mask_util.h>
+
+#include <google/protobuf/field_mask.pb.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/test_util.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace {
+
+using protobuf_unittest::TestAllTypes;
+using protobuf_unittest::NestedTestAllTypes;
+using google::protobuf::FieldMask;
+
+TEST(FieldMaskUtilTest, StringFormat) {
+  FieldMask mask;
+  EXPECT_EQ("", FieldMaskUtil::ToString(mask));
+  mask.add_paths("foo");
+  EXPECT_EQ("foo", FieldMaskUtil::ToString(mask));
+  mask.add_paths("bar");
+  EXPECT_EQ("foo,bar", FieldMaskUtil::ToString(mask));
+
+  FieldMaskUtil::FromString("", &mask);
+  EXPECT_EQ(0, mask.paths_size());
+  FieldMaskUtil::FromString("foo", &mask);
+  EXPECT_EQ(1, mask.paths_size());
+  EXPECT_EQ("foo", mask.paths(0));
+  FieldMaskUtil::FromString("foo,bar", &mask);
+  EXPECT_EQ(2, mask.paths_size());
+  EXPECT_EQ("foo", mask.paths(0));
+  EXPECT_EQ("bar", mask.paths(1));
+}
+
+TEST(FieldMaskUtilTest, TestIsVaildPath) {
+  EXPECT_TRUE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_int32"));
+  EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nonexist"));
+  EXPECT_TRUE(
+      FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nested_message.bb"));
+  EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>(
+      "optional_nested_message.nonexist"));
+  // FieldMask cannot be used to specify sub-fields of a repeated message.
+  EXPECT_FALSE(
+      FieldMaskUtil::IsValidPath<TestAllTypes>("repeated_nested_message.bb"));
+}
+
+TEST(FieldMaskUtilTest, TestIsValidFieldMask) {
+  FieldMask mask;
+  FieldMaskUtil::FromString("optional_int32,optional_nested_message.bb", &mask);
+  EXPECT_TRUE(FieldMaskUtil::IsValidFieldMask<TestAllTypes>(mask));
+
+  FieldMaskUtil::FromString(
+      "optional_int32,optional_nested_message.bb,optional_nonexist", &mask);
+  EXPECT_FALSE(FieldMaskUtil::IsValidFieldMask<TestAllTypes>(mask));
+}
+
+TEST(FieldMaskUtilTest, TestGetFieldMaskForAllFields) {
+  FieldMask mask;
+  FieldMaskUtil::GetFieldMaskForAllFields<TestAllTypes::NestedMessage>(&mask);
+  EXPECT_EQ(1, mask.paths_size());
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("bb", mask));
+
+  FieldMaskUtil::GetFieldMaskForAllFields<TestAllTypes>(&mask);
+  EXPECT_EQ(76, mask.paths_size());
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_int32", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_int64", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_uint32", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_uint64", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sint32", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sint64", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_fixed32", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_fixed64", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sfixed32", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sfixed64", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_float", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_double", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_bool", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_string", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_bytes", mask));
+  EXPECT_TRUE(
+      FieldMaskUtil::IsPathInFieldMask("optional_nested_message", mask));
+  EXPECT_TRUE(
+      FieldMaskUtil::IsPathInFieldMask("optional_foreign_message", mask));
+  EXPECT_TRUE(
+      FieldMaskUtil::IsPathInFieldMask("optional_import_message", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_nested_enum", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_foreign_enum", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_import_enum", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_int32", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_int64", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_uint32", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_uint64", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sint32", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sint64", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_fixed32", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_fixed64", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sfixed32", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sfixed64", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_float", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_double", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_bool", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_string", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_bytes", mask));
+  EXPECT_TRUE(
+      FieldMaskUtil::IsPathInFieldMask("repeated_nested_message", mask));
+  EXPECT_TRUE(
+      FieldMaskUtil::IsPathInFieldMask("repeated_foreign_message", mask));
+  EXPECT_TRUE(
+      FieldMaskUtil::IsPathInFieldMask("repeated_import_message", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_nested_enum", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_foreign_enum", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_import_enum", mask));
+}
+
+TEST(FieldMaskUtilTest, TestToCanonicalForm) {
+  FieldMask in, out;
+  // Paths will be sorted.
+  FieldMaskUtil::FromString("baz.quz,bar,foo", &in);
+  FieldMaskUtil::ToCanonicalForm(in, &out);
+  EXPECT_EQ("bar,baz.quz,foo", FieldMaskUtil::ToString(out));
+  // Duplicated paths will be removed.
+  FieldMaskUtil::FromString("foo,bar,foo", &in);
+  FieldMaskUtil::ToCanonicalForm(in, &out);
+  EXPECT_EQ("bar,foo", FieldMaskUtil::ToString(out));
+  // Sub-paths of other paths will be removed.
+  FieldMaskUtil::FromString("foo.b1,bar.b1,foo.b2,bar", &in);
+  FieldMaskUtil::ToCanonicalForm(in, &out);
+  EXPECT_EQ("bar,foo.b1,foo.b2", FieldMaskUtil::ToString(out));
+
+  // Test more deeply nested cases.
+  FieldMaskUtil::FromString(
+      "foo.bar.baz1,"
+      "foo.bar.baz2.quz,"
+      "foo.bar.baz2",
+      &in);
+  FieldMaskUtil::ToCanonicalForm(in, &out);
+  EXPECT_EQ("foo.bar.baz1,foo.bar.baz2", FieldMaskUtil::ToString(out));
+  FieldMaskUtil::FromString(
+      "foo.bar.baz1,"
+      "foo.bar.baz2,"
+      "foo.bar.baz2.quz",
+      &in);
+  FieldMaskUtil::ToCanonicalForm(in, &out);
+  EXPECT_EQ("foo.bar.baz1,foo.bar.baz2", FieldMaskUtil::ToString(out));
+  FieldMaskUtil::FromString(
+      "foo.bar.baz1,"
+      "foo.bar.baz2,"
+      "foo.bar.baz2.quz,"
+      "foo.bar",
+      &in);
+  FieldMaskUtil::ToCanonicalForm(in, &out);
+  EXPECT_EQ("foo.bar", FieldMaskUtil::ToString(out));
+  FieldMaskUtil::FromString(
+      "foo.bar.baz1,"
+      "foo.bar.baz2,"
+      "foo.bar.baz2.quz,"
+      "foo",
+      &in);
+  FieldMaskUtil::ToCanonicalForm(in, &out);
+  EXPECT_EQ("foo", FieldMaskUtil::ToString(out));
+}
+
+TEST(FieldMaskUtilTest, TestUnion) {
+  FieldMask mask1, mask2, out;
+  // Test cases without overlapping.
+  FieldMaskUtil::FromString("foo,baz", &mask1);
+  FieldMaskUtil::FromString("bar,quz", &mask2);
+  FieldMaskUtil::Union(mask1, mask2, &out);
+  EXPECT_EQ("bar,baz,foo,quz", FieldMaskUtil::ToString(out));
+  // Overlap with duplicated paths.
+  FieldMaskUtil::FromString("foo,baz.bb", &mask1);
+  FieldMaskUtil::FromString("baz.bb,quz", &mask2);
+  FieldMaskUtil::Union(mask1, mask2, &out);
+  EXPECT_EQ("baz.bb,foo,quz", FieldMaskUtil::ToString(out));
+  // Overlap with paths covering some other paths.
+  FieldMaskUtil::FromString("foo.bar.baz,quz", &mask1);
+  FieldMaskUtil::FromString("foo.bar,bar", &mask2);
+  FieldMaskUtil::Union(mask1, mask2, &out);
+  EXPECT_EQ("bar,foo.bar,quz", FieldMaskUtil::ToString(out));
+}
+
+TEST(FieldMaskUtilTest, TestIntersect) {
+  FieldMask mask1, mask2, out;
+  // Test cases without overlapping.
+  FieldMaskUtil::FromString("foo,baz", &mask1);
+  FieldMaskUtil::FromString("bar,quz", &mask2);
+  FieldMaskUtil::Intersect(mask1, mask2, &out);
+  EXPECT_EQ("", FieldMaskUtil::ToString(out));
+  // Overlap with duplicated paths.
+  FieldMaskUtil::FromString("foo,baz.bb", &mask1);
+  FieldMaskUtil::FromString("baz.bb,quz", &mask2);
+  FieldMaskUtil::Intersect(mask1, mask2, &out);
+  EXPECT_EQ("baz.bb", FieldMaskUtil::ToString(out));
+  // Overlap with paths covering some other paths.
+  FieldMaskUtil::FromString("foo.bar.baz,quz", &mask1);
+  FieldMaskUtil::FromString("foo.bar,bar", &mask2);
+  FieldMaskUtil::Intersect(mask1, mask2, &out);
+  EXPECT_EQ("foo.bar.baz", FieldMaskUtil::ToString(out));
+}
+
+TEST(FieldMaskUtilTest, TestIspathInFieldMask) {
+  FieldMask mask;
+  FieldMaskUtil::FromString("foo.bar", &mask);
+  EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("", mask));
+  EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("foo", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("foo.bar", mask));
+  EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("foo.bar.baz", mask));
+  EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("foo.bar0.baz", mask));
+}
+
+TEST(FieldMaskUtilTest, MergeMessage) {
+  TestAllTypes src, dst;
+  TestUtil::SetAllFields(&src);
+  FieldMaskUtil::MergeOptions options;
+
+#define TEST_MERGE_ONE_PRIMITIVE_FIELD(field_name)           \
+  {                                                          \
+    TestAllTypes tmp;                                        \
+    tmp.set_##field_name(src.field_name());                  \
+    FieldMask mask;                                          \
+    mask.add_paths(#field_name);                             \
+    dst.Clear();                                             \
+    FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
+    EXPECT_EQ(tmp.DebugString(), dst.DebugString());         \
+  }
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int32)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int64)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_uint32)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_uint64)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sint32)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sint64)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_fixed32)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_fixed64)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sfixed32)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sfixed64)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_float)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_double)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_bool)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_string)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_bytes)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_nested_enum)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_foreign_enum)
+  TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_import_enum)
+#undef TEST_MERGE_ONE_PRIMITIVE_FIELD
+
+#define TEST_MERGE_ONE_FIELD(field_name)                     \
+  {                                                          \
+    TestAllTypes tmp;                                        \
+    *tmp.mutable_##field_name() = src.field_name();          \
+    FieldMask mask;                                          \
+    mask.add_paths(#field_name);                             \
+    dst.Clear();                                             \
+    FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
+    EXPECT_EQ(tmp.DebugString(), dst.DebugString());         \
+  }
+  TEST_MERGE_ONE_FIELD(optional_nested_message)
+  TEST_MERGE_ONE_FIELD(optional_foreign_message)
+  TEST_MERGE_ONE_FIELD(optional_import_message)
+
+  TEST_MERGE_ONE_FIELD(repeated_int32)
+  TEST_MERGE_ONE_FIELD(repeated_int64)
+  TEST_MERGE_ONE_FIELD(repeated_uint32)
+  TEST_MERGE_ONE_FIELD(repeated_uint64)
+  TEST_MERGE_ONE_FIELD(repeated_sint32)
+  TEST_MERGE_ONE_FIELD(repeated_sint64)
+  TEST_MERGE_ONE_FIELD(repeated_fixed32)
+  TEST_MERGE_ONE_FIELD(repeated_fixed64)
+  TEST_MERGE_ONE_FIELD(repeated_sfixed32)
+  TEST_MERGE_ONE_FIELD(repeated_sfixed64)
+  TEST_MERGE_ONE_FIELD(repeated_float)
+  TEST_MERGE_ONE_FIELD(repeated_double)
+  TEST_MERGE_ONE_FIELD(repeated_bool)
+  TEST_MERGE_ONE_FIELD(repeated_string)
+  TEST_MERGE_ONE_FIELD(repeated_bytes)
+  TEST_MERGE_ONE_FIELD(repeated_nested_message)
+  TEST_MERGE_ONE_FIELD(repeated_foreign_message)
+  TEST_MERGE_ONE_FIELD(repeated_import_message)
+  TEST_MERGE_ONE_FIELD(repeated_nested_enum)
+  TEST_MERGE_ONE_FIELD(repeated_foreign_enum)
+  TEST_MERGE_ONE_FIELD(repeated_import_enum)
+#undef TEST_MERGE_ONE_FIELD
+
+  // Test merge nested fields.
+  NestedTestAllTypes nested_src, nested_dst;
+  nested_src.mutable_child()->mutable_payload()->set_optional_int32(1234);
+  nested_src.mutable_child()
+      ->mutable_child()
+      ->mutable_payload()
+      ->set_optional_int32(5678);
+  FieldMask mask;
+  FieldMaskUtil::FromString("child.payload", &mask);
+  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+  EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+  EXPECT_EQ(0, nested_dst.child().child().payload().optional_int32());
+
+  FieldMaskUtil::FromString("child.child.payload", &mask);
+  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+  EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+  EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
+
+  nested_dst.Clear();
+  FieldMaskUtil::FromString("child.child.payload", &mask);
+  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+  EXPECT_EQ(0, nested_dst.child().payload().optional_int32());
+  EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
+
+  nested_dst.Clear();
+  FieldMaskUtil::FromString("child", &mask);
+  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+  EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+  EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
+
+  // Test MergeOptions.
+
+  nested_dst.Clear();
+  nested_dst.mutable_child()->mutable_payload()->set_optional_int64(4321);
+  // Message fields will be merged by default.
+  FieldMaskUtil::FromString("child.payload", &mask);
+  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+  EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+  EXPECT_EQ(4321, nested_dst.child().payload().optional_int64());
+  // Change the behavior to replace message fields.
+  options.set_replace_message_fields(true);
+  FieldMaskUtil::FromString("child.payload", &mask);
+  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+  EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+  EXPECT_EQ(0, nested_dst.child().payload().optional_int64());
+
+  // By default, fields missing in source are not cleared in destination.
+  options.set_replace_message_fields(false);
+  nested_dst.mutable_payload();
+  EXPECT_TRUE(nested_dst.has_payload());
+  FieldMaskUtil::FromString("payload", &mask);
+  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+  EXPECT_TRUE(nested_dst.has_payload());
+  // But they are cleared when replacing message fields.
+  options.set_replace_message_fields(true);
+  nested_dst.Clear();
+  nested_dst.mutable_payload();
+  FieldMaskUtil::FromString("payload", &mask);
+  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+  EXPECT_FALSE(nested_dst.has_payload());
+
+  nested_src.mutable_payload()->add_repeated_int32(1234);
+  nested_dst.mutable_payload()->add_repeated_int32(5678);
+  // Repeated fields will be appended by default.
+  FieldMaskUtil::FromString("payload.repeated_int32", &mask);
+  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+  ASSERT_EQ(2, nested_dst.payload().repeated_int32_size());
+  EXPECT_EQ(5678, nested_dst.payload().repeated_int32(0));
+  EXPECT_EQ(1234, nested_dst.payload().repeated_int32(1));
+  // Change the behavior to replace repeated fields.
+  options.set_replace_repeated_fields(true);
+  FieldMaskUtil::FromString("payload.repeated_int32", &mask);
+  FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+  ASSERT_EQ(1, nested_dst.payload().repeated_int32_size());
+  EXPECT_EQ(1234, nested_dst.payload().repeated_int32(0));
+}
+
+
+}  // namespace
+}  // namespace util
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/util/internal/testdata/oneofs.proto b/src/google/protobuf/util/internal/testdata/oneofs.proto
new file mode 100644
index 0000000..5bc9fa0
--- /dev/null
+++ b/src/google/protobuf/util/internal/testdata/oneofs.proto
@@ -0,0 +1,68 @@
+// 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.
+
+// Proto to test oneofs.
+syntax = "proto3";
+
+import "google/protobuf/any.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+
+package google.protobuf.testing.oneofs;
+option java_package = "com.google.protobuf.testing.oneofs";
+
+message OneOfsRequest {
+  string value = 1;
+  oneof data {
+    string str_data = 2;
+    int32 int_data = 3;
+    // Simple message
+    Data message_data = 4;
+    // Well known types
+    google.protobuf.Struct struct_data = 5;
+    google.protobuf.Value value_data = 6;
+    google.protobuf.ListValue list_value_data = 7;
+    google.protobuf.Timestamp ts_data = 8;
+  }
+  google.protobuf.Any any_data = 19;
+}
+
+message Data {
+  int32 data_value = 1;
+}
+
+message Response {
+  string value = 1;
+}
+
+service TestService {
+  // Test call.
+  rpc Call(OneOfsRequest) returns (Response);
+}
diff --git a/src/google/protobuf/util/time_util.cc b/src/google/protobuf/util/time_util.cc
new file mode 100644
index 0000000..c782d69
--- /dev/null
+++ b/src/google/protobuf/util/time_util.cc
@@ -0,0 +1,525 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/util/time_util.h>
+
+#include <google/protobuf/stubs/time.h>
+#include <google/protobuf/stubs/int128.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/duration.pb.h>
+#include <google/protobuf/timestamp.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+using google::protobuf::Timestamp;
+using google::protobuf::Duration;
+
+namespace {
+static const int kNanosPerSecond = 1000000000;
+static const int kMicrosPerSecond = 1000000;
+static const int kMillisPerSecond = 1000;
+static const int kNanosPerMillisecond = 1000000;
+static const int kMicrosPerMillisecond = 1000;
+static const int kNanosPerMicrosecond = 1000;
+static const int kSecondsPerMinute = 60;  // Note that we ignore leap seconds.
+static const int kSecondsPerHour = 3600;
+static const char kTimestampFormat[] = "%E4Y-%m-%dT%H:%M:%S";
+
+template <typename T>
+T CreateNormalized(int64 seconds, int64 nanos);
+
+template <>
+Timestamp CreateNormalized(int64 seconds, int64 nanos) {
+  // Make sure nanos is in the range.
+  if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) {
+    seconds += nanos / kNanosPerSecond;
+    nanos = nanos % kNanosPerSecond;
+  }
+  // For Timestamp nanos should be in the range [0, 999999999]
+  if (nanos < 0) {
+    seconds -= 1;
+    nanos += kNanosPerSecond;
+  }
+  GOOGLE_DCHECK(seconds >= TimeUtil::kTimestampMinSeconds &&
+         seconds <= TimeUtil::kTimestampMaxSeconds);
+  Timestamp result;
+  result.set_seconds(seconds);
+  result.set_nanos(static_cast<int32>(nanos));
+  return result;
+}
+
+template <>
+Duration CreateNormalized(int64 seconds, int64 nanos) {
+  // Make sure nanos is in the range.
+  if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) {
+    seconds += nanos / kNanosPerSecond;
+    nanos = nanos % kNanosPerSecond;
+  }
+  // nanos should have the same sign as seconds.
+  if (seconds < 0 && nanos > 0) {
+    seconds += 1;
+    nanos -= kNanosPerSecond;
+  } else if (seconds > 0 && nanos < 0) {
+    seconds -= 1;
+    nanos += kNanosPerSecond;
+  }
+  GOOGLE_DCHECK(seconds >= TimeUtil::kDurationMinSeconds &&
+         seconds <= TimeUtil::kDurationMaxSeconds);
+  Duration result;
+  result.set_seconds(seconds);
+  result.set_nanos(static_cast<int32>(nanos));
+  return result;
+}
+
+// Format nanoseconds with either 3, 6, or 9 digits depending on the required
+// precision to represent the exact value.
+string FormatNanos(int32 nanos) {
+  if (nanos % kNanosPerMillisecond == 0) {
+    return StringPrintf("%03d", nanos / kNanosPerMillisecond);
+  } else if (nanos % kNanosPerMicrosecond == 0) {
+    return StringPrintf("%06d", nanos / kNanosPerMicrosecond);
+  } else {
+    return StringPrintf("%09d", nanos);
+  }
+}
+
+string FormatTime(int64 seconds, int32 nanos) {
+  return ::google::protobuf::internal::FormatTime(seconds, nanos);
+}
+
+bool ParseTime(const string& value, int64* seconds, int32* nanos) {
+  return ::google::protobuf::internal::ParseTime(value, seconds, nanos);
+}
+
+void CurrentTime(int64* seconds, int32* nanos) {
+  return ::google::protobuf::internal::GetCurrentTime(seconds, nanos);
+}
+
+// Truncates the remainder part after division.
+int64 RoundTowardZero(int64 value, int64 divider) {
+  int64 result = value / divider;
+  int64 remainder = value % divider;
+  // Before C++11, the sign of the remainder is implementation dependent if
+  // any of the operands is negative. Here we try to enforce C++11's "rounded
+  // toward zero" semantics. For example, for (-5) / 2 an implementation may
+  // give -3 as the result with the remainder being 1. This function ensures
+  // we always return -2 (closer to zero) regardless of the implementation.
+  if (result < 0 && remainder > 0) {
+    return result + 1;
+  } else {
+    return result;
+  }
+}
+}  // namespace
+
+string TimeUtil::ToString(const Timestamp& timestamp) {
+  return FormatTime(timestamp.seconds(), timestamp.nanos());
+}
+
+bool TimeUtil::FromString(const string& value, Timestamp* timestamp) {
+  int64 seconds;
+  int32 nanos;
+  if (!ParseTime(value, &seconds, &nanos)) {
+    return false;
+  }
+  *timestamp = CreateNormalized<Timestamp>(seconds, nanos);
+  return true;
+}
+
+Timestamp TimeUtil::GetCurrentTime() {
+  int64 seconds;
+  int32 nanos;
+  CurrentTime(&seconds, &nanos);
+  return CreateNormalized<Timestamp>(seconds, nanos);
+}
+
+Timestamp TimeUtil::GetEpoch() { return Timestamp(); }
+
+string TimeUtil::ToString(const Duration& duration) {
+  string result;
+  int64 seconds = duration.seconds();
+  int32 nanos = duration.nanos();
+  if (seconds < 0 || nanos < 0) {
+    result += "-";
+    seconds = -seconds;
+    nanos = -nanos;
+  }
+  result += StringPrintf("%" GOOGLE_LL_FORMAT "d", seconds);
+  if (nanos != 0) {
+    result += "." + FormatNanos(nanos);
+  }
+  result += "s";
+  return result;
+}
+
+static int64 Pow(int64 x, int y) {
+  int64 result = 1;
+  for (int i = 0; i < y; ++i) {
+    result *= x;
+  }
+  return result;
+}
+
+bool TimeUtil::FromString(const string& value, Duration* duration) {
+  if (value.length() <= 1 || value[value.length() - 1] != 's') {
+    return false;
+  }
+  bool negative = (value[0] == '-');
+  int sign_length = (negative ? 1 : 0);
+  // Parse the duration value as two integers rather than a float value
+  // to avoid precision loss.
+  string seconds_part, nanos_part;
+  size_t pos = value.find_last_of(".");
+  if (pos == string::npos) {
+    seconds_part = value.substr(sign_length, value.length() - 1 - sign_length);
+    nanos_part = "0";
+  } else {
+    seconds_part = value.substr(sign_length, pos - sign_length);
+    nanos_part = value.substr(pos + 1, value.length() - pos - 2);
+  }
+  char* end;
+  int64 seconds = strto64(seconds_part.c_str(), &end, 10);
+  if (end != seconds_part.c_str() + seconds_part.length()) {
+    return false;
+  }
+  int64 nanos = strto64(nanos_part.c_str(), &end, 10);
+  if (end != nanos_part.c_str() + nanos_part.length()) {
+    return false;
+  }
+  nanos = nanos * Pow(10, 9 - nanos_part.length());
+  if (negative) {
+    // If a Duration is negative, both seconds and nanos should be negative.
+    seconds = -seconds;
+    nanos = -nanos;
+  }
+  duration->set_seconds(seconds);
+  duration->set_nanos(static_cast<int32>(nanos));
+  return true;
+}
+
+Duration TimeUtil::NanosecondsToDuration(int64 nanos) {
+  return CreateNormalized<Duration>(nanos / kNanosPerSecond,
+                                    nanos % kNanosPerSecond);
+}
+
+Duration TimeUtil::MicrosecondsToDuration(int64 micros) {
+  return CreateNormalized<Duration>(
+      micros / kMicrosPerSecond,
+      (micros % kMicrosPerSecond) * kNanosPerMicrosecond);
+}
+
+Duration TimeUtil::MillisecondsToDuration(int64 millis) {
+  return CreateNormalized<Duration>(
+      millis / kMillisPerSecond,
+      (millis % kMillisPerSecond) * kNanosPerMillisecond);
+}
+
+Duration TimeUtil::SecondsToDuration(int64 seconds) {
+  return CreateNormalized<Duration>(seconds, 0);
+}
+
+Duration TimeUtil::MinutesToDuration(int64 minutes) {
+  return CreateNormalized<Duration>(minutes * kSecondsPerMinute, 0);
+}
+
+Duration TimeUtil::HoursToDuration(int64 hours) {
+  return CreateNormalized<Duration>(hours * kSecondsPerHour, 0);
+}
+
+int64 TimeUtil::DurationToNanoseconds(const Duration& duration) {
+  return duration.seconds() * kNanosPerSecond + duration.nanos();
+}
+
+int64 TimeUtil::DurationToMicroseconds(const Duration& duration) {
+  return duration.seconds() * kMicrosPerSecond +
+         RoundTowardZero(duration.nanos(), kNanosPerMicrosecond);
+}
+
+int64 TimeUtil::DurationToMilliseconds(const Duration& duration) {
+  return duration.seconds() * kMillisPerSecond +
+         RoundTowardZero(duration.nanos(), kNanosPerMillisecond);
+}
+
+int64 TimeUtil::DurationToSeconds(const Duration& duration) {
+  return duration.seconds();
+}
+
+int64 TimeUtil::DurationToMinutes(const Duration& duration) {
+  return RoundTowardZero(duration.seconds(), kSecondsPerMinute);
+}
+
+int64 TimeUtil::DurationToHours(const Duration& duration) {
+  return RoundTowardZero(duration.seconds(), kSecondsPerHour);
+}
+
+Timestamp TimeUtil::NanosecondsToTimestamp(int64 nanos) {
+  return CreateNormalized<Timestamp>(nanos / kNanosPerSecond,
+                                     nanos % kNanosPerSecond);
+}
+
+Timestamp TimeUtil::MicrosecondsToTimestamp(int64 micros) {
+  return CreateNormalized<Timestamp>(
+      micros / kMicrosPerSecond,
+      micros % kMicrosPerSecond * kNanosPerMicrosecond);
+}
+
+Timestamp TimeUtil::MillisecondsToTimestamp(int64 millis) {
+  return CreateNormalized<Timestamp>(
+      millis / kMillisPerSecond,
+      millis % kMillisPerSecond * kNanosPerMillisecond);
+}
+
+Timestamp TimeUtil::SecondsToTimestamp(int64 seconds) {
+  return CreateNormalized<Timestamp>(seconds, 0);
+}
+
+int64 TimeUtil::TimestampToNanoseconds(const Timestamp& timestamp) {
+  return timestamp.seconds() * kNanosPerSecond + timestamp.nanos();
+}
+
+int64 TimeUtil::TimestampToMicroseconds(const Timestamp& timestamp) {
+  return timestamp.seconds() * kMicrosPerSecond +
+         RoundTowardZero(timestamp.nanos(), kNanosPerMicrosecond);
+}
+
+int64 TimeUtil::TimestampToMilliseconds(const Timestamp& timestamp) {
+  return timestamp.seconds() * kMillisPerSecond +
+         RoundTowardZero(timestamp.nanos(), kNanosPerMillisecond);
+}
+
+int64 TimeUtil::TimestampToSeconds(const Timestamp& timestamp) {
+  return timestamp.seconds();
+}
+
+Timestamp TimeUtil::TimeTToTimestamp(time_t value) {
+  return CreateNormalized<Timestamp>(static_cast<int64>(value), 0);
+}
+
+time_t TimeUtil::TimestampToTimeT(const Timestamp& value) {
+  return static_cast<time_t>(value.seconds());
+}
+
+Timestamp TimeUtil::TimevalToTimestamp(const timeval& value) {
+  return CreateNormalized<Timestamp>(value.tv_sec,
+                                     value.tv_usec * kNanosPerMicrosecond);
+}
+
+timeval TimeUtil::TimestampToTimeval(const Timestamp& value) {
+  timeval result;
+  result.tv_sec = value.seconds();
+  result.tv_usec = RoundTowardZero(value.nanos(), kNanosPerMicrosecond);
+  return result;
+}
+
+Duration TimeUtil::TimevalToDuration(const timeval& value) {
+  return CreateNormalized<Duration>(value.tv_sec,
+                                    value.tv_usec * kNanosPerMicrosecond);
+}
+
+timeval TimeUtil::DurationToTimeval(const Duration& value) {
+  timeval result;
+  result.tv_sec = value.seconds();
+  result.tv_usec = RoundTowardZero(value.nanos(), kNanosPerMicrosecond);
+  // timeval.tv_usec's range is [0, 1000000)
+  if (result.tv_usec < 0) {
+    result.tv_sec -= 1;
+    result.tv_usec += kMicrosPerSecond;
+  }
+  return result;
+}
+
+}  // namespace util
+}  // namespace protobuf
+
+
+namespace protobuf {
+namespace {
+using google::protobuf::util::kNanosPerSecond;
+using google::protobuf::util::CreateNormalized;
+
+// Convert a Timestamp to uint128.
+void ToUint128(const Timestamp& value, uint128* result, bool* negative) {
+  if (value.seconds() < 0) {
+    *negative = true;
+    *result = static_cast<uint64>(-value.seconds());
+    *result = *result * kNanosPerSecond - static_cast<uint32>(value.nanos());
+  } else {
+    *negative = false;
+    *result = static_cast<uint64>(value.seconds());
+    *result = *result * kNanosPerSecond + static_cast<uint32>(value.nanos());
+  }
+}
+
+// Convert a Duration to uint128.
+void ToUint128(const Duration& value, uint128* result, bool* negative) {
+  if (value.seconds() < 0 || value.nanos() < 0) {
+    *negative = true;
+    *result = static_cast<uint64>(-value.seconds());
+    *result = *result * kNanosPerSecond + static_cast<uint32>(-value.nanos());
+  } else {
+    *negative = false;
+    *result = static_cast<uint64>(value.seconds());
+    *result = *result * kNanosPerSecond + static_cast<uint32>(value.nanos());
+  }
+}
+
+void ToTimestamp(const uint128& value, bool negative, Timestamp* timestamp) {
+  int64 seconds = static_cast<int64>(Uint128Low64(value / kNanosPerSecond));
+  int32 nanos = static_cast<int32>(Uint128Low64(value % kNanosPerSecond));
+  if (negative) {
+    seconds = -seconds;
+    nanos = -nanos;
+    if (nanos < 0) {
+      nanos += kNanosPerSecond;
+      seconds -= 1;
+    }
+  }
+  timestamp->set_seconds(seconds);
+  timestamp->set_nanos(nanos);
+}
+
+void ToDuration(const uint128& value, bool negative, Duration* duration) {
+  int64 seconds = static_cast<int64>(Uint128Low64(value / kNanosPerSecond));
+  int32 nanos = static_cast<int32>(Uint128Low64(value % kNanosPerSecond));
+  if (negative) {
+    seconds = -seconds;
+    nanos = -nanos;
+  }
+  duration->set_seconds(seconds);
+  duration->set_nanos(nanos);
+}
+}  // namespace
+
+Duration& operator+=(Duration& d1, const Duration& d2) {
+  d1 = CreateNormalized<Duration>(d1.seconds() + d2.seconds(),
+                                  d1.nanos() + d2.nanos());
+  return d1;
+}
+
+Duration& operator-=(Duration& d1, const Duration& d2) {  // NOLINT
+  d1 = CreateNormalized<Duration>(d1.seconds() - d2.seconds(),
+                                  d1.nanos() - d2.nanos());
+  return d1;
+}
+
+Duration& operator*=(Duration& d, int64 r) {  // NOLINT
+  bool negative;
+  uint128 value;
+  ToUint128(d, &value, &negative);
+  if (r > 0) {
+    value *= static_cast<uint64>(r);
+  } else {
+    negative = !negative;
+    value *= static_cast<uint64>(-r);
+  }
+  ToDuration(value, negative, &d);
+  return d;
+}
+
+Duration& operator*=(Duration& d, double r) {  // NOLINT
+  double result = (d.seconds() * 1.0 + 1.0 * d.nanos() / kNanosPerSecond) * r;
+  int64 seconds = static_cast<int64>(result);
+  int32 nanos = static_cast<int32>((result - seconds) * kNanosPerSecond);
+  // Note that we normalize here not just because nanos can have a different
+  // sign from seconds but also that nanos can be any arbitrary value when
+  // overflow happens (i.e., the result is a much larger value than what
+  // int64 can represent).
+  d = CreateNormalized<Duration>(seconds, nanos);
+  return d;
+}
+
+Duration& operator/=(Duration& d, int64 r) {  // NOLINT
+  bool negative;
+  uint128 value;
+  ToUint128(d, &value, &negative);
+  if (r > 0) {
+    value /= static_cast<uint64>(r);
+  } else {
+    negative = !negative;
+    value /= static_cast<uint64>(-r);
+  }
+  ToDuration(value, negative, &d);
+  return d;
+}
+
+Duration& operator/=(Duration& d, double r) {  // NOLINT
+  return d *= 1.0 / r;
+}
+
+Duration& operator%=(Duration& d1, const Duration& d2) {  // NOLINT
+  bool negative1, negative2;
+  uint128 value1, value2;
+  ToUint128(d1, &value1, &negative1);
+  ToUint128(d2, &value2, &negative2);
+  uint128 result = value1 % value2;
+  // When negative values are involved in division, we round the division
+  // result towards zero. With this semantics, sign of the remainder is the
+  // same as the dividend. For example:
+  //     -5 / 10    = 0, -5 % 10    = -5
+  //     -5 / (-10) = 0, -5 % (-10) = -5
+  //      5 / (-10) = 0,  5 % (-10) = 5
+  ToDuration(result, negative1, &d1);
+  return d1;
+}
+
+int64 operator/(const Duration& d1, const Duration& d2) {
+  bool negative1, negative2;
+  uint128 value1, value2;
+  ToUint128(d1, &value1, &negative1);
+  ToUint128(d2, &value2, &negative2);
+  int64 result = Uint128Low64(value1 / value2);
+  if (negative1 != negative2) {
+    result = -result;
+  }
+  return result;
+}
+
+Timestamp& operator+=(Timestamp& t, const Duration& d) {  // NOLINT
+  t = CreateNormalized<Timestamp>(t.seconds() + d.seconds(),
+                                  t.nanos() + d.nanos());
+  return t;
+}
+
+Timestamp& operator-=(Timestamp& t, const Duration& d) {  // NOLINT
+  t = CreateNormalized<Timestamp>(t.seconds() - d.seconds(),
+                                  t.nanos() - d.nanos());
+  return t;
+}
+
+Duration operator-(const Timestamp& t1, const Timestamp& t2) {
+  return CreateNormalized<Duration>(t1.seconds() - t2.seconds(),
+                                    t1.nanos() - t2.nanos());
+}
+}  // namespace protobuf
+
+}  // namespace google
diff --git a/src/google/protobuf/util/time_util.h b/src/google/protobuf/util/time_util.h
new file mode 100644
index 0000000..1126815
--- /dev/null
+++ b/src/google/protobuf/util/time_util.h
@@ -0,0 +1,287 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
+#define GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
+
+#include <sys/time.h>
+
+#include <ctime>
+#include <ostream>
+#include <string>
+
+#include <google/protobuf/duration.pb.h>
+#include <google/protobuf/timestamp.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+class LIBPROTOBUF_EXPORT TimeUtil {
+  typedef google::protobuf::Timestamp Timestamp;
+  typedef google::protobuf::Duration Duration;
+
+ public:
+  // The min/max Timestamp/Duration values we support.
+  //
+  // For "0001-01-01T00:00:00Z".
+  static const int64 kTimestampMinSeconds = -62135596800LL;
+  // For "9999-12-31T23:59:59.999999999Z".
+  static const int64 kTimestampMaxSeconds = 253402300799LL;
+  static const int64 kDurationMinSeconds = -315576000000LL;
+  static const int64 kDurationMaxSeconds = 315576000000LL;
+
+  // Converts Timestamp to/from RFC 3339 date string format.
+  // Generated output will always be Z-normalized and uses 3, 6 or 9
+  // fractional digits as required to represent the exact time. When
+  // parsing, any fractional digits (or none) and any offset are
+  // accepted as long as they fit into nano-seconds precision.
+  // Note that Timestamp can only represent time from
+  // 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. Converting
+  // a Timestamp outside of this range is undefined behavior.
+  // See https://www.ietf.org/rfc/rfc3339.txt
+  //
+  // Example of generated format:
+  //   "1972-01-01T10:00:20.021Z"
+  //
+  // Example of accepted format:
+  //   "1972-01-01T10:00:20.021-05:00"
+  static string ToString(const Timestamp& timestamp);
+  static bool FromString(const string& value, Timestamp* timestamp);
+
+  // Converts Duration to/from string format. The string format will contains
+  // 3, 6, or 9 fractional digits depending on the precision required to
+  // represent the exact Duration value. For example:
+  //   "1s", "1.010s", "1.000000100s", "-3.100s"
+  // The range that can be represented by Duration is from -315,576,000,000
+  // to +315,576,000,000 inclusive (in seconds).
+  static string ToString(const Duration& duration);
+  static bool FromString(const string& value, Duration* timestamp);
+
+  // Gets the current UTC time.
+  static Timestamp GetCurrentTime();
+  // Returns the Time representing "1970-01-01 00:00:00".
+  static Timestamp GetEpoch();
+
+  // Converts between Duration and integer types. The behavior is undefined if
+  // the input value is not in the valid range of Duration.
+  static Duration NanosecondsToDuration(int64 nanos);
+  static Duration MicrosecondsToDuration(int64 micros);
+  static Duration MillisecondsToDuration(int64 millis);
+  static Duration SecondsToDuration(int64 seconds);
+  static Duration MinutesToDuration(int64 minutes);
+  static Duration HoursToDuration(int64 hours);
+  // Result will be truncated towards zero. For example, "-1.5s" will be
+  // truncated to "-1s", and "1.5s" to "1s" when converting to seconds.
+  // It's undefined behavior if the input duration is not valid or the result
+  // exceeds the range of int64. A duration is not valid if it's not in the
+  // valid range of Duration, or have an invalid nanos value (i.e., larger
+  // than 999999999, less than -999999999, or have a different sign from the
+  // seconds part).
+  static int64 DurationToNanoseconds(const Duration& duration);
+  static int64 DurationToMicroseconds(const Duration& duration);
+  static int64 DurationToMilliseconds(const Duration& duration);
+  static int64 DurationToSeconds(const Duration& duration);
+  static int64 DurationToMinutes(const Duration& duration);
+  static int64 DurationToHours(const Duration& duration);
+  // Creates Timestamp from integer types. The integer value indicates the
+  // time elapsed from Epoch time. The behavior is undefined if the input
+  // value is not in the valid range of Timestamp.
+  static Timestamp NanosecondsToTimestamp(int64 nanos);
+  static Timestamp MicrosecondsToTimestamp(int64 micros);
+  static Timestamp MillisecondsToTimestamp(int64 millis);
+  static Timestamp SecondsToTimestamp(int64 seconds);
+  // Result will be truncated down to the nearest integer value. For example,
+  // with "1969-12-31T23:59:59.9Z", TimestampToMilliseconds() returns -100
+  // and TimestampToSeconds() returns -1. It's undefined behavior if the input
+  // Timestamp is not valid (i.e., its seconds part or nanos part does not fall
+  // in the valid range) or the return value doesn't fit into int64.
+  static int64 TimestampToNanoseconds(const Timestamp& timestamp);
+  static int64 TimestampToMicroseconds(const Timestamp& timestamp);
+  static int64 TimestampToMilliseconds(const Timestamp& timestamp);
+  static int64 TimestampToSeconds(const Timestamp& timestamp);
+
+  // Conversion to/from other time/date types. Note that these types may
+  // have a different precision and time range from Timestamp/Duration.
+  // When converting to a lower precision type, the value will be truncated
+  // to the nearest value that can be represented. If the value is
+  // out of the range of the result type, the return value is undefined.
+  //
+  // Conversion to/from time_t
+  static Timestamp TimeTToTimestamp(time_t value);
+  static time_t TimestampToTimeT(const Timestamp& value);
+
+  // Conversion to/from timeval
+  static Timestamp TimevalToTimestamp(const timeval& value);
+  static timeval TimestampToTimeval(const Timestamp& value);
+  static Duration TimevalToDuration(const timeval& value);
+  static timeval DurationToTimeval(const Duration& value);
+};
+
+}  // namespace util
+}  // namespace protobuf
+
+
+namespace protobuf {
+// Overloaded operators for Duration.
+//
+// Assignment operators.
+Duration& operator+=(Duration& d1, const Duration& d2);  // NOLINT
+Duration& operator-=(Duration& d1, const Duration& d2);  // NOLINT
+Duration& operator*=(Duration& d, int64 r);  // NOLINT
+Duration& operator*=(Duration& d, double r);  // NOLINT
+Duration& operator/=(Duration& d, int64 r);  // NOLINT
+Duration& operator/=(Duration& d, double r);  // NOLINT
+// Overload for other integer types.
+template <typename T>
+Duration& operator*=(Duration& d, T r) {  // NOLINT
+  int64 x = r;
+  return d *= x;
+}
+template <typename T>
+Duration& operator/=(Duration& d, T r) {  // NOLINT
+  int64 x = r;
+  return d /= x;
+}
+Duration& operator%=(Duration& d1, const Duration& d2);  // NOLINT
+// Relational operators.
+inline bool operator<(const Duration& d1, const Duration& d2) {
+  if (d1.seconds() == d2.seconds()) {
+    return d1.nanos() < d2.nanos();
+  }
+  return d1.seconds() < d2.seconds();
+}
+inline bool operator>(const Duration& d1, const Duration& d2) {
+  return d2 < d1;
+}
+inline bool operator>=(const Duration& d1, const Duration& d2) {
+  return !(d1 < d2);
+}
+inline bool operator<=(const Duration& d1, const Duration& d2) {
+  return !(d2 < d1);
+}
+inline bool operator==(const Duration& d1, const Duration& d2) {
+  return d1.seconds() == d2.seconds() && d1.nanos() == d2.nanos();
+}
+inline bool operator!=(const Duration& d1, const Duration& d2) {
+  return !(d1 == d2);
+}
+// Additive operators
+inline Duration operator-(const Duration& d) {
+  Duration result;
+  result.set_seconds(-d.seconds());
+  result.set_nanos(-d.nanos());
+  return result;
+}
+inline Duration operator+(const Duration& d1, const Duration& d2) {
+  Duration result = d1;
+  return result += d2;
+}
+inline Duration operator-(const Duration& d1, const Duration& d2) {
+  Duration result = d1;
+  return result -= d2;
+}
+// Multiplicative operators
+template<typename T>
+inline Duration operator*(Duration d, T r) {
+  return d *= r;
+}
+template<typename T>
+inline Duration operator*(T r, Duration d) {
+  return d *= r;
+}
+template<typename T>
+inline Duration operator/(Duration d, T r) {
+  return d /= r;
+}
+int64 operator/(const Duration& d1, const Duration& d2);
+
+inline Duration operator%(const Duration& d1, const Duration& d2) {
+  Duration result = d1;
+  return result %= d2;
+}
+
+inline ostream& operator<<(ostream& out, const Duration& d) {
+  out << google::protobuf::util::TimeUtil::ToString(d);
+  return out;
+}
+
+// Overloaded operators for Timestamp
+//
+// Assignement operators.
+Timestamp& operator+=(Timestamp& t, const Duration& d);  // NOLINT
+Timestamp& operator-=(Timestamp& t, const Duration& d);  // NOLINT
+// Relational operators.
+inline bool operator<(const Timestamp& t1, const Timestamp& t2) {
+  if (t1.seconds() == t2.seconds()) {
+    return t1.nanos() < t2.nanos();
+  }
+  return t1.seconds() < t2.seconds();
+}
+inline bool operator>(const Timestamp& t1, const Timestamp& t2) {
+  return t2 < t1;
+}
+inline bool operator>=(const Timestamp& t1, const Timestamp& t2) {
+  return !(t1 < t2);
+}
+inline bool operator<=(const Timestamp& t1, const Timestamp& t2) {
+  return !(t2 < t1);
+}
+inline bool operator==(const Timestamp& t1, const Timestamp& t2) {
+  return t1.seconds() == t2.seconds() && t1.nanos() == t2.nanos();
+}
+inline bool operator!=(const Timestamp& t1, const Timestamp& t2) {
+  return !(t1 == t2);
+}
+// Additive operators.
+inline Timestamp operator+(const Timestamp& t, const Duration& d) {
+  Timestamp result = t;
+  return result += d;
+}
+inline Timestamp operator+(const Duration& d, const Timestamp& t) {
+  Timestamp result = t;
+  return result += d;
+}
+inline Timestamp operator-(const Timestamp& t, const Duration& d) {
+  Timestamp result = t;
+  return result -= d;
+}
+Duration operator-(const Timestamp& t1, const Timestamp& t2);
+
+inline ostream& operator<<(ostream& out, const Timestamp& t) {
+  out << google::protobuf::util::TimeUtil::ToString(t);
+  return out;
+}
+
+}  // namespace protobuf
+
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
diff --git a/src/google/protobuf/util/time_util_test.cc b/src/google/protobuf/util/time_util_test.cc
new file mode 100644
index 0000000..285740a
--- /dev/null
+++ b/src/google/protobuf/util/time_util_test.cc
@@ -0,0 +1,380 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/util/time_util.h>
+
+#include <ctime>
+
+#include <google/protobuf/timestamp.pb.h>
+#include <google/protobuf/duration.pb.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+using google::protobuf::Timestamp;
+using google::protobuf::Duration;
+
+namespace {
+
+TEST(TimeUtilTest, TimestampStringFormat) {
+  Timestamp begin, end;
+  EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
+  EXPECT_EQ(TimeUtil::kTimestampMinSeconds, begin.seconds());
+  EXPECT_EQ(0, begin.nanos());
+  EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
+  EXPECT_EQ(TimeUtil::kTimestampMaxSeconds, end.seconds());
+  EXPECT_EQ(999999999, end.nanos());
+  EXPECT_EQ("0001-01-01T00:00:00Z", TimeUtil::ToString(begin));
+  EXPECT_EQ("9999-12-31T23:59:59.999999999Z", TimeUtil::ToString(end));
+
+  // Test negative timestamps.
+  Timestamp time = TimeUtil::NanosecondsToTimestamp(-1);
+  EXPECT_EQ(-1, time.seconds());
+  // Timestamp's nano part is always non-negative.
+  EXPECT_EQ(999999999, time.nanos());
+  EXPECT_EQ("1969-12-31T23:59:59.999999999Z", TimeUtil::ToString(time));
+
+  // Generated output should contain 3, 6, or 9 fractional digits.
+  EXPECT_EQ("1970-01-01T00:00:00Z",
+            TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(0)));
+  EXPECT_EQ("1970-01-01T00:00:00.010Z",
+            TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10000000)));
+  EXPECT_EQ("1970-01-01T00:00:00.000010Z",
+            TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10000)));
+  EXPECT_EQ("1970-01-01T00:00:00.000000010Z",
+            TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10)));
+
+  // Parsing accepts an fractional digits as long as they fit into nano
+  // precision.
+  EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.1Z", &time));
+  EXPECT_EQ(100000000, TimeUtil::TimestampToNanoseconds(time));
+  EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.0001Z", &time));
+  EXPECT_EQ(100000, TimeUtil::TimestampToNanoseconds(time));
+  EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.0000001Z", &time));
+  EXPECT_EQ(100, TimeUtil::TimestampToNanoseconds(time));
+
+  // Also accpets offsets.
+  EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00-08:00", &time));
+  EXPECT_EQ(8 * 3600, TimeUtil::TimestampToSeconds(time));
+}
+
+TEST(TimeUtilTest, DurationStringFormat) {
+  Timestamp begin, end;
+  EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
+  EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
+
+  EXPECT_EQ("315537897599.999999999s", TimeUtil::ToString(end - begin));
+  EXPECT_EQ(999999999, (end - begin).nanos());
+  EXPECT_EQ("-315537897599.999999999s", TimeUtil::ToString(begin - end));
+  EXPECT_EQ(-999999999, (begin - end).nanos());
+
+  // Generated output should contain 3, 6, or 9 fractional digits.
+  EXPECT_EQ("1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(1)));
+  EXPECT_EQ("0.010s", TimeUtil::ToString(TimeUtil::MillisecondsToDuration(10)));
+  EXPECT_EQ("0.000010s",
+            TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(10)));
+  EXPECT_EQ("0.000000010s",
+            TimeUtil::ToString(TimeUtil::NanosecondsToDuration(10)));
+
+  // Parsing accepts an fractional digits as long as they fit into nano
+  // precision.
+  Duration d;
+  EXPECT_TRUE(TimeUtil::FromString("0.1s", &d));
+  EXPECT_EQ(100, TimeUtil::DurationToMilliseconds(d));
+  EXPECT_TRUE(TimeUtil::FromString("0.0001s", &d));
+  EXPECT_EQ(100, TimeUtil::DurationToMicroseconds(d));
+  EXPECT_TRUE(TimeUtil::FromString("0.0000001s", &d));
+  EXPECT_EQ(100, TimeUtil::DurationToNanoseconds(d));
+
+  // Duration must support range from -315,576,000,000s to +315576000000s
+  // which includes negative values.
+  EXPECT_TRUE(TimeUtil::FromString("315576000000.999999999s", &d));
+  EXPECT_EQ(315576000000LL, d.seconds());
+  EXPECT_EQ(999999999, d.nanos());
+  EXPECT_TRUE(TimeUtil::FromString("-315576000000.999999999s", &d));
+  EXPECT_EQ(-315576000000LL, d.seconds());
+  EXPECT_EQ(-999999999, d.nanos());
+}
+
+TEST(TimeUtilTest, GetEpoch) {
+  EXPECT_EQ(0, TimeUtil::TimestampToNanoseconds(TimeUtil::GetEpoch()));
+}
+
+TEST(TimeUtilTest, DurationIntegerConversion) {
+  EXPECT_EQ("0.000000001s",
+            TimeUtil::ToString(TimeUtil::NanosecondsToDuration(1)));
+  EXPECT_EQ("-0.000000001s",
+            TimeUtil::ToString(TimeUtil::NanosecondsToDuration(-1)));
+  EXPECT_EQ("0.000001s",
+            TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(1)));
+  EXPECT_EQ("-0.000001s",
+            TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(-1)));
+  EXPECT_EQ("0.001s", TimeUtil::ToString(TimeUtil::MillisecondsToDuration(1)));
+  EXPECT_EQ("-0.001s",
+            TimeUtil::ToString(TimeUtil::MillisecondsToDuration(-1)));
+  EXPECT_EQ("1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(1)));
+  EXPECT_EQ("-1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(-1)));
+  EXPECT_EQ("60s", TimeUtil::ToString(TimeUtil::MinutesToDuration(1)));
+  EXPECT_EQ("-60s", TimeUtil::ToString(TimeUtil::MinutesToDuration(-1)));
+  EXPECT_EQ("3600s", TimeUtil::ToString(TimeUtil::HoursToDuration(1)));
+  EXPECT_EQ("-3600s", TimeUtil::ToString(TimeUtil::HoursToDuration(-1)));
+
+  EXPECT_EQ(
+      1, TimeUtil::DurationToNanoseconds(TimeUtil::NanosecondsToDuration(1)));
+  EXPECT_EQ(
+      -1, TimeUtil::DurationToNanoseconds(TimeUtil::NanosecondsToDuration(-1)));
+  EXPECT_EQ(
+      1, TimeUtil::DurationToMicroseconds(TimeUtil::MicrosecondsToDuration(1)));
+  EXPECT_EQ(-1, TimeUtil::DurationToMicroseconds(
+                    TimeUtil::MicrosecondsToDuration(-1)));
+  EXPECT_EQ(
+      1, TimeUtil::DurationToMilliseconds(TimeUtil::MillisecondsToDuration(1)));
+  EXPECT_EQ(-1, TimeUtil::DurationToMilliseconds(
+                    TimeUtil::MillisecondsToDuration(-1)));
+  EXPECT_EQ(1, TimeUtil::DurationToSeconds(TimeUtil::SecondsToDuration(1)));
+  EXPECT_EQ(-1, TimeUtil::DurationToSeconds(TimeUtil::SecondsToDuration(-1)));
+  EXPECT_EQ(1, TimeUtil::DurationToMinutes(TimeUtil::MinutesToDuration(1)));
+  EXPECT_EQ(-1, TimeUtil::DurationToMinutes(TimeUtil::MinutesToDuration(-1)));
+  EXPECT_EQ(1, TimeUtil::DurationToHours(TimeUtil::HoursToDuration(1)));
+  EXPECT_EQ(-1, TimeUtil::DurationToHours(TimeUtil::HoursToDuration(-1)));
+
+  // Test truncation behavior.
+  EXPECT_EQ(1, TimeUtil::DurationToMicroseconds(
+                   TimeUtil::NanosecondsToDuration(1999)));
+  // For negative values, Duration will be rounded towards 0.
+  EXPECT_EQ(-1, TimeUtil::DurationToMicroseconds(
+                    TimeUtil::NanosecondsToDuration(-1999)));
+}
+
+TEST(TestUtilTest, TimestampIntegerConversion) {
+  EXPECT_EQ("1970-01-01T00:00:00.000000001Z",
+            TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(1)));
+  EXPECT_EQ("1969-12-31T23:59:59.999999999Z",
+            TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(-1)));
+  EXPECT_EQ("1970-01-01T00:00:00.000001Z",
+            TimeUtil::ToString(TimeUtil::MicrosecondsToTimestamp(1)));
+  EXPECT_EQ("1969-12-31T23:59:59.999999Z",
+            TimeUtil::ToString(TimeUtil::MicrosecondsToTimestamp(-1)));
+  EXPECT_EQ("1970-01-01T00:00:00.001Z",
+            TimeUtil::ToString(TimeUtil::MillisecondsToTimestamp(1)));
+  EXPECT_EQ("1969-12-31T23:59:59.999Z",
+            TimeUtil::ToString(TimeUtil::MillisecondsToTimestamp(-1)));
+  EXPECT_EQ("1970-01-01T00:00:01Z",
+            TimeUtil::ToString(TimeUtil::SecondsToTimestamp(1)));
+  EXPECT_EQ("1969-12-31T23:59:59Z",
+            TimeUtil::ToString(TimeUtil::SecondsToTimestamp(-1)));
+
+  EXPECT_EQ(
+      1, TimeUtil::TimestampToNanoseconds(TimeUtil::NanosecondsToTimestamp(1)));
+  EXPECT_EQ(-1, TimeUtil::TimestampToNanoseconds(
+                    TimeUtil::NanosecondsToTimestamp(-1)));
+  EXPECT_EQ(1, TimeUtil::TimestampToMicroseconds(
+                   TimeUtil::MicrosecondsToTimestamp(1)));
+  EXPECT_EQ(-1, TimeUtil::TimestampToMicroseconds(
+                    TimeUtil::MicrosecondsToTimestamp(-1)));
+  EXPECT_EQ(1, TimeUtil::TimestampToMilliseconds(
+                   TimeUtil::MillisecondsToTimestamp(1)));
+  EXPECT_EQ(-1, TimeUtil::TimestampToMilliseconds(
+                    TimeUtil::MillisecondsToTimestamp(-1)));
+  EXPECT_EQ(1, TimeUtil::TimestampToSeconds(TimeUtil::SecondsToTimestamp(1)));
+  EXPECT_EQ(-1, TimeUtil::TimestampToSeconds(TimeUtil::SecondsToTimestamp(-1)));
+
+  // Test truncation behavior.
+  EXPECT_EQ(1, TimeUtil::TimestampToMicroseconds(
+                   TimeUtil::NanosecondsToTimestamp(1999)));
+  // For negative values, Timestamp will be rounded down.
+  // For example, "1969-12-31T23:59:59.5Z" (i.e., -0.5s) rounded to seconds
+  // will be "1969-12-31T23:59:59Z" (i.e., -1s) rather than
+  // "1970-01-01T00:00:00Z" (i.e., 0s).
+  EXPECT_EQ(-2, TimeUtil::TimestampToMicroseconds(
+                    TimeUtil::NanosecondsToTimestamp(-1999)));
+}
+
+TEST(TimeUtilTest, TimeTConversion) {
+  time_t value = time(NULL);
+  EXPECT_EQ(value,
+            TimeUtil::TimestampToTimeT(TimeUtil::TimeTToTimestamp(value)));
+  EXPECT_EQ(
+      1, TimeUtil::TimestampToTimeT(TimeUtil::MillisecondsToTimestamp(1999)));
+}
+
+TEST(TimeUtilTest, TimevalConversion) {
+  timeval value = TimeUtil::TimestampToTimeval(
+      TimeUtil::NanosecondsToTimestamp(1999999999));
+  EXPECT_EQ(1, value.tv_sec);
+  EXPECT_EQ(999999, value.tv_usec);
+  value = TimeUtil::TimestampToTimeval(
+      TimeUtil::NanosecondsToTimestamp(-1999999999));
+  EXPECT_EQ(-2, value.tv_sec);
+  EXPECT_EQ(0, value.tv_usec);
+
+  value =
+      TimeUtil::DurationToTimeval(TimeUtil::NanosecondsToDuration(1999999999));
+  EXPECT_EQ(1, value.tv_sec);
+  EXPECT_EQ(999999, value.tv_usec);
+  value =
+      TimeUtil::DurationToTimeval(TimeUtil::NanosecondsToDuration(-1999999999));
+  EXPECT_EQ(-2, value.tv_sec);
+  EXPECT_EQ(1, value.tv_usec);
+}
+
+TEST(TimeUtilTest, DurationOperators) {
+  Duration one_second = TimeUtil::SecondsToDuration(1);
+  Duration one_nano = TimeUtil::NanosecondsToDuration(1);
+
+  // Test +/-
+  Duration a = one_second;
+  a += one_second;
+  a -= one_nano;
+  EXPECT_EQ("1.999999999s", TimeUtil::ToString(a));
+  Duration b = -a;
+  EXPECT_EQ("-1.999999999s", TimeUtil::ToString(b));
+  EXPECT_EQ("3.999999998s", TimeUtil::ToString(a + a));
+  EXPECT_EQ("0s", TimeUtil::ToString(a + b));
+  EXPECT_EQ("0s", TimeUtil::ToString(b + a));
+  EXPECT_EQ("-3.999999998s", TimeUtil::ToString(b + b));
+  EXPECT_EQ("3.999999998s", TimeUtil::ToString(a - b));
+  EXPECT_EQ("0s", TimeUtil::ToString(a - a));
+  EXPECT_EQ("0s", TimeUtil::ToString(b - b));
+  EXPECT_EQ("-3.999999998s", TimeUtil::ToString(b - a));
+
+  // Test *
+  EXPECT_EQ(a + a, a * 2);
+  EXPECT_EQ(b + b, a * (-2));
+  EXPECT_EQ(b + b, b * 2);
+  EXPECT_EQ(a + a, b * (-2));
+  EXPECT_EQ("0.999999999s", TimeUtil::ToString(a * 0.5));
+  EXPECT_EQ("-0.999999999s", TimeUtil::ToString(b * 0.5));
+  // Multiplication should not overflow if the result fits into the supported
+  // range of Duration (intermediate result may be larger than int64).
+  EXPECT_EQ("315575999684.424s",
+            TimeUtil::ToString((one_second - one_nano) * 315576000000LL));
+  EXPECT_EQ("-315575999684.424s",
+            TimeUtil::ToString((one_nano - one_second) * 315576000000LL));
+  EXPECT_EQ("-315575999684.424s",
+            TimeUtil::ToString((one_second - one_nano) * (-315576000000LL)));
+
+  // Test / and %
+  EXPECT_EQ("0.999999999s", TimeUtil::ToString(a / 2));
+  EXPECT_EQ("-0.999999999s", TimeUtil::ToString(b / 2));
+  Duration large = TimeUtil::SecondsToDuration(315576000000LL) - one_nano;
+  // We have to handle division with values beyond 64 bits.
+  EXPECT_EQ("0.999999999s", TimeUtil::ToString(large / 315576000000LL));
+  EXPECT_EQ("-0.999999999s", TimeUtil::ToString((-large) / 315576000000LL));
+  EXPECT_EQ("-0.999999999s", TimeUtil::ToString(large / (-315576000000LL)));
+  Duration large2 = large + one_nano;
+  EXPECT_EQ(large, large % large2);
+  EXPECT_EQ(-large, (-large) % large2);
+  EXPECT_EQ(large, large % (-large2));
+  EXPECT_EQ(one_nano, large2 % large);
+  EXPECT_EQ(-one_nano, (-large2) % large);
+  EXPECT_EQ(one_nano, large2 % (-large));
+  // Some corner cases about negative values.
+  //
+  // (-5) / 2 = -2, remainder = -1
+  // (-5) / (-2) = 2, remainder = -1
+  a = TimeUtil::NanosecondsToDuration(-5);
+  EXPECT_EQ(TimeUtil::NanosecondsToDuration(-2), a / 2);
+  EXPECT_EQ(TimeUtil::NanosecondsToDuration(2), a / (-2));
+  b = TimeUtil::NanosecondsToDuration(2);
+  EXPECT_EQ(-2, a / b);
+  EXPECT_EQ(TimeUtil::NanosecondsToDuration(-1), a % b);
+  EXPECT_EQ(2, a / (-b));
+  EXPECT_EQ(TimeUtil::NanosecondsToDuration(-1), a % (-b));
+
+  // Test relational operators.
+  EXPECT_TRUE(one_nano < one_second);
+  EXPECT_FALSE(one_second < one_second);
+  EXPECT_FALSE(one_second < one_nano);
+  EXPECT_FALSE(-one_nano < -one_second);
+  EXPECT_FALSE(-one_second < -one_second);
+  EXPECT_TRUE(-one_second < -one_nano);
+  EXPECT_TRUE(-one_nano < one_nano);
+  EXPECT_FALSE(one_nano < -one_nano);
+
+  EXPECT_FALSE(one_nano > one_second);
+  EXPECT_FALSE(one_nano > one_nano);
+  EXPECT_TRUE(one_second > one_nano);
+
+  EXPECT_FALSE(one_nano >= one_second);
+  EXPECT_TRUE(one_nano >= one_nano);
+  EXPECT_TRUE(one_second >= one_nano);
+
+  EXPECT_TRUE(one_nano <= one_second);
+  EXPECT_TRUE(one_nano <= one_nano);
+  EXPECT_FALSE(one_second <= one_nano);
+
+  EXPECT_TRUE(one_nano == one_nano);
+  EXPECT_FALSE(one_nano == one_second);
+
+  EXPECT_FALSE(one_nano != one_nano);
+  EXPECT_TRUE(one_nano != one_second);
+}
+
+TEST(TimeUtilTest, TimestampOperators) {
+  Timestamp begin, end;
+  EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
+  EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
+  Duration d = end - begin;
+  EXPECT_TRUE(end == begin + d);
+  EXPECT_TRUE(end == d + begin);
+  EXPECT_TRUE(begin == end - d);
+
+  // Test relational operators
+  Timestamp t1 = begin + d / 4;
+  Timestamp t2 = end - d / 4;
+  EXPECT_TRUE(t1 < t2);
+  EXPECT_FALSE(t1 < t1);
+  EXPECT_FALSE(t2 < t1);
+  EXPECT_FALSE(t1 > t2);
+  EXPECT_FALSE(t1 > t1);
+  EXPECT_TRUE(t2 > t1);
+  EXPECT_FALSE(t1 >= t2);
+  EXPECT_TRUE(t1 >= t1);
+  EXPECT_TRUE(t2 >= t1);
+  EXPECT_TRUE(t1 <= t2);
+  EXPECT_TRUE(t1 <= t1);
+  EXPECT_FALSE(t2 <= t1);
+
+  EXPECT_FALSE(t1 == t2);
+  EXPECT_TRUE(t1 == t1);
+  EXPECT_FALSE(t2 == t1);
+  EXPECT_TRUE(t1 != t2);
+  EXPECT_FALSE(t1 != t1);
+  EXPECT_TRUE(t2 != t1);
+}
+
+}  // namespace
+}  // namespace util
+}  // namespace protobuf
+}  // namespace google
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc
index db75db1..fd4b490 100644
--- a/src/google/protobuf/wrappers.pb.cc
+++ b/src/google/protobuf/wrappers.pb.cc
@@ -262,9 +262,10 @@
     "e\030\001 \001(\004\"\033\n\nInt32Value\022\r\n\005value\030\001 \001(\005\"\034\n\013"
     "UInt32Value\022\r\n\005value\030\001 \001(\r\"\032\n\tBoolValue\022"
     "\r\n\005value\030\001 \001(\010\"\034\n\013StringValue\022\r\n\005value\030\001"
-    " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014BM\n\023com"
-    ".google.protobufB\rWrappersProtoP\001\242\002\003GPB\252"
-    "\002\036Google.Protobuf.WellKnownTypesb\006proto3", 400);
+    " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014BP\n\023com"
+    ".google.protobufB\rWrappersProtoP\001\240\001\001\242\002\003G"
+    "PB\252\002\036Google.Protobuf.WellKnownTypesb\006pro"
+    "to3", 403);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "google/protobuf/wrappers.proto", &protobuf_RegisterTypes);
   DoubleValue::default_instance_ = new DoubleValue();
diff --git a/src/google/protobuf/wrappers.proto b/src/google/protobuf/wrappers.proto
index 6d3181b..a1d6e44 100644
--- a/src/google/protobuf/wrappers.proto
+++ b/src/google/protobuf/wrappers.proto
@@ -37,62 +37,80 @@
 
 package google.protobuf;
 
+option java_generate_equals_and_hash = true;
 option java_multiple_files = true;
 option java_outer_classname = "WrappersProto";
 option java_package = "com.google.protobuf";
 option csharp_namespace = "Google.Protobuf.WellKnownTypes";
 option objc_class_prefix = "GPB";
 
-
-// Wrapper message for double.
+// Wrapper message for `double`.
+//
+// The JSON representation for `DoubleValue` is JSON number.
 message DoubleValue {
   // The double value.
   double value = 1;
 }
 
-// Wrapper message for float.
+// Wrapper message for `float`.
+//
+// The JSON representation for `FloatValue` is JSON number.
 message FloatValue {
   // The float value.
   float value = 1;
 }
 
-// Wrapper message for int64.
+// Wrapper message for `int64`.
+//
+// The JSON representation for `Int64Value` is JSON string.
 message Int64Value {
   // The int64 value.
   int64 value = 1;
 }
 
-// Wrapper message for uint64.
+// Wrapper message for `uint64`.
+//
+// The JSON representation for `UInt64Value` is JSON string.
 message UInt64Value {
   // The uint64 value.
   uint64 value = 1;
 }
 
-// Wrapper message for int32.
+// Wrapper message for `int32`.
+//
+// The JSON representation for `Int32Value` is JSON number.
 message Int32Value {
   // The int32 value.
   int32 value = 1;
 }
 
-// Wrapper message for uint32.
+// Wrapper message for `uint32`.
+//
+// The JSON representation for `UInt32Value` is JSON number.
 message UInt32Value {
   // The uint32 value.
   uint32 value = 1;
 }
 
-// Wrapper message for bool.
+// Wrapper message for `bool`.
+//
+// The JSON representation for `BoolValue` is JSON `true` and `false`.
 message BoolValue {
   // The bool value.
   bool value = 1;
 }
 
-// Wrapper message for string.
+// Wrapper message for `string`.
+//
+// The JSON representation for `StringValue` is JSON string.
 message StringValue {
   // The string value.
   string value = 1;
 }
 
-// Wrapper message for bytes.
+// Wrapper message for `bytes`.
+//
+// The JSON representation for `BytesValue` is JSON string.
 message BytesValue {
   // The bytes value.
   bytes value = 1;
diff --git a/update_file_lists.sh b/update_file_lists.sh
index 3444345..206be43 100755
--- a/update_file_lists.sh
+++ b/update_file_lists.sh
@@ -133,11 +133,6 @@
 # Update bazel BUILD files.
 ################################################################################
 
-BAZEL_BUILD=./BUILD
-[ -f "$BAZEL_BUILD" ] || {
-  echo "Cannot find: $BAZEL_BUILD"
-  exit 1
-}
 set_bazel_value() {
   local FILENAME=$1
   local VARNAME=$2
@@ -169,14 +164,19 @@
 }
 
 
+BAZEL_BUILD=./BUILD
 BAZEL_PREFIX="src/"
-set_bazel_value $BAZEL_BUILD protobuf_lite_srcs $BAZEL_PREFIX $LIBPROTOBUF_LITE_SOURCES
-set_bazel_value $BAZEL_BUILD protobuf_srcs $BAZEL_PREFIX $LIBPROTOBUF_SOURCES
-set_bazel_value $BAZEL_BUILD protoc_lib_srcs $BAZEL_PREFIX $LIBPROTOC_SOURCES
-set_bazel_value $BAZEL_BUILD lite_test_protos "" $LITE_PROTOS
-set_bazel_value $BAZEL_BUILD well_known_protos "" $WKT_PROTOS
-set_bazel_value $BAZEL_BUILD test_protos "" $PROTOS
-set_bazel_value $BAZEL_BUILD common_test_srcs $BAZEL_PREFIX $COMMON_TEST_SOURCES
-set_bazel_value $BAZEL_BUILD test_srcs $BAZEL_PREFIX $TEST_SOURCES
-set_bazel_value $BAZEL_BUILD test_plugin_srcs $BAZEL_PREFIX $TEST_PLUGIN_SOURCES
+if [ -f "$BAZEL_BUILD" ]; then
+  set_bazel_value $BAZEL_BUILD protobuf_lite_srcs $BAZEL_PREFIX $LIBPROTOBUF_LITE_SOURCES
+  set_bazel_value $BAZEL_BUILD protobuf_srcs $BAZEL_PREFIX $LIBPROTOBUF_SOURCES
+  set_bazel_value $BAZEL_BUILD protoc_lib_srcs $BAZEL_PREFIX $LIBPROTOC_SOURCES
+  set_bazel_value $BAZEL_BUILD lite_test_protos "" $LITE_PROTOS
+  set_bazel_value $BAZEL_BUILD well_known_protos "" $WKT_PROTOS
+  set_bazel_value $BAZEL_BUILD test_protos "" $PROTOS
+  set_bazel_value $BAZEL_BUILD common_test_srcs $BAZEL_PREFIX $COMMON_TEST_SOURCES
+  set_bazel_value $BAZEL_BUILD test_srcs $BAZEL_PREFIX $TEST_SOURCES
+  set_bazel_value $BAZEL_BUILD test_plugin_srcs $BAZEL_PREFIX $TEST_PLUGIN_SOURCES
+else
+  echo "Skipped BUILD file update."
+fi