Upgrade nanopb to 0.3.9.1
am: 86bd676e06

Change-Id: Ib7ddacb28606b0c063ff5e6feabb3280be25e4ee
diff --git a/AUTHORS.txt b/AUTHORS.txt
new file mode 100644
index 0000000..0034abf
--- /dev/null
+++ b/AUTHORS.txt
@@ -0,0 +1,45 @@
+Petteri Aimonen <jpa@npb.mail.kapsi.fi>
+Michael Poole <mdpoole@troilus.org>
+Daniel Kan <extremeblue99@gmail.com>
+Stan Hu <stanhu@aclimalabs.com>
+David Hotham <david.hotham@blueyonder.co.uk>
+Steffen Siering <steffen siering gmail com>
+Jens Steinhauser <jens.steinhauser@gmail.com>
+Pavel Ilin <ilin.pa@gmail.com>
+Kent Ryhorchuk <kryhorchuk@xeralux.com>
+Martin Donath <scifish@gmail.com>
+Oliver Lee <oliverzlee@gmail.com>
+Michael Haberler <git@mah.priv.at>
+Nicolas Colomer <ncolomer@viadeoteam.com>
+Ivan Kravets <me@ikravets.com>
+Kyle Manna <kyle@kylemanna.com>
+Benjamin Kamath <ben.kamath@synapse.com>
+Andrew Ruder <andrew.ruder@elecsyscorp.com>
+Kenshi Kawaguchi <kenshi@recurse.ca>
+isotes <isotes@gmail.com>
+Maxim Khitrov <max@mxcrypt.com>
+Yaniv Mordekhay <yanivmo@users.noreply.github.com>
+Ming Zhao <mzhao@luminatewireless.com>
+Google, Inc.
+Tom Roeder <tmroeder@google.com>
+Piotr Sikora <piotrsikora@google.com>
+Bernhard Krämer <bdkrae@gmail.com>
+Konstantin Podsvirov <konstantin@podsvirov.pro>
+William A. Kennington III <wak@google.com>
+Guillaume Lager <g.lager@innoseis.com>
+Tobias Haegermarck <tobias.haegermarck@gmail.com>
+Justin DeMartino <jdemarti@gmail.com>
+Constantine Grantcharov <cgrantcharov@trustpointinnovation.com>
+Nick Ewalt <nicholasewalt@google.com>
+Harald Fernengel <harryf@gmx.com>
+Alice Wang <aw@squareup.com>
+Kevin Fitch <kfitch42@gmail.com>
+Kamal Marhubi <kamal@marhubi.com>
+Elco Jacobs <elco@brewpi.com>
+Sébastien Morin <sebastien.morin@primerogames.com>
+Dave Flogeras <dflogeras2@gmail.com>
+Edward Z. Yang <ezyang@mit.edu>
+Robbie Shade <rjshade@google.com>
+Andrew Ballinger <andrewballinger@stratisopt.com>
+Hamina, Juha-Pekka <Juha-Pekka.Hamina@nordicsemi.no>
+
diff --git a/Android.bp b/Android.bp
index f7d729f..d9378f9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -23,6 +23,7 @@
         "-Wno-unused-parameter",
     ],
     srcs: [
+        "pb_common.c",
         "pb_decode.c",
         "pb_encode.c",
     ],
diff --git a/BUILD b/BUILD
new file mode 100644
index 0000000..f9fc57f
--- /dev/null
+++ b/BUILD
@@ -0,0 +1,21 @@
+licenses(["notice"])
+
+exports_files(["LICENSE.txt"])
+
+package(default_visibility = ["//visibility:public"])
+
+cc_library(
+  name = "nanopb",
+  visibility = ["//visibility:public"],
+  hdrs = [
+    "pb.h",
+    "pb_common.h",
+    "pb_decode.h",
+    "pb_encode.h",
+  ],
+  srcs = [
+    "pb_common.c",
+    "pb_decode.c",
+    "pb_encode.c",
+  ],
+)
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 6d643ad..f7811a4 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,161 @@
+nanopb-0.3.9.1 (2017-04-xx)
+ Fix handling of special characters in string/bytes default values (issue #322)
+ Fix encoding of negative numbers with PB_WITHOUT_64BIT (#285)
+ Fix _zero initializer for enums that don't begin at 0. (#295)
+ Multiple CMake fixes (#296, #299, #304, #312, #320)
+ Fix compiler warnings (#305)
+ Fix scons rules for Python 3
+ Add check for large extension field number (issue #306)
+ Updated included descriptor.proto version (#314)
+ Resolve oneof sizes symbolically when needed (#311)
+ Add fixed_count option (#260)
+ Add some verbose prints in generator (issue #238)
+ Add test/example of using 'map' type. (#289)
+
+nanopb-0.3.9 (2017-09-23)
+ Fix bugs in proto3 encoding of submessages (#256)
+ Fix message size calculation for arrays of size 1 (#253)
+ Fix segfault with FT_CALLBACK inside FT_POINTER (#259)
+ Properly detect truncated tags in corrupted messages (#277)
+ Make pb_decode_varint32 overflow checks exact (#258)
+ Add option to build without 64-bit support (#86)
+ Add options to define source and header file extensions (#264)
+ Add pb_en/decode_nullterminated() (part of #278)
+ Add pb_decode_delimited_noinit (#284)
+ CMake: add dependency for .options file (#265)
+ CMake: change use of relative paths (#250,#271,#273)
+ Better error message for missing max_size option (#281)
+ Travis-CI build fixes (#283)
+ Add Bazel build system file (#266)
+
+nanopb-0.3.8 (2017-03-05)
+ Fix problems with multiple oneofs in same message (#229)
+ Zero-valued extension fields were mistakenly ignored by encoder (#242)
+ Multiple fixes related to proto3 mode (#242, #245, #247, #249)
+ Fix potential unaligned access (#226, #227)
+ Fix documentation for protoc --plugin argument (#239)
+ Extend inline / fixed length bytes array support (#244)
+ Add new option max_length for strings (#107)
+ Make string substream API more robust (#230)
+ Make pb_decode_varint32 public API (#231)
+ Allow overriding proto3 mode (#228)
+ Add optional enum->string mapping function (#223)
+ Add transitional options.proto file (#241)
+ Add better error message on Python library version imcompatibility (#240)
+ Include version number in PlatformIO library.json (#222)
+ CMake build script changes (#236, #237)
+ Change download links to https
+ Improvements to test cases.
+
+nanopb-0.3.7 (2016-10-30)
+ Add support for proto3-style singular fields (#182, #206, #216)
+ Updated binary package protoc to version 3.1.0
+ Add FT_INLINE allocation of bytes fields (#211)
+ Include package name in include guard (#207)
+ Fix missing warning with large bytes fields (issue #220)
+ Added CMake project (#208)
+ Add bazel BUILD file for nanopb (#209)
+ Added an AUTHORS file (#211)
+ Documentation updates
+ Improvements to test cases.
+
+nanopb-0.3.6 (2016-06-19)
+ Protect against corrupted _count fields in pb_release (#205)
+ Fix error in STATIC_ASSERT with multiple files (#203)
+ Add -D option to specify output directory (#193)
+ Generate MIN/MAX/ARRAYSIZE defines for enums (#194)
+ Generate comments about uncalculable message sizes (#195)
+ Documentation updates (#196, #201)
+ Improvements to test cases.
+
+nanopb-0.3.5 (2016-02-13)
+ NOTE: If you are using pb_syshdr.h, you will need to add uint_least8_t
+ definition. See docs/migration.rst for details.
+
+ Fix generator crash with Enum inside Oneof (#188)
+ Fix some generator regressions related to .options file path (#172)
+ Add support for platforms without uint8_t (#191)
+ Allow const parameter to pb_istream_from_buffer (#152)
+ Ignore null pointers in pb_release() (#183)
+ Add support for anonymous unions (#184)
+ Add Python3 support to the generator (#169)
+ Add code generator insertion points to generated files (#178)
+ Improvements to CMake script (#181)
+ Improvements to test cases.
+
+nanopb-0.3.4 (2015-09-26)
+ Fix handling of unsigned 8- and 16-bit enums (issue 164)
+ Fix generator on systems where python = python3. (issue 155)
+ Fix compiler warning on GCC 5.x (issue 171)
+ Make the generator better handle imported .protos (issue 165)
+ Add packed_enum option to generator.
+ Add syntax= line to .proto files (issue 167)
+ Add PlatformIO registry manifest file. (pr 156)
+
+nanopb-0.3.3 (2015-04-10)
+ Fix missing files in Linux binary package (issue 146)
+ Fix generator bug when oneof is first field in a message. (issue 142)
+ Fix generator error when long_names:false is combined with Oneofs. (issue 147)
+ Fix oneof submessage initialization bug. (issue 149)
+ Fix problem with plugin options on Python 2.7.2 and older. (issue 153)
+ Fix crash when callback is inside oneof field. (issue 148)
+ Switch to .tar.gz format for Mac OS X packages. (issue 154)
+ Always define enum long names so that cross-file references work. (issue 118)
+ Add msgid generator option. (issue 151)
+ Improve comment support in .options files. (issue 145)
+ Updates for the CMake rule file, add cmake example.
+ Better error messages for syntax errors in .options file
+
+nanopb-0.3.2 (2015-01-24)
+ Fix memory leaks with PB_ENABLE_MALLOC with some submessage hierarchies (issue 138)
+ Implement support for oneofs (C unions). (issues 131, 141)
+ Add int_size option for generator (issue 139)
+ Add compilation option to disable struct packing. (issue 136)
+ Change PB_RETURN_ERROR() macro to avoid compiler warnings (issue 140)
+ Fix build problems with protoc 3.0.0
+ Add support for POINTER type in extensions
+ Initialize also extension fields to defaults in pb_decode().
+ Detect too large varint values when decoding.
+
+nanopb-0.3.1 (2014-09-11)
+ Fix security issue due to size_t overflows. (issue 132)
+ Fix memory leak with duplicated fields and PB_ENABLE_MALLOC
+ Fix crash if pb_release() is called twice.
+ Fix cyclic message support (issue 130)
+ Fix error in generated initializers for repeated pointer fields.
+ Improve tests (issues 113, 126)
+
+nanopb-0.3.0 (2014-08-26)
+ NOTE: See docs/migration.html or online at
+ http://koti.kapsi.fi/~jpa/nanopb/docs/migration.html
+ for changes in this version. Most importantly, you need to add
+ pb_common.c to the list of files to compile.
+
+ Separated field iterator logic to pb_common.c (issue 128)
+ Change the _count fields to use pb_size_t datatype (issue 82)
+ Added PB_ prefix to macro names (issue 106)
+ Added #if version guard to generated files (issue 129)
+ Added migration document
+
+nanopb-0.2.9 (2014-08-09)
+ NOTE: If you are using the -e option with the generator, you have
+ to prepend . to the argument to get the same behaviour as before.
+
+ Do not automatically add a dot with generator -e option. (issue 122)
+ Fix problem with .options file and extension fields. (issue 125)
+ Don't use SIZE_MAX macro, as it is not in C89. (issue 120)
+ Generate #defines for initializing message structures. (issue 79)
+ Add skip_message option to generator. (issue 121)
+ Add PB_PACKED_STRUCT support for Keil MDK-ARM toolchain (issue 119)
+ Give better messages about the .options file path. (issue 124)
+ Improved tests
+
+nanopb-0.2.8 (2014-05-20)
+ Fix security issue with PB_ENABLE_MALLOC. (issue 117)
+ Add option to not add timestamps to .pb.h and .pb.c preambles. (issue 115)
+ Documentation updates
+ Improved tests
+
 nanopb-0.2.7 (2014-04-07)
  Fix bug with default values for extension fields (issue 111)
  Fix some MISRA-C warnings (issue 91)
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..2625a66
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,94 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+project(nanopb C)
+
+set(nanopb_VERSION_STRING nanopb-0.3.9.1)
+
+string(REPLACE "nanopb-" "" nanopb_VERSION ${nanopb_VERSION_STRING})
+
+option(nanopb_BUILD_RUNTIME "Build the headers and libraries needed at runtime" ON)
+option(nanopb_BUILD_GENERATOR "Build the protoc plugin for code generation" ON)
+option(nanopb_MSVC_STATIC_RUNTIME "Link static runtime libraries" ON)
+
+if(NOT DEFINED nanopb_PROTOC_PATH)
+    set(nanopb_PROTOC_PATH "protoc")
+endif()
+
+if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
+    set(CMAKE_DEBUG_POSTFIX "d")
+endif()
+
+include(GNUInstallDirs)
+
+if(MSVC AND nanopb_MSVC_STATIC_RUNTIME)
+    foreach(flag_var
+            CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
+            CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
+        if(${flag_var} MATCHES "/MD")
+            string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
+        endif(${flag_var} MATCHES "/MD")
+    endforeach(flag_var)
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_CMAKEDIR)
+    set(CMAKE_INSTALL_CMAKEDIR "lib/cmake/nanopb")
+endif()
+
+if(nanopb_BUILD_GENERATOR)
+    set(generator_protos nanopb plugin)
+
+    find_package(PythonInterp 2.7 REQUIRED)
+    execute_process(
+        COMMAND ${PYTHON_EXECUTABLE} -c
+            "from distutils import sysconfig; print(sysconfig.get_python_lib(prefix=''))"
+        OUTPUT_VARIABLE PYTHON_INSTDIR
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+
+    foreach(generator_proto IN LISTS generator_protos)
+        string(REGEX REPLACE "([^;]+)" "${PROJECT_SOURCE_DIR}/generator/proto/\\1.proto" generator_proto_file "${generator_proto}")
+        string(REGEX REPLACE "([^;]+)" "\\1_pb2.py" generator_proto_py_file "${generator_proto}")
+        add_custom_command(
+            OUTPUT ${generator_proto_py_file}
+            COMMAND ${nanopb_PROTOC_PATH} --python_out=${PROJECT_BINARY_DIR} -I${PROJECT_SOURCE_DIR}/generator/proto ${generator_proto_file}
+            DEPENDS ${generator_proto_file}
+        )
+        add_custom_target("generate_${generator_proto_py_file}" ALL DEPENDS ${generator_proto_py_file})
+        install(
+            FILES ${PROJECT_BINARY_DIR}/${generator_proto_py_file}
+			DESTINATION ${PYTHON_INSTDIR}
+        )
+    endforeach()
+endif()
+
+if(nanopb_BUILD_RUNTIME)
+    add_library(protobuf-nanopb STATIC
+        pb.h
+        pb_common.h
+        pb_common.c
+        pb_encode.h
+        pb_encode.c
+        pb_decode.h
+        pb_decode.c)
+
+    target_include_directories(protobuf-nanopb INTERFACE
+      $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+    )
+
+    configure_file(extra/nanopb-config-version.cmake.in
+        nanopb-config-version.cmake @ONLY)
+
+    install(TARGETS protobuf-nanopb EXPORT nanopb-targets
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+
+    install(EXPORT nanopb-targets
+        DESTINATION ${CMAKE_INSTALL_CMAKEDIR}
+        NAMESPACE nanopb::)
+
+    install(FILES extra/nanopb-config.cmake
+        ${CMAKE_CURRENT_BINARY_DIR}/nanopb-config-version.cmake
+        DESTINATION ${CMAKE_INSTALL_CMAKEDIR})
+
+    install(FILES pb.h pb_common.h pb_encode.h pb_decode.h
+        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+endif()
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..4041bc3
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,32 @@
+Contributing to Nanopb development
+==================================
+
+Reporting issues and requesting features
+----------------------------------------
+
+Feel free to report any issues you see or features you would like
+to see in the future to the Github issue tracker. Using the templates
+below is preferred:
+
+* [Report a bug](https://github.com/nanopb/nanopb/issues/new?body=**Steps%20to%20reproduce%20the%20issue**%0a%0a1.%0a2.%0a3.%0a%0a**What%20happens?**%0A%0A**What%20should%20happen?**&labels=Type-Defect)
+* [Request a feature](https://github.com/nanopb/nanopb/issues/new?body=**What%20should%20the%20feature%20do?**%0A%0A**In%20what%20situation%20would%20the%20feature%20be%20useful?**&labels=Type-Enhancement)
+
+Requesting help
+---------------
+
+If there is something strange going on, but you do not know if
+it is actually a bug in nanopb, try asking first on the
+[discussion forum](https://groups.google.com/forum/#!forum/nanopb).
+
+Pull requests
+-------------
+
+Pull requests are welcome!
+
+If it is not obvious from the commit message, please indicate the
+same information as you would for an issue report:
+
+* What functionality it fixes/adds.
+* How can the problem be reproduced / when would the feature be useful.
+
+
diff --git a/README.android b/README.android
index 2a2d518..5ce0117 100644
--- a/README.android
+++ b/README.android
@@ -1,5 +1,5 @@
-URL: http://koti.kapsi.fi/jpa/nanopb/
-Version: 2.8.0
+URL: https://jpa.kapsi.fi/nanopb/
+Version: 0.3.9.1
 License: zlib
 Description: "nanopb-c: A plugin for Google Protobuf compiler that generates C code"
 
@@ -9,4 +9,4 @@
   LOCAL_SRC_FILES += simple.proto
   LOCAL_PROTOC_OPTIMIZE_TYPE := nanopb-c
 
-Then look at http://koti.kapsi.fi/jpa/nanopb/ Documentation for how to use nanopb-c.
+Then look at https://jpa.kapsi.fi/nanopb/ Documentation for how to use nanopb-c.
diff --git a/README.txt b/README.md
similarity index 69%
rename from README.txt
rename to README.md
index 0f2ade8..07860f0 100644
--- a/README.txt
+++ b/README.md
@@ -1,18 +1,25 @@
+Nanopb - Protocol Buffers for Embedded Systems
+==============================================
+
+[![Build Status](https://travis-ci.org/nanopb/nanopb.svg?branch=master)](https://travis-ci.org/nanopb/nanopb)
+
 Nanopb is a small code-size Protocol Buffers implementation in ansi C. It is
 especially suitable for use in microcontrollers, but fits any memory
 restricted system.
 
-Homepage: http://kapsi.fi/~jpa/nanopb/
-
+* **Homepage:** https://jpa.kapsi.fi/nanopb/
+* **Documentation:** https://jpa.kapsi.fi/nanopb/docs/
+* **Downloads:** https://jpa.kapsi.fi/nanopb/download/
+* **Forum:** https://groups.google.com/forum/#!forum/nanopb
 
 
 
 Using the nanopb library
-========================
+------------------------
 To use the nanopb library, you need to do two things:
 
-1) Compile your .proto files for nanopb, using protoc.
-2) Include pb_encode.c and pb_decode.c in your project.
+1. Compile your .proto files for nanopb, using protoc.
+2. Include pb_encode.c, pb_decode.c and pb_common.c in your project.
 
 The easiest way to get started is to study the project in "examples/simple".
 It contains a Makefile, which should work directly under most Linux systems.
@@ -22,7 +29,7 @@
 
 
 Using the Protocol Buffers compiler (protoc)
-============================================
+--------------------------------------------
 The nanopb generator is implemented as a plugin for the Google's own protoc
 compiler. This has the advantage that there is no need to reimplement the
 basic parsing of .proto files. However, it does mean that you need the
@@ -46,7 +53,7 @@
 
 
 Running the tests
-=================
+-----------------
 If you want to perform further development of the nanopb core, or to verify
 its functionality using your compiler and platform, you'll want to run the
 test suite. The build rules for the test suite are implemented using Scons,
@@ -58,4 +65,7 @@
 This will show the progress of various test cases. If the output does not
 end in an error, the test cases were successful.
 
-
+Note: Mac OS X by default aliases 'clang' as 'gcc', while not actually
+supporting the same command line options as gcc does. To run tests on
+Mac OS X, use: "scons CC=clang CXX=clang". Same way can be used to run
+tests with different compilers on any platform.
diff --git a/README.version b/README.version
index 837b3ef..b0e5805 100644
--- a/README.version
+++ b/README.version
@@ -1,3 +1,3 @@
-URL: http://koti.kapsi.fi/~jpa/nanopb/download/nanopb-0.2.8.tar.gz
-Version: 0.2.8
+URL: https://github.com/nanopb/nanopb/archive/0.3.9.1.tar.gz
+Version: 0.3.9.1
 BugComponent: 31808
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..2837cb3
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1 @@
+workspace(name="com_github_nanopb_nanopb")
diff --git a/docs/Makefile b/docs/Makefile
index e7143b2..0dbd97c 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -1,4 +1,4 @@
-all: index.html concepts.html reference.html security.html \
+all: index.html concepts.html reference.html security.html migration.html \
 	generator_flow.png
 
 %.png: %.svg
diff --git a/docs/concepts.rst b/docs/concepts.rst
index 0df5ad6..1f9aec1 100644
--- a/docs/concepts.rst
+++ b/docs/concepts.rst
@@ -148,7 +148,9 @@
 
 1) Strings, bytes and repeated fields of any type map to callback functions by default.
 2) If there is a special option *(nanopb).max_size* specified in the .proto file, string maps to null-terminated char array and bytes map to a structure containing a char array and a size field.
-3) If there is a special option *(nanopb).max_count* specified on a repeated field, it maps to an array of whatever type is being repeated. Another field will be created for the actual number of entries stored.
+3) If *(nanopb).fixed_length* is set to *true* and *(nanopb).max_size* is also set, then bytes map to an inline byte array of fixed size.
+4) If there is a special option *(nanopb).max_count* specified on a repeated field, it maps to an array of whatever type is being repeated. Another field will be created for the actual number of entries stored.
+5) If *(nanopb).fixed_count* is set to *true* and *(nanopb).max_count* is also set, the field for the actual number of entries will not by created as the count is always assumed to be max count.
 
 =============================================================================== =======================
       field in .proto                                                           autogenerated in .h
@@ -160,16 +162,22 @@
                                                                                 | char name[5][40];
 required bytes data = 1 [(nanopb).max_size = 40];                               | typedef struct {
                                                                                 |    size_t size;
-                                                                                |    uint8_t bytes[40];
+                                                                                |    pb_byte_t bytes[40];
                                                                                 | } Person_data_t;
                                                                                 | Person_data_t data;
+required bytes data = 1 [(nanopb).max_size = 40, (nanopb).fixed_length = true]; | pb_byte_t data[40];
+repeated int32 data = 1 [(nanopb).max_count = 5, (nanopb).fixed_count true];    | int32_t data[5];
 =============================================================================== =======================
 
 The maximum lengths are checked in runtime. If string/bytes/array exceeds the allocated length, *pb_decode* will return false.
 
-Note: for the *bytes* datatype, the field length checking may not be exact.
+Note: For the *bytes* datatype, the field length checking may not be exact.
 The compiler may add some padding to the *pb_bytes_t* structure, and the nanopb runtime doesn't know how much of the structure size is padding. Therefore it uses the whole length of the structure for storing data, which is not very smart but shouldn't cause problems. In practise, this means that if you specify *(nanopb).max_size=5* on a *bytes* field, you may be able to store 6 bytes there. For the *string* field type, the length limit is exact.
 
+Note: When using the *fixed_count* option, the decoder assumes the repeated elements are
+received sequentially or that repeated elements for a non-packed field will not be interleaved with
+another *fixed_count* non-packed field.
+
 Field callbacks
 ===============
 When a field has dynamic length, nanopb cannot statically allocate storage for it. Instead, it allows you to handle the field in whatever way you want, using a callback function.
@@ -255,6 +263,61 @@
     PB_LAST_FIELD
  };
 
+Oneof
+=====
+Protocol Buffers supports `oneof`_ sections. Here is an example of ``oneof`` usage::
+
+ message MsgType1 {
+     required int32 value = 1;
+ }
+
+ message MsgType2 {
+     required bool value = 1;
+ }
+ 
+ message MsgType3 {
+     required int32 value1 = 1;
+     required int32 value2 = 2;
+ } 
+ 
+ message MyMessage {
+     required uint32 uid = 1;
+     required uint32 pid = 2;
+     required uint32 utime = 3;
+ 
+     oneof payload {
+         MsgType1 msg1 = 4;
+         MsgType2 msg2 = 5;
+         MsgType3 msg3 = 6;
+     }
+ }
+
+Nanopb will generate ``payload`` as a C union and add an additional field ``which_payload``::
+
+  typedef struct _MyMessage {
+    uint32_t uid;
+    uint32_t pid;
+    uint32_t utime;
+    pb_size_t which_payload;
+    union {
+        MsgType1 msg1;
+        MsgType2 msg2;
+        MsgType3 msg3;
+    } payload;
+  /* @@protoc_insertion_point(struct:MyMessage) */
+  } MyMessage;
+
+``which_payload`` indicates which of the ``oneof`` fields is actually set. 
+The user is expected to set the filed manually using the correct field tag::
+
+  MyMessage msg = MyMessage_init_zero;
+  msg.payload.msg2.value = true;
+  msg.which_payload = MyMessage_msg2_tag;
+
+Notice that neither ``which_payload`` field nor the unused fileds in ``payload``
+will consume any space in the resulting encoded message.
+
+.. _`oneof`: https://developers.google.com/protocol-buffers/docs/reference/proto2-spec#oneof_and_oneof_field
 
 Extension fields
 ================
@@ -299,6 +362,44 @@
 
 .. _`extension fields`: https://developers.google.com/protocol-buffers/docs/proto#extensions
 
+Default values
+==============
+Protobuf has two syntax variants, proto2 and proto3. Of these proto2 has user
+definable default values that can be given in .proto file::
+
+ message MyMessage {
+     optional bytes foo = 1 [default = "ABC\x01\x02\x03"];
+     optional string bar = 2 [default = "åäö"];
+ }
+
+Nanopb will generate both static and runtime initialization for the default
+values. In `myproto.pb.h` there will be a `#define MyMessage_init_default` that
+can be used to initialize whole message into default values::
+
+ MyMessage msg = MyMessage_init_default;
+
+In addition to this, `pb_decode()` will initialize message fields to defaults
+at runtime. If this is not desired, `pb_decode_noinit()` can be used instead.
+
+Message framing
+===============
+Protocol Buffers does not specify a method of framing the messages for transmission.
+This is something that must be provided by the library user, as there is no one-size-fits-all
+solution. Typical needs for a framing format are to:
+
+1. Encode the message length.
+2. Encode the message type.
+3. Perform any synchronization and error checking that may be needed depending on application.
+
+For example UDP packets already fullfill all the requirements, and TCP streams typically only
+need a way to identify the message length and type. Lower level interfaces such as serial ports
+may need a more robust frame format, such as HDLC (high-level data link control).
+
+Nanopb provides a few helpers to facilitate implementing framing formats:
+
+1. Functions *pb_encode_delimited* and *pb_decode_delimited* prefix the message data with a varint-encoded length.
+2. Union messages and oneofs are supported in order to implement top-level container messages.
+3. Message IDs can be specified using the *(nanopb_msgopt).msgid* option and can then be accessed from the header.
 
 Return values and error handling
 ================================
@@ -312,5 +413,5 @@
 3) IO errors in your own stream callbacks.
 4) Errors that happen in your callback functions.
 5) Exceeding the max_size or bytes_left of a stream.
-6) Exceeding the max_size of a string or array field
+6) Exceeding the max_size/max_count of a string or array field
 7) Invalid protocol buffers binary message.
diff --git a/docs/index.rst b/docs/index.rst
index d49abc0..afc7ee4 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -7,7 +7,7 @@
 Nanopb is an ANSI-C library for encoding and decoding messages in Google's `Protocol Buffers`__ format with minimal requirements for RAM and code space.
 It is primarily suitable for 32-bit microcontrollers.
 
-__ http://code.google.com/apis/protocolbuffers/
+__ https://developers.google.com/protocol-buffers/docs/reference/overview
 
 Overall structure
 =================
@@ -23,6 +23,7 @@
 
 1) Nanopb runtime library:
     - pb.h
+    - pb_common.h and pb_common.c (always needed)
     - pb_decode.h and pb_decode.c (needed for decoding messages)
     - pb_encode.h and pb_encode.c (needed for encoding messages)
 2) Protocol description (you can have many):
@@ -39,9 +40,9 @@
 #) Small code size (2–10 kB depending on processor, plus any message definitions)
 #) Small ram usage (typically ~300 bytes, plus any message structs)
 #) Allows specifying maximum size for strings and arrays, so that they can be allocated statically.
-#) No malloc needed: everything can be allocated statically or on the stack.
+#) No malloc needed: everything can be allocated statically or on the stack. Optional malloc support available.
 #) You can use either encoder or decoder alone to cut the code size in half.
-#) Support for most protobuf features, including: all data types, nested submessages, default values, repeated and optional fields, packed arrays, extension fields.
+#) Support for most protobuf features, including: all data types, nested submessages, default values, repeated and optional fields, oneofs, packed arrays, extension fields.
 #) Callback mechanism for handling messages larger than can fit in available RAM.
 #) Extensive set of tests.
 
@@ -53,8 +54,8 @@
 #) Fields in the generated structs are ordered by the tag number, instead of the natural ordering in .proto file.
 #) Unknown fields are not preserved when decoding and re-encoding a message.
 #) Reflection (runtime introspection) is not supported. E.g. you can't request a field by giving its name in a string.
-#) Numeric arrays are always encoded as packed, even if not marked as packed in .proto. This causes incompatibility with decoders that do not support packed format.
-#) Cyclic references between messages are supported only in callback mode.
+#) Numeric arrays are always encoded as packed, even if not marked as packed in .proto.
+#) Cyclic references between messages are supported only in callback and malloc mode.
 
 Getting started
 ===============
diff --git a/docs/menu.rst b/docs/menu.rst
index a49b22c..2c110de 100644
--- a/docs/menu.rst
+++ b/docs/menu.rst
@@ -4,8 +4,10 @@
     2) `Concepts`_
     3) `API reference`_
     4) `Security model`_
+    5) `Migration from older versions`_
     
 .. _`Overview`: index.html
 .. _`Concepts`: concepts.html
 .. _`API reference`: reference.html
 .. _`Security model`: security.html
+.. _`Migration from older versions`: migration.html
diff --git a/docs/migration.rst b/docs/migration.rst
new file mode 100644
index 0000000..fdc1d8c
--- /dev/null
+++ b/docs/migration.rst
@@ -0,0 +1,320 @@
+=====================================
+Nanopb: Migration from older versions
+=====================================
+
+.. include :: menu.rst
+
+This document details all the breaking changes that have been made to nanopb
+since its initial release. For each change, the rationale and required
+modifications of user applications are explained. Also any error indications
+are included, in order to make it easier to find this document.
+
+.. contents ::
+
+Nanopb-0.3.9.1, 0.4.0 (2018-xx-xx)
+==================================
+
+Fix handling of string and bytes default values
+-----------------------------------------------
+
+**Rationale:** Previously nanopb didn't properly decode special character
+escapes like \\200 emitted by protoc. This caused these escapes to end up
+verbatim in the default values in .pb.c file.
+
+**Changes:** Escapes are now decoded, and e.g. "\\200" or "\\x80" results in
+{0x80} for bytes field and "\\x80" for string field.
+
+**Required actions:** If code has previously relied on '\\' in default value
+being passed through verbatim, it must now be changed to '\\\\'.
+
+Nanopb-0.3.8 (2017-03-05)
+=========================
+
+Fully drain substreams before closing
+-------------------------------------
+
+**Rationale:** If the substream functions were called directly and the caller
+did not completely empty the substring before closing it, the parent stream
+would be put into an incorrect state.
+
+**Changes:** *pb_close_string_substream* can now error and returns a boolean.
+
+**Required actions:** Add error checking onto any call to
+*pb_close_string_substream*.
+
+Change oneof format in .pb.c files
+----------------------------------
+
+**Rationale:** Previously two oneofs in a single message would be erroneously
+handled as part of the same union.
+
+**Changes:** Oneofs fields now use special *PB_DATAOFFSET_UNION* offset type
+in generated .pb.c files to distinguish whether they are the first or following
+field inside an union.
+
+**Required actions:** Regenerate *.pb.c/.pb.h* files with new nanopb version if
+oneofs are used.
+
+Nanopb-0.3.5 (2016-02-13)
+=========================
+
+Add support for platforms without uint8_t
+-----------------------------------------
+**Rationale:** Some platforms cannot access 8-bit sized values directly, and
+do not define *uint8_t*. Nanopb previously didn't support these platforms.
+
+**Changes:** References to *uint8_t* were replaced with several alternatives,
+one of them being a new *pb_byte_t* typedef. This in turn uses *uint_least8_t*
+which means the smallest available type.
+
+**Required actions:** If your platform does not have a standards-compliant
+*stdint.h*, it may lack the definition for *[u]int_least8_t*. This must be
+added manually, example can be found in *extra/pb_syshdr.h*.
+
+**Error indications:** Compiler error: "unknown type name 'uint_least8_t'".
+
+Nanopb-0.3.2 (2015-01-24)
+=========================
+
+Add support for OneOfs
+----------------------
+**Rationale:** Previously nanopb did not support the *oneof* construct in
+*.proto* files. Those fields were generated as regular *optional* fields.
+
+**Changes:** OneOfs are now generated as C unions. Callback fields are not
+supported inside oneof and generator gives an error.
+
+**Required actions:** The generator option *no_unions* can be used to restore old
+behaviour and to allow callbacks to be used. To use unions, one change is
+needed: use *which_xxxx* field to detect which field is present, instead
+of *has_xxxx*. Compare the value against *MyStruct_myfield_tag*.
+
+**Error indications:** Generator error: "Callback fields inside of oneof are
+not supported". Compiler error: "Message" has no member named "has_xxxx".
+
+Nanopb-0.3.0 (2014-08-26)
+=========================
+
+Separate field iterator logic to pb_common.c
+--------------------------------------------
+**Rationale:** Originally, the field iteration logic was simple enough to be
+duplicated in *pb_decode.c* and *pb_encode.c*. New field types have made the
+logic more complex, which required the creation of a new file to contain the
+common functionality.
+
+**Changes:** There is a new file, *pb_common.c*, which must be included in
+builds.
+
+**Required actions:** Add *pb_common.c* to build rules. This file is always
+required. Either *pb_decode.c* or *pb_encode.c* can still be left out if some
+functionality is not needed.
+
+**Error indications:** Linker error: undefined reference to
+*pb_field_iter_begin*, *pb_field_iter_next* or similar.
+
+Change data type of field counts to pb_size_t
+---------------------------------------------
+**Rationale:** Often nanopb is used with small arrays, such as 255 items or
+less. Using a full *size_t* field to store the array count wastes memory if
+there are many arrays. There already exists parameters *PB_FIELD_16BIT* and
+*PB_FIELD_32BIT* which tell nanopb what is the maximum size of arrays in use.
+
+**Changes:** Generator will now use *pb_size_t* for the array *_count* fields.
+The size of the type will be controlled by the *PB_FIELD_16BIT* and
+*PB_FIELD_32BIT* compilation time options.
+
+**Required actions:** Regenerate all *.pb.h* files. In some cases casts to the
+*pb_size_t* type may need to be added in the user code when accessing the
+*_count* fields.
+
+**Error indications:** Incorrect data at runtime, crashes. But note that other
+changes in the same version already require regenerating the files and have
+better indications of errors, so this is only an issue for development
+versions.
+
+Renamed some macros and identifiers
+-----------------------------------
+**Rationale:** Some names in nanopb core were badly chosen and conflicted with
+ISO C99 reserved names or lacked a prefix. While they haven't caused trouble
+so far, it is reasonable to switch to non-conflicting names as these are rarely
+used from user code.
+
+**Changes:** The following identifier names have changed:
+
+  * Macros:
+  
+    * STATIC_ASSERT(x) -> PB_STATIC_ASSERT(x)
+    * UNUSED(x) -> PB_UNUSED(x)
+  
+  * Include guards:
+  
+    * _PB_filename_ -> PB_filename_INCLUDED
+  
+  * Structure forward declaration tags:
+  
+    * _pb_field_t -> pb_field_s
+    * _pb_bytes_array_t -> pb_bytes_array_s
+    * _pb_callback_t -> pb_callback_s
+    * _pb_extension_type_t -> pb_extension_type_s
+    * _pb_extension_t -> pb_extension_s
+    * _pb_istream_t -> pb_istream_s
+    * _pb_ostream_t -> pb_ostream_s
+
+**Required actions:** Regenerate all *.pb.c* files. If you use any of the above
+identifiers in your application code, perform search-replace to the new name.
+
+**Error indications:** Compiler errors on lines with the macro/type names.
+
+Nanopb-0.2.9 (2014-08-09)
+=========================
+
+Change semantics of generator -e option
+---------------------------------------
+**Rationale:** Some compilers do not accept filenames with two dots (like
+in default extension .pb.c). The *-e* option to the generator allowed changing
+the extension, but not skipping the extra dot.
+
+**Changes:** The *-e* option in generator will no longer add the prepending
+dot. The default value has been adjusted accordingly to *.pb.c* to keep the
+default behaviour the same as before.
+
+**Required actions:** Only if using the generator -e option. Add dot before
+the parameter value on the command line.
+
+**Error indications:** File not found when trying to compile generated files.
+
+Nanopb-0.2.7 (2014-04-07)
+=========================
+
+Changed pointer-type bytes field datatype
+-----------------------------------------
+**Rationale:** In the initial pointer encoding support since nanopb-0.2.5,
+the bytes type used a separate *pb_bytes_ptr_t* type to represent *bytes*
+fields. This made it easy to encode data from a separate, user-allocated
+buffer. However, it made the internal logic more complex and was inconsistent
+with the other types.
+
+**Changes:** Dynamically allocated bytes fields now have the *pb_bytes_array_t*
+type, just like statically allocated ones.
+
+**Required actions:** Only if using pointer-type fields with the bytes datatype.
+Change any access to *msg->field.size* to *msg->field->size*. Change any
+allocation to reserve space of amount *PB_BYTES_ARRAY_T_ALLOCSIZE(n)*. If the
+data pointer was begin assigned from external source, implement the field using
+a callback function instead.
+
+**Error indications:** Compiler error: unknown type name *pb_bytes_ptr_t*.
+
+Nanopb-0.2.4 (2013-11-07)
+=========================
+
+Remove the NANOPB_INTERNALS compilation option
+----------------------------------------------
+**Rationale:** Having the option in the headers required the functions to
+be non-static, even if the option is not used. This caused errors on some
+static analysis tools.
+
+**Changes:** The *#ifdef* and associated functions were removed from the
+header.
+
+**Required actions:** Only if the *NANOPB_INTERNALS* option was previously
+used. Actions are as listed under nanopb-0.1.3 and nanopb-0.1.6.
+
+**Error indications:** Compiler warning: implicit declaration of function
+*pb_dec_string*, *pb_enc_string*, or similar.
+
+Nanopb-0.2.1 (2013-04-14)
+=========================
+
+Callback function signature
+---------------------------
+**Rationale:** Previously the auxilary data to field callbacks was passed
+as *void\**. This allowed passing of any data, but made it unnecessarily
+complex to return a pointer from callback.
+
+**Changes:** The callback function parameter was changed to *void\*\**.
+
+**Required actions:** You can continue using the old callback style by
+defining *PB_OLD_CALLBACK_STYLE*. Recommended action is to:
+
+  * Change the callback signatures to contain *void\*\** for decoders and
+    *void \* const \** for encoders.
+  * Change the callback function body to use *\*arg* instead of *arg*.
+
+**Error indications:** Compiler warning: assignment from incompatible
+pointer type, when initializing *funcs.encode* or *funcs.decode*.
+
+Nanopb-0.2.0 (2013-03-02)
+=========================
+
+Reformatted generated .pb.c file using macros
+---------------------------------------------
+**Rationale:** Previously the generator made a list of C *pb_field_t*
+initializers in the .pb.c file. This led to a need to regenerate all .pb.c
+files after even small changes to the *pb_field_t* definition.
+
+**Changes:** Macros were added to pb.h which allow for cleaner definition
+of the .pb.c contents. By changing the macro definitions, changes to the
+field structure are possible without breaking compatibility with old .pb.c
+files.
+
+**Required actions:** Regenerate all .pb.c files from the .proto sources.
+
+**Error indications:** Compiler warning: implicit declaration of function
+*pb_delta_end*.
+
+Changed pb_type_t definitions
+-----------------------------
+**Rationale:** The *pb_type_t* was previously an enumeration type. This
+caused warnings on some compilers when using bitwise operations to set flags
+inside the values.
+
+**Changes:** The *pb_type_t* was changed to *typedef uint8_t*. The values
+were changed to *#define*. Some value names were changed for consistency.
+
+**Required actions:** Only if you directly access the `pb_field_t` contents
+in your own code, something which is not usually done. Needed changes:
+
+  * Change *PB_HTYPE_ARRAY* to *PB_HTYPE_REPEATED*.
+  * Change *PB_HTYPE_CALLBACK* to *PB_ATYPE()* and *PB_ATYPE_CALLBACK*.
+
+**Error indications:** Compiler error: *PB_HTYPE_ARRAY* or *PB_HTYPE_CALLBACK*
+undeclared.
+
+Nanopb-0.1.6 (2012-09-02)
+=========================
+
+Refactored field decoder interface
+----------------------------------
+**Rationale:** Similarly to field encoders in nanopb-0.1.3.
+
+**Changes:** New functions with names *pb_decode_\** were added.
+
+**Required actions:** By defining NANOPB_INTERNALS, you can still keep using
+the old functions. Recommended action is to replace any calls with the newer
+*pb_decode_\** equivalents.
+
+**Error indications:** Compiler warning: implicit declaration of function
+*pb_dec_string*, *pb_dec_varint*, *pb_dec_submessage* or similar.
+
+Nanopb-0.1.3 (2012-06-12)
+=========================
+
+Refactored field encoder interface
+----------------------------------
+**Rationale:** The old *pb_enc_\** functions were designed mostly for the
+internal use by the core. Because they are internally accessed through
+function pointers, their signatures had to be common. This led to a confusing
+interface for external users.
+
+**Changes:** New functions with names *pb_encode_\** were added. These have
+easier to use interfaces. The old functions are now only thin wrappers for
+the new interface.
+
+**Required actions:** By defining NANOPB_INTERNALS, you can still keep using
+the old functions. Recommended action is to replace any calls with the newer
+*pb_encode_\** equivalents.
+
+**Error indications:** Compiler warning: implicit declaration of function
+*pb_enc_string*, *pb_enc_varint, *pb_enc_submessage* or similar.
+
diff --git a/docs/reference.rst b/docs/reference.rst
index ccbf0a4..40a69ad 100644
--- a/docs/reference.rst
+++ b/docs/reference.rst
@@ -20,10 +20,9 @@
 includes pb.h.
 
 ============================  ================================================
-__BIG_ENDIAN__                 Set this if your platform stores integers and
-                               floats in big-endian format. Mixed-endian
-                               systems (different layout for ints and floats)
-                               are currently not supported.
+PB_NO_PACKED_STRUCTS           Disable packed structs. Increases RAM usage but
+                               is necessary on some platforms that do not
+                               support unaligned memory access.
 PB_ENABLE_MALLOC               Set this to enable dynamic allocation support
                                in the decoder.
 PB_MAX_REQUIRED_FIELDS         Maximum number of required fields to check for
@@ -54,6 +53,8 @@
                                functions and typedefs listed on the
                                `overview page`_. Value must include quotes,
                                for example *#define PB_SYSTEM_HEADER "foo.h"*.
+PB_WITHOUT_64BIT               Disable 64-bit support, for old compilers or
+                               for a slight speedup on 8-bit platforms.
 ============================  ================================================
 
 The PB_MAX_REQUIRED_FIELDS, PB_FIELD_16BIT and PB_FIELD_32BIT settings allow
@@ -73,18 +74,31 @@
 max_size                       Allocated size for *bytes* and *string* fields.
 max_count                      Allocated number of entries in arrays
                                (*repeated* fields).
+int_size                       Override the integer type of a field.
+                               (To use e.g. uint8_t to save RAM.)
 type                           Type of the generated field. Default value
                                is *FT_DEFAULT*, which selects automatically.
                                You can use *FT_CALLBACK*, *FT_POINTER*,
-                               *FT_STATIC* or *FT_IGNORE* to force a callback
-                               field, a dynamically allocated field, a static
-                               field or to completely ignore the field.
+                               *FT_STATIC* or *FT_IGNORE* to
+                               force a callback field, a dynamically
+                               allocated field, a static field or to
+                               completely ignore the field.
 long_names                     Prefix the enum name to the enum value in
                                definitions, i.e. *EnumName_EnumValue*. Enabled
                                by default.
 packed_struct                  Make the generated structures packed.
                                NOTE: This cannot be used on CPUs that break
                                on unaligned accesses to variables.
+skip_message                   Skip the whole message from generation.
+no_unions                      Generate 'oneof' fields as optional fields
+                               instead of C unions.
+msgid                          Specifies a unique id for this message type.
+                               Can be used by user code as an identifier.
+anonymous_oneof                Generate 'oneof' fields as anonymous unions.
+fixed_length                   Generate 'bytes' fields with constant length
+                               (max_size must also be defined).
+fixed_count                    Generate arrays with constant length
+                               (max_count must also be defined).
 ============================  ================================================
 
 These options can be defined for the .proto files before they are converted
@@ -143,8 +157,20 @@
   it makes sense to define wildcard options first in the file and more specific
   ones later.
   
-If preferred, the name of the options file can be set using the command line
-switch *-f* to nanopb_generator.py.
+To debug problems in applying the options, you can use the *-v* option for the
+plugin. Plugin options are specified in front of the output path:
+
+    protoc ... --nanopb_out=-v:. message.proto
+
+Protoc doesn't currently pass include path into plugins. Therefore if your
+*.proto* is in a subdirectory, nanopb may have trouble finding the associated
+*.options* file. A workaround is to specify include path separately to the
+nanopb plugin, like:
+
+    protoc -Isubdir --nanopb_out=-Isubdir:. message.proto
+  
+If preferred, the name of the options file can be set using plugin argument
+*-f*.
 
 Defining the options on command line
 ------------------------------------
@@ -170,7 +196,7 @@
 */usr/include*. Therefore, to compile a .proto file which uses options, use a
 protoc command similar to::
 
-    protoc -I/usr/include -Inanopb/generator -I. -omessage.pb message.proto
+    protoc -I/usr/include -Inanopb/generator -I. --nanopb_out=. message.proto
 
 The options can be defined in file, message and field scopes::
 
@@ -182,35 +208,40 @@
     }
 
 
-
-
-
-
-
-
-
 pb.h
 ====
 
+pb_byte_t
+---------
+Type used for storing byte-sized data, such as raw binary input and bytes-type fields. ::
+
+    typedef uint_least8_t pb_byte_t;
+
+For most platforms this is equivalent to `uint8_t`. Some platforms however do not support
+8-bit variables, and on those platforms 16 or 32 bits need to be used for each byte.
+
 pb_type_t
 ---------
-Defines the encoder/decoder behaviour that should be used for a field. ::
+Type used to store the type of each field, to control the encoder/decoder behaviour. ::
 
-    typedef uint8_t pb_type_t;
+    typedef uint_least8_t pb_type_t;
 
 The low-order nibble of the enumeration values defines the function that can be used for encoding and decoding the field data:
 
-==================== ===== ================================================
-LTYPE identifier     Value Storage format
-==================== ===== ================================================
-PB_LTYPE_VARINT      0x00  Integer.
-PB_LTYPE_SVARINT     0x01  Integer, zigzag encoded.
-PB_LTYPE_FIXED32     0x02  32-bit integer or floating point.
-PB_LTYPE_FIXED64     0x03  64-bit integer or floating point.
-PB_LTYPE_BYTES       0x04  Structure with *size_t* field and byte array.
-PB_LTYPE_STRING      0x05  Null-terminated string.
-PB_LTYPE_SUBMESSAGE  0x06  Submessage structure.
-==================== ===== ================================================
+=========================== ===== ================================================
+LTYPE identifier            Value Storage format
+=========================== ===== ================================================
+PB_LTYPE_VARINT             0x00  Integer.
+PB_LTYPE_UVARINT            0x01  Unsigned integer.
+PB_LTYPE_SVARINT            0x02  Integer, zigzag encoded.
+PB_LTYPE_FIXED32            0x03  32-bit integer or floating point.
+PB_LTYPE_FIXED64            0x04  64-bit integer or floating point.
+PB_LTYPE_BYTES              0x05  Structure with *size_t* field and byte array.
+PB_LTYPE_STRING             0x06  Null-terminated string.
+PB_LTYPE_SUBMESSAGE         0x07  Submessage structure.
+PB_LTYPE_EXTENSION          0x08  Point to *pb_extension_t*.
+PB_LTYPE_FIXED_LENGTH_BYTES 0x09  Inline *pb_byte_t* array of fixed size.
+=========================== ===== ================================================
 
 The bits 4-5 define whether the field is required, optional or repeated:
 
@@ -242,14 +273,14 @@
 ----------
 Describes a single structure field with memory position in relation to others. The descriptions are usually autogenerated. ::
 
-    typedef struct _pb_field_t pb_field_t;
-    struct _pb_field_t {
-        uint8_t tag;
+    typedef struct pb_field_s pb_field_t;
+    struct pb_field_s {
+        pb_size_t tag;
         pb_type_t type;
-        uint8_t data_offset;
-        int8_t size_offset;
-        uint8_t data_size;
-        uint8_t array_size;
+        pb_size_t data_offset;
+        pb_ssize_t size_offset;
+        pb_size_t data_size;
+        pb_size_t array_size;
         const void *ptr;
     } pb_packed;
 
@@ -268,8 +299,8 @@
 An byte array with a field for storing the length::
 
     typedef struct {
-        size_t size;
-        uint8_t bytes[1];
+        pb_size_t size;
+        pb_byte_t bytes[1];
     } pb_bytes_array_t;
 
 In an actual array, the length of *bytes* may be different.
@@ -333,12 +364,14 @@
         const pb_extension_type_t *type;
         void *dest;
         pb_extension_t *next;
+        bool found;
     } pb_extension_t;
 
 :type:      Pointer to the structure that defines the callback functions.
 :dest:      Pointer to the variable that stores the field value
             (as used by the default extension callback functions.)
 :next:      Pointer to the next extension handler, or *NULL*.
+:found:     Decoder sets this to true if the extension was found.
 
 PB_GET_ERROR
 ------------
@@ -382,7 +415,7 @@
 ----------------------
 Constructs an output stream for writing into a memory buffer. This is just a helper function, it doesn't do anything you couldn't do yourself in a callback function. It uses an internal callback that stores the pointer in stream *state* field. ::
 
-    pb_ostream_t pb_ostream_from_buffer(uint8_t *buf, size_t bufsize);
+    pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize);
 
 :buf:           Memory buffer to write into.
 :bufsize:       Maximum number of bytes to write.
@@ -394,7 +427,7 @@
 --------
 Writes data to an output stream. Always use this function, instead of trying to call stream callback manually. ::
 
-    bool pb_write(pb_ostream_t *stream, const uint8_t *buf, size_t count);
+    bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count);
 
 :stream:        Output stream to write to.
 :buf:           Pointer to buffer with the data to be written.
@@ -435,11 +468,22 @@
 
     Writing packed arrays is a little bit more involved: you need to use `pb_encode_tag` and specify `PB_WT_STRING` as the wire type. Then you need to know exactly how much data you are going to write, and use `pb_encode_varint`_ to write out the number of bytes before writing the actual data. Substreams can be used to determine the number of bytes beforehand; see `pb_encode_submessage`_ source code for an example.
 
+pb_get_encoded_size
+-------------------
+Calculates the length of the encoded message. ::
+
+    bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct);
+
+:size:          Calculated size of the encoded message.
+:fields:        A field description array, usually autogenerated.
+:src_struct:    Pointer to the data that will be serialized.
+:returns:       True on success, false on detectable errors in field description or if a field encoder returns false.
+
 pb_encode_tag
 -------------
 Starts a field in the Protocol Buffers binary format: encodes the field number and the wire type of the data. ::
 
-    bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, int field_number);
+    bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number);
 
 :stream:        Output stream to write to. 1-5 bytes will be written.
 :wiretype:      PB_WT_VARINT, PB_WT_64BIT, PB_WT_STRING or PB_WT_32BIT
@@ -460,14 +504,14 @@
 
 Wire type mapping is as follows:
 
-========================= ============
-LTYPEs                    Wire type
-========================= ============
-VARINT, SVARINT           PB_WT_VARINT
-FIXED64                   PB_WT_64BIT  
-STRING, BYTES, SUBMESSAGE PB_WT_STRING 
-FIXED32                   PB_WT_32BIT
-========================= ============
+============================================= ============
+LTYPEs                                        Wire type
+============================================= ============
+VARINT, UVARINT, SVARINT                      PB_WT_VARINT
+FIXED64                                       PB_WT_64BIT
+STRING, BYTES, SUBMESSAGE, FIXED_LENGTH_BYTES PB_WT_STRING
+FIXED32                                       PB_WT_32BIT
+============================================= ============
 
 pb_encode_varint
 ----------------
@@ -493,7 +537,7 @@
 ----------------
 Writes the length of a string as varint and then contents of the string. Works for fields of type `bytes` and `string`::
 
-    bool pb_encode_string(pb_ostream_t *stream, const uint8_t *buffer, size_t size);
+    bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size);
 
 :stream:        Output stream to write to.
 :buffer:        Pointer to string data.
@@ -553,7 +597,7 @@
 ----------------------
 Helper function for creating an input stream that reads data from a memory buffer. ::
 
-    pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize);
+    pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize);
 
 :buf:           Pointer to byte array to read from.
 :bufsize:       Size of the byte array.
@@ -563,7 +607,7 @@
 -------
 Read data from input stream. Always use this function, don't try to call the stream callback directly. ::
 
-    bool pb_read(pb_istream_t *stream, uint8_t *buf, size_t count);
+    bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count);
 
 :stream:        Input stream to read from.
 :buf:           Buffer to store the data to, or NULL to just read data without storing it anywhere.
@@ -622,39 +666,21 @@
 
 pb_release
 ----------
-Releases any dynamically allocated fields.
+Releases any dynamically allocated fields::
 
     void pb_release(const pb_field_t fields[], void *dest_struct);
 
 :fields:        A field description array. Usually autogenerated.
-:dest_struct:   Pointer to structure where data will be stored.
+:dest_struct:   Pointer to structure where data is stored. If NULL, function does nothing.
 
 This function is only available if *PB_ENABLE_MALLOC* is defined. It will release any
 pointer type fields in the structure and set the pointers to NULL.
 
-pb_skip_varint
---------------
-Skip a varint_ encoded integer without decoding it. ::
-
-    bool pb_skip_varint(pb_istream_t *stream);
-
-:stream:        Input stream to read from. Will read 1 byte at a time until the MSB is clear.
-:returns:       True on success, false on IO error.
-
-pb_skip_string
---------------
-Skip a varint-length-prefixed string. This means skipping a value with wire type PB_WT_STRING. ::
-
-    bool pb_skip_string(pb_istream_t *stream);
-
-:stream:        Input stream to read from.
-:returns:       True on success, false on IO error or length exceeding uint32_t.
-
 pb_decode_tag
 -------------
 Decode the tag that comes before field in the protobuf encoding::
 
-    bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, int *tag, bool *eof);
+    bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof);
 
 :stream:        Input stream to read from.
 :wire_type:     Pointer to variable where to store the wire type of the field.
@@ -721,10 +747,9 @@
 -----------------
 Decode a *fixed64*, *sfixed64* or *double* value. ::
 
-    bool pb_dec_fixed(pb_istream_t *stream, const pb_field_t *field, void *dest);
+    bool pb_decode_fixed64(pb_istream_t *stream, void *dest);
 
 :stream:        Input stream to read from. 8 bytes will be read.
-:field:         Not used.
 :dest:          Pointer to destination *int64_t*, *uint64_t* or *double*.
 :returns:       True on success, false on IO errors.
 
diff --git a/docs/security.rst b/docs/security.rst
index e865f83..d854612 100644
--- a/docs/security.rst
+++ b/docs/security.rst
@@ -26,9 +26,9 @@
 the application writer. Malicious data in these structures could cause
 security issues, such as execution of arbitrary code:
 
-1. Callback and extension fields in message structures given to pb_encode()
-   and pb_decode(). These fields are memory pointers, and are generated
-   depending on the .proto file.
+1. Callback, pointer and extension fields in message structures given to
+   pb_encode() and pb_decode(). These fields are memory pointers, and are
+   generated depending on the message definition in the .proto file.
 2. The automatically generated field definitions, i.e. *pb_field_t* lists.
 3. Contents of the *pb_istream_t* and *pb_ostream_t* structures (this does not
    mean the contents of the stream itself, just the stream definition).
@@ -38,8 +38,11 @@
 buffer overflows, information disclosure or other security problems:
 
 1. All data read from *pb_istream_t*.
-2. All fields in message structures, except callbacks and extensions.
-   (Beginning with nanopb-0.2.4, in earlier versions the field sizes are partially unchecked.)
+2. All fields in message structures, except:
+   
+   - callbacks (*pb_callback_t* structures)
+   - pointer fields (malloc support) and *_count* fields for pointers
+   - extensions (*pb_extension_t* structures)
 
 Invariants
 ==========
@@ -76,4 +79,6 @@
    stop a denial of service attack from using an infinite message.
 4. If using network sockets as streams, a timeout should be set to stop
    denial of service attacks.
-
+5. If using *malloc()* support, some method of limiting memory use should be
+   employed. This can be done by defining custom *pb_realloc()* function.
+   Nanopb will properly detect and handle failed memory allocations.
diff --git a/examples/cmake_relpath/CMakeLists.txt b/examples/cmake_relpath/CMakeLists.txt
new file mode 100644
index 0000000..e7727d8
--- /dev/null
+++ b/examples/cmake_relpath/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 2.8)
+project(NANOPB_CMAKE_SIMPLE C)
+
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../extra)
+find_package(Nanopb REQUIRED)
+include_directories(${NANOPB_INCLUDE_DIRS})
+
+nanopb_generate_cpp(PROTO_SRCS PROTO_HDRS RELPATH proto
+	proto/simple.proto proto/sub/unlucky.proto)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+#add_custom_target(generate_proto_sources DEPENDS ${PROTO_SRCS} ${PROTO_HDRS})
+set_source_files_properties(${PROTO_SRCS} ${PROTO_HDRS}
+    PROPERTIES GENERATED TRUE)
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -g -O0")
+
+add_executable(simple simple.c ${PROTO_SRCS} ${PROTO_HDRS})
diff --git a/examples/cmake_relpath/README.txt b/examples/cmake_relpath/README.txt
new file mode 100644
index 0000000..aa0f3f3
--- /dev/null
+++ b/examples/cmake_relpath/README.txt
@@ -0,0 +1,18 @@
+Nanopb example "simple" using CMake
+=======================
+
+This example is the same as the simple nanopb example but built using CMake.
+
+Example usage
+-------------
+
+On Linux, create a build directory and then call cmake:
+
+    nanopb/examples/cmake_simple$ mkdir build
+    nanopb/examples/cmake_simple$ cd build/
+    nanopb/examples/cmake_simple/build$ cmake ..
+    nanopb/examples/cmake_simple/build$ make
+
+After that, you can run it with the command: ./simple
+
+On other platforms supported by CMake, refer to CMake instructions.
diff --git a/examples/cmake_relpath/proto/simple.proto b/examples/cmake_relpath/proto/simple.proto
new file mode 100644
index 0000000..3bf4ad1
--- /dev/null
+++ b/examples/cmake_relpath/proto/simple.proto
@@ -0,0 +1,11 @@
+// A very simple protocol definition, consisting of only
+// one message.
+syntax = "proto2";
+
+import "sub/unlucky.proto";
+
+message SimpleMessage {
+    required int32 lucky_number = 1;
+    required UnluckyNumber unlucky = 2;
+}
+
diff --git a/examples/cmake_relpath/proto/sub/unlucky.proto b/examples/cmake_relpath/proto/sub/unlucky.proto
new file mode 100644
index 0000000..97a42c9
--- /dev/null
+++ b/examples/cmake_relpath/proto/sub/unlucky.proto
@@ -0,0 +1,5 @@
+syntax = "proto2";
+
+message UnluckyNumber {
+	required uint32 number = 1;
+}
diff --git a/examples/cmake_relpath/simple.c b/examples/cmake_relpath/simple.c
new file mode 100644
index 0000000..231886c
--- /dev/null
+++ b/examples/cmake_relpath/simple.c
@@ -0,0 +1,73 @@
+#include <stdio.h>
+#include <pb_encode.h>
+#include <pb_decode.h>
+#include "simple.pb.h"
+
+int main()
+{
+    /* This is the buffer where we will store our message. */
+    uint8_t buffer[128];
+    size_t message_length;
+    bool status;
+    
+    /* Encode our message */
+    {
+        /* Allocate space on the stack to store the message data.
+         *
+         * Nanopb generates simple struct definitions for all the messages.
+         * - check out the contents of simple.pb.h!
+         * It is a good idea to always initialize your structures
+         * so that you do not have garbage data from RAM in there.
+         */
+        SimpleMessage message = SimpleMessage_init_zero;
+        
+        /* Create a stream that will write to our buffer. */
+        pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+        
+        /* Fill in the lucky number */
+        message.lucky_number = 13;
+        message.unlucky.number = 42;
+        
+        /* Now we are ready to encode the message! */
+        status = pb_encode(&stream, SimpleMessage_fields, &message);
+        message_length = stream.bytes_written;
+        
+        /* Then just check for any errors.. */
+        if (!status)
+        {
+            printf("Encoding failed: %s\n", PB_GET_ERROR(&stream));
+            return 1;
+        }
+    }
+    
+    /* Now we could transmit the message over network, store it in a file or
+     * wrap it to a pigeon's leg.
+     */
+
+    /* But because we are lazy, we will just decode it immediately. */
+    
+    {
+        /* Allocate space for the decoded message. */
+        SimpleMessage message = SimpleMessage_init_zero;
+        
+        /* Create a stream that reads from the buffer. */
+        pb_istream_t stream = pb_istream_from_buffer(buffer, message_length);
+        
+        /* Now we are ready to decode the message. */
+        status = pb_decode(&stream, SimpleMessage_fields, &message);
+        
+        /* Check for errors... */
+        if (!status)
+        {
+            printf("Decoding failed: %s\n", PB_GET_ERROR(&stream));
+            return 1;
+        }
+        
+        /* Print the data contained in the message. */
+        printf("Your lucky number was %d!\n", message.lucky_number);
+        printf("Your unlucky number was %u!\n", message.unlucky.number);
+    }
+    
+    return 0;
+}
+
diff --git a/examples/cmake_simple/CMakeLists.txt b/examples/cmake_simple/CMakeLists.txt
new file mode 100644
index 0000000..e5f33a0
--- /dev/null
+++ b/examples/cmake_simple/CMakeLists.txt
@@ -0,0 +1,16 @@
+cmake_minimum_required(VERSION 2.8)
+project(NANOPB_CMAKE_SIMPLE C)
+
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../extra)
+find_package(Nanopb REQUIRED)
+include_directories(${NANOPB_INCLUDE_DIRS})
+
+nanopb_generate_cpp(PROTO_SRCS PROTO_HDRS simple.proto)
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+#add_custom_target(generate_proto_sources DEPENDS ${PROTO_SRCS} ${PROTO_HDRS})
+set_source_files_properties(${PROTO_SRCS} ${PROTO_HDRS}
+    PROPERTIES GENERATED TRUE)
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -g -O0")
+
+add_executable(simple simple.c ${PROTO_SRCS} ${PROTO_HDRS})
diff --git a/examples/cmake_simple/README.txt b/examples/cmake_simple/README.txt
new file mode 100644
index 0000000..aa0f3f3
--- /dev/null
+++ b/examples/cmake_simple/README.txt
@@ -0,0 +1,18 @@
+Nanopb example "simple" using CMake
+=======================
+
+This example is the same as the simple nanopb example but built using CMake.
+
+Example usage
+-------------
+
+On Linux, create a build directory and then call cmake:
+
+    nanopb/examples/cmake_simple$ mkdir build
+    nanopb/examples/cmake_simple$ cd build/
+    nanopb/examples/cmake_simple/build$ cmake ..
+    nanopb/examples/cmake_simple/build$ make
+
+After that, you can run it with the command: ./simple
+
+On other platforms supported by CMake, refer to CMake instructions.
diff --git a/examples/cmake_simple/simple.c b/examples/cmake_simple/simple.c
new file mode 100644
index 0000000..1f6b137
--- /dev/null
+++ b/examples/cmake_simple/simple.c
@@ -0,0 +1,71 @@
+#include <stdio.h>
+#include <pb_encode.h>
+#include <pb_decode.h>
+#include "simple.pb.h"
+
+int main()
+{
+    /* This is the buffer where we will store our message. */
+    uint8_t buffer[128];
+    size_t message_length;
+    bool status;
+    
+    /* Encode our message */
+    {
+        /* Allocate space on the stack to store the message data.
+         *
+         * Nanopb generates simple struct definitions for all the messages.
+         * - check out the contents of simple.pb.h!
+         * It is a good idea to always initialize your structures
+         * so that you do not have garbage data from RAM in there.
+         */
+        SimpleMessage message = SimpleMessage_init_zero;
+        
+        /* Create a stream that will write to our buffer. */
+        pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+        
+        /* Fill in the lucky number */
+        message.lucky_number = 13;
+        
+        /* Now we are ready to encode the message! */
+        status = pb_encode(&stream, SimpleMessage_fields, &message);
+        message_length = stream.bytes_written;
+        
+        /* Then just check for any errors.. */
+        if (!status)
+        {
+            printf("Encoding failed: %s\n", PB_GET_ERROR(&stream));
+            return 1;
+        }
+    }
+    
+    /* Now we could transmit the message over network, store it in a file or
+     * wrap it to a pigeon's leg.
+     */
+
+    /* But because we are lazy, we will just decode it immediately. */
+    
+    {
+        /* Allocate space for the decoded message. */
+        SimpleMessage message = SimpleMessage_init_zero;
+        
+        /* Create a stream that reads from the buffer. */
+        pb_istream_t stream = pb_istream_from_buffer(buffer, message_length);
+        
+        /* Now we are ready to decode the message. */
+        status = pb_decode(&stream, SimpleMessage_fields, &message);
+        
+        /* Check for errors... */
+        if (!status)
+        {
+            printf("Decoding failed: %s\n", PB_GET_ERROR(&stream));
+            return 1;
+        }
+        
+        /* Print the data contained in the message. */
+        printf("Your lucky number was %d!\n", message.lucky_number);
+    }
+    
+    return 0;
+}
+
diff --git a/examples/cmake_simple/simple.proto b/examples/cmake_simple/simple.proto
new file mode 100644
index 0000000..5c73a3b
--- /dev/null
+++ b/examples/cmake_simple/simple.proto
@@ -0,0 +1,9 @@
+// A very simple protocol definition, consisting of only
+// one message.
+
+syntax = "proto2";
+
+message SimpleMessage {
+    required int32 lucky_number = 1;
+}
+
diff --git a/examples/network_server/client.c b/examples/network_server/client.c
index e6e9a2e..ca0c68e 100644
--- a/examples/network_server/client.c
+++ b/examples/network_server/client.c
@@ -23,9 +23,13 @@
 #include "fileproto.pb.h"
 #include "common.h"
 
+/* This callback function will be called once for each filename received
+ * from the server. The filenames will be printed out immediately, so that
+ * no memory has to be allocated for them.
+ */
 bool printfile_callback(pb_istream_t *stream, const pb_field_t *field, void **arg)
 {
-    FileInfo fileinfo;
+    FileInfo fileinfo = {};
     
     if (!pb_decode(stream, FileInfo_fields, &fileinfo))
         return false;
@@ -35,51 +39,66 @@
     return true;
 }
 
+/* This function sends a request to socket 'fd' to list the files in
+ * directory given in 'path'. The results received from server will
+ * be printed to stdout.
+ */
 bool listdir(int fd, char *path)
 {
-    ListFilesRequest request;
-    ListFilesResponse response;
-    pb_istream_t input = pb_istream_from_socket(fd);
-    pb_ostream_t output = pb_ostream_from_socket(fd);
-    uint8_t zero = 0;
-    
-    if (path == NULL)
+    /* Construct and send the request to server */
     {
-        request.has_path = false;
-    }
-    else
-    {
-        request.has_path = true;
-        if (strlen(path) + 1 > sizeof(request.path))
+        ListFilesRequest request = {};
+        pb_ostream_t output = pb_ostream_from_socket(fd);
+        
+        /* In our protocol, path is optional. If it is not given,
+         * the server will list the root directory. */
+        if (path == NULL)
         {
-            fprintf(stderr, "Too long path.\n");
+            request.has_path = false;
+        }
+        else
+        {
+            request.has_path = true;
+            if (strlen(path) + 1 > sizeof(request.path))
+            {
+                fprintf(stderr, "Too long path.\n");
+                return false;
+            }
+            
+            strcpy(request.path, path);
+        }
+        
+        /* Encode the request. It is written to the socket immediately
+         * through our custom stream. */
+        if (!pb_encode_delimited(&output, ListFilesRequest_fields, &request))
+        {
+            fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&output));
+            return false;
+        }
+    }
+    
+    /* Read back the response from server */
+    {
+        ListFilesResponse response = {};
+        pb_istream_t input = pb_istream_from_socket(fd);
+        
+        /* Give a pointer to our callback function, which will handle the
+         * filenames as they arrive. */
+        response.file.funcs.decode = &printfile_callback;
+        
+        if (!pb_decode_delimited(&input, ListFilesResponse_fields, &response))
+        {
+            fprintf(stderr, "Decode failed: %s\n", PB_GET_ERROR(&input));
             return false;
         }
         
-        strcpy(request.path, path);
-    }
-    
-    if (!pb_encode(&output, ListFilesRequest_fields, &request))
-    {
-        fprintf(stderr, "Encoding failed.\n");
-        return false;
-    }
-    
-    /* We signal the end of request with a 0 tag. */
-    pb_write(&output, &zero, 1);
-    
-    response.file.funcs.decode = &printfile_callback;
-    
-    if (!pb_decode(&input, ListFilesResponse_fields, &response))
-    {
-        fprintf(stderr, "Decode failed: %s\n", PB_GET_ERROR(&input));
-        return false;
-    }
-    
-    if (response.path_error)
-    {
-        fprintf(stderr, "Server reported error.\n");
-        return false;
+        /* If the message from server decodes properly, but directory was
+         * not found on server side, we get path_error == true. */
+        if (response.path_error)
+        {
+            fprintf(stderr, "Server reported error.\n");
+            return false;
+        }
     }
     
     return true;
@@ -96,6 +115,7 @@
     
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     
+    /* Connect to server running on localhost:1234 */
     memset(&servaddr, 0, sizeof(servaddr));
     servaddr.sin_family = AF_INET;
     servaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -107,9 +127,11 @@
         return 1;
     }
     
+    /* Send the directory listing request */
     if (!listdir(sockfd, path))
         return 2;
     
+    /* Close connection */
     close(sockfd);
     
     return 0;
diff --git a/examples/network_server/fileproto.proto b/examples/network_server/fileproto.proto
index 3e70c49..5640b8d 100644
--- a/examples/network_server/fileproto.proto
+++ b/examples/network_server/fileproto.proto
@@ -2,6 +2,8 @@
 //
 // See also the nanopb-specific options in fileproto.options.
 
+syntax = "proto2";
+
 message ListFilesRequest {
     optional string path = 1 [default = "/"];
 }
diff --git a/examples/network_server/server.c b/examples/network_server/server.c
index 9a9c264..f500dcd 100644
--- a/examples/network_server/server.c
+++ b/examples/network_server/server.c
@@ -23,11 +23,16 @@
 #include "fileproto.pb.h"
 #include "common.h"
 
+/* This callback function will be called once during the encoding.
+ * It will write out any number of FileInfo entries, without consuming unnecessary memory.
+ * This is accomplished by fetching the filenames one at a time and encoding them
+ * immediately.
+ */
 bool listdir_callback(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
 {
     DIR *dir = (DIR*) *arg;
     struct dirent *file;
-    FileInfo fileinfo;
+    FileInfo fileinfo = {};
     
     while ((file = readdir(dir)) != NULL)
     {
@@ -35,53 +40,76 @@
         strncpy(fileinfo.name, file->d_name, sizeof(fileinfo.name));
         fileinfo.name[sizeof(fileinfo.name) - 1] = '\0';
         
+        /* This encodes the header for the field, based on the constant info
+         * from pb_field_t. */
         if (!pb_encode_tag_for_field(stream, field))
             return false;
         
+        /* This encodes the data for the field, based on our FileInfo structure. */
         if (!pb_encode_submessage(stream, FileInfo_fields, &fileinfo))
             return false;
     }
     
+    /* Because the main program uses pb_encode_delimited(), this callback will be
+     * called twice. Rewind the directory for the next call. */
+    rewinddir(dir);
+
     return true;
 }
 
+/* Handle one arriving client connection.
+ * Clients are expected to send a ListFilesRequest, terminated by a '0'.
+ * Server will respond with a ListFilesResponse message.
+ */
 void handle_connection(int connfd)
 {
-    ListFilesRequest request;
-    ListFilesResponse response;
-    pb_istream_t input = pb_istream_from_socket(connfd);
-    pb_ostream_t output = pb_ostream_from_socket(connfd);
-    DIR *directory;
+    DIR *directory = NULL;
     
-    if (!pb_decode(&input, ListFilesRequest_fields, &request))
+    /* Decode the message from the client and open the requested directory. */
     {
-        printf("Decode failed: %s\n", PB_GET_ERROR(&input));
-        return;
-    }
-    
-    directory = opendir(request.path);
-    
-    printf("Listing directory: %s\n", request.path);
-    
-    if (directory == NULL)
-    {
-        perror("opendir");
+        ListFilesRequest request = {};
+        pb_istream_t input = pb_istream_from_socket(connfd);
         
-        response.has_path_error = true;
-        response.path_error = true;
-        response.file.funcs.encode = NULL;
-    }
-    else
-    {
-        response.has_path_error = false;
-        response.file.funcs.encode = &listdir_callback;
-        response.file.arg = directory;
+        if (!pb_decode_delimited(&input, ListFilesRequest_fields, &request))
+        {
+            printf("Decode failed: %s\n", PB_GET_ERROR(&input));
+            return;
+        }
+        
+        directory = opendir(request.path);
+        printf("Listing directory: %s\n", request.path);
     }
     
-    if (!pb_encode(&output, ListFilesResponse_fields, &response))
+    /* List the files in the directory and transmit the response to client */
     {
-        printf("Encoding failed.\n");
+        ListFilesResponse response = {};
+        pb_ostream_t output = pb_ostream_from_socket(connfd);
+        
+        if (directory == NULL)
+        {
+            perror("opendir");
+            
+            /* Directory was not found, transmit error status */
+            response.has_path_error = true;
+            response.path_error = true;
+            response.file.funcs.encode = NULL;
+        }
+        else
+        {
+            /* Directory was found, transmit filenames */
+            response.has_path_error = false;
+            response.file.funcs.encode = &listdir_callback;
+            response.file.arg = directory;
+        }
+        
+        if (!pb_encode_delimited(&output, ListFilesResponse_fields, &response))
+        {
+            printf("Encoding failed: %s\n", PB_GET_ERROR(&output));
+        }
     }
+    
+    if (directory != NULL)
+        closedir(directory);
 }
 
 int main(int argc, char **argv)
@@ -90,8 +118,8 @@
     struct sockaddr_in servaddr;
     int reuse = 1;
     
+    /* Listen on localhost:1234 for TCP connections */
     listenfd = socket(AF_INET, SOCK_STREAM, 0);
-    
     setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
     
     memset(&servaddr, 0, sizeof(servaddr));
@@ -112,6 +140,7 @@
     
     for(;;)
     {
+        /* Wait for a client */
         connfd = accept(listenfd, NULL, NULL);
         
         if (connfd < 0)
@@ -128,4 +157,6 @@
         
         close(connfd);
     }
+    
+    return 0;
 }
diff --git a/examples/simple/Makefile b/examples/simple/Makefile
index 02a4c3f..970a865 100644
--- a/examples/simple/Makefile
+++ b/examples/simple/Makefile
@@ -10,6 +10,7 @@
 CSRC += simple.pb.c                # The compiled protocol definition
 CSRC += $(NANOPB_DIR)/pb_encode.c  # The nanopb encoder
 CSRC += $(NANOPB_DIR)/pb_decode.c  # The nanopb decoder
+CSRC += $(NANOPB_DIR)/pb_common.c  # The nanopb common parts
 
 # Build rule for the main program
 simple: $(CSRC)
diff --git a/examples/simple/rules.mk b/examples/simple/rules.mk
new file mode 100644
index 0000000..1e4221d
--- /dev/null
+++ b/examples/simple/rules.mk
@@ -0,0 +1,24 @@
+NANOPB_DIR := external/nanopb-0.3.9.1-linux-x86
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_SRCS += \
+	$(LOCAL_DIR)/simple.c \
+	$(LOCAL_DIR)/simple.pb.c \
+	$(NANOPB_DIR)/pb_encode.c \
+	$(NANOPB_DIR)/pb_decode.c \
+	$(NANOPB_DIR)/pb_common.c
+
+MODULE_CPPFLAGS += -std=c++11
+
+MODULE_INCLUDES += \
+	$(NANOPB_DIR)
+
+$(LOCAL_DIR)/simple.pb.c: $(LOCAL_DIR)/simple.proto
+	$(PROTOC) $(PROTOC_OPTS) --nanopb_out=$(LOCAL_DIR) $(LOCAL_DIR)/simple.proto
+
+include $(NANOPB_DIR)/extra/nanopb.mk
+include make/module.mk
+
diff --git a/examples/simple/simple.c b/examples/simple/simple.c
index 3127230..c16ec52 100644
--- a/examples/simple/simple.c
+++ b/examples/simple/simple.c
@@ -15,8 +15,11 @@
         /* Allocate space on the stack to store the message data.
          *
          * Nanopb generates simple struct definitions for all the messages.
-         * - check out the contents of simple.pb.h! */
-        SimpleMessage message;
+         * - check out the contents of simple.pb.h!
+         * It is a good idea to always initialize your structures
+         * so that you do not have garbage data from RAM in there.
+         */
+        SimpleMessage message = SimpleMessage_init_zero;
         
         /* Create a stream that will write to our buffer. */
         pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
@@ -44,7 +47,7 @@
     
     {
         /* Allocate space for the decoded message. */
-        SimpleMessage message;
+        SimpleMessage message = SimpleMessage_init_zero;
         
         /* Create a stream that reads from the buffer. */
         pb_istream_t stream = pb_istream_from_buffer(buffer, message_length);
@@ -60,7 +63,7 @@
         }
         
         /* Print the data contained in the message. */
-        printf("Your lucky number was %d!\n", message.lucky_number);
+        printf("Your lucky number was %d!\n", (int)message.lucky_number);
     }
     
     return 0;
diff --git a/examples/simple/simple.pb.c b/examples/simple/simple.pb.c
new file mode 100644
index 0000000..481aa7d
--- /dev/null
+++ b/examples/simple/simple.pb.c
@@ -0,0 +1,19 @@
+/* Automatically generated nanopb constant definitions */
+/* Generated by nanopb-0.3.9.1 at Fri May 25 16:28:54 2018. */
+
+#include "simple.pb.h"
+
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+
+
+const pb_field_t SimpleMessage_fields[2] = {
+    PB_FIELD(  1, INT32   , REQUIRED, STATIC  , FIRST, SimpleMessage, lucky_number, lucky_number, 0),
+    PB_LAST_FIELD
+};
+
+
+/* @@protoc_insertion_point(eof) */
diff --git a/examples/simple/simple.pb.h b/examples/simple/simple.pb.h
new file mode 100644
index 0000000..f4614db
--- /dev/null
+++ b/examples/simple/simple.pb.h
@@ -0,0 +1,51 @@
+/* Automatically generated nanopb header */
+/* Generated by nanopb-0.3.9.1 at Fri May 25 16:28:54 2018. */
+
+#ifndef PB_SIMPLE_PB_H_INCLUDED
+#define PB_SIMPLE_PB_H_INCLUDED
+#include <pb.h>
+
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Struct definitions */
+typedef struct _SimpleMessage {
+    int32_t lucky_number;
+/* @@protoc_insertion_point(struct:SimpleMessage) */
+} SimpleMessage;
+
+/* Default values for struct fields */
+
+/* Initializer values for message structs */
+#define SimpleMessage_init_default               {0}
+#define SimpleMessage_init_zero                  {0}
+
+/* Field tags (for use in manual encoding/decoding) */
+#define SimpleMessage_lucky_number_tag           1
+
+/* Struct field encoding specification for nanopb */
+extern const pb_field_t SimpleMessage_fields[2];
+
+/* Maximum encoded size of messages (where known) */
+#define SimpleMessage_size                       11
+
+/* Message IDs (where set with "msgid" option) */
+#ifdef PB_MSGID
+
+#define SIMPLE_MESSAGES \
+
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+/* @@protoc_insertion_point(eof) */
+
+#endif
diff --git a/examples/simple/simple.proto b/examples/simple/simple.proto
index 26e72f4..5c73a3b 100644
--- a/examples/simple/simple.proto
+++ b/examples/simple/simple.proto
@@ -1,6 +1,8 @@
 // A very simple protocol definition, consisting of only
 // one message.
 
+syntax = "proto2";
+
 message SimpleMessage {
     required int32 lucky_number = 1;
 }
diff --git a/examples/using_double_on_avr/doubleproto.proto b/examples/using_double_on_avr/doubleproto.proto
index d8b7f2d..72d3f9c 100644
--- a/examples/using_double_on_avr/doubleproto.proto
+++ b/examples/using_double_on_avr/doubleproto.proto
@@ -1,4 +1,6 @@
 // A message containing doubles, as used by other applications.
+syntax = "proto2";
+
 message DoubleMessage {
     required double field1 = 1;
     required double field2 = 2;
diff --git a/examples/using_union_messages/README.txt b/examples/using_union_messages/README.txt
index 7a1e75d..d4b7fd2 100644
--- a/examples/using_union_messages/README.txt
+++ b/examples/using_union_messages/README.txt
@@ -17,6 +17,9 @@
 the top level message, and only then allocate the memory for the submessage
 after we already know its type.
 
+NOTE: There is a newer protobuf feature called `oneof` that is also supported
+by nanopb. It might be a better option for new code.
+
 
 Example usage
 -------------
diff --git a/examples/using_union_messages/unionproto.proto b/examples/using_union_messages/unionproto.proto
index d7c9de2..209df0d 100644
--- a/examples/using_union_messages/unionproto.proto
+++ b/examples/using_union_messages/unionproto.proto
@@ -5,6 +5,8 @@
 // but they are commonly implemented by filling out exactly one of
 // several optional fields.
 
+syntax = "proto2";
+
 message MsgType1
 {
     required int32 value = 1;
diff --git a/extra/FindNanopb.cmake b/extra/FindNanopb.cmake
index c804e70..bba341d 100644
--- a/extra/FindNanopb.cmake
+++ b/extra/FindNanopb.cmake
@@ -1,10 +1,6 @@
 # This is an example script for use with CMake projects for locating and configuring
 # the nanopb library.
 #
-# The following varialbes have to be set:
-#
-#   NANOPB_SRC_ROOT_FOLDER  - Path to nanopb source folder
-#
 # The following variables can be set and are optional:
 #
 #
@@ -16,6 +12,13 @@
 #   NANOPB_IMPORT_DIRS       - List of additional directories to be searched for
 #                              imported .proto files.
 #
+#   NANOPB_OPTIONS           - List of options passed to nanopb.
+#
+#   NANOPB_DEPENDS           - List of files to be used as dependencies
+#                              for the generated source and header files. These
+#                              files are not directly passed as options to
+#                              nanopb but rather their directories.
+#
 #   NANOPB_GENERATE_CPP_APPEND_PATH - By default -I will be passed to protoc
 #                                     for each directory where a proto file is referenced.
 #                                     Set to FALSE if you want to disable this behaviour.
@@ -26,23 +29,28 @@
 #   NANOPB_INCLUDE_DIRS - Include directories for Google Protocol Buffers
 #
 # The following cache variables are also available to set or use:
-#   NANOPB_GENERATOR_EXECUTABLE - The nanopb generator
 #   PROTOBUF_PROTOC_EXECUTABLE - The protoc compiler
+#   NANOPB_GENERATOR_SOURCE_DIR - The nanopb generator source
 #
 #  ====================================================================
 #
 # NANOPB_GENERATE_CPP (public function)
-#   SRCS = Variable to define with autogenerated
-#          source files
-#   HDRS = Variable to define with autogenerated
-#          header files
-#   ARGN = proto files
+# NANOPB_GENERATE_CPP(SRCS HDRS [RELPATH <root-path-of-proto-files>]
+#                     <proto-files>...)
+#   SRCS = Variable to define with autogenerated source files
+#   HDRS = Variable to define with autogenerated header files
+#   If you want to use relative paths in your import statements use the RELPATH
+#   option. The argument to RELPATH should be the directory that all the
+#   imports will be relative to.
+#   When RELPATH is not specified then all proto files can be imported without
+#   a path.
+#
 #
 #  ====================================================================
 #  Example:
 #
 #   set(NANOPB_SRC_ROOT_FOLDER "/path/to/nanopb")
-#   set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${NANOPB_SRC_ROOT_FOLDER}/cmake)
+#   set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${NANOPB_SRC_ROOT_FOLDER}/extra)
 #   find_package( Nanopb REQUIRED )
 #   include_directories(${NANOPB_INCLUDE_DIRS})
 #
@@ -51,6 +59,19 @@
 #   include_directories(${CMAKE_CURRENT_BINARY_DIR})
 #   add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
 #
+#  Example with RELPATH:
+#   Assume we have a layout like:
+#    .../CMakeLists.txt
+#    .../bar.cc
+#    .../proto/
+#    .../proto/foo.proto  (Which contains: import "sub/bar.proto"; )
+#    .../proto/sub/bar.proto
+#   Everything would be the same as the previous example, but the call to
+#   NANOPB_GENERATE_CPP would change to:
+#
+#   NANOPB_GENERATE_CPP(PROTO_SRCS PROTO_HDRS RELPATH proto
+#                       proto/foo.proto proto/sub/bar.proto)
+#
 #  ====================================================================
 
 #=============================================================================
@@ -96,62 +117,148 @@
 
 
 function(NANOPB_GENERATE_CPP SRCS HDRS)
-  if(NOT ARGN)
+  cmake_parse_arguments(NANOPB_GENERATE_CPP "" "RELPATH" "" ${ARGN})
+  if(NOT NANOPB_GENERATE_CPP_UNPARSED_ARGUMENTS)
     return()
   endif()
 
   if(NANOPB_GENERATE_CPP_APPEND_PATH)
     # Create an include path for each file specified
-    foreach(FIL ${ARGN})
+    foreach(FIL ${NANOPB_GENERATE_CPP_UNPARSED_ARGUMENTS})
       get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
       get_filename_component(ABS_PATH ${ABS_FIL} PATH)
-
-      list(FIND _nanobp_include_path ${ABS_PATH} _contains_already)
-      if(${_contains_already} EQUAL -1)
-          list(APPEND _nanobp_include_path -I ${ABS_PATH})
-      endif()
+      list(APPEND _nanopb_include_path "-I${ABS_PATH}")
     endforeach()
   else()
-    set(_nanobp_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
+    set(_nanopb_include_path "-I${CMAKE_CURRENT_SOURCE_DIR}")
+  endif()
+
+  if(NANOPB_GENERATE_CPP_RELPATH)
+    list(APPEND _nanopb_include_path "-I${NANOPB_GENERATE_CPP_RELPATH}")
   endif()
 
   if(DEFINED NANOPB_IMPORT_DIRS)
     foreach(DIR ${NANOPB_IMPORT_DIRS})
       get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
-      list(FIND _nanobp_include_path ${ABS_PATH} _contains_already)
-      if(${_contains_already} EQUAL -1)
-          list(APPEND _nanobp_include_path -I ${ABS_PATH})
-      endif()
+      list(APPEND _nanopb_include_path "-I${ABS_PATH}")
     endforeach()
   endif()
 
-  set(${SRCS})
-  set(${HDRS})
-  get_filename_component(GENERATOR_PATH ${NANOPB_GENERATOR_EXECUTABLE} PATH)
+  list(REMOVE_DUPLICATES _nanopb_include_path)
 
-  foreach(FIL ${ARGN})
+  set(GENERATOR_PATH ${CMAKE_BINARY_DIR}/nanopb/generator)
+
+  set(NANOPB_GENERATOR_EXECUTABLE ${GENERATOR_PATH}/nanopb_generator.py)
+  set(NANOPB_GENERATOR_PLUGIN ${GENERATOR_PATH}/protoc-gen-nanopb)
+
+  set(GENERATOR_CORE_DIR ${GENERATOR_PATH}/proto)
+  set(GENERATOR_CORE_SRC
+      ${GENERATOR_CORE_DIR}/nanopb.proto
+      ${GENERATOR_CORE_DIR}/plugin.proto)
+
+  # Treat the source diretory as immutable.
+  #
+  # Copy the generator directory to the build directory before
+  # compiling python and proto files.  Fixes issues when using the
+  # same build directory with different python/protobuf versions
+  # as the binary build directory is discarded across builds.
+  #
+  add_custom_command(
+      OUTPUT ${NANOPB_GENERATOR_EXECUTABLE} ${GENERATOR_CORE_SRC}
+      COMMAND ${CMAKE_COMMAND} -E copy_directory
+      ARGS ${NANOPB_GENERATOR_SOURCE_DIR} ${GENERATOR_PATH}
+      VERBATIM)
+
+  set(GENERATOR_CORE_PYTHON_SRC)
+  foreach(FIL ${GENERATOR_CORE_SRC})
+      get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+      get_filename_component(FIL_WE ${FIL} NAME_WE)
+
+      set(output "${GENERATOR_CORE_DIR}/${FIL_WE}_pb2.py")
+      set(GENERATOR_CORE_PYTHON_SRC ${GENERATOR_CORE_PYTHON_SRC} ${output})
+      add_custom_command(
+        OUTPUT ${output}
+        COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
+        ARGS -I${GENERATOR_PATH}/proto
+          --python_out=${GENERATOR_CORE_DIR} ${ABS_FIL}
+        DEPENDS ${ABS_FIL}
+        VERBATIM)
+  endforeach()
+
+  if(NANOPB_GENERATE_CPP_RELPATH)
+      get_filename_component(ABS_ROOT ${NANOPB_GENERATE_CPP_RELPATH} ABSOLUTE)
+  endif()
+  foreach(FIL ${NANOPB_GENERATE_CPP_UNPARSED_ARGUMENTS})
     get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
     get_filename_component(FIL_WE ${FIL} NAME_WE)
+    get_filename_component(FIL_DIR ${FIL} PATH)
+    set(FIL_PATH_REL)
+    if(ABS_ROOT)
+      # Check that the file is under the given "RELPATH"
+      string(FIND ${ABS_FIL} ${ABS_ROOT} LOC)
+      if (${LOC} EQUAL 0)
+        string(REPLACE "${ABS_ROOT}/" "" FIL_REL ${ABS_FIL})
+        get_filename_component(FIL_PATH_REL ${FIL_REL} PATH)
+        file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL})
+      endif()
+    endif()
+    if(NOT FIL_PATH_REL)
+      set(FIL_PATH_REL ".")
+    endif()
 
-    list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.c")
-    list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
+    list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.c")
+    list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.h")
+
+    set(NANOPB_PLUGIN_OPTIONS)
+    set(NANOPB_OPTIONS_DIRS)
+
+    # If there an options file in the same working directory, set it as a dependency
+    set(NANOPB_OPTIONS_FILE ${FIL_DIR}/${FIL_WE}.options)
+    if(EXISTS ${NANOPB_OPTIONS_FILE})
+        # Get directory as lookups for dependency options fail if an options
+        # file is used. The options is still set as a dependency of the
+        # generated source and header.
+        get_filename_component(options_dir ${NANOPB_OPTIONS_FILE} DIRECTORY)
+        list(APPEND NANOPB_OPTIONS_DIRS ${options_dir})
+    else()
+        set(NANOPB_OPTIONS_FILE)
+    endif()
+
+    # If the dependencies are options files, we need to pass the directories
+    # as arguments to nanopb
+    foreach(depends_file ${NANOPB_DEPENDS})
+        get_filename_component(ext ${depends_file} EXT)
+        if(ext STREQUAL ".options")
+            get_filename_component(depends_dir ${depends_file} DIRECTORY)
+            list(APPEND NANOPB_OPTIONS_DIRS ${depends_dir})
+        endif()
+    endforeach()
+
+    if(NANOPB_OPTIONS_DIRS)
+        list(REMOVE_DUPLICATES NANOPB_OPTIONS_DIRS)
+    endif()
+
+    foreach(options_path ${NANOPB_OPTIONS_DIRS})
+        set(NANOPB_PLUGIN_OPTIONS "${NANOPB_PLUGIN_OPTIONS} -I${options_path}")
+    endforeach()
+
+    if(NANOPB_OPTIONS)
+        set(NANOPB_PLUGIN_OPTIONS "${NANOPB_PLUGIN_OPTIONS} ${NANOPB_OPTIONS}")
+    endif()
 
     add_custom_command(
-      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb"
+      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.c"
+             "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.h"
       COMMAND  ${PROTOBUF_PROTOC_EXECUTABLE}
-      ARGS -I${GENERATOR_PATH} -I${CMAKE_CURRENT_BINARY_DIR} ${_nanobp_include_path} -o${FIL_WE}.pb ${ABS_FIL}
-      DEPENDS ${ABS_FIL}
-      COMMENT "Running C++ protocol buffer compiler on ${FIL}"
+      ARGS -I${GENERATOR_PATH} -I${GENERATOR_CORE_DIR}
+           -I${CMAKE_CURRENT_BINARY_DIR} ${_nanopb_include_path}
+           --plugin=protoc-gen-nanopb=${NANOPB_GENERATOR_PLUGIN}
+           "--nanopb_out=${NANOPB_PLUGIN_OPTIONS}:${CMAKE_CURRENT_BINARY_DIR}" ${ABS_FIL}
+      DEPENDS ${ABS_FIL} ${GENERATOR_CORE_PYTHON_SRC}
+           ${NANOPB_OPTIONS_FILE} ${NANOPB_DEPENDS}
+      COMMENT "Running C++ protocol buffer compiler using nanopb plugin on ${FIL}"
       VERBATIM )
 
-    add_custom_command(
-      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.c"
-             "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
-      COMMAND python
-      ARGS ${NANOPB_GENERATOR_EXECUTABLE} ${FIL_WE}.pb
-      DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb"
-      COMMENT "Running nanopb generator on ${FIL_WE}.pb"
-      VERBATIM )
   endforeach()
 
   set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
@@ -172,6 +279,12 @@
   set(NANOPB_GENERATE_CPP_APPEND_PATH TRUE)
 endif()
 
+# Make a really good guess regarding location of NANOPB_SRC_ROOT_FOLDER
+if(NOT DEFINED NANOPB_SRC_ROOT_FOLDER)
+  get_filename_component(NANOPB_SRC_ROOT_FOLDER
+                         ${CMAKE_CURRENT_LIST_DIR}/.. ABSOLUTE)
+endif()
+
 # Find the include directory
 find_path(NANOPB_INCLUDE_DIRS
     pb.h
@@ -182,8 +295,8 @@
 # Find nanopb source files
 set(NANOPB_SRCS)
 set(NANOPB_HDRS)
-list(APPEND _nanopb_srcs pb_decode.c pb_encode.c)
-list(APPEND _nanopb_hdrs pb_decode.h pb_encode.h pb.h)
+list(APPEND _nanopb_srcs pb_decode.c pb_encode.c pb_common.c)
+list(APPEND _nanopb_hdrs pb_decode.h pb_encode.h pb_common.h pb.h)
 
 foreach(FIL ${_nanopb_srcs})
   find_file(${FIL}__nano_pb_file NAMES ${FIL} PATHS ${NANOPB_SRC_ROOT_FOLDER} ${NANOPB_INCLUDE_DIRS})
@@ -207,19 +320,21 @@
 )
 mark_as_advanced(PROTOBUF_PROTOC_EXECUTABLE)
 
-# Find nanopb generator
-find_file(NANOPB_GENERATOR_EXECUTABLE
+# Find nanopb generator source dir
+find_path(NANOPB_GENERATOR_SOURCE_DIR
     NAMES nanopb_generator.py
-    DOC "nanopb generator"
+    DOC "nanopb generator source"
     PATHS
     ${NANOPB_SRC_ROOT_FOLDER}/generator
 )
-mark_as_advanced(NANOPB_GENERATOR_EXECUTABLE)
+mark_as_advanced(NANOPB_GENERATOR_SOURCE_DIR)
+
+find_package(PythonInterp REQUIRED)
 
 include(FindPackageHandleStandardArgs)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(NANOPB DEFAULT_MSG
   NANOPB_INCLUDE_DIRS
   NANOPB_SRCS NANOPB_HDRS
-  NANOPB_GENERATOR_EXECUTABLE
+  NANOPB_GENERATOR_SOURCE_DIR
   PROTOBUF_PROTOC_EXECUTABLE
   )
diff --git a/extra/nanopb-config-version.cmake.in b/extra/nanopb-config-version.cmake.in
new file mode 100644
index 0000000..1b51027
--- /dev/null
+++ b/extra/nanopb-config-version.cmake.in
@@ -0,0 +1,11 @@
+set(PACKAGE_VERSION "@nanopb_VERSION@")
+
+# Check whether the requested PACKAGE_FIND_VERSION is compatible
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
+    set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+    set(PACKAGE_VERSION_COMPATIBLE TRUE)
+    if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
+        set(PACKAGE_VERSION_EXACT TRUE)
+    endif()
+endif()
diff --git a/extra/nanopb-config.cmake b/extra/nanopb-config.cmake
new file mode 100644
index 0000000..42d977a
--- /dev/null
+++ b/extra/nanopb-config.cmake
@@ -0,0 +1 @@
+include(${CMAKE_CURRENT_LIST_DIR}/nanopb-targets.cmake)
diff --git a/extra/nanopb.mk b/extra/nanopb.mk
index 7576bae..5c2cff5 100644
--- a/extra/nanopb.mk
+++ b/extra/nanopb.mk
@@ -5,7 +5,7 @@
 NANOPB_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))../)
 
 # Files for the nanopb core
-NANOPB_CORE = $(NANOPB_DIR)/pb_encode.c $(NANOPB_DIR)/pb_decode.c
+NANOPB_CORE = $(NANOPB_DIR)/pb_encode.c $(NANOPB_DIR)/pb_decode.c $(NANOPB_DIR)/pb_common.c
 
 # Check if we are running on Windows
 ifdef windir
diff --git a/extra/pb_syshdr.h b/extra/pb_syshdr.h
index 1ff4823..55d06a3 100644
--- a/extra/pb_syshdr.h
+++ b/extra/pb_syshdr.h
@@ -24,6 +24,14 @@
 typedef unsigned int uint32_t;
 typedef signed long long int64_t;
 typedef unsigned long long uint64_t;
+
+/* These are ok for most platforms, unless uint8_t is actually not available,
+ * in which case you should give the smallest available type. */
+typedef int8_t int_least8_t;
+typedef uint8_t uint_least8_t;
+typedef uint8_t uint_fast8_t;
+typedef int16_t int_least16_t;
+typedef uint16_t uint_least16_t;
 #endif
 
 /* stddef.h subset */
diff --git a/generator/google/protobuf/__init__.py b/generator/google/protobuf/__init__.py
index e69de29..6210a40 100644
--- a/generator/google/protobuf/__init__.py
+++ b/generator/google/protobuf/__init__.py
@@ -0,0 +1,39 @@
+# 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.
+
+# Copyright 2007 Google Inc. All Rights Reserved.
+
+__version__ = '3.0.0'
+
+if __name__ != '__main__':
+  try:
+    __import__('pkg_resources').declare_namespace(__name__)
+  except ImportError:
+    __path__ = __import__('pkgutil').extend_path(__path__, __name__)
diff --git a/generator/google/protobuf/any_pb2.py b/generator/google/protobuf/any_pb2.py
new file mode 100644
index 0000000..f219c9d
--- /dev/null
+++ b/generator/google/protobuf/any_pb2.py
@@ -0,0 +1,78 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/any.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/any.proto',
+  package='google.protobuf',
+  syntax='proto3',
+  serialized_pb=_b('\n\x19google/protobuf/any.proto\x12\x0fgoogle.protobuf\"&\n\x03\x41ny\x12\x10\n\x08type_url\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\x42r\n\x13\x63om.google.protobufB\x08\x41nyProtoP\x01Z%github.com/golang/protobuf/ptypes/any\xa0\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_ANY = _descriptor.Descriptor(
+  name='Any',
+  full_name='google.protobuf.Any',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='type_url', full_name='google.protobuf.Any.type_url', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.Any.value', index=1,
+      number=2, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=46,
+  serialized_end=84,
+)
+
+DESCRIPTOR.message_types_by_name['Any'] = _ANY
+
+Any = _reflection.GeneratedProtocolMessageType('Any', (_message.Message,), dict(
+  DESCRIPTOR = _ANY,
+  __module__ = 'google.protobuf.any_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Any)
+  ))
+_sym_db.RegisterMessage(Any)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\023com.google.protobufB\010AnyProtoP\001Z%github.com/golang/protobuf/ptypes/any\240\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/any_test_pb2.py b/generator/google/protobuf/any_test_pb2.py
new file mode 100644
index 0000000..64f90e8
--- /dev/null
+++ b/generator/google/protobuf/any_test_pb2.py
@@ -0,0 +1,87 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/any_test.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/any_test.proto',
+  package='protobuf_unittest',
+  syntax='proto3',
+  serialized_pb=_b('\n\x1egoogle/protobuf/any_test.proto\x12\x11protobuf_unittest\x1a\x19google/protobuf/any.proto\"y\n\x07TestAny\x12\x13\n\x0bint32_value\x18\x01 \x01(\x05\x12\'\n\tany_value\x18\x02 \x01(\x0b\x32\x14.google.protobuf.Any\x12\x30\n\x12repeated_any_value\x18\x03 \x03(\x0b\x32\x14.google.protobuf.Anyb\x06proto3')
+  ,
+  dependencies=[google_dot_protobuf_dot_any__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_TESTANY = _descriptor.Descriptor(
+  name='TestAny',
+  full_name='protobuf_unittest.TestAny',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='int32_value', full_name='protobuf_unittest.TestAny.int32_value', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='any_value', full_name='protobuf_unittest.TestAny.any_value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_any_value', full_name='protobuf_unittest.TestAny.repeated_any_value', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=80,
+  serialized_end=201,
+)
+
+_TESTANY.fields_by_name['any_value'].message_type = google_dot_protobuf_dot_any__pb2._ANY
+_TESTANY.fields_by_name['repeated_any_value'].message_type = google_dot_protobuf_dot_any__pb2._ANY
+DESCRIPTOR.message_types_by_name['TestAny'] = _TESTANY
+
+TestAny = _reflection.GeneratedProtocolMessageType('TestAny', (_message.Message,), dict(
+  DESCRIPTOR = _TESTANY,
+  __module__ = 'google.protobuf.any_test_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestAny)
+  ))
+_sym_db.RegisterMessage(TestAny)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/api_pb2.py b/generator/google/protobuf/api_pb2.py
new file mode 100644
index 0000000..5a0bc1b
--- /dev/null
+++ b/generator/google/protobuf/api_pb2.py
@@ -0,0 +1,250 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/api.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import source_context_pb2 as google_dot_protobuf_dot_source__context__pb2
+from google.protobuf import type_pb2 as google_dot_protobuf_dot_type__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/api.proto',
+  package='google.protobuf',
+  syntax='proto3',
+  serialized_pb=_b('\n\x19google/protobuf/api.proto\x12\x0fgoogle.protobuf\x1a$google/protobuf/source_context.proto\x1a\x1agoogle/protobuf/type.proto\"\x81\x02\n\x03\x41pi\x12\x0c\n\x04name\x18\x01 \x01(\t\x12(\n\x07methods\x18\x02 \x03(\x0b\x32\x17.google.protobuf.Method\x12(\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.Option\x12\x0f\n\x07version\x18\x04 \x01(\t\x12\x36\n\x0esource_context\x18\x05 \x01(\x0b\x32\x1e.google.protobuf.SourceContext\x12&\n\x06mixins\x18\x06 \x03(\x0b\x32\x16.google.protobuf.Mixin\x12\'\n\x06syntax\x18\x07 \x01(\x0e\x32\x17.google.protobuf.Syntax\"\xd5\x01\n\x06Method\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x18\n\x10request_type_url\x18\x02 \x01(\t\x12\x19\n\x11request_streaming\x18\x03 \x01(\x08\x12\x19\n\x11response_type_url\x18\x04 \x01(\t\x12\x1a\n\x12response_streaming\x18\x05 \x01(\x08\x12(\n\x07options\x18\x06 \x03(\x0b\x32\x17.google.protobuf.Option\x12\'\n\x06syntax\x18\x07 \x01(\x0e\x32\x17.google.protobuf.Syntax\"#\n\x05Mixin\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04root\x18\x02 \x01(\tBK\n\x13\x63om.google.protobufB\x08\x41piProtoP\x01\xa0\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3')
+  ,
+  dependencies=[google_dot_protobuf_dot_source__context__pb2.DESCRIPTOR,google_dot_protobuf_dot_type__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_API = _descriptor.Descriptor(
+  name='Api',
+  full_name='google.protobuf.Api',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='google.protobuf.Api.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='methods', full_name='google.protobuf.Api.methods', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='options', full_name='google.protobuf.Api.options', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='version', full_name='google.protobuf.Api.version', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='source_context', full_name='google.protobuf.Api.source_context', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='mixins', full_name='google.protobuf.Api.mixins', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='syntax', full_name='google.protobuf.Api.syntax', index=6,
+      number=7, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=113,
+  serialized_end=370,
+)
+
+
+_METHOD = _descriptor.Descriptor(
+  name='Method',
+  full_name='google.protobuf.Method',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='google.protobuf.Method.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='request_type_url', full_name='google.protobuf.Method.request_type_url', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='request_streaming', full_name='google.protobuf.Method.request_streaming', index=2,
+      number=3, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='response_type_url', full_name='google.protobuf.Method.response_type_url', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='response_streaming', full_name='google.protobuf.Method.response_streaming', index=4,
+      number=5, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='options', full_name='google.protobuf.Method.options', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='syntax', full_name='google.protobuf.Method.syntax', index=6,
+      number=7, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=373,
+  serialized_end=586,
+)
+
+
+_MIXIN = _descriptor.Descriptor(
+  name='Mixin',
+  full_name='google.protobuf.Mixin',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='google.protobuf.Mixin.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='root', full_name='google.protobuf.Mixin.root', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=588,
+  serialized_end=623,
+)
+
+_API.fields_by_name['methods'].message_type = _METHOD
+_API.fields_by_name['options'].message_type = google_dot_protobuf_dot_type__pb2._OPTION
+_API.fields_by_name['source_context'].message_type = google_dot_protobuf_dot_source__context__pb2._SOURCECONTEXT
+_API.fields_by_name['mixins'].message_type = _MIXIN
+_API.fields_by_name['syntax'].enum_type = google_dot_protobuf_dot_type__pb2._SYNTAX
+_METHOD.fields_by_name['options'].message_type = google_dot_protobuf_dot_type__pb2._OPTION
+_METHOD.fields_by_name['syntax'].enum_type = google_dot_protobuf_dot_type__pb2._SYNTAX
+DESCRIPTOR.message_types_by_name['Api'] = _API
+DESCRIPTOR.message_types_by_name['Method'] = _METHOD
+DESCRIPTOR.message_types_by_name['Mixin'] = _MIXIN
+
+Api = _reflection.GeneratedProtocolMessageType('Api', (_message.Message,), dict(
+  DESCRIPTOR = _API,
+  __module__ = 'google.protobuf.api_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Api)
+  ))
+_sym_db.RegisterMessage(Api)
+
+Method = _reflection.GeneratedProtocolMessageType('Method', (_message.Message,), dict(
+  DESCRIPTOR = _METHOD,
+  __module__ = 'google.protobuf.api_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Method)
+  ))
+_sym_db.RegisterMessage(Method)
+
+Mixin = _reflection.GeneratedProtocolMessageType('Mixin', (_message.Message,), dict(
+  DESCRIPTOR = _MIXIN,
+  __module__ = 'google.protobuf.api_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Mixin)
+  ))
+_sym_db.RegisterMessage(Mixin)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\023com.google.protobufB\010ApiProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/compiler/plugin_pb2.py b/generator/google/protobuf/compiler/plugin_pb2.py
index 77cc07a..e01b7a7 100644
--- a/generator/google/protobuf/compiler/plugin_pb2.py
+++ b/generator/google/protobuf/compiler/plugin_pb2.py
@@ -1,20 +1,29 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/compiler/plugin.proto
 
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
 from google.protobuf import descriptor as _descriptor
 from google.protobuf import message as _message
 from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
 from google.protobuf import descriptor_pb2
 # @@protoc_insertion_point(imports)
 
+_sym_db = _symbol_database.Default()
 
-import google.protobuf.descriptor_pb2
+
+from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
   name='google/protobuf/compiler/plugin.proto',
   package='google.protobuf.compiler',
-  serialized_pb='\n%google/protobuf/compiler/plugin.proto\x12\x18google.protobuf.compiler\x1a google/protobuf/descriptor.proto\"}\n\x14\x43odeGeneratorRequest\x12\x18\n\x10\x66ile_to_generate\x18\x01 \x03(\t\x12\x11\n\tparameter\x18\x02 \x01(\t\x12\x38\n\nproto_file\x18\x0f \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xaa\x01\n\x15\x43odeGeneratorResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x12\x42\n\x04\x66ile\x18\x0f \x03(\x0b\x32\x34.google.protobuf.compiler.CodeGeneratorResponse.File\x1a>\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0finsertion_point\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x0f \x01(\tB,\n\x1c\x63om.google.protobuf.compilerB\x0cPluginProtos')
+  syntax='proto2',
+  serialized_pb=_b('\n%google/protobuf/compiler/plugin.proto\x12\x18google.protobuf.compiler\x1a google/protobuf/descriptor.proto\"}\n\x14\x43odeGeneratorRequest\x12\x18\n\x10\x66ile_to_generate\x18\x01 \x03(\t\x12\x11\n\tparameter\x18\x02 \x01(\t\x12\x38\n\nproto_file\x18\x0f \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xaa\x01\n\x15\x43odeGeneratorResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x12\x42\n\x04\x66ile\x18\x0f \x03(\x0b\x32\x34.google.protobuf.compiler.CodeGeneratorResponse.File\x1a>\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0finsertion_point\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x0f \x01(\tB7\n\x1c\x63om.google.protobuf.compilerB\x0cPluginProtosZ\tplugin_go')
+  ,
+  dependencies=[google_dot_protobuf_dot_descriptor__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
 
 
@@ -36,7 +45,7 @@
     _descriptor.FieldDescriptor(
       name='parameter', full_name='google.protobuf.compiler.CodeGeneratorRequest.parameter', index=1,
       number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -55,7 +64,10 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
+  oneofs=[
+  ],
   serialized_start=101,
   serialized_end=226,
 )
@@ -71,21 +83,21 @@
     _descriptor.FieldDescriptor(
       name='name', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.name', index=0,
       number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
       name='insertion_point', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point', index=1,
       number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
       name='content', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.content', index=2,
       number=15, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -97,7 +109,10 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
+  oneofs=[
+  ],
   serialized_start=337,
   serialized_end=399,
 )
@@ -112,7 +127,7 @@
     _descriptor.FieldDescriptor(
       name='error', full_name='google.protobuf.compiler.CodeGeneratorResponse.error', index=0,
       number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -131,36 +146,43 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
+  oneofs=[
+  ],
   serialized_start=229,
   serialized_end=399,
 )
 
-_CODEGENERATORREQUEST.fields_by_name['proto_file'].message_type = google.protobuf.descriptor_pb2._FILEDESCRIPTORPROTO
-_CODEGENERATORRESPONSE_FILE.containing_type = _CODEGENERATORRESPONSE;
+_CODEGENERATORREQUEST.fields_by_name['proto_file'].message_type = google_dot_protobuf_dot_descriptor__pb2._FILEDESCRIPTORPROTO
+_CODEGENERATORRESPONSE_FILE.containing_type = _CODEGENERATORRESPONSE
 _CODEGENERATORRESPONSE.fields_by_name['file'].message_type = _CODEGENERATORRESPONSE_FILE
 DESCRIPTOR.message_types_by_name['CodeGeneratorRequest'] = _CODEGENERATORREQUEST
 DESCRIPTOR.message_types_by_name['CodeGeneratorResponse'] = _CODEGENERATORRESPONSE
 
-class CodeGeneratorRequest(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _CODEGENERATORREQUEST
-
+CodeGeneratorRequest = _reflection.GeneratedProtocolMessageType('CodeGeneratorRequest', (_message.Message,), dict(
+  DESCRIPTOR = _CODEGENERATORREQUEST,
+  __module__ = 'google.protobuf.compiler.plugin_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
+  ))
+_sym_db.RegisterMessage(CodeGeneratorRequest)
 
-class CodeGeneratorResponse(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
+CodeGeneratorResponse = _reflection.GeneratedProtocolMessageType('CodeGeneratorResponse', (_message.Message,), dict(
 
-  class File(_message.Message):
-    __metaclass__ = _reflection.GeneratedProtocolMessageType
-    DESCRIPTOR = _CODEGENERATORRESPONSE_FILE
-
+  File = _reflection.GeneratedProtocolMessageType('File', (_message.Message,), dict(
+    DESCRIPTOR = _CODEGENERATORRESPONSE_FILE,
+    __module__ = 'google.protobuf.compiler.plugin_pb2'
     # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
-  DESCRIPTOR = _CODEGENERATORRESPONSE
-
+    ))
+  ,
+  DESCRIPTOR = _CODEGENERATORRESPONSE,
+  __module__ = 'google.protobuf.compiler.plugin_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
+  ))
+_sym_db.RegisterMessage(CodeGeneratorResponse)
+_sym_db.RegisterMessage(CodeGeneratorResponse.File)
 
 
 DESCRIPTOR.has_options = True
-DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), '\n\034com.google.protobuf.compilerB\014PluginProtos')
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\034com.google.protobuf.compilerB\014PluginProtosZ\tplugin_go'))
 # @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/descriptor.py b/generator/google/protobuf/descriptor.py
index eb13eda..873af30 100644
--- a/generator/google/protobuf/descriptor.py
+++ b/generator/google/protobuf/descriptor.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -34,15 +34,17 @@
 
 __author__ = 'robinson@google.com (Will Robinson)'
 
+import six
 
 from google.protobuf.internal import api_implementation
 
-
+_USE_C_DESCRIPTORS = False
 if api_implementation.Type() == 'cpp':
-  if api_implementation.Version() == 2:
-    from google.protobuf.internal.cpp import _message
-  else:
-    from google.protobuf.internal import cpp_message
+  # Used by MakeDescriptor in cpp mode
+  import os
+  import uuid
+  from google.protobuf.pyext import _message
+  _USE_C_DESCRIPTORS = getattr(_message, '_USE_C_DESCRIPTORS', False)
 
 
 class Error(Exception):
@@ -53,12 +55,29 @@
   """Error transforming between python proto type and corresponding C++ type."""
 
 
-class DescriptorBase(object):
+if _USE_C_DESCRIPTORS:
+  # This metaclass allows to override the behavior of code like
+  #     isinstance(my_descriptor, FieldDescriptor)
+  # and make it return True when the descriptor is an instance of the extension
+  # type written in C++.
+  class DescriptorMetaclass(type):
+    def __instancecheck__(cls, obj):
+      if super(DescriptorMetaclass, cls).__instancecheck__(obj):
+        return True
+      if isinstance(obj, cls._C_DESCRIPTOR_CLASS):
+        return True
+      return False
+else:
+  # The standard metaclass; nothing changes.
+  DescriptorMetaclass = type
+
+
+class DescriptorBase(six.with_metaclass(DescriptorMetaclass)):
 
   """Descriptors base class.
 
   This class is the base of all descriptor classes. It provides common options
-  related functionaility.
+  related functionality.
 
   Attributes:
     has_options:  True if the descriptor has non-default options.  Usually it
@@ -68,6 +87,11 @@
         avoid some bootstrapping issues.
   """
 
+  if _USE_C_DESCRIPTORS:
+    # The class, or tuple of classes, that are considered as "virtual
+    # subclasses" of this descriptor class.
+    _C_DESCRIPTOR_CLASS = ()
+
   def __init__(self, options, options_class_name):
     """Initialize the descriptor given its options message and the name of the
     class of the options message. The name of the class is required in case
@@ -194,6 +218,9 @@
     fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor
       objects as in |fields|, but indexed by "name" attribute in each
       FieldDescriptor.
+    fields_by_camelcase_name: (dict str -> FieldDescriptor) Same
+      FieldDescriptor objects as in |fields|, but indexed by
+      "camelcase_name" attribute in each FieldDescriptor.
 
     nested_types: (list of Descriptors) Descriptor references
       for all protocol message types nested within this one.
@@ -217,16 +244,33 @@
 
     is_extendable:  Does this type define any extension ranges?
 
-    options: (descriptor_pb2.MessageOptions) Protocol message options or None
-      to use default message options.
+    oneofs: (list of OneofDescriptor) The list of descriptors for oneof fields
+      in this message.
+    oneofs_by_name: (dict str -> OneofDescriptor) Same objects as in |oneofs|,
+      but indexed by "name" attribute.
 
     file: (FileDescriptor) Reference to file descriptor.
   """
 
+  if _USE_C_DESCRIPTORS:
+    _C_DESCRIPTOR_CLASS = _message.Descriptor
+
+    def __new__(cls, name, full_name, filename, containing_type, fields,
+                nested_types, enum_types, extensions, options=None,
+                is_extendable=True, extension_ranges=None, oneofs=None,
+                file=None, serialized_start=None, serialized_end=None,  # pylint: disable=redefined-builtin
+                syntax=None):
+      _message.Message._CheckCalledFromGeneratedFile()
+      return _message.default_pool.FindMessageTypeByName(full_name)
+
+  # NOTE(tmarek): The file argument redefining a builtin is nothing we can
+  # fix right now since we don't know how many clients already rely on the
+  # name of the argument.
   def __init__(self, name, full_name, filename, containing_type, fields,
                nested_types, enum_types, extensions, options=None,
-               is_extendable=True, extension_ranges=None, file=None,
-               serialized_start=None, serialized_end=None):
+               is_extendable=True, extension_ranges=None, oneofs=None,
+               file=None, serialized_start=None, serialized_end=None,  # pylint: disable=redefined-builtin
+               syntax=None):
     """Arguments to __init__() are as described in the description
     of Descriptor fields above.
 
@@ -236,7 +280,7 @@
     super(Descriptor, self).__init__(
         options, 'MessageOptions', name, full_name, file,
         containing_type, serialized_start=serialized_start,
-        serialized_end=serialized_start)
+        serialized_end=serialized_end)
 
     # We have fields in addition to fields_by_name and fields_by_number,
     # so that:
@@ -248,8 +292,11 @@
       field.containing_type = self
     self.fields_by_number = dict((f.number, f) for f in fields)
     self.fields_by_name = dict((f.name, f) for f in fields)
+    self._fields_by_camelcase_name = None
 
     self.nested_types = nested_types
+    for nested_type in nested_types:
+      nested_type.containing_type = self
     self.nested_types_by_name = dict((t.name, t) for t in nested_types)
 
     self.enum_types = enum_types
@@ -265,9 +312,18 @@
     self.extensions_by_name = dict((f.name, f) for f in extensions)
     self.is_extendable = is_extendable
     self.extension_ranges = extension_ranges
+    self.oneofs = oneofs if oneofs is not None else []
+    self.oneofs_by_name = dict((o.name, o) for o in self.oneofs)
+    for oneof in self.oneofs:
+      oneof.containing_type = self
+    self.syntax = syntax or "proto2"
 
-    self._serialized_start = serialized_start
-    self._serialized_end = serialized_end
+  @property
+  def fields_by_camelcase_name(self):
+    if self._fields_by_camelcase_name is None:
+      self._fields_by_camelcase_name = dict(
+          (f.camelcase_name, f) for f in self.fields)
+    return self._fields_by_camelcase_name
 
   def EnumValueName(self, enum, value):
     """Returns the string name of an enum value.
@@ -293,7 +349,7 @@
     Args:
       proto: An empty descriptor_pb2.DescriptorProto.
     """
-    # This function is overriden to give a better doc comment.
+    # This function is overridden to give a better doc comment.
     super(Descriptor, self).CopyToProto(proto)
 
 
@@ -317,6 +373,7 @@
     name: (str) Name of this field, exactly as it appears in .proto.
     full_name: (str) Name of this field, including containing scope.  This is
       particularly relevant for extensions.
+    camelcase_name: (str) Camelcase name of this field.
     index: (int) Dense, 0-indexed index giving the order that this
       field textually appears within its message in the .proto file.
     number: (int) Tag number declared for this field in the .proto file.
@@ -353,6 +410,9 @@
 
     options: (descriptor_pb2.FieldOptions) Protocol message field options or
       None to use default field options.
+
+    containing_oneof: (OneofDescriptor) If the field is a member of a oneof
+      union, contains its descriptor. Otherwise, None.
   """
 
   # Must be consistent with C++ FieldDescriptor::Type enum in
@@ -425,10 +485,29 @@
   LABEL_REPEATED      = 3
   MAX_LABEL           = 3
 
+  # Must be consistent with C++ constants kMaxNumber, kFirstReservedNumber,
+  # and kLastReservedNumber in descriptor.h
+  MAX_FIELD_NUMBER = (1 << 29) - 1
+  FIRST_RESERVED_FIELD_NUMBER = 19000
+  LAST_RESERVED_FIELD_NUMBER = 19999
+
+  if _USE_C_DESCRIPTORS:
+    _C_DESCRIPTOR_CLASS = _message.FieldDescriptor
+
+    def __new__(cls, name, full_name, index, number, type, cpp_type, label,
+                default_value, message_type, enum_type, containing_type,
+                is_extension, extension_scope, options=None,
+                has_default_value=True, containing_oneof=None):
+      _message.Message._CheckCalledFromGeneratedFile()
+      if is_extension:
+        return _message.default_pool.FindExtensionByName(full_name)
+      else:
+        return _message.default_pool.FindFieldByName(full_name)
+
   def __init__(self, name, full_name, index, number, type, cpp_type, label,
                default_value, message_type, enum_type, containing_type,
                is_extension, extension_scope, options=None,
-               has_default_value=True):
+               has_default_value=True, containing_oneof=None):
     """The arguments are as described in the description of FieldDescriptor
     attributes above.
 
@@ -439,6 +518,7 @@
     super(FieldDescriptor, self).__init__(options, 'FieldOptions')
     self.name = name
     self.full_name = full_name
+    self._camelcase_name = None
     self.index = index
     self.number = number
     self.type = type
@@ -451,20 +531,21 @@
     self.enum_type = enum_type
     self.is_extension = is_extension
     self.extension_scope = extension_scope
+    self.containing_oneof = containing_oneof
     if api_implementation.Type() == 'cpp':
       if is_extension:
-        if api_implementation.Version() == 2:
-          self._cdescriptor = _message.GetExtensionDescriptor(full_name)
-        else:
-          self._cdescriptor = cpp_message.GetExtensionDescriptor(full_name)
+        self._cdescriptor = _message.default_pool.FindExtensionByName(full_name)
       else:
-        if api_implementation.Version() == 2:
-          self._cdescriptor = _message.GetFieldDescriptor(full_name)
-        else:
-          self._cdescriptor = cpp_message.GetFieldDescriptor(full_name)
+        self._cdescriptor = _message.default_pool.FindFieldByName(full_name)
     else:
       self._cdescriptor = None
 
+  @property
+  def camelcase_name(self):
+    if self._camelcase_name is None:
+      self._camelcase_name = _ToCamelCase(self.name)
+    return self._camelcase_name
+
   @staticmethod
   def ProtoTypeToCppProtoType(proto_type):
     """Converts from a Python proto type to a C++ Proto Type.
@@ -511,6 +592,15 @@
       None to use default enum options.
   """
 
+  if _USE_C_DESCRIPTORS:
+    _C_DESCRIPTOR_CLASS = _message.EnumDescriptor
+
+    def __new__(cls, name, full_name, filename, values,
+                containing_type=None, options=None, file=None,
+                serialized_start=None, serialized_end=None):
+      _message.Message._CheckCalledFromGeneratedFile()
+      return _message.default_pool.FindEnumTypeByName(full_name)
+
   def __init__(self, name, full_name, filename, values,
                containing_type=None, options=None, file=None,
                serialized_start=None, serialized_end=None):
@@ -522,7 +612,7 @@
     super(EnumDescriptor, self).__init__(
         options, 'EnumOptions', name, full_name, file,
         containing_type, serialized_start=serialized_start,
-        serialized_end=serialized_start)
+        serialized_end=serialized_end)
 
     self.values = values
     for value in self.values:
@@ -530,16 +620,13 @@
     self.values_by_name = dict((v.name, v) for v in values)
     self.values_by_number = dict((v.number, v) for v in values)
 
-    self._serialized_start = serialized_start
-    self._serialized_end = serialized_end
-
   def CopyToProto(self, proto):
     """Copies this to a descriptor_pb2.EnumDescriptorProto.
 
     Args:
       proto: An empty descriptor_pb2.EnumDescriptorProto.
     """
-    # This function is overriden to give a better doc comment.
+    # This function is overridden to give a better doc comment.
     super(EnumDescriptor, self).CopyToProto(proto)
 
 
@@ -558,6 +645,17 @@
       None to use default enum value options options.
   """
 
+  if _USE_C_DESCRIPTORS:
+    _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor
+
+    def __new__(cls, name, index, number, type=None, options=None):
+      _message.Message._CheckCalledFromGeneratedFile()
+      # There is no way we can build a complete EnumValueDescriptor with the
+      # given parameters (the name of the Enum is not known, for example).
+      # Fortunately generated files just pass it to the EnumDescriptor()
+      # constructor, which will ignore it, so returning None is good enough.
+      return None
+
   def __init__(self, name, index, number, type=None, options=None):
     """Arguments are as described in the attribute description above."""
     super(EnumValueDescriptor, self).__init__(options, 'EnumValueOptions')
@@ -567,6 +665,39 @@
     self.type = type
 
 
+class OneofDescriptor(DescriptorBase):
+  """Descriptor for a oneof field.
+
+    name: (str) Name of the oneof field.
+    full_name: (str) Full name of the oneof field, including package name.
+    index: (int) 0-based index giving the order of the oneof field inside
+      its containing type.
+    containing_type: (Descriptor) Descriptor of the protocol message
+      type that contains this field.  Set by the Descriptor constructor
+      if we're passed into one.
+    fields: (list of FieldDescriptor) The list of field descriptors this
+      oneof can contain.
+  """
+
+  if _USE_C_DESCRIPTORS:
+    _C_DESCRIPTOR_CLASS = _message.OneofDescriptor
+
+    def __new__(
+        cls, name, full_name, index, containing_type, fields, options=None):
+      _message.Message._CheckCalledFromGeneratedFile()
+      return _message.default_pool.FindOneofByName(full_name)
+
+  def __init__(
+      self, name, full_name, index, containing_type, fields, options=None):
+    """Arguments are as described in the attribute description above."""
+    super(OneofDescriptor, self).__init__(options, 'OneofOptions')
+    self.name = name
+    self.full_name = full_name
+    self.index = index
+    self.containing_type = containing_type
+    self.fields = fields
+
+
 class ServiceDescriptor(_NestedDescriptorBase):
 
   """Descriptor for a service.
@@ -577,11 +708,22 @@
       definition appears withing the .proto file.
     methods: (list of MethodDescriptor) List of methods provided by this
       service.
+    methods_by_name: (dict str -> MethodDescriptor) Same MethodDescriptor
+      objects as in |methods_by_name|, but indexed by "name" attribute in each
+      MethodDescriptor.
     options: (descriptor_pb2.ServiceOptions) Service options message or
       None to use default service options.
     file: (FileDescriptor) Reference to file info.
   """
 
+  if _USE_C_DESCRIPTORS:
+    _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor
+
+    def __new__(cls, name, full_name, index, methods, options=None, file=None,  # pylint: disable=redefined-builtin
+                serialized_start=None, serialized_end=None):
+      _message.Message._CheckCalledFromGeneratedFile()  # pylint: disable=protected-access
+      return _message.default_pool.FindServiceByName(full_name)
+
   def __init__(self, name, full_name, index, methods, options=None, file=None,
                serialized_start=None, serialized_end=None):
     super(ServiceDescriptor, self).__init__(
@@ -590,16 +732,14 @@
         serialized_end=serialized_end)
     self.index = index
     self.methods = methods
+    self.methods_by_name = dict((m.name, m) for m in methods)
     # Set the containing service for each method in this service.
     for method in self.methods:
       method.containing_service = self
 
   def FindMethodByName(self, name):
     """Searches for the specified method, and returns its descriptor."""
-    for method in self.methods:
-      if name == method.name:
-        return method
-    return None
+    return self.methods_by_name.get(name, None)
 
   def CopyToProto(self, proto):
     """Copies this to a descriptor_pb2.ServiceDescriptorProto.
@@ -607,7 +747,7 @@
     Args:
       proto: An empty descriptor_pb2.ServiceDescriptorProto.
     """
-    # This function is overriden to give a better doc comment.
+    # This function is overridden to give a better doc comment.
     super(ServiceDescriptor, self).CopyToProto(proto)
 
 
@@ -626,6 +766,14 @@
     None to use default method options.
   """
 
+  if _USE_C_DESCRIPTORS:
+    _C_DESCRIPTOR_CLASS = _message.MethodDescriptor
+
+    def __new__(cls, name, full_name, index, containing_service,
+                input_type, output_type, options=None):
+      _message.Message._CheckCalledFromGeneratedFile()  # pylint: disable=protected-access
+      return _message.default_pool.FindMethodByName(full_name)
+
   def __init__(self, name, full_name, index, containing_service,
                input_type, output_type, options=None):
     """The arguments are as described in the description of MethodDescriptor
@@ -645,26 +793,66 @@
 class FileDescriptor(DescriptorBase):
   """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto.
 
+  Note that enum_types_by_name, extensions_by_name, and dependencies
+  fields are only set by the message_factory module, and not by the
+  generated proto code.
+
   name: name of file, relative to root of source tree.
   package: name of the package
+  syntax: string indicating syntax of the file (can be "proto2" or "proto3")
   serialized_pb: (str) Byte string of serialized
     descriptor_pb2.FileDescriptorProto.
+  dependencies: List of other FileDescriptors this FileDescriptor depends on.
+  public_dependencies: A list of FileDescriptors, subset of the dependencies
+    above, which were declared as "public".
+  message_types_by_name: Dict of message names of their descriptors.
+  enum_types_by_name: Dict of enum names and their descriptors.
+  extensions_by_name: Dict of extension names and their descriptors.
+  services_by_name: Dict of services names and their descriptors.
+  pool: the DescriptorPool this descriptor belongs to.  When not passed to the
+    constructor, the global default pool is used.
   """
 
-  def __init__(self, name, package, options=None, serialized_pb=None):
+  if _USE_C_DESCRIPTORS:
+    _C_DESCRIPTOR_CLASS = _message.FileDescriptor
+
+    def __new__(cls, name, package, options=None, serialized_pb=None,
+                dependencies=None, public_dependencies=None,
+                syntax=None, pool=None):
+      # FileDescriptor() is called from various places, not only from generated
+      # files, to register dynamic proto files and messages.
+      if serialized_pb:
+        # TODO(amauryfa): use the pool passed as argument. This will work only
+        # for C++-implemented DescriptorPools.
+        return _message.default_pool.AddSerializedFile(serialized_pb)
+      else:
+        return super(FileDescriptor, cls).__new__(cls)
+
+  def __init__(self, name, package, options=None, serialized_pb=None,
+               dependencies=None, public_dependencies=None,
+               syntax=None, pool=None):
     """Constructor."""
     super(FileDescriptor, self).__init__(options, 'FileOptions')
 
+    if pool is None:
+      from google.protobuf import descriptor_pool
+      pool = descriptor_pool.Default()
+    self.pool = pool
     self.message_types_by_name = {}
     self.name = name
     self.package = package
+    self.syntax = syntax or "proto2"
     self.serialized_pb = serialized_pb
+
+    self.enum_types_by_name = {}
+    self.extensions_by_name = {}
+    self.services_by_name = {}
+    self.dependencies = (dependencies or [])
+    self.public_dependencies = (public_dependencies or [])
+
     if (api_implementation.Type() == 'cpp' and
         self.serialized_pb is not None):
-      if api_implementation.Version() == 2:
-        _message.BuildFile(self.serialized_pb)
-      else:
-        cpp_message.BuildFile(self.serialized_pb)
+      _message.default_pool.AddSerializedFile(self.serialized_pb)
 
   def CopyToProto(self, proto):
     """Copies this to a descriptor_pb2.FileDescriptorProto.
@@ -685,29 +873,121 @@
   return message
 
 
-def MakeDescriptor(desc_proto, package=''):
+def _ToCamelCase(name):
+  """Converts name to camel-case and returns it."""
+  capitalize_next = False
+  result = []
+
+  for c in name:
+    if c == '_':
+      if result:
+        capitalize_next = True
+    elif capitalize_next:
+      result.append(c.upper())
+      capitalize_next = False
+    else:
+      result += c
+
+  # Lower-case the first letter.
+  if result and result[0].isupper():
+    result[0] = result[0].lower()
+  return ''.join(result)
+
+
+def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True,
+                   syntax=None):
   """Make a protobuf Descriptor given a DescriptorProto protobuf.
 
+  Handles nested descriptors. Note that this is limited to the scope of defining
+  a message inside of another message. Composite fields can currently only be
+  resolved if the message is defined in the same scope as the field.
+
   Args:
     desc_proto: The descriptor_pb2.DescriptorProto protobuf message.
     package: Optional package name for the new message Descriptor (string).
-
+    build_file_if_cpp: Update the C++ descriptor pool if api matches.
+                       Set to False on recursion, so no duplicates are created.
+    syntax: The syntax/semantics that should be used.  Set to "proto3" to get
+            proto3 field presence semantics.
   Returns:
     A Descriptor for protobuf messages.
   """
+  if api_implementation.Type() == 'cpp' and build_file_if_cpp:
+    # The C++ implementation requires all descriptors to be backed by the same
+    # definition in the C++ descriptor pool. To do this, we build a
+    # FileDescriptorProto with the same definition as this descriptor and build
+    # it into the pool.
+    from google.protobuf import descriptor_pb2
+    file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
+    file_descriptor_proto.message_type.add().MergeFrom(desc_proto)
+
+    # Generate a random name for this proto file to prevent conflicts with any
+    # imported ones. We need to specify a file name so the descriptor pool
+    # accepts our FileDescriptorProto, but it is not important what that file
+    # name is actually set to.
+    proto_name = str(uuid.uuid4())
+
+    if package:
+      file_descriptor_proto.name = os.path.join(package.replace('.', '/'),
+                                                proto_name + '.proto')
+      file_descriptor_proto.package = package
+    else:
+      file_descriptor_proto.name = proto_name + '.proto'
+
+    _message.default_pool.Add(file_descriptor_proto)
+    result = _message.default_pool.FindFileByName(file_descriptor_proto.name)
+
+    if _USE_C_DESCRIPTORS:
+      return result.message_types_by_name[desc_proto.name]
+
   full_message_name = [desc_proto.name]
   if package: full_message_name.insert(0, package)
+
+  # Create Descriptors for enum types
+  enum_types = {}
+  for enum_proto in desc_proto.enum_type:
+    full_name = '.'.join(full_message_name + [enum_proto.name])
+    enum_desc = EnumDescriptor(
+      enum_proto.name, full_name, None, [
+          EnumValueDescriptor(enum_val.name, ii, enum_val.number)
+          for ii, enum_val in enumerate(enum_proto.value)])
+    enum_types[full_name] = enum_desc
+
+  # Create Descriptors for nested types
+  nested_types = {}
+  for nested_proto in desc_proto.nested_type:
+    full_name = '.'.join(full_message_name + [nested_proto.name])
+    # Nested types are just those defined inside of the message, not all types
+    # used by fields in the message, so no loops are possible here.
+    nested_desc = MakeDescriptor(nested_proto,
+                                 package='.'.join(full_message_name),
+                                 build_file_if_cpp=False,
+                                 syntax=syntax)
+    nested_types[full_name] = nested_desc
+
   fields = []
   for field_proto in desc_proto.field:
     full_name = '.'.join(full_message_name + [field_proto.name])
+    enum_desc = None
+    nested_desc = None
+    if field_proto.HasField('type_name'):
+      type_name = field_proto.type_name
+      full_type_name = '.'.join(full_message_name +
+                                [type_name[type_name.rfind('.')+1:]])
+      if full_type_name in nested_types:
+        nested_desc = nested_types[full_type_name]
+      elif full_type_name in enum_types:
+        enum_desc = enum_types[full_type_name]
+      # Else type_name references a non-local type, which isn't implemented
     field = FieldDescriptor(
         field_proto.name, full_name, field_proto.number - 1,
         field_proto.number, field_proto.type,
         FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type),
-        field_proto.label, None, None, None, None, False, None,
-        has_default_value=False)
+        field_proto.label, None, nested_desc, enum_desc, None, False, None,
+        options=field_proto.options, has_default_value=False)
     fields.append(field)
 
   desc_name = '.'.join(full_message_name)
   return Descriptor(desc_proto.name, desc_name, None, None, fields,
-                    [], [], [])
+                    list(nested_types.values()), list(enum_types.values()), [],
+                    options=desc_proto.options)
diff --git a/generator/google/protobuf/descriptor_database.py b/generator/google/protobuf/descriptor_database.py
index 8665d3c..1333f99 100644
--- a/generator/google/protobuf/descriptor_database.py
+++ b/generator/google/protobuf/descriptor_database.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -33,6 +33,14 @@
 __author__ = 'matthewtoia@google.com (Matt Toia)'
 
 
+class Error(Exception):
+  pass
+
+
+class DescriptorDatabaseConflictingDefinitionError(Error):
+  """Raised when a proto is added with the same name & different descriptor."""
+
+
 class DescriptorDatabase(object):
   """A container accepting FileDescriptorProtos and maps DescriptorProtos."""
 
@@ -45,9 +53,19 @@
 
     Args:
       file_desc_proto: The FileDescriptorProto to add.
+    Raises:
+      DescriptorDatabaseException: if an attempt is made to add a proto
+        with the same name but different definition than an exisiting
+        proto in the database.
     """
+    proto_name = file_desc_proto.name
+    if proto_name not in self._file_desc_protos_by_file:
+      self._file_desc_protos_by_file[proto_name] = file_desc_proto
+    elif self._file_desc_protos_by_file[proto_name] != file_desc_proto:
+      raise DescriptorDatabaseConflictingDefinitionError(
+          '%s already added, but with different descriptor.' % proto_name)
 
-    self._file_desc_protos_by_file[file_desc_proto.name] = file_desc_proto
+    # Add the top-level Message, Enum and Extension descriptors to the index.
     package = file_desc_proto.package
     for message in file_desc_proto.message_type:
       self._file_desc_protos_by_symbol.update(
@@ -55,6 +73,9 @@
     for enum in file_desc_proto.enum_type:
       self._file_desc_protos_by_symbol[
           '.'.join((package, enum.name))] = file_desc_proto
+    for extension in file_desc_proto.extension:
+      self._file_desc_protos_by_symbol[
+          '.'.join((package, extension.name))] = file_desc_proto
 
   def FindFileByName(self, name):
     """Finds the file descriptor proto by file name.
@@ -116,5 +137,5 @@
   for nested_type in desc_proto.nested_type:
     for symbol in _ExtractSymbols(nested_type, message_name):
       yield symbol
-    for enum_type in desc_proto.enum_type:
-      yield '.'.join((message_name, enum_type.name))
+  for enum_type in desc_proto.enum_type:
+    yield '.'.join((message_name, enum_type.name))
diff --git a/generator/google/protobuf/descriptor_pb2.py b/generator/google/protobuf/descriptor_pb2.py
index 20b2d94..3d2964a 100644
--- a/generator/google/protobuf/descriptor_pb2.py
+++ b/generator/google/protobuf/descriptor_pb2.py
@@ -1,18 +1,26 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # source: google/protobuf/descriptor.proto
 
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
 from google.protobuf import descriptor as _descriptor
 from google.protobuf import message as _message
 from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
 # @@protoc_insertion_point(imports)
 
+_sym_db = _symbol_database.Default()
+
 
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
   name='google/protobuf/descriptor.proto',
   package='google.protobuf',
-  serialized_pb='\n google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"G\n\x11\x46ileDescriptorSet\x12\x32\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xcb\x03\n\x13\x46ileDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07package\x18\x02 \x01(\t\x12\x12\n\ndependency\x18\x03 \x03(\t\x12\x19\n\x11public_dependency\x18\n \x03(\x05\x12\x17\n\x0fweak_dependency\x18\x0b \x03(\x05\x12\x36\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x05 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12\x38\n\x07service\x18\x06 \x03(\x0b\x32\'.google.protobuf.ServiceDescriptorProto\x12\x38\n\textension\x18\x07 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12-\n\x07options\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.FileOptions\x12\x39\n\x10source_code_info\x18\t \x01(\x0b\x32\x1f.google.protobuf.SourceCodeInfo\"\xa9\x03\n\x0f\x44\x65scriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x34\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x38\n\textension\x18\x06 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x35\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x04 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12H\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32/.google.protobuf.DescriptorProto.ExtensionRange\x12\x30\n\x07options\x18\x07 \x01(\x0b\x32\x1f.google.protobuf.MessageOptions\x1a,\n\x0e\x45xtensionRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"\x94\x05\n\x14\x46ieldDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12:\n\x05label\x18\x04 \x01(\x0e\x32+.google.protobuf.FieldDescriptorProto.Label\x12\x38\n\x04type\x18\x05 \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x11\n\ttype_name\x18\x06 \x01(\t\x12\x10\n\x08\x65xtendee\x18\x02 \x01(\t\x12\x15\n\rdefault_value\x18\x07 \x01(\t\x12.\n\x07options\x18\x08 \x01(\x0b\x32\x1d.google.protobuf.FieldOptions\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\x12\x12\n\x0eLABEL_REPEATED\x10\x03\"\x8c\x01\n\x13\x45numDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x38\n\x05value\x18\x02 \x03(\x0b\x32).google.protobuf.EnumValueDescriptorProto\x12-\n\x07options\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.EnumOptions\"l\n\x18\x45numValueDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12\x32\n\x07options\x18\x03 \x01(\x0b\x32!.google.protobuf.EnumValueOptions\"\x90\x01\n\x16ServiceDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x36\n\x06method\x18\x02 \x03(\x0b\x32&.google.protobuf.MethodDescriptorProto\x12\x30\n\x07options\x18\x03 \x01(\x0b\x32\x1f.google.protobuf.ServiceOptions\"\x7f\n\x15MethodDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\ninput_type\x18\x02 \x01(\t\x12\x13\n\x0boutput_type\x18\x03 \x01(\t\x12/\n\x07options\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.MethodOptions\"\xe9\x03\n\x0b\x46ileOptions\x12\x14\n\x0cjava_package\x18\x01 \x01(\t\x12\x1c\n\x14java_outer_classname\x18\x08 \x01(\t\x12\"\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lse\x12,\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08:\x05\x66\x61lse\x12\x46\n\x0coptimize_for\x18\t \x01(\x0e\x32).google.protobuf.FileOptions.OptimizeMode:\x05SPEED\x12\x12\n\ngo_package\x18\x0b \x01(\t\x12\"\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lse\x12$\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lse\x12\"\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xb8\x01\n\x0eMessageOptions\x12&\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lse\x12.\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xbe\x02\n\x0c\x46ieldOptions\x12:\n\x05\x63type\x18\x01 \x01(\x0e\x32#.google.protobuf.FieldOptions.CType:\x06STRING\x12\x0e\n\x06packed\x18\x02 \x01(\x08\x12\x13\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x1c\n\x14\x65xperimental_map_key\x18\t \x01(\t\x12\x13\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"x\n\x0b\x45numOptions\x12\x19\n\x0b\x61llow_alias\x18\x02 \x01(\x08:\x04true\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"b\n\x10\x45numValueOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"`\n\x0eServiceOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"_\n\rMethodOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x9e\x02\n\x13UninterpretedOption\x12;\n\x04name\x18\x02 \x03(\x0b\x32-.google.protobuf.UninterpretedOption.NamePart\x12\x18\n\x10identifier_value\x18\x03 \x01(\t\x12\x1a\n\x12positive_int_value\x18\x04 \x01(\x04\x12\x1a\n\x12negative_int_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x14\n\x0cstring_value\x18\x07 \x01(\x0c\x12\x17\n\x0f\x61ggregate_value\x18\x08 \x01(\t\x1a\x33\n\x08NamePart\x12\x11\n\tname_part\x18\x01 \x02(\t\x12\x14\n\x0cis_extension\x18\x02 \x02(\x08\"\xb1\x01\n\x0eSourceCodeInfo\x12:\n\x08location\x18\x01 \x03(\x0b\x32(.google.protobuf.SourceCodeInfo.Location\x1a\x63\n\x08Location\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x10\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01\x12\x18\n\x10leading_comments\x18\x03 \x01(\t\x12\x19\n\x11trailing_comments\x18\x04 \x01(\tB)\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01')
+  syntax='proto2',
+  serialized_pb=_b('\n google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"G\n\x11\x46ileDescriptorSet\x12\x32\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xdb\x03\n\x13\x46ileDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07package\x18\x02 \x01(\t\x12\x12\n\ndependency\x18\x03 \x03(\t\x12\x19\n\x11public_dependency\x18\n \x03(\x05\x12\x17\n\x0fweak_dependency\x18\x0b \x03(\x05\x12\x36\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x05 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12\x38\n\x07service\x18\x06 \x03(\x0b\x32\'.google.protobuf.ServiceDescriptorProto\x12\x38\n\textension\x18\x07 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12-\n\x07options\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.FileOptions\x12\x39\n\x10source_code_info\x18\t \x01(\x0b\x32\x1f.google.protobuf.SourceCodeInfo\x12\x0e\n\x06syntax\x18\x0c \x01(\t\"\xf0\x04\n\x0f\x44\x65scriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x34\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x38\n\textension\x18\x06 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x35\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x04 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12H\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32/.google.protobuf.DescriptorProto.ExtensionRange\x12\x39\n\noneof_decl\x18\x08 \x03(\x0b\x32%.google.protobuf.OneofDescriptorProto\x12\x30\n\x07options\x18\x07 \x01(\x0b\x32\x1f.google.protobuf.MessageOptions\x12\x46\n\x0ereserved_range\x18\t \x03(\x0b\x32..google.protobuf.DescriptorProto.ReservedRange\x12\x15\n\rreserved_name\x18\n \x03(\t\x1a,\n\x0e\x45xtensionRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\x1a+\n\rReservedRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"\xbc\x05\n\x14\x46ieldDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12:\n\x05label\x18\x04 \x01(\x0e\x32+.google.protobuf.FieldDescriptorProto.Label\x12\x38\n\x04type\x18\x05 \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x11\n\ttype_name\x18\x06 \x01(\t\x12\x10\n\x08\x65xtendee\x18\x02 \x01(\t\x12\x15\n\rdefault_value\x18\x07 \x01(\t\x12\x13\n\x0boneof_index\x18\t \x01(\x05\x12\x11\n\tjson_name\x18\n \x01(\t\x12.\n\x07options\x18\x08 \x01(\x0b\x32\x1d.google.protobuf.FieldOptions\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\x12\x12\n\x0eLABEL_REPEATED\x10\x03\"T\n\x14OneofDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12.\n\x07options\x18\x02 \x01(\x0b\x32\x1d.google.protobuf.OneofOptions\"\x8c\x01\n\x13\x45numDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x38\n\x05value\x18\x02 \x03(\x0b\x32).google.protobuf.EnumValueDescriptorProto\x12-\n\x07options\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.EnumOptions\"l\n\x18\x45numValueDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12\x32\n\x07options\x18\x03 \x01(\x0b\x32!.google.protobuf.EnumValueOptions\"\x90\x01\n\x16ServiceDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x36\n\x06method\x18\x02 \x03(\x0b\x32&.google.protobuf.MethodDescriptorProto\x12\x30\n\x07options\x18\x03 \x01(\x0b\x32\x1f.google.protobuf.ServiceOptions\"\xc1\x01\n\x15MethodDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\ninput_type\x18\x02 \x01(\t\x12\x13\n\x0boutput_type\x18\x03 \x01(\t\x12/\n\x07options\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.MethodOptions\x12\x1f\n\x10\x63lient_streaming\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1f\n\x10server_streaming\x18\x06 \x01(\x08:\x05\x66\x61lse\"\x87\x05\n\x0b\x46ileOptions\x12\x14\n\x0cjava_package\x18\x01 \x01(\t\x12\x1c\n\x14java_outer_classname\x18\x08 \x01(\t\x12\"\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lse\x12,\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08:\x05\x66\x61lse\x12%\n\x16java_string_check_utf8\x18\x1b \x01(\x08:\x05\x66\x61lse\x12\x46\n\x0coptimize_for\x18\t \x01(\x0e\x32).google.protobuf.FileOptions.OptimizeMode:\x05SPEED\x12\x12\n\ngo_package\x18\x0b \x01(\t\x12\"\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lse\x12$\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lse\x12\"\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x1f\n\x10\x63\x63_enable_arenas\x18\x1f \x01(\x08:\x05\x66\x61lse\x12\x19\n\x11objc_class_prefix\x18$ \x01(\t\x12\x18\n\x10\x63sharp_namespace\x18% \x01(\t\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08&\x10\'\"\xe6\x01\n\x0eMessageOptions\x12&\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lse\x12.\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x11\n\tmap_entry\x18\x07 \x01(\x08\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x98\x03\n\x0c\x46ieldOptions\x12:\n\x05\x63type\x18\x01 \x01(\x0e\x32#.google.protobuf.FieldOptions.CType:\x06STRING\x12\x0e\n\x06packed\x18\x02 \x01(\x08\x12?\n\x06jstype\x18\x06 \x01(\x0e\x32$.google.protobuf.FieldOptions.JSType:\tJS_NORMAL\x12\x13\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x13\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02\"5\n\x06JSType\x12\r\n\tJS_NORMAL\x10\x00\x12\r\n\tJS_STRING\x10\x01\x12\r\n\tJS_NUMBER\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"^\n\x0cOneofOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x8d\x01\n\x0b\x45numOptions\x12\x13\n\x0b\x61llow_alias\x18\x02 \x01(\x08\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"}\n\x10\x45numValueOptions\x12\x19\n\ndeprecated\x18\x01 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"{\n\x0eServiceOptions\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"z\n\rMethodOptions\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x9e\x02\n\x13UninterpretedOption\x12;\n\x04name\x18\x02 \x03(\x0b\x32-.google.protobuf.UninterpretedOption.NamePart\x12\x18\n\x10identifier_value\x18\x03 \x01(\t\x12\x1a\n\x12positive_int_value\x18\x04 \x01(\x04\x12\x1a\n\x12negative_int_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x14\n\x0cstring_value\x18\x07 \x01(\x0c\x12\x17\n\x0f\x61ggregate_value\x18\x08 \x01(\t\x1a\x33\n\x08NamePart\x12\x11\n\tname_part\x18\x01 \x02(\t\x12\x14\n\x0cis_extension\x18\x02 \x02(\x08\"\xd5\x01\n\x0eSourceCodeInfo\x12:\n\x08location\x18\x01 \x03(\x0b\x32(.google.protobuf.SourceCodeInfo.Location\x1a\x86\x01\n\x08Location\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x10\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01\x12\x18\n\x10leading_comments\x18\x03 \x01(\t\x12\x19\n\x11trailing_comments\x18\x04 \x01(\t\x12!\n\x19leading_detached_comments\x18\x06 \x03(\t\"\xa7\x01\n\x11GeneratedCodeInfo\x12\x41\n\nannotation\x18\x01 \x03(\x0b\x32-.google.protobuf.GeneratedCodeInfo.Annotation\x1aO\n\nAnnotation\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x13\n\x0bsource_file\x18\x02 \x01(\t\x12\r\n\x05\x62\x65gin\x18\x03 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x04 \x01(\x05\x42[\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01Z\ndescriptor\xa0\x01\x01\xa2\x02\x03GPB\xaa\x02\x1aGoogle.Protobuf.Reflection')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
 
 
@@ -97,9 +105,10 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=1298,
-  serialized_end=1608,
+  serialized_start=1553,
+  serialized_end=1863,
 )
+_sym_db.RegisterEnumDescriptor(_FIELDDESCRIPTORPROTO_TYPE)
 
 _FIELDDESCRIPTORPROTO_LABEL = _descriptor.EnumDescriptor(
   name='Label',
@@ -122,9 +131,10 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=1610,
-  serialized_end=1677,
+  serialized_start=1865,
+  serialized_end=1932,
 )
+_sym_db.RegisterEnumDescriptor(_FIELDDESCRIPTORPROTO_LABEL)
 
 _FILEOPTIONS_OPTIMIZEMODE = _descriptor.EnumDescriptor(
   name='OptimizeMode',
@@ -147,9 +157,10 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=2629,
-  serialized_end=2687,
+  serialized_start=3189,
+  serialized_end=3247,
 )
+_sym_db.RegisterEnumDescriptor(_FILEOPTIONS_OPTIMIZEMODE)
 
 _FIELDOPTIONS_CTYPE = _descriptor.EnumDescriptor(
   name='CType',
@@ -172,9 +183,36 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=3148,
-  serialized_end=3195,
+  serialized_start=3795,
+  serialized_end=3842,
 )
+_sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_CTYPE)
+
+_FIELDOPTIONS_JSTYPE = _descriptor.EnumDescriptor(
+  name='JSType',
+  full_name='google.protobuf.FieldOptions.JSType',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='JS_NORMAL', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='JS_STRING', index=1, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='JS_NUMBER', index=2, number=2,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=3844,
+  serialized_end=3897,
+)
+_sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_JSTYPE)
 
 
 _FILEDESCRIPTORSET = _descriptor.Descriptor(
@@ -199,7 +237,10 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
+  oneofs=[
+  ],
   serialized_start=53,
   serialized_end=124,
 )
@@ -215,14 +256,14 @@
     _descriptor.FieldDescriptor(
       name='name', full_name='google.protobuf.FileDescriptorProto.name', index=0,
       number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
       name='package', full_name='google.protobuf.FileDescriptorProto.package', index=1,
       number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -289,6 +330,13 @@
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
+    _descriptor.FieldDescriptor(
+      name='syntax', full_name='google.protobuf.FileDescriptorProto.syntax', index=11,
+      number=12, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
   ],
   extensions=[
   ],
@@ -297,9 +345,12 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
+  oneofs=[
+  ],
   serialized_start=127,
-  serialized_end=586,
+  serialized_end=602,
 )
 
 
@@ -332,9 +383,49 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=970,
-  serialized_end=1014,
+  oneofs=[
+  ],
+  serialized_start=1140,
+  serialized_end=1184,
+)
+
+_DESCRIPTORPROTO_RESERVEDRANGE = _descriptor.Descriptor(
+  name='ReservedRange',
+  full_name='google.protobuf.DescriptorProto.ReservedRange',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='start', full_name='google.protobuf.DescriptorProto.ReservedRange.start', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='end', full_name='google.protobuf.DescriptorProto.ReservedRange.end', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1186,
+  serialized_end=1229,
 )
 
 _DESCRIPTORPROTO = _descriptor.Descriptor(
@@ -347,7 +438,7 @@
     _descriptor.FieldDescriptor(
       name='name', full_name='google.protobuf.DescriptorProto.name', index=0,
       number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -387,23 +478,47 @@
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='options', full_name='google.protobuf.DescriptorProto.options', index=6,
+      name='oneof_decl', full_name='google.protobuf.DescriptorProto.oneof_decl', index=6,
+      number=8, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='options', full_name='google.protobuf.DescriptorProto.options', index=7,
       number=7, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
+    _descriptor.FieldDescriptor(
+      name='reserved_range', full_name='google.protobuf.DescriptorProto.reserved_range', index=8,
+      number=9, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='reserved_name', full_name='google.protobuf.DescriptorProto.reserved_name', index=9,
+      number=10, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
   ],
   extensions=[
   ],
-  nested_types=[_DESCRIPTORPROTO_EXTENSIONRANGE, ],
+  nested_types=[_DESCRIPTORPROTO_EXTENSIONRANGE, _DESCRIPTORPROTO_RESERVEDRANGE, ],
   enum_types=[
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=589,
-  serialized_end=1014,
+  oneofs=[
+  ],
+  serialized_start=605,
+  serialized_end=1229,
 )
 
 
@@ -417,7 +532,7 @@
     _descriptor.FieldDescriptor(
       name='name', full_name='google.protobuf.FieldDescriptorProto.name', index=0,
       number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -445,26 +560,40 @@
     _descriptor.FieldDescriptor(
       name='type_name', full_name='google.protobuf.FieldDescriptorProto.type_name', index=4,
       number=6, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
       name='extendee', full_name='google.protobuf.FieldDescriptorProto.extendee', index=5,
       number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
       name='default_value', full_name='google.protobuf.FieldDescriptorProto.default_value', index=6,
       number=7, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='options', full_name='google.protobuf.FieldDescriptorProto.options', index=7,
+      name='oneof_index', full_name='google.protobuf.FieldDescriptorProto.oneof_index', index=7,
+      number=9, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='json_name', full_name='google.protobuf.FieldDescriptorProto.json_name', index=8,
+      number=10, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='options', full_name='google.protobuf.FieldDescriptorProto.options', index=9,
       number=8, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -480,9 +609,50 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=1017,
-  serialized_end=1677,
+  oneofs=[
+  ],
+  serialized_start=1232,
+  serialized_end=1932,
+)
+
+
+_ONEOFDESCRIPTORPROTO = _descriptor.Descriptor(
+  name='OneofDescriptorProto',
+  full_name='google.protobuf.OneofDescriptorProto',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='google.protobuf.OneofDescriptorProto.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='options', full_name='google.protobuf.OneofDescriptorProto.options', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1934,
+  serialized_end=2018,
 )
 
 
@@ -496,7 +666,7 @@
     _descriptor.FieldDescriptor(
       name='name', full_name='google.protobuf.EnumDescriptorProto.name', index=0,
       number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -522,9 +692,12 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=1680,
-  serialized_end=1820,
+  oneofs=[
+  ],
+  serialized_start=2021,
+  serialized_end=2161,
 )
 
 
@@ -538,7 +711,7 @@
     _descriptor.FieldDescriptor(
       name='name', full_name='google.protobuf.EnumValueDescriptorProto.name', index=0,
       number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -564,9 +737,12 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=1822,
-  serialized_end=1930,
+  oneofs=[
+  ],
+  serialized_start=2163,
+  serialized_end=2271,
 )
 
 
@@ -580,7 +756,7 @@
     _descriptor.FieldDescriptor(
       name='name', full_name='google.protobuf.ServiceDescriptorProto.name', index=0,
       number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -606,9 +782,12 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=1933,
-  serialized_end=2077,
+  oneofs=[
+  ],
+  serialized_start=2274,
+  serialized_end=2418,
 )
 
 
@@ -622,21 +801,21 @@
     _descriptor.FieldDescriptor(
       name='name', full_name='google.protobuf.MethodDescriptorProto.name', index=0,
       number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
       name='input_type', full_name='google.protobuf.MethodDescriptorProto.input_type', index=1,
       number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
       name='output_type', full_name='google.protobuf.MethodDescriptorProto.output_type', index=2,
       number=3, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -647,6 +826,20 @@
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
+    _descriptor.FieldDescriptor(
+      name='client_streaming', full_name='google.protobuf.MethodDescriptorProto.client_streaming', index=4,
+      number=5, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='server_streaming', full_name='google.protobuf.MethodDescriptorProto.server_streaming', index=5,
+      number=6, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
   ],
   extensions=[
   ],
@@ -655,9 +848,12 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=2079,
-  serialized_end=2206,
+  oneofs=[
+  ],
+  serialized_start=2421,
+  serialized_end=2614,
 )
 
 
@@ -671,14 +867,14 @@
     _descriptor.FieldDescriptor(
       name='java_package', full_name='google.protobuf.FileOptions.java_package', index=0,
       number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
       name='java_outer_classname', full_name='google.protobuf.FileOptions.java_outer_classname', index=1,
       number=8, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -697,42 +893,77 @@
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='optimize_for', full_name='google.protobuf.FileOptions.optimize_for', index=4,
+      name='java_string_check_utf8', full_name='google.protobuf.FileOptions.java_string_check_utf8', index=4,
+      number=27, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optimize_for', full_name='google.protobuf.FileOptions.optimize_for', index=5,
       number=9, type=14, cpp_type=8, label=1,
       has_default_value=True, default_value=1,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='go_package', full_name='google.protobuf.FileOptions.go_package', index=5,
+      name='go_package', full_name='google.protobuf.FileOptions.go_package', index=6,
       number=11, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='cc_generic_services', full_name='google.protobuf.FileOptions.cc_generic_services', index=6,
+      name='cc_generic_services', full_name='google.protobuf.FileOptions.cc_generic_services', index=7,
       number=16, type=8, cpp_type=7, label=1,
       has_default_value=True, default_value=False,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='java_generic_services', full_name='google.protobuf.FileOptions.java_generic_services', index=7,
+      name='java_generic_services', full_name='google.protobuf.FileOptions.java_generic_services', index=8,
       number=17, type=8, cpp_type=7, label=1,
       has_default_value=True, default_value=False,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='py_generic_services', full_name='google.protobuf.FileOptions.py_generic_services', index=8,
+      name='py_generic_services', full_name='google.protobuf.FileOptions.py_generic_services', index=9,
       number=18, type=8, cpp_type=7, label=1,
       has_default_value=True, default_value=False,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='uninterpreted_option', full_name='google.protobuf.FileOptions.uninterpreted_option', index=9,
+      name='deprecated', full_name='google.protobuf.FileOptions.deprecated', index=10,
+      number=23, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='cc_enable_arenas', full_name='google.protobuf.FileOptions.cc_enable_arenas', index=11,
+      number=31, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='objc_class_prefix', full_name='google.protobuf.FileOptions.objc_class_prefix', index=12,
+      number=36, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='csharp_namespace', full_name='google.protobuf.FileOptions.csharp_namespace', index=13,
+      number=37, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uninterpreted_option', full_name='google.protobuf.FileOptions.uninterpreted_option', index=14,
       number=999, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
@@ -747,9 +978,12 @@
   ],
   options=None,
   is_extendable=True,
+  syntax='proto2',
   extension_ranges=[(1000, 536870912), ],
-  serialized_start=2209,
-  serialized_end=2698,
+  oneofs=[
+  ],
+  serialized_start=2617,
+  serialized_end=3264,
 )
 
 
@@ -775,7 +1009,21 @@
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='uninterpreted_option', full_name='google.protobuf.MessageOptions.uninterpreted_option', index=2,
+      name='deprecated', full_name='google.protobuf.MessageOptions.deprecated', index=2,
+      number=3, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_entry', full_name='google.protobuf.MessageOptions.map_entry', index=3,
+      number=7, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uninterpreted_option', full_name='google.protobuf.MessageOptions.uninterpreted_option', index=4,
       number=999, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
@@ -789,9 +1037,12 @@
   ],
   options=None,
   is_extendable=True,
+  syntax='proto2',
   extension_ranges=[(1000, 536870912), ],
-  serialized_start=2701,
-  serialized_end=2885,
+  oneofs=[
+  ],
+  serialized_start=3267,
+  serialized_end=3497,
 )
 
 
@@ -817,27 +1068,27 @@
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='lazy', full_name='google.protobuf.FieldOptions.lazy', index=2,
+      name='jstype', full_name='google.protobuf.FieldOptions.jstype', index=2,
+      number=6, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='lazy', full_name='google.protobuf.FieldOptions.lazy', index=3,
       number=5, type=8, cpp_type=7, label=1,
       has_default_value=True, default_value=False,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='deprecated', full_name='google.protobuf.FieldOptions.deprecated', index=3,
+      name='deprecated', full_name='google.protobuf.FieldOptions.deprecated', index=4,
       number=3, type=8, cpp_type=7, label=1,
       has_default_value=True, default_value=False,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='experimental_map_key', full_name='google.protobuf.FieldOptions.experimental_map_key', index=4,
-      number=9, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    _descriptor.FieldDescriptor(
       name='weak', full_name='google.protobuf.FieldOptions.weak', index=5,
       number=10, type=8, cpp_type=7, label=1,
       has_default_value=True, default_value=False,
@@ -857,12 +1108,47 @@
   nested_types=[],
   enum_types=[
     _FIELDOPTIONS_CTYPE,
+    _FIELDOPTIONS_JSTYPE,
   ],
   options=None,
   is_extendable=True,
+  syntax='proto2',
   extension_ranges=[(1000, 536870912), ],
-  serialized_start=2888,
-  serialized_end=3206,
+  oneofs=[
+  ],
+  serialized_start=3500,
+  serialized_end=3908,
+)
+
+
+_ONEOFOPTIONS = _descriptor.Descriptor(
+  name='OneofOptions',
+  full_name='google.protobuf.OneofOptions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='uninterpreted_option', full_name='google.protobuf.OneofOptions.uninterpreted_option', index=0,
+      number=999, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(1000, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=3910,
+  serialized_end=4004,
 )
 
 
@@ -876,12 +1162,19 @@
     _descriptor.FieldDescriptor(
       name='allow_alias', full_name='google.protobuf.EnumOptions.allow_alias', index=0,
       number=2, type=8, cpp_type=7, label=1,
-      has_default_value=True, default_value=True,
+      has_default_value=False, default_value=False,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='uninterpreted_option', full_name='google.protobuf.EnumOptions.uninterpreted_option', index=1,
+      name='deprecated', full_name='google.protobuf.EnumOptions.deprecated', index=1,
+      number=3, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uninterpreted_option', full_name='google.protobuf.EnumOptions.uninterpreted_option', index=2,
       number=999, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
@@ -895,9 +1188,12 @@
   ],
   options=None,
   is_extendable=True,
+  syntax='proto2',
   extension_ranges=[(1000, 536870912), ],
-  serialized_start=3208,
-  serialized_end=3328,
+  oneofs=[
+  ],
+  serialized_start=4007,
+  serialized_end=4148,
 )
 
 
@@ -909,7 +1205,14 @@
   containing_type=None,
   fields=[
     _descriptor.FieldDescriptor(
-      name='uninterpreted_option', full_name='google.protobuf.EnumValueOptions.uninterpreted_option', index=0,
+      name='deprecated', full_name='google.protobuf.EnumValueOptions.deprecated', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uninterpreted_option', full_name='google.protobuf.EnumValueOptions.uninterpreted_option', index=1,
       number=999, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
@@ -923,9 +1226,12 @@
   ],
   options=None,
   is_extendable=True,
+  syntax='proto2',
   extension_ranges=[(1000, 536870912), ],
-  serialized_start=3330,
-  serialized_end=3428,
+  oneofs=[
+  ],
+  serialized_start=4150,
+  serialized_end=4275,
 )
 
 
@@ -937,7 +1243,14 @@
   containing_type=None,
   fields=[
     _descriptor.FieldDescriptor(
-      name='uninterpreted_option', full_name='google.protobuf.ServiceOptions.uninterpreted_option', index=0,
+      name='deprecated', full_name='google.protobuf.ServiceOptions.deprecated', index=0,
+      number=33, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uninterpreted_option', full_name='google.protobuf.ServiceOptions.uninterpreted_option', index=1,
       number=999, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
@@ -951,9 +1264,12 @@
   ],
   options=None,
   is_extendable=True,
+  syntax='proto2',
   extension_ranges=[(1000, 536870912), ],
-  serialized_start=3430,
-  serialized_end=3526,
+  oneofs=[
+  ],
+  serialized_start=4277,
+  serialized_end=4400,
 )
 
 
@@ -965,7 +1281,14 @@
   containing_type=None,
   fields=[
     _descriptor.FieldDescriptor(
-      name='uninterpreted_option', full_name='google.protobuf.MethodOptions.uninterpreted_option', index=0,
+      name='deprecated', full_name='google.protobuf.MethodOptions.deprecated', index=0,
+      number=33, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uninterpreted_option', full_name='google.protobuf.MethodOptions.uninterpreted_option', index=1,
       number=999, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
@@ -979,9 +1302,12 @@
   ],
   options=None,
   is_extendable=True,
+  syntax='proto2',
   extension_ranges=[(1000, 536870912), ],
-  serialized_start=3528,
-  serialized_end=3623,
+  oneofs=[
+  ],
+  serialized_start=4402,
+  serialized_end=4524,
 )
 
 
@@ -995,7 +1321,7 @@
     _descriptor.FieldDescriptor(
       name='name_part', full_name='google.protobuf.UninterpretedOption.NamePart.name_part', index=0,
       number=1, type=9, cpp_type=9, label=2,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -1014,9 +1340,12 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=3861,
-  serialized_end=3912,
+  oneofs=[
+  ],
+  serialized_start=4762,
+  serialized_end=4813,
 )
 
 _UNINTERPRETEDOPTION = _descriptor.Descriptor(
@@ -1036,7 +1365,7 @@
     _descriptor.FieldDescriptor(
       name='identifier_value', full_name='google.protobuf.UninterpretedOption.identifier_value', index=1,
       number=3, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -1057,21 +1386,21 @@
     _descriptor.FieldDescriptor(
       name='double_value', full_name='google.protobuf.UninterpretedOption.double_value', index=4,
       number=6, type=1, cpp_type=5, label=1,
-      has_default_value=False, default_value=0,
+      has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
       name='string_value', full_name='google.protobuf.UninterpretedOption.string_value', index=5,
       number=7, type=12, cpp_type=9, label=1,
-      has_default_value=False, default_value="",
+      has_default_value=False, default_value=_b(""),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
       name='aggregate_value', full_name='google.protobuf.UninterpretedOption.aggregate_value', index=6,
       number=8, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -1083,9 +1412,12 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=3626,
-  serialized_end=3912,
+  oneofs=[
+  ],
+  serialized_start=4527,
+  serialized_end=4813,
 )
 
 
@@ -1113,14 +1445,21 @@
     _descriptor.FieldDescriptor(
       name='leading_comments', full_name='google.protobuf.SourceCodeInfo.Location.leading_comments', index=2,
       number=3, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
       name='trailing_comments', full_name='google.protobuf.SourceCodeInfo.Location.trailing_comments', index=3,
       number=4, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='leading_detached_comments', full_name='google.protobuf.SourceCodeInfo.Location.leading_detached_comments', index=4,
+      number=6, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -1132,9 +1471,12 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=3993,
-  serialized_end=4092,
+  oneofs=[
+  ],
+  serialized_start=4895,
+  serialized_end=5029,
 )
 
 _SOURCECODEINFO = _descriptor.Descriptor(
@@ -1159,9 +1501,94 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
-  serialized_start=3915,
-  serialized_end=4092,
+  oneofs=[
+  ],
+  serialized_start=4816,
+  serialized_end=5029,
+)
+
+
+_GENERATEDCODEINFO_ANNOTATION = _descriptor.Descriptor(
+  name='Annotation',
+  full_name='google.protobuf.GeneratedCodeInfo.Annotation',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='path', full_name='google.protobuf.GeneratedCodeInfo.Annotation.path', index=0,
+      number=1, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='source_file', full_name='google.protobuf.GeneratedCodeInfo.Annotation.source_file', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='begin', full_name='google.protobuf.GeneratedCodeInfo.Annotation.begin', index=2,
+      number=3, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='end', full_name='google.protobuf.GeneratedCodeInfo.Annotation.end', index=3,
+      number=4, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5120,
+  serialized_end=5199,
+)
+
+_GENERATEDCODEINFO = _descriptor.Descriptor(
+  name='GeneratedCodeInfo',
+  full_name='google.protobuf.GeneratedCodeInfo',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='annotation', full_name='google.protobuf.GeneratedCodeInfo.annotation', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_GENERATEDCODEINFO_ANNOTATION, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5032,
+  serialized_end=5199,
 )
 
 _FILEDESCRIPTORSET.fields_by_name['file'].message_type = _FILEDESCRIPTORPROTO
@@ -1171,18 +1598,22 @@
 _FILEDESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO
 _FILEDESCRIPTORPROTO.fields_by_name['options'].message_type = _FILEOPTIONS
 _FILEDESCRIPTORPROTO.fields_by_name['source_code_info'].message_type = _SOURCECODEINFO
-_DESCRIPTORPROTO_EXTENSIONRANGE.containing_type = _DESCRIPTORPROTO;
+_DESCRIPTORPROTO_EXTENSIONRANGE.containing_type = _DESCRIPTORPROTO
+_DESCRIPTORPROTO_RESERVEDRANGE.containing_type = _DESCRIPTORPROTO
 _DESCRIPTORPROTO.fields_by_name['field'].message_type = _FIELDDESCRIPTORPROTO
 _DESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO
 _DESCRIPTORPROTO.fields_by_name['nested_type'].message_type = _DESCRIPTORPROTO
 _DESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO
 _DESCRIPTORPROTO.fields_by_name['extension_range'].message_type = _DESCRIPTORPROTO_EXTENSIONRANGE
+_DESCRIPTORPROTO.fields_by_name['oneof_decl'].message_type = _ONEOFDESCRIPTORPROTO
 _DESCRIPTORPROTO.fields_by_name['options'].message_type = _MESSAGEOPTIONS
+_DESCRIPTORPROTO.fields_by_name['reserved_range'].message_type = _DESCRIPTORPROTO_RESERVEDRANGE
 _FIELDDESCRIPTORPROTO.fields_by_name['label'].enum_type = _FIELDDESCRIPTORPROTO_LABEL
 _FIELDDESCRIPTORPROTO.fields_by_name['type'].enum_type = _FIELDDESCRIPTORPROTO_TYPE
 _FIELDDESCRIPTORPROTO.fields_by_name['options'].message_type = _FIELDOPTIONS
-_FIELDDESCRIPTORPROTO_TYPE.containing_type = _FIELDDESCRIPTORPROTO;
-_FIELDDESCRIPTORPROTO_LABEL.containing_type = _FIELDDESCRIPTORPROTO;
+_FIELDDESCRIPTORPROTO_TYPE.containing_type = _FIELDDESCRIPTORPROTO
+_FIELDDESCRIPTORPROTO_LABEL.containing_type = _FIELDDESCRIPTORPROTO
+_ONEOFDESCRIPTORPROTO.fields_by_name['options'].message_type = _ONEOFOPTIONS
 _ENUMDESCRIPTORPROTO.fields_by_name['value'].message_type = _ENUMVALUEDESCRIPTORPROTO
 _ENUMDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMOPTIONS
 _ENUMVALUEDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMVALUEOPTIONS
@@ -1191,23 +1622,29 @@
 _METHODDESCRIPTORPROTO.fields_by_name['options'].message_type = _METHODOPTIONS
 _FILEOPTIONS.fields_by_name['optimize_for'].enum_type = _FILEOPTIONS_OPTIMIZEMODE
 _FILEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
-_FILEOPTIONS_OPTIMIZEMODE.containing_type = _FILEOPTIONS;
+_FILEOPTIONS_OPTIMIZEMODE.containing_type = _FILEOPTIONS
 _MESSAGEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
 _FIELDOPTIONS.fields_by_name['ctype'].enum_type = _FIELDOPTIONS_CTYPE
+_FIELDOPTIONS.fields_by_name['jstype'].enum_type = _FIELDOPTIONS_JSTYPE
 _FIELDOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
-_FIELDOPTIONS_CTYPE.containing_type = _FIELDOPTIONS;
+_FIELDOPTIONS_CTYPE.containing_type = _FIELDOPTIONS
+_FIELDOPTIONS_JSTYPE.containing_type = _FIELDOPTIONS
+_ONEOFOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
 _ENUMOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
 _ENUMVALUEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
 _SERVICEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
 _METHODOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
-_UNINTERPRETEDOPTION_NAMEPART.containing_type = _UNINTERPRETEDOPTION;
+_UNINTERPRETEDOPTION_NAMEPART.containing_type = _UNINTERPRETEDOPTION
 _UNINTERPRETEDOPTION.fields_by_name['name'].message_type = _UNINTERPRETEDOPTION_NAMEPART
-_SOURCECODEINFO_LOCATION.containing_type = _SOURCECODEINFO;
+_SOURCECODEINFO_LOCATION.containing_type = _SOURCECODEINFO
 _SOURCECODEINFO.fields_by_name['location'].message_type = _SOURCECODEINFO_LOCATION
+_GENERATEDCODEINFO_ANNOTATION.containing_type = _GENERATEDCODEINFO
+_GENERATEDCODEINFO.fields_by_name['annotation'].message_type = _GENERATEDCODEINFO_ANNOTATION
 DESCRIPTOR.message_types_by_name['FileDescriptorSet'] = _FILEDESCRIPTORSET
 DESCRIPTOR.message_types_by_name['FileDescriptorProto'] = _FILEDESCRIPTORPROTO
 DESCRIPTOR.message_types_by_name['DescriptorProto'] = _DESCRIPTORPROTO
 DESCRIPTOR.message_types_by_name['FieldDescriptorProto'] = _FIELDDESCRIPTORPROTO
+DESCRIPTOR.message_types_by_name['OneofDescriptorProto'] = _ONEOFDESCRIPTORPROTO
 DESCRIPTOR.message_types_by_name['EnumDescriptorProto'] = _ENUMDESCRIPTORPROTO
 DESCRIPTOR.message_types_by_name['EnumValueDescriptorProto'] = _ENUMVALUEDESCRIPTORPROTO
 DESCRIPTOR.message_types_by_name['ServiceDescriptorProto'] = _SERVICEDESCRIPTORPROTO
@@ -1215,132 +1652,194 @@
 DESCRIPTOR.message_types_by_name['FileOptions'] = _FILEOPTIONS
 DESCRIPTOR.message_types_by_name['MessageOptions'] = _MESSAGEOPTIONS
 DESCRIPTOR.message_types_by_name['FieldOptions'] = _FIELDOPTIONS
+DESCRIPTOR.message_types_by_name['OneofOptions'] = _ONEOFOPTIONS
 DESCRIPTOR.message_types_by_name['EnumOptions'] = _ENUMOPTIONS
 DESCRIPTOR.message_types_by_name['EnumValueOptions'] = _ENUMVALUEOPTIONS
 DESCRIPTOR.message_types_by_name['ServiceOptions'] = _SERVICEOPTIONS
 DESCRIPTOR.message_types_by_name['MethodOptions'] = _METHODOPTIONS
 DESCRIPTOR.message_types_by_name['UninterpretedOption'] = _UNINTERPRETEDOPTION
 DESCRIPTOR.message_types_by_name['SourceCodeInfo'] = _SOURCECODEINFO
+DESCRIPTOR.message_types_by_name['GeneratedCodeInfo'] = _GENERATEDCODEINFO
 
-class FileDescriptorSet(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _FILEDESCRIPTORSET
-
+FileDescriptorSet = _reflection.GeneratedProtocolMessageType('FileDescriptorSet', (_message.Message,), dict(
+  DESCRIPTOR = _FILEDESCRIPTORSET,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet)
+  ))
+_sym_db.RegisterMessage(FileDescriptorSet)
 
-class FileDescriptorProto(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _FILEDESCRIPTORPROTO
-
+FileDescriptorProto = _reflection.GeneratedProtocolMessageType('FileDescriptorProto', (_message.Message,), dict(
+  DESCRIPTOR = _FILEDESCRIPTORPROTO,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto)
+  ))
+_sym_db.RegisterMessage(FileDescriptorProto)
 
-class DescriptorProto(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
+DescriptorProto = _reflection.GeneratedProtocolMessageType('DescriptorProto', (_message.Message,), dict(
 
-  class ExtensionRange(_message.Message):
-    __metaclass__ = _reflection.GeneratedProtocolMessageType
-    DESCRIPTOR = _DESCRIPTORPROTO_EXTENSIONRANGE
-
+  ExtensionRange = _reflection.GeneratedProtocolMessageType('ExtensionRange', (_message.Message,), dict(
+    DESCRIPTOR = _DESCRIPTORPROTO_EXTENSIONRANGE,
+    __module__ = 'google.protobuf.descriptor_pb2'
     # @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange)
-  DESCRIPTOR = _DESCRIPTORPROTO
+    ))
+  ,
 
+  ReservedRange = _reflection.GeneratedProtocolMessageType('ReservedRange', (_message.Message,), dict(
+    DESCRIPTOR = _DESCRIPTORPROTO_RESERVEDRANGE,
+    __module__ = 'google.protobuf.descriptor_pb2'
+    # @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ReservedRange)
+    ))
+  ,
+  DESCRIPTOR = _DESCRIPTORPROTO,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto)
+  ))
+_sym_db.RegisterMessage(DescriptorProto)
+_sym_db.RegisterMessage(DescriptorProto.ExtensionRange)
+_sym_db.RegisterMessage(DescriptorProto.ReservedRange)
 
-class FieldDescriptorProto(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _FIELDDESCRIPTORPROTO
-
+FieldDescriptorProto = _reflection.GeneratedProtocolMessageType('FieldDescriptorProto', (_message.Message,), dict(
+  DESCRIPTOR = _FIELDDESCRIPTORPROTO,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
+  ))
+_sym_db.RegisterMessage(FieldDescriptorProto)
 
-class EnumDescriptorProto(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _ENUMDESCRIPTORPROTO
+OneofDescriptorProto = _reflection.GeneratedProtocolMessageType('OneofDescriptorProto', (_message.Message,), dict(
+  DESCRIPTOR = _ONEOFDESCRIPTORPROTO,
+  __module__ = 'google.protobuf.descriptor_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto)
+  ))
+_sym_db.RegisterMessage(OneofDescriptorProto)
 
+EnumDescriptorProto = _reflection.GeneratedProtocolMessageType('EnumDescriptorProto', (_message.Message,), dict(
+  DESCRIPTOR = _ENUMDESCRIPTORPROTO,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto)
+  ))
+_sym_db.RegisterMessage(EnumDescriptorProto)
 
-class EnumValueDescriptorProto(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _ENUMVALUEDESCRIPTORPROTO
-
+EnumValueDescriptorProto = _reflection.GeneratedProtocolMessageType('EnumValueDescriptorProto', (_message.Message,), dict(
+  DESCRIPTOR = _ENUMVALUEDESCRIPTORPROTO,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto)
+  ))
+_sym_db.RegisterMessage(EnumValueDescriptorProto)
 
-class ServiceDescriptorProto(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _SERVICEDESCRIPTORPROTO
-
+ServiceDescriptorProto = _reflection.GeneratedProtocolMessageType('ServiceDescriptorProto', (_message.Message,), dict(
+  DESCRIPTOR = _SERVICEDESCRIPTORPROTO,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto)
+  ))
+_sym_db.RegisterMessage(ServiceDescriptorProto)
 
-class MethodDescriptorProto(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _METHODDESCRIPTORPROTO
-
+MethodDescriptorProto = _reflection.GeneratedProtocolMessageType('MethodDescriptorProto', (_message.Message,), dict(
+  DESCRIPTOR = _METHODDESCRIPTORPROTO,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto)
+  ))
+_sym_db.RegisterMessage(MethodDescriptorProto)
 
-class FileOptions(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _FILEOPTIONS
-
+FileOptions = _reflection.GeneratedProtocolMessageType('FileOptions', (_message.Message,), dict(
+  DESCRIPTOR = _FILEOPTIONS,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
+  ))
+_sym_db.RegisterMessage(FileOptions)
 
-class MessageOptions(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _MESSAGEOPTIONS
-
+MessageOptions = _reflection.GeneratedProtocolMessageType('MessageOptions', (_message.Message,), dict(
+  DESCRIPTOR = _MESSAGEOPTIONS,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
+  ))
+_sym_db.RegisterMessage(MessageOptions)
 
-class FieldOptions(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _FIELDOPTIONS
-
+FieldOptions = _reflection.GeneratedProtocolMessageType('FieldOptions', (_message.Message,), dict(
+  DESCRIPTOR = _FIELDOPTIONS,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
+  ))
+_sym_db.RegisterMessage(FieldOptions)
 
-class EnumOptions(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _ENUMOPTIONS
+OneofOptions = _reflection.GeneratedProtocolMessageType('OneofOptions', (_message.Message,), dict(
+  DESCRIPTOR = _ONEOFOPTIONS,
+  __module__ = 'google.protobuf.descriptor_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.OneofOptions)
+  ))
+_sym_db.RegisterMessage(OneofOptions)
 
+EnumOptions = _reflection.GeneratedProtocolMessageType('EnumOptions', (_message.Message,), dict(
+  DESCRIPTOR = _ENUMOPTIONS,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
+  ))
+_sym_db.RegisterMessage(EnumOptions)
 
-class EnumValueOptions(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _ENUMVALUEOPTIONS
-
+EnumValueOptions = _reflection.GeneratedProtocolMessageType('EnumValueOptions', (_message.Message,), dict(
+  DESCRIPTOR = _ENUMVALUEOPTIONS,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
+  ))
+_sym_db.RegisterMessage(EnumValueOptions)
 
-class ServiceOptions(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _SERVICEOPTIONS
-
+ServiceOptions = _reflection.GeneratedProtocolMessageType('ServiceOptions', (_message.Message,), dict(
+  DESCRIPTOR = _SERVICEOPTIONS,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
+  ))
+_sym_db.RegisterMessage(ServiceOptions)
 
-class MethodOptions(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _METHODOPTIONS
-
+MethodOptions = _reflection.GeneratedProtocolMessageType('MethodOptions', (_message.Message,), dict(
+  DESCRIPTOR = _METHODOPTIONS,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
+  ))
+_sym_db.RegisterMessage(MethodOptions)
 
-class UninterpretedOption(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
+UninterpretedOption = _reflection.GeneratedProtocolMessageType('UninterpretedOption', (_message.Message,), dict(
 
-  class NamePart(_message.Message):
-    __metaclass__ = _reflection.GeneratedProtocolMessageType
-    DESCRIPTOR = _UNINTERPRETEDOPTION_NAMEPART
-
+  NamePart = _reflection.GeneratedProtocolMessageType('NamePart', (_message.Message,), dict(
+    DESCRIPTOR = _UNINTERPRETEDOPTION_NAMEPART,
+    __module__ = 'google.protobuf.descriptor_pb2'
     # @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart)
-  DESCRIPTOR = _UNINTERPRETEDOPTION
-
+    ))
+  ,
+  DESCRIPTOR = _UNINTERPRETEDOPTION,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption)
+  ))
+_sym_db.RegisterMessage(UninterpretedOption)
+_sym_db.RegisterMessage(UninterpretedOption.NamePart)
 
-class SourceCodeInfo(_message.Message):
-  __metaclass__ = _reflection.GeneratedProtocolMessageType
+SourceCodeInfo = _reflection.GeneratedProtocolMessageType('SourceCodeInfo', (_message.Message,), dict(
 
-  class Location(_message.Message):
-    __metaclass__ = _reflection.GeneratedProtocolMessageType
-    DESCRIPTOR = _SOURCECODEINFO_LOCATION
-
+  Location = _reflection.GeneratedProtocolMessageType('Location', (_message.Message,), dict(
+    DESCRIPTOR = _SOURCECODEINFO_LOCATION,
+    __module__ = 'google.protobuf.descriptor_pb2'
     # @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location)
-  DESCRIPTOR = _SOURCECODEINFO
-
+    ))
+  ,
+  DESCRIPTOR = _SOURCECODEINFO,
+  __module__ = 'google.protobuf.descriptor_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo)
+  ))
+_sym_db.RegisterMessage(SourceCodeInfo)
+_sym_db.RegisterMessage(SourceCodeInfo.Location)
+
+GeneratedCodeInfo = _reflection.GeneratedProtocolMessageType('GeneratedCodeInfo', (_message.Message,), dict(
+
+  Annotation = _reflection.GeneratedProtocolMessageType('Annotation', (_message.Message,), dict(
+    DESCRIPTOR = _GENERATEDCODEINFO_ANNOTATION,
+    __module__ = 'google.protobuf.descriptor_pb2'
+    # @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo.Annotation)
+    ))
+  ,
+  DESCRIPTOR = _GENERATEDCODEINFO,
+  __module__ = 'google.protobuf.descriptor_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo)
+  ))
+_sym_db.RegisterMessage(GeneratedCodeInfo)
+_sym_db.RegisterMessage(GeneratedCodeInfo.Annotation)
 
 
 # @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/descriptor_pool.py b/generator/google/protobuf/descriptor_pool.py
index 8f1f445..5c055ab 100644
--- a/generator/google/protobuf/descriptor_pool.py
+++ b/generator/google/protobuf/descriptor_pool.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -49,18 +49,46 @@
 The message descriptor can be used in conjunction with the message_factory
 module in order to create a protocol buffer class that can be encoded and
 decoded.
+
+If you want to get a Python class for the specified proto, use the
+helper functions inside google.protobuf.message_factory
+directly instead of this class.
 """
 
 __author__ = 'matthewtoia@google.com (Matt Toia)'
 
-from google.protobuf import descriptor_pb2
 from google.protobuf import descriptor
 from google.protobuf import descriptor_database
+from google.protobuf import text_encoding
+
+
+_USE_C_DESCRIPTORS = descriptor._USE_C_DESCRIPTORS
+
+
+def _NormalizeFullyQualifiedName(name):
+  """Remove leading period from fully-qualified type name.
+
+  Due to b/13860351 in descriptor_database.py, types in the root namespace are
+  generated with a leading period. This function removes that prefix.
+
+  Args:
+    name: A str, the fully-qualified symbol name.
+
+  Returns:
+    A str, the normalized fully-qualified symbol name.
+  """
+  return name.lstrip('.')
 
 
 class DescriptorPool(object):
   """A collection of protobufs dynamically constructed by descriptor protos."""
 
+  if _USE_C_DESCRIPTORS:
+
+    def __new__(cls, descriptor_db=None):
+      # pylint: disable=protected-access
+      return descriptor._message.DescriptorPool(descriptor_db)
+
   def __init__(self, descriptor_db=None):
     """Initializes a Pool of proto buffs.
 
@@ -89,6 +117,65 @@
 
     self._internal_db.Add(file_desc_proto)
 
+  def AddSerializedFile(self, serialized_file_desc_proto):
+    """Adds the FileDescriptorProto and its types to this pool.
+
+    Args:
+      serialized_file_desc_proto: A bytes string, serialization of the
+        FileDescriptorProto to add.
+    """
+
+    # pylint: disable=g-import-not-at-top
+    from google.protobuf import descriptor_pb2
+    file_desc_proto = descriptor_pb2.FileDescriptorProto.FromString(
+        serialized_file_desc_proto)
+    self.Add(file_desc_proto)
+
+  def AddDescriptor(self, desc):
+    """Adds a Descriptor to the pool, non-recursively.
+
+    If the Descriptor contains nested messages or enums, the caller must
+    explicitly register them. This method also registers the FileDescriptor
+    associated with the message.
+
+    Args:
+      desc: A Descriptor.
+    """
+    if not isinstance(desc, descriptor.Descriptor):
+      raise TypeError('Expected instance of descriptor.Descriptor.')
+
+    self._descriptors[desc.full_name] = desc
+    self.AddFileDescriptor(desc.file)
+
+  def AddEnumDescriptor(self, enum_desc):
+    """Adds an EnumDescriptor to the pool.
+
+    This method also registers the FileDescriptor associated with the message.
+
+    Args:
+      enum_desc: An EnumDescriptor.
+    """
+
+    if not isinstance(enum_desc, descriptor.EnumDescriptor):
+      raise TypeError('Expected instance of descriptor.EnumDescriptor.')
+
+    self._enum_descriptors[enum_desc.full_name] = enum_desc
+    self.AddFileDescriptor(enum_desc.file)
+
+  def AddFileDescriptor(self, file_desc):
+    """Adds a FileDescriptor to the pool, non-recursively.
+
+    If the FileDescriptor contains messages or enums, the caller must explicitly
+    register them.
+
+    Args:
+      file_desc: A FileDescriptor.
+    """
+
+    if not isinstance(file_desc, descriptor.FileDescriptor):
+      raise TypeError('Expected instance of descriptor.FileDescriptor.')
+    self._file_descriptors[file_desc.name] = file_desc
+
   def FindFileByName(self, file_name):
     """Gets a FileDescriptor by file name.
 
@@ -103,6 +190,11 @@
     """
 
     try:
+      return self._file_descriptors[file_name]
+    except KeyError:
+      pass
+
+    try:
       file_proto = self._internal_db.FindFileByName(file_name)
     except KeyError as error:
       if self._descriptor_db:
@@ -126,6 +218,17 @@
       KeyError: if the file can not be found in the pool.
     """
 
+    symbol = _NormalizeFullyQualifiedName(symbol)
+    try:
+      return self._descriptors[symbol].file
+    except KeyError:
+      pass
+
+    try:
+      return self._enum_descriptors[symbol].file
+    except KeyError:
+      pass
+
     try:
       file_proto = self._internal_db.FindFileContainingSymbol(symbol)
     except KeyError as error:
@@ -147,7 +250,7 @@
       The descriptor for the named type.
     """
 
-    full_name = full_name.lstrip('.')  # fix inconsistent qualified name formats
+    full_name = _NormalizeFullyQualifiedName(full_name)
     if full_name not in self._descriptors:
       self.FindFileContainingSymbol(full_name)
     return self._descriptors[full_name]
@@ -162,11 +265,44 @@
       The enum descriptor for the named type.
     """
 
-    full_name = full_name.lstrip('.')  # fix inconsistent qualified name formats
+    full_name = _NormalizeFullyQualifiedName(full_name)
     if full_name not in self._enum_descriptors:
       self.FindFileContainingSymbol(full_name)
     return self._enum_descriptors[full_name]
 
+  def FindFieldByName(self, full_name):
+    """Loads the named field descriptor from the pool.
+
+    Args:
+      full_name: The full name of the field descriptor to load.
+
+    Returns:
+      The field descriptor for the named field.
+    """
+    full_name = _NormalizeFullyQualifiedName(full_name)
+    message_name, _, field_name = full_name.rpartition('.')
+    message_descriptor = self.FindMessageTypeByName(message_name)
+    return message_descriptor.fields_by_name[field_name]
+
+  def FindExtensionByName(self, full_name):
+    """Loads the named extension descriptor from the pool.
+
+    Args:
+      full_name: The full name of the extension descriptor to load.
+
+    Returns:
+      A FieldDescriptor, describing the named extension.
+    """
+    full_name = _NormalizeFullyQualifiedName(full_name)
+    message_name, _, extension_name = full_name.rpartition('.')
+    try:
+      # Most extensions are nested inside a message.
+      scope = self.FindMessageTypeByName(message_name)
+    except KeyError:
+      # Some extensions are defined at file scope.
+      scope = self.FindFileContainingSymbol(full_name)
+    return scope.extensions_by_name[extension_name]
+
   def _ConvertFileProtoToFileDescriptor(self, file_proto):
     """Creates a FileDescriptor from a proto or returns a cached copy.
 
@@ -181,54 +317,95 @@
     """
 
     if file_proto.name not in self._file_descriptors:
+      built_deps = list(self._GetDeps(file_proto.dependency))
+      direct_deps = [self.FindFileByName(n) for n in file_proto.dependency]
+      public_deps = [direct_deps[i] for i in file_proto.public_dependency]
+
       file_descriptor = descriptor.FileDescriptor(
+          pool=self,
           name=file_proto.name,
           package=file_proto.package,
+          syntax=file_proto.syntax,
           options=file_proto.options,
-          serialized_pb=file_proto.SerializeToString())
-      scope = {}
-      dependencies = list(self._GetDeps(file_proto))
+          serialized_pb=file_proto.SerializeToString(),
+          dependencies=direct_deps,
+          public_dependencies=public_deps)
+      if _USE_C_DESCRIPTORS:
+        # When using C++ descriptors, all objects defined in the file were added
+        # to the C++ database when the FileDescriptor was built above.
+        # Just add them to this descriptor pool.
+        def _AddMessageDescriptor(message_desc):
+          self._descriptors[message_desc.full_name] = message_desc
+          for nested in message_desc.nested_types:
+            _AddMessageDescriptor(nested)
+          for enum_type in message_desc.enum_types:
+            _AddEnumDescriptor(enum_type)
+        def _AddEnumDescriptor(enum_desc):
+          self._enum_descriptors[enum_desc.full_name] = enum_desc
+        for message_type in file_descriptor.message_types_by_name.values():
+          _AddMessageDescriptor(message_type)
+        for enum_type in file_descriptor.enum_types_by_name.values():
+          _AddEnumDescriptor(enum_type)
+      else:
+        scope = {}
 
-      for dependency in dependencies:
-        dep_desc = self.FindFileByName(dependency.name)
-        dep_proto = descriptor_pb2.FileDescriptorProto.FromString(
-            dep_desc.serialized_pb)
-        package = '.' + dep_proto.package
-        package_prefix = package + '.'
+        # This loop extracts all the message and enum types from all the
+        # dependencies of the file_proto. This is necessary to create the
+        # scope of available message types when defining the passed in
+        # file proto.
+        for dependency in built_deps:
+          scope.update(self._ExtractSymbols(
+              dependency.message_types_by_name.values()))
+          scope.update((_PrefixWithDot(enum.full_name), enum)
+                       for enum in dependency.enum_types_by_name.values())
 
-        def _strip_package(symbol):
-          if symbol.startswith(package_prefix):
-            return symbol[len(package_prefix):]
-          return symbol
+        for message_type in file_proto.message_type:
+          message_desc = self._ConvertMessageDescriptor(
+              message_type, file_proto.package, file_descriptor, scope,
+              file_proto.syntax)
+          file_descriptor.message_types_by_name[message_desc.name] = (
+              message_desc)
 
-        symbols = list(self._ExtractSymbols(dep_proto.message_type, package))
-        scope.update(symbols)
-        scope.update((_strip_package(k), v) for k, v in symbols)
+        for enum_type in file_proto.enum_type:
+          file_descriptor.enum_types_by_name[enum_type.name] = (
+              self._ConvertEnumDescriptor(enum_type, file_proto.package,
+                                          file_descriptor, None, scope))
 
-        symbols = list(self._ExtractEnums(dep_proto.enum_type, package))
-        scope.update(symbols)
-        scope.update((_strip_package(k), v) for k, v in symbols)
+        for index, extension_proto in enumerate(file_proto.extension):
+          extension_desc = self._MakeFieldDescriptor(
+              extension_proto, file_proto.package, index, is_extension=True)
+          extension_desc.containing_type = self._GetTypeFromScope(
+              file_descriptor.package, extension_proto.extendee, scope)
+          self._SetFieldType(extension_proto, extension_desc,
+                            file_descriptor.package, scope)
+          file_descriptor.extensions_by_name[extension_desc.name] = (
+              extension_desc)
 
-      for message_type in file_proto.message_type:
-        message_desc = self._ConvertMessageDescriptor(
-            message_type, file_proto.package, file_descriptor, scope)
-        file_descriptor.message_types_by_name[message_desc.name] = message_desc
-      for enum_type in file_proto.enum_type:
-        self._ConvertEnumDescriptor(enum_type, file_proto.package,
-                                    file_descriptor, None, scope)
-      for desc_proto in self._ExtractMessages(file_proto.message_type):
-        self._SetFieldTypes(desc_proto, scope)
+        for desc_proto in file_proto.message_type:
+          self._SetAllFieldTypes(file_proto.package, desc_proto, scope)
 
-      for desc_proto in file_proto.message_type:
-        desc = scope[desc_proto.name]
-        file_descriptor.message_types_by_name[desc_proto.name] = desc
+        if file_proto.package:
+          desc_proto_prefix = _PrefixWithDot(file_proto.package)
+        else:
+          desc_proto_prefix = ''
+
+        for desc_proto in file_proto.message_type:
+          desc = self._GetTypeFromScope(
+              desc_proto_prefix, desc_proto.name, scope)
+          file_descriptor.message_types_by_name[desc_proto.name] = desc
+
+        for index, service_proto in enumerate(file_proto.service):
+          file_descriptor.services_by_name[service_proto.name] = (
+              self._MakeServiceDescriptor(service_proto, index, scope,
+                                          file_proto.package, file_descriptor))
+
       self.Add(file_proto)
       self._file_descriptors[file_proto.name] = file_descriptor
 
     return self._file_descriptors[file_proto.name]
 
   def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None,
-                                scope=None):
+                                scope=None, syntax=None):
     """Adds the proto to the pool in the specified package.
 
     Args:
@@ -255,15 +432,22 @@
       scope = {}
 
     nested = [
-        self._ConvertMessageDescriptor(nested, desc_name, file_desc, scope)
+        self._ConvertMessageDescriptor(
+            nested, desc_name, file_desc, scope, syntax)
         for nested in desc_proto.nested_type]
     enums = [
         self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope)
         for enum in desc_proto.enum_type]
     fields = [self._MakeFieldDescriptor(field, desc_name, index)
               for index, field in enumerate(desc_proto.field)]
-    extensions = [self._MakeFieldDescriptor(extension, desc_name, True)
-                  for index, extension in enumerate(desc_proto.extension)]
+    extensions = [
+        self._MakeFieldDescriptor(extension, desc_name, index,
+                                  is_extension=True)
+        for index, extension in enumerate(desc_proto.extension)]
+    oneofs = [
+        descriptor.OneofDescriptor(desc.name, '.'.join((desc_name, desc.name)),
+                                   index, None, [], desc.options)
+        for index, desc in enumerate(desc_proto.oneof_decl)]
     extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range]
     if extension_ranges:
       is_extendable = True
@@ -275,6 +459,7 @@
         filename=file_name,
         containing_type=None,
         fields=fields,
+        oneofs=oneofs,
         nested_types=nested,
         enum_types=enums,
         extensions=extensions,
@@ -283,13 +468,19 @@
         extension_ranges=extension_ranges,
         file=file_desc,
         serialized_start=None,
-        serialized_end=None)
+        serialized_end=None,
+        syntax=syntax)
     for nested in desc.nested_types:
       nested.containing_type = desc
     for enum in desc.enum_types:
       enum.containing_type = desc
-    scope[desc_proto.name] = desc
-    scope['.' + desc_name] = desc
+    for field_index, field_desc in enumerate(desc_proto.field):
+      if field_desc.HasField('oneof_index'):
+        oneof_index = field_desc.oneof_index
+        oneofs[oneof_index].fields.append(fields[field_index])
+        fields[field_index].containing_oneof = oneofs[oneof_index]
+
+    scope[_PrefixWithDot(desc_name)] = desc
     self._descriptors[desc_name] = desc
     return desc
 
@@ -327,7 +518,6 @@
                                      values=values,
                                      containing_type=containing_type,
                                      options=enum_proto.options)
-    scope[enum_proto.name] = desc
     scope['.%s' % enum_name] = desc
     self._enum_descriptors[enum_name] = desc
     return desc
@@ -374,65 +564,107 @@
         extension_scope=None,
         options=field_proto.options)
 
-  def _SetFieldTypes(self, desc_proto, scope):
-    """Sets the field's type, cpp_type, message_type and enum_type.
+  def _SetAllFieldTypes(self, package, desc_proto, scope):
+    """Sets all the descriptor's fields's types.
+
+    This method also sets the containing types on any extensions.
 
     Args:
+      package: The current package of desc_proto.
       desc_proto: The message descriptor to update.
       scope: Enclosing scope of available types.
     """
 
-    desc = scope[desc_proto.name]
-    for field_proto, field_desc in zip(desc_proto.field, desc.fields):
-      if field_proto.type_name:
-        type_name = field_proto.type_name
-        if type_name not in scope:
-          type_name = '.' + type_name
-        desc = scope[type_name]
-      else:
-        desc = None
+    package = _PrefixWithDot(package)
 
-      if not field_proto.HasField('type'):
-        if isinstance(desc, descriptor.Descriptor):
-          field_proto.type = descriptor.FieldDescriptor.TYPE_MESSAGE
-        else:
-          field_proto.type = descriptor.FieldDescriptor.TYPE_ENUM
+    main_desc = self._GetTypeFromScope(package, desc_proto.name, scope)
 
-      field_desc.cpp_type = descriptor.FieldDescriptor.ProtoTypeToCppProtoType(
-          field_proto.type)
+    if package == '.':
+      nested_package = _PrefixWithDot(desc_proto.name)
+    else:
+      nested_package = '.'.join([package, desc_proto.name])
 
-      if (field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE
-          or field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP):
-        field_desc.message_type = desc
+    for field_proto, field_desc in zip(desc_proto.field, main_desc.fields):
+      self._SetFieldType(field_proto, field_desc, nested_package, scope)
 
-      if field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
-        field_desc.enum_type = desc
-
-      if field_proto.label == descriptor.FieldDescriptor.LABEL_REPEATED:
-        field_desc.has_default = False
-        field_desc.default_value = []
-      elif field_proto.HasField('default_value'):
-        field_desc.has_default = True
-        if (field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE or
-            field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT):
-          field_desc.default_value = float(field_proto.default_value)
-        elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING:
-          field_desc.default_value = field_proto.default_value
-        elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL:
-          field_desc.default_value = field_proto.default_value.lower() == 'true'
-        elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
-          field_desc.default_value = field_desc.enum_type.values_by_name[
-              field_proto.default_value].index
-        else:
-          field_desc.default_value = int(field_proto.default_value)
-      else:
-        field_desc.has_default = False
-        field_desc.default_value = None
-
-      field_desc.type = field_proto.type
+    for extension_proto, extension_desc in (
+        zip(desc_proto.extension, main_desc.extensions)):
+      extension_desc.containing_type = self._GetTypeFromScope(
+          nested_package, extension_proto.extendee, scope)
+      self._SetFieldType(extension_proto, extension_desc, nested_package, scope)
 
     for nested_type in desc_proto.nested_type:
-      self._SetFieldTypes(nested_type, scope)
+      self._SetAllFieldTypes(nested_package, nested_type, scope)
+
+  def _SetFieldType(self, field_proto, field_desc, package, scope):
+    """Sets the field's type, cpp_type, message_type and enum_type.
+
+    Args:
+      field_proto: Data about the field in proto format.
+      field_desc: The descriptor to modiy.
+      package: The package the field's container is in.
+      scope: Enclosing scope of available types.
+    """
+    if field_proto.type_name:
+      desc = self._GetTypeFromScope(package, field_proto.type_name, scope)
+    else:
+      desc = None
+
+    if not field_proto.HasField('type'):
+      if isinstance(desc, descriptor.Descriptor):
+        field_proto.type = descriptor.FieldDescriptor.TYPE_MESSAGE
+      else:
+        field_proto.type = descriptor.FieldDescriptor.TYPE_ENUM
+
+    field_desc.cpp_type = descriptor.FieldDescriptor.ProtoTypeToCppProtoType(
+        field_proto.type)
+
+    if (field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE
+        or field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP):
+      field_desc.message_type = desc
+
+    if field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
+      field_desc.enum_type = desc
+
+    if field_proto.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+      field_desc.has_default_value = False
+      field_desc.default_value = []
+    elif field_proto.HasField('default_value'):
+      field_desc.has_default_value = True
+      if (field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE or
+          field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT):
+        field_desc.default_value = float(field_proto.default_value)
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING:
+        field_desc.default_value = field_proto.default_value
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL:
+        field_desc.default_value = field_proto.default_value.lower() == 'true'
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
+        field_desc.default_value = field_desc.enum_type.values_by_name[
+            field_proto.default_value].number
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES:
+        field_desc.default_value = text_encoding.CUnescape(
+            field_proto.default_value)
+      else:
+        # All other types are of the "int" type.
+        field_desc.default_value = int(field_proto.default_value)
+    else:
+      field_desc.has_default_value = False
+      if (field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE or
+          field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT):
+        field_desc.default_value = 0.0
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING:
+        field_desc.default_value = u''
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL:
+        field_desc.default_value = False
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
+        field_desc.default_value = field_desc.enum_type.values[0].number
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES:
+        field_desc.default_value = b''
+      else:
+        # All other types are of the "int" type.
+        field_desc.default_value = 0
+
+    field_desc.type = field_proto.type
 
   def _MakeEnumValueDescriptor(self, value_proto, index):
     """Creates a enum value descriptor object from a enum value proto.
@@ -452,76 +684,131 @@
         options=value_proto.options,
         type=None)
 
-  def _ExtractSymbols(self, desc_protos, package):
+  def _MakeServiceDescriptor(self, service_proto, service_index, scope,
+                             package, file_desc):
+    """Make a protobuf ServiceDescriptor given a ServiceDescriptorProto.
+
+    Args:
+      service_proto: The descriptor_pb2.ServiceDescriptorProto protobuf message.
+      service_index: The index of the service in the File.
+      scope: Dict mapping short and full symbols to message and enum types.
+      package: Optional package name for the new message EnumDescriptor.
+      file_desc: The file containing the service descriptor.
+
+    Returns:
+      The added descriptor.
+    """
+
+    if package:
+      service_name = '.'.join((package, service_proto.name))
+    else:
+      service_name = service_proto.name
+
+    methods = [self._MakeMethodDescriptor(method_proto, service_name, package,
+                                          scope, index)
+               for index, method_proto in enumerate(service_proto.method)]
+    desc = descriptor.ServiceDescriptor(name=service_proto.name,
+                                        full_name=service_name,
+                                        index=service_index,
+                                        methods=methods,
+                                        options=service_proto.options,
+                                        file=file_desc)
+    return desc
+
+  def _MakeMethodDescriptor(self, method_proto, service_name, package, scope,
+                            index):
+    """Creates a method descriptor from a MethodDescriptorProto.
+
+    Args:
+      method_proto: The proto describing the method.
+      service_name: The name of the containing service.
+      package: Optional package name to look up for types.
+      scope: Scope containing available types.
+      index: Index of the method in the service.
+
+    Returns:
+      An initialized MethodDescriptor object.
+    """
+    full_name = '.'.join((service_name, method_proto.name))
+    input_type = self._GetTypeFromScope(
+        package, method_proto.input_type, scope)
+    output_type = self._GetTypeFromScope(
+        package, method_proto.output_type, scope)
+    return descriptor.MethodDescriptor(name=method_proto.name,
+                                       full_name=full_name,
+                                       index=index,
+                                       containing_service=None,
+                                       input_type=input_type,
+                                       output_type=output_type,
+                                       options=method_proto.options)
+
+  def _ExtractSymbols(self, descriptors):
     """Pulls out all the symbols from descriptor protos.
 
     Args:
-      desc_protos: The protos to extract symbols from.
-      package: The package containing the descriptor type.
+      descriptors: The messages to extract descriptors from.
     Yields:
       A two element tuple of the type name and descriptor object.
     """
 
-    for desc_proto in desc_protos:
-      if package:
-        message_name = '.'.join((package, desc_proto.name))
-      else:
-        message_name = desc_proto.name
-      message_desc = self.FindMessageTypeByName(message_name)
-      yield (message_name, message_desc)
-      for symbol in self._ExtractSymbols(desc_proto.nested_type, message_name):
+    for desc in descriptors:
+      yield (_PrefixWithDot(desc.full_name), desc)
+      for symbol in self._ExtractSymbols(desc.nested_types):
         yield symbol
-      for symbol in self._ExtractEnums(desc_proto.enum_type, message_name):
-        yield symbol
+      for enum in desc.enum_types:
+        yield (_PrefixWithDot(enum.full_name), enum)
 
-  def _ExtractEnums(self, enum_protos, package):
-    """Pulls out all the symbols from enum protos.
-
-    Args:
-      enum_protos: The protos to extract symbols from.
-      package: The package containing the enum type.
-
-    Yields:
-      A two element tuple of the type name and enum descriptor object.
-    """
-
-    for enum_proto in enum_protos:
-      if package:
-        enum_name = '.'.join((package, enum_proto.name))
-      else:
-        enum_name = enum_proto.name
-      enum_desc = self.FindEnumTypeByName(enum_name)
-      yield (enum_name, enum_desc)
-
-  def _ExtractMessages(self, desc_protos):
-    """Pulls out all the message protos from descriptos.
-
-    Args:
-      desc_protos: The protos to extract symbols from.
-
-    Yields:
-      Descriptor protos.
-    """
-
-    for desc_proto in desc_protos:
-      yield desc_proto
-      for message in self._ExtractMessages(desc_proto.nested_type):
-        yield message
-
-  def _GetDeps(self, file_proto):
+  def _GetDeps(self, dependencies):
     """Recursively finds dependencies for file protos.
 
     Args:
-      file_proto: The proto to get dependencies from.
+      dependencies: The names of the files being depended on.
 
     Yields:
       Each direct and indirect dependency.
     """
 
-    for dependency in file_proto.dependency:
+    for dependency in dependencies:
       dep_desc = self.FindFileByName(dependency)
-      dep_proto = descriptor_pb2.FileDescriptorProto.FromString(
-          dep_desc.serialized_pb)
-      yield dep_proto
-      for parent_dep in self._GetDeps(dep_proto):
+      yield dep_desc
+      for parent_dep in dep_desc.dependencies:
         yield parent_dep
+
+  def _GetTypeFromScope(self, package, type_name, scope):
+    """Finds a given type name in the current scope.
+
+    Args:
+      package: The package the proto should be located in.
+      type_name: The name of the type to be found in the scope.
+      scope: Dict mapping short and full symbols to message and enum types.
+
+    Returns:
+      The descriptor for the requested type.
+    """
+    if type_name not in scope:
+      components = _PrefixWithDot(package).split('.')
+      while components:
+        possible_match = '.'.join(components + [type_name])
+        if possible_match in scope:
+          type_name = possible_match
+          break
+        else:
+          components.pop(-1)
+    return scope[type_name]
+
+
+def _PrefixWithDot(name):
+  return name if name.startswith('.') else '.%s' % name
+
+
+if _USE_C_DESCRIPTORS:
+  # TODO(amauryfa): This pool could be constructed from Python code, when we
+  # support a flag like 'use_cpp_generated_pool=True'.
+  # pylint: disable=protected-access
+  _DEFAULT = descriptor._message.default_pool
+else:
+  _DEFAULT = DescriptorPool()
+
+
+def Default():
+  return _DEFAULT
diff --git a/generator/google/protobuf/duration_pb2.py b/generator/google/protobuf/duration_pb2.py
new file mode 100644
index 0000000..f28b667
--- /dev/null
+++ b/generator/google/protobuf/duration_pb2.py
@@ -0,0 +1,78 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/duration.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/duration.proto',
+  package='google.protobuf',
+  syntax='proto3',
+  serialized_pb=_b('\n\x1egoogle/protobuf/duration.proto\x12\x0fgoogle.protobuf\"*\n\x08\x44uration\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x42|\n\x13\x63om.google.protobufB\rDurationProtoP\x01Z*github.com/golang/protobuf/ptypes/duration\xa0\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_DURATION = _descriptor.Descriptor(
+  name='Duration',
+  full_name='google.protobuf.Duration',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='seconds', full_name='google.protobuf.Duration.seconds', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nanos', full_name='google.protobuf.Duration.nanos', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=51,
+  serialized_end=93,
+)
+
+DESCRIPTOR.message_types_by_name['Duration'] = _DURATION
+
+Duration = _reflection.GeneratedProtocolMessageType('Duration', (_message.Message,), dict(
+  DESCRIPTOR = _DURATION,
+  __module__ = 'google.protobuf.duration_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Duration)
+  ))
+_sym_db.RegisterMessage(Duration)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\023com.google.protobufB\rDurationProtoP\001Z*github.com/golang/protobuf/ptypes/duration\240\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/empty_pb2.py b/generator/google/protobuf/empty_pb2.py
new file mode 100644
index 0000000..fae44a9
--- /dev/null
+++ b/generator/google/protobuf/empty_pb2.py
@@ -0,0 +1,64 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/empty.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/empty.proto',
+  package='google.protobuf',
+  syntax='proto3',
+  serialized_pb=_b('\n\x1bgoogle/protobuf/empty.proto\x12\x0fgoogle.protobuf\"\x07\n\x05\x45mptyBy\n\x13\x63om.google.protobufB\nEmptyProtoP\x01Z\'github.com/golang/protobuf/ptypes/empty\xa0\x01\x01\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_EMPTY = _descriptor.Descriptor(
+  name='Empty',
+  full_name='google.protobuf.Empty',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=48,
+  serialized_end=55,
+)
+
+DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY
+
+Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), dict(
+  DESCRIPTOR = _EMPTY,
+  __module__ = 'google.protobuf.empty_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Empty)
+  ))
+_sym_db.RegisterMessage(Empty)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\023com.google.protobufB\nEmptyProtoP\001Z\'github.com/golang/protobuf/ptypes/empty\240\001\001\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/field_mask_pb2.py b/generator/google/protobuf/field_mask_pb2.py
new file mode 100644
index 0000000..bfda7fc
--- /dev/null
+++ b/generator/google/protobuf/field_mask_pb2.py
@@ -0,0 +1,71 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/field_mask.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/field_mask.proto',
+  package='google.protobuf',
+  syntax='proto3',
+  serialized_pb=_b('\n google/protobuf/field_mask.proto\x12\x0fgoogle.protobuf\"\x1a\n\tFieldMask\x12\r\n\x05paths\x18\x01 \x03(\tBQ\n\x13\x63om.google.protobufB\x0e\x46ieldMaskProtoP\x01\xa0\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_FIELDMASK = _descriptor.Descriptor(
+  name='FieldMask',
+  full_name='google.protobuf.FieldMask',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='paths', full_name='google.protobuf.FieldMask.paths', index=0,
+      number=1, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=53,
+  serialized_end=79,
+)
+
+DESCRIPTOR.message_types_by_name['FieldMask'] = _FIELDMASK
+
+FieldMask = _reflection.GeneratedProtocolMessageType('FieldMask', (_message.Message,), dict(
+  DESCRIPTOR = _FIELDMASK,
+  __module__ = 'google.protobuf.field_mask_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.FieldMask)
+  ))
+_sym_db.RegisterMessage(FieldMask)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\023com.google.protobufB\016FieldMaskProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/_parameterized.py b/generator/google/protobuf/internal/_parameterized.py
new file mode 100644
index 0000000..23a78f0
--- /dev/null
+++ b/generator/google/protobuf/internal/_parameterized.py
@@ -0,0 +1,443 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Adds support for parameterized tests to Python's unittest TestCase class.
+
+A parameterized test is a method in a test case that is invoked with different
+argument tuples.
+
+A simple example:
+
+  class AdditionExample(parameterized.ParameterizedTestCase):
+    @parameterized.Parameters(
+       (1, 2, 3),
+       (4, 5, 9),
+       (1, 1, 3))
+    def testAddition(self, op1, op2, result):
+      self.assertEqual(result, op1 + op2)
+
+
+Each invocation is a separate test case and properly isolated just
+like a normal test method, with its own setUp/tearDown cycle. In the
+example above, there are three separate testcases, one of which will
+fail due to an assertion error (1 + 1 != 3).
+
+Parameters for invididual test cases can be tuples (with positional parameters)
+or dictionaries (with named parameters):
+
+  class AdditionExample(parameterized.ParameterizedTestCase):
+    @parameterized.Parameters(
+       {'op1': 1, 'op2': 2, 'result': 3},
+       {'op1': 4, 'op2': 5, 'result': 9},
+    )
+    def testAddition(self, op1, op2, result):
+      self.assertEqual(result, op1 + op2)
+
+If a parameterized test fails, the error message will show the
+original test name (which is modified internally) and the arguments
+for the specific invocation, which are part of the string returned by
+the shortDescription() method on test cases.
+
+The id method of the test, used internally by the unittest framework,
+is also modified to show the arguments. To make sure that test names
+stay the same across several invocations, object representations like
+
+  >>> class Foo(object):
+  ...  pass
+  >>> repr(Foo())
+  '<__main__.Foo object at 0x23d8610>'
+
+are turned into '<__main__.Foo>'. For even more descriptive names,
+especially in test logs, you can use the NamedParameters decorator. In
+this case, only tuples are supported, and the first parameters has to
+be a string (or an object that returns an apt name when converted via
+str()):
+
+  class NamedExample(parameterized.ParameterizedTestCase):
+    @parameterized.NamedParameters(
+       ('Normal', 'aa', 'aaa', True),
+       ('EmptyPrefix', '', 'abc', True),
+       ('BothEmpty', '', '', True))
+    def testStartsWith(self, prefix, string, result):
+      self.assertEqual(result, strings.startswith(prefix))
+
+Named tests also have the benefit that they can be run individually
+from the command line:
+
+  $ testmodule.py NamedExample.testStartsWithNormal
+  .
+  --------------------------------------------------------------------
+  Ran 1 test in 0.000s
+
+  OK
+
+Parameterized Classes
+=====================
+If invocation arguments are shared across test methods in a single
+ParameterizedTestCase class, instead of decorating all test methods
+individually, the class itself can be decorated:
+
+  @parameterized.Parameters(
+    (1, 2, 3)
+    (4, 5, 9))
+  class ArithmeticTest(parameterized.ParameterizedTestCase):
+    def testAdd(self, arg1, arg2, result):
+      self.assertEqual(arg1 + arg2, result)
+
+    def testSubtract(self, arg2, arg2, result):
+      self.assertEqual(result - arg1, arg2)
+
+Inputs from Iterables
+=====================
+If parameters should be shared across several test cases, or are dynamically
+created from other sources, a single non-tuple iterable can be passed into
+the decorator. This iterable will be used to obtain the test cases:
+
+  class AdditionExample(parameterized.ParameterizedTestCase):
+    @parameterized.Parameters(
+      c.op1, c.op2, c.result for c in testcases
+    )
+    def testAddition(self, op1, op2, result):
+      self.assertEqual(result, op1 + op2)
+
+
+Single-Argument Test Methods
+============================
+If a test method takes only one argument, the single argument does not need to
+be wrapped into a tuple:
+
+  class NegativeNumberExample(parameterized.ParameterizedTestCase):
+    @parameterized.Parameters(
+       -1, -3, -4, -5
+    )
+    def testIsNegative(self, arg):
+      self.assertTrue(IsNegative(arg))
+"""
+
+__author__ = 'tmarek@google.com (Torsten Marek)'
+
+import collections
+import functools
+import re
+import types
+try:
+  import unittest2 as unittest
+except ImportError:
+  import unittest
+import uuid
+
+import six
+
+ADDR_RE = re.compile(r'\<([a-zA-Z0-9_\-\.]+) object at 0x[a-fA-F0-9]+\>')
+_SEPARATOR = uuid.uuid1().hex
+_FIRST_ARG = object()
+_ARGUMENT_REPR = object()
+
+
+def _CleanRepr(obj):
+  return ADDR_RE.sub(r'<\1>', repr(obj))
+
+
+# Helper function formerly from the unittest module, removed from it in
+# Python 2.7.
+def _StrClass(cls):
+  return '%s.%s' % (cls.__module__, cls.__name__)
+
+
+def _NonStringIterable(obj):
+  return (isinstance(obj, collections.Iterable) and not
+          isinstance(obj, six.string_types))
+
+
+def _FormatParameterList(testcase_params):
+  if isinstance(testcase_params, collections.Mapping):
+    return ', '.join('%s=%s' % (argname, _CleanRepr(value))
+                     for argname, value in testcase_params.items())
+  elif _NonStringIterable(testcase_params):
+    return ', '.join(map(_CleanRepr, testcase_params))
+  else:
+    return _FormatParameterList((testcase_params,))
+
+
+class _ParameterizedTestIter(object):
+  """Callable and iterable class for producing new test cases."""
+
+  def __init__(self, test_method, testcases, naming_type):
+    """Returns concrete test functions for a test and a list of parameters.
+
+    The naming_type is used to determine the name of the concrete
+    functions as reported by the unittest framework. If naming_type is
+    _FIRST_ARG, the testcases must be tuples, and the first element must
+    have a string representation that is a valid Python identifier.
+
+    Args:
+      test_method: The decorated test method.
+      testcases: (list of tuple/dict) A list of parameter
+                 tuples/dicts for individual test invocations.
+      naming_type: The test naming type, either _NAMED or _ARGUMENT_REPR.
+    """
+    self._test_method = test_method
+    self.testcases = testcases
+    self._naming_type = naming_type
+
+  def __call__(self, *args, **kwargs):
+    raise RuntimeError('You appear to be running a parameterized test case '
+                       'without having inherited from parameterized.'
+                       'ParameterizedTestCase. This is bad because none of '
+                       'your test cases are actually being run.')
+
+  def __iter__(self):
+    test_method = self._test_method
+    naming_type = self._naming_type
+
+    def MakeBoundParamTest(testcase_params):
+      @functools.wraps(test_method)
+      def BoundParamTest(self):
+        if isinstance(testcase_params, collections.Mapping):
+          test_method(self, **testcase_params)
+        elif _NonStringIterable(testcase_params):
+          test_method(self, *testcase_params)
+        else:
+          test_method(self, testcase_params)
+
+      if naming_type is _FIRST_ARG:
+        # Signal the metaclass that the name of the test function is unique
+        # and descriptive.
+        BoundParamTest.__x_use_name__ = True
+        BoundParamTest.__name__ += str(testcase_params[0])
+        testcase_params = testcase_params[1:]
+      elif naming_type is _ARGUMENT_REPR:
+        # __x_extra_id__ is used to pass naming information to the __new__
+        # method of TestGeneratorMetaclass.
+        # The metaclass will make sure to create a unique, but nondescriptive
+        # name for this test.
+        BoundParamTest.__x_extra_id__ = '(%s)' % (
+            _FormatParameterList(testcase_params),)
+      else:
+        raise RuntimeError('%s is not a valid naming type.' % (naming_type,))
+
+      BoundParamTest.__doc__ = '%s(%s)' % (
+          BoundParamTest.__name__, _FormatParameterList(testcase_params))
+      if test_method.__doc__:
+        BoundParamTest.__doc__ += '\n%s' % (test_method.__doc__,)
+      return BoundParamTest
+    return (MakeBoundParamTest(c) for c in self.testcases)
+
+
+def _IsSingletonList(testcases):
+  """True iff testcases contains only a single non-tuple element."""
+  return len(testcases) == 1 and not isinstance(testcases[0], tuple)
+
+
+def _ModifyClass(class_object, testcases, naming_type):
+  assert not getattr(class_object, '_id_suffix', None), (
+      'Cannot add parameters to %s,'
+      ' which already has parameterized methods.' % (class_object,))
+  class_object._id_suffix = id_suffix = {}
+  # We change the size of __dict__ while we iterate over it, 
+  # which Python 3.x will complain about, so use copy().
+  for name, obj in class_object.__dict__.copy().items():
+    if (name.startswith(unittest.TestLoader.testMethodPrefix)
+        and isinstance(obj, types.FunctionType)):
+      delattr(class_object, name)
+      methods = {}
+      _UpdateClassDictForParamTestCase(
+          methods, id_suffix, name,
+          _ParameterizedTestIter(obj, testcases, naming_type))
+      for name, meth in methods.items():
+        setattr(class_object, name, meth)
+
+
+def _ParameterDecorator(naming_type, testcases):
+  """Implementation of the parameterization decorators.
+
+  Args:
+    naming_type: The naming type.
+    testcases: Testcase parameters.
+
+  Returns:
+    A function for modifying the decorated object.
+  """
+  def _Apply(obj):
+    if isinstance(obj, type):
+      _ModifyClass(
+          obj,
+          list(testcases) if not isinstance(testcases, collections.Sequence)
+          else testcases,
+          naming_type)
+      return obj
+    else:
+      return _ParameterizedTestIter(obj, testcases, naming_type)
+
+  if _IsSingletonList(testcases):
+    assert _NonStringIterable(testcases[0]), (
+        'Single parameter argument must be a non-string iterable')
+    testcases = testcases[0]
+
+  return _Apply
+
+
+def Parameters(*testcases):
+  """A decorator for creating parameterized tests.
+
+  See the module docstring for a usage example.
+  Args:
+    *testcases: Parameters for the decorated method, either a single
+                iterable, or a list of tuples/dicts/objects (for tests
+                with only one argument).
+
+  Returns:
+     A test generator to be handled by TestGeneratorMetaclass.
+  """
+  return _ParameterDecorator(_ARGUMENT_REPR, testcases)
+
+
+def NamedParameters(*testcases):
+  """A decorator for creating parameterized tests.
+
+  See the module docstring for a usage example. The first element of
+  each parameter tuple should be a string and will be appended to the
+  name of the test method.
+
+  Args:
+    *testcases: Parameters for the decorated method, either a single
+                iterable, or a list of tuples.
+
+  Returns:
+     A test generator to be handled by TestGeneratorMetaclass.
+  """
+  return _ParameterDecorator(_FIRST_ARG, testcases)
+
+
+class TestGeneratorMetaclass(type):
+  """Metaclass for test cases with test generators.
+
+  A test generator is an iterable in a testcase that produces callables. These
+  callables must be single-argument methods. These methods are injected into
+  the class namespace and the original iterable is removed. If the name of the
+  iterable conforms to the test pattern, the injected methods will be picked
+  up as tests by the unittest framework.
+
+  In general, it is supposed to be used in conjunction with the
+  Parameters decorator.
+  """
+
+  def __new__(mcs, class_name, bases, dct):
+    dct['_id_suffix'] = id_suffix = {}
+    for name, obj in dct.items():
+      if (name.startswith(unittest.TestLoader.testMethodPrefix) and
+          _NonStringIterable(obj)):
+        iterator = iter(obj)
+        dct.pop(name)
+        _UpdateClassDictForParamTestCase(dct, id_suffix, name, iterator)
+
+    return type.__new__(mcs, class_name, bases, dct)
+
+
+def _UpdateClassDictForParamTestCase(dct, id_suffix, name, iterator):
+  """Adds individual test cases to a dictionary.
+
+  Args:
+    dct: The target dictionary.
+    id_suffix: The dictionary for mapping names to test IDs.
+    name: The original name of the test case.
+    iterator: The iterator generating the individual test cases.
+  """
+  for idx, func in enumerate(iterator):
+    assert callable(func), 'Test generators must yield callables, got %r' % (
+        func,)
+    if getattr(func, '__x_use_name__', False):
+      new_name = func.__name__
+    else:
+      new_name = '%s%s%d' % (name, _SEPARATOR, idx)
+    assert new_name not in dct, (
+        'Name of parameterized test case "%s" not unique' % (new_name,))
+    dct[new_name] = func
+    id_suffix[new_name] = getattr(func, '__x_extra_id__', '')
+
+
+class ParameterizedTestCase(unittest.TestCase):
+  """Base class for test cases using the Parameters decorator."""
+  __metaclass__ = TestGeneratorMetaclass
+
+  def _OriginalName(self):
+    return self._testMethodName.split(_SEPARATOR)[0]
+
+  def __str__(self):
+    return '%s (%s)' % (self._OriginalName(), _StrClass(self.__class__))
+
+  def id(self):  # pylint: disable=invalid-name
+    """Returns the descriptive ID of the test.
+
+    This is used internally by the unittesting framework to get a name
+    for the test to be used in reports.
+
+    Returns:
+      The test id.
+    """
+    return '%s.%s%s' % (_StrClass(self.__class__),
+                        self._OriginalName(),
+                        self._id_suffix.get(self._testMethodName, ''))
+
+
+def CoopParameterizedTestCase(other_base_class):
+  """Returns a new base class with a cooperative metaclass base.
+
+  This enables the ParameterizedTestCase to be used in combination
+  with other base classes that have custom metaclasses, such as
+  mox.MoxTestBase.
+
+  Only works with metaclasses that do not override type.__new__.
+
+  Example:
+
+    import google3
+    import mox
+
+    from google3.testing.pybase import parameterized
+
+    class ExampleTest(parameterized.CoopParameterizedTestCase(mox.MoxTestBase)):
+      ...
+
+  Args:
+    other_base_class: (class) A test case base class.
+
+  Returns:
+    A new class object.
+  """
+  metaclass = type(
+      'CoopMetaclass',
+      (other_base_class.__metaclass__,
+       TestGeneratorMetaclass), {})
+  return metaclass(
+      'CoopParameterizedTestCase',
+      (other_base_class, ParameterizedTestCase), {})
diff --git a/generator/google/protobuf/internal/any_test_pb2.py b/generator/google/protobuf/internal/any_test_pb2.py
new file mode 100644
index 0000000..ded08b6
--- /dev/null
+++ b/generator/google/protobuf/internal/any_test_pb2.py
@@ -0,0 +1,79 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/any_test.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/any_test.proto',
+  package='google.protobuf.internal',
+  syntax='proto3',
+  serialized_pb=_b('\n\'google/protobuf/internal/any_test.proto\x12\x18google.protobuf.internal\x1a\x19google/protobuf/any.proto\"A\n\x07TestAny\x12#\n\x05value\x18\x01 \x01(\x0b\x32\x14.google.protobuf.Any\x12\x11\n\tint_value\x18\x02 \x01(\x05\x62\x06proto3')
+  ,
+  dependencies=[google_dot_protobuf_dot_any__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_TESTANY = _descriptor.Descriptor(
+  name='TestAny',
+  full_name='google.protobuf.internal.TestAny',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.internal.TestAny.value', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='int_value', full_name='google.protobuf.internal.TestAny.int_value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=96,
+  serialized_end=161,
+)
+
+_TESTANY.fields_by_name['value'].message_type = google_dot_protobuf_dot_any__pb2._ANY
+DESCRIPTOR.message_types_by_name['TestAny'] = _TESTANY
+
+TestAny = _reflection.GeneratedProtocolMessageType('TestAny', (_message.Message,), dict(
+  DESCRIPTOR = _TESTANY,
+  __module__ = 'google.protobuf.internal.any_test_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.internal.TestAny)
+  ))
+_sym_db.RegisterMessage(TestAny)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/api_implementation.py b/generator/google/protobuf/internal/api_implementation.py
index ce02a32..460a4a6 100644
--- a/generator/google/protobuf/internal/api_implementation.py
+++ b/generator/google/protobuf/internal/api_implementation.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -28,53 +28,78 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+"""Determine which implementation of the protobuf API is used in this process.
 """
-This module is the central entity that determines which implementation of the
-API is used.
-"""
-
-__author__ = 'petar@google.com (Petar Petrov)'
 
 import os
-# This environment variable can be used to switch to a certain implementation
-# of the Python API. Right now only 'python' and 'cpp' are valid values. Any
-# other value will be ignored.
-_implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION',
-                                 'python')
+import warnings
+import sys
 
+try:
+  # pylint: disable=g-import-not-at-top
+  from google.protobuf.internal import _api_implementation
+  # The compile-time constants in the _api_implementation module can be used to
+  # switch to a certain implementation of the Python API at build time.
+  _api_version = _api_implementation.api_version
+  _proto_extension_modules_exist_in_build = True
+except ImportError:
+  _api_version = -1  # Unspecified by compiler flags.
+  _proto_extension_modules_exist_in_build = False
+
+if _api_version == 1:
+  raise ValueError('api_version=1 is no longer supported.')
+if _api_version < 0:  # Still unspecified?
+  try:
+    # The presence of this module in a build allows the proto implementation to
+    # be upgraded merely via build deps rather than a compiler flag or the
+    # runtime environment variable.
+    # pylint: disable=g-import-not-at-top
+    from google.protobuf import _use_fast_cpp_protos
+    # Work around a known issue in the classic bootstrap .par import hook.
+    if not _use_fast_cpp_protos:
+      raise ImportError('_use_fast_cpp_protos import succeeded but was None')
+    del _use_fast_cpp_protos
+    _api_version = 2
+  except ImportError:
+    if _proto_extension_modules_exist_in_build:
+      if sys.version_info[0] >= 3:  # Python 3 defaults to C++ impl v2.
+        _api_version = 2
+      # TODO(b/17427486): Make Python 2 default to C++ impl v2.
+
+_default_implementation_type = (
+    'python' if _api_version <= 0 else 'cpp')
+
+# This environment variable can be used to switch to a certain implementation
+# of the Python API, overriding the compile-time constants in the
+# _api_implementation module. Right now only 'python' and 'cpp' are valid
+# values. Any other value will be ignored.
+_implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION',
+                                 _default_implementation_type)
 
 if _implementation_type != 'python':
-  # For now, by default use the pure-Python implementation.
-  # The code below checks if the C extension is available and
-  # uses it if it is available.
   _implementation_type = 'cpp'
-  ## Determine automatically which implementation to use.
-  #try:
-  #  from google.protobuf.internal import cpp_message
-  #  _implementation_type = 'cpp'
-  #except ImportError, e:
-  #  _implementation_type = 'python'
 
+if 'PyPy' in sys.version and _implementation_type == 'cpp':
+  warnings.warn('PyPy does not work yet with cpp protocol buffers. '
+                'Falling back to the python implementation.')
+  _implementation_type = 'python'
 
 # This environment variable can be used to switch between the two
-# 'cpp' implementations. Right now only 1 and 2 are valid values. Any
-# other value will be ignored.
+# 'cpp' implementations, overriding the compile-time constants in the
+# _api_implementation module. Right now only '2' is supported. Any other
+# value will cause an error to be raised.
 _implementation_version_str = os.getenv(
-    'PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION',
-    '1')
+    'PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION', '2')
 
-
-if _implementation_version_str not in ('1', '2'):
+if _implementation_version_str != '2':
   raise ValueError(
-      "unsupported PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION: '" +
-      _implementation_version_str + "' (supported versions: 1, 2)"
+      'unsupported PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION: "' +
+      _implementation_version_str + '" (supported versions: 2)'
       )
 
-
 _implementation_version = int(_implementation_version_str)
 
 
-
 # Usage of this function is discouraged. Clients shouldn't care which
 # implementation of the API is in use. Note that there is no guarantee
 # that differences between APIs will be maintained.
@@ -82,6 +107,7 @@
 def Type():
   return _implementation_type
 
+
 # See comment on 'Type' above.
 def Version():
   return _implementation_version
diff --git a/generator/google/protobuf/internal/containers.py b/generator/google/protobuf/internal/containers.py
index 34b35f8..ce46d08 100644
--- a/generator/google/protobuf/internal/containers.py
+++ b/generator/google/protobuf/internal/containers.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -41,6 +41,146 @@
 
 __author__ = 'petar@google.com (Petar Petrov)'
 
+import collections
+import sys
+
+if sys.version_info[0] < 3:
+  # We would use collections.MutableMapping all the time, but in Python 2 it
+  # doesn't define __slots__.  This causes two significant problems:
+  #
+  # 1. we can't disallow arbitrary attribute assignment, even if our derived
+  #    classes *do* define __slots__.
+  #
+  # 2. we can't safely derive a C type from it without __slots__ defined (the
+  #    interpreter expects to find a dict at tp_dictoffset, which we can't
+  #    robustly provide.  And we don't want an instance dict anyway.
+  #
+  # So this is the Python 2.7 definition of Mapping/MutableMapping functions
+  # verbatim, except that:
+  # 1. We declare __slots__.
+  # 2. We don't declare this as a virtual base class.  The classes defined
+  #    in collections are the interesting base classes, not us.
+  #
+  # Note: deriving from object is critical.  It is the only thing that makes
+  # this a true type, allowing us to derive from it in C++ cleanly and making
+  # __slots__ properly disallow arbitrary element assignment.
+
+  class Mapping(object):
+    __slots__ = ()
+
+    def get(self, key, default=None):
+      try:
+        return self[key]
+      except KeyError:
+        return default
+
+    def __contains__(self, key):
+      try:
+        self[key]
+      except KeyError:
+        return False
+      else:
+        return True
+
+    def iterkeys(self):
+      return iter(self)
+
+    def itervalues(self):
+      for key in self:
+        yield self[key]
+
+    def iteritems(self):
+      for key in self:
+        yield (key, self[key])
+
+    def keys(self):
+      return list(self)
+
+    def items(self):
+      return [(key, self[key]) for key in self]
+
+    def values(self):
+      return [self[key] for key in self]
+
+    # Mappings are not hashable by default, but subclasses can change this
+    __hash__ = None
+
+    def __eq__(self, other):
+      if not isinstance(other, collections.Mapping):
+        return NotImplemented
+      return dict(self.items()) == dict(other.items())
+
+    def __ne__(self, other):
+      return not (self == other)
+
+  class MutableMapping(Mapping):
+    __slots__ = ()
+
+    __marker = object()
+
+    def pop(self, key, default=__marker):
+      try:
+        value = self[key]
+      except KeyError:
+        if default is self.__marker:
+          raise
+        return default
+      else:
+        del self[key]
+        return value
+
+    def popitem(self):
+      try:
+        key = next(iter(self))
+      except StopIteration:
+        raise KeyError
+      value = self[key]
+      del self[key]
+      return key, value
+
+    def clear(self):
+      try:
+        while True:
+          self.popitem()
+      except KeyError:
+        pass
+
+    def update(*args, **kwds):
+      if len(args) > 2:
+        raise TypeError("update() takes at most 2 positional "
+                        "arguments ({} given)".format(len(args)))
+      elif not args:
+        raise TypeError("update() takes at least 1 argument (0 given)")
+      self = args[0]
+      other = args[1] if len(args) >= 2 else ()
+
+      if isinstance(other, Mapping):
+        for key in other:
+          self[key] = other[key]
+      elif hasattr(other, "keys"):
+        for key in other.keys():
+          self[key] = other[key]
+      else:
+        for key, value in other:
+          self[key] = value
+      for key, value in kwds.items():
+        self[key] = value
+
+    def setdefault(self, key, default=None):
+      try:
+        return self[key]
+      except KeyError:
+        self[key] = default
+      return default
+
+  collections.Mapping.register(Mapping)
+  collections.MutableMapping.register(MutableMapping)
+
+else:
+  # In Python 3 we can just use MutableMapping directly, because it defines
+  # __slots__.
+  MutableMapping = collections.MutableMapping
+
 
 class BaseContainer(object):
 
@@ -108,29 +248,34 @@
 
   def append(self, value):
     """Appends an item to the list. Similar to list.append()."""
-    self._type_checker.CheckValue(value)
-    self._values.append(value)
+    self._values.append(self._type_checker.CheckValue(value))
     if not self._message_listener.dirty:
       self._message_listener.Modified()
 
   def insert(self, key, value):
     """Inserts the item at the specified position. Similar to list.insert()."""
-    self._type_checker.CheckValue(value)
-    self._values.insert(key, value)
+    self._values.insert(key, self._type_checker.CheckValue(value))
     if not self._message_listener.dirty:
       self._message_listener.Modified()
 
   def extend(self, elem_seq):
-    """Extends by appending the given sequence. Similar to list.extend()."""
-    if not elem_seq:
-      return
+    """Extends by appending the given iterable. Similar to list.extend()."""
 
-    new_values = []
-    for elem in elem_seq:
-      self._type_checker.CheckValue(elem)
-      new_values.append(elem)
-    self._values.extend(new_values)
-    self._message_listener.Modified()
+    if elem_seq is None:
+      return
+    try:
+      elem_seq_iter = iter(elem_seq)
+    except TypeError:
+      if not elem_seq:
+        # silently ignore falsy inputs :-/.
+        # TODO(ptucker): Deprecate this behavior. b/18413862
+        return
+      raise
+
+    new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter]
+    if new_values:
+      self._values.extend(new_values)
+      self._message_listener.Modified()
 
   def MergeFrom(self, other):
     """Appends the contents of another repeated field of the same type to this
@@ -144,11 +289,21 @@
     self._values.remove(elem)
     self._message_listener.Modified()
 
+  def pop(self, key=-1):
+    """Removes and returns an item at a given index. Similar to list.pop()."""
+    value = self._values[key]
+    self.__delitem__(key)
+    return value
+
   def __setitem__(self, key, value):
     """Sets the item on the specified position."""
-    self._type_checker.CheckValue(value)
-    self._values[key] = value
-    self._message_listener.Modified()
+    if isinstance(key, slice):  # PY3
+      if key.step is not None:
+        raise ValueError('Extended slices not supported')
+      self.__setslice__(key.start, key.stop, value)
+    else:
+      self._values[key] = self._type_checker.CheckValue(value)
+      self._message_listener.Modified()
 
   def __getslice__(self, start, stop):
     """Retrieves the subset of items from between the specified indices."""
@@ -158,8 +313,7 @@
     """Sets the subset of items from between the specified indices."""
     new_values = []
     for value in values:
-      self._type_checker.CheckValue(value)
-      new_values.append(value)
+      new_values.append(self._type_checker.CheckValue(value))
     self._values[start:stop] = new_values
     self._message_listener.Modified()
 
@@ -183,6 +337,8 @@
     # We are presumably comparing against some other sequence type.
     return other == self._values
 
+collections.MutableSequence.register(BaseContainer)
+
 
 class RepeatedCompositeFieldContainer(BaseContainer):
 
@@ -245,6 +401,12 @@
     self._values.remove(elem)
     self._message_listener.Modified()
 
+  def pop(self, key=-1):
+    """Removes and returns an item at a given index. Similar to list.pop()."""
+    value = self._values[key]
+    self.__delitem__(key)
+    return value
+
   def __getslice__(self, start, stop):
     """Retrieves the subset of items from between the specified indices."""
     return self._values[start:stop]
@@ -267,3 +429,187 @@
       raise TypeError('Can only compare repeated composite fields against '
                       'other repeated composite fields.')
     return self._values == other._values
+
+
+class ScalarMap(MutableMapping):
+
+  """Simple, type-checked, dict-like container for holding repeated scalars."""
+
+  # Disallows assignment to other attributes.
+  __slots__ = ['_key_checker', '_value_checker', '_values', '_message_listener']
+
+  def __init__(self, message_listener, key_checker, value_checker):
+    """
+    Args:
+      message_listener: A MessageListener implementation.
+        The ScalarMap will call this object's Modified() method when it
+        is modified.
+      key_checker: A type_checkers.ValueChecker instance to run on keys
+        inserted into this container.
+      value_checker: A type_checkers.ValueChecker instance to run on values
+        inserted into this container.
+    """
+    self._message_listener = message_listener
+    self._key_checker = key_checker
+    self._value_checker = value_checker
+    self._values = {}
+
+  def __getitem__(self, key):
+    try:
+      return self._values[key]
+    except KeyError:
+      key = self._key_checker.CheckValue(key)
+      val = self._value_checker.DefaultValue()
+      self._values[key] = val
+      return val
+
+  def __contains__(self, item):
+    # We check the key's type to match the strong-typing flavor of the API.
+    # Also this makes it easier to match the behavior of the C++ implementation.
+    self._key_checker.CheckValue(item)
+    return item in self._values
+
+  # We need to override this explicitly, because our defaultdict-like behavior
+  # will make the default implementation (from our base class) always insert
+  # the key.
+  def get(self, key, default=None):
+    if key in self:
+      return self[key]
+    else:
+      return default
+
+  def __setitem__(self, key, value):
+    checked_key = self._key_checker.CheckValue(key)
+    checked_value = self._value_checker.CheckValue(value)
+    self._values[checked_key] = checked_value
+    self._message_listener.Modified()
+
+  def __delitem__(self, key):
+    del self._values[key]
+    self._message_listener.Modified()
+
+  def __len__(self):
+    return len(self._values)
+
+  def __iter__(self):
+    return iter(self._values)
+
+  def __repr__(self):
+    return repr(self._values)
+
+  def MergeFrom(self, other):
+    self._values.update(other._values)
+    self._message_listener.Modified()
+
+  def InvalidateIterators(self):
+    # It appears that the only way to reliably invalidate iterators to
+    # self._values is to ensure that its size changes.
+    original = self._values
+    self._values = original.copy()
+    original[None] = None
+
+  # This is defined in the abstract base, but we can do it much more cheaply.
+  def clear(self):
+    self._values.clear()
+    self._message_listener.Modified()
+
+
+class MessageMap(MutableMapping):
+
+  """Simple, type-checked, dict-like container for with submessage values."""
+
+  # Disallows assignment to other attributes.
+  __slots__ = ['_key_checker', '_values', '_message_listener',
+               '_message_descriptor']
+
+  def __init__(self, message_listener, message_descriptor, key_checker):
+    """
+    Args:
+      message_listener: A MessageListener implementation.
+        The ScalarMap will call this object's Modified() method when it
+        is modified.
+      key_checker: A type_checkers.ValueChecker instance to run on keys
+        inserted into this container.
+      value_checker: A type_checkers.ValueChecker instance to run on values
+        inserted into this container.
+    """
+    self._message_listener = message_listener
+    self._message_descriptor = message_descriptor
+    self._key_checker = key_checker
+    self._values = {}
+
+  def __getitem__(self, key):
+    try:
+      return self._values[key]
+    except KeyError:
+      key = self._key_checker.CheckValue(key)
+      new_element = self._message_descriptor._concrete_class()
+      new_element._SetListener(self._message_listener)
+      self._values[key] = new_element
+      self._message_listener.Modified()
+
+      return new_element
+
+  def get_or_create(self, key):
+    """get_or_create() is an alias for getitem (ie. map[key]).
+
+    Args:
+      key: The key to get or create in the map.
+
+    This is useful in cases where you want to be explicit that the call is
+    mutating the map.  This can avoid lint errors for statements like this
+    that otherwise would appear to be pointless statements:
+
+      msg.my_map[key]
+    """
+    return self[key]
+
+  # We need to override this explicitly, because our defaultdict-like behavior
+  # will make the default implementation (from our base class) always insert
+  # the key.
+  def get(self, key, default=None):
+    if key in self:
+      return self[key]
+    else:
+      return default
+
+  def __contains__(self, item):
+    return item in self._values
+
+  def __setitem__(self, key, value):
+    raise ValueError('May not set values directly, call my_map[key].foo = 5')
+
+  def __delitem__(self, key):
+    del self._values[key]
+    self._message_listener.Modified()
+
+  def __len__(self):
+    return len(self._values)
+
+  def __iter__(self):
+    return iter(self._values)
+
+  def __repr__(self):
+    return repr(self._values)
+
+  def MergeFrom(self, other):
+    for key in other:
+      # According to documentation: "When parsing from the wire or when merging,
+      # if there are duplicate map keys the last key seen is used".
+      if key in self:
+        del self[key]
+      self[key].CopyFrom(other[key])
+    # self._message_listener.Modified() not required here, because
+    # mutations to submessages already propagate.
+
+  def InvalidateIterators(self):
+    # It appears that the only way to reliably invalidate iterators to
+    # self._values is to ensure that its size changes.
+    original = self._values
+    self._values = original.copy()
+    original[None] = None
+
+  # This is defined in the abstract base, but we can do it much more cheaply.
+  def clear(self):
+    self._values.clear()
+    self._message_listener.Modified()
diff --git a/generator/google/protobuf/internal/decoder.py b/generator/google/protobuf/internal/decoder.py
index cb6f572..31869e4 100644
--- a/generator/google/protobuf/internal/decoder.py
+++ b/generator/google/protobuf/internal/decoder.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -81,6 +81,12 @@
 __author__ = 'kenton@google.com (Kenton Varda)'
 
 import struct
+
+import six
+
+if six.PY3:
+  long = int
+
 from google.protobuf.internal import encoder
 from google.protobuf.internal import wire_format
 from google.protobuf import message
@@ -98,7 +104,7 @@
 _DecodeError = message.DecodeError
 
 
-def _VarintDecoder(mask):
+def _VarintDecoder(mask, result_type):
   """Return an encoder for a basic varint value (does not include tag).
 
   Decoded values will be bitwise-anded with the given mask before being
@@ -108,16 +114,16 @@
   decoder returns a (value, new_pos) pair.
   """
 
-  local_ord = ord
   def DecodeVarint(buffer, pos):
     result = 0
     shift = 0
     while 1:
-      b = local_ord(buffer[pos])
+      b = six.indexbytes(buffer, pos)
       result |= ((b & 0x7f) << shift)
       pos += 1
       if not (b & 0x80):
         result &= mask
+        result = result_type(result)
         return (result, pos)
       shift += 7
       if shift >= 64:
@@ -125,15 +131,14 @@
   return DecodeVarint
 
 
-def _SignedVarintDecoder(mask):
+def _SignedVarintDecoder(mask, result_type):
   """Like _VarintDecoder() but decodes signed values."""
 
-  local_ord = ord
   def DecodeVarint(buffer, pos):
     result = 0
     shift = 0
     while 1:
-      b = local_ord(buffer[pos])
+      b = six.indexbytes(buffer, pos)
       result |= ((b & 0x7f) << shift)
       pos += 1
       if not (b & 0x80):
@@ -142,19 +147,23 @@
           result |= ~mask
         else:
           result &= mask
+        result = result_type(result)
         return (result, pos)
       shift += 7
       if shift >= 64:
         raise _DecodeError('Too many bytes when decoding varint.')
   return DecodeVarint
 
+# We force 32-bit values to int and 64-bit values to long to make
+# alternate implementations where the distinction is more significant
+# (e.g. the C++ implementation) simpler.
 
-_DecodeVarint = _VarintDecoder((1 << 64) - 1)
-_DecodeSignedVarint = _SignedVarintDecoder((1 << 64) - 1)
+_DecodeVarint = _VarintDecoder((1 << 64) - 1, long)
+_DecodeSignedVarint = _SignedVarintDecoder((1 << 64) - 1, long)
 
 # Use these versions for values which must be limited to 32 bits.
-_DecodeVarint32 = _VarintDecoder((1 << 32) - 1)
-_DecodeSignedVarint32 = _SignedVarintDecoder((1 << 32) - 1)
+_DecodeVarint32 = _VarintDecoder((1 << 32) - 1, int)
+_DecodeSignedVarint32 = _SignedVarintDecoder((1 << 32) - 1, int)
 
 
 def ReadTag(buffer, pos):
@@ -169,7 +178,7 @@
   """
 
   start = pos
-  while ord(buffer[pos]) & 0x80:
+  while six.indexbytes(buffer, pos) & 0x80:
     pos += 1
   pos += 1
   return (buffer[start:pos], pos)
@@ -294,13 +303,12 @@
     # If this value has all its exponent bits set, then it's non-finite.
     # In Python 2.4, struct.unpack will convert it to a finite 64-bit value.
     # To avoid that, we parse it specially.
-    if ((float_bytes[3] in '\x7F\xFF')
-        and (float_bytes[2] >= '\x80')):
+    if (float_bytes[3:4] in b'\x7F\xFF' and float_bytes[2:3] >= b'\x80'):
       # If at least one significand bit is set...
-      if float_bytes[0:3] != '\x00\x00\x80':
+      if float_bytes[0:3] != b'\x00\x00\x80':
         return (_NAN, new_pos)
       # If sign bit is set...
-      if float_bytes[3] == '\xFF':
+      if float_bytes[3:4] == b'\xFF':
         return (_NEG_INF, new_pos)
       return (_POS_INF, new_pos)
 
@@ -329,9 +337,9 @@
     # If this value has all its exponent bits set and at least one significand
     # bit set, it's not a number.  In Python 2.4, struct.unpack will treat it
     # as inf or -inf.  To avoid that, we treat it specially.
-    if ((double_bytes[7] in '\x7F\xFF')
-        and (double_bytes[6] >= '\xF0')
-        and (double_bytes[0:7] != '\x00\x00\x00\x00\x00\x00\xF0')):
+    if ((double_bytes[7:8] in b'\x7F\xFF')
+        and (double_bytes[6:7] >= b'\xF0')
+        and (double_bytes[0:7] != b'\x00\x00\x00\x00\x00\x00\xF0')):
       return (_NAN, new_pos)
 
     # Note that we expect someone up-stack to catch struct.error and convert
@@ -342,10 +350,86 @@
   return _SimpleDecoder(wire_format.WIRETYPE_FIXED64, InnerDecode)
 
 
+def EnumDecoder(field_number, is_repeated, is_packed, key, new_default):
+  enum_type = key.enum_type
+  if is_packed:
+    local_DecodeVarint = _DecodeVarint
+    def DecodePackedField(buffer, pos, end, message, field_dict):
+      value = field_dict.get(key)
+      if value is None:
+        value = field_dict.setdefault(key, new_default(message))
+      (endpoint, pos) = local_DecodeVarint(buffer, pos)
+      endpoint += pos
+      if endpoint > end:
+        raise _DecodeError('Truncated message.')
+      while pos < endpoint:
+        value_start_pos = pos
+        (element, pos) = _DecodeSignedVarint32(buffer, pos)
+        if element in enum_type.values_by_number:
+          value.append(element)
+        else:
+          if not message._unknown_fields:
+            message._unknown_fields = []
+          tag_bytes = encoder.TagBytes(field_number,
+                                       wire_format.WIRETYPE_VARINT)
+          message._unknown_fields.append(
+              (tag_bytes, buffer[value_start_pos:pos]))
+      if pos > endpoint:
+        if element in enum_type.values_by_number:
+          del value[-1]   # Discard corrupt value.
+        else:
+          del message._unknown_fields[-1]
+        raise _DecodeError('Packed element was truncated.')
+      return pos
+    return DecodePackedField
+  elif is_repeated:
+    tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT)
+    tag_len = len(tag_bytes)
+    def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+      value = field_dict.get(key)
+      if value is None:
+        value = field_dict.setdefault(key, new_default(message))
+      while 1:
+        (element, new_pos) = _DecodeSignedVarint32(buffer, pos)
+        if element in enum_type.values_by_number:
+          value.append(element)
+        else:
+          if not message._unknown_fields:
+            message._unknown_fields = []
+          message._unknown_fields.append(
+              (tag_bytes, buffer[pos:new_pos]))
+        # Predict that the next tag is another copy of the same repeated
+        # field.
+        pos = new_pos + tag_len
+        if buffer[new_pos:pos] != tag_bytes or new_pos >= end:
+          # Prediction failed.  Return.
+          if new_pos > end:
+            raise _DecodeError('Truncated message.')
+          return new_pos
+    return DecodeRepeatedField
+  else:
+    def DecodeField(buffer, pos, end, message, field_dict):
+      value_start_pos = pos
+      (enum_value, pos) = _DecodeSignedVarint32(buffer, pos)
+      if pos > end:
+        raise _DecodeError('Truncated message.')
+      if enum_value in enum_type.values_by_number:
+        field_dict[key] = enum_value
+      else:
+        if not message._unknown_fields:
+          message._unknown_fields = []
+        tag_bytes = encoder.TagBytes(field_number,
+                                     wire_format.WIRETYPE_VARINT)
+        message._unknown_fields.append(
+          (tag_bytes, buffer[value_start_pos:pos]))
+      return pos
+    return DecodeField
+
+
 # --------------------------------------------------------------------
 
 
-Int32Decoder = EnumDecoder = _SimpleDecoder(
+Int32Decoder = _SimpleDecoder(
     wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32)
 
 Int64Decoder = _SimpleDecoder(
@@ -378,7 +462,15 @@
   """Returns a decoder for a string field."""
 
   local_DecodeVarint = _DecodeVarint
-  local_unicode = unicode
+  local_unicode = six.text_type
+
+  def _ConvertToUnicode(byte_str):
+    try:
+      return local_unicode(byte_str, 'utf-8')
+    except UnicodeDecodeError as e:
+      # add more information to the error message and re-raise it.
+      e.reason = '%s in field: %s' % (e, key.full_name)
+      raise
 
   assert not is_packed
   if is_repeated:
@@ -394,7 +486,7 @@
         new_pos = pos + size
         if new_pos > end:
           raise _DecodeError('Truncated string.')
-        value.append(local_unicode(buffer[pos:new_pos], 'utf-8'))
+        value.append(_ConvertToUnicode(buffer[pos:new_pos]))
         # Predict that the next tag is another copy of the same repeated field.
         pos = new_pos + tag_len
         if buffer[new_pos:pos] != tag_bytes or new_pos == end:
@@ -407,7 +499,7 @@
       new_pos = pos + size
       if new_pos > end:
         raise _DecodeError('Truncated string.')
-      field_dict[key] = local_unicode(buffer[pos:new_pos], 'utf-8')
+      field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos])
       return new_pos
     return DecodeField
 
@@ -511,9 +603,6 @@
       if value is None:
         value = field_dict.setdefault(key, new_default(message))
       while 1:
-        value = field_dict.get(key)
-        if value is None:
-          value = field_dict.setdefault(key, new_default(message))
         # Read length.
         (size, pos) = local_DecodeVarint(buffer, pos)
         new_pos = pos + size
@@ -626,13 +715,59 @@
   return DecodeItem
 
 # --------------------------------------------------------------------
+
+def MapDecoder(field_descriptor, new_default, is_message_map):
+  """Returns a decoder for a map field."""
+
+  key = field_descriptor
+  tag_bytes = encoder.TagBytes(field_descriptor.number,
+                               wire_format.WIRETYPE_LENGTH_DELIMITED)
+  tag_len = len(tag_bytes)
+  local_DecodeVarint = _DecodeVarint
+  # Can't read _concrete_class yet; might not be initialized.
+  message_type = field_descriptor.message_type
+
+  def DecodeMap(buffer, pos, end, message, field_dict):
+    submsg = message_type._concrete_class()
+    value = field_dict.get(key)
+    if value is None:
+      value = field_dict.setdefault(key, new_default(message))
+    while 1:
+      # Read length.
+      (size, pos) = local_DecodeVarint(buffer, pos)
+      new_pos = pos + size
+      if new_pos > end:
+        raise _DecodeError('Truncated message.')
+      # Read sub-message.
+      submsg.Clear()
+      if submsg._InternalParse(buffer, pos, new_pos) != new_pos:
+        # The only reason _InternalParse would return early is if it
+        # encountered an end-group tag.
+        raise _DecodeError('Unexpected end-group tag.')
+
+      if is_message_map:
+        value[submsg.key].MergeFrom(submsg.value)
+      else:
+        value[submsg.key] = submsg.value
+
+      # Predict that the next tag is another copy of the same repeated field.
+      pos = new_pos + tag_len
+      if buffer[new_pos:pos] != tag_bytes or new_pos == end:
+        # Prediction failed.  Return.
+        return new_pos
+
+  return DecodeMap
+
+# --------------------------------------------------------------------
 # Optimization is not as heavy here because calls to SkipField() are rare,
 # except for handling end-group tags.
 
 def _SkipVarint(buffer, pos, end):
   """Skip a varint value.  Returns the new position."""
-
-  while ord(buffer[pos]) & 0x80:
+  # Previously ord(buffer[pos]) raised IndexError when pos is out of range.
+  # With this code, ord(b'') raises TypeError.  Both are handled in
+  # python_message.py to generate a 'Truncated message' error.
+  while ord(buffer[pos:pos+1]) & 0x80:
     pos += 1
   pos += 1
   if pos > end:
@@ -699,7 +834,6 @@
       ]
 
   wiretype_mask = wire_format.TAG_TYPE_MASK
-  local_ord = ord
 
   def SkipField(buffer, pos, end, tag_bytes):
     """Skips a field with the specified tag.
@@ -712,7 +846,7 @@
     """
 
     # The wire type is always in the first byte since varints are little-endian.
-    wire_type = local_ord(tag_bytes[0]) & wiretype_mask
+    wire_type = ord(tag_bytes[0:1]) & wiretype_mask
     return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end)
 
   return SkipField
diff --git a/generator/google/protobuf/internal/descriptor_database_test.py b/generator/google/protobuf/internal/descriptor_database_test.py
new file mode 100644
index 0000000..5225a45
--- /dev/null
+++ b/generator/google/protobuf/internal/descriptor_database_test.py
@@ -0,0 +1,69 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Tests for google.protobuf.descriptor_database."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+
+from google.protobuf import descriptor_pb2
+from google.protobuf.internal import factory_test2_pb2
+from google.protobuf import descriptor_database
+
+
+class DescriptorDatabaseTest(unittest.TestCase):
+
+  def testAdd(self):
+    db = descriptor_database.DescriptorDatabase()
+    file_desc_proto = descriptor_pb2.FileDescriptorProto.FromString(
+        factory_test2_pb2.DESCRIPTOR.serialized_pb)
+    db.Add(file_desc_proto)
+
+    self.assertEqual(file_desc_proto, db.FindFileByName(
+        'google/protobuf/internal/factory_test2.proto'))
+    self.assertEqual(file_desc_proto, db.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory2Message'))
+    self.assertEqual(file_desc_proto, db.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory2Message.NestedFactory2Message'))
+    self.assertEqual(file_desc_proto, db.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory2Enum'))
+    self.assertEqual(file_desc_proto, db.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory2Message.NestedFactory2Enum'))
+    self.assertEqual(file_desc_proto, db.FindFileContainingSymbol(
+        'google.protobuf.python.internal.MessageWithNestedEnumOnly.NestedEnum'))
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/descriptor_pool_test.py b/generator/google/protobuf/internal/descriptor_pool_test.py
new file mode 100644
index 0000000..3c8c793
--- /dev/null
+++ b/generator/google/protobuf/internal/descriptor_pool_test.py
@@ -0,0 +1,768 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Tests for google.protobuf.descriptor_pool."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+import os
+import sys
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_import_public_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import descriptor_pb2
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import descriptor_pool_test1_pb2
+from google.protobuf.internal import descriptor_pool_test2_pb2
+from google.protobuf.internal import factory_test1_pb2
+from google.protobuf.internal import factory_test2_pb2
+from google.protobuf.internal import file_options_test_pb2
+from google.protobuf.internal import more_messages_pb2
+from google.protobuf import descriptor
+from google.protobuf import descriptor_database
+from google.protobuf import descriptor_pool
+from google.protobuf import message_factory
+from google.protobuf import symbol_database
+
+
+class DescriptorPoolTest(unittest.TestCase):
+
+  def setUp(self):
+    self.pool = descriptor_pool.DescriptorPool()
+    self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString(
+        factory_test1_pb2.DESCRIPTOR.serialized_pb)
+    self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString(
+        factory_test2_pb2.DESCRIPTOR.serialized_pb)
+    self.pool.Add(self.factory_test1_fd)
+    self.pool.Add(self.factory_test2_fd)
+
+  def testFindFileByName(self):
+    name1 = 'google/protobuf/internal/factory_test1.proto'
+    file_desc1 = self.pool.FindFileByName(name1)
+    self.assertIsInstance(file_desc1, descriptor.FileDescriptor)
+    self.assertEqual(name1, file_desc1.name)
+    self.assertEqual('google.protobuf.python.internal', file_desc1.package)
+    self.assertIn('Factory1Message', file_desc1.message_types_by_name)
+
+    name2 = 'google/protobuf/internal/factory_test2.proto'
+    file_desc2 = self.pool.FindFileByName(name2)
+    self.assertIsInstance(file_desc2, descriptor.FileDescriptor)
+    self.assertEqual(name2, file_desc2.name)
+    self.assertEqual('google.protobuf.python.internal', file_desc2.package)
+    self.assertIn('Factory2Message', file_desc2.message_types_by_name)
+
+  def testFindFileByNameFailure(self):
+    with self.assertRaises(KeyError):
+      self.pool.FindFileByName('Does not exist')
+
+  def testFindFileContainingSymbol(self):
+    file_desc1 = self.pool.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory1Message')
+    self.assertIsInstance(file_desc1, descriptor.FileDescriptor)
+    self.assertEqual('google/protobuf/internal/factory_test1.proto',
+                     file_desc1.name)
+    self.assertEqual('google.protobuf.python.internal', file_desc1.package)
+    self.assertIn('Factory1Message', file_desc1.message_types_by_name)
+
+    file_desc2 = self.pool.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory2Message')
+    self.assertIsInstance(file_desc2, descriptor.FileDescriptor)
+    self.assertEqual('google/protobuf/internal/factory_test2.proto',
+                     file_desc2.name)
+    self.assertEqual('google.protobuf.python.internal', file_desc2.package)
+    self.assertIn('Factory2Message', file_desc2.message_types_by_name)
+
+  def testFindFileContainingSymbolFailure(self):
+    with self.assertRaises(KeyError):
+      self.pool.FindFileContainingSymbol('Does not exist')
+
+  def testFindMessageTypeByName(self):
+    msg1 = self.pool.FindMessageTypeByName(
+        'google.protobuf.python.internal.Factory1Message')
+    self.assertIsInstance(msg1, descriptor.Descriptor)
+    self.assertEqual('Factory1Message', msg1.name)
+    self.assertEqual('google.protobuf.python.internal.Factory1Message',
+                     msg1.full_name)
+    self.assertEqual(None, msg1.containing_type)
+
+    nested_msg1 = msg1.nested_types[0]
+    self.assertEqual('NestedFactory1Message', nested_msg1.name)
+    self.assertEqual(msg1, nested_msg1.containing_type)
+
+    nested_enum1 = msg1.enum_types[0]
+    self.assertEqual('NestedFactory1Enum', nested_enum1.name)
+    self.assertEqual(msg1, nested_enum1.containing_type)
+
+    self.assertEqual(nested_msg1, msg1.fields_by_name[
+        'nested_factory_1_message'].message_type)
+    self.assertEqual(nested_enum1, msg1.fields_by_name[
+        'nested_factory_1_enum'].enum_type)
+
+    msg2 = self.pool.FindMessageTypeByName(
+        'google.protobuf.python.internal.Factory2Message')
+    self.assertIsInstance(msg2, descriptor.Descriptor)
+    self.assertEqual('Factory2Message', msg2.name)
+    self.assertEqual('google.protobuf.python.internal.Factory2Message',
+                     msg2.full_name)
+    self.assertIsNone(msg2.containing_type)
+
+    nested_msg2 = msg2.nested_types[0]
+    self.assertEqual('NestedFactory2Message', nested_msg2.name)
+    self.assertEqual(msg2, nested_msg2.containing_type)
+
+    nested_enum2 = msg2.enum_types[0]
+    self.assertEqual('NestedFactory2Enum', nested_enum2.name)
+    self.assertEqual(msg2, nested_enum2.containing_type)
+
+    self.assertEqual(nested_msg2, msg2.fields_by_name[
+        'nested_factory_2_message'].message_type)
+    self.assertEqual(nested_enum2, msg2.fields_by_name[
+        'nested_factory_2_enum'].enum_type)
+
+    self.assertTrue(msg2.fields_by_name['int_with_default'].has_default_value)
+    self.assertEqual(
+        1776, msg2.fields_by_name['int_with_default'].default_value)
+
+    self.assertTrue(
+        msg2.fields_by_name['double_with_default'].has_default_value)
+    self.assertEqual(
+        9.99, msg2.fields_by_name['double_with_default'].default_value)
+
+    self.assertTrue(
+        msg2.fields_by_name['string_with_default'].has_default_value)
+    self.assertEqual(
+        'hello world', msg2.fields_by_name['string_with_default'].default_value)
+
+    self.assertTrue(msg2.fields_by_name['bool_with_default'].has_default_value)
+    self.assertFalse(msg2.fields_by_name['bool_with_default'].default_value)
+
+    self.assertTrue(msg2.fields_by_name['enum_with_default'].has_default_value)
+    self.assertEqual(
+        1, msg2.fields_by_name['enum_with_default'].default_value)
+
+    msg3 = self.pool.FindMessageTypeByName(
+        'google.protobuf.python.internal.Factory2Message.NestedFactory2Message')
+    self.assertEqual(nested_msg2, msg3)
+
+    self.assertTrue(msg2.fields_by_name['bytes_with_default'].has_default_value)
+    self.assertEqual(
+        b'a\xfb\x00c',
+        msg2.fields_by_name['bytes_with_default'].default_value)
+
+    self.assertEqual(1, len(msg2.oneofs))
+    self.assertEqual(1, len(msg2.oneofs_by_name))
+    self.assertEqual(2, len(msg2.oneofs[0].fields))
+    for name in ['oneof_int', 'oneof_string']:
+      self.assertEqual(msg2.oneofs[0],
+                       msg2.fields_by_name[name].containing_oneof)
+      self.assertIn(msg2.fields_by_name[name], msg2.oneofs[0].fields)
+
+  def testFindMessageTypeByNameFailure(self):
+    with self.assertRaises(KeyError):
+      self.pool.FindMessageTypeByName('Does not exist')
+
+  def testFindEnumTypeByName(self):
+    enum1 = self.pool.FindEnumTypeByName(
+        'google.protobuf.python.internal.Factory1Enum')
+    self.assertIsInstance(enum1, descriptor.EnumDescriptor)
+    self.assertEqual(0, enum1.values_by_name['FACTORY_1_VALUE_0'].number)
+    self.assertEqual(1, enum1.values_by_name['FACTORY_1_VALUE_1'].number)
+
+    nested_enum1 = self.pool.FindEnumTypeByName(
+        'google.protobuf.python.internal.Factory1Message.NestedFactory1Enum')
+    self.assertIsInstance(nested_enum1, descriptor.EnumDescriptor)
+    self.assertEqual(
+        0, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_0'].number)
+    self.assertEqual(
+        1, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_1'].number)
+
+    enum2 = self.pool.FindEnumTypeByName(
+        'google.protobuf.python.internal.Factory2Enum')
+    self.assertIsInstance(enum2, descriptor.EnumDescriptor)
+    self.assertEqual(0, enum2.values_by_name['FACTORY_2_VALUE_0'].number)
+    self.assertEqual(1, enum2.values_by_name['FACTORY_2_VALUE_1'].number)
+
+    nested_enum2 = self.pool.FindEnumTypeByName(
+        'google.protobuf.python.internal.Factory2Message.NestedFactory2Enum')
+    self.assertIsInstance(nested_enum2, descriptor.EnumDescriptor)
+    self.assertEqual(
+        0, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_0'].number)
+    self.assertEqual(
+        1, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_1'].number)
+
+  def testFindEnumTypeByNameFailure(self):
+    with self.assertRaises(KeyError):
+      self.pool.FindEnumTypeByName('Does not exist')
+
+  def testFindFieldByName(self):
+    field = self.pool.FindFieldByName(
+        'google.protobuf.python.internal.Factory1Message.list_value')
+    self.assertEqual(field.name, 'list_value')
+    self.assertEqual(field.label, field.LABEL_REPEATED)
+    with self.assertRaises(KeyError):
+      self.pool.FindFieldByName('Does not exist')
+
+  def testFindExtensionByName(self):
+    # An extension defined in a message.
+    extension = self.pool.FindExtensionByName(
+        'google.protobuf.python.internal.Factory2Message.one_more_field')
+    self.assertEqual(extension.name, 'one_more_field')
+    # An extension defined at file scope.
+    extension = self.pool.FindExtensionByName(
+        'google.protobuf.python.internal.another_field')
+    self.assertEqual(extension.name, 'another_field')
+    self.assertEqual(extension.number, 1002)
+    with self.assertRaises(KeyError):
+      self.pool.FindFieldByName('Does not exist')
+
+  def testExtensionsAreNotFields(self):
+    with self.assertRaises(KeyError):
+      self.pool.FindFieldByName('google.protobuf.python.internal.another_field')
+    with self.assertRaises(KeyError):
+      self.pool.FindFieldByName(
+          'google.protobuf.python.internal.Factory2Message.one_more_field')
+    with self.assertRaises(KeyError):
+      self.pool.FindExtensionByName(
+          'google.protobuf.python.internal.Factory1Message.list_value')
+
+  def testUserDefinedDB(self):
+    db = descriptor_database.DescriptorDatabase()
+    self.pool = descriptor_pool.DescriptorPool(db)
+    db.Add(self.factory_test1_fd)
+    db.Add(self.factory_test2_fd)
+    self.testFindMessageTypeByName()
+
+  def testAddSerializedFile(self):
+    self.pool = descriptor_pool.DescriptorPool()
+    self.pool.AddSerializedFile(self.factory_test1_fd.SerializeToString())
+    self.pool.AddSerializedFile(self.factory_test2_fd.SerializeToString())
+    self.testFindMessageTypeByName()
+
+  def testComplexNesting(self):
+    more_messages_desc = descriptor_pb2.FileDescriptorProto.FromString(
+        more_messages_pb2.DESCRIPTOR.serialized_pb)
+    test1_desc = descriptor_pb2.FileDescriptorProto.FromString(
+        descriptor_pool_test1_pb2.DESCRIPTOR.serialized_pb)
+    test2_desc = descriptor_pb2.FileDescriptorProto.FromString(
+        descriptor_pool_test2_pb2.DESCRIPTOR.serialized_pb)
+    self.pool.Add(more_messages_desc)
+    self.pool.Add(test1_desc)
+    self.pool.Add(test2_desc)
+    TEST1_FILE.CheckFile(self, self.pool)
+    TEST2_FILE.CheckFile(self, self.pool)
+
+
+  def testEnumDefaultValue(self):
+    """Test the default value of enums which don't start at zero."""
+    def _CheckDefaultValue(file_descriptor):
+      default_value = (file_descriptor
+                       .message_types_by_name['DescriptorPoolTest1']
+                       .fields_by_name['nested_enum']
+                       .default_value)
+      self.assertEqual(default_value,
+                       descriptor_pool_test1_pb2.DescriptorPoolTest1.BETA)
+    # First check what the generated descriptor contains.
+    _CheckDefaultValue(descriptor_pool_test1_pb2.DESCRIPTOR)
+    # Then check the generated pool. Normally this is the same descriptor.
+    file_descriptor = symbol_database.Default().pool.FindFileByName(
+        'google/protobuf/internal/descriptor_pool_test1.proto')
+    self.assertIs(file_descriptor, descriptor_pool_test1_pb2.DESCRIPTOR)
+    _CheckDefaultValue(file_descriptor)
+
+    # Then check the dynamic pool and its internal DescriptorDatabase.
+    descriptor_proto = descriptor_pb2.FileDescriptorProto.FromString(
+        descriptor_pool_test1_pb2.DESCRIPTOR.serialized_pb)
+    self.pool.Add(descriptor_proto)
+    # And do the same check as above
+    file_descriptor = self.pool.FindFileByName(
+        'google/protobuf/internal/descriptor_pool_test1.proto')
+    _CheckDefaultValue(file_descriptor)
+
+  def testDefaultValueForCustomMessages(self):
+    """Check the value returned by non-existent fields."""
+    def _CheckValueAndType(value, expected_value, expected_type):
+      self.assertEqual(value, expected_value)
+      self.assertIsInstance(value, expected_type)
+
+    def _CheckDefaultValues(msg):
+      try:
+        int64 = long
+      except NameError:  # Python3
+        int64 = int
+      try:
+        unicode_type = unicode
+      except NameError:  # Python3
+        unicode_type = str
+      _CheckValueAndType(msg.optional_int32, 0, int)
+      _CheckValueAndType(msg.optional_uint64, 0, (int64, int))
+      _CheckValueAndType(msg.optional_float, 0, (float, int))
+      _CheckValueAndType(msg.optional_double, 0, (float, int))
+      _CheckValueAndType(msg.optional_bool, False, bool)
+      _CheckValueAndType(msg.optional_string, u'', unicode_type)
+      _CheckValueAndType(msg.optional_bytes, b'', bytes)
+      _CheckValueAndType(msg.optional_nested_enum, msg.FOO, int)
+    # First for the generated message
+    _CheckDefaultValues(unittest_pb2.TestAllTypes())
+    # Then for a message built with from the DescriptorPool.
+    pool = descriptor_pool.DescriptorPool()
+    pool.Add(descriptor_pb2.FileDescriptorProto.FromString(
+        unittest_import_public_pb2.DESCRIPTOR.serialized_pb))
+    pool.Add(descriptor_pb2.FileDescriptorProto.FromString(
+        unittest_import_pb2.DESCRIPTOR.serialized_pb))
+    pool.Add(descriptor_pb2.FileDescriptorProto.FromString(
+        unittest_pb2.DESCRIPTOR.serialized_pb))
+    message_class = message_factory.MessageFactory(pool).GetPrototype(
+        pool.FindMessageTypeByName(
+            unittest_pb2.TestAllTypes.DESCRIPTOR.full_name))
+    _CheckDefaultValues(message_class())
+
+
+class ProtoFile(object):
+
+  def __init__(self, name, package, messages, dependencies=None,
+               public_dependencies=None):
+    self.name = name
+    self.package = package
+    self.messages = messages
+    self.dependencies = dependencies or []
+    self.public_dependencies = public_dependencies or []
+
+  def CheckFile(self, test, pool):
+    file_desc = pool.FindFileByName(self.name)
+    test.assertEqual(self.name, file_desc.name)
+    test.assertEqual(self.package, file_desc.package)
+    dependencies_names = [f.name for f in file_desc.dependencies]
+    test.assertEqual(self.dependencies, dependencies_names)
+    public_dependencies_names = [f.name for f in file_desc.public_dependencies]
+    test.assertEqual(self.public_dependencies, public_dependencies_names)
+    for name, msg_type in self.messages.items():
+      msg_type.CheckType(test, None, name, file_desc)
+
+
+class EnumType(object):
+
+  def __init__(self, values):
+    self.values = values
+
+  def CheckType(self, test, msg_desc, name, file_desc):
+    enum_desc = msg_desc.enum_types_by_name[name]
+    test.assertEqual(name, enum_desc.name)
+    expected_enum_full_name = '.'.join([msg_desc.full_name, name])
+    test.assertEqual(expected_enum_full_name, enum_desc.full_name)
+    test.assertEqual(msg_desc, enum_desc.containing_type)
+    test.assertEqual(file_desc, enum_desc.file)
+    for index, (value, number) in enumerate(self.values):
+      value_desc = enum_desc.values_by_name[value]
+      test.assertEqual(value, value_desc.name)
+      test.assertEqual(index, value_desc.index)
+      test.assertEqual(number, value_desc.number)
+      test.assertEqual(enum_desc, value_desc.type)
+      test.assertIn(value, msg_desc.enum_values_by_name)
+
+
+class MessageType(object):
+
+  def __init__(self, type_dict, field_list, is_extendable=False,
+               extensions=None):
+    self.type_dict = type_dict
+    self.field_list = field_list
+    self.is_extendable = is_extendable
+    self.extensions = extensions or []
+
+  def CheckType(self, test, containing_type_desc, name, file_desc):
+    if containing_type_desc is None:
+      desc = file_desc.message_types_by_name[name]
+      expected_full_name = '.'.join([file_desc.package, name])
+    else:
+      desc = containing_type_desc.nested_types_by_name[name]
+      expected_full_name = '.'.join([containing_type_desc.full_name, name])
+
+    test.assertEqual(name, desc.name)
+    test.assertEqual(expected_full_name, desc.full_name)
+    test.assertEqual(containing_type_desc, desc.containing_type)
+    test.assertEqual(desc.file, file_desc)
+    test.assertEqual(self.is_extendable, desc.is_extendable)
+    for name, subtype in self.type_dict.items():
+      subtype.CheckType(test, desc, name, file_desc)
+
+    for index, (name, field) in enumerate(self.field_list):
+      field.CheckField(test, desc, name, index)
+
+    for index, (name, field) in enumerate(self.extensions):
+      field.CheckField(test, desc, name, index)
+
+
+class EnumField(object):
+
+  def __init__(self, number, type_name, default_value):
+    self.number = number
+    self.type_name = type_name
+    self.default_value = default_value
+
+  def CheckField(self, test, msg_desc, name, index):
+    field_desc = msg_desc.fields_by_name[name]
+    enum_desc = msg_desc.enum_types_by_name[self.type_name]
+    test.assertEqual(name, field_desc.name)
+    expected_field_full_name = '.'.join([msg_desc.full_name, name])
+    test.assertEqual(expected_field_full_name, field_desc.full_name)
+    test.assertEqual(index, field_desc.index)
+    test.assertEqual(self.number, field_desc.number)
+    test.assertEqual(descriptor.FieldDescriptor.TYPE_ENUM, field_desc.type)
+    test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_ENUM,
+                     field_desc.cpp_type)
+    test.assertTrue(field_desc.has_default_value)
+    test.assertEqual(enum_desc.values_by_name[self.default_value].number,
+                     field_desc.default_value)
+    test.assertEqual(msg_desc, field_desc.containing_type)
+    test.assertEqual(enum_desc, field_desc.enum_type)
+
+
+class MessageField(object):
+
+  def __init__(self, number, type_name):
+    self.number = number
+    self.type_name = type_name
+
+  def CheckField(self, test, msg_desc, name, index):
+    field_desc = msg_desc.fields_by_name[name]
+    field_type_desc = msg_desc.nested_types_by_name[self.type_name]
+    test.assertEqual(name, field_desc.name)
+    expected_field_full_name = '.'.join([msg_desc.full_name, name])
+    test.assertEqual(expected_field_full_name, field_desc.full_name)
+    test.assertEqual(index, field_desc.index)
+    test.assertEqual(self.number, field_desc.number)
+    test.assertEqual(descriptor.FieldDescriptor.TYPE_MESSAGE, field_desc.type)
+    test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_MESSAGE,
+                     field_desc.cpp_type)
+    test.assertFalse(field_desc.has_default_value)
+    test.assertEqual(msg_desc, field_desc.containing_type)
+    test.assertEqual(field_type_desc, field_desc.message_type)
+
+
+class StringField(object):
+
+  def __init__(self, number, default_value):
+    self.number = number
+    self.default_value = default_value
+
+  def CheckField(self, test, msg_desc, name, index):
+    field_desc = msg_desc.fields_by_name[name]
+    test.assertEqual(name, field_desc.name)
+    expected_field_full_name = '.'.join([msg_desc.full_name, name])
+    test.assertEqual(expected_field_full_name, field_desc.full_name)
+    test.assertEqual(index, field_desc.index)
+    test.assertEqual(self.number, field_desc.number)
+    test.assertEqual(descriptor.FieldDescriptor.TYPE_STRING, field_desc.type)
+    test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_STRING,
+                     field_desc.cpp_type)
+    test.assertTrue(field_desc.has_default_value)
+    test.assertEqual(self.default_value, field_desc.default_value)
+
+
+class ExtensionField(object):
+
+  def __init__(self, number, extended_type):
+    self.number = number
+    self.extended_type = extended_type
+
+  def CheckField(self, test, msg_desc, name, index):
+    field_desc = msg_desc.extensions_by_name[name]
+    test.assertEqual(name, field_desc.name)
+    expected_field_full_name = '.'.join([msg_desc.full_name, name])
+    test.assertEqual(expected_field_full_name, field_desc.full_name)
+    test.assertEqual(self.number, field_desc.number)
+    test.assertEqual(index, field_desc.index)
+    test.assertEqual(descriptor.FieldDescriptor.TYPE_MESSAGE, field_desc.type)
+    test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_MESSAGE,
+                     field_desc.cpp_type)
+    test.assertFalse(field_desc.has_default_value)
+    test.assertTrue(field_desc.is_extension)
+    test.assertEqual(msg_desc, field_desc.extension_scope)
+    test.assertEqual(msg_desc, field_desc.message_type)
+    test.assertEqual(self.extended_type, field_desc.containing_type.name)
+
+
+class AddDescriptorTest(unittest.TestCase):
+
+  def _TestMessage(self, prefix):
+    pool = descriptor_pool.DescriptorPool()
+    pool.AddDescriptor(unittest_pb2.TestAllTypes.DESCRIPTOR)
+    self.assertEqual(
+        'protobuf_unittest.TestAllTypes',
+        pool.FindMessageTypeByName(
+            prefix + 'protobuf_unittest.TestAllTypes').full_name)
+
+    # AddDescriptor is not recursive.
+    with self.assertRaises(KeyError):
+      pool.FindMessageTypeByName(
+          prefix + 'protobuf_unittest.TestAllTypes.NestedMessage')
+
+    pool.AddDescriptor(unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR)
+    self.assertEqual(
+        'protobuf_unittest.TestAllTypes.NestedMessage',
+        pool.FindMessageTypeByName(
+            prefix + 'protobuf_unittest.TestAllTypes.NestedMessage').full_name)
+
+    # Files are implicitly also indexed when messages are added.
+    self.assertEqual(
+        'google/protobuf/unittest.proto',
+        pool.FindFileByName(
+            'google/protobuf/unittest.proto').name)
+
+    self.assertEqual(
+        'google/protobuf/unittest.proto',
+        pool.FindFileContainingSymbol(
+            prefix + 'protobuf_unittest.TestAllTypes.NestedMessage').name)
+
+  @unittest.skipIf(api_implementation.Type() == 'cpp',
+                   'With the cpp implementation, Add() must be called first')
+  def testMessage(self):
+    self._TestMessage('')
+    self._TestMessage('.')
+
+  def _TestEnum(self, prefix):
+    pool = descriptor_pool.DescriptorPool()
+    pool.AddEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR)
+    self.assertEqual(
+        'protobuf_unittest.ForeignEnum',
+        pool.FindEnumTypeByName(
+            prefix + 'protobuf_unittest.ForeignEnum').full_name)
+
+    # AddEnumDescriptor is not recursive.
+    with self.assertRaises(KeyError):
+      pool.FindEnumTypeByName(
+          prefix + 'protobuf_unittest.ForeignEnum.NestedEnum')
+
+    pool.AddEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR)
+    self.assertEqual(
+        'protobuf_unittest.TestAllTypes.NestedEnum',
+        pool.FindEnumTypeByName(
+            prefix + 'protobuf_unittest.TestAllTypes.NestedEnum').full_name)
+
+    # Files are implicitly also indexed when enums are added.
+    self.assertEqual(
+        'google/protobuf/unittest.proto',
+        pool.FindFileByName(
+            'google/protobuf/unittest.proto').name)
+
+    self.assertEqual(
+        'google/protobuf/unittest.proto',
+        pool.FindFileContainingSymbol(
+            prefix + 'protobuf_unittest.TestAllTypes.NestedEnum').name)
+
+  @unittest.skipIf(api_implementation.Type() == 'cpp',
+                   'With the cpp implementation, Add() must be called first')
+  def testEnum(self):
+    self._TestEnum('')
+    self._TestEnum('.')
+
+  @unittest.skipIf(api_implementation.Type() == 'cpp',
+                   'With the cpp implementation, Add() must be called first')
+  def testFile(self):
+    pool = descriptor_pool.DescriptorPool()
+    pool.AddFileDescriptor(unittest_pb2.DESCRIPTOR)
+    self.assertEqual(
+        'google/protobuf/unittest.proto',
+        pool.FindFileByName(
+            'google/protobuf/unittest.proto').name)
+
+    # AddFileDescriptor is not recursive; messages and enums within files must
+    # be explicitly registered.
+    with self.assertRaises(KeyError):
+      pool.FindFileContainingSymbol(
+          'protobuf_unittest.TestAllTypes')
+
+  def testEmptyDescriptorPool(self):
+    # Check that an empty DescriptorPool() contains no messages.
+    pool = descriptor_pool.DescriptorPool()
+    proto_file_name = descriptor_pb2.DESCRIPTOR.name
+    self.assertRaises(KeyError, pool.FindFileByName, proto_file_name)
+    # Add the above file to the pool
+    file_descriptor = descriptor_pb2.FileDescriptorProto()
+    descriptor_pb2.DESCRIPTOR.CopyToProto(file_descriptor)
+    pool.Add(file_descriptor)
+    # Now it exists.
+    self.assertTrue(pool.FindFileByName(proto_file_name))
+
+  def testCustomDescriptorPool(self):
+    # Create a new pool, and add a file descriptor.
+    pool = descriptor_pool.DescriptorPool()
+    file_desc = descriptor_pb2.FileDescriptorProto(
+        name='some/file.proto', package='package')
+    file_desc.message_type.add(name='Message')
+    pool.Add(file_desc)
+    self.assertEqual(pool.FindFileByName('some/file.proto').name,
+                     'some/file.proto')
+    self.assertEqual(pool.FindMessageTypeByName('package.Message').name,
+                     'Message')
+
+  def testFileDescriptorOptionsWithCustomDescriptorPool(self):
+    # Create a descriptor pool, and add a new FileDescriptorProto to it.
+    pool = descriptor_pool.DescriptorPool()
+    file_name = 'file_descriptor_options_with_custom_descriptor_pool.proto'
+    file_descriptor_proto = descriptor_pb2.FileDescriptorProto(name=file_name)
+    extension_id = file_options_test_pb2.foo_options
+    file_descriptor_proto.options.Extensions[extension_id].foo_name = 'foo'
+    pool.Add(file_descriptor_proto)
+    # The options set on the FileDescriptorProto should be available in the
+    # descriptor even if they contain extensions that cannot be deserialized
+    # using the pool.
+    file_descriptor = pool.FindFileByName(file_name)
+    options = file_descriptor.GetOptions()
+    self.assertEqual('foo', options.Extensions[extension_id].foo_name)
+    # The object returned by GetOptions() is cached.
+    self.assertIs(options, file_descriptor.GetOptions())
+
+
+@unittest.skipIf(
+    api_implementation.Type() != 'cpp',
+    'default_pool is only supported by the C++ implementation')
+class DefaultPoolTest(unittest.TestCase):
+
+  def testFindMethods(self):
+    # pylint: disable=g-import-not-at-top
+    from google.protobuf.pyext import _message
+    pool = _message.default_pool
+    self.assertIs(
+        pool.FindFileByName('google/protobuf/unittest.proto'),
+        unittest_pb2.DESCRIPTOR)
+    self.assertIs(
+        pool.FindMessageTypeByName('protobuf_unittest.TestAllTypes'),
+        unittest_pb2.TestAllTypes.DESCRIPTOR)
+    self.assertIs(
+        pool.FindFieldByName('protobuf_unittest.TestAllTypes.optional_int32'),
+        unittest_pb2.TestAllTypes.DESCRIPTOR.fields_by_name['optional_int32'])
+    self.assertIs(
+        pool.FindExtensionByName('protobuf_unittest.optional_int32_extension'),
+        unittest_pb2.DESCRIPTOR.extensions_by_name['optional_int32_extension'])
+    self.assertIs(
+        pool.FindEnumTypeByName('protobuf_unittest.ForeignEnum'),
+        unittest_pb2.ForeignEnum.DESCRIPTOR)
+    self.assertIs(
+        pool.FindOneofByName('protobuf_unittest.TestAllTypes.oneof_field'),
+        unittest_pb2.TestAllTypes.DESCRIPTOR.oneofs_by_name['oneof_field'])
+
+  def testAddFileDescriptor(self):
+    # pylint: disable=g-import-not-at-top
+    from google.protobuf.pyext import _message
+    pool = _message.default_pool
+    file_desc = descriptor_pb2.FileDescriptorProto(name='some/file.proto')
+    pool.Add(file_desc)
+    pool.AddSerializedFile(file_desc.SerializeToString())
+
+
+TEST1_FILE = ProtoFile(
+    'google/protobuf/internal/descriptor_pool_test1.proto',
+    'google.protobuf.python.internal',
+    {
+        'DescriptorPoolTest1': MessageType({
+            'NestedEnum': EnumType([('ALPHA', 1), ('BETA', 2)]),
+            'NestedMessage': MessageType({
+                'NestedEnum': EnumType([('EPSILON', 5), ('ZETA', 6)]),
+                'DeepNestedMessage': MessageType({
+                    'NestedEnum': EnumType([('ETA', 7), ('THETA', 8)]),
+                }, [
+                    ('nested_enum', EnumField(1, 'NestedEnum', 'ETA')),
+                    ('nested_field', StringField(2, 'theta')),
+                ]),
+            }, [
+                ('nested_enum', EnumField(1, 'NestedEnum', 'ZETA')),
+                ('nested_field', StringField(2, 'beta')),
+                ('deep_nested_message', MessageField(3, 'DeepNestedMessage')),
+            ])
+        }, [
+            ('nested_enum', EnumField(1, 'NestedEnum', 'BETA')),
+            ('nested_message', MessageField(2, 'NestedMessage')),
+        ], is_extendable=True),
+
+        'DescriptorPoolTest2': MessageType({
+            'NestedEnum': EnumType([('GAMMA', 3), ('DELTA', 4)]),
+            'NestedMessage': MessageType({
+                'NestedEnum': EnumType([('IOTA', 9), ('KAPPA', 10)]),
+                'DeepNestedMessage': MessageType({
+                    'NestedEnum': EnumType([('LAMBDA', 11), ('MU', 12)]),
+                }, [
+                    ('nested_enum', EnumField(1, 'NestedEnum', 'MU')),
+                    ('nested_field', StringField(2, 'lambda')),
+                ]),
+            }, [
+                ('nested_enum', EnumField(1, 'NestedEnum', 'IOTA')),
+                ('nested_field', StringField(2, 'delta')),
+                ('deep_nested_message', MessageField(3, 'DeepNestedMessage')),
+            ])
+        }, [
+            ('nested_enum', EnumField(1, 'NestedEnum', 'GAMMA')),
+            ('nested_message', MessageField(2, 'NestedMessage')),
+        ]),
+    })
+
+
+TEST2_FILE = ProtoFile(
+    'google/protobuf/internal/descriptor_pool_test2.proto',
+    'google.protobuf.python.internal',
+    {
+        'DescriptorPoolTest3': MessageType({
+            'NestedEnum': EnumType([('NU', 13), ('XI', 14)]),
+            'NestedMessage': MessageType({
+                'NestedEnum': EnumType([('OMICRON', 15), ('PI', 16)]),
+                'DeepNestedMessage': MessageType({
+                    'NestedEnum': EnumType([('RHO', 17), ('SIGMA', 18)]),
+                }, [
+                    ('nested_enum', EnumField(1, 'NestedEnum', 'RHO')),
+                    ('nested_field', StringField(2, 'sigma')),
+                ]),
+            }, [
+                ('nested_enum', EnumField(1, 'NestedEnum', 'PI')),
+                ('nested_field', StringField(2, 'nu')),
+                ('deep_nested_message', MessageField(3, 'DeepNestedMessage')),
+            ])
+        }, [
+            ('nested_enum', EnumField(1, 'NestedEnum', 'XI')),
+            ('nested_message', MessageField(2, 'NestedMessage')),
+        ], extensions=[
+            ('descriptor_pool_test',
+             ExtensionField(1001, 'DescriptorPoolTest1')),
+        ]),
+    },
+    dependencies=['google/protobuf/internal/descriptor_pool_test1.proto',
+                  'google/protobuf/internal/more_messages.proto'],
+    public_dependencies=['google/protobuf/internal/more_messages.proto'])
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/descriptor_pool_test1_pb2.py b/generator/google/protobuf/internal/descriptor_pool_test1_pb2.py
new file mode 100644
index 0000000..f093d83
--- /dev/null
+++ b/generator/google/protobuf/internal/descriptor_pool_test1_pb2.py
@@ -0,0 +1,474 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/descriptor_pool_test1.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/descriptor_pool_test1.proto',
+  package='google.protobuf.python.internal',
+  syntax='proto2',
+  serialized_pb=_b('\n4google/protobuf/internal/descriptor_pool_test1.proto\x12\x1fgoogle.protobuf.python.internal\"\xfb\x05\n\x13\x44\x65scriptorPoolTest1\x12Z\n\x0bnested_enum\x18\x01 \x01(\x0e\x32?.google.protobuf.python.internal.DescriptorPoolTest1.NestedEnum:\x04\x42\x45TA\x12Z\n\x0enested_message\x18\x02 \x01(\x0b\x32\x42.google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage\x1a\xfd\x03\n\rNestedMessage\x12h\n\x0bnested_enum\x18\x01 \x01(\x0e\x32M.google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage.NestedEnum:\x04ZETA\x12\x1a\n\x0cnested_field\x18\x02 \x01(\t:\x04\x62\x65ta\x12q\n\x13\x64\x65\x65p_nested_message\x18\x03 \x01(\x0b\x32T.google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage.DeepNestedMessage\x1a\xcd\x01\n\x11\x44\x65\x65pNestedMessage\x12y\n\x0bnested_enum\x18\x01 \x01(\x0e\x32_.google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage.DeepNestedMessage.NestedEnum:\x03\x45TA\x12\x1b\n\x0cnested_field\x18\x02 \x01(\t:\x05theta\" \n\nNestedEnum\x12\x07\n\x03\x45TA\x10\x07\x12\t\n\x05THETA\x10\x08\"#\n\nNestedEnum\x12\x0b\n\x07\x45PSILON\x10\x05\x12\x08\n\x04ZETA\x10\x06\"!\n\nNestedEnum\x12\t\n\x05\x41LPHA\x10\x01\x12\x08\n\x04\x42\x45TA\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xf1\x05\n\x13\x44\x65scriptorPoolTest2\x12[\n\x0bnested_enum\x18\x01 \x01(\x0e\x32?.google.protobuf.python.internal.DescriptorPoolTest2.NestedEnum:\x05GAMMA\x12Z\n\x0enested_message\x18\x02 \x01(\x0b\x32\x42.google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage\x1a\xfc\x03\n\rNestedMessage\x12h\n\x0bnested_enum\x18\x01 \x01(\x0e\x32M.google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage.NestedEnum:\x04IOTA\x12\x1b\n\x0cnested_field\x18\x02 \x01(\t:\x05\x64\x65lta\x12q\n\x13\x64\x65\x65p_nested_message\x18\x03 \x01(\x0b\x32T.google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage.DeepNestedMessage\x1a\xcd\x01\n\x11\x44\x65\x65pNestedMessage\x12x\n\x0bnested_enum\x18\x01 \x01(\x0e\x32_.google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage.DeepNestedMessage.NestedEnum:\x02MU\x12\x1c\n\x0cnested_field\x18\x02 \x01(\t:\x06lambda\" \n\nNestedEnum\x12\n\n\x06LAMBDA\x10\x0b\x12\x06\n\x02MU\x10\x0c\"!\n\nNestedEnum\x12\x08\n\x04IOTA\x10\t\x12\t\n\x05KAPPA\x10\n\"\"\n\nNestedEnum\x12\t\n\x05GAMMA\x10\x03\x12\t\n\x05\x44\x45LTA\x10\x04')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+_DESCRIPTORPOOLTEST1_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage.DeepNestedMessage.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='ETA', index=0, number=7,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='THETA', index=1, number=8,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=738,
+  serialized_end=770,
+)
+_sym_db.RegisterEnumDescriptor(_DESCRIPTORPOOLTEST1_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM)
+
+_DESCRIPTORPOOLTEST1_NESTEDMESSAGE_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='EPSILON', index=0, number=5,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='ZETA', index=1, number=6,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=772,
+  serialized_end=807,
+)
+_sym_db.RegisterEnumDescriptor(_DESCRIPTORPOOLTEST1_NESTEDMESSAGE_NESTEDENUM)
+
+_DESCRIPTORPOOLTEST1_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest1.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='ALPHA', index=0, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BETA', index=1, number=2,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=809,
+  serialized_end=842,
+)
+_sym_db.RegisterEnumDescriptor(_DESCRIPTORPOOLTEST1_NESTEDENUM)
+
+_DESCRIPTORPOOLTEST2_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage.DeepNestedMessage.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='LAMBDA', index=0, number=11,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='MU', index=1, number=12,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=1506,
+  serialized_end=1538,
+)
+_sym_db.RegisterEnumDescriptor(_DESCRIPTORPOOLTEST2_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM)
+
+_DESCRIPTORPOOLTEST2_NESTEDMESSAGE_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='IOTA', index=0, number=9,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='KAPPA', index=1, number=10,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=1540,
+  serialized_end=1573,
+)
+_sym_db.RegisterEnumDescriptor(_DESCRIPTORPOOLTEST2_NESTEDMESSAGE_NESTEDENUM)
+
+_DESCRIPTORPOOLTEST2_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest2.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='GAMMA', index=0, number=3,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='DELTA', index=1, number=4,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=1575,
+  serialized_end=1609,
+)
+_sym_db.RegisterEnumDescriptor(_DESCRIPTORPOOLTEST2_NESTEDENUM)
+
+
+_DESCRIPTORPOOLTEST1_NESTEDMESSAGE_DEEPNESTEDMESSAGE = _descriptor.Descriptor(
+  name='DeepNestedMessage',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage.DeepNestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='nested_enum', full_name='google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage.DeepNestedMessage.nested_enum', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=7,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_field', full_name='google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage.DeepNestedMessage.nested_field', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("theta").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _DESCRIPTORPOOLTEST1_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=565,
+  serialized_end=770,
+)
+
+_DESCRIPTORPOOLTEST1_NESTEDMESSAGE = _descriptor.Descriptor(
+  name='NestedMessage',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='nested_enum', full_name='google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage.nested_enum', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=6,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_field', full_name='google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage.nested_field', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("beta").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='deep_nested_message', full_name='google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage.deep_nested_message', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_DESCRIPTORPOOLTEST1_NESTEDMESSAGE_DEEPNESTEDMESSAGE, ],
+  enum_types=[
+    _DESCRIPTORPOOLTEST1_NESTEDMESSAGE_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=298,
+  serialized_end=807,
+)
+
+_DESCRIPTORPOOLTEST1 = _descriptor.Descriptor(
+  name='DescriptorPoolTest1',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest1',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='nested_enum', full_name='google.protobuf.python.internal.DescriptorPoolTest1.nested_enum', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=2,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_message', full_name='google.protobuf.python.internal.DescriptorPoolTest1.nested_message', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_DESCRIPTORPOOLTEST1_NESTEDMESSAGE, ],
+  enum_types=[
+    _DESCRIPTORPOOLTEST1_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(1000, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=90,
+  serialized_end=853,
+)
+
+
+_DESCRIPTORPOOLTEST2_NESTEDMESSAGE_DEEPNESTEDMESSAGE = _descriptor.Descriptor(
+  name='DeepNestedMessage',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage.DeepNestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='nested_enum', full_name='google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage.DeepNestedMessage.nested_enum', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=12,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_field', full_name='google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage.DeepNestedMessage.nested_field', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("lambda").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _DESCRIPTORPOOLTEST2_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1333,
+  serialized_end=1538,
+)
+
+_DESCRIPTORPOOLTEST2_NESTEDMESSAGE = _descriptor.Descriptor(
+  name='NestedMessage',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='nested_enum', full_name='google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage.nested_enum', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=9,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_field', full_name='google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage.nested_field', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("delta").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='deep_nested_message', full_name='google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage.deep_nested_message', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_DESCRIPTORPOOLTEST2_NESTEDMESSAGE_DEEPNESTEDMESSAGE, ],
+  enum_types=[
+    _DESCRIPTORPOOLTEST2_NESTEDMESSAGE_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1065,
+  serialized_end=1573,
+)
+
+_DESCRIPTORPOOLTEST2 = _descriptor.Descriptor(
+  name='DescriptorPoolTest2',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest2',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='nested_enum', full_name='google.protobuf.python.internal.DescriptorPoolTest2.nested_enum', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=3,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_message', full_name='google.protobuf.python.internal.DescriptorPoolTest2.nested_message', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_DESCRIPTORPOOLTEST2_NESTEDMESSAGE, ],
+  enum_types=[
+    _DESCRIPTORPOOLTEST2_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=856,
+  serialized_end=1609,
+)
+
+_DESCRIPTORPOOLTEST1_NESTEDMESSAGE_DEEPNESTEDMESSAGE.fields_by_name['nested_enum'].enum_type = _DESCRIPTORPOOLTEST1_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM
+_DESCRIPTORPOOLTEST1_NESTEDMESSAGE_DEEPNESTEDMESSAGE.containing_type = _DESCRIPTORPOOLTEST1_NESTEDMESSAGE
+_DESCRIPTORPOOLTEST1_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM.containing_type = _DESCRIPTORPOOLTEST1_NESTEDMESSAGE_DEEPNESTEDMESSAGE
+_DESCRIPTORPOOLTEST1_NESTEDMESSAGE.fields_by_name['nested_enum'].enum_type = _DESCRIPTORPOOLTEST1_NESTEDMESSAGE_NESTEDENUM
+_DESCRIPTORPOOLTEST1_NESTEDMESSAGE.fields_by_name['deep_nested_message'].message_type = _DESCRIPTORPOOLTEST1_NESTEDMESSAGE_DEEPNESTEDMESSAGE
+_DESCRIPTORPOOLTEST1_NESTEDMESSAGE.containing_type = _DESCRIPTORPOOLTEST1
+_DESCRIPTORPOOLTEST1_NESTEDMESSAGE_NESTEDENUM.containing_type = _DESCRIPTORPOOLTEST1_NESTEDMESSAGE
+_DESCRIPTORPOOLTEST1.fields_by_name['nested_enum'].enum_type = _DESCRIPTORPOOLTEST1_NESTEDENUM
+_DESCRIPTORPOOLTEST1.fields_by_name['nested_message'].message_type = _DESCRIPTORPOOLTEST1_NESTEDMESSAGE
+_DESCRIPTORPOOLTEST1_NESTEDENUM.containing_type = _DESCRIPTORPOOLTEST1
+_DESCRIPTORPOOLTEST2_NESTEDMESSAGE_DEEPNESTEDMESSAGE.fields_by_name['nested_enum'].enum_type = _DESCRIPTORPOOLTEST2_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM
+_DESCRIPTORPOOLTEST2_NESTEDMESSAGE_DEEPNESTEDMESSAGE.containing_type = _DESCRIPTORPOOLTEST2_NESTEDMESSAGE
+_DESCRIPTORPOOLTEST2_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM.containing_type = _DESCRIPTORPOOLTEST2_NESTEDMESSAGE_DEEPNESTEDMESSAGE
+_DESCRIPTORPOOLTEST2_NESTEDMESSAGE.fields_by_name['nested_enum'].enum_type = _DESCRIPTORPOOLTEST2_NESTEDMESSAGE_NESTEDENUM
+_DESCRIPTORPOOLTEST2_NESTEDMESSAGE.fields_by_name['deep_nested_message'].message_type = _DESCRIPTORPOOLTEST2_NESTEDMESSAGE_DEEPNESTEDMESSAGE
+_DESCRIPTORPOOLTEST2_NESTEDMESSAGE.containing_type = _DESCRIPTORPOOLTEST2
+_DESCRIPTORPOOLTEST2_NESTEDMESSAGE_NESTEDENUM.containing_type = _DESCRIPTORPOOLTEST2_NESTEDMESSAGE
+_DESCRIPTORPOOLTEST2.fields_by_name['nested_enum'].enum_type = _DESCRIPTORPOOLTEST2_NESTEDENUM
+_DESCRIPTORPOOLTEST2.fields_by_name['nested_message'].message_type = _DESCRIPTORPOOLTEST2_NESTEDMESSAGE
+_DESCRIPTORPOOLTEST2_NESTEDENUM.containing_type = _DESCRIPTORPOOLTEST2
+DESCRIPTOR.message_types_by_name['DescriptorPoolTest1'] = _DESCRIPTORPOOLTEST1
+DESCRIPTOR.message_types_by_name['DescriptorPoolTest2'] = _DESCRIPTORPOOLTEST2
+
+DescriptorPoolTest1 = _reflection.GeneratedProtocolMessageType('DescriptorPoolTest1', (_message.Message,), dict(
+
+  NestedMessage = _reflection.GeneratedProtocolMessageType('NestedMessage', (_message.Message,), dict(
+
+    DeepNestedMessage = _reflection.GeneratedProtocolMessageType('DeepNestedMessage', (_message.Message,), dict(
+      DESCRIPTOR = _DESCRIPTORPOOLTEST1_NESTEDMESSAGE_DEEPNESTEDMESSAGE,
+      __module__ = 'google.protobuf.internal.descriptor_pool_test1_pb2'
+      # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage.DeepNestedMessage)
+      ))
+    ,
+    DESCRIPTOR = _DESCRIPTORPOOLTEST1_NESTEDMESSAGE,
+    __module__ = 'google.protobuf.internal.descriptor_pool_test1_pb2'
+    # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.DescriptorPoolTest1.NestedMessage)
+    ))
+  ,
+  DESCRIPTOR = _DESCRIPTORPOOLTEST1,
+  __module__ = 'google.protobuf.internal.descriptor_pool_test1_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.DescriptorPoolTest1)
+  ))
+_sym_db.RegisterMessage(DescriptorPoolTest1)
+_sym_db.RegisterMessage(DescriptorPoolTest1.NestedMessage)
+_sym_db.RegisterMessage(DescriptorPoolTest1.NestedMessage.DeepNestedMessage)
+
+DescriptorPoolTest2 = _reflection.GeneratedProtocolMessageType('DescriptorPoolTest2', (_message.Message,), dict(
+
+  NestedMessage = _reflection.GeneratedProtocolMessageType('NestedMessage', (_message.Message,), dict(
+
+    DeepNestedMessage = _reflection.GeneratedProtocolMessageType('DeepNestedMessage', (_message.Message,), dict(
+      DESCRIPTOR = _DESCRIPTORPOOLTEST2_NESTEDMESSAGE_DEEPNESTEDMESSAGE,
+      __module__ = 'google.protobuf.internal.descriptor_pool_test1_pb2'
+      # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage.DeepNestedMessage)
+      ))
+    ,
+    DESCRIPTOR = _DESCRIPTORPOOLTEST2_NESTEDMESSAGE,
+    __module__ = 'google.protobuf.internal.descriptor_pool_test1_pb2'
+    # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.DescriptorPoolTest2.NestedMessage)
+    ))
+  ,
+  DESCRIPTOR = _DESCRIPTORPOOLTEST2,
+  __module__ = 'google.protobuf.internal.descriptor_pool_test1_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.DescriptorPoolTest2)
+  ))
+_sym_db.RegisterMessage(DescriptorPoolTest2)
+_sym_db.RegisterMessage(DescriptorPoolTest2.NestedMessage)
+_sym_db.RegisterMessage(DescriptorPoolTest2.NestedMessage.DeepNestedMessage)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/descriptor_pool_test2_pb2.py b/generator/google/protobuf/internal/descriptor_pool_test2_pb2.py
new file mode 100644
index 0000000..eee46a5
--- /dev/null
+++ b/generator/google/protobuf/internal/descriptor_pool_test2_pb2.py
@@ -0,0 +1,265 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/descriptor_pool_test2.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf.internal import descriptor_pool_test1_pb2 as google_dot_protobuf_dot_internal_dot_descriptor__pool__test1__pb2
+from google.protobuf.internal import more_messages_pb2 as google_dot_protobuf_dot_internal_dot_more__messages__pb2
+
+from google.protobuf.internal.more_messages_pb2 import *
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/descriptor_pool_test2.proto',
+  package='google.protobuf.python.internal',
+  syntax='proto2',
+  serialized_pb=_b('\n4google/protobuf/internal/descriptor_pool_test2.proto\x12\x1fgoogle.protobuf.python.internal\x1a\x34google/protobuf/internal/descriptor_pool_test1.proto\x1a,google/protobuf/internal/more_messages.proto\"\xef\x06\n\x13\x44\x65scriptorPoolTest3\x12X\n\x0bnested_enum\x18\x01 \x01(\x0e\x32?.google.protobuf.python.internal.DescriptorPoolTest3.NestedEnum:\x02XI\x12Z\n\x0enested_message\x18\x02 \x01(\x0b\x32\x42.google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage\x1a\xf7\x03\n\rNestedMessage\x12\x66\n\x0bnested_enum\x18\x01 \x01(\x0e\x32M.google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage.NestedEnum:\x02PI\x12\x18\n\x0cnested_field\x18\x02 \x01(\t:\x02nu\x12q\n\x13\x64\x65\x65p_nested_message\x18\x03 \x01(\x0b\x32T.google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage.DeepNestedMessage\x1a\xcd\x01\n\x11\x44\x65\x65pNestedMessage\x12y\n\x0bnested_enum\x18\x01 \x01(\x0e\x32_.google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage.DeepNestedMessage.NestedEnum:\x03RHO\x12\x1b\n\x0cnested_field\x18\x02 \x01(\t:\x05sigma\" \n\nNestedEnum\x12\x07\n\x03RHO\x10\x11\x12\t\n\x05SIGMA\x10\x12\"!\n\nNestedEnum\x12\x0b\n\x07OMICRON\x10\x0f\x12\x06\n\x02PI\x10\x10\"\x1c\n\nNestedEnum\x12\x06\n\x02NU\x10\r\x12\x06\n\x02XI\x10\x0e\x32\x89\x01\n\x14\x64\x65scriptor_pool_test\x12\x34.google.protobuf.python.internal.DescriptorPoolTest1\x18\xe9\x07 \x01(\x0b\x32\x34.google.protobuf.python.internal.DescriptorPoolTest3P\x01')
+  ,
+  dependencies=[google_dot_protobuf_dot_internal_dot_descriptor__pool__test1__pb2.DESCRIPTOR,google_dot_protobuf_dot_internal_dot_more__messages__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+_DESCRIPTORPOOLTEST3_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage.DeepNestedMessage.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='RHO', index=0, number=17,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='SIGMA', index=1, number=18,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=832,
+  serialized_end=864,
+)
+_sym_db.RegisterEnumDescriptor(_DESCRIPTORPOOLTEST3_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM)
+
+_DESCRIPTORPOOLTEST3_NESTEDMESSAGE_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='OMICRON', index=0, number=15,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='PI', index=1, number=16,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=866,
+  serialized_end=899,
+)
+_sym_db.RegisterEnumDescriptor(_DESCRIPTORPOOLTEST3_NESTEDMESSAGE_NESTEDENUM)
+
+_DESCRIPTORPOOLTEST3_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest3.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='NU', index=0, number=13,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='XI', index=1, number=14,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=901,
+  serialized_end=929,
+)
+_sym_db.RegisterEnumDescriptor(_DESCRIPTORPOOLTEST3_NESTEDENUM)
+
+
+_DESCRIPTORPOOLTEST3_NESTEDMESSAGE_DEEPNESTEDMESSAGE = _descriptor.Descriptor(
+  name='DeepNestedMessage',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage.DeepNestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='nested_enum', full_name='google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage.DeepNestedMessage.nested_enum', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=17,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_field', full_name='google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage.DeepNestedMessage.nested_field', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("sigma").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _DESCRIPTORPOOLTEST3_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=659,
+  serialized_end=864,
+)
+
+_DESCRIPTORPOOLTEST3_NESTEDMESSAGE = _descriptor.Descriptor(
+  name='NestedMessage',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='nested_enum', full_name='google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage.nested_enum', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=16,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_field', full_name='google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage.nested_field', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("nu").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='deep_nested_message', full_name='google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage.deep_nested_message', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_DESCRIPTORPOOLTEST3_NESTEDMESSAGE_DEEPNESTEDMESSAGE, ],
+  enum_types=[
+    _DESCRIPTORPOOLTEST3_NESTEDMESSAGE_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=396,
+  serialized_end=899,
+)
+
+_DESCRIPTORPOOLTEST3 = _descriptor.Descriptor(
+  name='DescriptorPoolTest3',
+  full_name='google.protobuf.python.internal.DescriptorPoolTest3',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='nested_enum', full_name='google.protobuf.python.internal.DescriptorPoolTest3.nested_enum', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=14,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_message', full_name='google.protobuf.python.internal.DescriptorPoolTest3.nested_message', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+    _descriptor.FieldDescriptor(
+      name='descriptor_pool_test', full_name='google.protobuf.python.internal.DescriptorPoolTest3.descriptor_pool_test', index=0,
+      number=1001, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+  ],
+  nested_types=[_DESCRIPTORPOOLTEST3_NESTEDMESSAGE, ],
+  enum_types=[
+    _DESCRIPTORPOOLTEST3_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=190,
+  serialized_end=1069,
+)
+
+_DESCRIPTORPOOLTEST3_NESTEDMESSAGE_DEEPNESTEDMESSAGE.fields_by_name['nested_enum'].enum_type = _DESCRIPTORPOOLTEST3_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM
+_DESCRIPTORPOOLTEST3_NESTEDMESSAGE_DEEPNESTEDMESSAGE.containing_type = _DESCRIPTORPOOLTEST3_NESTEDMESSAGE
+_DESCRIPTORPOOLTEST3_NESTEDMESSAGE_DEEPNESTEDMESSAGE_NESTEDENUM.containing_type = _DESCRIPTORPOOLTEST3_NESTEDMESSAGE_DEEPNESTEDMESSAGE
+_DESCRIPTORPOOLTEST3_NESTEDMESSAGE.fields_by_name['nested_enum'].enum_type = _DESCRIPTORPOOLTEST3_NESTEDMESSAGE_NESTEDENUM
+_DESCRIPTORPOOLTEST3_NESTEDMESSAGE.fields_by_name['deep_nested_message'].message_type = _DESCRIPTORPOOLTEST3_NESTEDMESSAGE_DEEPNESTEDMESSAGE
+_DESCRIPTORPOOLTEST3_NESTEDMESSAGE.containing_type = _DESCRIPTORPOOLTEST3
+_DESCRIPTORPOOLTEST3_NESTEDMESSAGE_NESTEDENUM.containing_type = _DESCRIPTORPOOLTEST3_NESTEDMESSAGE
+_DESCRIPTORPOOLTEST3.fields_by_name['nested_enum'].enum_type = _DESCRIPTORPOOLTEST3_NESTEDENUM
+_DESCRIPTORPOOLTEST3.fields_by_name['nested_message'].message_type = _DESCRIPTORPOOLTEST3_NESTEDMESSAGE
+_DESCRIPTORPOOLTEST3_NESTEDENUM.containing_type = _DESCRIPTORPOOLTEST3
+DESCRIPTOR.message_types_by_name['DescriptorPoolTest3'] = _DESCRIPTORPOOLTEST3
+
+DescriptorPoolTest3 = _reflection.GeneratedProtocolMessageType('DescriptorPoolTest3', (_message.Message,), dict(
+
+  NestedMessage = _reflection.GeneratedProtocolMessageType('NestedMessage', (_message.Message,), dict(
+
+    DeepNestedMessage = _reflection.GeneratedProtocolMessageType('DeepNestedMessage', (_message.Message,), dict(
+      DESCRIPTOR = _DESCRIPTORPOOLTEST3_NESTEDMESSAGE_DEEPNESTEDMESSAGE,
+      __module__ = 'google.protobuf.internal.descriptor_pool_test2_pb2'
+      # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage.DeepNestedMessage)
+      ))
+    ,
+    DESCRIPTOR = _DESCRIPTORPOOLTEST3_NESTEDMESSAGE,
+    __module__ = 'google.protobuf.internal.descriptor_pool_test2_pb2'
+    # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.DescriptorPoolTest3.NestedMessage)
+    ))
+  ,
+  DESCRIPTOR = _DESCRIPTORPOOLTEST3,
+  __module__ = 'google.protobuf.internal.descriptor_pool_test2_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.DescriptorPoolTest3)
+  ))
+_sym_db.RegisterMessage(DescriptorPoolTest3)
+_sym_db.RegisterMessage(DescriptorPoolTest3.NestedMessage)
+_sym_db.RegisterMessage(DescriptorPoolTest3.NestedMessage.DeepNestedMessage)
+
+_DESCRIPTORPOOLTEST3.extensions_by_name['descriptor_pool_test'].message_type = _DESCRIPTORPOOLTEST3
+google_dot_protobuf_dot_internal_dot_descriptor__pool__test1__pb2.DescriptorPoolTest1.RegisterExtension(_DESCRIPTORPOOLTEST3.extensions_by_name['descriptor_pool_test'])
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/descriptor_test.py b/generator/google/protobuf/internal/descriptor_test.py
new file mode 100644
index 0000000..623198c
--- /dev/null
+++ b/generator/google/protobuf/internal/descriptor_test.py
@@ -0,0 +1,823 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Unittest for google.protobuf.internal.descriptor."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import sys
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+
+from google.protobuf import unittest_custom_options_pb2
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import descriptor_pb2
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import test_util
+from google.protobuf import descriptor
+from google.protobuf import descriptor_pool
+from google.protobuf import symbol_database
+from google.protobuf import text_format
+
+
+TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII = """
+name: 'TestEmptyMessage'
+"""
+
+
+class DescriptorTest(unittest.TestCase):
+
+  def setUp(self):
+    file_proto = descriptor_pb2.FileDescriptorProto(
+        name='some/filename/some.proto',
+        package='protobuf_unittest')
+    message_proto = file_proto.message_type.add(
+        name='NestedMessage')
+    message_proto.field.add(
+        name='bb',
+        number=1,
+        type=descriptor_pb2.FieldDescriptorProto.TYPE_INT32,
+        label=descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL)
+    enum_proto = message_proto.enum_type.add(
+        name='ForeignEnum')
+    enum_proto.value.add(name='FOREIGN_FOO', number=4)
+    enum_proto.value.add(name='FOREIGN_BAR', number=5)
+    enum_proto.value.add(name='FOREIGN_BAZ', number=6)
+
+    file_proto.message_type.add(name='ResponseMessage')
+    service_proto = file_proto.service.add(
+        name='Service')
+    method_proto = service_proto.method.add(
+        name='CallMethod',
+        input_type='.protobuf_unittest.NestedMessage',
+        output_type='.protobuf_unittest.ResponseMessage')
+
+    # Note: Calling DescriptorPool.Add() multiple times with the same file only
+    # works if the input is canonical; in particular, all type names must be
+    # fully qualified.
+    self.pool = self.GetDescriptorPool()
+    self.pool.Add(file_proto)
+    self.my_file = self.pool.FindFileByName(file_proto.name)
+    self.my_message = self.my_file.message_types_by_name[message_proto.name]
+    self.my_enum = self.my_message.enum_types_by_name[enum_proto.name]
+    self.my_service = self.my_file.services_by_name[service_proto.name]
+    self.my_method = self.my_service.methods_by_name[method_proto.name]
+
+  def GetDescriptorPool(self):
+    return symbol_database.Default().pool
+
+  def testEnumValueName(self):
+    self.assertEqual(self.my_message.EnumValueName('ForeignEnum', 4),
+                     'FOREIGN_FOO')
+
+    self.assertEqual(
+        self.my_message.enum_types_by_name[
+            'ForeignEnum'].values_by_number[4].name,
+        self.my_message.EnumValueName('ForeignEnum', 4))
+
+  def testEnumFixups(self):
+    self.assertEqual(self.my_enum, self.my_enum.values[0].type)
+
+  def testContainingTypeFixups(self):
+    self.assertEqual(self.my_message, self.my_message.fields[0].containing_type)
+    self.assertEqual(self.my_message, self.my_enum.containing_type)
+
+  def testContainingServiceFixups(self):
+    self.assertEqual(self.my_service, self.my_method.containing_service)
+
+  def testGetOptions(self):
+    self.assertEqual(self.my_enum.GetOptions(),
+                     descriptor_pb2.EnumOptions())
+    self.assertEqual(self.my_enum.values[0].GetOptions(),
+                     descriptor_pb2.EnumValueOptions())
+    self.assertEqual(self.my_message.GetOptions(),
+                     descriptor_pb2.MessageOptions())
+    self.assertEqual(self.my_message.fields[0].GetOptions(),
+                     descriptor_pb2.FieldOptions())
+    self.assertEqual(self.my_method.GetOptions(),
+                     descriptor_pb2.MethodOptions())
+    self.assertEqual(self.my_service.GetOptions(),
+                     descriptor_pb2.ServiceOptions())
+
+  def testSimpleCustomOptions(self):
+    file_descriptor = unittest_custom_options_pb2.DESCRIPTOR
+    message_descriptor =\
+        unittest_custom_options_pb2.TestMessageWithCustomOptions.DESCRIPTOR
+    field_descriptor = message_descriptor.fields_by_name['field1']
+    oneof_descriptor = message_descriptor.oneofs_by_name['AnOneof']
+    enum_descriptor = message_descriptor.enum_types_by_name['AnEnum']
+    enum_value_descriptor =\
+        message_descriptor.enum_values_by_name['ANENUM_VAL2']
+    service_descriptor =\
+        unittest_custom_options_pb2.TestServiceWithCustomOptions.DESCRIPTOR
+    method_descriptor = service_descriptor.FindMethodByName('Foo')
+
+    file_options = file_descriptor.GetOptions()
+    file_opt1 = unittest_custom_options_pb2.file_opt1
+    self.assertEqual(9876543210, file_options.Extensions[file_opt1])
+    message_options = message_descriptor.GetOptions()
+    message_opt1 = unittest_custom_options_pb2.message_opt1
+    self.assertEqual(-56, message_options.Extensions[message_opt1])
+    field_options = field_descriptor.GetOptions()
+    field_opt1 = unittest_custom_options_pb2.field_opt1
+    self.assertEqual(8765432109, field_options.Extensions[field_opt1])
+    field_opt2 = unittest_custom_options_pb2.field_opt2
+    self.assertEqual(42, field_options.Extensions[field_opt2])
+    oneof_options = oneof_descriptor.GetOptions()
+    oneof_opt1 = unittest_custom_options_pb2.oneof_opt1
+    self.assertEqual(-99, oneof_options.Extensions[oneof_opt1])
+    enum_options = enum_descriptor.GetOptions()
+    enum_opt1 = unittest_custom_options_pb2.enum_opt1
+    self.assertEqual(-789, enum_options.Extensions[enum_opt1])
+    enum_value_options = enum_value_descriptor.GetOptions()
+    enum_value_opt1 = unittest_custom_options_pb2.enum_value_opt1
+    self.assertEqual(123, enum_value_options.Extensions[enum_value_opt1])
+
+    service_options = service_descriptor.GetOptions()
+    service_opt1 = unittest_custom_options_pb2.service_opt1
+    self.assertEqual(-9876543210, service_options.Extensions[service_opt1])
+    method_options = method_descriptor.GetOptions()
+    method_opt1 = unittest_custom_options_pb2.method_opt1
+    self.assertEqual(unittest_custom_options_pb2.METHODOPT1_VAL2,
+                     method_options.Extensions[method_opt1])
+
+    message_descriptor = (
+        unittest_custom_options_pb2.DummyMessageContainingEnum.DESCRIPTOR)
+    self.assertTrue(file_descriptor.has_options)
+    self.assertFalse(message_descriptor.has_options)
+
+  def testDifferentCustomOptionTypes(self):
+    kint32min = -2**31
+    kint64min = -2**63
+    kint32max = 2**31 - 1
+    kint64max = 2**63 - 1
+    kuint32max = 2**32 - 1
+    kuint64max = 2**64 - 1
+
+    message_descriptor =\
+        unittest_custom_options_pb2.CustomOptionMinIntegerValues.DESCRIPTOR
+    message_options = message_descriptor.GetOptions()
+    self.assertEqual(False, message_options.Extensions[
+        unittest_custom_options_pb2.bool_opt])
+    self.assertEqual(kint32min, message_options.Extensions[
+        unittest_custom_options_pb2.int32_opt])
+    self.assertEqual(kint64min, message_options.Extensions[
+        unittest_custom_options_pb2.int64_opt])
+    self.assertEqual(0, message_options.Extensions[
+        unittest_custom_options_pb2.uint32_opt])
+    self.assertEqual(0, message_options.Extensions[
+        unittest_custom_options_pb2.uint64_opt])
+    self.assertEqual(kint32min, message_options.Extensions[
+        unittest_custom_options_pb2.sint32_opt])
+    self.assertEqual(kint64min, message_options.Extensions[
+        unittest_custom_options_pb2.sint64_opt])
+    self.assertEqual(0, message_options.Extensions[
+        unittest_custom_options_pb2.fixed32_opt])
+    self.assertEqual(0, message_options.Extensions[
+        unittest_custom_options_pb2.fixed64_opt])
+    self.assertEqual(kint32min, message_options.Extensions[
+        unittest_custom_options_pb2.sfixed32_opt])
+    self.assertEqual(kint64min, message_options.Extensions[
+        unittest_custom_options_pb2.sfixed64_opt])
+
+    message_descriptor =\
+        unittest_custom_options_pb2.CustomOptionMaxIntegerValues.DESCRIPTOR
+    message_options = message_descriptor.GetOptions()
+    self.assertEqual(True, message_options.Extensions[
+        unittest_custom_options_pb2.bool_opt])
+    self.assertEqual(kint32max, message_options.Extensions[
+        unittest_custom_options_pb2.int32_opt])
+    self.assertEqual(kint64max, message_options.Extensions[
+        unittest_custom_options_pb2.int64_opt])
+    self.assertEqual(kuint32max, message_options.Extensions[
+        unittest_custom_options_pb2.uint32_opt])
+    self.assertEqual(kuint64max, message_options.Extensions[
+        unittest_custom_options_pb2.uint64_opt])
+    self.assertEqual(kint32max, message_options.Extensions[
+        unittest_custom_options_pb2.sint32_opt])
+    self.assertEqual(kint64max, message_options.Extensions[
+        unittest_custom_options_pb2.sint64_opt])
+    self.assertEqual(kuint32max, message_options.Extensions[
+        unittest_custom_options_pb2.fixed32_opt])
+    self.assertEqual(kuint64max, message_options.Extensions[
+        unittest_custom_options_pb2.fixed64_opt])
+    self.assertEqual(kint32max, message_options.Extensions[
+        unittest_custom_options_pb2.sfixed32_opt])
+    self.assertEqual(kint64max, message_options.Extensions[
+        unittest_custom_options_pb2.sfixed64_opt])
+
+    message_descriptor =\
+        unittest_custom_options_pb2.CustomOptionOtherValues.DESCRIPTOR
+    message_options = message_descriptor.GetOptions()
+    self.assertEqual(-100, message_options.Extensions[
+        unittest_custom_options_pb2.int32_opt])
+    self.assertAlmostEqual(12.3456789, message_options.Extensions[
+        unittest_custom_options_pb2.float_opt], 6)
+    self.assertAlmostEqual(1.234567890123456789, message_options.Extensions[
+        unittest_custom_options_pb2.double_opt])
+    self.assertEqual("Hello, \"World\"", message_options.Extensions[
+        unittest_custom_options_pb2.string_opt])
+    self.assertEqual(b"Hello\0World", message_options.Extensions[
+        unittest_custom_options_pb2.bytes_opt])
+    dummy_enum = unittest_custom_options_pb2.DummyMessageContainingEnum
+    self.assertEqual(
+        dummy_enum.TEST_OPTION_ENUM_TYPE2,
+        message_options.Extensions[unittest_custom_options_pb2.enum_opt])
+
+    message_descriptor =\
+        unittest_custom_options_pb2.SettingRealsFromPositiveInts.DESCRIPTOR
+    message_options = message_descriptor.GetOptions()
+    self.assertAlmostEqual(12, message_options.Extensions[
+        unittest_custom_options_pb2.float_opt], 6)
+    self.assertAlmostEqual(154, message_options.Extensions[
+        unittest_custom_options_pb2.double_opt])
+
+    message_descriptor =\
+        unittest_custom_options_pb2.SettingRealsFromNegativeInts.DESCRIPTOR
+    message_options = message_descriptor.GetOptions()
+    self.assertAlmostEqual(-12, message_options.Extensions[
+        unittest_custom_options_pb2.float_opt], 6)
+    self.assertAlmostEqual(-154, message_options.Extensions[
+        unittest_custom_options_pb2.double_opt])
+
+  def testComplexExtensionOptions(self):
+    descriptor =\
+        unittest_custom_options_pb2.VariousComplexOptions.DESCRIPTOR
+    options = descriptor.GetOptions()
+    self.assertEqual(42, options.Extensions[
+        unittest_custom_options_pb2.complex_opt1].foo)
+    self.assertEqual(324, options.Extensions[
+        unittest_custom_options_pb2.complex_opt1].Extensions[
+            unittest_custom_options_pb2.quux])
+    self.assertEqual(876, options.Extensions[
+        unittest_custom_options_pb2.complex_opt1].Extensions[
+            unittest_custom_options_pb2.corge].qux)
+    self.assertEqual(987, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].baz)
+    self.assertEqual(654, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].Extensions[
+            unittest_custom_options_pb2.grault])
+    self.assertEqual(743, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].bar.foo)
+    self.assertEqual(1999, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].bar.Extensions[
+            unittest_custom_options_pb2.quux])
+    self.assertEqual(2008, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].bar.Extensions[
+            unittest_custom_options_pb2.corge].qux)
+    self.assertEqual(741, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].Extensions[
+            unittest_custom_options_pb2.garply].foo)
+    self.assertEqual(1998, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].Extensions[
+            unittest_custom_options_pb2.garply].Extensions[
+                unittest_custom_options_pb2.quux])
+    self.assertEqual(2121, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].Extensions[
+            unittest_custom_options_pb2.garply].Extensions[
+                unittest_custom_options_pb2.corge].qux)
+    self.assertEqual(1971, options.Extensions[
+        unittest_custom_options_pb2.ComplexOptionType2
+        .ComplexOptionType4.complex_opt4].waldo)
+    self.assertEqual(321, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].fred.waldo)
+    self.assertEqual(9, options.Extensions[
+        unittest_custom_options_pb2.complex_opt3].qux)
+    self.assertEqual(22, options.Extensions[
+        unittest_custom_options_pb2.complex_opt3].complexoptiontype5.plugh)
+    self.assertEqual(24, options.Extensions[
+        unittest_custom_options_pb2.complexopt6].xyzzy)
+
+  # Check that aggregate options were parsed and saved correctly in
+  # the appropriate descriptors.
+  def testAggregateOptions(self):
+    file_descriptor = unittest_custom_options_pb2.DESCRIPTOR
+    message_descriptor =\
+        unittest_custom_options_pb2.AggregateMessage.DESCRIPTOR
+    field_descriptor = message_descriptor.fields_by_name["fieldname"]
+    enum_descriptor = unittest_custom_options_pb2.AggregateEnum.DESCRIPTOR
+    enum_value_descriptor = enum_descriptor.values_by_name["VALUE"]
+    service_descriptor =\
+        unittest_custom_options_pb2.AggregateService.DESCRIPTOR
+    method_descriptor = service_descriptor.FindMethodByName("Method")
+
+    # Tests for the different types of data embedded in fileopt
+    file_options = file_descriptor.GetOptions().Extensions[
+        unittest_custom_options_pb2.fileopt]
+    self.assertEqual(100, file_options.i)
+    self.assertEqual("FileAnnotation", file_options.s)
+    self.assertEqual("NestedFileAnnotation", file_options.sub.s)
+    self.assertEqual("FileExtensionAnnotation", file_options.file.Extensions[
+        unittest_custom_options_pb2.fileopt].s)
+    self.assertEqual("EmbeddedMessageSetElement", file_options.mset.Extensions[
+        unittest_custom_options_pb2.AggregateMessageSetElement
+        .message_set_extension].s)
+
+    # Simple tests for all the other types of annotations
+    self.assertEqual(
+        "MessageAnnotation",
+        message_descriptor.GetOptions().Extensions[
+            unittest_custom_options_pb2.msgopt].s)
+    self.assertEqual(
+        "FieldAnnotation",
+        field_descriptor.GetOptions().Extensions[
+            unittest_custom_options_pb2.fieldopt].s)
+    self.assertEqual(
+        "EnumAnnotation",
+        enum_descriptor.GetOptions().Extensions[
+            unittest_custom_options_pb2.enumopt].s)
+    self.assertEqual(
+        "EnumValueAnnotation",
+        enum_value_descriptor.GetOptions().Extensions[
+            unittest_custom_options_pb2.enumvalopt].s)
+    self.assertEqual(
+        "ServiceAnnotation",
+        service_descriptor.GetOptions().Extensions[
+            unittest_custom_options_pb2.serviceopt].s)
+    self.assertEqual(
+        "MethodAnnotation",
+        method_descriptor.GetOptions().Extensions[
+            unittest_custom_options_pb2.methodopt].s)
+
+  def testNestedOptions(self):
+    nested_message =\
+        unittest_custom_options_pb2.NestedOptionType.NestedMessage.DESCRIPTOR
+    self.assertEqual(1001, nested_message.GetOptions().Extensions[
+        unittest_custom_options_pb2.message_opt1])
+    nested_field = nested_message.fields_by_name["nested_field"]
+    self.assertEqual(1002, nested_field.GetOptions().Extensions[
+        unittest_custom_options_pb2.field_opt1])
+    outer_message =\
+        unittest_custom_options_pb2.NestedOptionType.DESCRIPTOR
+    nested_enum = outer_message.enum_types_by_name["NestedEnum"]
+    self.assertEqual(1003, nested_enum.GetOptions().Extensions[
+        unittest_custom_options_pb2.enum_opt1])
+    nested_enum_value = outer_message.enum_values_by_name["NESTED_ENUM_VALUE"]
+    self.assertEqual(1004, nested_enum_value.GetOptions().Extensions[
+        unittest_custom_options_pb2.enum_value_opt1])
+    nested_extension = outer_message.extensions_by_name["nested_extension"]
+    self.assertEqual(1005, nested_extension.GetOptions().Extensions[
+        unittest_custom_options_pb2.field_opt2])
+
+  def testFileDescriptorReferences(self):
+    self.assertEqual(self.my_enum.file, self.my_file)
+    self.assertEqual(self.my_message.file, self.my_file)
+
+  def testFileDescriptor(self):
+    self.assertEqual(self.my_file.name, 'some/filename/some.proto')
+    self.assertEqual(self.my_file.package, 'protobuf_unittest')
+    self.assertEqual(self.my_file.pool, self.pool)
+    # Generated modules also belong to the default pool.
+    self.assertEqual(unittest_pb2.DESCRIPTOR.pool, descriptor_pool.Default())
+
+  @unittest.skipIf(
+      api_implementation.Type() != 'cpp' or api_implementation.Version() != 2,
+      'Immutability of descriptors is only enforced in v2 implementation')
+  def testImmutableCppDescriptor(self):
+    message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
+    with self.assertRaises(AttributeError):
+      message_descriptor.fields_by_name = None
+    with self.assertRaises(TypeError):
+      message_descriptor.fields_by_name['Another'] = None
+    with self.assertRaises(TypeError):
+      message_descriptor.fields.append(None)
+
+
+class NewDescriptorTest(DescriptorTest):
+  """Redo the same tests as above, but with a separate DescriptorPool."""
+
+  def GetDescriptorPool(self):
+    return descriptor_pool.DescriptorPool()
+
+
+class GeneratedDescriptorTest(unittest.TestCase):
+  """Tests for the properties of descriptors in generated code."""
+
+  def CheckMessageDescriptor(self, message_descriptor):
+    # Basic properties
+    self.assertEqual(message_descriptor.name, 'TestAllTypes')
+    self.assertEqual(message_descriptor.full_name,
+                     'protobuf_unittest.TestAllTypes')
+    # Test equality and hashability
+    self.assertEqual(message_descriptor, message_descriptor)
+    self.assertEqual(message_descriptor.fields[0].containing_type,
+                     message_descriptor)
+    self.assertIn(message_descriptor, [message_descriptor])
+    self.assertIn(message_descriptor, {message_descriptor: None})
+    # Test field containers
+    self.CheckDescriptorSequence(message_descriptor.fields)
+    self.CheckDescriptorMapping(message_descriptor.fields_by_name)
+    self.CheckDescriptorMapping(message_descriptor.fields_by_number)
+    self.CheckDescriptorMapping(message_descriptor.fields_by_camelcase_name)
+
+  def CheckFieldDescriptor(self, field_descriptor):
+    # Basic properties
+    self.assertEqual(field_descriptor.name, 'optional_int32')
+    self.assertEqual(field_descriptor.camelcase_name, 'optionalInt32')
+    self.assertEqual(field_descriptor.full_name,
+                     'protobuf_unittest.TestAllTypes.optional_int32')
+    self.assertEqual(field_descriptor.containing_type.name, 'TestAllTypes')
+    # Test equality and hashability
+    self.assertEqual(field_descriptor, field_descriptor)
+    self.assertEqual(
+        field_descriptor.containing_type.fields_by_name['optional_int32'],
+        field_descriptor)
+    self.assertEqual(
+        field_descriptor.containing_type.fields_by_camelcase_name[
+            'optionalInt32'],
+        field_descriptor)
+    self.assertIn(field_descriptor, [field_descriptor])
+    self.assertIn(field_descriptor, {field_descriptor: None})
+
+  def CheckDescriptorSequence(self, sequence):
+    # Verifies that a property like 'messageDescriptor.fields' has all the
+    # properties of an immutable abc.Sequence.
+    self.assertGreater(len(sequence), 0)  # Sized
+    self.assertEqual(len(sequence), len(list(sequence)))  # Iterable
+    item = sequence[0]
+    self.assertEqual(item, sequence[0])
+    self.assertIn(item, sequence)  # Container
+    self.assertEqual(sequence.index(item), 0)
+    self.assertEqual(sequence.count(item), 1)
+    reversed_iterator = reversed(sequence)
+    self.assertEqual(list(reversed_iterator), list(sequence)[::-1])
+    self.assertRaises(StopIteration, next, reversed_iterator)
+
+  def CheckDescriptorMapping(self, mapping):
+    # Verifies that a property like 'messageDescriptor.fields' has all the
+    # properties of an immutable abc.Mapping.
+    self.assertGreater(len(mapping), 0)  # Sized
+    self.assertEqual(len(mapping), len(list(mapping)))  # Iterable
+    if sys.version_info >= (3,):
+      key, item = next(iter(mapping.items()))
+    else:
+      key, item = mapping.items()[0]
+    self.assertIn(key, mapping)  # Container
+    self.assertEqual(mapping.get(key), item)
+    # keys(), iterkeys() &co
+    item = (next(iter(mapping.keys())), next(iter(mapping.values())))
+    self.assertEqual(item, next(iter(mapping.items())))
+    if sys.version_info < (3,):
+      def CheckItems(seq, iterator):
+        self.assertEqual(next(iterator), seq[0])
+        self.assertEqual(list(iterator), seq[1:])
+      CheckItems(mapping.keys(), mapping.iterkeys())
+      CheckItems(mapping.values(), mapping.itervalues())
+      CheckItems(mapping.items(), mapping.iteritems())
+
+  def testDescriptor(self):
+    message_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
+    self.CheckMessageDescriptor(message_descriptor)
+    field_descriptor = message_descriptor.fields_by_name['optional_int32']
+    self.CheckFieldDescriptor(field_descriptor)
+    field_descriptor = message_descriptor.fields_by_camelcase_name[
+        'optionalInt32']
+    self.CheckFieldDescriptor(field_descriptor)
+
+  def testCppDescriptorContainer(self):
+    # Check that the collection is still valid even if the parent disappeared.
+    enum = unittest_pb2.TestAllTypes.DESCRIPTOR.enum_types_by_name['NestedEnum']
+    values = enum.values
+    del enum
+    self.assertEqual('FOO', values[0].name)
+
+  def testCppDescriptorContainer_Iterator(self):
+    # Same test with the iterator
+    enum = unittest_pb2.TestAllTypes.DESCRIPTOR.enum_types_by_name['NestedEnum']
+    values_iter = iter(enum.values)
+    del enum
+    self.assertEqual('FOO', next(values_iter).name)
+
+
+class DescriptorCopyToProtoTest(unittest.TestCase):
+  """Tests for CopyTo functions of Descriptor."""
+
+  def _AssertProtoEqual(self, actual_proto, expected_class, expected_ascii):
+    expected_proto = expected_class()
+    text_format.Merge(expected_ascii, expected_proto)
+
+    self.assertEqual(
+        actual_proto, expected_proto,
+        'Not equal,\nActual:\n%s\nExpected:\n%s\n'
+        % (str(actual_proto), str(expected_proto)))
+
+  def _InternalTestCopyToProto(self, desc, expected_proto_class,
+                               expected_proto_ascii):
+    actual = expected_proto_class()
+    desc.CopyToProto(actual)
+    self._AssertProtoEqual(
+        actual, expected_proto_class, expected_proto_ascii)
+
+  def testCopyToProto_EmptyMessage(self):
+    self._InternalTestCopyToProto(
+        unittest_pb2.TestEmptyMessage.DESCRIPTOR,
+        descriptor_pb2.DescriptorProto,
+        TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII)
+
+  def testCopyToProto_NestedMessage(self):
+    TEST_NESTED_MESSAGE_ASCII = """
+      name: 'NestedMessage'
+      field: <
+        name: 'bb'
+        number: 1
+        label: 1  # Optional
+        type: 5  # TYPE_INT32
+      >
+      """
+
+    self._InternalTestCopyToProto(
+        unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR,
+        descriptor_pb2.DescriptorProto,
+        TEST_NESTED_MESSAGE_ASCII)
+
+  def testCopyToProto_ForeignNestedMessage(self):
+    TEST_FOREIGN_NESTED_ASCII = """
+      name: 'TestForeignNested'
+      field: <
+        name: 'foreign_nested'
+        number: 1
+        label: 1  # Optional
+        type: 11  # TYPE_MESSAGE
+        type_name: '.protobuf_unittest.TestAllTypes.NestedMessage'
+      >
+      """
+
+    self._InternalTestCopyToProto(
+        unittest_pb2.TestForeignNested.DESCRIPTOR,
+        descriptor_pb2.DescriptorProto,
+        TEST_FOREIGN_NESTED_ASCII)
+
+  def testCopyToProto_ForeignEnum(self):
+    TEST_FOREIGN_ENUM_ASCII = """
+      name: 'ForeignEnum'
+      value: <
+        name: 'FOREIGN_FOO'
+        number: 4
+      >
+      value: <
+        name: 'FOREIGN_BAR'
+        number: 5
+      >
+      value: <
+        name: 'FOREIGN_BAZ'
+        number: 6
+      >
+      """
+
+    self._InternalTestCopyToProto(
+        unittest_pb2.ForeignEnum.DESCRIPTOR,
+        descriptor_pb2.EnumDescriptorProto,
+        TEST_FOREIGN_ENUM_ASCII)
+
+  def testCopyToProto_Options(self):
+    TEST_DEPRECATED_FIELDS_ASCII = """
+      name: 'TestDeprecatedFields'
+      field: <
+        name: 'deprecated_int32'
+        number: 1
+        label: 1  # Optional
+        type: 5  # TYPE_INT32
+        options: <
+          deprecated: true
+        >
+      >
+      """
+
+    self._InternalTestCopyToProto(
+        unittest_pb2.TestDeprecatedFields.DESCRIPTOR,
+        descriptor_pb2.DescriptorProto,
+        TEST_DEPRECATED_FIELDS_ASCII)
+
+  def testCopyToProto_AllExtensions(self):
+    TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII = """
+      name: 'TestEmptyMessageWithExtensions'
+      extension_range: <
+        start: 1
+        end: 536870912
+      >
+      """
+
+    self._InternalTestCopyToProto(
+        unittest_pb2.TestEmptyMessageWithExtensions.DESCRIPTOR,
+        descriptor_pb2.DescriptorProto,
+        TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII)
+
+  def testCopyToProto_SeveralExtensions(self):
+    TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII = """
+      name: 'TestMultipleExtensionRanges'
+      extension_range: <
+        start: 42
+        end: 43
+      >
+      extension_range: <
+        start: 4143
+        end: 4244
+      >
+      extension_range: <
+        start: 65536
+        end: 536870912
+      >
+      """
+
+    self._InternalTestCopyToProto(
+        unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR,
+        descriptor_pb2.DescriptorProto,
+        TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII)
+
+  # Disable this test so we can make changes to the proto file.
+  # TODO(xiaofeng): Enable this test after cl/55530659 is submitted.
+  #
+  # def testCopyToProto_FileDescriptor(self):
+  #   UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII = ("""
+  #     name: 'google/protobuf/unittest_import.proto'
+  #     package: 'protobuf_unittest_import'
+  #     dependency: 'google/protobuf/unittest_import_public.proto'
+  #     message_type: <
+  #       name: 'ImportMessage'
+  #       field: <
+  #         name: 'd'
+  #         number: 1
+  #         label: 1  # Optional
+  #         type: 5  # TYPE_INT32
+  #       >
+  #     >
+  #     """ +
+  #     """enum_type: <
+  #       name: 'ImportEnum'
+  #       value: <
+  #         name: 'IMPORT_FOO'
+  #         number: 7
+  #       >
+  #       value: <
+  #         name: 'IMPORT_BAR'
+  #         number: 8
+  #       >
+  #       value: <
+  #         name: 'IMPORT_BAZ'
+  #         number: 9
+  #       >
+  #     >
+  #     options: <
+  #       java_package: 'com.google.protobuf.test'
+  #       optimize_for: 1  # SPEED
+  #     >
+  #     public_dependency: 0
+  #  """)
+  #  self._InternalTestCopyToProto(
+  #      unittest_import_pb2.DESCRIPTOR,
+  #      descriptor_pb2.FileDescriptorProto,
+  #      UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII)
+
+  def testCopyToProto_ServiceDescriptor(self):
+    TEST_SERVICE_ASCII = """
+      name: 'TestService'
+      method: <
+        name: 'Foo'
+        input_type: '.protobuf_unittest.FooRequest'
+        output_type: '.protobuf_unittest.FooResponse'
+      >
+      method: <
+        name: 'Bar'
+        input_type: '.protobuf_unittest.BarRequest'
+        output_type: '.protobuf_unittest.BarResponse'
+      >
+      """
+    # TODO(rocking): enable this test after the proto descriptor change is
+    # checked in.
+    #self._InternalTestCopyToProto(
+    #    unittest_pb2.TestService.DESCRIPTOR,
+    #    descriptor_pb2.ServiceDescriptorProto,
+    #    TEST_SERVICE_ASCII)
+
+
+class MakeDescriptorTest(unittest.TestCase):
+
+  def testMakeDescriptorWithNestedFields(self):
+    file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
+    file_descriptor_proto.name = 'Foo2'
+    message_type = file_descriptor_proto.message_type.add()
+    message_type.name = file_descriptor_proto.name
+    nested_type = message_type.nested_type.add()
+    nested_type.name = 'Sub'
+    enum_type = nested_type.enum_type.add()
+    enum_type.name = 'FOO'
+    enum_type_val = enum_type.value.add()
+    enum_type_val.name = 'BAR'
+    enum_type_val.number = 3
+    field = message_type.field.add()
+    field.number = 1
+    field.name = 'uint64_field'
+    field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+    field.type = descriptor.FieldDescriptor.TYPE_UINT64
+    field = message_type.field.add()
+    field.number = 2
+    field.name = 'nested_message_field'
+    field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+    field.type = descriptor.FieldDescriptor.TYPE_MESSAGE
+    field.type_name = 'Sub'
+    enum_field = nested_type.field.add()
+    enum_field.number = 2
+    enum_field.name = 'bar_field'
+    enum_field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+    enum_field.type = descriptor.FieldDescriptor.TYPE_ENUM
+    enum_field.type_name = 'Foo2.Sub.FOO'
+
+    result = descriptor.MakeDescriptor(message_type)
+    self.assertEqual(result.fields[0].cpp_type,
+                     descriptor.FieldDescriptor.CPPTYPE_UINT64)
+    self.assertEqual(result.fields[1].cpp_type,
+                     descriptor.FieldDescriptor.CPPTYPE_MESSAGE)
+    self.assertEqual(result.fields[1].message_type.containing_type,
+                     result)
+    self.assertEqual(result.nested_types[0].fields[0].full_name,
+                     'Foo2.Sub.bar_field')
+    self.assertEqual(result.nested_types[0].fields[0].enum_type,
+                     result.nested_types[0].enum_types[0])
+
+  def testMakeDescriptorWithUnsignedIntField(self):
+    file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
+    file_descriptor_proto.name = 'Foo'
+    message_type = file_descriptor_proto.message_type.add()
+    message_type.name = file_descriptor_proto.name
+    enum_type = message_type.enum_type.add()
+    enum_type.name = 'FOO'
+    enum_type_val = enum_type.value.add()
+    enum_type_val.name = 'BAR'
+    enum_type_val.number = 3
+    field = message_type.field.add()
+    field.number = 1
+    field.name = 'uint64_field'
+    field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+    field.type = descriptor.FieldDescriptor.TYPE_UINT64
+    enum_field = message_type.field.add()
+    enum_field.number = 2
+    enum_field.name = 'bar_field'
+    enum_field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+    enum_field.type = descriptor.FieldDescriptor.TYPE_ENUM
+    enum_field.type_name = 'Foo.FOO'
+
+    result = descriptor.MakeDescriptor(message_type)
+    self.assertEqual(result.fields[0].cpp_type,
+                     descriptor.FieldDescriptor.CPPTYPE_UINT64)
+
+
+  def testMakeDescriptorWithOptions(self):
+    descriptor_proto = descriptor_pb2.DescriptorProto()
+    aggregate_message = unittest_custom_options_pb2.AggregateMessage
+    aggregate_message.DESCRIPTOR.CopyToProto(descriptor_proto)
+    reformed_descriptor = descriptor.MakeDescriptor(descriptor_proto)
+
+    options = reformed_descriptor.GetOptions()
+    self.assertEqual(101,
+                      options.Extensions[unittest_custom_options_pb2.msgopt].i)
+
+  def testCamelcaseName(self):
+    descriptor_proto = descriptor_pb2.DescriptorProto()
+    descriptor_proto.name = 'Bar'
+    names = ['foo_foo', 'FooBar', 'fooBaz', 'fooFoo', 'foobar']
+    camelcase_names = ['fooFoo', 'fooBar', 'fooBaz', 'fooFoo', 'foobar']
+    for index in range(len(names)):
+      field = descriptor_proto.field.add()
+      field.number = index + 1
+      field.name = names[index]
+    result = descriptor.MakeDescriptor(descriptor_proto)
+    for index in range(len(camelcase_names)):
+      self.assertEqual(result.fields[index].camelcase_name,
+                       camelcase_names[index])
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/encoder.py b/generator/google/protobuf/internal/encoder.py
index 777975e..48ef2df 100644
--- a/generator/google/protobuf/internal/encoder.py
+++ b/generator/google/protobuf/internal/encoder.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -41,7 +41,7 @@
 sizer takes a value of this field's type and computes its byte size.  The
 encoder takes a writer function and a value.  It encodes the value into byte
 strings and invokes the writer function to write those strings.  Typically the
-writer function is the write() method of a cStringIO.
+writer function is the write() method of a BytesIO.
 
 We try to do as much work as possible when constructing the writer and the
 sizer rather than when calling them.  In particular:
@@ -67,6 +67,9 @@
 __author__ = 'kenton@google.com (Kenton Varda)'
 
 import struct
+
+import six
+
 from google.protobuf.internal import wire_format
 
 
@@ -308,7 +311,7 @@
 
 
 # --------------------------------------------------------------------
-# MessageSet is special.
+# MessageSet is special: it needs custom logic to compute its size properly.
 
 
 def MessageSetItemSizer(field_number):
@@ -333,6 +336,32 @@
   return FieldSize
 
 
+# --------------------------------------------------------------------
+# Map is special: it needs custom logic to compute its size properly.
+
+
+def MapSizer(field_descriptor):
+  """Returns a sizer for a map field."""
+
+  # Can't look at field_descriptor.message_type._concrete_class because it may
+  # not have been initialized yet.
+  message_type = field_descriptor.message_type
+  message_sizer = MessageSizer(field_descriptor.number, False, False)
+
+  def FieldSize(map_value):
+    total = 0
+    for key in map_value:
+      value = map_value[key]
+      # It's wasteful to create the messages and throw them away one second
+      # later since we'll do the same for the actual encode.  But there's not an
+      # obvious way to avoid this within the current design without tons of code
+      # duplication.
+      entry_msg = message_type._concrete_class(key=key, value=value)
+      total += message_sizer(entry_msg)
+    return total
+
+  return FieldSize
+
 # ====================================================================
 # Encoders!
 
@@ -340,15 +369,14 @@
 def _VarintEncoder():
   """Return an encoder for a basic varint value (does not include tag)."""
 
-  local_chr = chr
   def EncodeVarint(write, value):
     bits = value & 0x7f
     value >>= 7
     while value:
-      write(local_chr(0x80|bits))
+      write(six.int2byte(0x80|bits))
       bits = value & 0x7f
       value >>= 7
-    return write(local_chr(bits))
+    return write(six.int2byte(bits))
 
   return EncodeVarint
 
@@ -357,17 +385,16 @@
   """Return an encoder for a basic signed varint value (does not include
   tag)."""
 
-  local_chr = chr
   def EncodeSignedVarint(write, value):
     if value < 0:
       value += (1 << 64)
     bits = value & 0x7f
     value >>= 7
     while value:
-      write(local_chr(0x80|bits))
+      write(six.int2byte(0x80|bits))
       bits = value & 0x7f
       value >>= 7
-    return write(local_chr(bits))
+    return write(six.int2byte(bits))
 
   return EncodeSignedVarint
 
@@ -382,7 +409,7 @@
 
   pieces = []
   _EncodeVarint(pieces.append, value)
-  return "".join(pieces)
+  return b"".join(pieces)
 
 
 def TagBytes(field_number, wire_type):
@@ -525,21 +552,21 @@
     def EncodeNonFiniteOrRaise(write, value):
       # Remember that the serialized form uses little-endian byte order.
       if value == _POS_INF:
-        write('\x00\x00\x80\x7F')
+        write(b'\x00\x00\x80\x7F')
       elif value == _NEG_INF:
-        write('\x00\x00\x80\xFF')
+        write(b'\x00\x00\x80\xFF')
       elif value != value:           # NaN
-        write('\x00\x00\xC0\x7F')
+        write(b'\x00\x00\xC0\x7F')
       else:
         raise
   elif value_size == 8:
     def EncodeNonFiniteOrRaise(write, value):
       if value == _POS_INF:
-        write('\x00\x00\x00\x00\x00\x00\xF0\x7F')
+        write(b'\x00\x00\x00\x00\x00\x00\xF0\x7F')
       elif value == _NEG_INF:
-        write('\x00\x00\x00\x00\x00\x00\xF0\xFF')
+        write(b'\x00\x00\x00\x00\x00\x00\xF0\xFF')
       elif value != value:                         # NaN
-        write('\x00\x00\x00\x00\x00\x00\xF8\x7F')
+        write(b'\x00\x00\x00\x00\x00\x00\xF8\x7F')
       else:
         raise
   else:
@@ -615,8 +642,8 @@
 def BoolEncoder(field_number, is_repeated, is_packed):
   """Returns an encoder for a boolean field."""
 
-  false_byte = chr(0)
-  true_byte = chr(1)
+  false_byte = b'\x00'
+  true_byte = b'\x01'
   if is_packed:
     tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
     local_EncodeVarint = _EncodeVarint
@@ -752,7 +779,7 @@
       }
     }
   """
-  start_bytes = "".join([
+  start_bytes = b"".join([
       TagBytes(1, wire_format.WIRETYPE_START_GROUP),
       TagBytes(2, wire_format.WIRETYPE_VARINT),
       _VarintBytes(field_number),
@@ -767,3 +794,30 @@
     return write(end_bytes)
 
   return EncodeField
+
+
+# --------------------------------------------------------------------
+# As before, Map is special.
+
+
+def MapEncoder(field_descriptor):
+  """Encoder for extensions of MessageSet.
+
+  Maps always have a wire format like this:
+    message MapEntry {
+      key_type key = 1;
+      value_type value = 2;
+    }
+    repeated MapEntry map = N;
+  """
+  # Can't look at field_descriptor.message_type._concrete_class because it may
+  # not have been initialized yet.
+  message_type = field_descriptor.message_type
+  encode_message = MessageEncoder(field_descriptor.number, False, False)
+
+  def EncodeField(write, value):
+    for key in value:
+      entry_msg = message_type._concrete_class(key=key, value=value[key])
+      encode_message(write, entry_msg)
+
+  return EncodeField
diff --git a/generator/google/protobuf/internal/enum_type_wrapper.py b/generator/google/protobuf/internal/enum_type_wrapper.py
index 7b28645..1cffe35 100644
--- a/generator/google/protobuf/internal/enum_type_wrapper.py
+++ b/generator/google/protobuf/internal/enum_type_wrapper.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
diff --git a/generator/google/protobuf/internal/factory_test1_pb2.py b/generator/google/protobuf/internal/factory_test1_pb2.py
new file mode 100644
index 0000000..baa0ae4
--- /dev/null
+++ b/generator/google/protobuf/internal/factory_test1_pb2.py
@@ -0,0 +1,190 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/factory_test1.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/factory_test1.proto',
+  package='google.protobuf.python.internal',
+  syntax='proto2',
+  serialized_pb=_b('\n,google/protobuf/internal/factory_test1.proto\x12\x1fgoogle.protobuf.python.internal\"\xd5\x03\n\x0f\x46\x61\x63tory1Message\x12\x45\n\x0e\x66\x61\x63tory_1_enum\x18\x01 \x01(\x0e\x32-.google.protobuf.python.internal.Factory1Enum\x12\x62\n\x15nested_factory_1_enum\x18\x02 \x01(\x0e\x32\x43.google.protobuf.python.internal.Factory1Message.NestedFactory1Enum\x12h\n\x18nested_factory_1_message\x18\x03 \x01(\x0b\x32\x46.google.protobuf.python.internal.Factory1Message.NestedFactory1Message\x12\x14\n\x0cscalar_value\x18\x04 \x01(\x05\x12\x12\n\nlist_value\x18\x05 \x03(\t\x1a&\n\x15NestedFactory1Message\x12\r\n\x05value\x18\x01 \x01(\t\"P\n\x12NestedFactory1Enum\x12\x1c\n\x18NESTED_FACTORY_1_VALUE_0\x10\x00\x12\x1c\n\x18NESTED_FACTORY_1_VALUE_1\x10\x01*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02*<\n\x0c\x46\x61\x63tory1Enum\x12\x15\n\x11\x46\x41\x43TORY_1_VALUE_0\x10\x00\x12\x15\n\x11\x46\x41\x43TORY_1_VALUE_1\x10\x01')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+_FACTORY1ENUM = _descriptor.EnumDescriptor(
+  name='Factory1Enum',
+  full_name='google.protobuf.python.internal.Factory1Enum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='FACTORY_1_VALUE_0', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FACTORY_1_VALUE_1', index=1, number=1,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=553,
+  serialized_end=613,
+)
+_sym_db.RegisterEnumDescriptor(_FACTORY1ENUM)
+
+Factory1Enum = enum_type_wrapper.EnumTypeWrapper(_FACTORY1ENUM)
+FACTORY_1_VALUE_0 = 0
+FACTORY_1_VALUE_1 = 1
+
+
+_FACTORY1MESSAGE_NESTEDFACTORY1ENUM = _descriptor.EnumDescriptor(
+  name='NestedFactory1Enum',
+  full_name='google.protobuf.python.internal.Factory1Message.NestedFactory1Enum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='NESTED_FACTORY_1_VALUE_0', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='NESTED_FACTORY_1_VALUE_1', index=1, number=1,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=460,
+  serialized_end=540,
+)
+_sym_db.RegisterEnumDescriptor(_FACTORY1MESSAGE_NESTEDFACTORY1ENUM)
+
+
+_FACTORY1MESSAGE_NESTEDFACTORY1MESSAGE = _descriptor.Descriptor(
+  name='NestedFactory1Message',
+  full_name='google.protobuf.python.internal.Factory1Message.NestedFactory1Message',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.python.internal.Factory1Message.NestedFactory1Message.value', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=420,
+  serialized_end=458,
+)
+
+_FACTORY1MESSAGE = _descriptor.Descriptor(
+  name='Factory1Message',
+  full_name='google.protobuf.python.internal.Factory1Message',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='factory_1_enum', full_name='google.protobuf.python.internal.Factory1Message.factory_1_enum', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_factory_1_enum', full_name='google.protobuf.python.internal.Factory1Message.nested_factory_1_enum', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_factory_1_message', full_name='google.protobuf.python.internal.Factory1Message.nested_factory_1_message', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='scalar_value', full_name='google.protobuf.python.internal.Factory1Message.scalar_value', index=3,
+      number=4, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='list_value', full_name='google.protobuf.python.internal.Factory1Message.list_value', index=4,
+      number=5, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_FACTORY1MESSAGE_NESTEDFACTORY1MESSAGE, ],
+  enum_types=[
+    _FACTORY1MESSAGE_NESTEDFACTORY1ENUM,
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(1000, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=82,
+  serialized_end=551,
+)
+
+_FACTORY1MESSAGE_NESTEDFACTORY1MESSAGE.containing_type = _FACTORY1MESSAGE
+_FACTORY1MESSAGE.fields_by_name['factory_1_enum'].enum_type = _FACTORY1ENUM
+_FACTORY1MESSAGE.fields_by_name['nested_factory_1_enum'].enum_type = _FACTORY1MESSAGE_NESTEDFACTORY1ENUM
+_FACTORY1MESSAGE.fields_by_name['nested_factory_1_message'].message_type = _FACTORY1MESSAGE_NESTEDFACTORY1MESSAGE
+_FACTORY1MESSAGE_NESTEDFACTORY1ENUM.containing_type = _FACTORY1MESSAGE
+DESCRIPTOR.message_types_by_name['Factory1Message'] = _FACTORY1MESSAGE
+DESCRIPTOR.enum_types_by_name['Factory1Enum'] = _FACTORY1ENUM
+
+Factory1Message = _reflection.GeneratedProtocolMessageType('Factory1Message', (_message.Message,), dict(
+
+  NestedFactory1Message = _reflection.GeneratedProtocolMessageType('NestedFactory1Message', (_message.Message,), dict(
+    DESCRIPTOR = _FACTORY1MESSAGE_NESTEDFACTORY1MESSAGE,
+    __module__ = 'google.protobuf.internal.factory_test1_pb2'
+    # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.Factory1Message.NestedFactory1Message)
+    ))
+  ,
+  DESCRIPTOR = _FACTORY1MESSAGE,
+  __module__ = 'google.protobuf.internal.factory_test1_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.Factory1Message)
+  ))
+_sym_db.RegisterMessage(Factory1Message)
+_sym_db.RegisterMessage(Factory1Message.NestedFactory1Message)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/factory_test2_pb2.py b/generator/google/protobuf/internal/factory_test2_pb2.py
new file mode 100644
index 0000000..64808ae
--- /dev/null
+++ b/generator/google/protobuf/internal/factory_test2_pb2.py
@@ -0,0 +1,477 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/factory_test2.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf.internal import factory_test1_pb2 as google_dot_protobuf_dot_internal_dot_factory__test1__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/factory_test2.proto',
+  package='google.protobuf.python.internal',
+  syntax='proto2',
+  serialized_pb=_b('\n,google/protobuf/internal/factory_test2.proto\x12\x1fgoogle.protobuf.python.internal\x1a,google/protobuf/internal/factory_test1.proto\"\xd8\x0b\n\x0f\x46\x61\x63tory2Message\x12\x11\n\tmandatory\x18\x01 \x02(\x05\x12\x45\n\x0e\x66\x61\x63tory_2_enum\x18\x02 \x01(\x0e\x32-.google.protobuf.python.internal.Factory2Enum\x12\x62\n\x15nested_factory_2_enum\x18\x03 \x01(\x0e\x32\x43.google.protobuf.python.internal.Factory2Message.NestedFactory2Enum\x12h\n\x18nested_factory_2_message\x18\x04 \x01(\x0b\x32\x46.google.protobuf.python.internal.Factory2Message.NestedFactory2Message\x12K\n\x11\x66\x61\x63tory_1_message\x18\x05 \x01(\x0b\x32\x30.google.protobuf.python.internal.Factory1Message\x12\x45\n\x0e\x66\x61\x63tory_1_enum\x18\x06 \x01(\x0e\x32-.google.protobuf.python.internal.Factory1Enum\x12\x62\n\x15nested_factory_1_enum\x18\x07 \x01(\x0e\x32\x43.google.protobuf.python.internal.Factory1Message.NestedFactory1Enum\x12h\n\x18nested_factory_1_message\x18\x08 \x01(\x0b\x32\x46.google.protobuf.python.internal.Factory1Message.NestedFactory1Message\x12J\n\x10\x63ircular_message\x18\t \x01(\x0b\x32\x30.google.protobuf.python.internal.Factory2Message\x12\x14\n\x0cscalar_value\x18\n \x01(\t\x12\x12\n\nlist_value\x18\x0b \x03(\t\x12I\n\x07grouped\x18\x0c \x03(\n28.google.protobuf.python.internal.Factory2Message.Grouped\x12:\n\x04loop\x18\x0f \x01(\x0b\x32,.google.protobuf.python.internal.LoopMessage\x12\x1e\n\x10int_with_default\x18\x10 \x01(\x05:\x04\x31\x37\x37\x36\x12!\n\x13\x64ouble_with_default\x18\x11 \x01(\x01:\x04\x39.99\x12(\n\x13string_with_default\x18\x12 \x01(\t:\x0bhello world\x12 \n\x11\x62ool_with_default\x18\x13 \x01(\x08:\x05\x66\x61lse\x12[\n\x11\x65num_with_default\x18\x14 \x01(\x0e\x32-.google.protobuf.python.internal.Factory2Enum:\x11\x46\x41\x43TORY_2_VALUE_1\x12&\n\x12\x62ytes_with_default\x18\x15 \x01(\x0c:\na\\373\\000c\x12\x13\n\toneof_int\x18\x16 \x01(\x05H\x00\x12\x16\n\x0coneof_string\x18\x17 \x01(\tH\x00\x1a&\n\x15NestedFactory2Message\x12\r\n\x05value\x18\x01 \x01(\t\x1a)\n\x07Grouped\x12\x0e\n\x06part_1\x18\r \x01(\t\x12\x0e\n\x06part_2\x18\x0e \x01(\t\"P\n\x12NestedFactory2Enum\x12\x1c\n\x18NESTED_FACTORY_2_VALUE_0\x10\x00\x12\x1c\n\x18NESTED_FACTORY_2_VALUE_1\x10\x01\x32I\n\x0eone_more_field\x12\x30.google.protobuf.python.internal.Factory1Message\x18\xe9\x07 \x01(\tB\r\n\x0boneof_field\"M\n\x0bLoopMessage\x12>\n\x04loop\x18\x01 \x01(\x0b\x32\x30.google.protobuf.python.internal.Factory2Message\"D\n\x19MessageWithNestedEnumOnly\"\'\n\nNestedEnum\x12\x19\n\x15NESTED_MESSAGE_ENUM_0\x10\x00*<\n\x0c\x46\x61\x63tory2Enum\x12\x15\n\x11\x46\x41\x43TORY_2_VALUE_0\x10\x00\x12\x15\n\x11\x46\x41\x43TORY_2_VALUE_1\x10\x01:H\n\ranother_field\x12\x30.google.protobuf.python.internal.Factory1Message\x18\xea\x07 \x01(\t')
+  ,
+  dependencies=[google_dot_protobuf_dot_internal_dot_factory__test1__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+_FACTORY2ENUM = _descriptor.EnumDescriptor(
+  name='Factory2Enum',
+  full_name='google.protobuf.python.internal.Factory2Enum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='FACTORY_2_VALUE_0', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FACTORY_2_VALUE_1', index=1, number=1,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=1775,
+  serialized_end=1835,
+)
+_sym_db.RegisterEnumDescriptor(_FACTORY2ENUM)
+
+Factory2Enum = enum_type_wrapper.EnumTypeWrapper(_FACTORY2ENUM)
+FACTORY_2_VALUE_0 = 0
+FACTORY_2_VALUE_1 = 1
+
+ANOTHER_FIELD_FIELD_NUMBER = 1002
+another_field = _descriptor.FieldDescriptor(
+  name='another_field', full_name='google.protobuf.python.internal.another_field', index=0,
+  number=1002, type=9, cpp_type=9, label=1,
+  has_default_value=False, default_value=_b("").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+
+_FACTORY2MESSAGE_NESTEDFACTORY2ENUM = _descriptor.EnumDescriptor(
+  name='NestedFactory2Enum',
+  full_name='google.protobuf.python.internal.Factory2Message.NestedFactory2Enum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='NESTED_FACTORY_2_VALUE_0', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='NESTED_FACTORY_2_VALUE_1', index=1, number=1,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=1454,
+  serialized_end=1534,
+)
+_sym_db.RegisterEnumDescriptor(_FACTORY2MESSAGE_NESTEDFACTORY2ENUM)
+
+_MESSAGEWITHNESTEDENUMONLY_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='google.protobuf.python.internal.MessageWithNestedEnumOnly.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='NESTED_MESSAGE_ENUM_0', index=0, number=0,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=1734,
+  serialized_end=1773,
+)
+_sym_db.RegisterEnumDescriptor(_MESSAGEWITHNESTEDENUMONLY_NESTEDENUM)
+
+
+_FACTORY2MESSAGE_NESTEDFACTORY2MESSAGE = _descriptor.Descriptor(
+  name='NestedFactory2Message',
+  full_name='google.protobuf.python.internal.Factory2Message.NestedFactory2Message',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.python.internal.Factory2Message.NestedFactory2Message.value', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1371,
+  serialized_end=1409,
+)
+
+_FACTORY2MESSAGE_GROUPED = _descriptor.Descriptor(
+  name='Grouped',
+  full_name='google.protobuf.python.internal.Factory2Message.Grouped',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='part_1', full_name='google.protobuf.python.internal.Factory2Message.Grouped.part_1', index=0,
+      number=13, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='part_2', full_name='google.protobuf.python.internal.Factory2Message.Grouped.part_2', index=1,
+      number=14, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1411,
+  serialized_end=1452,
+)
+
+_FACTORY2MESSAGE = _descriptor.Descriptor(
+  name='Factory2Message',
+  full_name='google.protobuf.python.internal.Factory2Message',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='mandatory', full_name='google.protobuf.python.internal.Factory2Message.mandatory', index=0,
+      number=1, type=5, cpp_type=1, label=2,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='factory_2_enum', full_name='google.protobuf.python.internal.Factory2Message.factory_2_enum', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_factory_2_enum', full_name='google.protobuf.python.internal.Factory2Message.nested_factory_2_enum', index=2,
+      number=3, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_factory_2_message', full_name='google.protobuf.python.internal.Factory2Message.nested_factory_2_message', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='factory_1_message', full_name='google.protobuf.python.internal.Factory2Message.factory_1_message', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='factory_1_enum', full_name='google.protobuf.python.internal.Factory2Message.factory_1_enum', index=5,
+      number=6, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_factory_1_enum', full_name='google.protobuf.python.internal.Factory2Message.nested_factory_1_enum', index=6,
+      number=7, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_factory_1_message', full_name='google.protobuf.python.internal.Factory2Message.nested_factory_1_message', index=7,
+      number=8, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='circular_message', full_name='google.protobuf.python.internal.Factory2Message.circular_message', index=8,
+      number=9, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='scalar_value', full_name='google.protobuf.python.internal.Factory2Message.scalar_value', index=9,
+      number=10, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='list_value', full_name='google.protobuf.python.internal.Factory2Message.list_value', index=10,
+      number=11, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='grouped', full_name='google.protobuf.python.internal.Factory2Message.grouped', index=11,
+      number=12, type=10, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='loop', full_name='google.protobuf.python.internal.Factory2Message.loop', index=12,
+      number=15, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='int_with_default', full_name='google.protobuf.python.internal.Factory2Message.int_with_default', index=13,
+      number=16, type=5, cpp_type=1, label=1,
+      has_default_value=True, default_value=1776,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='double_with_default', full_name='google.protobuf.python.internal.Factory2Message.double_with_default', index=14,
+      number=17, type=1, cpp_type=5, label=1,
+      has_default_value=True, default_value=float(9.99),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='string_with_default', full_name='google.protobuf.python.internal.Factory2Message.string_with_default', index=15,
+      number=18, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("hello world").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bool_with_default', full_name='google.protobuf.python.internal.Factory2Message.bool_with_default', index=16,
+      number=19, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='enum_with_default', full_name='google.protobuf.python.internal.Factory2Message.enum_with_default', index=17,
+      number=20, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=1,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bytes_with_default', full_name='google.protobuf.python.internal.Factory2Message.bytes_with_default', index=18,
+      number=21, type=12, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("a\373\000c"),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_int', full_name='google.protobuf.python.internal.Factory2Message.oneof_int', index=19,
+      number=22, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_string', full_name='google.protobuf.python.internal.Factory2Message.oneof_string', index=20,
+      number=23, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+    _descriptor.FieldDescriptor(
+      name='one_more_field', full_name='google.protobuf.python.internal.Factory2Message.one_more_field', index=0,
+      number=1001, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+  ],
+  nested_types=[_FACTORY2MESSAGE_NESTEDFACTORY2MESSAGE, _FACTORY2MESSAGE_GROUPED, ],
+  enum_types=[
+    _FACTORY2MESSAGE_NESTEDFACTORY2ENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='oneof_field', full_name='google.protobuf.python.internal.Factory2Message.oneof_field',
+      index=0, containing_type=None, fields=[]),
+  ],
+  serialized_start=128,
+  serialized_end=1624,
+)
+
+
+_LOOPMESSAGE = _descriptor.Descriptor(
+  name='LoopMessage',
+  full_name='google.protobuf.python.internal.LoopMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='loop', full_name='google.protobuf.python.internal.LoopMessage.loop', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1626,
+  serialized_end=1703,
+)
+
+
+_MESSAGEWITHNESTEDENUMONLY = _descriptor.Descriptor(
+  name='MessageWithNestedEnumOnly',
+  full_name='google.protobuf.python.internal.MessageWithNestedEnumOnly',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _MESSAGEWITHNESTEDENUMONLY_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1705,
+  serialized_end=1773,
+)
+
+_FACTORY2MESSAGE_NESTEDFACTORY2MESSAGE.containing_type = _FACTORY2MESSAGE
+_FACTORY2MESSAGE_GROUPED.containing_type = _FACTORY2MESSAGE
+_FACTORY2MESSAGE.fields_by_name['factory_2_enum'].enum_type = _FACTORY2ENUM
+_FACTORY2MESSAGE.fields_by_name['nested_factory_2_enum'].enum_type = _FACTORY2MESSAGE_NESTEDFACTORY2ENUM
+_FACTORY2MESSAGE.fields_by_name['nested_factory_2_message'].message_type = _FACTORY2MESSAGE_NESTEDFACTORY2MESSAGE
+_FACTORY2MESSAGE.fields_by_name['factory_1_message'].message_type = google_dot_protobuf_dot_internal_dot_factory__test1__pb2._FACTORY1MESSAGE
+_FACTORY2MESSAGE.fields_by_name['factory_1_enum'].enum_type = google_dot_protobuf_dot_internal_dot_factory__test1__pb2._FACTORY1ENUM
+_FACTORY2MESSAGE.fields_by_name['nested_factory_1_enum'].enum_type = google_dot_protobuf_dot_internal_dot_factory__test1__pb2._FACTORY1MESSAGE_NESTEDFACTORY1ENUM
+_FACTORY2MESSAGE.fields_by_name['nested_factory_1_message'].message_type = google_dot_protobuf_dot_internal_dot_factory__test1__pb2._FACTORY1MESSAGE_NESTEDFACTORY1MESSAGE
+_FACTORY2MESSAGE.fields_by_name['circular_message'].message_type = _FACTORY2MESSAGE
+_FACTORY2MESSAGE.fields_by_name['grouped'].message_type = _FACTORY2MESSAGE_GROUPED
+_FACTORY2MESSAGE.fields_by_name['loop'].message_type = _LOOPMESSAGE
+_FACTORY2MESSAGE.fields_by_name['enum_with_default'].enum_type = _FACTORY2ENUM
+_FACTORY2MESSAGE_NESTEDFACTORY2ENUM.containing_type = _FACTORY2MESSAGE
+_FACTORY2MESSAGE.oneofs_by_name['oneof_field'].fields.append(
+  _FACTORY2MESSAGE.fields_by_name['oneof_int'])
+_FACTORY2MESSAGE.fields_by_name['oneof_int'].containing_oneof = _FACTORY2MESSAGE.oneofs_by_name['oneof_field']
+_FACTORY2MESSAGE.oneofs_by_name['oneof_field'].fields.append(
+  _FACTORY2MESSAGE.fields_by_name['oneof_string'])
+_FACTORY2MESSAGE.fields_by_name['oneof_string'].containing_oneof = _FACTORY2MESSAGE.oneofs_by_name['oneof_field']
+_LOOPMESSAGE.fields_by_name['loop'].message_type = _FACTORY2MESSAGE
+_MESSAGEWITHNESTEDENUMONLY_NESTEDENUM.containing_type = _MESSAGEWITHNESTEDENUMONLY
+DESCRIPTOR.message_types_by_name['Factory2Message'] = _FACTORY2MESSAGE
+DESCRIPTOR.message_types_by_name['LoopMessage'] = _LOOPMESSAGE
+DESCRIPTOR.message_types_by_name['MessageWithNestedEnumOnly'] = _MESSAGEWITHNESTEDENUMONLY
+DESCRIPTOR.enum_types_by_name['Factory2Enum'] = _FACTORY2ENUM
+DESCRIPTOR.extensions_by_name['another_field'] = another_field
+
+Factory2Message = _reflection.GeneratedProtocolMessageType('Factory2Message', (_message.Message,), dict(
+
+  NestedFactory2Message = _reflection.GeneratedProtocolMessageType('NestedFactory2Message', (_message.Message,), dict(
+    DESCRIPTOR = _FACTORY2MESSAGE_NESTEDFACTORY2MESSAGE,
+    __module__ = 'google.protobuf.internal.factory_test2_pb2'
+    # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.Factory2Message.NestedFactory2Message)
+    ))
+  ,
+
+  Grouped = _reflection.GeneratedProtocolMessageType('Grouped', (_message.Message,), dict(
+    DESCRIPTOR = _FACTORY2MESSAGE_GROUPED,
+    __module__ = 'google.protobuf.internal.factory_test2_pb2'
+    # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.Factory2Message.Grouped)
+    ))
+  ,
+  DESCRIPTOR = _FACTORY2MESSAGE,
+  __module__ = 'google.protobuf.internal.factory_test2_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.Factory2Message)
+  ))
+_sym_db.RegisterMessage(Factory2Message)
+_sym_db.RegisterMessage(Factory2Message.NestedFactory2Message)
+_sym_db.RegisterMessage(Factory2Message.Grouped)
+
+LoopMessage = _reflection.GeneratedProtocolMessageType('LoopMessage', (_message.Message,), dict(
+  DESCRIPTOR = _LOOPMESSAGE,
+  __module__ = 'google.protobuf.internal.factory_test2_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.LoopMessage)
+  ))
+_sym_db.RegisterMessage(LoopMessage)
+
+MessageWithNestedEnumOnly = _reflection.GeneratedProtocolMessageType('MessageWithNestedEnumOnly', (_message.Message,), dict(
+  DESCRIPTOR = _MESSAGEWITHNESTEDENUMONLY,
+  __module__ = 'google.protobuf.internal.factory_test2_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.MessageWithNestedEnumOnly)
+  ))
+_sym_db.RegisterMessage(MessageWithNestedEnumOnly)
+
+google_dot_protobuf_dot_internal_dot_factory__test1__pb2.Factory1Message.RegisterExtension(another_field)
+google_dot_protobuf_dot_internal_dot_factory__test1__pb2.Factory1Message.RegisterExtension(_FACTORY2MESSAGE.extensions_by_name['one_more_field'])
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/file_options_test_pb2.py b/generator/google/protobuf/internal/file_options_test_pb2.py
new file mode 100644
index 0000000..315df4b
--- /dev/null
+++ b/generator/google/protobuf/internal/file_options_test_pb2.py
@@ -0,0 +1,82 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/file_options_test.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/file_options_test.proto',
+  package='google.protobuf.python.internal',
+  syntax='proto2',
+  serialized_pb=_b('\n0google/protobuf/internal/file_options_test.proto\x12\x1fgoogle.protobuf.python.internal\x1a google/protobuf/descriptor.proto\"\x1e\n\nFooOptions\x12\x10\n\x08\x66oo_name\x18\x01 \x01(\t:a\n\x0b\x66oo_options\x12\x1c.google.protobuf.FileOptions\x18\xac\xec\xb6\x39 \x01(\x0b\x32+.google.protobuf.python.internal.FooOptions')
+  ,
+  dependencies=[google_dot_protobuf_dot_descriptor__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+FOO_OPTIONS_FIELD_NUMBER = 120436268
+foo_options = _descriptor.FieldDescriptor(
+  name='foo_options', full_name='google.protobuf.python.internal.foo_options', index=0,
+  number=120436268, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+
+
+_FOOOPTIONS = _descriptor.Descriptor(
+  name='FooOptions',
+  full_name='google.protobuf.python.internal.FooOptions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='foo_name', full_name='google.protobuf.python.internal.FooOptions.foo_name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=119,
+  serialized_end=149,
+)
+
+DESCRIPTOR.message_types_by_name['FooOptions'] = _FOOOPTIONS
+DESCRIPTOR.extensions_by_name['foo_options'] = foo_options
+
+FooOptions = _reflection.GeneratedProtocolMessageType('FooOptions', (_message.Message,), dict(
+  DESCRIPTOR = _FOOOPTIONS,
+  __module__ = 'google.protobuf.internal.file_options_test_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.FooOptions)
+  ))
+_sym_db.RegisterMessage(FooOptions)
+
+foo_options.message_type = _FOOOPTIONS
+google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(foo_options)
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/generator_test.py b/generator/google/protobuf/internal/generator_test.py
new file mode 100644
index 0000000..83ea5f5
--- /dev/null
+++ b/generator/google/protobuf/internal/generator_test.py
@@ -0,0 +1,348 @@
+#! /usr/bin/env python
+#
+# 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.
+
+# TODO(robinson): Flesh this out considerably.  We focused on reflection_test.py
+# first, since it's testing the subtler code, and since it provides decent
+# indirect testing of the protocol compiler output.
+
+"""Unittest that directly tests the output of the pure-Python protocol
+compiler.  See //google/protobuf/internal/reflection_test.py for a test which
+further ensures that we can use Python protocol message objects as we expect.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+
+from google.protobuf.internal import test_bad_identifiers_pb2
+from google.protobuf import unittest_custom_options_pb2
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_import_public_pb2
+from google.protobuf import unittest_mset_pb2
+from google.protobuf import unittest_mset_wire_format_pb2
+from google.protobuf import unittest_no_generic_services_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import service
+from google.protobuf import symbol_database
+
+MAX_EXTENSION = 536870912
+
+
+class GeneratorTest(unittest.TestCase):
+
+  def testNestedMessageDescriptor(self):
+    field_name = 'optional_nested_message'
+    proto_type = unittest_pb2.TestAllTypes
+    self.assertEqual(
+        proto_type.NestedMessage.DESCRIPTOR,
+        proto_type.DESCRIPTOR.fields_by_name[field_name].message_type)
+
+  def testEnums(self):
+    # We test only module-level enums here.
+    # TODO(robinson): Examine descriptors directly to check
+    # enum descriptor output.
+    self.assertEqual(4, unittest_pb2.FOREIGN_FOO)
+    self.assertEqual(5, unittest_pb2.FOREIGN_BAR)
+    self.assertEqual(6, unittest_pb2.FOREIGN_BAZ)
+
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(1, proto.FOO)
+    self.assertEqual(1, unittest_pb2.TestAllTypes.FOO)
+    self.assertEqual(2, proto.BAR)
+    self.assertEqual(2, unittest_pb2.TestAllTypes.BAR)
+    self.assertEqual(3, proto.BAZ)
+    self.assertEqual(3, unittest_pb2.TestAllTypes.BAZ)
+
+  def testExtremeDefaultValues(self):
+    message = unittest_pb2.TestExtremeDefaultValues()
+
+    # Python pre-2.6 does not have isinf() or isnan() functions, so we have
+    # to provide our own.
+    def isnan(val):
+      # NaN is never equal to itself.
+      return val != val
+    def isinf(val):
+      # Infinity times zero equals NaN.
+      return not isnan(val) and isnan(val * 0)
+
+    self.assertTrue(isinf(message.inf_double))
+    self.assertTrue(message.inf_double > 0)
+    self.assertTrue(isinf(message.neg_inf_double))
+    self.assertTrue(message.neg_inf_double < 0)
+    self.assertTrue(isnan(message.nan_double))
+
+    self.assertTrue(isinf(message.inf_float))
+    self.assertTrue(message.inf_float > 0)
+    self.assertTrue(isinf(message.neg_inf_float))
+    self.assertTrue(message.neg_inf_float < 0)
+    self.assertTrue(isnan(message.nan_float))
+    self.assertEqual("? ? ?? ?? ??? ??/ ??-", message.cpp_trigraph)
+
+  def testHasDefaultValues(self):
+    desc = unittest_pb2.TestAllTypes.DESCRIPTOR
+
+    expected_has_default_by_name = {
+        'optional_int32': False,
+        'repeated_int32': False,
+        'optional_nested_message': False,
+        'default_int32': True,
+    }
+
+    has_default_by_name = dict(
+        [(f.name, f.has_default_value)
+         for f in desc.fields
+         if f.name in expected_has_default_by_name])
+    self.assertEqual(expected_has_default_by_name, has_default_by_name)
+
+  def testContainingTypeBehaviorForExtensions(self):
+    self.assertEqual(unittest_pb2.optional_int32_extension.containing_type,
+                     unittest_pb2.TestAllExtensions.DESCRIPTOR)
+    self.assertEqual(unittest_pb2.TestRequired.single.containing_type,
+                     unittest_pb2.TestAllExtensions.DESCRIPTOR)
+
+  def testExtensionScope(self):
+    self.assertEqual(unittest_pb2.optional_int32_extension.extension_scope,
+                     None)
+    self.assertEqual(unittest_pb2.TestRequired.single.extension_scope,
+                     unittest_pb2.TestRequired.DESCRIPTOR)
+
+  def testIsExtension(self):
+    self.assertTrue(unittest_pb2.optional_int32_extension.is_extension)
+    self.assertTrue(unittest_pb2.TestRequired.single.is_extension)
+
+    message_descriptor = unittest_pb2.TestRequired.DESCRIPTOR
+    non_extension_descriptor = message_descriptor.fields_by_name['a']
+    self.assertTrue(not non_extension_descriptor.is_extension)
+
+  def testOptions(self):
+    proto = unittest_mset_wire_format_pb2.TestMessageSet()
+    self.assertTrue(proto.DESCRIPTOR.GetOptions().message_set_wire_format)
+
+  def testMessageWithCustomOptions(self):
+    proto = unittest_custom_options_pb2.TestMessageWithCustomOptions()
+    enum_options = proto.DESCRIPTOR.enum_types_by_name['AnEnum'].GetOptions()
+    self.assertTrue(enum_options is not None)
+    # TODO(gps): We really should test for the presence of the enum_opt1
+    # extension and for its value to be set to -789.
+
+  def testNestedTypes(self):
+    self.assertEqual(
+        set(unittest_pb2.TestAllTypes.DESCRIPTOR.nested_types),
+        set([
+            unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR,
+            unittest_pb2.TestAllTypes.OptionalGroup.DESCRIPTOR,
+            unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR,
+        ]))
+    self.assertEqual(unittest_pb2.TestEmptyMessage.DESCRIPTOR.nested_types, [])
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.nested_types, [])
+
+  def testContainingType(self):
+    self.assertTrue(
+        unittest_pb2.TestEmptyMessage.DESCRIPTOR.containing_type is None)
+    self.assertTrue(
+        unittest_pb2.TestAllTypes.DESCRIPTOR.containing_type is None)
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type,
+        unittest_pb2.TestAllTypes.DESCRIPTOR)
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type,
+        unittest_pb2.TestAllTypes.DESCRIPTOR)
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR.containing_type,
+        unittest_pb2.TestAllTypes.DESCRIPTOR)
+
+  def testContainingTypeInEnumDescriptor(self):
+    self.assertTrue(unittest_pb2._FOREIGNENUM.containing_type is None)
+    self.assertEqual(unittest_pb2._TESTALLTYPES_NESTEDENUM.containing_type,
+                     unittest_pb2.TestAllTypes.DESCRIPTOR)
+
+  def testPackage(self):
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.DESCRIPTOR.file.package,
+        'protobuf_unittest')
+    desc = unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR
+    self.assertEqual(desc.file.package, 'protobuf_unittest')
+    self.assertEqual(
+        unittest_import_pb2.ImportMessage.DESCRIPTOR.file.package,
+        'protobuf_unittest_import')
+
+    self.assertEqual(
+        unittest_pb2._FOREIGNENUM.file.package, 'protobuf_unittest')
+    self.assertEqual(
+        unittest_pb2._TESTALLTYPES_NESTEDENUM.file.package,
+        'protobuf_unittest')
+    self.assertEqual(
+        unittest_import_pb2._IMPORTENUM.file.package,
+        'protobuf_unittest_import')
+
+  def testExtensionRange(self):
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.DESCRIPTOR.extension_ranges, [])
+    self.assertEqual(
+        unittest_pb2.TestAllExtensions.DESCRIPTOR.extension_ranges,
+        [(1, MAX_EXTENSION)])
+    self.assertEqual(
+        unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR.extension_ranges,
+        [(42, 43), (4143, 4244), (65536, MAX_EXTENSION)])
+
+  def testFileDescriptor(self):
+    self.assertEqual(unittest_pb2.DESCRIPTOR.name,
+                     'google/protobuf/unittest.proto')
+    self.assertEqual(unittest_pb2.DESCRIPTOR.package, 'protobuf_unittest')
+    self.assertFalse(unittest_pb2.DESCRIPTOR.serialized_pb is None)
+    self.assertEqual(unittest_pb2.DESCRIPTOR.dependencies,
+                     [unittest_import_pb2.DESCRIPTOR])
+    self.assertEqual(unittest_import_pb2.DESCRIPTOR.dependencies,
+                     [unittest_import_public_pb2.DESCRIPTOR])
+
+  def testNoGenericServices(self):
+    self.assertTrue(hasattr(unittest_no_generic_services_pb2, "TestMessage"))
+    self.assertTrue(hasattr(unittest_no_generic_services_pb2, "FOO"))
+    self.assertTrue(hasattr(unittest_no_generic_services_pb2, "test_extension"))
+
+    # Make sure unittest_no_generic_services_pb2 has no services subclassing
+    # Proto2 Service class.
+    if hasattr(unittest_no_generic_services_pb2, "TestService"):
+      self.assertFalse(issubclass(unittest_no_generic_services_pb2.TestService,
+                                  service.Service))
+
+  def testMessageTypesByName(self):
+    file_type = unittest_pb2.DESCRIPTOR
+    self.assertEqual(
+        unittest_pb2._TESTALLTYPES,
+        file_type.message_types_by_name[unittest_pb2._TESTALLTYPES.name])
+
+    # Nested messages shouldn't be included in the message_types_by_name
+    # dictionary (like in the C++ API).
+    self.assertFalse(
+        unittest_pb2._TESTALLTYPES_NESTEDMESSAGE.name in
+        file_type.message_types_by_name)
+
+  def testEnumTypesByName(self):
+    file_type = unittest_pb2.DESCRIPTOR
+    self.assertEqual(
+        unittest_pb2._FOREIGNENUM,
+        file_type.enum_types_by_name[unittest_pb2._FOREIGNENUM.name])
+
+  def testExtensionsByName(self):
+    file_type = unittest_pb2.DESCRIPTOR
+    self.assertEqual(
+        unittest_pb2.my_extension_string,
+        file_type.extensions_by_name[unittest_pb2.my_extension_string.name])
+
+  def testPublicImports(self):
+    # Test public imports as embedded message.
+    all_type_proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(0, all_type_proto.optional_public_import_message.e)
+
+    # PublicImportMessage is actually defined in unittest_import_public_pb2
+    # module, and is public imported by unittest_import_pb2 module.
+    public_import_proto = unittest_import_pb2.PublicImportMessage()
+    self.assertEqual(0, public_import_proto.e)
+    self.assertTrue(unittest_import_public_pb2.PublicImportMessage is
+                    unittest_import_pb2.PublicImportMessage)
+
+  def testBadIdentifiers(self):
+    # We're just testing that the code was imported without problems.
+    message = test_bad_identifiers_pb2.TestBadIdentifiers()
+    self.assertEqual(message.Extensions[test_bad_identifiers_pb2.message],
+                     "foo")
+    self.assertEqual(message.Extensions[test_bad_identifiers_pb2.descriptor],
+                     "bar")
+    self.assertEqual(message.Extensions[test_bad_identifiers_pb2.reflection],
+                     "baz")
+    self.assertEqual(message.Extensions[test_bad_identifiers_pb2.service],
+                     "qux")
+
+  def testOneof(self):
+    desc = unittest_pb2.TestAllTypes.DESCRIPTOR
+    self.assertEqual(1, len(desc.oneofs))
+    self.assertEqual('oneof_field', desc.oneofs[0].name)
+    self.assertEqual(0, desc.oneofs[0].index)
+    self.assertIs(desc, desc.oneofs[0].containing_type)
+    self.assertIs(desc.oneofs[0], desc.oneofs_by_name['oneof_field'])
+    nested_names = set(['oneof_uint32', 'oneof_nested_message',
+                        'oneof_string', 'oneof_bytes'])
+    self.assertEqual(
+        nested_names,
+        set([field.name for field in desc.oneofs[0].fields]))
+    for field_name, field_desc in desc.fields_by_name.items():
+      if field_name in nested_names:
+        self.assertIs(desc.oneofs[0], field_desc.containing_oneof)
+      else:
+        self.assertIsNone(field_desc.containing_oneof)
+
+
+class SymbolDatabaseRegistrationTest(unittest.TestCase):
+  """Checks that messages, enums and files are correctly registered."""
+
+  def testGetSymbol(self):
+    self.assertEqual(
+        unittest_pb2.TestAllTypes, symbol_database.Default().GetSymbol(
+            'protobuf_unittest.TestAllTypes'))
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.NestedMessage,
+        symbol_database.Default().GetSymbol(
+            'protobuf_unittest.TestAllTypes.NestedMessage'))
+    with self.assertRaises(KeyError):
+      symbol_database.Default().GetSymbol('protobuf_unittest.NestedMessage')
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.OptionalGroup,
+        symbol_database.Default().GetSymbol(
+            'protobuf_unittest.TestAllTypes.OptionalGroup'))
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.RepeatedGroup,
+        symbol_database.Default().GetSymbol(
+            'protobuf_unittest.TestAllTypes.RepeatedGroup'))
+
+  def testEnums(self):
+    self.assertEqual(
+        'protobuf_unittest.ForeignEnum',
+        symbol_database.Default().pool.FindEnumTypeByName(
+            'protobuf_unittest.ForeignEnum').full_name)
+    self.assertEqual(
+        'protobuf_unittest.TestAllTypes.NestedEnum',
+        symbol_database.Default().pool.FindEnumTypeByName(
+            'protobuf_unittest.TestAllTypes.NestedEnum').full_name)
+
+  def testFindFileByName(self):
+    self.assertEqual(
+        'google/protobuf/unittest.proto',
+        symbol_database.Default().pool.FindFileByName(
+            'google/protobuf/unittest.proto').name)
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/import_test_package/__init__.py b/generator/google/protobuf/internal/import_test_package/__init__.py
new file mode 100644
index 0000000..5121dd0
--- /dev/null
+++ b/generator/google/protobuf/internal/import_test_package/__init__.py
@@ -0,0 +1,33 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Sample module importing a nested proto from itself."""
+
+from google.protobuf.internal.import_test_package import outer_pb2 as myproto
diff --git a/generator/google/protobuf/internal/import_test_package/inner_pb2.py b/generator/google/protobuf/internal/import_test_package/inner_pb2.py
new file mode 100644
index 0000000..e45c21b
--- /dev/null
+++ b/generator/google/protobuf/internal/import_test_package/inner_pb2.py
@@ -0,0 +1,69 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/import_test_package/inner.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/import_test_package/inner.proto',
+  package='google.protobuf.python.internal.import_test_package',
+  syntax='proto2',
+  serialized_pb=_b('\n8google/protobuf/internal/import_test_package/inner.proto\x12\x33google.protobuf.python.internal.import_test_package\"\x1a\n\x05Inner\x12\x11\n\x05value\x18\x01 \x01(\x05:\x02\x35\x37')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_INNER = _descriptor.Descriptor(
+  name='Inner',
+  full_name='google.protobuf.python.internal.import_test_package.Inner',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.python.internal.import_test_package.Inner.value', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=True, default_value=57,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=113,
+  serialized_end=139,
+)
+
+DESCRIPTOR.message_types_by_name['Inner'] = _INNER
+
+Inner = _reflection.GeneratedProtocolMessageType('Inner', (_message.Message,), dict(
+  DESCRIPTOR = _INNER,
+  __module__ = 'google.protobuf.internal.import_test_package.inner_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.import_test_package.Inner)
+  ))
+_sym_db.RegisterMessage(Inner)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/import_test_package/outer_pb2.py b/generator/google/protobuf/internal/import_test_package/outer_pb2.py
new file mode 100644
index 0000000..15f72f4
--- /dev/null
+++ b/generator/google/protobuf/internal/import_test_package/outer_pb2.py
@@ -0,0 +1,72 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/import_test_package/outer.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf.internal.import_test_package import inner_pb2 as google_dot_protobuf_dot_internal_dot_import__test__package_dot_inner__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/import_test_package/outer.proto',
+  package='google.protobuf.python.internal.import_test_package',
+  syntax='proto2',
+  serialized_pb=_b('\n8google/protobuf/internal/import_test_package/outer.proto\x12\x33google.protobuf.python.internal.import_test_package\x1a\x38google/protobuf/internal/import_test_package/inner.proto\"R\n\x05Outer\x12I\n\x05inner\x18\x01 \x01(\x0b\x32:.google.protobuf.python.internal.import_test_package.Inner')
+  ,
+  dependencies=[google_dot_protobuf_dot_internal_dot_import__test__package_dot_inner__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_OUTER = _descriptor.Descriptor(
+  name='Outer',
+  full_name='google.protobuf.python.internal.import_test_package.Outer',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='inner', full_name='google.protobuf.python.internal.import_test_package.Outer.inner', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=171,
+  serialized_end=253,
+)
+
+_OUTER.fields_by_name['inner'].message_type = google_dot_protobuf_dot_internal_dot_import__test__package_dot_inner__pb2._INNER
+DESCRIPTOR.message_types_by_name['Outer'] = _OUTER
+
+Outer = _reflection.GeneratedProtocolMessageType('Outer', (_message.Message,), dict(
+  DESCRIPTOR = _OUTER,
+  __module__ = 'google.protobuf.internal.import_test_package.outer_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.import_test_package.Outer)
+  ))
+_sym_db.RegisterMessage(Outer)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/json_format_test.py b/generator/google/protobuf/internal/json_format_test.py
new file mode 100644
index 0000000..a5ee8ac
--- /dev/null
+++ b/generator/google/protobuf/internal/json_format_test.py
@@ -0,0 +1,815 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Test for google.protobuf.json_format."""
+
+__author__ = 'jieluo@google.com (Jie Luo)'
+
+import json
+import math
+import sys
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+
+from google.protobuf import any_pb2
+from google.protobuf import duration_pb2
+from google.protobuf import field_mask_pb2
+from google.protobuf import struct_pb2
+from google.protobuf import timestamp_pb2
+from google.protobuf import wrappers_pb2
+from google.protobuf.internal import well_known_types
+from google.protobuf import json_format
+from google.protobuf.util import json_format_proto3_pb2
+
+
+class JsonFormatBase(unittest.TestCase):
+
+  def FillAllFields(self, message):
+    message.int32_value = 20
+    message.int64_value = -20
+    message.uint32_value = 3120987654
+    message.uint64_value = 12345678900
+    message.float_value = float('-inf')
+    message.double_value = 3.1415
+    message.bool_value = True
+    message.string_value = 'foo'
+    message.bytes_value = b'bar'
+    message.message_value.value = 10
+    message.enum_value = json_format_proto3_pb2.BAR
+    # Repeated
+    message.repeated_int32_value.append(0x7FFFFFFF)
+    message.repeated_int32_value.append(-2147483648)
+    message.repeated_int64_value.append(9007199254740992)
+    message.repeated_int64_value.append(-9007199254740992)
+    message.repeated_uint32_value.append(0xFFFFFFF)
+    message.repeated_uint32_value.append(0x7FFFFFF)
+    message.repeated_uint64_value.append(9007199254740992)
+    message.repeated_uint64_value.append(9007199254740991)
+    message.repeated_float_value.append(0)
+
+    message.repeated_double_value.append(1E-15)
+    message.repeated_double_value.append(float('inf'))
+    message.repeated_bool_value.append(True)
+    message.repeated_bool_value.append(False)
+    message.repeated_string_value.append('Few symbols!#$,;')
+    message.repeated_string_value.append('bar')
+    message.repeated_bytes_value.append(b'foo')
+    message.repeated_bytes_value.append(b'bar')
+    message.repeated_message_value.add().value = 10
+    message.repeated_message_value.add().value = 11
+    message.repeated_enum_value.append(json_format_proto3_pb2.FOO)
+    message.repeated_enum_value.append(json_format_proto3_pb2.BAR)
+    self.message = message
+
+  def CheckParseBack(self, message, parsed_message):
+    json_format.Parse(json_format.MessageToJson(message),
+                      parsed_message)
+    self.assertEqual(message, parsed_message)
+
+  def CheckError(self, text, error_message):
+    message = json_format_proto3_pb2.TestMessage()
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        error_message,
+        json_format.Parse, text, message)
+
+
+class JsonFormatTest(JsonFormatBase):
+
+  def testEmptyMessageToJson(self):
+    message = json_format_proto3_pb2.TestMessage()
+    self.assertEqual(json_format.MessageToJson(message),
+                     '{}')
+    parsed_message = json_format_proto3_pb2.TestMessage()
+    self.CheckParseBack(message, parsed_message)
+
+  def testPartialMessageToJson(self):
+    message = json_format_proto3_pb2.TestMessage(
+        string_value='test',
+        repeated_int32_value=[89, 4])
+    self.assertEqual(json.loads(json_format.MessageToJson(message)),
+                     json.loads('{"stringValue": "test", '
+                                '"repeatedInt32Value": [89, 4]}'))
+    parsed_message = json_format_proto3_pb2.TestMessage()
+    self.CheckParseBack(message, parsed_message)
+
+  def testAllFieldsToJson(self):
+    message = json_format_proto3_pb2.TestMessage()
+    text = ('{"int32Value": 20, '
+            '"int64Value": "-20", '
+            '"uint32Value": 3120987654,'
+            '"uint64Value": "12345678900",'
+            '"floatValue": "-Infinity",'
+            '"doubleValue": 3.1415,'
+            '"boolValue": true,'
+            '"stringValue": "foo",'
+            '"bytesValue": "YmFy",'
+            '"messageValue": {"value": 10},'
+            '"enumValue": "BAR",'
+            '"repeatedInt32Value": [2147483647, -2147483648],'
+            '"repeatedInt64Value": ["9007199254740992", "-9007199254740992"],'
+            '"repeatedUint32Value": [268435455, 134217727],'
+            '"repeatedUint64Value": ["9007199254740992", "9007199254740991"],'
+            '"repeatedFloatValue": [0],'
+            '"repeatedDoubleValue": [1e-15, "Infinity"],'
+            '"repeatedBoolValue": [true, false],'
+            '"repeatedStringValue": ["Few symbols!#$,;", "bar"],'
+            '"repeatedBytesValue": ["Zm9v", "YmFy"],'
+            '"repeatedMessageValue": [{"value": 10}, {"value": 11}],'
+            '"repeatedEnumValue": ["FOO", "BAR"]'
+            '}')
+    self.FillAllFields(message)
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message)),
+        json.loads(text))
+    parsed_message = json_format_proto3_pb2.TestMessage()
+    json_format.Parse(text, parsed_message)
+    self.assertEqual(message, parsed_message)
+
+  def testJsonEscapeString(self):
+    message = json_format_proto3_pb2.TestMessage()
+    if sys.version_info[0] < 3:
+      message.string_value = '&\n<\"\r>\b\t\f\\\001/\xe2\x80\xa8\xe2\x80\xa9'
+    else:
+      message.string_value = '&\n<\"\r>\b\t\f\\\001/'
+      message.string_value += (b'\xe2\x80\xa8\xe2\x80\xa9').decode('utf-8')
+    self.assertEqual(
+        json_format.MessageToJson(message),
+        '{\n  "stringValue": '
+        '"&\\n<\\\"\\r>\\b\\t\\f\\\\\\u0001/\\u2028\\u2029"\n}')
+    parsed_message = json_format_proto3_pb2.TestMessage()
+    self.CheckParseBack(message, parsed_message)
+    text = u'{"int32Value": "\u0031"}'
+    json_format.Parse(text, message)
+    self.assertEqual(message.int32_value, 1)
+
+  def testAlwaysSeriliaze(self):
+    message = json_format_proto3_pb2.TestMessage(
+        string_value='foo')
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, True)),
+        json.loads('{'
+                   '"repeatedStringValue": [],'
+                   '"stringValue": "foo",'
+                   '"repeatedBoolValue": [],'
+                   '"repeatedUint32Value": [],'
+                   '"repeatedInt32Value": [],'
+                   '"enumValue": "FOO",'
+                   '"int32Value": 0,'
+                   '"floatValue": 0,'
+                   '"int64Value": "0",'
+                   '"uint32Value": 0,'
+                   '"repeatedBytesValue": [],'
+                   '"repeatedUint64Value": [],'
+                   '"repeatedDoubleValue": [],'
+                   '"bytesValue": "",'
+                   '"boolValue": false,'
+                   '"repeatedEnumValue": [],'
+                   '"uint64Value": "0",'
+                   '"doubleValue": 0,'
+                   '"repeatedFloatValue": [],'
+                   '"repeatedInt64Value": [],'
+                   '"repeatedMessageValue": []}'))
+    parsed_message = json_format_proto3_pb2.TestMessage()
+    self.CheckParseBack(message, parsed_message)
+
+  def testMapFields(self):
+    message = json_format_proto3_pb2.TestMap()
+    message.bool_map[True] = 1
+    message.bool_map[False] = 2
+    message.int32_map[1] = 2
+    message.int32_map[2] = 3
+    message.int64_map[1] = 2
+    message.int64_map[2] = 3
+    message.uint32_map[1] = 2
+    message.uint32_map[2] = 3
+    message.uint64_map[1] = 2
+    message.uint64_map[2] = 3
+    message.string_map['1'] = 2
+    message.string_map['null'] = 3
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, True)),
+        json.loads('{'
+                   '"boolMap": {"false": 2, "true": 1},'
+                   '"int32Map": {"1": 2, "2": 3},'
+                   '"int64Map": {"1": 2, "2": 3},'
+                   '"uint32Map": {"1": 2, "2": 3},'
+                   '"uint64Map": {"1": 2, "2": 3},'
+                   '"stringMap": {"1": 2, "null": 3}'
+                   '}'))
+    parsed_message = json_format_proto3_pb2.TestMap()
+    self.CheckParseBack(message, parsed_message)
+
+  def testOneofFields(self):
+    message = json_format_proto3_pb2.TestOneof()
+    # Always print does not affect oneof fields.
+    self.assertEqual(
+        json_format.MessageToJson(message, True),
+        '{}')
+    message.oneof_int32_value = 0
+    self.assertEqual(
+        json_format.MessageToJson(message, True),
+        '{\n'
+        '  "oneofInt32Value": 0\n'
+        '}')
+    parsed_message = json_format_proto3_pb2.TestOneof()
+    self.CheckParseBack(message, parsed_message)
+
+  def testSurrogates(self):
+    # Test correct surrogate handling.
+    message = json_format_proto3_pb2.TestMessage()
+    json_format.Parse('{"stringValue": "\\uD83D\\uDE01"}', message)
+    self.assertEqual(message.string_value,
+                     b'\xF0\x9F\x98\x81'.decode('utf-8', 'strict'))
+
+    # Error case: unpaired high surrogate.
+    self.CheckError(
+        '{"stringValue": "\\uD83D"}',
+        r'Invalid \\uXXXX escape|Unpaired.*surrogate')
+
+    # Unpaired low surrogate.
+    self.CheckError(
+        '{"stringValue": "\\uDE01"}',
+        r'Invalid \\uXXXX escape|Unpaired.*surrogate')
+
+  def testTimestampMessage(self):
+    message = json_format_proto3_pb2.TestTimestamp()
+    message.value.seconds = 0
+    message.value.nanos = 0
+    message.repeated_value.add().seconds = 20
+    message.repeated_value[0].nanos = 1
+    message.repeated_value.add().seconds = 0
+    message.repeated_value[1].nanos = 10000
+    message.repeated_value.add().seconds = 100000000
+    message.repeated_value[2].nanos = 0
+    # Maximum time
+    message.repeated_value.add().seconds = 253402300799
+    message.repeated_value[3].nanos = 999999999
+    # Minimum time
+    message.repeated_value.add().seconds = -62135596800
+    message.repeated_value[4].nanos = 0
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, True)),
+        json.loads('{'
+                   '"value": "1970-01-01T00:00:00Z",'
+                   '"repeatedValue": ['
+                   '  "1970-01-01T00:00:20.000000001Z",'
+                   '  "1970-01-01T00:00:00.000010Z",'
+                   '  "1973-03-03T09:46:40Z",'
+                   '  "9999-12-31T23:59:59.999999999Z",'
+                   '  "0001-01-01T00:00:00Z"'
+                   ']'
+                   '}'))
+    parsed_message = json_format_proto3_pb2.TestTimestamp()
+    self.CheckParseBack(message, parsed_message)
+    text = (r'{"value": "1970-01-01T00:00:00.01+08:00",'
+            r'"repeatedValue":['
+            r'  "1970-01-01T00:00:00.01+08:30",'
+            r'  "1970-01-01T00:00:00.01-01:23"]}')
+    json_format.Parse(text, parsed_message)
+    self.assertEqual(parsed_message.value.seconds, -8 * 3600)
+    self.assertEqual(parsed_message.value.nanos, 10000000)
+    self.assertEqual(parsed_message.repeated_value[0].seconds, -8.5 * 3600)
+    self.assertEqual(parsed_message.repeated_value[1].seconds, 3600 + 23 * 60)
+
+  def testDurationMessage(self):
+    message = json_format_proto3_pb2.TestDuration()
+    message.value.seconds = 1
+    message.repeated_value.add().seconds = 0
+    message.repeated_value[0].nanos = 10
+    message.repeated_value.add().seconds = -1
+    message.repeated_value[1].nanos = -1000
+    message.repeated_value.add().seconds = 10
+    message.repeated_value[2].nanos = 11000000
+    message.repeated_value.add().seconds = -315576000000
+    message.repeated_value.add().seconds = 315576000000
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, True)),
+        json.loads('{'
+                   '"value": "1s",'
+                   '"repeatedValue": ['
+                   '  "0.000000010s",'
+                   '  "-1.000001s",'
+                   '  "10.011s",'
+                   '  "-315576000000s",'
+                   '  "315576000000s"'
+                   ']'
+                   '}'))
+    parsed_message = json_format_proto3_pb2.TestDuration()
+    self.CheckParseBack(message, parsed_message)
+
+  def testFieldMaskMessage(self):
+    message = json_format_proto3_pb2.TestFieldMask()
+    message.value.paths.append('foo.bar')
+    message.value.paths.append('bar')
+    self.assertEqual(
+        json_format.MessageToJson(message, True),
+        '{\n'
+        '  "value": "foo.bar,bar"\n'
+        '}')
+    parsed_message = json_format_proto3_pb2.TestFieldMask()
+    self.CheckParseBack(message, parsed_message)
+
+  def testWrapperMessage(self):
+    message = json_format_proto3_pb2.TestWrapper()
+    message.bool_value.value = False
+    message.int32_value.value = 0
+    message.string_value.value = ''
+    message.bytes_value.value = b''
+    message.repeated_bool_value.add().value = True
+    message.repeated_bool_value.add().value = False
+    message.repeated_int32_value.add()
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, True)),
+        json.loads('{\n'
+                   '  "int32Value": 0,'
+                   '  "boolValue": false,'
+                   '  "stringValue": "",'
+                   '  "bytesValue": "",'
+                   '  "repeatedBoolValue": [true, false],'
+                   '  "repeatedInt32Value": [0],'
+                   '  "repeatedUint32Value": [],'
+                   '  "repeatedFloatValue": [],'
+                   '  "repeatedDoubleValue": [],'
+                   '  "repeatedBytesValue": [],'
+                   '  "repeatedInt64Value": [],'
+                   '  "repeatedUint64Value": [],'
+                   '  "repeatedStringValue": []'
+                   '}'))
+    parsed_message = json_format_proto3_pb2.TestWrapper()
+    self.CheckParseBack(message, parsed_message)
+
+  def testStructMessage(self):
+    message = json_format_proto3_pb2.TestStruct()
+    message.value['name'] = 'Jim'
+    message.value['age'] = 10
+    message.value['attend'] = True
+    message.value['email'] = None
+    message.value.get_or_create_struct('address')['city'] = 'SFO'
+    message.value['address']['house_number'] = 1024
+    struct_list = message.value.get_or_create_list('list')
+    struct_list.extend([6, 'seven', True, False, None])
+    struct_list.add_struct()['subkey2'] = 9
+    message.repeated_value.add()['age'] = 11
+    message.repeated_value.add()
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, False)),
+        json.loads(
+            '{'
+            '  "value": {'
+            '    "address": {'
+            '      "city": "SFO", '
+            '      "house_number": 1024'
+            '    }, '
+            '    "age": 10, '
+            '    "name": "Jim", '
+            '    "attend": true, '
+            '    "email": null, '
+            '    "list": [6, "seven", true, false, null, {"subkey2": 9}]'
+            '  },'
+            '  "repeatedValue": [{"age": 11}, {}]'
+            '}'))
+    parsed_message = json_format_proto3_pb2.TestStruct()
+    self.CheckParseBack(message, parsed_message)
+
+  def testValueMessage(self):
+    message = json_format_proto3_pb2.TestValue()
+    message.value.string_value = 'hello'
+    message.repeated_value.add().number_value = 11.1
+    message.repeated_value.add().bool_value = False
+    message.repeated_value.add().null_value = 0
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, False)),
+        json.loads(
+            '{'
+            '  "value": "hello",'
+            '  "repeatedValue": [11.1, false, null]'
+            '}'))
+    parsed_message = json_format_proto3_pb2.TestValue()
+    self.CheckParseBack(message, parsed_message)
+    # Can't parse back if the Value message is not set.
+    message.repeated_value.add()
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, False)),
+        json.loads(
+            '{'
+            '  "value": "hello",'
+            '  "repeatedValue": [11.1, false, null, null]'
+            '}'))
+
+  def testListValueMessage(self):
+    message = json_format_proto3_pb2.TestListValue()
+    message.value.values.add().number_value = 11.1
+    message.value.values.add().null_value = 0
+    message.value.values.add().bool_value = True
+    message.value.values.add().string_value = 'hello'
+    message.value.values.add().struct_value['name'] = 'Jim'
+    message.repeated_value.add().values.add().number_value = 1
+    message.repeated_value.add()
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, False)),
+        json.loads(
+            '{"value": [11.1, null, true, "hello", {"name": "Jim"}]\n,'
+            '"repeatedValue": [[1], []]}'))
+    parsed_message = json_format_proto3_pb2.TestListValue()
+    self.CheckParseBack(message, parsed_message)
+
+  def testAnyMessage(self):
+    message = json_format_proto3_pb2.TestAny()
+    value1 = json_format_proto3_pb2.MessageType()
+    value2 = json_format_proto3_pb2.MessageType()
+    value1.value = 1234
+    value2.value = 5678
+    message.value.Pack(value1)
+    message.repeated_value.add().Pack(value1)
+    message.repeated_value.add().Pack(value2)
+    message.repeated_value.add()
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, True)),
+        json.loads(
+            '{\n'
+            '  "repeatedValue": [ {\n'
+            '    "@type": "type.googleapis.com/proto3.MessageType",\n'
+            '    "value": 1234\n'
+            '  }, {\n'
+            '    "@type": "type.googleapis.com/proto3.MessageType",\n'
+            '    "value": 5678\n'
+            '  },\n'
+            '  {}],\n'
+            '  "value": {\n'
+            '    "@type": "type.googleapis.com/proto3.MessageType",\n'
+            '    "value": 1234\n'
+            '  }\n'
+            '}\n'))
+    parsed_message = json_format_proto3_pb2.TestAny()
+    self.CheckParseBack(message, parsed_message)
+    # Must print @type first
+    test_message = json_format_proto3_pb2.TestMessage(
+        bool_value=True,
+        int32_value=20,
+        int64_value=-20,
+        uint32_value=20,
+        uint64_value=20,
+        double_value=3.14,
+        string_value='foo')
+    message.Clear()
+    message.value.Pack(test_message)
+    self.assertEqual(
+        json_format.MessageToJson(message, False)[0:68],
+        '{\n'
+        '  "value": {\n'
+        '    "@type": "type.googleapis.com/proto3.TestMessage"')
+
+  def testWellKnownInAnyMessage(self):
+    message = any_pb2.Any()
+    int32_value = wrappers_pb2.Int32Value()
+    int32_value.value = 1234
+    message.Pack(int32_value)
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, True)),
+        json.loads(
+            '{\n'
+            '  "@type": \"type.googleapis.com/google.protobuf.Int32Value\",\n'
+            '  "value": 1234\n'
+            '}\n'))
+    parsed_message = any_pb2.Any()
+    self.CheckParseBack(message, parsed_message)
+
+    timestamp = timestamp_pb2.Timestamp()
+    message.Pack(timestamp)
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, True)),
+        json.loads(
+            '{\n'
+            '  "@type": "type.googleapis.com/google.protobuf.Timestamp",\n'
+            '  "value": "1970-01-01T00:00:00Z"\n'
+            '}\n'))
+    self.CheckParseBack(message, parsed_message)
+
+    duration = duration_pb2.Duration()
+    duration.seconds = 1
+    message.Pack(duration)
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, True)),
+        json.loads(
+            '{\n'
+            '  "@type": "type.googleapis.com/google.protobuf.Duration",\n'
+            '  "value": "1s"\n'
+            '}\n'))
+    self.CheckParseBack(message, parsed_message)
+
+    field_mask = field_mask_pb2.FieldMask()
+    field_mask.paths.append('foo.bar')
+    field_mask.paths.append('bar')
+    message.Pack(field_mask)
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, True)),
+        json.loads(
+            '{\n'
+            '  "@type": "type.googleapis.com/google.protobuf.FieldMask",\n'
+            '  "value": "foo.bar,bar"\n'
+            '}\n'))
+    self.CheckParseBack(message, parsed_message)
+
+    struct_message = struct_pb2.Struct()
+    struct_message['name'] = 'Jim'
+    message.Pack(struct_message)
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, True)),
+        json.loads(
+            '{\n'
+            '  "@type": "type.googleapis.com/google.protobuf.Struct",\n'
+            '  "value": {"name": "Jim"}\n'
+            '}\n'))
+    self.CheckParseBack(message, parsed_message)
+
+    nested_any = any_pb2.Any()
+    int32_value.value = 5678
+    nested_any.Pack(int32_value)
+    message.Pack(nested_any)
+    self.assertEqual(
+        json.loads(json_format.MessageToJson(message, True)),
+        json.loads(
+            '{\n'
+            '  "@type": "type.googleapis.com/google.protobuf.Any",\n'
+            '  "value": {\n'
+            '    "@type": "type.googleapis.com/google.protobuf.Int32Value",\n'
+            '    "value": 5678\n'
+            '  }\n'
+            '}\n'))
+    self.CheckParseBack(message, parsed_message)
+
+  def testParseNull(self):
+    message = json_format_proto3_pb2.TestMessage()
+    parsed_message = json_format_proto3_pb2.TestMessage()
+    self.FillAllFields(parsed_message)
+    json_format.Parse('{"int32Value": null, '
+                      '"int64Value": null, '
+                      '"uint32Value": null,'
+                      '"uint64Value": null,'
+                      '"floatValue": null,'
+                      '"doubleValue": null,'
+                      '"boolValue": null,'
+                      '"stringValue": null,'
+                      '"bytesValue": null,'
+                      '"messageValue": null,'
+                      '"enumValue": null,'
+                      '"repeatedInt32Value": null,'
+                      '"repeatedInt64Value": null,'
+                      '"repeatedUint32Value": null,'
+                      '"repeatedUint64Value": null,'
+                      '"repeatedFloatValue": null,'
+                      '"repeatedDoubleValue": null,'
+                      '"repeatedBoolValue": null,'
+                      '"repeatedStringValue": null,'
+                      '"repeatedBytesValue": null,'
+                      '"repeatedMessageValue": null,'
+                      '"repeatedEnumValue": null'
+                      '}',
+                      parsed_message)
+    self.assertEqual(message, parsed_message)
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        'Failed to parse repeatedInt32Value field: '
+        'null is not allowed to be used as an element in a repeated field.',
+        json_format.Parse,
+        '{"repeatedInt32Value":[1, null]}',
+        parsed_message)
+
+  def testNanFloat(self):
+    message = json_format_proto3_pb2.TestMessage()
+    message.float_value = float('nan')
+    text = '{\n  "floatValue": "NaN"\n}'
+    self.assertEqual(json_format.MessageToJson(message), text)
+    parsed_message = json_format_proto3_pb2.TestMessage()
+    json_format.Parse(text, parsed_message)
+    self.assertTrue(math.isnan(parsed_message.float_value))
+
+  def testParseEmptyText(self):
+    self.CheckError('',
+                    r'Failed to load JSON: (Expecting value)|(No JSON).')
+
+  def testParseBadEnumValue(self):
+    self.CheckError(
+        '{"enumValue": 1}',
+        'Enum value must be a string literal with double quotes. '
+        'Type "proto3.EnumType" has no value named 1.')
+    self.CheckError(
+        '{"enumValue": "baz"}',
+        'Enum value must be a string literal with double quotes. '
+        'Type "proto3.EnumType" has no value named baz.')
+
+  def testParseBadIdentifer(self):
+    self.CheckError('{int32Value: 1}',
+                    (r'Failed to load JSON: Expecting property name'
+                     r'( enclosed in double quotes)?: line 1'))
+    self.CheckError('{"unknownName": 1}',
+                    'Message type "proto3.TestMessage" has no field named '
+                    '"unknownName".')
+
+  def testIgnoreUnknownField(self):
+    text = '{"unknownName": 1}'
+    parsed_message = json_format_proto3_pb2.TestMessage()
+    json_format.Parse(text, parsed_message, ignore_unknown_fields=True)
+    text = ('{\n'
+            '  "repeatedValue": [ {\n'
+            '    "@type": "type.googleapis.com/proto3.MessageType",\n'
+            '    "unknownName": 1\n'
+            '  }]\n'
+            '}\n')
+    parsed_message = json_format_proto3_pb2.TestAny()
+    json_format.Parse(text, parsed_message, ignore_unknown_fields=True)
+
+  def testDuplicateField(self):
+    # Duplicate key check is not supported for python2.6
+    if sys.version_info < (2, 7):
+      return
+    self.CheckError('{"int32Value": 1,\n"int32Value":2}',
+                    'Failed to load JSON: duplicate key int32Value.')
+
+  def testInvalidBoolValue(self):
+    self.CheckError('{"boolValue": 1}',
+                    'Failed to parse boolValue field: '
+                    'Expected true or false without quotes.')
+    self.CheckError('{"boolValue": "true"}',
+                    'Failed to parse boolValue field: '
+                    'Expected true or false without quotes.')
+
+  def testInvalidIntegerValue(self):
+    message = json_format_proto3_pb2.TestMessage()
+    text = '{"int32Value": 0x12345}'
+    self.assertRaises(json_format.ParseError,
+                      json_format.Parse, text, message)
+    self.CheckError('{"int32Value": 012345}',
+                    (r'Failed to load JSON: Expecting \'?,\'? delimiter: '
+                     r'line 1.'))
+    self.CheckError('{"int32Value": 1.0}',
+                    'Failed to parse int32Value field: '
+                    'Couldn\'t parse integer: 1.0.')
+    self.CheckError('{"int32Value": " 1 "}',
+                    'Failed to parse int32Value field: '
+                    'Couldn\'t parse integer: " 1 ".')
+    self.CheckError('{"int32Value": "1 "}',
+                    'Failed to parse int32Value field: '
+                    'Couldn\'t parse integer: "1 ".')
+    self.CheckError('{"int32Value": 12345678901234567890}',
+                    'Failed to parse int32Value field: Value out of range: '
+                    '12345678901234567890.')
+    self.CheckError('{"int32Value": 1e5}',
+                    'Failed to parse int32Value field: '
+                    'Couldn\'t parse integer: 100000.0.')
+    self.CheckError('{"uint32Value": -1}',
+                    'Failed to parse uint32Value field: '
+                    'Value out of range: -1.')
+
+  def testInvalidFloatValue(self):
+    self.CheckError('{"floatValue": "nan"}',
+                    'Failed to parse floatValue field: Couldn\'t '
+                    'parse float "nan", use "NaN" instead.')
+
+  def testInvalidBytesValue(self):
+    self.CheckError('{"bytesValue": "AQI"}',
+                    'Failed to parse bytesValue field: Incorrect padding.')
+    self.CheckError('{"bytesValue": "AQI*"}',
+                    'Failed to parse bytesValue field: Incorrect padding.')
+
+  def testInvalidMap(self):
+    message = json_format_proto3_pb2.TestMap()
+    text = '{"int32Map": {"null": 2, "2": 3}}'
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        'Failed to parse int32Map field: invalid literal',
+        json_format.Parse, text, message)
+    text = '{"int32Map": {1: 2, "2": 3}}'
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        (r'Failed to load JSON: Expecting property name'
+         r'( enclosed in double quotes)?: line 1'),
+        json_format.Parse, text, message)
+    text = '{"boolMap": {"null": 1}}'
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        'Failed to parse boolMap field: Expected "true" or "false", not null.',
+        json_format.Parse, text, message)
+    if sys.version_info < (2, 7):
+      return
+    text = r'{"stringMap": {"a": 3, "\u0061": 2}}'
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        'Failed to load JSON: duplicate key a',
+        json_format.Parse, text, message)
+
+  def testInvalidTimestamp(self):
+    message = json_format_proto3_pb2.TestTimestamp()
+    text = '{"value": "10000-01-01T00:00:00.00Z"}'
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        'time data \'10000-01-01T00:00:00\' does not match'
+        ' format \'%Y-%m-%dT%H:%M:%S\'.',
+        json_format.Parse, text, message)
+    text = '{"value": "1970-01-01T00:00:00.0123456789012Z"}'
+    self.assertRaisesRegexp(
+        well_known_types.ParseError,
+        'nanos 0123456789012 more than 9 fractional digits.',
+        json_format.Parse, text, message)
+    text = '{"value": "1972-01-01T01:00:00.01+08"}'
+    self.assertRaisesRegexp(
+        well_known_types.ParseError,
+        (r'Invalid timezone offset value: \+08.'),
+        json_format.Parse, text, message)
+    # Time smaller than minimum time.
+    text = '{"value": "0000-01-01T00:00:00Z"}'
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        'Failed to parse value field: year is out of range.',
+        json_format.Parse, text, message)
+    # Time bigger than maxinum time.
+    message.value.seconds = 253402300800
+    self.assertRaisesRegexp(
+        OverflowError,
+        'date value out of range',
+        json_format.MessageToJson, message)
+
+  def testInvalidOneof(self):
+    message = json_format_proto3_pb2.TestOneof()
+    text = '{"oneofInt32Value": 1, "oneofStringValue": "2"}'
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        'Message type "proto3.TestOneof"'
+        ' should not have multiple "oneof_value" oneof fields.',
+        json_format.Parse, text, message)
+
+  def testInvalidListValue(self):
+    message = json_format_proto3_pb2.TestListValue()
+    text = '{"value": 1234}'
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        r'Failed to parse value field: ListValue must be in \[\] which is 1234',
+        json_format.Parse, text, message)
+
+  def testInvalidStruct(self):
+    message = json_format_proto3_pb2.TestStruct()
+    text = '{"value": 1234}'
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        'Failed to parse value field: Struct must be in a dict which is 1234',
+        json_format.Parse, text, message)
+
+  def testInvalidAny(self):
+    message = any_pb2.Any()
+    text = '{"@type": "type.googleapis.com/google.protobuf.Int32Value"}'
+    self.assertRaisesRegexp(
+        KeyError,
+        'value',
+        json_format.Parse, text, message)
+    text = '{"value": 1234}'
+    self.assertRaisesRegexp(
+        json_format.ParseError,
+        '@type is missing when parsing any message.',
+        json_format.Parse, text, message)
+    text = '{"@type": "type.googleapis.com/MessageNotExist", "value": 1234}'
+    self.assertRaisesRegexp(
+        TypeError,
+        'Can not find message descriptor by type_url: '
+        'type.googleapis.com/MessageNotExist.',
+        json_format.Parse, text, message)
+    # Only last part is to be used: b/25630112
+    text = (r'{"@type": "incorrect.googleapis.com/google.protobuf.Int32Value",'
+            r'"value": 1234}')
+    json_format.Parse(text, message)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/message_factory_test.py b/generator/google/protobuf/internal/message_factory_test.py
new file mode 100644
index 0000000..7bb7d1a
--- /dev/null
+++ b/generator/google/protobuf/internal/message_factory_test.py
@@ -0,0 +1,190 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Tests for google.protobuf.message_factory."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+
+from google.protobuf import descriptor_pb2
+from google.protobuf.internal import factory_test1_pb2
+from google.protobuf.internal import factory_test2_pb2
+from google.protobuf import descriptor_database
+from google.protobuf import descriptor_pool
+from google.protobuf import message_factory
+
+
+class MessageFactoryTest(unittest.TestCase):
+
+  def setUp(self):
+    self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString(
+        factory_test1_pb2.DESCRIPTOR.serialized_pb)
+    self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString(
+        factory_test2_pb2.DESCRIPTOR.serialized_pb)
+
+  def _ExerciseDynamicClass(self, cls):
+    msg = cls()
+    msg.mandatory = 42
+    msg.nested_factory_2_enum = 0
+    msg.nested_factory_2_message.value = 'nested message value'
+    msg.factory_1_message.factory_1_enum = 1
+    msg.factory_1_message.nested_factory_1_enum = 0
+    msg.factory_1_message.nested_factory_1_message.value = (
+        'nested message value')
+    msg.factory_1_message.scalar_value = 22
+    msg.factory_1_message.list_value.extend([u'one', u'two', u'three'])
+    msg.factory_1_message.list_value.append(u'four')
+    msg.factory_1_enum = 1
+    msg.nested_factory_1_enum = 0
+    msg.nested_factory_1_message.value = 'nested message value'
+    msg.circular_message.mandatory = 1
+    msg.circular_message.circular_message.mandatory = 2
+    msg.circular_message.scalar_value = 'one deep'
+    msg.scalar_value = 'zero deep'
+    msg.list_value.extend([u'four', u'three', u'two'])
+    msg.list_value.append(u'one')
+    msg.grouped.add()
+    msg.grouped[0].part_1 = 'hello'
+    msg.grouped[0].part_2 = 'world'
+    msg.grouped.add(part_1='testing', part_2='123')
+    msg.loop.loop.mandatory = 2
+    msg.loop.loop.loop.loop.mandatory = 4
+    serialized = msg.SerializeToString()
+    converted = factory_test2_pb2.Factory2Message.FromString(serialized)
+    reserialized = converted.SerializeToString()
+    self.assertEqual(serialized, reserialized)
+    result = cls.FromString(reserialized)
+    self.assertEqual(msg, result)
+
+  def testGetPrototype(self):
+    db = descriptor_database.DescriptorDatabase()
+    pool = descriptor_pool.DescriptorPool(db)
+    db.Add(self.factory_test1_fd)
+    db.Add(self.factory_test2_fd)
+    factory = message_factory.MessageFactory()
+    cls = factory.GetPrototype(pool.FindMessageTypeByName(
+        'google.protobuf.python.internal.Factory2Message'))
+    self.assertFalse(cls is factory_test2_pb2.Factory2Message)
+    self._ExerciseDynamicClass(cls)
+    cls2 = factory.GetPrototype(pool.FindMessageTypeByName(
+        'google.protobuf.python.internal.Factory2Message'))
+    self.assertTrue(cls is cls2)
+
+  def testGetMessages(self):
+    # performed twice because multiple calls with the same input must be allowed
+    for _ in range(2):
+      messages = message_factory.GetMessages([self.factory_test1_fd,
+                                              self.factory_test2_fd])
+      self.assertTrue(
+          set(['google.protobuf.python.internal.Factory2Message',
+               'google.protobuf.python.internal.Factory1Message'],
+             ).issubset(set(messages.keys())))
+      self._ExerciseDynamicClass(
+          messages['google.protobuf.python.internal.Factory2Message'])
+      self.assertTrue(
+          set(['google.protobuf.python.internal.Factory2Message.one_more_field',
+               'google.protobuf.python.internal.another_field'],
+             ).issubset(
+                 set(messages['google.protobuf.python.internal.Factory1Message']
+                     ._extensions_by_name.keys())))
+      factory_msg1 = messages['google.protobuf.python.internal.Factory1Message']
+      msg1 = messages['google.protobuf.python.internal.Factory1Message']()
+      ext1 = factory_msg1._extensions_by_name[
+          'google.protobuf.python.internal.Factory2Message.one_more_field']
+      ext2 = factory_msg1._extensions_by_name[
+          'google.protobuf.python.internal.another_field']
+      msg1.Extensions[ext1] = 'test1'
+      msg1.Extensions[ext2] = 'test2'
+      self.assertEqual('test1', msg1.Extensions[ext1])
+      self.assertEqual('test2', msg1.Extensions[ext2])
+
+  def testDuplicateExtensionNumber(self):
+    pool = descriptor_pool.DescriptorPool()
+    factory = message_factory.MessageFactory(pool=pool)
+
+    # Add Container message.
+    f = descriptor_pb2.FileDescriptorProto()
+    f.name = 'google/protobuf/internal/container.proto'
+    f.package = 'google.protobuf.python.internal'
+    msg = f.message_type.add()
+    msg.name = 'Container'
+    rng = msg.extension_range.add()
+    rng.start = 1
+    rng.end = 10
+    pool.Add(f)
+    msgs = factory.GetMessages([f.name])
+    self.assertIn('google.protobuf.python.internal.Container', msgs)
+
+    # Extend container.
+    f = descriptor_pb2.FileDescriptorProto()
+    f.name = 'google/protobuf/internal/extension.proto'
+    f.package = 'google.protobuf.python.internal'
+    f.dependency.append('google/protobuf/internal/container.proto')
+    msg = f.message_type.add()
+    msg.name = 'Extension'
+    ext = msg.extension.add()
+    ext.name = 'extension_field'
+    ext.number = 2
+    ext.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL
+    ext.type_name = 'Extension'
+    ext.extendee = 'Container'
+    pool.Add(f)
+    msgs = factory.GetMessages([f.name])
+    self.assertIn('google.protobuf.python.internal.Extension', msgs)
+
+    # Add Duplicate extending the same field number.
+    f = descriptor_pb2.FileDescriptorProto()
+    f.name = 'google/protobuf/internal/duplicate.proto'
+    f.package = 'google.protobuf.python.internal'
+    f.dependency.append('google/protobuf/internal/container.proto')
+    msg = f.message_type.add()
+    msg.name = 'Duplicate'
+    ext = msg.extension.add()
+    ext.name = 'extension_field'
+    ext.number = 2
+    ext.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL
+    ext.type_name = 'Duplicate'
+    ext.extendee = 'Container'
+    pool.Add(f)
+
+    with self.assertRaises(Exception) as cm:
+      factory.GetMessages([f.name])
+
+    self.assertIsInstance(cm.exception, (AssertionError, ValueError))
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/message_listener.py b/generator/google/protobuf/internal/message_listener.py
index 1080234..0fc255a 100644
--- a/generator/google/protobuf/internal/message_listener.py
+++ b/generator/google/protobuf/internal/message_listener.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
diff --git a/generator/google/protobuf/internal/message_set_extensions_pb2.py b/generator/google/protobuf/internal/message_set_extensions_pb2.py
new file mode 100644
index 0000000..4c9b475
--- /dev/null
+++ b/generator/google/protobuf/internal/message_set_extensions_pb2.py
@@ -0,0 +1,210 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/message_set_extensions.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/message_set_extensions.proto',
+  package='google.protobuf.internal',
+  syntax='proto2',
+  serialized_pb=_b('\n5google/protobuf/internal/message_set_extensions.proto\x12\x18google.protobuf.internal\"\x1e\n\x0eTestMessageSet*\x08\x08\x04\x10\xff\xff\xff\xff\x07:\x02\x08\x01\"\xa5\x01\n\x18TestMessageSetExtension1\x12\t\n\x01i\x18\x0f \x01(\x05\x32~\n\x15message_set_extension\x12(.google.protobuf.internal.TestMessageSet\x18\xab\xff\xf6. \x01(\x0b\x32\x32.google.protobuf.internal.TestMessageSetExtension1\"\xa7\x01\n\x18TestMessageSetExtension2\x12\x0b\n\x03str\x18\x19 \x01(\t2~\n\x15message_set_extension\x12(.google.protobuf.internal.TestMessageSet\x18\xca\xff\xf6. \x01(\x0b\x32\x32.google.protobuf.internal.TestMessageSetExtension2\"(\n\x18TestMessageSetExtension3\x12\x0c\n\x04text\x18# \x01(\t:\x7f\n\x16message_set_extension3\x12(.google.protobuf.internal.TestMessageSet\x18\xdf\xff\xf6. \x01(\x0b\x32\x32.google.protobuf.internal.TestMessageSetExtension3')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+MESSAGE_SET_EXTENSION3_FIELD_NUMBER = 98418655
+message_set_extension3 = _descriptor.FieldDescriptor(
+  name='message_set_extension3', full_name='google.protobuf.internal.message_set_extension3', index=0,
+  number=98418655, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+
+
+_TESTMESSAGESET = _descriptor.Descriptor(
+  name='TestMessageSet',
+  full_name='google.protobuf.internal.TestMessageSet',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\010\001')),
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(4, 2147483647), ],
+  oneofs=[
+  ],
+  serialized_start=83,
+  serialized_end=113,
+)
+
+
+_TESTMESSAGESETEXTENSION1 = _descriptor.Descriptor(
+  name='TestMessageSetExtension1',
+  full_name='google.protobuf.internal.TestMessageSetExtension1',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='i', full_name='google.protobuf.internal.TestMessageSetExtension1.i', index=0,
+      number=15, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+    _descriptor.FieldDescriptor(
+      name='message_set_extension', full_name='google.protobuf.internal.TestMessageSetExtension1.message_set_extension', index=0,
+      number=98418603, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=116,
+  serialized_end=281,
+)
+
+
+_TESTMESSAGESETEXTENSION2 = _descriptor.Descriptor(
+  name='TestMessageSetExtension2',
+  full_name='google.protobuf.internal.TestMessageSetExtension2',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='str', full_name='google.protobuf.internal.TestMessageSetExtension2.str', index=0,
+      number=25, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+    _descriptor.FieldDescriptor(
+      name='message_set_extension', full_name='google.protobuf.internal.TestMessageSetExtension2.message_set_extension', index=0,
+      number=98418634, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=284,
+  serialized_end=451,
+)
+
+
+_TESTMESSAGESETEXTENSION3 = _descriptor.Descriptor(
+  name='TestMessageSetExtension3',
+  full_name='google.protobuf.internal.TestMessageSetExtension3',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='text', full_name='google.protobuf.internal.TestMessageSetExtension3.text', index=0,
+      number=35, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=453,
+  serialized_end=493,
+)
+
+DESCRIPTOR.message_types_by_name['TestMessageSet'] = _TESTMESSAGESET
+DESCRIPTOR.message_types_by_name['TestMessageSetExtension1'] = _TESTMESSAGESETEXTENSION1
+DESCRIPTOR.message_types_by_name['TestMessageSetExtension2'] = _TESTMESSAGESETEXTENSION2
+DESCRIPTOR.message_types_by_name['TestMessageSetExtension3'] = _TESTMESSAGESETEXTENSION3
+DESCRIPTOR.extensions_by_name['message_set_extension3'] = message_set_extension3
+
+TestMessageSet = _reflection.GeneratedProtocolMessageType('TestMessageSet', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMESSAGESET,
+  __module__ = 'google.protobuf.internal.message_set_extensions_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.internal.TestMessageSet)
+  ))
+_sym_db.RegisterMessage(TestMessageSet)
+
+TestMessageSetExtension1 = _reflection.GeneratedProtocolMessageType('TestMessageSetExtension1', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMESSAGESETEXTENSION1,
+  __module__ = 'google.protobuf.internal.message_set_extensions_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.internal.TestMessageSetExtension1)
+  ))
+_sym_db.RegisterMessage(TestMessageSetExtension1)
+
+TestMessageSetExtension2 = _reflection.GeneratedProtocolMessageType('TestMessageSetExtension2', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMESSAGESETEXTENSION2,
+  __module__ = 'google.protobuf.internal.message_set_extensions_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.internal.TestMessageSetExtension2)
+  ))
+_sym_db.RegisterMessage(TestMessageSetExtension2)
+
+TestMessageSetExtension3 = _reflection.GeneratedProtocolMessageType('TestMessageSetExtension3', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMESSAGESETEXTENSION3,
+  __module__ = 'google.protobuf.internal.message_set_extensions_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.internal.TestMessageSetExtension3)
+  ))
+_sym_db.RegisterMessage(TestMessageSetExtension3)
+
+message_set_extension3.message_type = _TESTMESSAGESETEXTENSION3
+TestMessageSet.RegisterExtension(message_set_extension3)
+_TESTMESSAGESETEXTENSION1.extensions_by_name['message_set_extension'].message_type = _TESTMESSAGESETEXTENSION1
+TestMessageSet.RegisterExtension(_TESTMESSAGESETEXTENSION1.extensions_by_name['message_set_extension'])
+_TESTMESSAGESETEXTENSION2.extensions_by_name['message_set_extension'].message_type = _TESTMESSAGESETEXTENSION2
+TestMessageSet.RegisterExtension(_TESTMESSAGESETEXTENSION2.extensions_by_name['message_set_extension'])
+
+_TESTMESSAGESET.has_options = True
+_TESTMESSAGESET._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\010\001'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/message_test.py b/generator/google/protobuf/internal/message_test.py
new file mode 100644
index 0000000..1e95adf
--- /dev/null
+++ b/generator/google/protobuf/internal/message_test.py
@@ -0,0 +1,1856 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Tests python protocol buffers against the golden message.
+
+Note that the golden messages exercise every known field type, thus this
+test ends up exercising and verifying nearly all of the parsing and
+serialization code in the whole library.
+
+TODO(kenton):  Merge with wire_format_test?  It doesn't make a whole lot of
+sense to call this a test of the "message" module, which only declares an
+abstract interface.
+"""
+
+__author__ = 'gps@google.com (Gregory P. Smith)'
+
+
+import collections
+import copy
+import math
+import operator
+import pickle
+import six
+import sys
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+
+from google.protobuf import map_unittest_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import unittest_proto3_arena_pb2
+from google.protobuf import descriptor_pb2
+from google.protobuf import descriptor_pool
+from google.protobuf import message_factory
+from google.protobuf import text_format
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import packed_field_test_pb2
+from google.protobuf.internal import test_util
+from google.protobuf import message
+from google.protobuf.internal import _parameterized
+
+if six.PY3:
+  long = int
+
+
+# Python pre-2.6 does not have isinf() or isnan() functions, so we have
+# to provide our own.
+def isnan(val):
+  # NaN is never equal to itself.
+  return val != val
+def isinf(val):
+  # Infinity times zero equals NaN.
+  return not isnan(val) and isnan(val * 0)
+def IsPosInf(val):
+  return isinf(val) and (val > 0)
+def IsNegInf(val):
+  return isinf(val) and (val < 0)
+
+
+@_parameterized.Parameters(
+    (unittest_pb2),
+    (unittest_proto3_arena_pb2))
+class MessageTest(unittest.TestCase):
+
+  def testBadUtf8String(self, message_module):
+    if api_implementation.Type() != 'python':
+      self.skipTest("Skipping testBadUtf8String, currently only the python "
+                    "api implementation raises UnicodeDecodeError when a "
+                    "string field contains bad utf-8.")
+    bad_utf8_data = test_util.GoldenFileData('bad_utf8_string')
+    with self.assertRaises(UnicodeDecodeError) as context:
+      message_module.TestAllTypes.FromString(bad_utf8_data)
+    self.assertIn('TestAllTypes.optional_string', str(context.exception))
+
+  def testGoldenMessage(self, message_module):
+    # Proto3 doesn't have the "default_foo" members or foreign enums,
+    # and doesn't preserve unknown fields, so for proto3 we use a golden
+    # message that doesn't have these fields set.
+    if message_module is unittest_pb2:
+      golden_data = test_util.GoldenFileData(
+          'golden_message_oneof_implemented')
+    else:
+      golden_data = test_util.GoldenFileData('golden_message_proto3')
+
+    golden_message = message_module.TestAllTypes()
+    golden_message.ParseFromString(golden_data)
+    if message_module is unittest_pb2:
+      test_util.ExpectAllFieldsSet(self, golden_message)
+    self.assertEqual(golden_data, golden_message.SerializeToString())
+    golden_copy = copy.deepcopy(golden_message)
+    self.assertEqual(golden_data, golden_copy.SerializeToString())
+
+  def testGoldenPackedMessage(self, message_module):
+    golden_data = test_util.GoldenFileData('golden_packed_fields_message')
+    golden_message = message_module.TestPackedTypes()
+    golden_message.ParseFromString(golden_data)
+    all_set = message_module.TestPackedTypes()
+    test_util.SetAllPackedFields(all_set)
+    self.assertEqual(all_set, golden_message)
+    self.assertEqual(golden_data, all_set.SerializeToString())
+    golden_copy = copy.deepcopy(golden_message)
+    self.assertEqual(golden_data, golden_copy.SerializeToString())
+
+  def testPickleSupport(self, message_module):
+    golden_data = test_util.GoldenFileData('golden_message')
+    golden_message = message_module.TestAllTypes()
+    golden_message.ParseFromString(golden_data)
+    pickled_message = pickle.dumps(golden_message)
+
+    unpickled_message = pickle.loads(pickled_message)
+    self.assertEqual(unpickled_message, golden_message)
+
+  def testPositiveInfinity(self, message_module):
+    if message_module is unittest_pb2:
+      golden_data = (b'\x5D\x00\x00\x80\x7F'
+                     b'\x61\x00\x00\x00\x00\x00\x00\xF0\x7F'
+                     b'\xCD\x02\x00\x00\x80\x7F'
+                     b'\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\x7F')
+    else:
+      golden_data = (b'\x5D\x00\x00\x80\x7F'
+                     b'\x61\x00\x00\x00\x00\x00\x00\xF0\x7F'
+                     b'\xCA\x02\x04\x00\x00\x80\x7F'
+                     b'\xD2\x02\x08\x00\x00\x00\x00\x00\x00\xF0\x7F')
+
+    golden_message = message_module.TestAllTypes()
+    golden_message.ParseFromString(golden_data)
+    self.assertTrue(IsPosInf(golden_message.optional_float))
+    self.assertTrue(IsPosInf(golden_message.optional_double))
+    self.assertTrue(IsPosInf(golden_message.repeated_float[0]))
+    self.assertTrue(IsPosInf(golden_message.repeated_double[0]))
+    self.assertEqual(golden_data, golden_message.SerializeToString())
+
+  def testNegativeInfinity(self, message_module):
+    if message_module is unittest_pb2:
+      golden_data = (b'\x5D\x00\x00\x80\xFF'
+                     b'\x61\x00\x00\x00\x00\x00\x00\xF0\xFF'
+                     b'\xCD\x02\x00\x00\x80\xFF'
+                     b'\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\xFF')
+    else:
+      golden_data = (b'\x5D\x00\x00\x80\xFF'
+                     b'\x61\x00\x00\x00\x00\x00\x00\xF0\xFF'
+                     b'\xCA\x02\x04\x00\x00\x80\xFF'
+                     b'\xD2\x02\x08\x00\x00\x00\x00\x00\x00\xF0\xFF')
+
+    golden_message = message_module.TestAllTypes()
+    golden_message.ParseFromString(golden_data)
+    self.assertTrue(IsNegInf(golden_message.optional_float))
+    self.assertTrue(IsNegInf(golden_message.optional_double))
+    self.assertTrue(IsNegInf(golden_message.repeated_float[0]))
+    self.assertTrue(IsNegInf(golden_message.repeated_double[0]))
+    self.assertEqual(golden_data, golden_message.SerializeToString())
+
+  def testNotANumber(self, message_module):
+    golden_data = (b'\x5D\x00\x00\xC0\x7F'
+                   b'\x61\x00\x00\x00\x00\x00\x00\xF8\x7F'
+                   b'\xCD\x02\x00\x00\xC0\x7F'
+                   b'\xD1\x02\x00\x00\x00\x00\x00\x00\xF8\x7F')
+    golden_message = message_module.TestAllTypes()
+    golden_message.ParseFromString(golden_data)
+    self.assertTrue(isnan(golden_message.optional_float))
+    self.assertTrue(isnan(golden_message.optional_double))
+    self.assertTrue(isnan(golden_message.repeated_float[0]))
+    self.assertTrue(isnan(golden_message.repeated_double[0]))
+
+    # The protocol buffer may serialize to any one of multiple different
+    # representations of a NaN.  Rather than verify a specific representation,
+    # verify the serialized string can be converted into a correctly
+    # behaving protocol buffer.
+    serialized = golden_message.SerializeToString()
+    message = message_module.TestAllTypes()
+    message.ParseFromString(serialized)
+    self.assertTrue(isnan(message.optional_float))
+    self.assertTrue(isnan(message.optional_double))
+    self.assertTrue(isnan(message.repeated_float[0]))
+    self.assertTrue(isnan(message.repeated_double[0]))
+
+  def testPositiveInfinityPacked(self, message_module):
+    golden_data = (b'\xA2\x06\x04\x00\x00\x80\x7F'
+                   b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\x7F')
+    golden_message = message_module.TestPackedTypes()
+    golden_message.ParseFromString(golden_data)
+    self.assertTrue(IsPosInf(golden_message.packed_float[0]))
+    self.assertTrue(IsPosInf(golden_message.packed_double[0]))
+    self.assertEqual(golden_data, golden_message.SerializeToString())
+
+  def testNegativeInfinityPacked(self, message_module):
+    golden_data = (b'\xA2\x06\x04\x00\x00\x80\xFF'
+                   b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\xFF')
+    golden_message = message_module.TestPackedTypes()
+    golden_message.ParseFromString(golden_data)
+    self.assertTrue(IsNegInf(golden_message.packed_float[0]))
+    self.assertTrue(IsNegInf(golden_message.packed_double[0]))
+    self.assertEqual(golden_data, golden_message.SerializeToString())
+
+  def testNotANumberPacked(self, message_module):
+    golden_data = (b'\xA2\x06\x04\x00\x00\xC0\x7F'
+                   b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF8\x7F')
+    golden_message = message_module.TestPackedTypes()
+    golden_message.ParseFromString(golden_data)
+    self.assertTrue(isnan(golden_message.packed_float[0]))
+    self.assertTrue(isnan(golden_message.packed_double[0]))
+
+    serialized = golden_message.SerializeToString()
+    message = message_module.TestPackedTypes()
+    message.ParseFromString(serialized)
+    self.assertTrue(isnan(message.packed_float[0]))
+    self.assertTrue(isnan(message.packed_double[0]))
+
+  def testExtremeFloatValues(self, message_module):
+    message = message_module.TestAllTypes()
+
+    # Most positive exponent, no significand bits set.
+    kMostPosExponentNoSigBits = math.pow(2, 127)
+    message.optional_float = kMostPosExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == kMostPosExponentNoSigBits)
+
+    # Most positive exponent, one significand bit set.
+    kMostPosExponentOneSigBit = 1.5 * math.pow(2, 127)
+    message.optional_float = kMostPosExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == kMostPosExponentOneSigBit)
+
+    # Repeat last two cases with values of same magnitude, but negative.
+    message.optional_float = -kMostPosExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == -kMostPosExponentNoSigBits)
+
+    message.optional_float = -kMostPosExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == -kMostPosExponentOneSigBit)
+
+    # Most negative exponent, no significand bits set.
+    kMostNegExponentNoSigBits = math.pow(2, -127)
+    message.optional_float = kMostNegExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == kMostNegExponentNoSigBits)
+
+    # Most negative exponent, one significand bit set.
+    kMostNegExponentOneSigBit = 1.5 * math.pow(2, -127)
+    message.optional_float = kMostNegExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == kMostNegExponentOneSigBit)
+
+    # Repeat last two cases with values of the same magnitude, but negative.
+    message.optional_float = -kMostNegExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == -kMostNegExponentNoSigBits)
+
+    message.optional_float = -kMostNegExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == -kMostNegExponentOneSigBit)
+
+  def testExtremeDoubleValues(self, message_module):
+    message = message_module.TestAllTypes()
+
+    # Most positive exponent, no significand bits set.
+    kMostPosExponentNoSigBits = math.pow(2, 1023)
+    message.optional_double = kMostPosExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == kMostPosExponentNoSigBits)
+
+    # Most positive exponent, one significand bit set.
+    kMostPosExponentOneSigBit = 1.5 * math.pow(2, 1023)
+    message.optional_double = kMostPosExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == kMostPosExponentOneSigBit)
+
+    # Repeat last two cases with values of same magnitude, but negative.
+    message.optional_double = -kMostPosExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == -kMostPosExponentNoSigBits)
+
+    message.optional_double = -kMostPosExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == -kMostPosExponentOneSigBit)
+
+    # Most negative exponent, no significand bits set.
+    kMostNegExponentNoSigBits = math.pow(2, -1023)
+    message.optional_double = kMostNegExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == kMostNegExponentNoSigBits)
+
+    # Most negative exponent, one significand bit set.
+    kMostNegExponentOneSigBit = 1.5 * math.pow(2, -1023)
+    message.optional_double = kMostNegExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == kMostNegExponentOneSigBit)
+
+    # Repeat last two cases with values of the same magnitude, but negative.
+    message.optional_double = -kMostNegExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == -kMostNegExponentNoSigBits)
+
+    message.optional_double = -kMostNegExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == -kMostNegExponentOneSigBit)
+
+  def testFloatPrinting(self, message_module):
+    message = message_module.TestAllTypes()
+    message.optional_float = 2.0
+    self.assertEqual(str(message), 'optional_float: 2.0\n')
+
+  def testHighPrecisionFloatPrinting(self, message_module):
+    message = message_module.TestAllTypes()
+    message.optional_double = 0.12345678912345678
+    if sys.version_info >= (3,):
+      self.assertEqual(str(message), 'optional_double: 0.12345678912345678\n')
+    else:
+      self.assertEqual(str(message), 'optional_double: 0.123456789123\n')
+
+  def testUnknownFieldPrinting(self, message_module):
+    populated = message_module.TestAllTypes()
+    test_util.SetAllNonLazyFields(populated)
+    empty = message_module.TestEmptyMessage()
+    empty.ParseFromString(populated.SerializeToString())
+    self.assertEqual(str(empty), '')
+
+  def testRepeatedNestedFieldIteration(self, message_module):
+    msg = message_module.TestAllTypes()
+    msg.repeated_nested_message.add(bb=1)
+    msg.repeated_nested_message.add(bb=2)
+    msg.repeated_nested_message.add(bb=3)
+    msg.repeated_nested_message.add(bb=4)
+
+    self.assertEqual([1, 2, 3, 4],
+                     [m.bb for m in msg.repeated_nested_message])
+    self.assertEqual([4, 3, 2, 1],
+                     [m.bb for m in reversed(msg.repeated_nested_message)])
+    self.assertEqual([4, 3, 2, 1],
+                     [m.bb for m in msg.repeated_nested_message[::-1]])
+
+  def testSortingRepeatedScalarFieldsDefaultComparator(self, message_module):
+    """Check some different types with the default comparator."""
+    message = message_module.TestAllTypes()
+
+    # TODO(mattp): would testing more scalar types strengthen test?
+    message.repeated_int32.append(1)
+    message.repeated_int32.append(3)
+    message.repeated_int32.append(2)
+    message.repeated_int32.sort()
+    self.assertEqual(message.repeated_int32[0], 1)
+    self.assertEqual(message.repeated_int32[1], 2)
+    self.assertEqual(message.repeated_int32[2], 3)
+
+    message.repeated_float.append(1.1)
+    message.repeated_float.append(1.3)
+    message.repeated_float.append(1.2)
+    message.repeated_float.sort()
+    self.assertAlmostEqual(message.repeated_float[0], 1.1)
+    self.assertAlmostEqual(message.repeated_float[1], 1.2)
+    self.assertAlmostEqual(message.repeated_float[2], 1.3)
+
+    message.repeated_string.append('a')
+    message.repeated_string.append('c')
+    message.repeated_string.append('b')
+    message.repeated_string.sort()
+    self.assertEqual(message.repeated_string[0], 'a')
+    self.assertEqual(message.repeated_string[1], 'b')
+    self.assertEqual(message.repeated_string[2], 'c')
+
+    message.repeated_bytes.append(b'a')
+    message.repeated_bytes.append(b'c')
+    message.repeated_bytes.append(b'b')
+    message.repeated_bytes.sort()
+    self.assertEqual(message.repeated_bytes[0], b'a')
+    self.assertEqual(message.repeated_bytes[1], b'b')
+    self.assertEqual(message.repeated_bytes[2], b'c')
+
+  def testSortingRepeatedScalarFieldsCustomComparator(self, message_module):
+    """Check some different types with custom comparator."""
+    message = message_module.TestAllTypes()
+
+    message.repeated_int32.append(-3)
+    message.repeated_int32.append(-2)
+    message.repeated_int32.append(-1)
+    message.repeated_int32.sort(key=abs)
+    self.assertEqual(message.repeated_int32[0], -1)
+    self.assertEqual(message.repeated_int32[1], -2)
+    self.assertEqual(message.repeated_int32[2], -3)
+
+    message.repeated_string.append('aaa')
+    message.repeated_string.append('bb')
+    message.repeated_string.append('c')
+    message.repeated_string.sort(key=len)
+    self.assertEqual(message.repeated_string[0], 'c')
+    self.assertEqual(message.repeated_string[1], 'bb')
+    self.assertEqual(message.repeated_string[2], 'aaa')
+
+  def testSortingRepeatedCompositeFieldsCustomComparator(self, message_module):
+    """Check passing a custom comparator to sort a repeated composite field."""
+    message = message_module.TestAllTypes()
+
+    message.repeated_nested_message.add().bb = 1
+    message.repeated_nested_message.add().bb = 3
+    message.repeated_nested_message.add().bb = 2
+    message.repeated_nested_message.add().bb = 6
+    message.repeated_nested_message.add().bb = 5
+    message.repeated_nested_message.add().bb = 4
+    message.repeated_nested_message.sort(key=operator.attrgetter('bb'))
+    self.assertEqual(message.repeated_nested_message[0].bb, 1)
+    self.assertEqual(message.repeated_nested_message[1].bb, 2)
+    self.assertEqual(message.repeated_nested_message[2].bb, 3)
+    self.assertEqual(message.repeated_nested_message[3].bb, 4)
+    self.assertEqual(message.repeated_nested_message[4].bb, 5)
+    self.assertEqual(message.repeated_nested_message[5].bb, 6)
+
+  def testSortingRepeatedCompositeFieldsStable(self, message_module):
+    """Check passing a custom comparator to sort a repeated composite field."""
+    message = message_module.TestAllTypes()
+
+    message.repeated_nested_message.add().bb = 21
+    message.repeated_nested_message.add().bb = 20
+    message.repeated_nested_message.add().bb = 13
+    message.repeated_nested_message.add().bb = 33
+    message.repeated_nested_message.add().bb = 11
+    message.repeated_nested_message.add().bb = 24
+    message.repeated_nested_message.add().bb = 10
+    message.repeated_nested_message.sort(key=lambda z: z.bb // 10)
+    self.assertEqual(
+        [13, 11, 10, 21, 20, 24, 33],
+        [n.bb for n in message.repeated_nested_message])
+
+    # Make sure that for the C++ implementation, the underlying fields
+    # are actually reordered.
+    pb = message.SerializeToString()
+    message.Clear()
+    message.MergeFromString(pb)
+    self.assertEqual(
+        [13, 11, 10, 21, 20, 24, 33],
+        [n.bb for n in message.repeated_nested_message])
+
+  def testRepeatedCompositeFieldSortArguments(self, message_module):
+    """Check sorting a repeated composite field using list.sort() arguments."""
+    message = message_module.TestAllTypes()
+
+    get_bb = operator.attrgetter('bb')
+    cmp_bb = lambda a, b: cmp(a.bb, b.bb)
+    message.repeated_nested_message.add().bb = 1
+    message.repeated_nested_message.add().bb = 3
+    message.repeated_nested_message.add().bb = 2
+    message.repeated_nested_message.add().bb = 6
+    message.repeated_nested_message.add().bb = 5
+    message.repeated_nested_message.add().bb = 4
+    message.repeated_nested_message.sort(key=get_bb)
+    self.assertEqual([k.bb for k in message.repeated_nested_message],
+                     [1, 2, 3, 4, 5, 6])
+    message.repeated_nested_message.sort(key=get_bb, reverse=True)
+    self.assertEqual([k.bb for k in message.repeated_nested_message],
+                     [6, 5, 4, 3, 2, 1])
+    if sys.version_info >= (3,): return  # No cmp sorting in PY3.
+    message.repeated_nested_message.sort(sort_function=cmp_bb)
+    self.assertEqual([k.bb for k in message.repeated_nested_message],
+                     [1, 2, 3, 4, 5, 6])
+    message.repeated_nested_message.sort(cmp=cmp_bb, reverse=True)
+    self.assertEqual([k.bb for k in message.repeated_nested_message],
+                     [6, 5, 4, 3, 2, 1])
+
+  def testRepeatedScalarFieldSortArguments(self, message_module):
+    """Check sorting a scalar field using list.sort() arguments."""
+    message = message_module.TestAllTypes()
+
+    message.repeated_int32.append(-3)
+    message.repeated_int32.append(-2)
+    message.repeated_int32.append(-1)
+    message.repeated_int32.sort(key=abs)
+    self.assertEqual(list(message.repeated_int32), [-1, -2, -3])
+    message.repeated_int32.sort(key=abs, reverse=True)
+    self.assertEqual(list(message.repeated_int32), [-3, -2, -1])
+    if sys.version_info < (3,):  # No cmp sorting in PY3.
+      abs_cmp = lambda a, b: cmp(abs(a), abs(b))
+      message.repeated_int32.sort(sort_function=abs_cmp)
+      self.assertEqual(list(message.repeated_int32), [-1, -2, -3])
+      message.repeated_int32.sort(cmp=abs_cmp, reverse=True)
+      self.assertEqual(list(message.repeated_int32), [-3, -2, -1])
+
+    message.repeated_string.append('aaa')
+    message.repeated_string.append('bb')
+    message.repeated_string.append('c')
+    message.repeated_string.sort(key=len)
+    self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa'])
+    message.repeated_string.sort(key=len, reverse=True)
+    self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c'])
+    if sys.version_info < (3,):  # No cmp sorting in PY3.
+      len_cmp = lambda a, b: cmp(len(a), len(b))
+      message.repeated_string.sort(sort_function=len_cmp)
+      self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa'])
+      message.repeated_string.sort(cmp=len_cmp, reverse=True)
+      self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c'])
+
+  def testRepeatedFieldsComparable(self, message_module):
+    m1 = message_module.TestAllTypes()
+    m2 = message_module.TestAllTypes()
+    m1.repeated_int32.append(0)
+    m1.repeated_int32.append(1)
+    m1.repeated_int32.append(2)
+    m2.repeated_int32.append(0)
+    m2.repeated_int32.append(1)
+    m2.repeated_int32.append(2)
+    m1.repeated_nested_message.add().bb = 1
+    m1.repeated_nested_message.add().bb = 2
+    m1.repeated_nested_message.add().bb = 3
+    m2.repeated_nested_message.add().bb = 1
+    m2.repeated_nested_message.add().bb = 2
+    m2.repeated_nested_message.add().bb = 3
+
+    if sys.version_info >= (3,): return  # No cmp() in PY3.
+
+    # These comparisons should not raise errors.
+    _ = m1 < m2
+    _ = m1.repeated_nested_message < m2.repeated_nested_message
+
+    # Make sure cmp always works. If it wasn't defined, these would be
+    # id() comparisons and would all fail.
+    self.assertEqual(cmp(m1, m2), 0)
+    self.assertEqual(cmp(m1.repeated_int32, m2.repeated_int32), 0)
+    self.assertEqual(cmp(m1.repeated_int32, [0, 1, 2]), 0)
+    self.assertEqual(cmp(m1.repeated_nested_message,
+                         m2.repeated_nested_message), 0)
+    with self.assertRaises(TypeError):
+      # Can't compare repeated composite containers to lists.
+      cmp(m1.repeated_nested_message, m2.repeated_nested_message[:])
+
+    # TODO(anuraag): Implement extensiondict comparison in C++ and then add test
+
+  def testRepeatedFieldsAreSequences(self, message_module):
+    m = message_module.TestAllTypes()
+    self.assertIsInstance(m.repeated_int32, collections.MutableSequence)
+    self.assertIsInstance(m.repeated_nested_message,
+                          collections.MutableSequence)
+
+  def ensureNestedMessageExists(self, msg, attribute):
+    """Make sure that a nested message object exists.
+
+    As soon as a nested message attribute is accessed, it will be present in the
+    _fields dict, without being marked as actually being set.
+    """
+    getattr(msg, attribute)
+    self.assertFalse(msg.HasField(attribute))
+
+  def testOneofGetCaseNonexistingField(self, message_module):
+    m = message_module.TestAllTypes()
+    self.assertRaises(ValueError, m.WhichOneof, 'no_such_oneof_field')
+
+  def testOneofDefaultValues(self, message_module):
+    m = message_module.TestAllTypes()
+    self.assertIs(None, m.WhichOneof('oneof_field'))
+    self.assertFalse(m.HasField('oneof_uint32'))
+
+    # Oneof is set even when setting it to a default value.
+    m.oneof_uint32 = 0
+    self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
+    self.assertTrue(m.HasField('oneof_uint32'))
+    self.assertFalse(m.HasField('oneof_string'))
+
+    m.oneof_string = ""
+    self.assertEqual('oneof_string', m.WhichOneof('oneof_field'))
+    self.assertTrue(m.HasField('oneof_string'))
+    self.assertFalse(m.HasField('oneof_uint32'))
+
+  def testOneofSemantics(self, message_module):
+    m = message_module.TestAllTypes()
+    self.assertIs(None, m.WhichOneof('oneof_field'))
+
+    m.oneof_uint32 = 11
+    self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
+    self.assertTrue(m.HasField('oneof_uint32'))
+
+    m.oneof_string = u'foo'
+    self.assertEqual('oneof_string', m.WhichOneof('oneof_field'))
+    self.assertFalse(m.HasField('oneof_uint32'))
+    self.assertTrue(m.HasField('oneof_string'))
+
+    # Read nested message accessor without accessing submessage.
+    m.oneof_nested_message
+    self.assertEqual('oneof_string', m.WhichOneof('oneof_field'))
+    self.assertTrue(m.HasField('oneof_string'))
+    self.assertFalse(m.HasField('oneof_nested_message'))
+
+    # Read accessor of nested message without accessing submessage.
+    m.oneof_nested_message.bb
+    self.assertEqual('oneof_string', m.WhichOneof('oneof_field'))
+    self.assertTrue(m.HasField('oneof_string'))
+    self.assertFalse(m.HasField('oneof_nested_message'))
+
+    m.oneof_nested_message.bb = 11
+    self.assertEqual('oneof_nested_message', m.WhichOneof('oneof_field'))
+    self.assertFalse(m.HasField('oneof_string'))
+    self.assertTrue(m.HasField('oneof_nested_message'))
+
+    m.oneof_bytes = b'bb'
+    self.assertEqual('oneof_bytes', m.WhichOneof('oneof_field'))
+    self.assertFalse(m.HasField('oneof_nested_message'))
+    self.assertTrue(m.HasField('oneof_bytes'))
+
+  def testOneofCompositeFieldReadAccess(self, message_module):
+    m = message_module.TestAllTypes()
+    m.oneof_uint32 = 11
+
+    self.ensureNestedMessageExists(m, 'oneof_nested_message')
+    self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
+    self.assertEqual(11, m.oneof_uint32)
+
+  def testOneofWhichOneof(self, message_module):
+    m = message_module.TestAllTypes()
+    self.assertIs(None, m.WhichOneof('oneof_field'))
+    if message_module is unittest_pb2:
+      self.assertFalse(m.HasField('oneof_field'))
+
+    m.oneof_uint32 = 11
+    self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
+    if message_module is unittest_pb2:
+      self.assertTrue(m.HasField('oneof_field'))
+
+    m.oneof_bytes = b'bb'
+    self.assertEqual('oneof_bytes', m.WhichOneof('oneof_field'))
+
+    m.ClearField('oneof_bytes')
+    self.assertIs(None, m.WhichOneof('oneof_field'))
+    if message_module is unittest_pb2:
+      self.assertFalse(m.HasField('oneof_field'))
+
+  def testOneofClearField(self, message_module):
+    m = message_module.TestAllTypes()
+    m.oneof_uint32 = 11
+    m.ClearField('oneof_field')
+    if message_module is unittest_pb2:
+      self.assertFalse(m.HasField('oneof_field'))
+    self.assertFalse(m.HasField('oneof_uint32'))
+    self.assertIs(None, m.WhichOneof('oneof_field'))
+
+  def testOneofClearSetField(self, message_module):
+    m = message_module.TestAllTypes()
+    m.oneof_uint32 = 11
+    m.ClearField('oneof_uint32')
+    if message_module is unittest_pb2:
+      self.assertFalse(m.HasField('oneof_field'))
+    self.assertFalse(m.HasField('oneof_uint32'))
+    self.assertIs(None, m.WhichOneof('oneof_field'))
+
+  def testOneofClearUnsetField(self, message_module):
+    m = message_module.TestAllTypes()
+    m.oneof_uint32 = 11
+    self.ensureNestedMessageExists(m, 'oneof_nested_message')
+    m.ClearField('oneof_nested_message')
+    self.assertEqual(11, m.oneof_uint32)
+    if message_module is unittest_pb2:
+      self.assertTrue(m.HasField('oneof_field'))
+    self.assertTrue(m.HasField('oneof_uint32'))
+    self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
+
+  def testOneofDeserialize(self, message_module):
+    m = message_module.TestAllTypes()
+    m.oneof_uint32 = 11
+    m2 = message_module.TestAllTypes()
+    m2.ParseFromString(m.SerializeToString())
+    self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
+
+  def testOneofCopyFrom(self, message_module):
+    m = message_module.TestAllTypes()
+    m.oneof_uint32 = 11
+    m2 = message_module.TestAllTypes()
+    m2.CopyFrom(m)
+    self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
+
+  def testOneofNestedMergeFrom(self, message_module):
+    m = message_module.NestedTestAllTypes()
+    m.payload.oneof_uint32 = 11
+    m2 = message_module.NestedTestAllTypes()
+    m2.payload.oneof_bytes = b'bb'
+    m2.child.payload.oneof_bytes = b'bb'
+    m2.MergeFrom(m)
+    self.assertEqual('oneof_uint32', m2.payload.WhichOneof('oneof_field'))
+    self.assertEqual('oneof_bytes', m2.child.payload.WhichOneof('oneof_field'))
+
+  def testOneofMessageMergeFrom(self, message_module):
+    m = message_module.NestedTestAllTypes()
+    m.payload.oneof_nested_message.bb = 11
+    m.child.payload.oneof_nested_message.bb = 12
+    m2 = message_module.NestedTestAllTypes()
+    m2.payload.oneof_uint32 = 13
+    m2.MergeFrom(m)
+    self.assertEqual('oneof_nested_message',
+                     m2.payload.WhichOneof('oneof_field'))
+    self.assertEqual('oneof_nested_message',
+                     m2.child.payload.WhichOneof('oneof_field'))
+
+  def testOneofNestedMessageInit(self, message_module):
+    m = message_module.TestAllTypes(
+        oneof_nested_message=message_module.TestAllTypes.NestedMessage())
+    self.assertEqual('oneof_nested_message', m.WhichOneof('oneof_field'))
+
+  def testOneofClear(self, message_module):
+    m = message_module.TestAllTypes()
+    m.oneof_uint32 = 11
+    m.Clear()
+    self.assertIsNone(m.WhichOneof('oneof_field'))
+    m.oneof_bytes = b'bb'
+    self.assertEqual('oneof_bytes', m.WhichOneof('oneof_field'))
+
+  def testAssignByteStringToUnicodeField(self, message_module):
+    """Assigning a byte string to a string field should result
+    in the value being converted to a Unicode string."""
+    m = message_module.TestAllTypes()
+    m.optional_string = str('')
+    self.assertIsInstance(m.optional_string, six.text_type)
+
+  def testLongValuedSlice(self, message_module):
+    """It should be possible to use long-valued indicies in slices
+
+    This didn't used to work in the v2 C++ implementation.
+    """
+    m = message_module.TestAllTypes()
+
+    # Repeated scalar
+    m.repeated_int32.append(1)
+    sl = m.repeated_int32[long(0):long(len(m.repeated_int32))]
+    self.assertEqual(len(m.repeated_int32), len(sl))
+
+    # Repeated composite
+    m.repeated_nested_message.add().bb = 3
+    sl = m.repeated_nested_message[long(0):long(len(m.repeated_nested_message))]
+    self.assertEqual(len(m.repeated_nested_message), len(sl))
+
+  def testExtendShouldNotSwallowExceptions(self, message_module):
+    """This didn't use to work in the v2 C++ implementation."""
+    m = message_module.TestAllTypes()
+    with self.assertRaises(NameError) as _:
+      m.repeated_int32.extend(a for i in range(10))  # pylint: disable=undefined-variable
+    with self.assertRaises(NameError) as _:
+      m.repeated_nested_enum.extend(
+          a for i in range(10))  # pylint: disable=undefined-variable
+
+  FALSY_VALUES = [None, False, 0, 0.0, b'', u'', bytearray(), [], {}, set()]
+
+  def testExtendInt32WithNothing(self, message_module):
+    """Test no-ops extending repeated int32 fields."""
+    m = message_module.TestAllTypes()
+    self.assertSequenceEqual([], m.repeated_int32)
+
+    # TODO(ptucker): Deprecate this behavior. b/18413862
+    for falsy_value in MessageTest.FALSY_VALUES:
+      m.repeated_int32.extend(falsy_value)
+      self.assertSequenceEqual([], m.repeated_int32)
+
+    m.repeated_int32.extend([])
+    self.assertSequenceEqual([], m.repeated_int32)
+
+  def testExtendFloatWithNothing(self, message_module):
+    """Test no-ops extending repeated float fields."""
+    m = message_module.TestAllTypes()
+    self.assertSequenceEqual([], m.repeated_float)
+
+    # TODO(ptucker): Deprecate this behavior. b/18413862
+    for falsy_value in MessageTest.FALSY_VALUES:
+      m.repeated_float.extend(falsy_value)
+      self.assertSequenceEqual([], m.repeated_float)
+
+    m.repeated_float.extend([])
+    self.assertSequenceEqual([], m.repeated_float)
+
+  def testExtendStringWithNothing(self, message_module):
+    """Test no-ops extending repeated string fields."""
+    m = message_module.TestAllTypes()
+    self.assertSequenceEqual([], m.repeated_string)
+
+    # TODO(ptucker): Deprecate this behavior. b/18413862
+    for falsy_value in MessageTest.FALSY_VALUES:
+      m.repeated_string.extend(falsy_value)
+      self.assertSequenceEqual([], m.repeated_string)
+
+    m.repeated_string.extend([])
+    self.assertSequenceEqual([], m.repeated_string)
+
+  def testExtendInt32WithPythonList(self, message_module):
+    """Test extending repeated int32 fields with python lists."""
+    m = message_module.TestAllTypes()
+    self.assertSequenceEqual([], m.repeated_int32)
+    m.repeated_int32.extend([0])
+    self.assertSequenceEqual([0], m.repeated_int32)
+    m.repeated_int32.extend([1, 2])
+    self.assertSequenceEqual([0, 1, 2], m.repeated_int32)
+    m.repeated_int32.extend([3, 4])
+    self.assertSequenceEqual([0, 1, 2, 3, 4], m.repeated_int32)
+
+  def testExtendFloatWithPythonList(self, message_module):
+    """Test extending repeated float fields with python lists."""
+    m = message_module.TestAllTypes()
+    self.assertSequenceEqual([], m.repeated_float)
+    m.repeated_float.extend([0.0])
+    self.assertSequenceEqual([0.0], m.repeated_float)
+    m.repeated_float.extend([1.0, 2.0])
+    self.assertSequenceEqual([0.0, 1.0, 2.0], m.repeated_float)
+    m.repeated_float.extend([3.0, 4.0])
+    self.assertSequenceEqual([0.0, 1.0, 2.0, 3.0, 4.0], m.repeated_float)
+
+  def testExtendStringWithPythonList(self, message_module):
+    """Test extending repeated string fields with python lists."""
+    m = message_module.TestAllTypes()
+    self.assertSequenceEqual([], m.repeated_string)
+    m.repeated_string.extend([''])
+    self.assertSequenceEqual([''], m.repeated_string)
+    m.repeated_string.extend(['11', '22'])
+    self.assertSequenceEqual(['', '11', '22'], m.repeated_string)
+    m.repeated_string.extend(['33', '44'])
+    self.assertSequenceEqual(['', '11', '22', '33', '44'], m.repeated_string)
+
+  def testExtendStringWithString(self, message_module):
+    """Test extending repeated string fields with characters from a string."""
+    m = message_module.TestAllTypes()
+    self.assertSequenceEqual([], m.repeated_string)
+    m.repeated_string.extend('abc')
+    self.assertSequenceEqual(['a', 'b', 'c'], m.repeated_string)
+
+  class TestIterable(object):
+    """This iterable object mimics the behavior of numpy.array.
+
+    __nonzero__ fails for length > 1, and returns bool(item[0]) for length == 1.
+
+    """
+
+    def __init__(self, values=None):
+      self._list = values or []
+
+    def __nonzero__(self):
+      size = len(self._list)
+      if size == 0:
+        return False
+      if size == 1:
+        return bool(self._list[0])
+      raise ValueError('Truth value is ambiguous.')
+
+    def __len__(self):
+      return len(self._list)
+
+    def __iter__(self):
+      return self._list.__iter__()
+
+  def testExtendInt32WithIterable(self, message_module):
+    """Test extending repeated int32 fields with iterable."""
+    m = message_module.TestAllTypes()
+    self.assertSequenceEqual([], m.repeated_int32)
+    m.repeated_int32.extend(MessageTest.TestIterable([]))
+    self.assertSequenceEqual([], m.repeated_int32)
+    m.repeated_int32.extend(MessageTest.TestIterable([0]))
+    self.assertSequenceEqual([0], m.repeated_int32)
+    m.repeated_int32.extend(MessageTest.TestIterable([1, 2]))
+    self.assertSequenceEqual([0, 1, 2], m.repeated_int32)
+    m.repeated_int32.extend(MessageTest.TestIterable([3, 4]))
+    self.assertSequenceEqual([0, 1, 2, 3, 4], m.repeated_int32)
+
+  def testExtendFloatWithIterable(self, message_module):
+    """Test extending repeated float fields with iterable."""
+    m = message_module.TestAllTypes()
+    self.assertSequenceEqual([], m.repeated_float)
+    m.repeated_float.extend(MessageTest.TestIterable([]))
+    self.assertSequenceEqual([], m.repeated_float)
+    m.repeated_float.extend(MessageTest.TestIterable([0.0]))
+    self.assertSequenceEqual([0.0], m.repeated_float)
+    m.repeated_float.extend(MessageTest.TestIterable([1.0, 2.0]))
+    self.assertSequenceEqual([0.0, 1.0, 2.0], m.repeated_float)
+    m.repeated_float.extend(MessageTest.TestIterable([3.0, 4.0]))
+    self.assertSequenceEqual([0.0, 1.0, 2.0, 3.0, 4.0], m.repeated_float)
+
+  def testExtendStringWithIterable(self, message_module):
+    """Test extending repeated string fields with iterable."""
+    m = message_module.TestAllTypes()
+    self.assertSequenceEqual([], m.repeated_string)
+    m.repeated_string.extend(MessageTest.TestIterable([]))
+    self.assertSequenceEqual([], m.repeated_string)
+    m.repeated_string.extend(MessageTest.TestIterable(['']))
+    self.assertSequenceEqual([''], m.repeated_string)
+    m.repeated_string.extend(MessageTest.TestIterable(['1', '2']))
+    self.assertSequenceEqual(['', '1', '2'], m.repeated_string)
+    m.repeated_string.extend(MessageTest.TestIterable(['3', '4']))
+    self.assertSequenceEqual(['', '1', '2', '3', '4'], m.repeated_string)
+
+  def testPickleRepeatedScalarContainer(self, message_module):
+    # TODO(tibell): The pure-Python implementation support pickling of
+    #   scalar containers in *some* cases. For now the cpp2 version
+    #   throws an exception to avoid a segfault. Investigate if we
+    #   want to support pickling of these fields.
+    #
+    # For more information see: https://b2.corp.google.com/u/0/issues/18677897
+    if (api_implementation.Type() != 'cpp' or
+        api_implementation.Version() == 2):
+      return
+    m = message_module.TestAllTypes()
+    with self.assertRaises(pickle.PickleError) as _:
+      pickle.dumps(m.repeated_int32, pickle.HIGHEST_PROTOCOL)
+
+  def testSortEmptyRepeatedCompositeContainer(self, message_module):
+    """Exercise a scenario that has led to segfaults in the past.
+    """
+    m = message_module.TestAllTypes()
+    m.repeated_nested_message.sort()
+
+  def testHasFieldOnRepeatedField(self, message_module):
+    """Using HasField on a repeated field should raise an exception.
+    """
+    m = message_module.TestAllTypes()
+    with self.assertRaises(ValueError) as _:
+      m.HasField('repeated_int32')
+
+  def testRepeatedScalarFieldPop(self, message_module):
+    m = message_module.TestAllTypes()
+    with self.assertRaises(IndexError) as _:
+      m.repeated_int32.pop()
+    m.repeated_int32.extend(range(5))
+    self.assertEqual(4, m.repeated_int32.pop())
+    self.assertEqual(0, m.repeated_int32.pop(0))
+    self.assertEqual(2, m.repeated_int32.pop(1))
+    self.assertEqual([1, 3], m.repeated_int32)
+
+  def testRepeatedCompositeFieldPop(self, message_module):
+    m = message_module.TestAllTypes()
+    with self.assertRaises(IndexError) as _:
+      m.repeated_nested_message.pop()
+    for i in range(5):
+      n = m.repeated_nested_message.add()
+      n.bb = i
+    self.assertEqual(4, m.repeated_nested_message.pop().bb)
+    self.assertEqual(0, m.repeated_nested_message.pop(0).bb)
+    self.assertEqual(2, m.repeated_nested_message.pop(1).bb)
+    self.assertEqual([1, 3], [n.bb for n in m.repeated_nested_message])
+
+
+# Class to test proto2-only features (required, extensions, etc.)
+class Proto2Test(unittest.TestCase):
+
+  def testFieldPresence(self):
+    message = unittest_pb2.TestAllTypes()
+
+    self.assertFalse(message.HasField("optional_int32"))
+    self.assertFalse(message.HasField("optional_bool"))
+    self.assertFalse(message.HasField("optional_nested_message"))
+
+    with self.assertRaises(ValueError):
+      message.HasField("field_doesnt_exist")
+
+    with self.assertRaises(ValueError):
+      message.HasField("repeated_int32")
+    with self.assertRaises(ValueError):
+      message.HasField("repeated_nested_message")
+
+    self.assertEqual(0, message.optional_int32)
+    self.assertEqual(False, message.optional_bool)
+    self.assertEqual(0, message.optional_nested_message.bb)
+
+    # Fields are set even when setting the values to default values.
+    message.optional_int32 = 0
+    message.optional_bool = False
+    message.optional_nested_message.bb = 0
+    self.assertTrue(message.HasField("optional_int32"))
+    self.assertTrue(message.HasField("optional_bool"))
+    self.assertTrue(message.HasField("optional_nested_message"))
+
+    # Set the fields to non-default values.
+    message.optional_int32 = 5
+    message.optional_bool = True
+    message.optional_nested_message.bb = 15
+
+    self.assertTrue(message.HasField("optional_int32"))
+    self.assertTrue(message.HasField("optional_bool"))
+    self.assertTrue(message.HasField("optional_nested_message"))
+
+    # Clearing the fields unsets them and resets their value to default.
+    message.ClearField("optional_int32")
+    message.ClearField("optional_bool")
+    message.ClearField("optional_nested_message")
+
+    self.assertFalse(message.HasField("optional_int32"))
+    self.assertFalse(message.HasField("optional_bool"))
+    self.assertFalse(message.HasField("optional_nested_message"))
+    self.assertEqual(0, message.optional_int32)
+    self.assertEqual(False, message.optional_bool)
+    self.assertEqual(0, message.optional_nested_message.bb)
+
+  # TODO(tibell): The C++ implementations actually allows assignment
+  # of unknown enum values to *scalar* fields (but not repeated
+  # fields). Once checked enum fields becomes the default in the
+  # Python implementation, the C++ implementation should follow suit.
+  def testAssignInvalidEnum(self):
+    """It should not be possible to assign an invalid enum number to an
+    enum field."""
+    m = unittest_pb2.TestAllTypes()
+
+    with self.assertRaises(ValueError) as _:
+      m.optional_nested_enum = 1234567
+    self.assertRaises(ValueError, m.repeated_nested_enum.append, 1234567)
+
+  def testGoldenExtensions(self):
+    golden_data = test_util.GoldenFileData('golden_message')
+    golden_message = unittest_pb2.TestAllExtensions()
+    golden_message.ParseFromString(golden_data)
+    all_set = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(all_set)
+    self.assertEqual(all_set, golden_message)
+    self.assertEqual(golden_data, golden_message.SerializeToString())
+    golden_copy = copy.deepcopy(golden_message)
+    self.assertEqual(golden_data, golden_copy.SerializeToString())
+
+  def testGoldenPackedExtensions(self):
+    golden_data = test_util.GoldenFileData('golden_packed_fields_message')
+    golden_message = unittest_pb2.TestPackedExtensions()
+    golden_message.ParseFromString(golden_data)
+    all_set = unittest_pb2.TestPackedExtensions()
+    test_util.SetAllPackedExtensions(all_set)
+    self.assertEqual(all_set, golden_message)
+    self.assertEqual(golden_data, all_set.SerializeToString())
+    golden_copy = copy.deepcopy(golden_message)
+    self.assertEqual(golden_data, golden_copy.SerializeToString())
+
+  def testPickleIncompleteProto(self):
+    golden_message = unittest_pb2.TestRequired(a=1)
+    pickled_message = pickle.dumps(golden_message)
+
+    unpickled_message = pickle.loads(pickled_message)
+    self.assertEqual(unpickled_message, golden_message)
+    self.assertEqual(unpickled_message.a, 1)
+    # This is still an incomplete proto - so serializing should fail
+    self.assertRaises(message.EncodeError, unpickled_message.SerializeToString)
+
+
+  # TODO(haberman): this isn't really a proto2-specific test except that this
+  # message has a required field in it.  Should probably be factored out so
+  # that we can test the other parts with proto3.
+  def testParsingMerge(self):
+    """Check the merge behavior when a required or optional field appears
+    multiple times in the input."""
+    messages = [
+        unittest_pb2.TestAllTypes(),
+        unittest_pb2.TestAllTypes(),
+        unittest_pb2.TestAllTypes() ]
+    messages[0].optional_int32 = 1
+    messages[1].optional_int64 = 2
+    messages[2].optional_int32 = 3
+    messages[2].optional_string = 'hello'
+
+    merged_message = unittest_pb2.TestAllTypes()
+    merged_message.optional_int32 = 3
+    merged_message.optional_int64 = 2
+    merged_message.optional_string = 'hello'
+
+    generator = unittest_pb2.TestParsingMerge.RepeatedFieldsGenerator()
+    generator.field1.extend(messages)
+    generator.field2.extend(messages)
+    generator.field3.extend(messages)
+    generator.ext1.extend(messages)
+    generator.ext2.extend(messages)
+    generator.group1.add().field1.MergeFrom(messages[0])
+    generator.group1.add().field1.MergeFrom(messages[1])
+    generator.group1.add().field1.MergeFrom(messages[2])
+    generator.group2.add().field1.MergeFrom(messages[0])
+    generator.group2.add().field1.MergeFrom(messages[1])
+    generator.group2.add().field1.MergeFrom(messages[2])
+
+    data = generator.SerializeToString()
+    parsing_merge = unittest_pb2.TestParsingMerge()
+    parsing_merge.ParseFromString(data)
+
+    # Required and optional fields should be merged.
+    self.assertEqual(parsing_merge.required_all_types, merged_message)
+    self.assertEqual(parsing_merge.optional_all_types, merged_message)
+    self.assertEqual(parsing_merge.optionalgroup.optional_group_all_types,
+                     merged_message)
+    self.assertEqual(parsing_merge.Extensions[
+                     unittest_pb2.TestParsingMerge.optional_ext],
+                     merged_message)
+
+    # Repeated fields should not be merged.
+    self.assertEqual(len(parsing_merge.repeated_all_types), 3)
+    self.assertEqual(len(parsing_merge.repeatedgroup), 3)
+    self.assertEqual(len(parsing_merge.Extensions[
+        unittest_pb2.TestParsingMerge.repeated_ext]), 3)
+
+  def testPythonicInit(self):
+    message = unittest_pb2.TestAllTypes(
+        optional_int32=100,
+        optional_fixed32=200,
+        optional_float=300.5,
+        optional_bytes=b'x',
+        optionalgroup={'a': 400},
+        optional_nested_message={'bb': 500},
+        optional_nested_enum='BAZ',
+        repeatedgroup=[{'a': 600},
+                       {'a': 700}],
+        repeated_nested_enum=['FOO', unittest_pb2.TestAllTypes.BAR],
+        default_int32=800,
+        oneof_string='y')
+    self.assertIsInstance(message, unittest_pb2.TestAllTypes)
+    self.assertEqual(100, message.optional_int32)
+    self.assertEqual(200, message.optional_fixed32)
+    self.assertEqual(300.5, message.optional_float)
+    self.assertEqual(b'x', message.optional_bytes)
+    self.assertEqual(400, message.optionalgroup.a)
+    self.assertIsInstance(message.optional_nested_message, unittest_pb2.TestAllTypes.NestedMessage)
+    self.assertEqual(500, message.optional_nested_message.bb)
+    self.assertEqual(unittest_pb2.TestAllTypes.BAZ,
+                     message.optional_nested_enum)
+    self.assertEqual(2, len(message.repeatedgroup))
+    self.assertEqual(600, message.repeatedgroup[0].a)
+    self.assertEqual(700, message.repeatedgroup[1].a)
+    self.assertEqual(2, len(message.repeated_nested_enum))
+    self.assertEqual(unittest_pb2.TestAllTypes.FOO,
+                     message.repeated_nested_enum[0])
+    self.assertEqual(unittest_pb2.TestAllTypes.BAR,
+                     message.repeated_nested_enum[1])
+    self.assertEqual(800, message.default_int32)
+    self.assertEqual('y', message.oneof_string)
+    self.assertFalse(message.HasField('optional_int64'))
+    self.assertEqual(0, len(message.repeated_float))
+    self.assertEqual(42, message.default_int64)
+
+    message = unittest_pb2.TestAllTypes(optional_nested_enum=u'BAZ')
+    self.assertEqual(unittest_pb2.TestAllTypes.BAZ,
+                     message.optional_nested_enum)
+
+    with self.assertRaises(ValueError):
+      unittest_pb2.TestAllTypes(
+          optional_nested_message={'INVALID_NESTED_FIELD': 17})
+
+    with self.assertRaises(TypeError):
+      unittest_pb2.TestAllTypes(
+          optional_nested_message={'bb': 'INVALID_VALUE_TYPE'})
+
+    with self.assertRaises(ValueError):
+      unittest_pb2.TestAllTypes(optional_nested_enum='INVALID_LABEL')
+
+    with self.assertRaises(ValueError):
+      unittest_pb2.TestAllTypes(repeated_nested_enum='FOO')
+
+
+
+# Class to test proto3-only features/behavior (updated field presence & enums)
+class Proto3Test(unittest.TestCase):
+
+  # Utility method for comparing equality with a map.
+  def assertMapIterEquals(self, map_iter, dict_value):
+    # Avoid mutating caller's copy.
+    dict_value = dict(dict_value)
+
+    for k, v in map_iter:
+      self.assertEqual(v, dict_value[k])
+      del dict_value[k]
+
+    self.assertEqual({}, dict_value)
+
+  def testFieldPresence(self):
+    message = unittest_proto3_arena_pb2.TestAllTypes()
+
+    # We can't test presence of non-repeated, non-submessage fields.
+    with self.assertRaises(ValueError):
+      message.HasField('optional_int32')
+    with self.assertRaises(ValueError):
+      message.HasField('optional_float')
+    with self.assertRaises(ValueError):
+      message.HasField('optional_string')
+    with self.assertRaises(ValueError):
+      message.HasField('optional_bool')
+
+    # But we can still test presence of submessage fields.
+    self.assertFalse(message.HasField('optional_nested_message'))
+
+    # As with proto2, we can't test presence of fields that don't exist, or
+    # repeated fields.
+    with self.assertRaises(ValueError):
+      message.HasField('field_doesnt_exist')
+
+    with self.assertRaises(ValueError):
+      message.HasField('repeated_int32')
+    with self.assertRaises(ValueError):
+      message.HasField('repeated_nested_message')
+
+    # Fields should default to their type-specific default.
+    self.assertEqual(0, message.optional_int32)
+    self.assertEqual(0, message.optional_float)
+    self.assertEqual('', message.optional_string)
+    self.assertEqual(False, message.optional_bool)
+    self.assertEqual(0, message.optional_nested_message.bb)
+
+    # Setting a submessage should still return proper presence information.
+    message.optional_nested_message.bb = 0
+    self.assertTrue(message.HasField('optional_nested_message'))
+
+    # Set the fields to non-default values.
+    message.optional_int32 = 5
+    message.optional_float = 1.1
+    message.optional_string = 'abc'
+    message.optional_bool = True
+    message.optional_nested_message.bb = 15
+
+    # Clearing the fields unsets them and resets their value to default.
+    message.ClearField('optional_int32')
+    message.ClearField('optional_float')
+    message.ClearField('optional_string')
+    message.ClearField('optional_bool')
+    message.ClearField('optional_nested_message')
+
+    self.assertEqual(0, message.optional_int32)
+    self.assertEqual(0, message.optional_float)
+    self.assertEqual('', message.optional_string)
+    self.assertEqual(False, message.optional_bool)
+    self.assertEqual(0, message.optional_nested_message.bb)
+
+  def testAssignUnknownEnum(self):
+    """Assigning an unknown enum value is allowed and preserves the value."""
+    m = unittest_proto3_arena_pb2.TestAllTypes()
+
+    m.optional_nested_enum = 1234567
+    self.assertEqual(1234567, m.optional_nested_enum)
+    m.repeated_nested_enum.append(22334455)
+    self.assertEqual(22334455, m.repeated_nested_enum[0])
+    # Assignment is a different code path than append for the C++ impl.
+    m.repeated_nested_enum[0] = 7654321
+    self.assertEqual(7654321, m.repeated_nested_enum[0])
+    serialized = m.SerializeToString()
+
+    m2 = unittest_proto3_arena_pb2.TestAllTypes()
+    m2.ParseFromString(serialized)
+    self.assertEqual(1234567, m2.optional_nested_enum)
+    self.assertEqual(7654321, m2.repeated_nested_enum[0])
+
+  # Map isn't really a proto3-only feature. But there is no proto2 equivalent
+  # of google/protobuf/map_unittest.proto right now, so it's not easy to
+  # test both with the same test like we do for the other proto2/proto3 tests.
+  # (google/protobuf/map_protobuf_unittest.proto is very different in the set
+  # of messages and fields it contains).
+  def testScalarMapDefaults(self):
+    msg = map_unittest_pb2.TestMap()
+
+    # Scalars start out unset.
+    self.assertFalse(-123 in msg.map_int32_int32)
+    self.assertFalse(-2**33 in msg.map_int64_int64)
+    self.assertFalse(123 in msg.map_uint32_uint32)
+    self.assertFalse(2**33 in msg.map_uint64_uint64)
+    self.assertFalse(123 in msg.map_int32_double)
+    self.assertFalse(False in msg.map_bool_bool)
+    self.assertFalse('abc' in msg.map_string_string)
+    self.assertFalse(111 in msg.map_int32_bytes)
+    self.assertFalse(888 in msg.map_int32_enum)
+
+    # Accessing an unset key returns the default.
+    self.assertEqual(0, msg.map_int32_int32[-123])
+    self.assertEqual(0, msg.map_int64_int64[-2**33])
+    self.assertEqual(0, msg.map_uint32_uint32[123])
+    self.assertEqual(0, msg.map_uint64_uint64[2**33])
+    self.assertEqual(0.0, msg.map_int32_double[123])
+    self.assertTrue(isinstance(msg.map_int32_double[123], float))
+    self.assertEqual(False, msg.map_bool_bool[False])
+    self.assertTrue(isinstance(msg.map_bool_bool[False], bool))
+    self.assertEqual('', msg.map_string_string['abc'])
+    self.assertEqual(b'', msg.map_int32_bytes[111])
+    self.assertEqual(0, msg.map_int32_enum[888])
+
+    # It also sets the value in the map
+    self.assertTrue(-123 in msg.map_int32_int32)
+    self.assertTrue(-2**33 in msg.map_int64_int64)
+    self.assertTrue(123 in msg.map_uint32_uint32)
+    self.assertTrue(2**33 in msg.map_uint64_uint64)
+    self.assertTrue(123 in msg.map_int32_double)
+    self.assertTrue(False in msg.map_bool_bool)
+    self.assertTrue('abc' in msg.map_string_string)
+    self.assertTrue(111 in msg.map_int32_bytes)
+    self.assertTrue(888 in msg.map_int32_enum)
+
+    self.assertIsInstance(msg.map_string_string['abc'], six.text_type)
+
+    # Accessing an unset key still throws TypeError if the type of the key
+    # is incorrect.
+    with self.assertRaises(TypeError):
+      msg.map_string_string[123]
+
+    with self.assertRaises(TypeError):
+      123 in msg.map_string_string
+
+  def testMapGet(self):
+    # Need to test that get() properly returns the default, even though the dict
+    # has defaultdict-like semantics.
+    msg = map_unittest_pb2.TestMap()
+
+    self.assertIsNone(msg.map_int32_int32.get(5))
+    self.assertEqual(10, msg.map_int32_int32.get(5, 10))
+    self.assertIsNone(msg.map_int32_int32.get(5))
+
+    msg.map_int32_int32[5] = 15
+    self.assertEqual(15, msg.map_int32_int32.get(5))
+
+    self.assertIsNone(msg.map_int32_foreign_message.get(5))
+    self.assertEqual(10, msg.map_int32_foreign_message.get(5, 10))
+
+    submsg = msg.map_int32_foreign_message[5]
+    self.assertIs(submsg, msg.map_int32_foreign_message.get(5))
+
+  def testScalarMap(self):
+    msg = map_unittest_pb2.TestMap()
+
+    self.assertEqual(0, len(msg.map_int32_int32))
+    self.assertFalse(5 in msg.map_int32_int32)
+
+    msg.map_int32_int32[-123] = -456
+    msg.map_int64_int64[-2**33] = -2**34
+    msg.map_uint32_uint32[123] = 456
+    msg.map_uint64_uint64[2**33] = 2**34
+    msg.map_string_string['abc'] = '123'
+    msg.map_int32_enum[888] = 2
+
+    self.assertEqual([], msg.FindInitializationErrors())
+
+    self.assertEqual(1, len(msg.map_string_string))
+
+    # Bad key.
+    with self.assertRaises(TypeError):
+      msg.map_string_string[123] = '123'
+
+    # Verify that trying to assign a bad key doesn't actually add a member to
+    # the map.
+    self.assertEqual(1, len(msg.map_string_string))
+
+    # Bad value.
+    with self.assertRaises(TypeError):
+      msg.map_string_string['123'] = 123
+
+    serialized = msg.SerializeToString()
+    msg2 = map_unittest_pb2.TestMap()
+    msg2.ParseFromString(serialized)
+
+    # Bad key.
+    with self.assertRaises(TypeError):
+      msg2.map_string_string[123] = '123'
+
+    # Bad value.
+    with self.assertRaises(TypeError):
+      msg2.map_string_string['123'] = 123
+
+    self.assertEqual(-456, msg2.map_int32_int32[-123])
+    self.assertEqual(-2**34, msg2.map_int64_int64[-2**33])
+    self.assertEqual(456, msg2.map_uint32_uint32[123])
+    self.assertEqual(2**34, msg2.map_uint64_uint64[2**33])
+    self.assertEqual('123', msg2.map_string_string['abc'])
+    self.assertEqual(2, msg2.map_int32_enum[888])
+
+  def testStringUnicodeConversionInMap(self):
+    msg = map_unittest_pb2.TestMap()
+
+    unicode_obj = u'\u1234'
+    bytes_obj = unicode_obj.encode('utf8')
+
+    msg.map_string_string[bytes_obj] = bytes_obj
+
+    (key, value) = list(msg.map_string_string.items())[0]
+
+    self.assertEqual(key, unicode_obj)
+    self.assertEqual(value, unicode_obj)
+
+    self.assertIsInstance(key, six.text_type)
+    self.assertIsInstance(value, six.text_type)
+
+  def testMessageMap(self):
+    msg = map_unittest_pb2.TestMap()
+
+    self.assertEqual(0, len(msg.map_int32_foreign_message))
+    self.assertFalse(5 in msg.map_int32_foreign_message)
+
+    msg.map_int32_foreign_message[123]
+    # get_or_create() is an alias for getitem.
+    msg.map_int32_foreign_message.get_or_create(-456)
+
+    self.assertEqual(2, len(msg.map_int32_foreign_message))
+    self.assertIn(123, msg.map_int32_foreign_message)
+    self.assertIn(-456, msg.map_int32_foreign_message)
+    self.assertEqual(2, len(msg.map_int32_foreign_message))
+
+    # Bad key.
+    with self.assertRaises(TypeError):
+      msg.map_int32_foreign_message['123']
+
+    # Can't assign directly to submessage.
+    with self.assertRaises(ValueError):
+      msg.map_int32_foreign_message[999] = msg.map_int32_foreign_message[123]
+
+    # Verify that trying to assign a bad key doesn't actually add a member to
+    # the map.
+    self.assertEqual(2, len(msg.map_int32_foreign_message))
+
+    serialized = msg.SerializeToString()
+    msg2 = map_unittest_pb2.TestMap()
+    msg2.ParseFromString(serialized)
+
+    self.assertEqual(2, len(msg2.map_int32_foreign_message))
+    self.assertIn(123, msg2.map_int32_foreign_message)
+    self.assertIn(-456, msg2.map_int32_foreign_message)
+    self.assertEqual(2, len(msg2.map_int32_foreign_message))
+
+  def testMergeFrom(self):
+    msg = map_unittest_pb2.TestMap()
+    msg.map_int32_int32[12] = 34
+    msg.map_int32_int32[56] = 78
+    msg.map_int64_int64[22] = 33
+    msg.map_int32_foreign_message[111].c = 5
+    msg.map_int32_foreign_message[222].c = 10
+
+    msg2 = map_unittest_pb2.TestMap()
+    msg2.map_int32_int32[12] = 55
+    msg2.map_int64_int64[88] = 99
+    msg2.map_int32_foreign_message[222].c = 15
+    msg2.map_int32_foreign_message[222].d = 20
+    old_map_value = msg2.map_int32_foreign_message[222]
+
+    msg2.MergeFrom(msg)
+
+    self.assertEqual(34, msg2.map_int32_int32[12])
+    self.assertEqual(78, msg2.map_int32_int32[56])
+    self.assertEqual(33, msg2.map_int64_int64[22])
+    self.assertEqual(99, msg2.map_int64_int64[88])
+    self.assertEqual(5, msg2.map_int32_foreign_message[111].c)
+    self.assertEqual(10, msg2.map_int32_foreign_message[222].c)
+    self.assertFalse(msg2.map_int32_foreign_message[222].HasField('d'))
+    self.assertEqual(15, old_map_value.c)
+
+    # Verify that there is only one entry per key, even though the MergeFrom
+    # may have internally created multiple entries for a single key in the
+    # list representation.
+    as_dict = {}
+    for key in msg2.map_int32_foreign_message:
+      self.assertFalse(key in as_dict)
+      as_dict[key] = msg2.map_int32_foreign_message[key].c
+
+    self.assertEqual({111: 5, 222: 10}, as_dict)
+
+    # Special case: test that delete of item really removes the item, even if
+    # there might have physically been duplicate keys due to the previous merge.
+    # This is only a special case for the C++ implementation which stores the
+    # map as an array.
+    del msg2.map_int32_int32[12]
+    self.assertFalse(12 in msg2.map_int32_int32)
+
+    del msg2.map_int32_foreign_message[222]
+    self.assertFalse(222 in msg2.map_int32_foreign_message)
+
+  def testMergeFromBadType(self):
+    msg = map_unittest_pb2.TestMap()
+    with self.assertRaisesRegexp(
+        TypeError,
+        r'Parameter to MergeFrom\(\) must be instance of same class: expected '
+        r'.*TestMap got int\.'):
+      msg.MergeFrom(1)
+
+  def testCopyFromBadType(self):
+    msg = map_unittest_pb2.TestMap()
+    with self.assertRaisesRegexp(
+        TypeError,
+        r'Parameter to [A-Za-z]*From\(\) must be instance of same class: '
+        r'expected .*TestMap got int\.'):
+      msg.CopyFrom(1)
+
+  def testIntegerMapWithLongs(self):
+    msg = map_unittest_pb2.TestMap()
+    msg.map_int32_int32[long(-123)] = long(-456)
+    msg.map_int64_int64[long(-2**33)] = long(-2**34)
+    msg.map_uint32_uint32[long(123)] = long(456)
+    msg.map_uint64_uint64[long(2**33)] = long(2**34)
+
+    serialized = msg.SerializeToString()
+    msg2 = map_unittest_pb2.TestMap()
+    msg2.ParseFromString(serialized)
+
+    self.assertEqual(-456, msg2.map_int32_int32[-123])
+    self.assertEqual(-2**34, msg2.map_int64_int64[-2**33])
+    self.assertEqual(456, msg2.map_uint32_uint32[123])
+    self.assertEqual(2**34, msg2.map_uint64_uint64[2**33])
+
+  def testMapAssignmentCausesPresence(self):
+    msg = map_unittest_pb2.TestMapSubmessage()
+    msg.test_map.map_int32_int32[123] = 456
+
+    serialized = msg.SerializeToString()
+    msg2 = map_unittest_pb2.TestMapSubmessage()
+    msg2.ParseFromString(serialized)
+
+    self.assertEqual(msg, msg2)
+
+    # Now test that various mutations of the map properly invalidate the
+    # cached size of the submessage.
+    msg.test_map.map_int32_int32[888] = 999
+    serialized = msg.SerializeToString()
+    msg2.ParseFromString(serialized)
+    self.assertEqual(msg, msg2)
+
+    msg.test_map.map_int32_int32.clear()
+    serialized = msg.SerializeToString()
+    msg2.ParseFromString(serialized)
+    self.assertEqual(msg, msg2)
+
+  def testMapAssignmentCausesPresenceForSubmessages(self):
+    msg = map_unittest_pb2.TestMapSubmessage()
+    msg.test_map.map_int32_foreign_message[123].c = 5
+
+    serialized = msg.SerializeToString()
+    msg2 = map_unittest_pb2.TestMapSubmessage()
+    msg2.ParseFromString(serialized)
+
+    self.assertEqual(msg, msg2)
+
+    # Now test that various mutations of the map properly invalidate the
+    # cached size of the submessage.
+    msg.test_map.map_int32_foreign_message[888].c = 7
+    serialized = msg.SerializeToString()
+    msg2.ParseFromString(serialized)
+    self.assertEqual(msg, msg2)
+
+    msg.test_map.map_int32_foreign_message[888].MergeFrom(
+        msg.test_map.map_int32_foreign_message[123])
+    serialized = msg.SerializeToString()
+    msg2.ParseFromString(serialized)
+    self.assertEqual(msg, msg2)
+
+    msg.test_map.map_int32_foreign_message.clear()
+    serialized = msg.SerializeToString()
+    msg2.ParseFromString(serialized)
+    self.assertEqual(msg, msg2)
+
+  def testModifyMapWhileIterating(self):
+    msg = map_unittest_pb2.TestMap()
+
+    string_string_iter = iter(msg.map_string_string)
+    int32_foreign_iter = iter(msg.map_int32_foreign_message)
+
+    msg.map_string_string['abc'] = '123'
+    msg.map_int32_foreign_message[5].c = 5
+
+    with self.assertRaises(RuntimeError):
+      for key in string_string_iter:
+        pass
+
+    with self.assertRaises(RuntimeError):
+      for key in int32_foreign_iter:
+        pass
+
+  def testSubmessageMap(self):
+    msg = map_unittest_pb2.TestMap()
+
+    submsg = msg.map_int32_foreign_message[111]
+    self.assertIs(submsg, msg.map_int32_foreign_message[111])
+    self.assertIsInstance(submsg, unittest_pb2.ForeignMessage)
+
+    submsg.c = 5
+
+    serialized = msg.SerializeToString()
+    msg2 = map_unittest_pb2.TestMap()
+    msg2.ParseFromString(serialized)
+
+    self.assertEqual(5, msg2.map_int32_foreign_message[111].c)
+
+    # Doesn't allow direct submessage assignment.
+    with self.assertRaises(ValueError):
+      msg.map_int32_foreign_message[88] = unittest_pb2.ForeignMessage()
+
+  def testMapIteration(self):
+    msg = map_unittest_pb2.TestMap()
+
+    for k, v in msg.map_int32_int32.items():
+      # Should not be reached.
+      self.assertTrue(False)
+
+    msg.map_int32_int32[2] = 4
+    msg.map_int32_int32[3] = 6
+    msg.map_int32_int32[4] = 8
+    self.assertEqual(3, len(msg.map_int32_int32))
+
+    matching_dict = {2: 4, 3: 6, 4: 8}
+    self.assertMapIterEquals(msg.map_int32_int32.items(), matching_dict)
+
+  def testMapItems(self):
+    # Map items used to have strange behaviors when use c extension. Because
+    # [] may reorder the map and invalidate any exsting iterators.
+    # TODO(jieluo): Check if [] reordering the map is a bug or intended
+    # behavior.
+    msg = map_unittest_pb2.TestMap()
+    msg.map_string_string['local_init_op'] = ''
+    msg.map_string_string['trainable_variables'] = ''
+    msg.map_string_string['variables'] = ''
+    msg.map_string_string['init_op'] = ''
+    msg.map_string_string['summaries'] = ''
+    items1 = msg.map_string_string.items()
+    items2 = msg.map_string_string.items()
+    self.assertEqual(items1, items2)
+
+  def testMapIterationClearMessage(self):
+    # Iterator needs to work even if message and map are deleted.
+    msg = map_unittest_pb2.TestMap()
+
+    msg.map_int32_int32[2] = 4
+    msg.map_int32_int32[3] = 6
+    msg.map_int32_int32[4] = 8
+
+    it = msg.map_int32_int32.items()
+    del msg
+
+    matching_dict = {2: 4, 3: 6, 4: 8}
+    self.assertMapIterEquals(it, matching_dict)
+
+  def testMapConstruction(self):
+    msg = map_unittest_pb2.TestMap(map_int32_int32={1: 2, 3: 4})
+    self.assertEqual(2, msg.map_int32_int32[1])
+    self.assertEqual(4, msg.map_int32_int32[3])
+
+    msg = map_unittest_pb2.TestMap(
+        map_int32_foreign_message={3: unittest_pb2.ForeignMessage(c=5)})
+    self.assertEqual(5, msg.map_int32_foreign_message[3].c)
+
+  def testMapValidAfterFieldCleared(self):
+    # Map needs to work even if field is cleared.
+    # For the C++ implementation this tests the correctness of
+    # ScalarMapContainer::Release()
+    msg = map_unittest_pb2.TestMap()
+    int32_map = msg.map_int32_int32
+
+    int32_map[2] = 4
+    int32_map[3] = 6
+    int32_map[4] = 8
+
+    msg.ClearField('map_int32_int32')
+    self.assertEqual(b'', msg.SerializeToString())
+    matching_dict = {2: 4, 3: 6, 4: 8}
+    self.assertMapIterEquals(int32_map.items(), matching_dict)
+
+  def testMessageMapValidAfterFieldCleared(self):
+    # Map needs to work even if field is cleared.
+    # For the C++ implementation this tests the correctness of
+    # ScalarMapContainer::Release()
+    msg = map_unittest_pb2.TestMap()
+    int32_foreign_message = msg.map_int32_foreign_message
+
+    int32_foreign_message[2].c = 5
+
+    msg.ClearField('map_int32_foreign_message')
+    self.assertEqual(b'', msg.SerializeToString())
+    self.assertTrue(2 in int32_foreign_message.keys())
+
+  def testMapIterInvalidatedByClearField(self):
+    # Map iterator is invalidated when field is cleared.
+    # But this case does need to not crash the interpreter.
+    # For the C++ implementation this tests the correctness of
+    # ScalarMapContainer::Release()
+    msg = map_unittest_pb2.TestMap()
+
+    it = iter(msg.map_int32_int32)
+
+    msg.ClearField('map_int32_int32')
+    with self.assertRaises(RuntimeError):
+      for _ in it:
+        pass
+
+    it = iter(msg.map_int32_foreign_message)
+    msg.ClearField('map_int32_foreign_message')
+    with self.assertRaises(RuntimeError):
+      for _ in it:
+        pass
+
+  def testMapDelete(self):
+    msg = map_unittest_pb2.TestMap()
+
+    self.assertEqual(0, len(msg.map_int32_int32))
+
+    msg.map_int32_int32[4] = 6
+    self.assertEqual(1, len(msg.map_int32_int32))
+
+    with self.assertRaises(KeyError):
+      del msg.map_int32_int32[88]
+
+    del msg.map_int32_int32[4]
+    self.assertEqual(0, len(msg.map_int32_int32))
+
+  def testMapsAreMapping(self):
+    msg = map_unittest_pb2.TestMap()
+    self.assertIsInstance(msg.map_int32_int32, collections.Mapping)
+    self.assertIsInstance(msg.map_int32_int32, collections.MutableMapping)
+    self.assertIsInstance(msg.map_int32_foreign_message, collections.Mapping)
+    self.assertIsInstance(msg.map_int32_foreign_message,
+                          collections.MutableMapping)
+
+  def testMapFindInitializationErrorsSmokeTest(self):
+    msg = map_unittest_pb2.TestMap()
+    msg.map_string_string['abc'] = '123'
+    msg.map_int32_int32[35] = 64
+    msg.map_string_foreign_message['foo'].c = 5
+    self.assertEqual(0, len(msg.FindInitializationErrors()))
+
+
+
+class ValidTypeNamesTest(unittest.TestCase):
+
+  def assertImportFromName(self, msg, base_name):
+    # Parse <type 'module.class_name'> to extra 'some.name' as a string.
+    tp_name = str(type(msg)).split("'")[1]
+    valid_names = ('Repeated%sContainer' % base_name,
+                   'Repeated%sFieldContainer' % base_name)
+    self.assertTrue(any(tp_name.endswith(v) for v in valid_names),
+                    '%r does end with any of %r' % (tp_name, valid_names))
+
+    parts = tp_name.split('.')
+    class_name = parts[-1]
+    module_name = '.'.join(parts[:-1])
+    __import__(module_name, fromlist=[class_name])
+
+  def testTypeNamesCanBeImported(self):
+    # If import doesn't work, pickling won't work either.
+    pb = unittest_pb2.TestAllTypes()
+    self.assertImportFromName(pb.repeated_int32, 'Scalar')
+    self.assertImportFromName(pb.repeated_nested_message, 'Composite')
+
+class PackedFieldTest(unittest.TestCase):
+
+  def setMessage(self, message):
+    message.repeated_int32.append(1)
+    message.repeated_int64.append(1)
+    message.repeated_uint32.append(1)
+    message.repeated_uint64.append(1)
+    message.repeated_sint32.append(1)
+    message.repeated_sint64.append(1)
+    message.repeated_fixed32.append(1)
+    message.repeated_fixed64.append(1)
+    message.repeated_sfixed32.append(1)
+    message.repeated_sfixed64.append(1)
+    message.repeated_float.append(1.0)
+    message.repeated_double.append(1.0)
+    message.repeated_bool.append(True)
+    message.repeated_nested_enum.append(1)
+
+  def testPackedFields(self):
+    message = packed_field_test_pb2.TestPackedTypes()
+    self.setMessage(message)
+    golden_data = (b'\x0A\x01\x01'
+                   b'\x12\x01\x01'
+                   b'\x1A\x01\x01'
+                   b'\x22\x01\x01'
+                   b'\x2A\x01\x02'
+                   b'\x32\x01\x02'
+                   b'\x3A\x04\x01\x00\x00\x00'
+                   b'\x42\x08\x01\x00\x00\x00\x00\x00\x00\x00'
+                   b'\x4A\x04\x01\x00\x00\x00'
+                   b'\x52\x08\x01\x00\x00\x00\x00\x00\x00\x00'
+                   b'\x5A\x04\x00\x00\x80\x3f'
+                   b'\x62\x08\x00\x00\x00\x00\x00\x00\xf0\x3f'
+                   b'\x6A\x01\x01'
+                   b'\x72\x01\x01')
+    self.assertEqual(golden_data, message.SerializeToString())
+
+  def testUnpackedFields(self):
+    message = packed_field_test_pb2.TestUnpackedTypes()
+    self.setMessage(message)
+    golden_data = (b'\x08\x01'
+                   b'\x10\x01'
+                   b'\x18\x01'
+                   b'\x20\x01'
+                   b'\x28\x02'
+                   b'\x30\x02'
+                   b'\x3D\x01\x00\x00\x00'
+                   b'\x41\x01\x00\x00\x00\x00\x00\x00\x00'
+                   b'\x4D\x01\x00\x00\x00'
+                   b'\x51\x01\x00\x00\x00\x00\x00\x00\x00'
+                   b'\x5D\x00\x00\x80\x3f'
+                   b'\x61\x00\x00\x00\x00\x00\x00\xf0\x3f'
+                   b'\x68\x01'
+                   b'\x70\x01')
+    self.assertEqual(golden_data, message.SerializeToString())
+
+
+@unittest.skipIf(api_implementation.Type() != 'cpp',
+                 'explicit tests of the C++ implementation')
+class OversizeProtosTest(unittest.TestCase):
+
+  def setUp(self):
+    self.file_desc = """
+      name: "f/f.msg2"
+      package: "f"
+      message_type {
+        name: "msg1"
+        field {
+          name: "payload"
+          number: 1
+          label: LABEL_OPTIONAL
+          type: TYPE_STRING
+        }
+      }
+      message_type {
+        name: "msg2"
+        field {
+          name: "field"
+          number: 1
+          label: LABEL_OPTIONAL
+          type: TYPE_MESSAGE
+          type_name: "msg1"
+        }
+      }
+    """
+    pool = descriptor_pool.DescriptorPool()
+    desc = descriptor_pb2.FileDescriptorProto()
+    text_format.Parse(self.file_desc, desc)
+    pool.Add(desc)
+    self.proto_cls = message_factory.MessageFactory(pool).GetPrototype(
+        pool.FindMessageTypeByName('f.msg2'))
+    self.p = self.proto_cls()
+    self.p.field.payload = 'c' * (1024 * 1024 * 64 + 1)
+    self.p_serialized = self.p.SerializeToString()
+
+  def testAssertOversizeProto(self):
+    from google.protobuf.pyext._message import SetAllowOversizeProtos
+    SetAllowOversizeProtos(False)
+    q = self.proto_cls()
+    try:
+      q.ParseFromString(self.p_serialized)
+    except message.DecodeError as e:
+      self.assertEqual(str(e), 'Error parsing message')
+
+  def testSucceedOversizeProto(self):
+    from google.protobuf.pyext._message import SetAllowOversizeProtos
+    SetAllowOversizeProtos(True)
+    q = self.proto_cls()
+    q.ParseFromString(self.p_serialized)
+    self.assertEqual(self.p.field.payload, q.field.payload)
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/missing_enum_values_pb2.py b/generator/google/protobuf/internal/missing_enum_values_pb2.py
new file mode 100644
index 0000000..4767f03
--- /dev/null
+++ b/generator/google/protobuf/internal/missing_enum_values_pb2.py
@@ -0,0 +1,229 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/missing_enum_values.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/missing_enum_values.proto',
+  package='google.protobuf.python.internal',
+  syntax='proto2',
+  serialized_pb=_b('\n2google/protobuf/internal/missing_enum_values.proto\x12\x1fgoogle.protobuf.python.internal\"\xc1\x02\n\x0eTestEnumValues\x12X\n\x14optional_nested_enum\x18\x01 \x01(\x0e\x32:.google.protobuf.python.internal.TestEnumValues.NestedEnum\x12X\n\x14repeated_nested_enum\x18\x02 \x03(\x0e\x32:.google.protobuf.python.internal.TestEnumValues.NestedEnum\x12Z\n\x12packed_nested_enum\x18\x03 \x03(\x0e\x32:.google.protobuf.python.internal.TestEnumValues.NestedEnumB\x02\x10\x01\"\x1f\n\nNestedEnum\x12\x08\n\x04ZERO\x10\x00\x12\x07\n\x03ONE\x10\x01\"\xd3\x02\n\x15TestMissingEnumValues\x12_\n\x14optional_nested_enum\x18\x01 \x01(\x0e\x32\x41.google.protobuf.python.internal.TestMissingEnumValues.NestedEnum\x12_\n\x14repeated_nested_enum\x18\x02 \x03(\x0e\x32\x41.google.protobuf.python.internal.TestMissingEnumValues.NestedEnum\x12\x61\n\x12packed_nested_enum\x18\x03 \x03(\x0e\x32\x41.google.protobuf.python.internal.TestMissingEnumValues.NestedEnumB\x02\x10\x01\"\x15\n\nNestedEnum\x12\x07\n\x03TWO\x10\x02\"\x1b\n\nJustString\x12\r\n\x05\x64ummy\x18\x01 \x02(\t')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+_TESTENUMVALUES_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='google.protobuf.python.internal.TestEnumValues.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='ZERO', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='ONE', index=1, number=1,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=378,
+  serialized_end=409,
+)
+_sym_db.RegisterEnumDescriptor(_TESTENUMVALUES_NESTEDENUM)
+
+_TESTMISSINGENUMVALUES_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='google.protobuf.python.internal.TestMissingEnumValues.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='TWO', index=0, number=2,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=730,
+  serialized_end=751,
+)
+_sym_db.RegisterEnumDescriptor(_TESTMISSINGENUMVALUES_NESTEDENUM)
+
+
+_TESTENUMVALUES = _descriptor.Descriptor(
+  name='TestEnumValues',
+  full_name='google.protobuf.python.internal.TestEnumValues',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='optional_nested_enum', full_name='google.protobuf.python.internal.TestEnumValues.optional_nested_enum', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_nested_enum', full_name='google.protobuf.python.internal.TestEnumValues.repeated_nested_enum', index=1,
+      number=2, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='packed_nested_enum', full_name='google.protobuf.python.internal.TestEnumValues.packed_nested_enum', index=2,
+      number=3, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _TESTENUMVALUES_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=88,
+  serialized_end=409,
+)
+
+
+_TESTMISSINGENUMVALUES = _descriptor.Descriptor(
+  name='TestMissingEnumValues',
+  full_name='google.protobuf.python.internal.TestMissingEnumValues',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='optional_nested_enum', full_name='google.protobuf.python.internal.TestMissingEnumValues.optional_nested_enum', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=2,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_nested_enum', full_name='google.protobuf.python.internal.TestMissingEnumValues.repeated_nested_enum', index=1,
+      number=2, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='packed_nested_enum', full_name='google.protobuf.python.internal.TestMissingEnumValues.packed_nested_enum', index=2,
+      number=3, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _TESTMISSINGENUMVALUES_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=412,
+  serialized_end=751,
+)
+
+
+_JUSTSTRING = _descriptor.Descriptor(
+  name='JustString',
+  full_name='google.protobuf.python.internal.JustString',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='dummy', full_name='google.protobuf.python.internal.JustString.dummy', index=0,
+      number=1, type=9, cpp_type=9, label=2,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=753,
+  serialized_end=780,
+)
+
+_TESTENUMVALUES.fields_by_name['optional_nested_enum'].enum_type = _TESTENUMVALUES_NESTEDENUM
+_TESTENUMVALUES.fields_by_name['repeated_nested_enum'].enum_type = _TESTENUMVALUES_NESTEDENUM
+_TESTENUMVALUES.fields_by_name['packed_nested_enum'].enum_type = _TESTENUMVALUES_NESTEDENUM
+_TESTENUMVALUES_NESTEDENUM.containing_type = _TESTENUMVALUES
+_TESTMISSINGENUMVALUES.fields_by_name['optional_nested_enum'].enum_type = _TESTMISSINGENUMVALUES_NESTEDENUM
+_TESTMISSINGENUMVALUES.fields_by_name['repeated_nested_enum'].enum_type = _TESTMISSINGENUMVALUES_NESTEDENUM
+_TESTMISSINGENUMVALUES.fields_by_name['packed_nested_enum'].enum_type = _TESTMISSINGENUMVALUES_NESTEDENUM
+_TESTMISSINGENUMVALUES_NESTEDENUM.containing_type = _TESTMISSINGENUMVALUES
+DESCRIPTOR.message_types_by_name['TestEnumValues'] = _TESTENUMVALUES
+DESCRIPTOR.message_types_by_name['TestMissingEnumValues'] = _TESTMISSINGENUMVALUES
+DESCRIPTOR.message_types_by_name['JustString'] = _JUSTSTRING
+
+TestEnumValues = _reflection.GeneratedProtocolMessageType('TestEnumValues', (_message.Message,), dict(
+  DESCRIPTOR = _TESTENUMVALUES,
+  __module__ = 'google.protobuf.internal.missing_enum_values_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.TestEnumValues)
+  ))
+_sym_db.RegisterMessage(TestEnumValues)
+
+TestMissingEnumValues = _reflection.GeneratedProtocolMessageType('TestMissingEnumValues', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMISSINGENUMVALUES,
+  __module__ = 'google.protobuf.internal.missing_enum_values_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.TestMissingEnumValues)
+  ))
+_sym_db.RegisterMessage(TestMissingEnumValues)
+
+JustString = _reflection.GeneratedProtocolMessageType('JustString', (_message.Message,), dict(
+  DESCRIPTOR = _JUSTSTRING,
+  __module__ = 'google.protobuf.internal.missing_enum_values_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.JustString)
+  ))
+_sym_db.RegisterMessage(JustString)
+
+
+_TESTENUMVALUES.fields_by_name['packed_nested_enum'].has_options = True
+_TESTENUMVALUES.fields_by_name['packed_nested_enum']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTMISSINGENUMVALUES.fields_by_name['packed_nested_enum'].has_options = True
+_TESTMISSINGENUMVALUES.fields_by_name['packed_nested_enum']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/more_extensions_dynamic_pb2.py b/generator/google/protobuf/internal/more_extensions_dynamic_pb2.py
new file mode 100644
index 0000000..e147800
--- /dev/null
+++ b/generator/google/protobuf/internal/more_extensions_dynamic_pb2.py
@@ -0,0 +1,92 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/more_extensions_dynamic.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf.internal import more_extensions_pb2 as google_dot_protobuf_dot_internal_dot_more__extensions__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/more_extensions_dynamic.proto',
+  package='google.protobuf.internal',
+  syntax='proto2',
+  serialized_pb=_b('\n6google/protobuf/internal/more_extensions_dynamic.proto\x12\x18google.protobuf.internal\x1a.google/protobuf/internal/more_extensions.proto\"\x1f\n\x12\x44ynamicMessageType\x12\t\n\x01\x61\x18\x01 \x01(\x05:J\n\x17\x64ynamic_int32_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x64 \x01(\x05:z\n\x19\x64ynamic_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x65 \x01(\x0b\x32,.google.protobuf.internal.DynamicMessageType')
+  ,
+  dependencies=[google_dot_protobuf_dot_internal_dot_more__extensions__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+DYNAMIC_INT32_EXTENSION_FIELD_NUMBER = 100
+dynamic_int32_extension = _descriptor.FieldDescriptor(
+  name='dynamic_int32_extension', full_name='google.protobuf.internal.dynamic_int32_extension', index=0,
+  number=100, type=5, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DYNAMIC_MESSAGE_EXTENSION_FIELD_NUMBER = 101
+dynamic_message_extension = _descriptor.FieldDescriptor(
+  name='dynamic_message_extension', full_name='google.protobuf.internal.dynamic_message_extension', index=1,
+  number=101, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+
+
+_DYNAMICMESSAGETYPE = _descriptor.Descriptor(
+  name='DynamicMessageType',
+  full_name='google.protobuf.internal.DynamicMessageType',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='google.protobuf.internal.DynamicMessageType.a', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=132,
+  serialized_end=163,
+)
+
+DESCRIPTOR.message_types_by_name['DynamicMessageType'] = _DYNAMICMESSAGETYPE
+DESCRIPTOR.extensions_by_name['dynamic_int32_extension'] = dynamic_int32_extension
+DESCRIPTOR.extensions_by_name['dynamic_message_extension'] = dynamic_message_extension
+
+DynamicMessageType = _reflection.GeneratedProtocolMessageType('DynamicMessageType', (_message.Message,), dict(
+  DESCRIPTOR = _DYNAMICMESSAGETYPE,
+  __module__ = 'google.protobuf.internal.more_extensions_dynamic_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.internal.DynamicMessageType)
+  ))
+_sym_db.RegisterMessage(DynamicMessageType)
+
+google_dot_protobuf_dot_internal_dot_more__extensions__pb2.ExtendedMessage.RegisterExtension(dynamic_int32_extension)
+dynamic_message_extension.message_type = _DYNAMICMESSAGETYPE
+google_dot_protobuf_dot_internal_dot_more__extensions__pb2.ExtendedMessage.RegisterExtension(dynamic_message_extension)
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/more_extensions_pb2.py b/generator/google/protobuf/internal/more_extensions_pb2.py
new file mode 100644
index 0000000..c2a03aa
--- /dev/null
+++ b/generator/google/protobuf/internal/more_extensions_pb2.py
@@ -0,0 +1,183 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/more_extensions.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/more_extensions.proto',
+  package='google.protobuf.internal',
+  syntax='proto2',
+  serialized_pb=_b('\n.google/protobuf/internal/more_extensions.proto\x12\x18google.protobuf.internal\"P\n\x0fTopLevelMessage\x12=\n\nsubmessage\x18\x01 \x01(\x0b\x32).google.protobuf.internal.ExtendedMessage\"\x1b\n\x0f\x45xtendedMessage*\x08\x08\x01\x10\x80\x80\x80\x80\x02\"-\n\x0e\x46oreignMessage\x12\x1b\n\x13\x66oreign_message_int\x18\x01 \x01(\x05:I\n\x16optional_int_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x01 \x01(\x05:w\n\x1aoptional_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x02 \x01(\x0b\x32(.google.protobuf.internal.ForeignMessage:I\n\x16repeated_int_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x03 \x03(\x05:w\n\x1arepeated_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x04 \x03(\x0b\x32(.google.protobuf.internal.ForeignMessage')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+OPTIONAL_INT_EXTENSION_FIELD_NUMBER = 1
+optional_int_extension = _descriptor.FieldDescriptor(
+  name='optional_int_extension', full_name='google.protobuf.internal.optional_int_extension', index=0,
+  number=1, type=5, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_MESSAGE_EXTENSION_FIELD_NUMBER = 2
+optional_message_extension = _descriptor.FieldDescriptor(
+  name='optional_message_extension', full_name='google.protobuf.internal.optional_message_extension', index=1,
+  number=2, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_INT_EXTENSION_FIELD_NUMBER = 3
+repeated_int_extension = _descriptor.FieldDescriptor(
+  name='repeated_int_extension', full_name='google.protobuf.internal.repeated_int_extension', index=2,
+  number=3, type=5, cpp_type=1, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_MESSAGE_EXTENSION_FIELD_NUMBER = 4
+repeated_message_extension = _descriptor.FieldDescriptor(
+  name='repeated_message_extension', full_name='google.protobuf.internal.repeated_message_extension', index=3,
+  number=4, type=11, cpp_type=10, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+
+
+_TOPLEVELMESSAGE = _descriptor.Descriptor(
+  name='TopLevelMessage',
+  full_name='google.protobuf.internal.TopLevelMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='submessage', full_name='google.protobuf.internal.TopLevelMessage.submessage', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=76,
+  serialized_end=156,
+)
+
+
+_EXTENDEDMESSAGE = _descriptor.Descriptor(
+  name='ExtendedMessage',
+  full_name='google.protobuf.internal.ExtendedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(1, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=158,
+  serialized_end=185,
+)
+
+
+_FOREIGNMESSAGE = _descriptor.Descriptor(
+  name='ForeignMessage',
+  full_name='google.protobuf.internal.ForeignMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='foreign_message_int', full_name='google.protobuf.internal.ForeignMessage.foreign_message_int', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=187,
+  serialized_end=232,
+)
+
+_TOPLEVELMESSAGE.fields_by_name['submessage'].message_type = _EXTENDEDMESSAGE
+DESCRIPTOR.message_types_by_name['TopLevelMessage'] = _TOPLEVELMESSAGE
+DESCRIPTOR.message_types_by_name['ExtendedMessage'] = _EXTENDEDMESSAGE
+DESCRIPTOR.message_types_by_name['ForeignMessage'] = _FOREIGNMESSAGE
+DESCRIPTOR.extensions_by_name['optional_int_extension'] = optional_int_extension
+DESCRIPTOR.extensions_by_name['optional_message_extension'] = optional_message_extension
+DESCRIPTOR.extensions_by_name['repeated_int_extension'] = repeated_int_extension
+DESCRIPTOR.extensions_by_name['repeated_message_extension'] = repeated_message_extension
+
+TopLevelMessage = _reflection.GeneratedProtocolMessageType('TopLevelMessage', (_message.Message,), dict(
+  DESCRIPTOR = _TOPLEVELMESSAGE,
+  __module__ = 'google.protobuf.internal.more_extensions_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.internal.TopLevelMessage)
+  ))
+_sym_db.RegisterMessage(TopLevelMessage)
+
+ExtendedMessage = _reflection.GeneratedProtocolMessageType('ExtendedMessage', (_message.Message,), dict(
+  DESCRIPTOR = _EXTENDEDMESSAGE,
+  __module__ = 'google.protobuf.internal.more_extensions_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.internal.ExtendedMessage)
+  ))
+_sym_db.RegisterMessage(ExtendedMessage)
+
+ForeignMessage = _reflection.GeneratedProtocolMessageType('ForeignMessage', (_message.Message,), dict(
+  DESCRIPTOR = _FOREIGNMESSAGE,
+  __module__ = 'google.protobuf.internal.more_extensions_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.internal.ForeignMessage)
+  ))
+_sym_db.RegisterMessage(ForeignMessage)
+
+ExtendedMessage.RegisterExtension(optional_int_extension)
+optional_message_extension.message_type = _FOREIGNMESSAGE
+ExtendedMessage.RegisterExtension(optional_message_extension)
+ExtendedMessage.RegisterExtension(repeated_int_extension)
+repeated_message_extension.message_type = _FOREIGNMESSAGE
+ExtendedMessage.RegisterExtension(repeated_message_extension)
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/more_messages_pb2.py b/generator/google/protobuf/internal/more_messages_pb2.py
new file mode 100644
index 0000000..4ad9c9e
--- /dev/null
+++ b/generator/google/protobuf/internal/more_messages_pb2.py
@@ -0,0 +1,103 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/more_messages.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/more_messages.proto',
+  package='google.protobuf.internal',
+  syntax='proto2',
+  serialized_pb=_b('\n,google/protobuf/internal/more_messages.proto\x12\x18google.protobuf.internal\"h\n\x10OutOfOrderFields\x12\x17\n\x0foptional_sint32\x18\x05 \x01(\x11\x12\x17\n\x0foptional_uint32\x18\x03 \x01(\r\x12\x16\n\x0eoptional_int32\x18\x01 \x01(\x05*\x04\x08\x04\x10\x05*\x04\x08\x02\x10\x03:C\n\x0foptional_uint64\x12*.google.protobuf.internal.OutOfOrderFields\x18\x04 \x01(\x04:B\n\x0eoptional_int64\x12*.google.protobuf.internal.OutOfOrderFields\x18\x02 \x01(\x03')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+OPTIONAL_UINT64_FIELD_NUMBER = 4
+optional_uint64 = _descriptor.FieldDescriptor(
+  name='optional_uint64', full_name='google.protobuf.internal.optional_uint64', index=0,
+  number=4, type=4, cpp_type=4, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_INT64_FIELD_NUMBER = 2
+optional_int64 = _descriptor.FieldDescriptor(
+  name='optional_int64', full_name='google.protobuf.internal.optional_int64', index=1,
+  number=2, type=3, cpp_type=2, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+
+
+_OUTOFORDERFIELDS = _descriptor.Descriptor(
+  name='OutOfOrderFields',
+  full_name='google.protobuf.internal.OutOfOrderFields',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='optional_sint32', full_name='google.protobuf.internal.OutOfOrderFields.optional_sint32', index=0,
+      number=5, type=17, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_uint32', full_name='google.protobuf.internal.OutOfOrderFields.optional_uint32', index=1,
+      number=3, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_int32', full_name='google.protobuf.internal.OutOfOrderFields.optional_int32', index=2,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(4, 5), (2, 3), ],
+  oneofs=[
+  ],
+  serialized_start=74,
+  serialized_end=178,
+)
+
+DESCRIPTOR.message_types_by_name['OutOfOrderFields'] = _OUTOFORDERFIELDS
+DESCRIPTOR.extensions_by_name['optional_uint64'] = optional_uint64
+DESCRIPTOR.extensions_by_name['optional_int64'] = optional_int64
+
+OutOfOrderFields = _reflection.GeneratedProtocolMessageType('OutOfOrderFields', (_message.Message,), dict(
+  DESCRIPTOR = _OUTOFORDERFIELDS,
+  __module__ = 'google.protobuf.internal.more_messages_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.internal.OutOfOrderFields)
+  ))
+_sym_db.RegisterMessage(OutOfOrderFields)
+
+OutOfOrderFields.RegisterExtension(optional_uint64)
+OutOfOrderFields.RegisterExtension(optional_int64)
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/packed_field_test_pb2.py b/generator/google/protobuf/internal/packed_field_test_pb2.py
new file mode 100644
index 0000000..77b6384
--- /dev/null
+++ b/generator/google/protobuf/internal/packed_field_test_pb2.py
@@ -0,0 +1,348 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/packed_field_test.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/packed_field_test.proto',
+  package='google.protobuf.python.internal',
+  syntax='proto3',
+  serialized_pb=_b('\n0google/protobuf/internal/packed_field_test.proto\x12\x1fgoogle.protobuf.python.internal\"\xdb\x03\n\x0fTestPackedTypes\x12\x16\n\x0erepeated_int32\x18\x01 \x03(\x05\x12\x16\n\x0erepeated_int64\x18\x02 \x03(\x03\x12\x17\n\x0frepeated_uint32\x18\x03 \x03(\r\x12\x17\n\x0frepeated_uint64\x18\x04 \x03(\x04\x12\x17\n\x0frepeated_sint32\x18\x05 \x03(\x11\x12\x17\n\x0frepeated_sint64\x18\x06 \x03(\x12\x12\x18\n\x10repeated_fixed32\x18\x07 \x03(\x07\x12\x18\n\x10repeated_fixed64\x18\x08 \x03(\x06\x12\x19\n\x11repeated_sfixed32\x18\t \x03(\x0f\x12\x19\n\x11repeated_sfixed64\x18\n \x03(\x10\x12\x16\n\x0erepeated_float\x18\x0b \x03(\x02\x12\x17\n\x0frepeated_double\x18\x0c \x03(\x01\x12\x15\n\rrepeated_bool\x18\r \x03(\x08\x12Y\n\x14repeated_nested_enum\x18\x0e \x03(\x0e\x32;.google.protobuf.python.internal.TestPackedTypes.NestedEnum\"\'\n\nNestedEnum\x12\x07\n\x03\x46OO\x10\x00\x12\x07\n\x03\x42\x41R\x10\x01\x12\x07\n\x03\x42\x41Z\x10\x02\"\xec\x03\n\x11TestUnpackedTypes\x12\x1a\n\x0erepeated_int32\x18\x01 \x03(\x05\x42\x02\x10\x00\x12\x1a\n\x0erepeated_int64\x18\x02 \x03(\x03\x42\x02\x10\x00\x12\x1b\n\x0frepeated_uint32\x18\x03 \x03(\rB\x02\x10\x00\x12\x1b\n\x0frepeated_uint64\x18\x04 \x03(\x04\x42\x02\x10\x00\x12\x1b\n\x0frepeated_sint32\x18\x05 \x03(\x11\x42\x02\x10\x00\x12\x1b\n\x0frepeated_sint64\x18\x06 \x03(\x12\x42\x02\x10\x00\x12\x1c\n\x10repeated_fixed32\x18\x07 \x03(\x07\x42\x02\x10\x00\x12\x1c\n\x10repeated_fixed64\x18\x08 \x03(\x06\x42\x02\x10\x00\x12\x1d\n\x11repeated_sfixed32\x18\t \x03(\x0f\x42\x02\x10\x00\x12\x1d\n\x11repeated_sfixed64\x18\n \x03(\x10\x42\x02\x10\x00\x12\x1a\n\x0erepeated_float\x18\x0b \x03(\x02\x42\x02\x10\x00\x12\x1b\n\x0frepeated_double\x18\x0c \x03(\x01\x42\x02\x10\x00\x12\x19\n\rrepeated_bool\x18\r \x03(\x08\x42\x02\x10\x00\x12]\n\x14repeated_nested_enum\x18\x0e \x03(\x0e\x32;.google.protobuf.python.internal.TestPackedTypes.NestedEnumB\x02\x10\x00\x62\x06proto3')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+_TESTPACKEDTYPES_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='google.protobuf.python.internal.TestPackedTypes.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='FOO', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAR', index=1, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAZ', index=2, number=2,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=522,
+  serialized_end=561,
+)
+_sym_db.RegisterEnumDescriptor(_TESTPACKEDTYPES_NESTEDENUM)
+
+
+_TESTPACKEDTYPES = _descriptor.Descriptor(
+  name='TestPackedTypes',
+  full_name='google.protobuf.python.internal.TestPackedTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='repeated_int32', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_int32', index=0,
+      number=1, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_int64', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_int64', index=1,
+      number=2, type=3, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint32', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_uint32', index=2,
+      number=3, type=13, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint64', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_uint64', index=3,
+      number=4, type=4, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sint32', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_sint32', index=4,
+      number=5, type=17, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sint64', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_sint64', index=5,
+      number=6, type=18, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed32', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_fixed32', index=6,
+      number=7, type=7, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed64', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_fixed64', index=7,
+      number=8, type=6, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sfixed32', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_sfixed32', index=8,
+      number=9, type=15, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sfixed64', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_sfixed64', index=9,
+      number=10, type=16, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_float', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_float', index=10,
+      number=11, type=2, cpp_type=6, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_double', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_double', index=11,
+      number=12, type=1, cpp_type=5, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_bool', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_bool', index=12,
+      number=13, type=8, cpp_type=7, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_nested_enum', full_name='google.protobuf.python.internal.TestPackedTypes.repeated_nested_enum', index=13,
+      number=14, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _TESTPACKEDTYPES_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=86,
+  serialized_end=561,
+)
+
+
+_TESTUNPACKEDTYPES = _descriptor.Descriptor(
+  name='TestUnpackedTypes',
+  full_name='google.protobuf.python.internal.TestUnpackedTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='repeated_int32', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_int32', index=0,
+      number=1, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_int64', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_int64', index=1,
+      number=2, type=3, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint32', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_uint32', index=2,
+      number=3, type=13, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint64', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_uint64', index=3,
+      number=4, type=4, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_sint32', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_sint32', index=4,
+      number=5, type=17, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_sint64', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_sint64', index=5,
+      number=6, type=18, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed32', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_fixed32', index=6,
+      number=7, type=7, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed64', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_fixed64', index=7,
+      number=8, type=6, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_sfixed32', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_sfixed32', index=8,
+      number=9, type=15, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_sfixed64', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_sfixed64', index=9,
+      number=10, type=16, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_float', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_float', index=10,
+      number=11, type=2, cpp_type=6, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_double', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_double', index=11,
+      number=12, type=1, cpp_type=5, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_bool', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_bool', index=12,
+      number=13, type=8, cpp_type=7, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_nested_enum', full_name='google.protobuf.python.internal.TestUnpackedTypes.repeated_nested_enum', index=13,
+      number=14, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=564,
+  serialized_end=1056,
+)
+
+_TESTPACKEDTYPES.fields_by_name['repeated_nested_enum'].enum_type = _TESTPACKEDTYPES_NESTEDENUM
+_TESTPACKEDTYPES_NESTEDENUM.containing_type = _TESTPACKEDTYPES
+_TESTUNPACKEDTYPES.fields_by_name['repeated_nested_enum'].enum_type = _TESTPACKEDTYPES_NESTEDENUM
+DESCRIPTOR.message_types_by_name['TestPackedTypes'] = _TESTPACKEDTYPES
+DESCRIPTOR.message_types_by_name['TestUnpackedTypes'] = _TESTUNPACKEDTYPES
+
+TestPackedTypes = _reflection.GeneratedProtocolMessageType('TestPackedTypes', (_message.Message,), dict(
+  DESCRIPTOR = _TESTPACKEDTYPES,
+  __module__ = 'google.protobuf.internal.packed_field_test_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.TestPackedTypes)
+  ))
+_sym_db.RegisterMessage(TestPackedTypes)
+
+TestUnpackedTypes = _reflection.GeneratedProtocolMessageType('TestUnpackedTypes', (_message.Message,), dict(
+  DESCRIPTOR = _TESTUNPACKEDTYPES,
+  __module__ = 'google.protobuf.internal.packed_field_test_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.TestUnpackedTypes)
+  ))
+_sym_db.RegisterMessage(TestUnpackedTypes)
+
+
+_TESTUNPACKEDTYPES.fields_by_name['repeated_int32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_int32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_int64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_int64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_uint32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_uint32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_uint64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_uint64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sint32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sint32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sint64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sint64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_fixed32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_fixed32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_fixed64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_fixed64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sfixed32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sfixed32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sfixed64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sfixed64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_float'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_float']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_double'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_double']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_bool'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_bool']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_nested_enum'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_nested_enum']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/proto_builder_test.py b/generator/google/protobuf/internal/proto_builder_test.py
new file mode 100644
index 0000000..36dfbfd
--- /dev/null
+++ b/generator/google/protobuf/internal/proto_builder_test.py
@@ -0,0 +1,96 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Tests for google.protobuf.proto_builder."""
+
+try:
+    from collections import OrderedDict
+except ImportError:
+    from ordereddict import OrderedDict  #PY26
+try:
+  import unittest2 as unittest
+except ImportError:
+  import unittest
+
+from google.protobuf import descriptor_pb2
+from google.protobuf import descriptor_pool
+from google.protobuf import proto_builder
+from google.protobuf import text_format
+
+
+class ProtoBuilderTest(unittest.TestCase):
+
+  def setUp(self):
+    self.ordered_fields = OrderedDict([
+        ('foo', descriptor_pb2.FieldDescriptorProto.TYPE_INT64),
+        ('bar', descriptor_pb2.FieldDescriptorProto.TYPE_STRING),
+        ])
+    self._fields = dict(self.ordered_fields)
+
+  def testMakeSimpleProtoClass(self):
+    """Test that we can create a proto class."""
+    proto_cls = proto_builder.MakeSimpleProtoClass(
+        self._fields,
+        full_name='net.proto2.python.public.proto_builder_test.Test')
+    proto = proto_cls()
+    proto.foo = 12345
+    proto.bar = 'asdf'
+    self.assertMultiLineEqual(
+        'bar: "asdf"\nfoo: 12345\n', text_format.MessageToString(proto))
+
+  def testOrderedFields(self):
+    """Test that the field order is maintained when given an OrderedDict."""
+    proto_cls = proto_builder.MakeSimpleProtoClass(
+        self.ordered_fields,
+        full_name='net.proto2.python.public.proto_builder_test.OrderedTest')
+    proto = proto_cls()
+    proto.foo = 12345
+    proto.bar = 'asdf'
+    self.assertMultiLineEqual(
+        'foo: 12345\nbar: "asdf"\n', text_format.MessageToString(proto))
+
+  def testMakeSameProtoClassTwice(self):
+    """Test that the DescriptorPool is used."""
+    pool = descriptor_pool.DescriptorPool()
+    proto_cls1 = proto_builder.MakeSimpleProtoClass(
+        self._fields,
+        full_name='net.proto2.python.public.proto_builder_test.Test',
+        pool=pool)
+    proto_cls2 = proto_builder.MakeSimpleProtoClass(
+        self._fields,
+        full_name='net.proto2.python.public.proto_builder_test.Test',
+        pool=pool)
+    self.assertIs(proto_cls1.DESCRIPTOR, proto_cls2.DESCRIPTOR)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/python_message.py b/generator/google/protobuf/internal/python_message.py
index 4bea57a..c0d0ad4 100644
--- a/generator/google/protobuf/internal/python_message.py
+++ b/generator/google/protobuf/internal/python_message.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -50,14 +50,21 @@
 
 __author__ = 'robinson@google.com (Will Robinson)'
 
-try:
-  from cStringIO import StringIO
-except ImportError:
-  from StringIO import StringIO
-import copy_reg
+from io import BytesIO
+import sys
 import struct
 import weakref
 
+import six
+try:
+  import six.moves.copyreg as copyreg
+except ImportError:
+  # On some platforms, for example gMac, we run native Python because there is
+  # nothing like hermetic Python. This means lesser control on the system and
+  # the six.moves package may be missing (is missing on 20150321 on gMac). Be
+  # extra conservative and try to load the old replacement if it fails.
+  import copy_reg as copyreg
+
 # We use "as" to avoid name collisions with variables.
 from google.protobuf.internal import containers
 from google.protobuf.internal import decoder
@@ -65,41 +72,116 @@
 from google.protobuf.internal import enum_type_wrapper
 from google.protobuf.internal import message_listener as message_listener_mod
 from google.protobuf.internal import type_checkers
+from google.protobuf.internal import well_known_types
 from google.protobuf.internal import wire_format
 from google.protobuf import descriptor as descriptor_mod
 from google.protobuf import message as message_mod
 from google.protobuf import text_format
 
 _FieldDescriptor = descriptor_mod.FieldDescriptor
+_AnyFullTypeName = 'google.protobuf.Any'
 
 
-def NewMessage(bases, descriptor, dictionary):
-  _AddClassAttributesForNestedExtensions(descriptor, dictionary)
-  _AddSlots(descriptor, dictionary)
-  return bases
+class GeneratedProtocolMessageType(type):
 
+  """Metaclass for protocol message classes created at runtime from Descriptors.
 
-def InitMessage(descriptor, cls):
-  cls._decoders_by_tag = {}
-  cls._extensions_by_name = {}
-  cls._extensions_by_number = {}
-  if (descriptor.has_options and
-      descriptor.GetOptions().message_set_wire_format):
-    cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = (
-        decoder.MessageSetItemDecoder(cls._extensions_by_number))
+  We add implementations for all methods described in the Message class.  We
+  also create properties to allow getting/setting all fields in the protocol
+  message.  Finally, we create slots to prevent users from accidentally
+  "setting" nonexistent fields in the protocol message, which then wouldn't get
+  serialized / deserialized properly.
 
-  # Attach stuff to each FieldDescriptor for quick lookup later on.
-  for field in descriptor.fields:
-    _AttachFieldHelpers(cls, field)
+  The protocol compiler currently uses this metaclass to create protocol
+  message classes at runtime.  Clients can also manually create their own
+  classes at runtime, as in this example:
 
-  _AddEnumValues(descriptor, cls)
-  _AddInitMethod(descriptor, cls)
-  _AddPropertiesForFields(descriptor, cls)
-  _AddPropertiesForExtensions(descriptor, cls)
-  _AddStaticMethods(cls)
-  _AddMessageMethods(descriptor, cls)
-  _AddPrivateHelperMethods(cls)
-  copy_reg.pickle(cls, lambda obj: (cls, (), obj.__getstate__()))
+  mydescriptor = Descriptor(.....)
+  factory = symbol_database.Default()
+  factory.pool.AddDescriptor(mydescriptor)
+  MyProtoClass = factory.GetPrototype(mydescriptor)
+  myproto_instance = MyProtoClass()
+  myproto.foo_field = 23
+  ...
+  """
+
+  # Must be consistent with the protocol-compiler code in
+  # proto2/compiler/internal/generator.*.
+  _DESCRIPTOR_KEY = 'DESCRIPTOR'
+
+  def __new__(cls, name, bases, dictionary):
+    """Custom allocation for runtime-generated class types.
+
+    We override __new__ because this is apparently the only place
+    where we can meaningfully set __slots__ on the class we're creating(?).
+    (The interplay between metaclasses and slots is not very well-documented).
+
+    Args:
+      name: Name of the class (ignored, but required by the
+        metaclass protocol).
+      bases: Base classes of the class we're constructing.
+        (Should be message.Message).  We ignore this field, but
+        it's required by the metaclass protocol
+      dictionary: The class dictionary of the class we're
+        constructing.  dictionary[_DESCRIPTOR_KEY] must contain
+        a Descriptor object describing this protocol message
+        type.
+
+    Returns:
+      Newly-allocated class.
+    """
+    descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
+    if descriptor.full_name in well_known_types.WKTBASES:
+      bases += (well_known_types.WKTBASES[descriptor.full_name],)
+    _AddClassAttributesForNestedExtensions(descriptor, dictionary)
+    _AddSlots(descriptor, dictionary)
+
+    superclass = super(GeneratedProtocolMessageType, cls)
+    new_class = superclass.__new__(cls, name, bases, dictionary)
+    return new_class
+
+  def __init__(cls, name, bases, dictionary):
+    """Here we perform the majority of our work on the class.
+    We add enum getters, an __init__ method, implementations
+    of all Message methods, and properties for all fields
+    in the protocol type.
+
+    Args:
+      name: Name of the class (ignored, but required by the
+        metaclass protocol).
+      bases: Base classes of the class we're constructing.
+        (Should be message.Message).  We ignore this field, but
+        it's required by the metaclass protocol
+      dictionary: The class dictionary of the class we're
+        constructing.  dictionary[_DESCRIPTOR_KEY] must contain
+        a Descriptor object describing this protocol message
+        type.
+    """
+    descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
+    cls._decoders_by_tag = {}
+    cls._extensions_by_name = {}
+    cls._extensions_by_number = {}
+    if (descriptor.has_options and
+        descriptor.GetOptions().message_set_wire_format):
+      cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = (
+          decoder.MessageSetItemDecoder(cls._extensions_by_number), None)
+
+    # Attach stuff to each FieldDescriptor for quick lookup later on.
+    for field in descriptor.fields:
+      _AttachFieldHelpers(cls, field)
+
+    descriptor._concrete_class = cls  # pylint: disable=protected-access
+    _AddEnumValues(descriptor, cls)
+    _AddInitMethod(descriptor, cls)
+    _AddPropertiesForFields(descriptor, cls)
+    _AddPropertiesForExtensions(descriptor, cls)
+    _AddStaticMethods(cls)
+    _AddMessageMethods(descriptor, cls)
+    _AddPrivateHelperMethods(descriptor, cls)
+    copyreg.pickle(cls, lambda obj: (cls, (), obj.__getstate__()))
+
+    superclass = super(GeneratedProtocolMessageType, cls)
+    superclass.__init__(name, bases, dictionary)
 
 
 # Stateless helpers for GeneratedProtocolMessageType below.
@@ -176,7 +258,8 @@
                              '_is_present_in_parent',
                              '_listener',
                              '_listener_for_children',
-                             '__weakref__']
+                             '__weakref__',
+                             '_oneofs']
 
 
 def _IsMessageSetExtension(field):
@@ -184,16 +267,40 @@
           field.containing_type.has_options and
           field.containing_type.GetOptions().message_set_wire_format and
           field.type == _FieldDescriptor.TYPE_MESSAGE and
-          field.message_type == field.extension_scope and
           field.label == _FieldDescriptor.LABEL_OPTIONAL)
 
 
+def _IsMapField(field):
+  return (field.type == _FieldDescriptor.TYPE_MESSAGE and
+          field.message_type.has_options and
+          field.message_type.GetOptions().map_entry)
+
+
+def _IsMessageMapField(field):
+  value_type = field.message_type.fields_by_name["value"]
+  return value_type.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE
+
+
 def _AttachFieldHelpers(cls, field_descriptor):
   is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED)
-  is_packed = (field_descriptor.has_options and
-               field_descriptor.GetOptions().packed)
+  is_packable = (is_repeated and
+                 wire_format.IsTypePackable(field_descriptor.type))
+  if not is_packable:
+    is_packed = False
+  elif field_descriptor.containing_type.syntax == "proto2":
+    is_packed = (field_descriptor.has_options and
+                field_descriptor.GetOptions().packed)
+  else:
+    has_packed_false = (field_descriptor.has_options and
+                        field_descriptor.GetOptions().HasField("packed") and
+                        field_descriptor.GetOptions().packed == False)
+    is_packed = not has_packed_false
+  is_map_entry = _IsMapField(field_descriptor)
 
-  if _IsMessageSetExtension(field_descriptor):
+  if is_map_entry:
+    field_encoder = encoder.MapEncoder(field_descriptor)
+    sizer = encoder.MapSizer(field_descriptor)
+  elif _IsMessageSetExtension(field_descriptor):
     field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number)
     sizer = encoder.MessageSetItemSizer(field_descriptor.number)
   else:
@@ -209,10 +316,27 @@
 
   def AddDecoder(wiretype, is_packed):
     tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype)
-    cls._decoders_by_tag[tag_bytes] = (
-        type_checkers.TYPE_TO_DECODER[field_descriptor.type](
-            field_descriptor.number, is_repeated, is_packed,
-            field_descriptor, field_descriptor._default_constructor))
+    decode_type = field_descriptor.type
+    if (decode_type == _FieldDescriptor.TYPE_ENUM and
+        type_checkers.SupportsOpenEnums(field_descriptor)):
+      decode_type = _FieldDescriptor.TYPE_INT32
+
+    oneof_descriptor = None
+    if field_descriptor.containing_oneof is not None:
+      oneof_descriptor = field_descriptor
+
+    if is_map_entry:
+      is_message_map = _IsMessageMapField(field_descriptor)
+
+      field_decoder = decoder.MapDecoder(
+          field_descriptor, _GetInitializeDefaultForMap(field_descriptor),
+          is_message_map)
+    else:
+      field_decoder = type_checkers.TYPE_TO_DECODER[decode_type](
+              field_descriptor.number, is_repeated, is_packed,
+              field_descriptor, field_descriptor._default_constructor)
+
+    cls._decoders_by_tag[tag_bytes] = (field_decoder, oneof_descriptor)
 
   AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type],
              False)
@@ -225,7 +349,7 @@
 
 def _AddClassAttributesForNestedExtensions(descriptor, dictionary):
   extension_dict = descriptor.extensions_by_name
-  for extension_name, extension_field in extension_dict.iteritems():
+  for extension_name, extension_field in extension_dict.items():
     assert extension_name not in dictionary
     dictionary[extension_name] = extension_field
 
@@ -245,6 +369,26 @@
       setattr(cls, enum_value.name, enum_value.number)
 
 
+def _GetInitializeDefaultForMap(field):
+  if field.label != _FieldDescriptor.LABEL_REPEATED:
+    raise ValueError('map_entry set on non-repeated field %s' % (
+        field.name))
+  fields_by_name = field.message_type.fields_by_name
+  key_checker = type_checkers.GetTypeChecker(fields_by_name['key'])
+
+  value_field = fields_by_name['value']
+  if _IsMessageMapField(field):
+    def MakeMessageMapDefault(message):
+      return containers.MessageMap(
+          message._listener_for_children, value_field.message_type, key_checker)
+    return MakeMessageMapDefault
+  else:
+    value_checker = type_checkers.GetTypeChecker(value_field)
+    def MakePrimitiveMapDefault(message):
+      return containers.ScalarMap(
+          message._listener_for_children, key_checker, value_checker)
+    return MakePrimitiveMapDefault
+
 def _DefaultValueConstructorForField(field):
   """Returns a function which returns a default value for a field.
 
@@ -259,6 +403,9 @@
     value may refer back to |message| via a weak reference.
   """
 
+  if _IsMapField(field):
+    return _GetInitializeDefaultForMap(field)
+
   if field.label == _FieldDescriptor.LABEL_REPEATED:
     if field.has_default_value and field.default_value != []:
       raise ValueError('Repeated field default value not empty list: %s' % (
@@ -272,7 +419,7 @@
             message._listener_for_children, field.message_type)
       return MakeRepeatedMessageDefault
     else:
-      type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type)
+      type_checker = type_checkers.GetTypeChecker(field)
       def MakeRepeatedScalarDefault(message):
         return containers.RepeatedScalarFieldContainer(
             message._listener_for_children, type_checker)
@@ -283,7 +430,10 @@
     message_type = field.message_type
     def MakeSubMessageDefault(message):
       result = message_type._concrete_class()
-      result._SetListener(message._listener_for_children)
+      result._SetListener(
+          _OneofListener(message, field)
+          if field.containing_oneof is not None
+          else message._listener_for_children)
       return result
     return MakeSubMessageDefault
 
@@ -294,38 +444,95 @@
   return MakeScalarDefault
 
 
+def _ReraiseTypeErrorWithFieldName(message_name, field_name):
+  """Re-raise the currently-handled TypeError with the field name added."""
+  exc = sys.exc_info()[1]
+  if len(exc.args) == 1 and type(exc) is TypeError:
+    # simple TypeError; add field name to exception message
+    exc = TypeError('%s for field %s.%s' % (str(exc), message_name, field_name))
+
+  # re-raise possibly-amended exception with original traceback:
+  six.reraise(type(exc), exc, sys.exc_info()[2])
+
+
 def _AddInitMethod(message_descriptor, cls):
   """Adds an __init__ method to cls."""
-  fields = message_descriptor.fields
+
+  def _GetIntegerEnumValue(enum_type, value):
+    """Convert a string or integer enum value to an integer.
+
+    If the value is a string, it is converted to the enum value in
+    enum_type with the same name.  If the value is not a string, it's
+    returned as-is.  (No conversion or bounds-checking is done.)
+    """
+    if isinstance(value, six.string_types):
+      try:
+        return enum_type.values_by_name[value].number
+      except KeyError:
+        raise ValueError('Enum type %s: unknown label "%s"' % (
+            enum_type.full_name, value))
+    return value
+
   def init(self, **kwargs):
     self._cached_byte_size = 0
     self._cached_byte_size_dirty = len(kwargs) > 0
     self._fields = {}
+    # Contains a mapping from oneof field descriptors to the descriptor
+    # of the currently set field in that oneof field.
+    self._oneofs = {}
+
     # _unknown_fields is () when empty for efficiency, and will be turned into
     # a list if fields are added.
     self._unknown_fields = ()
     self._is_present_in_parent = False
     self._listener = message_listener_mod.NullMessageListener()
     self._listener_for_children = _Listener(self)
-    for field_name, field_value in kwargs.iteritems():
+    for field_name, field_value in kwargs.items():
       field = _GetFieldByName(message_descriptor, field_name)
       if field is None:
         raise TypeError("%s() got an unexpected keyword argument '%s'" %
                         (message_descriptor.name, field_name))
+      if field_value is None:
+        # field=None is the same as no field at all.
+        continue
       if field.label == _FieldDescriptor.LABEL_REPEATED:
         copy = field._default_constructor(self)
         if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:  # Composite
-          for val in field_value:
-            copy.add().MergeFrom(val)
+          if _IsMapField(field):
+            if _IsMessageMapField(field):
+              for key in field_value:
+                copy[key].MergeFrom(field_value[key])
+            else:
+              copy.update(field_value)
+          else:
+            for val in field_value:
+              if isinstance(val, dict):
+                copy.add(**val)
+              else:
+                copy.add().MergeFrom(val)
         else:  # Scalar
+          if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM:
+            field_value = [_GetIntegerEnumValue(field.enum_type, val)
+                           for val in field_value]
           copy.extend(field_value)
         self._fields[field] = copy
       elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
         copy = field._default_constructor(self)
-        copy.MergeFrom(field_value)
+        new_val = field_value
+        if isinstance(field_value, dict):
+          new_val = field.message_type._concrete_class(**field_value)
+        try:
+          copy.MergeFrom(new_val)
+        except TypeError:
+          _ReraiseTypeErrorWithFieldName(message_descriptor.name, field_name)
         self._fields[field] = copy
       else:
-        setattr(self, field_name, field_value)
+        if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM:
+          field_value = _GetIntegerEnumValue(field.enum_type, field_value)
+        try:
+          setattr(self, field_name, field_value)
+        except TypeError:
+          _ReraiseTypeErrorWithFieldName(message_descriptor.name, field_name)
 
   init.__module__ = None
   init.__doc__ = None
@@ -344,7 +551,8 @@
   try:
     return message_descriptor.fields_by_name[field_name]
   except KeyError:
-    raise ValueError('Protocol message has no "%s" field.' % field_name)
+    raise ValueError('Protocol message %s has no "%s" field.' %
+                     (message_descriptor.name, field_name))
 
 
 def _AddPropertiesForFields(descriptor, cls):
@@ -440,9 +648,10 @@
   """
   proto_field_name = field.name
   property_name = _PropertyName(proto_field_name)
-  type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type)
+  type_checker = type_checkers.GetTypeChecker(field)
   default_value = field.default_value
   valid_values = set()
+  is_proto3 = field.containing_type.syntax == "proto3"
 
   def getter(self):
     # TODO(protobuf-team): This may be broken since there may not be
@@ -450,14 +659,30 @@
     return self._fields.get(field, default_value)
   getter.__module__ = None
   getter.__doc__ = 'Getter for %s.' % proto_field_name
-  def setter(self, new_value):
-    type_checker.CheckValue(new_value)
-    self._fields[field] = new_value
+
+  clear_when_set_to_default = is_proto3 and not field.containing_oneof
+
+  def field_setter(self, new_value):
+    # pylint: disable=protected-access
+    # Testing the value for truthiness captures all of the proto3 defaults
+    # (0, 0.0, enum 0, and False).
+    new_value = type_checker.CheckValue(new_value)
+    if clear_when_set_to_default and not new_value:
+      self._fields.pop(field, None)
+    else:
+      self._fields[field] = new_value
     # Check _cached_byte_size_dirty inline to improve performance, since scalar
     # setters are called frequently.
     if not self._cached_byte_size_dirty:
       self._Modified()
 
+  if field.containing_oneof:
+    def setter(self, new_value):
+      field_setter(self, new_value)
+      self._UpdateOneofState(field)
+  else:
+    setter = field_setter
+
   setter.__module__ = None
   setter.__doc__ = 'Setter for %s.' % proto_field_name
 
@@ -482,18 +707,11 @@
   proto_field_name = field.name
   property_name = _PropertyName(proto_field_name)
 
-  # TODO(komarek): Can anyone explain to me why we cache the message_type this
-  # way, instead of referring to field.message_type inside of getter(self)?
-  # What if someone sets message_type later on (which makes for simpler
-  # dyanmic proto descriptor and class creation code).
-  message_type = field.message_type
-
   def getter(self):
     field_value = self._fields.get(field)
     if field_value is None:
       # Construct a new object to represent this field.
-      field_value = message_type._concrete_class()  # use field.message_type?
-      field_value._SetListener(self._listener_for_children)
+      field_value = field._default_constructor(self)
 
       # Atomically check if another thread has preempted us and, if not, swap
       # in the new object we just created.  If someone has preempted us, we
@@ -520,7 +738,7 @@
 def _AddPropertiesForExtensions(descriptor, cls):
   """Adds properties for all fields in this protocol message type."""
   extension_dict = descriptor.extensions_by_name
-  for extension_name, extension_field in extension_dict.iteritems():
+  for extension_name, extension_field in extension_dict.items():
     constant_name = extension_name.upper() + "_FIELD_NUMBER"
     setattr(cls, constant_name, extension_field.number)
 
@@ -575,33 +793,54 @@
   """Helper for _AddMessageMethods()."""
 
   def ListFields(self):
-    all_fields = [item for item in self._fields.iteritems() if _IsPresent(item)]
+    all_fields = [item for item in self._fields.items() if _IsPresent(item)]
     all_fields.sort(key = lambda item: item[0].number)
     return all_fields
 
   cls.ListFields = ListFields
 
+_Proto3HasError = 'Protocol message has no non-repeated submessage field "%s"'
+_Proto2HasError = 'Protocol message has no non-repeated field "%s"'
 
 def _AddHasFieldMethod(message_descriptor, cls):
   """Helper for _AddMessageMethods()."""
 
-  singular_fields = {}
+  is_proto3 = (message_descriptor.syntax == "proto3")
+  error_msg = _Proto3HasError if is_proto3 else _Proto2HasError
+
+  hassable_fields = {}
   for field in message_descriptor.fields:
-    if field.label != _FieldDescriptor.LABEL_REPEATED:
-      singular_fields[field.name] = field
+    if field.label == _FieldDescriptor.LABEL_REPEATED:
+      continue
+    # For proto3, only submessages and fields inside a oneof have presence.
+    if (is_proto3 and field.cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE and
+        not field.containing_oneof):
+      continue
+    hassable_fields[field.name] = field
+
+  if not is_proto3:
+    # Fields inside oneofs are never repeated (enforced by the compiler).
+    for oneof in message_descriptor.oneofs:
+      hassable_fields[oneof.name] = oneof
 
   def HasField(self, field_name):
     try:
-      field = singular_fields[field_name]
+      field = hassable_fields[field_name]
     except KeyError:
-      raise ValueError(
-          'Protocol message has no singular "%s" field.' % field_name)
+      raise ValueError(error_msg % field_name)
 
-    if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
-      value = self._fields.get(field)
-      return value is not None and value._is_present_in_parent
+    if isinstance(field, descriptor_mod.OneofDescriptor):
+      try:
+        return HasField(self, self._oneofs[field].name)
+      except KeyError:
+        return False
     else:
-      return field in self._fields
+      if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+        value = self._fields.get(field)
+        return value is not None and value._is_present_in_parent
+      else:
+        return field in self._fields
+
   cls.HasField = HasField
 
 
@@ -611,14 +850,30 @@
     try:
       field = message_descriptor.fields_by_name[field_name]
     except KeyError:
-      raise ValueError('Protocol message has no "%s" field.' % field_name)
+      try:
+        field = message_descriptor.oneofs_by_name[field_name]
+        if field in self._oneofs:
+          field = self._oneofs[field]
+        else:
+          return
+      except KeyError:
+        raise ValueError('Protocol message %s() has no "%s" field.' %
+                         (message_descriptor.name, field_name))
 
     if field in self._fields:
+      # To match the C++ implementation, we need to invalidate iterators
+      # for map fields when ClearField() happens.
+      if hasattr(self._fields[field], 'InvalidateIterators'):
+        self._fields[field].InvalidateIterators()
+
       # Note:  If the field is a sub-message, its listener will still point
       #   at us.  That's fine, because the worst than can happen is that it
       #   will call _Modified() and invalidate our byte size.  Big deal.
       del self._fields[field]
 
+      if self._oneofs.get(field.containing_oneof, None) is field:
+        del self._oneofs[field.containing_oneof]
+
     # Always call _Modified() -- even if nothing was changed, this is
     # a mutating method, and thus calling it should cause the field to become
     # present in the parent message.
@@ -639,16 +894,6 @@
   cls.ClearExtension = ClearExtension
 
 
-def _AddClearMethod(message_descriptor, cls):
-  """Helper for _AddMessageMethods()."""
-  def Clear(self):
-    # Clear fields.
-    self._fields = {}
-    self._unknown_fields = ()
-    self._Modified()
-  cls.Clear = Clear
-
-
 def _AddHasExtensionMethod(cls):
   """Helper for _AddMessageMethods()."""
   def HasExtension(self, extension_handle):
@@ -663,6 +908,45 @@
       return extension_handle in self._fields
   cls.HasExtension = HasExtension
 
+def _InternalUnpackAny(msg):
+  """Unpacks Any message and returns the unpacked message.
+
+  This internal method is differnt from public Any Unpack method which takes
+  the target message as argument. _InternalUnpackAny method does not have
+  target message type and need to find the message type in descriptor pool.
+
+  Args:
+    msg: An Any message to be unpacked.
+
+  Returns:
+    The unpacked message.
+  """
+  # TODO(amauryfa): Don't use the factory of generated messages.
+  # To make Any work with custom factories, use the message factory of the
+  # parent message.
+  # pylint: disable=g-import-not-at-top
+  from google.protobuf import symbol_database
+  factory = symbol_database.Default()
+
+  type_url = msg.type_url
+
+  if not type_url:
+    return None
+
+  # TODO(haberman): For now we just strip the hostname.  Better logic will be
+  # required.
+  type_name = type_url.split('/')[-1]
+  descriptor = factory.pool.FindMessageTypeByName(type_name)
+
+  if descriptor is None:
+    return None
+
+  message_class = factory.GetPrototype(descriptor)
+  message = message_class()
+
+  message.ParseFromString(msg.value)
+  return message
+
 
 def _AddEqualsMethod(message_descriptor, cls):
   """Helper for _AddMessageMethods()."""
@@ -674,6 +958,12 @@
     if self is other:
       return True
 
+    if self.DESCRIPTOR.full_name == _AnyFullTypeName:
+      any_a = _InternalUnpackAny(self)
+      any_b = _InternalUnpackAny(other)
+      if any_a and any_b:
+        return any_a == any_b
+
     if not self.ListFields() == other.ListFields():
       return False
 
@@ -695,6 +985,13 @@
   cls.__str__ = __str__
 
 
+def _AddReprMethod(message_descriptor, cls):
+  """Helper for _AddMessageMethods()."""
+  def __repr__(self):
+    return text_format.MessageToString(self)
+  cls.__repr__ = __repr__
+
+
 def _AddUnicodeMethod(unused_message_descriptor, cls):
   """Helper for _AddMessageMethods()."""
 
@@ -703,16 +1000,6 @@
   cls.__unicode__ = __unicode__
 
 
-def _AddSetListenerMethod(cls):
-  """Helper for _AddMessageMethods()."""
-  def SetListener(self, listener):
-    if listener is None:
-      self._listener = message_listener_mod.NullMessageListener()
-    else:
-      self._listener = listener
-  cls._SetListener = SetListener
-
-
 def _BytesForNonRepeatedElement(value, field_number, field_type):
   """Returns the number of bytes needed to serialize a non-repeated element.
   The returned byte count includes space for tag information and any
@@ -773,7 +1060,7 @@
   """Helper for _AddMessageMethods()."""
 
   def SerializePartialToString(self):
-    out = StringIO()
+    out = BytesIO()
     self._InternalSerialize(out.write)
     return out.getvalue()
   cls.SerializePartialToString = SerializePartialToString
@@ -796,9 +1083,10 @@
         # The only reason _InternalParse would return early is if it
         # encountered an end-group tag.
         raise message_mod.DecodeError('Unexpected end-group tag.')
-    except IndexError:
+    except (IndexError, TypeError):
+      # Now ord(buf[p:p+1]) == ord('') gets TypeError.
       raise message_mod.DecodeError('Truncated message.')
-    except struct.error, e:
+    except struct.error as e:
       raise message_mod.DecodeError(e)
     return length   # Return this for legacy reasons.
   cls.MergeFromString = MergeFromString
@@ -806,6 +1094,7 @@
   local_ReadTag = decoder.ReadTag
   local_SkipField = decoder.SkipField
   decoders_by_tag = cls._decoders_by_tag
+  is_proto3 = message_descriptor.syntax == "proto3"
 
   def InternalParse(self, buffer, pos, end):
     self._Modified()
@@ -813,18 +1102,22 @@
     unknown_field_list = self._unknown_fields
     while pos != end:
       (tag_bytes, new_pos) = local_ReadTag(buffer, pos)
-      field_decoder = decoders_by_tag.get(tag_bytes)
+      field_decoder, field_desc = decoders_by_tag.get(tag_bytes, (None, None))
       if field_decoder is None:
         value_start_pos = new_pos
         new_pos = local_SkipField(buffer, new_pos, end, tag_bytes)
         if new_pos == -1:
           return pos
-        if not unknown_field_list:
-          unknown_field_list = self._unknown_fields = []
-        unknown_field_list.append((tag_bytes, buffer[value_start_pos:new_pos]))
+        if not is_proto3:
+          if not unknown_field_list:
+            unknown_field_list = self._unknown_fields = []
+          unknown_field_list.append(
+              (tag_bytes, buffer[value_start_pos:new_pos]))
         pos = new_pos
       else:
         pos = field_decoder(buffer, new_pos, end, self, field_dict)
+        if field_desc:
+          self._UpdateOneofState(field_desc)
     return pos
   cls._InternalParse = InternalParse
 
@@ -857,9 +1150,12 @@
           errors.extend(self.FindInitializationErrors())
         return False
 
-    for field, value in self._fields.iteritems():
+    for field, value in list(self._fields.items()):  # dict can change size!
       if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
         if field.label == _FieldDescriptor.LABEL_REPEATED:
+          if (field.message_type.has_options and
+              field.message_type.GetOptions().map_entry):
+            continue
           for element in value:
             if not element.IsInitialized():
               if errors is not None:
@@ -895,16 +1191,26 @@
         else:
           name = field.name
 
-        if field.label == _FieldDescriptor.LABEL_REPEATED:
-          for i in xrange(len(value)):
+        if _IsMapField(field):
+          if _IsMessageMapField(field):
+            for key in value:
+              element = value[key]
+              prefix = "%s[%s]." % (name, key)
+              sub_errors = element.FindInitializationErrors()
+              errors += [prefix + error for error in sub_errors]
+          else:
+            # ScalarMaps can't have any initialization errors.
+            pass
+        elif field.label == _FieldDescriptor.LABEL_REPEATED:
+          for i in range(len(value)):
             element = value[i]
             prefix = "%s[%d]." % (name, i)
             sub_errors = element.FindInitializationErrors()
-            errors += [ prefix + error for error in sub_errors ]
+            errors += [prefix + error for error in sub_errors]
         else:
           prefix = name + "."
           sub_errors = value.FindInitializationErrors()
-          errors += [ prefix + error for error in sub_errors ]
+          errors += [prefix + error for error in sub_errors]
 
     return errors
 
@@ -926,7 +1232,7 @@
 
     fields = self._fields
 
-    for field, value in msg._fields.iteritems():
+    for field, value in msg._fields.items():
       if field.label == LABEL_REPEATED:
         field_value = fields.get(field)
         if field_value is None:
@@ -944,6 +1250,8 @@
           field_value.MergeFrom(value)
       else:
         self._fields[field] = value
+        if field.containing_oneof:
+          self._UpdateOneofState(field)
 
     if msg._unknown_fields:
       if not self._unknown_fields:
@@ -953,6 +1261,50 @@
   cls.MergeFrom = MergeFrom
 
 
+def _AddWhichOneofMethod(message_descriptor, cls):
+  def WhichOneof(self, oneof_name):
+    """Returns the name of the currently set field inside a oneof, or None."""
+    try:
+      field = message_descriptor.oneofs_by_name[oneof_name]
+    except KeyError:
+      raise ValueError(
+          'Protocol message has no oneof "%s" field.' % oneof_name)
+
+    nested_field = self._oneofs.get(field, None)
+    if nested_field is not None and self.HasField(nested_field.name):
+      return nested_field.name
+    else:
+      return None
+
+  cls.WhichOneof = WhichOneof
+
+
+def _Clear(self):
+  # Clear fields.
+  self._fields = {}
+  self._unknown_fields = ()
+  self._oneofs = {}
+  self._Modified()
+
+
+def _DiscardUnknownFields(self):
+  self._unknown_fields = []
+  for field, value in self.ListFields():
+    if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+      if field.label == _FieldDescriptor.LABEL_REPEATED:
+        for sub_message in value:
+          sub_message.DiscardUnknownFields()
+      else:
+        value.DiscardUnknownFields()
+
+
+def _SetListener(self, listener):
+  if listener is None:
+    self._listener = message_listener_mod.NullMessageListener()
+  else:
+    self._listener = listener
+
+
 def _AddMessageMethods(message_descriptor, cls):
   """Adds implementations of all Message methods to cls."""
   _AddListFieldsMethod(message_descriptor, cls)
@@ -961,20 +1313,24 @@
   if message_descriptor.is_extendable:
     _AddClearExtensionMethod(cls)
     _AddHasExtensionMethod(cls)
-  _AddClearMethod(message_descriptor, cls)
   _AddEqualsMethod(message_descriptor, cls)
   _AddStrMethod(message_descriptor, cls)
+  _AddReprMethod(message_descriptor, cls)
   _AddUnicodeMethod(message_descriptor, cls)
-  _AddSetListenerMethod(cls)
   _AddByteSizeMethod(message_descriptor, cls)
   _AddSerializeToStringMethod(message_descriptor, cls)
   _AddSerializePartialToStringMethod(message_descriptor, cls)
   _AddMergeFromStringMethod(message_descriptor, cls)
   _AddIsInitializedMethod(message_descriptor, cls)
   _AddMergeFromMethod(cls)
+  _AddWhichOneofMethod(message_descriptor, cls)
+  # Adds methods which do not depend on cls.
+  cls.Clear = _Clear
+  cls.DiscardUnknownFields = _DiscardUnknownFields
+  cls._SetListener = _SetListener
 
 
-def _AddPrivateHelperMethods(cls):
+def _AddPrivateHelperMethods(message_descriptor, cls):
   """Adds implementation of private helper methods to cls."""
 
   def Modified(self):
@@ -992,8 +1348,20 @@
       self._is_present_in_parent = True
       self._listener.Modified()
 
+  def _UpdateOneofState(self, field):
+    """Sets field as the active field in its containing oneof.
+
+    Will also delete currently active field in the oneof, if it is different
+    from the argument. Does not mark the message as modified.
+    """
+    other_field = self._oneofs.setdefault(field.containing_oneof, field)
+    if other_field is not field:
+      del self._fields[other_field]
+      self._oneofs[field.containing_oneof] = field
+
   cls._Modified = Modified
   cls.SetInParent = Modified
+  cls._UpdateOneofState = _UpdateOneofState
 
 
 class _Listener(object):
@@ -1042,6 +1410,27 @@
       pass
 
 
+class _OneofListener(_Listener):
+  """Special listener implementation for setting composite oneof fields."""
+
+  def __init__(self, parent_message, field):
+    """Args:
+      parent_message: The message whose _Modified() method we should call when
+        we receive Modified() messages.
+      field: The descriptor of the field being set in the parent message.
+    """
+    super(_OneofListener, self).__init__(parent_message)
+    self._field = field
+
+  def Modified(self):
+    """Also updates the state of the containing oneof in the parent message."""
+    try:
+      self._parent_message_weakref._UpdateOneofState(self._field)
+      super(_OneofListener, self).Modified()
+    except ReferenceError:
+      pass
+
+
 # TODO(robinson): Move elsewhere?  This file is getting pretty ridiculous...
 # TODO(robinson): Unify error handling of "unknown extension" crap.
 # TODO(robinson): Support iteritems()-style iteration over all
@@ -1132,10 +1521,10 @@
 
     # It's slightly wasteful to lookup the type checker each time,
     # but we expect this to be a vanishingly uncommon case anyway.
-    type_checker = type_checkers.GetTypeChecker(
-        extension_handle.cpp_type, extension_handle.type)
-    type_checker.CheckValue(value)
-    self._extended_message._fields[extension_handle] = value
+    type_checker = type_checkers.GetTypeChecker(extension_handle)
+    # pylint: disable=protected-access
+    self._extended_message._fields[extension_handle] = (
+        type_checker.CheckValue(value))
     self._extended_message._Modified()
 
   def _FindExtensionByName(self, name):
@@ -1148,3 +1537,14 @@
       Extension field descriptor.
     """
     return self._extended_message._extensions_by_name.get(name, None)
+
+  def _FindExtensionByNumber(self, number):
+    """Tries to find a known extension with the field number.
+
+    Args:
+      number: Extension field number.
+
+    Returns:
+      Extension field descriptor.
+    """
+    return self._extended_message._extensions_by_number.get(number, None)
diff --git a/generator/google/protobuf/internal/reflection_test.py b/generator/google/protobuf/internal/reflection_test.py
new file mode 100644
index 0000000..6f3b818
--- /dev/null
+++ b/generator/google/protobuf/internal/reflection_test.py
@@ -0,0 +1,2984 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# 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.
+
+"""Unittest for reflection.py, which also indirectly tests the output of the
+pure-Python protocol compiler.
+"""
+
+import copy
+import gc
+import operator
+import six
+import struct
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_mset_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import descriptor_pb2
+from google.protobuf import descriptor
+from google.protobuf import message
+from google.protobuf import reflection
+from google.protobuf import text_format
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import more_extensions_pb2
+from google.protobuf.internal import more_messages_pb2
+from google.protobuf.internal import message_set_extensions_pb2
+from google.protobuf.internal import wire_format
+from google.protobuf.internal import test_util
+from google.protobuf.internal import decoder
+
+
+class _MiniDecoder(object):
+  """Decodes a stream of values from a string.
+
+  Once upon a time we actually had a class called decoder.Decoder.  Then we
+  got rid of it during a redesign that made decoding much, much faster overall.
+  But a couple tests in this file used it to check that the serialized form of
+  a message was correct.  So, this class implements just the methods that were
+  used by said tests, so that we don't have to rewrite the tests.
+  """
+
+  def __init__(self, bytes):
+    self._bytes = bytes
+    self._pos = 0
+
+  def ReadVarint(self):
+    result, self._pos = decoder._DecodeVarint(self._bytes, self._pos)
+    return result
+
+  ReadInt32 = ReadVarint
+  ReadInt64 = ReadVarint
+  ReadUInt32 = ReadVarint
+  ReadUInt64 = ReadVarint
+
+  def ReadSInt64(self):
+    return wire_format.ZigZagDecode(self.ReadVarint())
+
+  ReadSInt32 = ReadSInt64
+
+  def ReadFieldNumberAndWireType(self):
+    return wire_format.UnpackTag(self.ReadVarint())
+
+  def ReadFloat(self):
+    result = struct.unpack("<f", self._bytes[self._pos:self._pos+4])[0]
+    self._pos += 4
+    return result
+
+  def ReadDouble(self):
+    result = struct.unpack("<d", self._bytes[self._pos:self._pos+8])[0]
+    self._pos += 8
+    return result
+
+  def EndOfStream(self):
+    return self._pos == len(self._bytes)
+
+
+class ReflectionTest(unittest.TestCase):
+
+  def assertListsEqual(self, values, others):
+    self.assertEqual(len(values), len(others))
+    for i in range(len(values)):
+      self.assertEqual(values[i], others[i])
+
+  def testScalarConstructor(self):
+    # Constructor with only scalar types should succeed.
+    proto = unittest_pb2.TestAllTypes(
+        optional_int32=24,
+        optional_double=54.321,
+        optional_string='optional_string',
+        optional_float=None)
+
+    self.assertEqual(24, proto.optional_int32)
+    self.assertEqual(54.321, proto.optional_double)
+    self.assertEqual('optional_string', proto.optional_string)
+    self.assertFalse(proto.HasField("optional_float"))
+
+  def testRepeatedScalarConstructor(self):
+    # Constructor with only repeated scalar types should succeed.
+    proto = unittest_pb2.TestAllTypes(
+        repeated_int32=[1, 2, 3, 4],
+        repeated_double=[1.23, 54.321],
+        repeated_bool=[True, False, False],
+        repeated_string=["optional_string"],
+        repeated_float=None)
+
+    self.assertEqual([1, 2, 3, 4], list(proto.repeated_int32))
+    self.assertEqual([1.23, 54.321], list(proto.repeated_double))
+    self.assertEqual([True, False, False], list(proto.repeated_bool))
+    self.assertEqual(["optional_string"], list(proto.repeated_string))
+    self.assertEqual([], list(proto.repeated_float))
+
+  def testRepeatedCompositeConstructor(self):
+    # Constructor with only repeated composite types should succeed.
+    proto = unittest_pb2.TestAllTypes(
+        repeated_nested_message=[
+            unittest_pb2.TestAllTypes.NestedMessage(
+                bb=unittest_pb2.TestAllTypes.FOO),
+            unittest_pb2.TestAllTypes.NestedMessage(
+                bb=unittest_pb2.TestAllTypes.BAR)],
+        repeated_foreign_message=[
+            unittest_pb2.ForeignMessage(c=-43),
+            unittest_pb2.ForeignMessage(c=45324),
+            unittest_pb2.ForeignMessage(c=12)],
+        repeatedgroup=[
+            unittest_pb2.TestAllTypes.RepeatedGroup(),
+            unittest_pb2.TestAllTypes.RepeatedGroup(a=1),
+            unittest_pb2.TestAllTypes.RepeatedGroup(a=2)])
+
+    self.assertEqual(
+        [unittest_pb2.TestAllTypes.NestedMessage(
+            bb=unittest_pb2.TestAllTypes.FOO),
+         unittest_pb2.TestAllTypes.NestedMessage(
+             bb=unittest_pb2.TestAllTypes.BAR)],
+        list(proto.repeated_nested_message))
+    self.assertEqual(
+        [unittest_pb2.ForeignMessage(c=-43),
+         unittest_pb2.ForeignMessage(c=45324),
+         unittest_pb2.ForeignMessage(c=12)],
+        list(proto.repeated_foreign_message))
+    self.assertEqual(
+        [unittest_pb2.TestAllTypes.RepeatedGroup(),
+         unittest_pb2.TestAllTypes.RepeatedGroup(a=1),
+         unittest_pb2.TestAllTypes.RepeatedGroup(a=2)],
+        list(proto.repeatedgroup))
+
+  def testMixedConstructor(self):
+    # Constructor with only mixed types should succeed.
+    proto = unittest_pb2.TestAllTypes(
+        optional_int32=24,
+        optional_string='optional_string',
+        repeated_double=[1.23, 54.321],
+        repeated_bool=[True, False, False],
+        repeated_nested_message=[
+            unittest_pb2.TestAllTypes.NestedMessage(
+                bb=unittest_pb2.TestAllTypes.FOO),
+            unittest_pb2.TestAllTypes.NestedMessage(
+                bb=unittest_pb2.TestAllTypes.BAR)],
+        repeated_foreign_message=[
+            unittest_pb2.ForeignMessage(c=-43),
+            unittest_pb2.ForeignMessage(c=45324),
+            unittest_pb2.ForeignMessage(c=12)],
+        optional_nested_message=None)
+
+    self.assertEqual(24, proto.optional_int32)
+    self.assertEqual('optional_string', proto.optional_string)
+    self.assertEqual([1.23, 54.321], list(proto.repeated_double))
+    self.assertEqual([True, False, False], list(proto.repeated_bool))
+    self.assertEqual(
+        [unittest_pb2.TestAllTypes.NestedMessage(
+            bb=unittest_pb2.TestAllTypes.FOO),
+         unittest_pb2.TestAllTypes.NestedMessage(
+             bb=unittest_pb2.TestAllTypes.BAR)],
+        list(proto.repeated_nested_message))
+    self.assertEqual(
+        [unittest_pb2.ForeignMessage(c=-43),
+         unittest_pb2.ForeignMessage(c=45324),
+         unittest_pb2.ForeignMessage(c=12)],
+        list(proto.repeated_foreign_message))
+    self.assertFalse(proto.HasField("optional_nested_message"))
+
+  def testConstructorTypeError(self):
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, optional_int32="foo")
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, optional_string=1234)
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, optional_nested_message=1234)
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, repeated_int32=1234)
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, repeated_int32=["foo"])
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, repeated_string=1234)
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, repeated_string=[1234])
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=1234)
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=[1234])
+
+  def testConstructorInvalidatesCachedByteSize(self):
+    message = unittest_pb2.TestAllTypes(optional_int32 = 12)
+    self.assertEqual(2, message.ByteSize())
+
+    message = unittest_pb2.TestAllTypes(
+        optional_nested_message = unittest_pb2.TestAllTypes.NestedMessage())
+    self.assertEqual(3, message.ByteSize())
+
+    message = unittest_pb2.TestAllTypes(repeated_int32 = [12])
+    self.assertEqual(3, message.ByteSize())
+
+    message = unittest_pb2.TestAllTypes(
+        repeated_nested_message = [unittest_pb2.TestAllTypes.NestedMessage()])
+    self.assertEqual(3, message.ByteSize())
+
+  def testSimpleHasBits(self):
+    # Test a scalar.
+    proto = unittest_pb2.TestAllTypes()
+    self.assertTrue(not proto.HasField('optional_int32'))
+    self.assertEqual(0, proto.optional_int32)
+    # HasField() shouldn't be true if all we've done is
+    # read the default value.
+    self.assertTrue(not proto.HasField('optional_int32'))
+    proto.optional_int32 = 1
+    # Setting a value however *should* set the "has" bit.
+    self.assertTrue(proto.HasField('optional_int32'))
+    proto.ClearField('optional_int32')
+    # And clearing that value should unset the "has" bit.
+    self.assertTrue(not proto.HasField('optional_int32'))
+
+  def testHasBitsWithSinglyNestedScalar(self):
+    # Helper used to test foreign messages and groups.
+    #
+    # composite_field_name should be the name of a non-repeated
+    # composite (i.e., foreign or group) field in TestAllTypes,
+    # and scalar_field_name should be the name of an integer-valued
+    # scalar field within that composite.
+    #
+    # I never thought I'd miss C++ macros and templates so much. :(
+    # This helper is semantically just:
+    #
+    #   assert proto.composite_field.scalar_field == 0
+    #   assert not proto.composite_field.HasField('scalar_field')
+    #   assert not proto.HasField('composite_field')
+    #
+    #   proto.composite_field.scalar_field = 10
+    #   old_composite_field = proto.composite_field
+    #
+    #   assert proto.composite_field.scalar_field == 10
+    #   assert proto.composite_field.HasField('scalar_field')
+    #   assert proto.HasField('composite_field')
+    #
+    #   proto.ClearField('composite_field')
+    #
+    #   assert not proto.composite_field.HasField('scalar_field')
+    #   assert not proto.HasField('composite_field')
+    #   assert proto.composite_field.scalar_field == 0
+    #
+    #   # Now ensure that ClearField('composite_field') disconnected
+    #   # the old field object from the object tree...
+    #   assert old_composite_field is not proto.composite_field
+    #   old_composite_field.scalar_field = 20
+    #   assert not proto.composite_field.HasField('scalar_field')
+    #   assert not proto.HasField('composite_field')
+    def TestCompositeHasBits(composite_field_name, scalar_field_name):
+      proto = unittest_pb2.TestAllTypes()
+      # First, check that we can get the scalar value, and see that it's the
+      # default (0), but that proto.HasField('omposite') and
+      # proto.composite.HasField('scalar') will still return False.
+      composite_field = getattr(proto, composite_field_name)
+      original_scalar_value = getattr(composite_field, scalar_field_name)
+      self.assertEqual(0, original_scalar_value)
+      # Assert that the composite object does not "have" the scalar.
+      self.assertTrue(not composite_field.HasField(scalar_field_name))
+      # Assert that proto does not "have" the composite field.
+      self.assertTrue(not proto.HasField(composite_field_name))
+
+      # Now set the scalar within the composite field.  Ensure that the setting
+      # is reflected, and that proto.HasField('composite') and
+      # proto.composite.HasField('scalar') now both return True.
+      new_val = 20
+      setattr(composite_field, scalar_field_name, new_val)
+      self.assertEqual(new_val, getattr(composite_field, scalar_field_name))
+      # Hold on to a reference to the current composite_field object.
+      old_composite_field = composite_field
+      # Assert that the has methods now return true.
+      self.assertTrue(composite_field.HasField(scalar_field_name))
+      self.assertTrue(proto.HasField(composite_field_name))
+
+      # Now call the clear method...
+      proto.ClearField(composite_field_name)
+
+      # ...and ensure that the "has" bits are all back to False...
+      composite_field = getattr(proto, composite_field_name)
+      self.assertTrue(not composite_field.HasField(scalar_field_name))
+      self.assertTrue(not proto.HasField(composite_field_name))
+      # ...and ensure that the scalar field has returned to its default.
+      self.assertEqual(0, getattr(composite_field, scalar_field_name))
+
+      self.assertTrue(old_composite_field is not composite_field)
+      setattr(old_composite_field, scalar_field_name, new_val)
+      self.assertTrue(not composite_field.HasField(scalar_field_name))
+      self.assertTrue(not proto.HasField(composite_field_name))
+      self.assertEqual(0, getattr(composite_field, scalar_field_name))
+
+    # Test simple, single-level nesting when we set a scalar.
+    TestCompositeHasBits('optionalgroup', 'a')
+    TestCompositeHasBits('optional_nested_message', 'bb')
+    TestCompositeHasBits('optional_foreign_message', 'c')
+    TestCompositeHasBits('optional_import_message', 'd')
+
+  def testReferencesToNestedMessage(self):
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+    del proto
+    # A previous version had a bug where this would raise an exception when
+    # hitting a now-dead weak reference.
+    nested.bb = 23
+
+  def testDisconnectingNestedMessageBeforeSettingField(self):
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+    proto.ClearField('optional_nested_message')  # Should disconnect from parent
+    self.assertTrue(nested is not proto.optional_nested_message)
+    nested.bb = 23
+    self.assertTrue(not proto.HasField('optional_nested_message'))
+    self.assertEqual(0, proto.optional_nested_message.bb)
+
+  def testGetDefaultMessageAfterDisconnectingDefaultMessage(self):
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+    proto.ClearField('optional_nested_message')
+    del proto
+    del nested
+    # Force a garbage collect so that the underlying CMessages are freed along
+    # with the Messages they point to. This is to make sure we're not deleting
+    # default message instances.
+    gc.collect()
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+
+  def testDisconnectingNestedMessageAfterSettingField(self):
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+    nested.bb = 5
+    self.assertTrue(proto.HasField('optional_nested_message'))
+    proto.ClearField('optional_nested_message')  # Should disconnect from parent
+    self.assertEqual(5, nested.bb)
+    self.assertEqual(0, proto.optional_nested_message.bb)
+    self.assertTrue(nested is not proto.optional_nested_message)
+    nested.bb = 23
+    self.assertTrue(not proto.HasField('optional_nested_message'))
+    self.assertEqual(0, proto.optional_nested_message.bb)
+
+  def testDisconnectingNestedMessageBeforeGettingField(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertTrue(not proto.HasField('optional_nested_message'))
+    proto.ClearField('optional_nested_message')
+    self.assertTrue(not proto.HasField('optional_nested_message'))
+
+  def testDisconnectingNestedMessageAfterMerge(self):
+    # This test exercises the code path that does not use ReleaseMessage().
+    # The underlying fear is that if we use ReleaseMessage() incorrectly,
+    # we will have memory leaks.  It's hard to check that that doesn't happen,
+    # but at least we can exercise that code path to make sure it works.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.optional_nested_message.bb = 5
+    proto1.MergeFrom(proto2)
+    self.assertTrue(proto1.HasField('optional_nested_message'))
+    proto1.ClearField('optional_nested_message')
+    self.assertTrue(not proto1.HasField('optional_nested_message'))
+
+  def testDisconnectingLazyNestedMessage(self):
+    # This test exercises releasing a nested message that is lazy. This test
+    # only exercises real code in the C++ implementation as Python does not
+    # support lazy parsing, but the current C++ implementation results in
+    # memory corruption and a crash.
+    if api_implementation.Type() != 'python':
+      return
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_lazy_message.bb = 5
+    proto.ClearField('optional_lazy_message')
+    del proto
+    gc.collect()
+
+  def testHasBitsWhenModifyingRepeatedFields(self):
+    # Test nesting when we add an element to a repeated field in a submessage.
+    proto = unittest_pb2.TestNestedMessageHasBits()
+    proto.optional_nested_message.nestedmessage_repeated_int32.append(5)
+    self.assertEqual(
+        [5], proto.optional_nested_message.nestedmessage_repeated_int32)
+    self.assertTrue(proto.HasField('optional_nested_message'))
+
+    # Do the same test, but with a repeated composite field within the
+    # submessage.
+    proto.ClearField('optional_nested_message')
+    self.assertTrue(not proto.HasField('optional_nested_message'))
+    proto.optional_nested_message.nestedmessage_repeated_foreignmessage.add()
+    self.assertTrue(proto.HasField('optional_nested_message'))
+
+  def testHasBitsForManyLevelsOfNesting(self):
+    # Test nesting many levels deep.
+    recursive_proto = unittest_pb2.TestMutualRecursionA()
+    self.assertTrue(not recursive_proto.HasField('bb'))
+    self.assertEqual(0, recursive_proto.bb.a.bb.a.bb.optional_int32)
+    self.assertTrue(not recursive_proto.HasField('bb'))
+    recursive_proto.bb.a.bb.a.bb.optional_int32 = 5
+    self.assertEqual(5, recursive_proto.bb.a.bb.a.bb.optional_int32)
+    self.assertTrue(recursive_proto.HasField('bb'))
+    self.assertTrue(recursive_proto.bb.HasField('a'))
+    self.assertTrue(recursive_proto.bb.a.HasField('bb'))
+    self.assertTrue(recursive_proto.bb.a.bb.HasField('a'))
+    self.assertTrue(recursive_proto.bb.a.bb.a.HasField('bb'))
+    self.assertTrue(not recursive_proto.bb.a.bb.a.bb.HasField('a'))
+    self.assertTrue(recursive_proto.bb.a.bb.a.bb.HasField('optional_int32'))
+
+  def testSingularListFields(self):
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_fixed32 = 1
+    proto.optional_int32 = 5
+    proto.optional_string = 'foo'
+    # Access sub-message but don't set it yet.
+    nested_message = proto.optional_nested_message
+    self.assertEqual(
+      [ (proto.DESCRIPTOR.fields_by_name['optional_int32'  ], 5),
+        (proto.DESCRIPTOR.fields_by_name['optional_fixed32'], 1),
+        (proto.DESCRIPTOR.fields_by_name['optional_string' ], 'foo') ],
+      proto.ListFields())
+
+    proto.optional_nested_message.bb = 123
+    self.assertEqual(
+      [ (proto.DESCRIPTOR.fields_by_name['optional_int32'  ], 5),
+        (proto.DESCRIPTOR.fields_by_name['optional_fixed32'], 1),
+        (proto.DESCRIPTOR.fields_by_name['optional_string' ], 'foo'),
+        (proto.DESCRIPTOR.fields_by_name['optional_nested_message' ],
+             nested_message) ],
+      proto.ListFields())
+
+  def testRepeatedListFields(self):
+    proto = unittest_pb2.TestAllTypes()
+    proto.repeated_fixed32.append(1)
+    proto.repeated_int32.append(5)
+    proto.repeated_int32.append(11)
+    proto.repeated_string.extend(['foo', 'bar'])
+    proto.repeated_string.extend([])
+    proto.repeated_string.append('baz')
+    proto.repeated_string.extend(str(x) for x in range(2))
+    proto.optional_int32 = 21
+    proto.repeated_bool  # Access but don't set anything; should not be listed.
+    self.assertEqual(
+      [ (proto.DESCRIPTOR.fields_by_name['optional_int32'  ], 21),
+        (proto.DESCRIPTOR.fields_by_name['repeated_int32'  ], [5, 11]),
+        (proto.DESCRIPTOR.fields_by_name['repeated_fixed32'], [1]),
+        (proto.DESCRIPTOR.fields_by_name['repeated_string' ],
+          ['foo', 'bar', 'baz', '0', '1']) ],
+      proto.ListFields())
+
+  def testSingularListExtensions(self):
+    proto = unittest_pb2.TestAllExtensions()
+    proto.Extensions[unittest_pb2.optional_fixed32_extension] = 1
+    proto.Extensions[unittest_pb2.optional_int32_extension  ] = 5
+    proto.Extensions[unittest_pb2.optional_string_extension ] = 'foo'
+    self.assertEqual(
+      [ (unittest_pb2.optional_int32_extension  , 5),
+        (unittest_pb2.optional_fixed32_extension, 1),
+        (unittest_pb2.optional_string_extension , 'foo') ],
+      proto.ListFields())
+
+  def testRepeatedListExtensions(self):
+    proto = unittest_pb2.TestAllExtensions()
+    proto.Extensions[unittest_pb2.repeated_fixed32_extension].append(1)
+    proto.Extensions[unittest_pb2.repeated_int32_extension  ].append(5)
+    proto.Extensions[unittest_pb2.repeated_int32_extension  ].append(11)
+    proto.Extensions[unittest_pb2.repeated_string_extension ].append('foo')
+    proto.Extensions[unittest_pb2.repeated_string_extension ].append('bar')
+    proto.Extensions[unittest_pb2.repeated_string_extension ].append('baz')
+    proto.Extensions[unittest_pb2.optional_int32_extension  ] = 21
+    self.assertEqual(
+      [ (unittest_pb2.optional_int32_extension  , 21),
+        (unittest_pb2.repeated_int32_extension  , [5, 11]),
+        (unittest_pb2.repeated_fixed32_extension, [1]),
+        (unittest_pb2.repeated_string_extension , ['foo', 'bar', 'baz']) ],
+      proto.ListFields())
+
+  def testListFieldsAndExtensions(self):
+    proto = unittest_pb2.TestFieldOrderings()
+    test_util.SetAllFieldsAndExtensions(proto)
+    unittest_pb2.my_extension_int
+    self.assertEqual(
+      [ (proto.DESCRIPTOR.fields_by_name['my_int'   ], 1),
+        (unittest_pb2.my_extension_int               , 23),
+        (proto.DESCRIPTOR.fields_by_name['my_string'], 'foo'),
+        (unittest_pb2.my_extension_string            , 'bar'),
+        (proto.DESCRIPTOR.fields_by_name['my_float' ], 1.0) ],
+      proto.ListFields())
+
+  def testDefaultValues(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(0, proto.optional_int32)
+    self.assertEqual(0, proto.optional_int64)
+    self.assertEqual(0, proto.optional_uint32)
+    self.assertEqual(0, proto.optional_uint64)
+    self.assertEqual(0, proto.optional_sint32)
+    self.assertEqual(0, proto.optional_sint64)
+    self.assertEqual(0, proto.optional_fixed32)
+    self.assertEqual(0, proto.optional_fixed64)
+    self.assertEqual(0, proto.optional_sfixed32)
+    self.assertEqual(0, proto.optional_sfixed64)
+    self.assertEqual(0.0, proto.optional_float)
+    self.assertEqual(0.0, proto.optional_double)
+    self.assertEqual(False, proto.optional_bool)
+    self.assertEqual('', proto.optional_string)
+    self.assertEqual(b'', proto.optional_bytes)
+
+    self.assertEqual(41, proto.default_int32)
+    self.assertEqual(42, proto.default_int64)
+    self.assertEqual(43, proto.default_uint32)
+    self.assertEqual(44, proto.default_uint64)
+    self.assertEqual(-45, proto.default_sint32)
+    self.assertEqual(46, proto.default_sint64)
+    self.assertEqual(47, proto.default_fixed32)
+    self.assertEqual(48, proto.default_fixed64)
+    self.assertEqual(49, proto.default_sfixed32)
+    self.assertEqual(-50, proto.default_sfixed64)
+    self.assertEqual(51.5, proto.default_float)
+    self.assertEqual(52e3, proto.default_double)
+    self.assertEqual(True, proto.default_bool)
+    self.assertEqual('hello', proto.default_string)
+    self.assertEqual(b'world', proto.default_bytes)
+    self.assertEqual(unittest_pb2.TestAllTypes.BAR, proto.default_nested_enum)
+    self.assertEqual(unittest_pb2.FOREIGN_BAR, proto.default_foreign_enum)
+    self.assertEqual(unittest_import_pb2.IMPORT_BAR,
+                     proto.default_import_enum)
+
+    proto = unittest_pb2.TestExtremeDefaultValues()
+    self.assertEqual(u'\u1234', proto.utf8_string)
+
+  def testHasFieldWithUnknownFieldName(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertRaises(ValueError, proto.HasField, 'nonexistent_field')
+
+  def testClearFieldWithUnknownFieldName(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertRaises(ValueError, proto.ClearField, 'nonexistent_field')
+
+  def testClearRemovesChildren(self):
+    # Make sure there aren't any implementation bugs that are only partially
+    # clearing the message (which can happen in the more complex C++
+    # implementation which has parallel message lists).
+    proto = unittest_pb2.TestRequiredForeign()
+    for i in range(10):
+      proto.repeated_message.add()
+    proto2 = unittest_pb2.TestRequiredForeign()
+    proto.CopyFrom(proto2)
+    self.assertRaises(IndexError, lambda: proto.repeated_message[5])
+
+  def testDisallowedAssignments(self):
+    # It's illegal to assign values directly to repeated fields
+    # or to nonrepeated composite fields.  Ensure that this fails.
+    proto = unittest_pb2.TestAllTypes()
+    # Repeated fields.
+    self.assertRaises(AttributeError, setattr, proto, 'repeated_int32', 10)
+    # Lists shouldn't work, either.
+    self.assertRaises(AttributeError, setattr, proto, 'repeated_int32', [10])
+    # Composite fields.
+    self.assertRaises(AttributeError, setattr, proto,
+                      'optional_nested_message', 23)
+    # Assignment to a repeated nested message field without specifying
+    # the index in the array of nested messages.
+    self.assertRaises(AttributeError, setattr, proto.repeated_nested_message,
+                      'bb', 34)
+    # Assignment to an attribute of a repeated field.
+    self.assertRaises(AttributeError, setattr, proto.repeated_float,
+                      'some_attribute', 34)
+    # proto.nonexistent_field = 23 should fail as well.
+    self.assertRaises(AttributeError, setattr, proto, 'nonexistent_field', 23)
+
+  def testSingleScalarTypeSafety(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertRaises(TypeError, setattr, proto, 'optional_int32', 1.1)
+    self.assertRaises(TypeError, setattr, proto, 'optional_int32', 'foo')
+    self.assertRaises(TypeError, setattr, proto, 'optional_string', 10)
+    self.assertRaises(TypeError, setattr, proto, 'optional_bytes', 10)
+
+  def testIntegerTypes(self):
+    def TestGetAndDeserialize(field_name, value, expected_type):
+      proto = unittest_pb2.TestAllTypes()
+      setattr(proto, field_name, value)
+      self.assertIsInstance(getattr(proto, field_name), expected_type)
+      proto2 = unittest_pb2.TestAllTypes()
+      proto2.ParseFromString(proto.SerializeToString())
+      self.assertIsInstance(getattr(proto2, field_name), expected_type)
+
+    TestGetAndDeserialize('optional_int32', 1, int)
+    TestGetAndDeserialize('optional_int32', 1 << 30, int)
+    TestGetAndDeserialize('optional_uint32', 1 << 30, int)
+    try:
+      integer_64 = long
+    except NameError: # Python3
+      integer_64 = int
+    if struct.calcsize('L') == 4:
+      # Python only has signed ints, so 32-bit python can't fit an uint32
+      # in an int.
+      TestGetAndDeserialize('optional_uint32', 1 << 31, integer_64)
+    else:
+      # 64-bit python can fit uint32 inside an int
+      TestGetAndDeserialize('optional_uint32', 1 << 31, int)
+    TestGetAndDeserialize('optional_int64', 1 << 30, integer_64)
+    TestGetAndDeserialize('optional_int64', 1 << 60, integer_64)
+    TestGetAndDeserialize('optional_uint64', 1 << 30, integer_64)
+    TestGetAndDeserialize('optional_uint64', 1 << 60, integer_64)
+
+  def testSingleScalarBoundsChecking(self):
+    def TestMinAndMaxIntegers(field_name, expected_min, expected_max):
+      pb = unittest_pb2.TestAllTypes()
+      setattr(pb, field_name, expected_min)
+      self.assertEqual(expected_min, getattr(pb, field_name))
+      setattr(pb, field_name, expected_max)
+      self.assertEqual(expected_max, getattr(pb, field_name))
+      self.assertRaises(ValueError, setattr, pb, field_name, expected_min - 1)
+      self.assertRaises(ValueError, setattr, pb, field_name, expected_max + 1)
+
+    TestMinAndMaxIntegers('optional_int32', -(1 << 31), (1 << 31) - 1)
+    TestMinAndMaxIntegers('optional_uint32', 0, 0xffffffff)
+    TestMinAndMaxIntegers('optional_int64', -(1 << 63), (1 << 63) - 1)
+    TestMinAndMaxIntegers('optional_uint64', 0, 0xffffffffffffffff)
+
+    pb = unittest_pb2.TestAllTypes()
+    pb.optional_nested_enum = 1
+    self.assertEqual(1, pb.optional_nested_enum)
+
+  def testRepeatedScalarTypeSafety(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertRaises(TypeError, proto.repeated_int32.append, 1.1)
+    self.assertRaises(TypeError, proto.repeated_int32.append, 'foo')
+    self.assertRaises(TypeError, proto.repeated_string, 10)
+    self.assertRaises(TypeError, proto.repeated_bytes, 10)
+
+    proto.repeated_int32.append(10)
+    proto.repeated_int32[0] = 23
+    self.assertRaises(IndexError, proto.repeated_int32.__setitem__, 500, 23)
+    self.assertRaises(TypeError, proto.repeated_int32.__setitem__, 0, 'abc')
+
+    # Repeated enums tests.
+    #proto.repeated_nested_enum.append(0)
+
+  def testSingleScalarGettersAndSetters(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(0, proto.optional_int32)
+    proto.optional_int32 = 1
+    self.assertEqual(1, proto.optional_int32)
+
+    proto.optional_uint64 = 0xffffffffffff
+    self.assertEqual(0xffffffffffff, proto.optional_uint64)
+    proto.optional_uint64 = 0xffffffffffffffff
+    self.assertEqual(0xffffffffffffffff, proto.optional_uint64)
+    # TODO(robinson): Test all other scalar field types.
+
+  def testSingleScalarClearField(self):
+    proto = unittest_pb2.TestAllTypes()
+    # Should be allowed to clear something that's not there (a no-op).
+    proto.ClearField('optional_int32')
+    proto.optional_int32 = 1
+    self.assertTrue(proto.HasField('optional_int32'))
+    proto.ClearField('optional_int32')
+    self.assertEqual(0, proto.optional_int32)
+    self.assertTrue(not proto.HasField('optional_int32'))
+    # TODO(robinson): Test all other scalar field types.
+
+  def testEnums(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(1, proto.FOO)
+    self.assertEqual(1, unittest_pb2.TestAllTypes.FOO)
+    self.assertEqual(2, proto.BAR)
+    self.assertEqual(2, unittest_pb2.TestAllTypes.BAR)
+    self.assertEqual(3, proto.BAZ)
+    self.assertEqual(3, unittest_pb2.TestAllTypes.BAZ)
+
+  def testEnum_Name(self):
+    self.assertEqual('FOREIGN_FOO',
+                     unittest_pb2.ForeignEnum.Name(unittest_pb2.FOREIGN_FOO))
+    self.assertEqual('FOREIGN_BAR',
+                     unittest_pb2.ForeignEnum.Name(unittest_pb2.FOREIGN_BAR))
+    self.assertEqual('FOREIGN_BAZ',
+                     unittest_pb2.ForeignEnum.Name(unittest_pb2.FOREIGN_BAZ))
+    self.assertRaises(ValueError,
+                      unittest_pb2.ForeignEnum.Name, 11312)
+
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual('FOO',
+                     proto.NestedEnum.Name(proto.FOO))
+    self.assertEqual('FOO',
+                     unittest_pb2.TestAllTypes.NestedEnum.Name(proto.FOO))
+    self.assertEqual('BAR',
+                     proto.NestedEnum.Name(proto.BAR))
+    self.assertEqual('BAR',
+                     unittest_pb2.TestAllTypes.NestedEnum.Name(proto.BAR))
+    self.assertEqual('BAZ',
+                     proto.NestedEnum.Name(proto.BAZ))
+    self.assertEqual('BAZ',
+                     unittest_pb2.TestAllTypes.NestedEnum.Name(proto.BAZ))
+    self.assertRaises(ValueError,
+                      proto.NestedEnum.Name, 11312)
+    self.assertRaises(ValueError,
+                      unittest_pb2.TestAllTypes.NestedEnum.Name, 11312)
+
+  def testEnum_Value(self):
+    self.assertEqual(unittest_pb2.FOREIGN_FOO,
+                     unittest_pb2.ForeignEnum.Value('FOREIGN_FOO'))
+    self.assertEqual(unittest_pb2.FOREIGN_BAR,
+                     unittest_pb2.ForeignEnum.Value('FOREIGN_BAR'))
+    self.assertEqual(unittest_pb2.FOREIGN_BAZ,
+                     unittest_pb2.ForeignEnum.Value('FOREIGN_BAZ'))
+    self.assertRaises(ValueError,
+                      unittest_pb2.ForeignEnum.Value, 'FO')
+
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(proto.FOO,
+                     proto.NestedEnum.Value('FOO'))
+    self.assertEqual(proto.FOO,
+                     unittest_pb2.TestAllTypes.NestedEnum.Value('FOO'))
+    self.assertEqual(proto.BAR,
+                     proto.NestedEnum.Value('BAR'))
+    self.assertEqual(proto.BAR,
+                     unittest_pb2.TestAllTypes.NestedEnum.Value('BAR'))
+    self.assertEqual(proto.BAZ,
+                     proto.NestedEnum.Value('BAZ'))
+    self.assertEqual(proto.BAZ,
+                     unittest_pb2.TestAllTypes.NestedEnum.Value('BAZ'))
+    self.assertRaises(ValueError,
+                      proto.NestedEnum.Value, 'Foo')
+    self.assertRaises(ValueError,
+                      unittest_pb2.TestAllTypes.NestedEnum.Value, 'Foo')
+
+  def testEnum_KeysAndValues(self):
+    self.assertEqual(['FOREIGN_FOO', 'FOREIGN_BAR', 'FOREIGN_BAZ'],
+                     list(unittest_pb2.ForeignEnum.keys()))
+    self.assertEqual([4, 5, 6],
+                     list(unittest_pb2.ForeignEnum.values()))
+    self.assertEqual([('FOREIGN_FOO', 4), ('FOREIGN_BAR', 5),
+                      ('FOREIGN_BAZ', 6)],
+                     list(unittest_pb2.ForeignEnum.items()))
+
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(['FOO', 'BAR', 'BAZ', 'NEG'], list(proto.NestedEnum.keys()))
+    self.assertEqual([1, 2, 3, -1], list(proto.NestedEnum.values()))
+    self.assertEqual([('FOO', 1), ('BAR', 2), ('BAZ', 3), ('NEG', -1)],
+                     list(proto.NestedEnum.items()))
+
+  def testRepeatedScalars(self):
+    proto = unittest_pb2.TestAllTypes()
+
+    self.assertTrue(not proto.repeated_int32)
+    self.assertEqual(0, len(proto.repeated_int32))
+    proto.repeated_int32.append(5)
+    proto.repeated_int32.append(10)
+    proto.repeated_int32.append(15)
+    self.assertTrue(proto.repeated_int32)
+    self.assertEqual(3, len(proto.repeated_int32))
+
+    self.assertEqual([5, 10, 15], proto.repeated_int32)
+
+    # Test single retrieval.
+    self.assertEqual(5, proto.repeated_int32[0])
+    self.assertEqual(15, proto.repeated_int32[-1])
+    # Test out-of-bounds indices.
+    self.assertRaises(IndexError, proto.repeated_int32.__getitem__, 1234)
+    self.assertRaises(IndexError, proto.repeated_int32.__getitem__, -1234)
+    # Test incorrect types passed to __getitem__.
+    self.assertRaises(TypeError, proto.repeated_int32.__getitem__, 'foo')
+    self.assertRaises(TypeError, proto.repeated_int32.__getitem__, None)
+
+    # Test single assignment.
+    proto.repeated_int32[1] = 20
+    self.assertEqual([5, 20, 15], proto.repeated_int32)
+
+    # Test insertion.
+    proto.repeated_int32.insert(1, 25)
+    self.assertEqual([5, 25, 20, 15], proto.repeated_int32)
+
+    # Test slice retrieval.
+    proto.repeated_int32.append(30)
+    self.assertEqual([25, 20, 15], proto.repeated_int32[1:4])
+    self.assertEqual([5, 25, 20, 15, 30], proto.repeated_int32[:])
+
+    # Test slice assignment with an iterator
+    proto.repeated_int32[1:4] = (i for i in range(3))
+    self.assertEqual([5, 0, 1, 2, 30], proto.repeated_int32)
+
+    # Test slice assignment.
+    proto.repeated_int32[1:4] = [35, 40, 45]
+    self.assertEqual([5, 35, 40, 45, 30], proto.repeated_int32)
+
+    # Test that we can use the field as an iterator.
+    result = []
+    for i in proto.repeated_int32:
+      result.append(i)
+    self.assertEqual([5, 35, 40, 45, 30], result)
+
+    # Test single deletion.
+    del proto.repeated_int32[2]
+    self.assertEqual([5, 35, 45, 30], proto.repeated_int32)
+
+    # Test slice deletion.
+    del proto.repeated_int32[2:]
+    self.assertEqual([5, 35], proto.repeated_int32)
+
+    # Test extending.
+    proto.repeated_int32.extend([3, 13])
+    self.assertEqual([5, 35, 3, 13], proto.repeated_int32)
+
+    # Test clearing.
+    proto.ClearField('repeated_int32')
+    self.assertTrue(not proto.repeated_int32)
+    self.assertEqual(0, len(proto.repeated_int32))
+
+    proto.repeated_int32.append(1)
+    self.assertEqual(1, proto.repeated_int32[-1])
+    # Test assignment to a negative index.
+    proto.repeated_int32[-1] = 2
+    self.assertEqual(2, proto.repeated_int32[-1])
+
+    # Test deletion at negative indices.
+    proto.repeated_int32[:] = [0, 1, 2, 3]
+    del proto.repeated_int32[-1]
+    self.assertEqual([0, 1, 2], proto.repeated_int32)
+
+    del proto.repeated_int32[-2]
+    self.assertEqual([0, 2], proto.repeated_int32)
+
+    self.assertRaises(IndexError, proto.repeated_int32.__delitem__, -3)
+    self.assertRaises(IndexError, proto.repeated_int32.__delitem__, 300)
+
+    del proto.repeated_int32[-2:-1]
+    self.assertEqual([2], proto.repeated_int32)
+
+    del proto.repeated_int32[100:10000]
+    self.assertEqual([2], proto.repeated_int32)
+
+  def testRepeatedScalarsRemove(self):
+    proto = unittest_pb2.TestAllTypes()
+
+    self.assertTrue(not proto.repeated_int32)
+    self.assertEqual(0, len(proto.repeated_int32))
+    proto.repeated_int32.append(5)
+    proto.repeated_int32.append(10)
+    proto.repeated_int32.append(5)
+    proto.repeated_int32.append(5)
+
+    self.assertEqual(4, len(proto.repeated_int32))
+    proto.repeated_int32.remove(5)
+    self.assertEqual(3, len(proto.repeated_int32))
+    self.assertEqual(10, proto.repeated_int32[0])
+    self.assertEqual(5, proto.repeated_int32[1])
+    self.assertEqual(5, proto.repeated_int32[2])
+
+    proto.repeated_int32.remove(5)
+    self.assertEqual(2, len(proto.repeated_int32))
+    self.assertEqual(10, proto.repeated_int32[0])
+    self.assertEqual(5, proto.repeated_int32[1])
+
+    proto.repeated_int32.remove(10)
+    self.assertEqual(1, len(proto.repeated_int32))
+    self.assertEqual(5, proto.repeated_int32[0])
+
+    # Remove a non-existent element.
+    self.assertRaises(ValueError, proto.repeated_int32.remove, 123)
+
+  def testRepeatedComposites(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertTrue(not proto.repeated_nested_message)
+    self.assertEqual(0, len(proto.repeated_nested_message))
+    m0 = proto.repeated_nested_message.add()
+    m1 = proto.repeated_nested_message.add()
+    self.assertTrue(proto.repeated_nested_message)
+    self.assertEqual(2, len(proto.repeated_nested_message))
+    self.assertListsEqual([m0, m1], proto.repeated_nested_message)
+    self.assertIsInstance(m0, unittest_pb2.TestAllTypes.NestedMessage)
+
+    # Test out-of-bounds indices.
+    self.assertRaises(IndexError, proto.repeated_nested_message.__getitem__,
+                      1234)
+    self.assertRaises(IndexError, proto.repeated_nested_message.__getitem__,
+                      -1234)
+
+    # Test incorrect types passed to __getitem__.
+    self.assertRaises(TypeError, proto.repeated_nested_message.__getitem__,
+                      'foo')
+    self.assertRaises(TypeError, proto.repeated_nested_message.__getitem__,
+                      None)
+
+    # Test slice retrieval.
+    m2 = proto.repeated_nested_message.add()
+    m3 = proto.repeated_nested_message.add()
+    m4 = proto.repeated_nested_message.add()
+    self.assertListsEqual(
+        [m1, m2, m3], proto.repeated_nested_message[1:4])
+    self.assertListsEqual(
+        [m0, m1, m2, m3, m4], proto.repeated_nested_message[:])
+    self.assertListsEqual(
+        [m0, m1], proto.repeated_nested_message[:2])
+    self.assertListsEqual(
+        [m2, m3, m4], proto.repeated_nested_message[2:])
+    self.assertEqual(
+        m0, proto.repeated_nested_message[0])
+    self.assertListsEqual(
+        [m0], proto.repeated_nested_message[:1])
+
+    # Test that we can use the field as an iterator.
+    result = []
+    for i in proto.repeated_nested_message:
+      result.append(i)
+    self.assertListsEqual([m0, m1, m2, m3, m4], result)
+
+    # Test single deletion.
+    del proto.repeated_nested_message[2]
+    self.assertListsEqual([m0, m1, m3, m4], proto.repeated_nested_message)
+
+    # Test slice deletion.
+    del proto.repeated_nested_message[2:]
+    self.assertListsEqual([m0, m1], proto.repeated_nested_message)
+
+    # Test extending.
+    n1 = unittest_pb2.TestAllTypes.NestedMessage(bb=1)
+    n2 = unittest_pb2.TestAllTypes.NestedMessage(bb=2)
+    proto.repeated_nested_message.extend([n1,n2])
+    self.assertEqual(4, len(proto.repeated_nested_message))
+    self.assertEqual(n1, proto.repeated_nested_message[2])
+    self.assertEqual(n2, proto.repeated_nested_message[3])
+
+    # Test clearing.
+    proto.ClearField('repeated_nested_message')
+    self.assertTrue(not proto.repeated_nested_message)
+    self.assertEqual(0, len(proto.repeated_nested_message))
+
+    # Test constructing an element while adding it.
+    proto.repeated_nested_message.add(bb=23)
+    self.assertEqual(1, len(proto.repeated_nested_message))
+    self.assertEqual(23, proto.repeated_nested_message[0].bb)
+    self.assertRaises(TypeError, proto.repeated_nested_message.add, 23)
+
+  def testRepeatedCompositeRemove(self):
+    proto = unittest_pb2.TestAllTypes()
+
+    self.assertEqual(0, len(proto.repeated_nested_message))
+    m0 = proto.repeated_nested_message.add()
+    # Need to set some differentiating variable so m0 != m1 != m2:
+    m0.bb = len(proto.repeated_nested_message)
+    m1 = proto.repeated_nested_message.add()
+    m1.bb = len(proto.repeated_nested_message)
+    self.assertTrue(m0 != m1)
+    m2 = proto.repeated_nested_message.add()
+    m2.bb = len(proto.repeated_nested_message)
+    self.assertListsEqual([m0, m1, m2], proto.repeated_nested_message)
+
+    self.assertEqual(3, len(proto.repeated_nested_message))
+    proto.repeated_nested_message.remove(m0)
+    self.assertEqual(2, len(proto.repeated_nested_message))
+    self.assertEqual(m1, proto.repeated_nested_message[0])
+    self.assertEqual(m2, proto.repeated_nested_message[1])
+
+    # Removing m0 again or removing None should raise error
+    self.assertRaises(ValueError, proto.repeated_nested_message.remove, m0)
+    self.assertRaises(ValueError, proto.repeated_nested_message.remove, None)
+    self.assertEqual(2, len(proto.repeated_nested_message))
+
+    proto.repeated_nested_message.remove(m2)
+    self.assertEqual(1, len(proto.repeated_nested_message))
+    self.assertEqual(m1, proto.repeated_nested_message[0])
+
+  def testHandWrittenReflection(self):
+    # Hand written extensions are only supported by the pure-Python
+    # implementation of the API.
+    if api_implementation.Type() != 'python':
+      return
+
+    FieldDescriptor = descriptor.FieldDescriptor
+    foo_field_descriptor = FieldDescriptor(
+        name='foo_field', full_name='MyProto.foo_field',
+        index=0, number=1, type=FieldDescriptor.TYPE_INT64,
+        cpp_type=FieldDescriptor.CPPTYPE_INT64,
+        label=FieldDescriptor.LABEL_OPTIONAL, default_value=0,
+        containing_type=None, message_type=None, enum_type=None,
+        is_extension=False, extension_scope=None,
+        options=descriptor_pb2.FieldOptions())
+    mydescriptor = descriptor.Descriptor(
+        name='MyProto', full_name='MyProto', filename='ignored',
+        containing_type=None, nested_types=[], enum_types=[],
+        fields=[foo_field_descriptor], extensions=[],
+        options=descriptor_pb2.MessageOptions())
+    class MyProtoClass(six.with_metaclass(reflection.GeneratedProtocolMessageType, message.Message)):
+      DESCRIPTOR = mydescriptor
+    myproto_instance = MyProtoClass()
+    self.assertEqual(0, myproto_instance.foo_field)
+    self.assertTrue(not myproto_instance.HasField('foo_field'))
+    myproto_instance.foo_field = 23
+    self.assertEqual(23, myproto_instance.foo_field)
+    self.assertTrue(myproto_instance.HasField('foo_field'))
+
+  def testDescriptorProtoSupport(self):
+    # Hand written descriptors/reflection are only supported by the pure-Python
+    # implementation of the API.
+    if api_implementation.Type() != 'python':
+      return
+
+    def AddDescriptorField(proto, field_name, field_type):
+      AddDescriptorField.field_index += 1
+      new_field = proto.field.add()
+      new_field.name = field_name
+      new_field.type = field_type
+      new_field.number = AddDescriptorField.field_index
+      new_field.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL
+
+    AddDescriptorField.field_index = 0
+
+    desc_proto = descriptor_pb2.DescriptorProto()
+    desc_proto.name = 'Car'
+    fdp = descriptor_pb2.FieldDescriptorProto
+    AddDescriptorField(desc_proto, 'name', fdp.TYPE_STRING)
+    AddDescriptorField(desc_proto, 'year', fdp.TYPE_INT64)
+    AddDescriptorField(desc_proto, 'automatic', fdp.TYPE_BOOL)
+    AddDescriptorField(desc_proto, 'price', fdp.TYPE_DOUBLE)
+    # Add a repeated field
+    AddDescriptorField.field_index += 1
+    new_field = desc_proto.field.add()
+    new_field.name = 'owners'
+    new_field.type = fdp.TYPE_STRING
+    new_field.number = AddDescriptorField.field_index
+    new_field.label = descriptor_pb2.FieldDescriptorProto.LABEL_REPEATED
+
+    desc = descriptor.MakeDescriptor(desc_proto)
+    self.assertTrue('name' in desc.fields_by_name)
+    self.assertTrue('year' in desc.fields_by_name)
+    self.assertTrue('automatic' in desc.fields_by_name)
+    self.assertTrue('price' in desc.fields_by_name)
+    self.assertTrue('owners' in desc.fields_by_name)
+
+    class CarMessage(six.with_metaclass(reflection.GeneratedProtocolMessageType, message.Message)):
+      DESCRIPTOR = desc
+
+    prius = CarMessage()
+    prius.name = 'prius'
+    prius.year = 2010
+    prius.automatic = True
+    prius.price = 25134.75
+    prius.owners.extend(['bob', 'susan'])
+
+    serialized_prius = prius.SerializeToString()
+    new_prius = reflection.ParseMessage(desc, serialized_prius)
+    self.assertTrue(new_prius is not prius)
+    self.assertEqual(prius, new_prius)
+
+    # these are unnecessary assuming message equality works as advertised but
+    # explicitly check to be safe since we're mucking about in metaclass foo
+    self.assertEqual(prius.name, new_prius.name)
+    self.assertEqual(prius.year, new_prius.year)
+    self.assertEqual(prius.automatic, new_prius.automatic)
+    self.assertEqual(prius.price, new_prius.price)
+    self.assertEqual(prius.owners, new_prius.owners)
+
+  def testTopLevelExtensionsForOptionalScalar(self):
+    extendee_proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.optional_int32_extension
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    self.assertEqual(0, extendee_proto.Extensions[extension])
+    # As with normal scalar fields, just doing a read doesn't actually set the
+    # "has" bit.
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    # Actually set the thing.
+    extendee_proto.Extensions[extension] = 23
+    self.assertEqual(23, extendee_proto.Extensions[extension])
+    self.assertTrue(extendee_proto.HasExtension(extension))
+    # Ensure that clearing works as well.
+    extendee_proto.ClearExtension(extension)
+    self.assertEqual(0, extendee_proto.Extensions[extension])
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+
+  def testTopLevelExtensionsForRepeatedScalar(self):
+    extendee_proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.repeated_string_extension
+    self.assertEqual(0, len(extendee_proto.Extensions[extension]))
+    extendee_proto.Extensions[extension].append('foo')
+    self.assertEqual(['foo'], extendee_proto.Extensions[extension])
+    string_list = extendee_proto.Extensions[extension]
+    extendee_proto.ClearExtension(extension)
+    self.assertEqual(0, len(extendee_proto.Extensions[extension]))
+    self.assertTrue(string_list is not extendee_proto.Extensions[extension])
+    # Shouldn't be allowed to do Extensions[extension] = 'a'
+    self.assertRaises(TypeError, operator.setitem, extendee_proto.Extensions,
+                      extension, 'a')
+
+  def testTopLevelExtensionsForOptionalMessage(self):
+    extendee_proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.optional_foreign_message_extension
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    self.assertEqual(0, extendee_proto.Extensions[extension].c)
+    # As with normal (non-extension) fields, merely reading from the
+    # thing shouldn't set the "has" bit.
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    extendee_proto.Extensions[extension].c = 23
+    self.assertEqual(23, extendee_proto.Extensions[extension].c)
+    self.assertTrue(extendee_proto.HasExtension(extension))
+    # Save a reference here.
+    foreign_message = extendee_proto.Extensions[extension]
+    extendee_proto.ClearExtension(extension)
+    self.assertTrue(foreign_message is not extendee_proto.Extensions[extension])
+    # Setting a field on foreign_message now shouldn't set
+    # any "has" bits on extendee_proto.
+    foreign_message.c = 42
+    self.assertEqual(42, foreign_message.c)
+    self.assertTrue(foreign_message.HasField('c'))
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    # Shouldn't be allowed to do Extensions[extension] = 'a'
+    self.assertRaises(TypeError, operator.setitem, extendee_proto.Extensions,
+                      extension, 'a')
+
+  def testTopLevelExtensionsForRepeatedMessage(self):
+    extendee_proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.repeatedgroup_extension
+    self.assertEqual(0, len(extendee_proto.Extensions[extension]))
+    group = extendee_proto.Extensions[extension].add()
+    group.a = 23
+    self.assertEqual(23, extendee_proto.Extensions[extension][0].a)
+    group.a = 42
+    self.assertEqual(42, extendee_proto.Extensions[extension][0].a)
+    group_list = extendee_proto.Extensions[extension]
+    extendee_proto.ClearExtension(extension)
+    self.assertEqual(0, len(extendee_proto.Extensions[extension]))
+    self.assertTrue(group_list is not extendee_proto.Extensions[extension])
+    # Shouldn't be allowed to do Extensions[extension] = 'a'
+    self.assertRaises(TypeError, operator.setitem, extendee_proto.Extensions,
+                      extension, 'a')
+
+  def testNestedExtensions(self):
+    extendee_proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.TestRequired.single
+
+    # We just test the non-repeated case.
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    required = extendee_proto.Extensions[extension]
+    self.assertEqual(0, required.a)
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    required.a = 23
+    self.assertEqual(23, extendee_proto.Extensions[extension].a)
+    self.assertTrue(extendee_proto.HasExtension(extension))
+    extendee_proto.ClearExtension(extension)
+    self.assertTrue(required is not extendee_proto.Extensions[extension])
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+
+  def testRegisteredExtensions(self):
+    self.assertTrue('protobuf_unittest.optional_int32_extension' in
+                    unittest_pb2.TestAllExtensions._extensions_by_name)
+    self.assertTrue(1 in unittest_pb2.TestAllExtensions._extensions_by_number)
+    # Make sure extensions haven't been registered into types that shouldn't
+    # have any.
+    self.assertEqual(0, len(unittest_pb2.TestAllTypes._extensions_by_name))
+
+  # If message A directly contains message B, and
+  # a.HasField('b') is currently False, then mutating any
+  # extension in B should change a.HasField('b') to True
+  # (and so on up the object tree).
+  def testHasBitsForAncestorsOfExtendedMessage(self):
+    # Optional scalar extension.
+    toplevel = more_extensions_pb2.TopLevelMessage()
+    self.assertTrue(not toplevel.HasField('submessage'))
+    self.assertEqual(0, toplevel.submessage.Extensions[
+        more_extensions_pb2.optional_int_extension])
+    self.assertTrue(not toplevel.HasField('submessage'))
+    toplevel.submessage.Extensions[
+        more_extensions_pb2.optional_int_extension] = 23
+    self.assertEqual(23, toplevel.submessage.Extensions[
+        more_extensions_pb2.optional_int_extension])
+    self.assertTrue(toplevel.HasField('submessage'))
+
+    # Repeated scalar extension.
+    toplevel = more_extensions_pb2.TopLevelMessage()
+    self.assertTrue(not toplevel.HasField('submessage'))
+    self.assertEqual([], toplevel.submessage.Extensions[
+        more_extensions_pb2.repeated_int_extension])
+    self.assertTrue(not toplevel.HasField('submessage'))
+    toplevel.submessage.Extensions[
+        more_extensions_pb2.repeated_int_extension].append(23)
+    self.assertEqual([23], toplevel.submessage.Extensions[
+        more_extensions_pb2.repeated_int_extension])
+    self.assertTrue(toplevel.HasField('submessage'))
+
+    # Optional message extension.
+    toplevel = more_extensions_pb2.TopLevelMessage()
+    self.assertTrue(not toplevel.HasField('submessage'))
+    self.assertEqual(0, toplevel.submessage.Extensions[
+        more_extensions_pb2.optional_message_extension].foreign_message_int)
+    self.assertTrue(not toplevel.HasField('submessage'))
+    toplevel.submessage.Extensions[
+        more_extensions_pb2.optional_message_extension].foreign_message_int = 23
+    self.assertEqual(23, toplevel.submessage.Extensions[
+        more_extensions_pb2.optional_message_extension].foreign_message_int)
+    self.assertTrue(toplevel.HasField('submessage'))
+
+    # Repeated message extension.
+    toplevel = more_extensions_pb2.TopLevelMessage()
+    self.assertTrue(not toplevel.HasField('submessage'))
+    self.assertEqual(0, len(toplevel.submessage.Extensions[
+        more_extensions_pb2.repeated_message_extension]))
+    self.assertTrue(not toplevel.HasField('submessage'))
+    foreign = toplevel.submessage.Extensions[
+        more_extensions_pb2.repeated_message_extension].add()
+    self.assertEqual(foreign, toplevel.submessage.Extensions[
+        more_extensions_pb2.repeated_message_extension][0])
+    self.assertTrue(toplevel.HasField('submessage'))
+
+  def testDisconnectionAfterClearingEmptyMessage(self):
+    toplevel = more_extensions_pb2.TopLevelMessage()
+    extendee_proto = toplevel.submessage
+    extension = more_extensions_pb2.optional_message_extension
+    extension_proto = extendee_proto.Extensions[extension]
+    extendee_proto.ClearExtension(extension)
+    extension_proto.foreign_message_int = 23
+
+    self.assertTrue(extension_proto is not extendee_proto.Extensions[extension])
+
+  def testExtensionFailureModes(self):
+    extendee_proto = unittest_pb2.TestAllExtensions()
+
+    # Try non-extension-handle arguments to HasExtension,
+    # ClearExtension(), and Extensions[]...
+    self.assertRaises(KeyError, extendee_proto.HasExtension, 1234)
+    self.assertRaises(KeyError, extendee_proto.ClearExtension, 1234)
+    self.assertRaises(KeyError, extendee_proto.Extensions.__getitem__, 1234)
+    self.assertRaises(KeyError, extendee_proto.Extensions.__setitem__, 1234, 5)
+
+    # Try something that *is* an extension handle, just not for
+    # this message...
+    for unknown_handle in (more_extensions_pb2.optional_int_extension,
+                           more_extensions_pb2.optional_message_extension,
+                           more_extensions_pb2.repeated_int_extension,
+                           more_extensions_pb2.repeated_message_extension):
+      self.assertRaises(KeyError, extendee_proto.HasExtension,
+                        unknown_handle)
+      self.assertRaises(KeyError, extendee_proto.ClearExtension,
+                        unknown_handle)
+      self.assertRaises(KeyError, extendee_proto.Extensions.__getitem__,
+                        unknown_handle)
+      self.assertRaises(KeyError, extendee_proto.Extensions.__setitem__,
+                        unknown_handle, 5)
+
+    # Try call HasExtension() with a valid handle, but for a
+    # *repeated* field.  (Just as with non-extension repeated
+    # fields, Has*() isn't supported for extension repeated fields).
+    self.assertRaises(KeyError, extendee_proto.HasExtension,
+                      unittest_pb2.repeated_string_extension)
+
+  def testStaticParseFrom(self):
+    proto1 = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(proto1)
+
+    string1 = proto1.SerializeToString()
+    proto2 = unittest_pb2.TestAllTypes.FromString(string1)
+
+    # Messages should be equal.
+    self.assertEqual(proto2, proto1)
+
+  def testMergeFromSingularField(self):
+    # Test merge with just a singular field.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.optional_int32 = 1
+
+    proto2 = unittest_pb2.TestAllTypes()
+    # This shouldn't get overwritten.
+    proto2.optional_string = 'value'
+
+    proto2.MergeFrom(proto1)
+    self.assertEqual(1, proto2.optional_int32)
+    self.assertEqual('value', proto2.optional_string)
+
+  def testMergeFromRepeatedField(self):
+    # Test merge with just a repeated field.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.repeated_int32.append(1)
+    proto1.repeated_int32.append(2)
+
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.repeated_int32.append(0)
+    proto2.MergeFrom(proto1)
+
+    self.assertEqual(0, proto2.repeated_int32[0])
+    self.assertEqual(1, proto2.repeated_int32[1])
+    self.assertEqual(2, proto2.repeated_int32[2])
+
+  def testMergeFromOptionalGroup(self):
+    # Test merge with an optional group.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.optionalgroup.a = 12
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.MergeFrom(proto1)
+    self.assertEqual(12, proto2.optionalgroup.a)
+
+  def testMergeFromRepeatedNestedMessage(self):
+    # Test merge with a repeated nested message.
+    proto1 = unittest_pb2.TestAllTypes()
+    m = proto1.repeated_nested_message.add()
+    m.bb = 123
+    m = proto1.repeated_nested_message.add()
+    m.bb = 321
+
+    proto2 = unittest_pb2.TestAllTypes()
+    m = proto2.repeated_nested_message.add()
+    m.bb = 999
+    proto2.MergeFrom(proto1)
+    self.assertEqual(999, proto2.repeated_nested_message[0].bb)
+    self.assertEqual(123, proto2.repeated_nested_message[1].bb)
+    self.assertEqual(321, proto2.repeated_nested_message[2].bb)
+
+    proto3 = unittest_pb2.TestAllTypes()
+    proto3.repeated_nested_message.MergeFrom(proto2.repeated_nested_message)
+    self.assertEqual(999, proto3.repeated_nested_message[0].bb)
+    self.assertEqual(123, proto3.repeated_nested_message[1].bb)
+    self.assertEqual(321, proto3.repeated_nested_message[2].bb)
+
+  def testMergeFromAllFields(self):
+    # With all fields set.
+    proto1 = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(proto1)
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.MergeFrom(proto1)
+
+    # Messages should be equal.
+    self.assertEqual(proto2, proto1)
+
+    # Serialized string should be equal too.
+    string1 = proto1.SerializeToString()
+    string2 = proto2.SerializeToString()
+    self.assertEqual(string1, string2)
+
+  def testMergeFromExtensionsSingular(self):
+    proto1 = unittest_pb2.TestAllExtensions()
+    proto1.Extensions[unittest_pb2.optional_int32_extension] = 1
+
+    proto2 = unittest_pb2.TestAllExtensions()
+    proto2.MergeFrom(proto1)
+    self.assertEqual(
+        1, proto2.Extensions[unittest_pb2.optional_int32_extension])
+
+  def testMergeFromExtensionsRepeated(self):
+    proto1 = unittest_pb2.TestAllExtensions()
+    proto1.Extensions[unittest_pb2.repeated_int32_extension].append(1)
+    proto1.Extensions[unittest_pb2.repeated_int32_extension].append(2)
+
+    proto2 = unittest_pb2.TestAllExtensions()
+    proto2.Extensions[unittest_pb2.repeated_int32_extension].append(0)
+    proto2.MergeFrom(proto1)
+    self.assertEqual(
+        3, len(proto2.Extensions[unittest_pb2.repeated_int32_extension]))
+    self.assertEqual(
+        0, proto2.Extensions[unittest_pb2.repeated_int32_extension][0])
+    self.assertEqual(
+        1, proto2.Extensions[unittest_pb2.repeated_int32_extension][1])
+    self.assertEqual(
+        2, proto2.Extensions[unittest_pb2.repeated_int32_extension][2])
+
+  def testMergeFromExtensionsNestedMessage(self):
+    proto1 = unittest_pb2.TestAllExtensions()
+    ext1 = proto1.Extensions[
+        unittest_pb2.repeated_nested_message_extension]
+    m = ext1.add()
+    m.bb = 222
+    m = ext1.add()
+    m.bb = 333
+
+    proto2 = unittest_pb2.TestAllExtensions()
+    ext2 = proto2.Extensions[
+        unittest_pb2.repeated_nested_message_extension]
+    m = ext2.add()
+    m.bb = 111
+
+    proto2.MergeFrom(proto1)
+    ext2 = proto2.Extensions[
+        unittest_pb2.repeated_nested_message_extension]
+    self.assertEqual(3, len(ext2))
+    self.assertEqual(111, ext2[0].bb)
+    self.assertEqual(222, ext2[1].bb)
+    self.assertEqual(333, ext2[2].bb)
+
+  def testMergeFromBug(self):
+    message1 = unittest_pb2.TestAllTypes()
+    message2 = unittest_pb2.TestAllTypes()
+
+    # Cause optional_nested_message to be instantiated within message1, even
+    # though it is not considered to be "present".
+    message1.optional_nested_message
+    self.assertFalse(message1.HasField('optional_nested_message'))
+
+    # Merge into message2.  This should not instantiate the field is message2.
+    message2.MergeFrom(message1)
+    self.assertFalse(message2.HasField('optional_nested_message'))
+
+  def testCopyFromSingularField(self):
+    # Test copy with just a singular field.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.optional_int32 = 1
+    proto1.optional_string = 'important-text'
+
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.optional_string = 'value'
+
+    proto2.CopyFrom(proto1)
+    self.assertEqual(1, proto2.optional_int32)
+    self.assertEqual('important-text', proto2.optional_string)
+
+  def testCopyFromRepeatedField(self):
+    # Test copy with a repeated field.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.repeated_int32.append(1)
+    proto1.repeated_int32.append(2)
+
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.repeated_int32.append(0)
+    proto2.CopyFrom(proto1)
+
+    self.assertEqual(1, proto2.repeated_int32[0])
+    self.assertEqual(2, proto2.repeated_int32[1])
+
+  def testCopyFromAllFields(self):
+    # With all fields set.
+    proto1 = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(proto1)
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.CopyFrom(proto1)
+
+    # Messages should be equal.
+    self.assertEqual(proto2, proto1)
+
+    # Serialized string should be equal too.
+    string1 = proto1.SerializeToString()
+    string2 = proto2.SerializeToString()
+    self.assertEqual(string1, string2)
+
+  def testCopyFromSelf(self):
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.repeated_int32.append(1)
+    proto1.optional_int32 = 2
+    proto1.optional_string = 'important-text'
+
+    proto1.CopyFrom(proto1)
+    self.assertEqual(1, proto1.repeated_int32[0])
+    self.assertEqual(2, proto1.optional_int32)
+    self.assertEqual('important-text', proto1.optional_string)
+
+  def testCopyFromBadType(self):
+    # The python implementation doesn't raise an exception in this
+    # case. In theory it should.
+    if api_implementation.Type() == 'python':
+      return
+    proto1 = unittest_pb2.TestAllTypes()
+    proto2 = unittest_pb2.TestAllExtensions()
+    self.assertRaises(TypeError, proto1.CopyFrom, proto2)
+
+  def testDeepCopy(self):
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.optional_int32 = 1
+    proto2 = copy.deepcopy(proto1)
+    self.assertEqual(1, proto2.optional_int32)
+
+    proto1.repeated_int32.append(2)
+    proto1.repeated_int32.append(3)
+    container = copy.deepcopy(proto1.repeated_int32)
+    self.assertEqual([2, 3], container)
+
+    # TODO(anuraag): Implement deepcopy for repeated composite / extension dict
+
+  def testClear(self):
+    proto = unittest_pb2.TestAllTypes()
+    # C++ implementation does not support lazy fields right now so leave it
+    # out for now.
+    if api_implementation.Type() == 'python':
+      test_util.SetAllFields(proto)
+    else:
+      test_util.SetAllNonLazyFields(proto)
+    # Clear the message.
+    proto.Clear()
+    self.assertEqual(proto.ByteSize(), 0)
+    empty_proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(proto, empty_proto)
+
+    # Test if extensions which were set are cleared.
+    proto = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(proto)
+    # Clear the message.
+    proto.Clear()
+    self.assertEqual(proto.ByteSize(), 0)
+    empty_proto = unittest_pb2.TestAllExtensions()
+    self.assertEqual(proto, empty_proto)
+
+  def testDisconnectingBeforeClear(self):
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+    proto.Clear()
+    self.assertTrue(nested is not proto.optional_nested_message)
+    nested.bb = 23
+    self.assertTrue(not proto.HasField('optional_nested_message'))
+    self.assertEqual(0, proto.optional_nested_message.bb)
+
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+    nested.bb = 5
+    foreign = proto.optional_foreign_message
+    foreign.c = 6
+
+    proto.Clear()
+    self.assertTrue(nested is not proto.optional_nested_message)
+    self.assertTrue(foreign is not proto.optional_foreign_message)
+    self.assertEqual(5, nested.bb)
+    self.assertEqual(6, foreign.c)
+    nested.bb = 15
+    foreign.c = 16
+    self.assertFalse(proto.HasField('optional_nested_message'))
+    self.assertEqual(0, proto.optional_nested_message.bb)
+    self.assertFalse(proto.HasField('optional_foreign_message'))
+    self.assertEqual(0, proto.optional_foreign_message.c)
+
+  def testOneOf(self):
+    proto = unittest_pb2.TestAllTypes()
+    proto.oneof_uint32 = 10
+    proto.oneof_nested_message.bb = 11
+    self.assertEqual(11, proto.oneof_nested_message.bb)
+    self.assertFalse(proto.HasField('oneof_uint32'))
+    nested = proto.oneof_nested_message
+    proto.oneof_string = 'abc'
+    self.assertEqual('abc', proto.oneof_string)
+    self.assertEqual(11, nested.bb)
+    self.assertFalse(proto.HasField('oneof_nested_message'))
+
+  def assertInitialized(self, proto):
+    self.assertTrue(proto.IsInitialized())
+    # Neither method should raise an exception.
+    proto.SerializeToString()
+    proto.SerializePartialToString()
+
+  def assertNotInitialized(self, proto):
+    self.assertFalse(proto.IsInitialized())
+    self.assertRaises(message.EncodeError, proto.SerializeToString)
+    # "Partial" serialization doesn't care if message is uninitialized.
+    proto.SerializePartialToString()
+
+  def testIsInitialized(self):
+    # Trivial cases - all optional fields and extensions.
+    proto = unittest_pb2.TestAllTypes()
+    self.assertInitialized(proto)
+    proto = unittest_pb2.TestAllExtensions()
+    self.assertInitialized(proto)
+
+    # The case of uninitialized required fields.
+    proto = unittest_pb2.TestRequired()
+    self.assertNotInitialized(proto)
+    proto.a = proto.b = proto.c = 2
+    self.assertInitialized(proto)
+
+    # The case of uninitialized submessage.
+    proto = unittest_pb2.TestRequiredForeign()
+    self.assertInitialized(proto)
+    proto.optional_message.a = 1
+    self.assertNotInitialized(proto)
+    proto.optional_message.b = 0
+    proto.optional_message.c = 0
+    self.assertInitialized(proto)
+
+    # Uninitialized repeated submessage.
+    message1 = proto.repeated_message.add()
+    self.assertNotInitialized(proto)
+    message1.a = message1.b = message1.c = 0
+    self.assertInitialized(proto)
+
+    # Uninitialized repeated group in an extension.
+    proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.TestRequired.multi
+    message1 = proto.Extensions[extension].add()
+    message2 = proto.Extensions[extension].add()
+    self.assertNotInitialized(proto)
+    message1.a = 1
+    message1.b = 1
+    message1.c = 1
+    self.assertNotInitialized(proto)
+    message2.a = 2
+    message2.b = 2
+    message2.c = 2
+    self.assertInitialized(proto)
+
+    # Uninitialized nonrepeated message in an extension.
+    proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.TestRequired.single
+    proto.Extensions[extension].a = 1
+    self.assertNotInitialized(proto)
+    proto.Extensions[extension].b = 2
+    proto.Extensions[extension].c = 3
+    self.assertInitialized(proto)
+
+    # Try passing an errors list.
+    errors = []
+    proto = unittest_pb2.TestRequired()
+    self.assertFalse(proto.IsInitialized(errors))
+    self.assertEqual(errors, ['a', 'b', 'c'])
+
+  @unittest.skipIf(
+      api_implementation.Type() != 'cpp' or api_implementation.Version() != 2,
+      'Errors are only available from the most recent C++ implementation.')
+  def testFileDescriptorErrors(self):
+    file_name = 'test_file_descriptor_errors.proto'
+    package_name = 'test_file_descriptor_errors.proto'
+    file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
+    file_descriptor_proto.name = file_name
+    file_descriptor_proto.package = package_name
+    m1 = file_descriptor_proto.message_type.add()
+    m1.name = 'msg1'
+    # Compiles the proto into the C++ descriptor pool
+    descriptor.FileDescriptor(
+        file_name,
+        package_name,
+        serialized_pb=file_descriptor_proto.SerializeToString())
+    # Add a FileDescriptorProto that has duplicate symbols
+    another_file_name = 'another_test_file_descriptor_errors.proto'
+    file_descriptor_proto.name = another_file_name
+    m2 = file_descriptor_proto.message_type.add()
+    m2.name = 'msg2'
+    with self.assertRaises(TypeError) as cm:
+      descriptor.FileDescriptor(
+          another_file_name,
+          package_name,
+          serialized_pb=file_descriptor_proto.SerializeToString())
+      self.assertTrue(hasattr(cm, 'exception'), '%s not raised' %
+                      getattr(cm.expected, '__name__', cm.expected))
+      self.assertIn('test_file_descriptor_errors.proto', str(cm.exception))
+      # Error message will say something about this definition being a
+      # duplicate, though we don't check the message exactly to avoid a
+      # dependency on the C++ logging code.
+      self.assertIn('test_file_descriptor_errors.msg1', str(cm.exception))
+
+  def testStringUTF8Encoding(self):
+    proto = unittest_pb2.TestAllTypes()
+
+    # Assignment of a unicode object to a field of type 'bytes' is not allowed.
+    self.assertRaises(TypeError,
+                      setattr, proto, 'optional_bytes', u'unicode object')
+
+    # Check that the default value is of python's 'unicode' type.
+    self.assertEqual(type(proto.optional_string), six.text_type)
+
+    proto.optional_string = six.text_type('Testing')
+    self.assertEqual(proto.optional_string, str('Testing'))
+
+    # Assign a value of type 'str' which can be encoded in UTF-8.
+    proto.optional_string = str('Testing')
+    self.assertEqual(proto.optional_string, six.text_type('Testing'))
+
+    # Try to assign a 'bytes' object which contains non-UTF-8.
+    self.assertRaises(ValueError,
+                      setattr, proto, 'optional_string', b'a\x80a')
+    # No exception: Assign already encoded UTF-8 bytes to a string field.
+    utf8_bytes = u'Тест'.encode('utf-8')
+    proto.optional_string = utf8_bytes
+    # No exception: Assign the a non-ascii unicode object.
+    proto.optional_string = u'Тест'
+    # No exception thrown (normal str assignment containing ASCII).
+    proto.optional_string = 'abc'
+
+  def testStringUTF8Serialization(self):
+    proto = message_set_extensions_pb2.TestMessageSet()
+    extension_message = message_set_extensions_pb2.TestMessageSetExtension2
+    extension = extension_message.message_set_extension
+
+    test_utf8 = u'Тест'
+    test_utf8_bytes = test_utf8.encode('utf-8')
+
+    # 'Test' in another language, using UTF-8 charset.
+    proto.Extensions[extension].str = test_utf8
+
+    # Serialize using the MessageSet wire format (this is specified in the
+    # .proto file).
+    serialized = proto.SerializeToString()
+
+    # Check byte size.
+    self.assertEqual(proto.ByteSize(), len(serialized))
+
+    raw = unittest_mset_pb2.RawMessageSet()
+    bytes_read = raw.MergeFromString(serialized)
+    self.assertEqual(len(serialized), bytes_read)
+
+    message2 = message_set_extensions_pb2.TestMessageSetExtension2()
+
+    self.assertEqual(1, len(raw.item))
+    # Check that the type_id is the same as the tag ID in the .proto file.
+    self.assertEqual(raw.item[0].type_id, 98418634)
+
+    # Check the actual bytes on the wire.
+    self.assertTrue(raw.item[0].message.endswith(test_utf8_bytes))
+    bytes_read = message2.MergeFromString(raw.item[0].message)
+    self.assertEqual(len(raw.item[0].message), bytes_read)
+
+    self.assertEqual(type(message2.str), six.text_type)
+    self.assertEqual(message2.str, test_utf8)
+
+    # The pure Python API throws an exception on MergeFromString(),
+    # if any of the string fields of the message can't be UTF-8 decoded.
+    # The C++ implementation of the API has no way to check that on
+    # MergeFromString and thus has no way to throw the exception.
+    #
+    # The pure Python API always returns objects of type 'unicode' (UTF-8
+    # encoded), or 'bytes' (in 7 bit ASCII).
+    badbytes = raw.item[0].message.replace(
+        test_utf8_bytes, len(test_utf8_bytes) * b'\xff')
+
+    unicode_decode_failed = False
+    try:
+      message2.MergeFromString(badbytes)
+    except UnicodeDecodeError:
+      unicode_decode_failed = True
+    string_field = message2.str
+    self.assertTrue(unicode_decode_failed or type(string_field) is bytes)
+
+  def testBytesInTextFormat(self):
+    proto = unittest_pb2.TestAllTypes(optional_bytes=b'\x00\x7f\x80\xff')
+    self.assertEqual(u'optional_bytes: "\\000\\177\\200\\377"\n',
+                     six.text_type(proto))
+
+  def testEmptyNestedMessage(self):
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_nested_message.MergeFrom(
+        unittest_pb2.TestAllTypes.NestedMessage())
+    self.assertTrue(proto.HasField('optional_nested_message'))
+
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_nested_message.CopyFrom(
+        unittest_pb2.TestAllTypes.NestedMessage())
+    self.assertTrue(proto.HasField('optional_nested_message'))
+
+    proto = unittest_pb2.TestAllTypes()
+    bytes_read = proto.optional_nested_message.MergeFromString(b'')
+    self.assertEqual(0, bytes_read)
+    self.assertTrue(proto.HasField('optional_nested_message'))
+
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_nested_message.ParseFromString(b'')
+    self.assertTrue(proto.HasField('optional_nested_message'))
+
+    serialized = proto.SerializeToString()
+    proto2 = unittest_pb2.TestAllTypes()
+    self.assertEqual(
+        len(serialized),
+        proto2.MergeFromString(serialized))
+    self.assertTrue(proto2.HasField('optional_nested_message'))
+
+  def testSetInParent(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertFalse(proto.HasField('optionalgroup'))
+    proto.optionalgroup.SetInParent()
+    self.assertTrue(proto.HasField('optionalgroup'))
+
+  def testPackageInitializationImport(self):
+    """Test that we can import nested messages from their __init__.py.
+
+    Such setup is not trivial since at the time of processing of __init__.py one
+    can't refer to its submodules by name in code, so expressions like
+    google.protobuf.internal.import_test_package.inner_pb2
+    don't work. They do work in imports, so we have assign an alias at import
+    and then use that alias in generated code.
+    """
+    # We import here since it's the import that used to fail, and we want
+    # the failure to have the right context.
+    # pylint: disable=g-import-not-at-top
+    from google.protobuf.internal import import_test_package
+    # pylint: enable=g-import-not-at-top
+    msg = import_test_package.myproto.Outer()
+    # Just check the default value.
+    self.assertEqual(57, msg.inner.value)
+
+#  Since we had so many tests for protocol buffer equality, we broke these out
+#  into separate TestCase classes.
+
+
+class TestAllTypesEqualityTest(unittest.TestCase):
+
+  def setUp(self):
+    self.first_proto = unittest_pb2.TestAllTypes()
+    self.second_proto = unittest_pb2.TestAllTypes()
+
+  def testNotHashable(self):
+    self.assertRaises(TypeError, hash, self.first_proto)
+
+  def testSelfEquality(self):
+    self.assertEqual(self.first_proto, self.first_proto)
+
+  def testEmptyProtosEqual(self):
+    self.assertEqual(self.first_proto, self.second_proto)
+
+
+class FullProtosEqualityTest(unittest.TestCase):
+
+  """Equality tests using completely-full protos as a starting point."""
+
+  def setUp(self):
+    self.first_proto = unittest_pb2.TestAllTypes()
+    self.second_proto = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(self.first_proto)
+    test_util.SetAllFields(self.second_proto)
+
+  def testNotHashable(self):
+    self.assertRaises(TypeError, hash, self.first_proto)
+
+  def testNoneNotEqual(self):
+    self.assertNotEqual(self.first_proto, None)
+    self.assertNotEqual(None, self.second_proto)
+
+  def testNotEqualToOtherMessage(self):
+    third_proto = unittest_pb2.TestRequired()
+    self.assertNotEqual(self.first_proto, third_proto)
+    self.assertNotEqual(third_proto, self.second_proto)
+
+  def testAllFieldsFilledEquality(self):
+    self.assertEqual(self.first_proto, self.second_proto)
+
+  def testNonRepeatedScalar(self):
+    # Nonrepeated scalar field change should cause inequality.
+    self.first_proto.optional_int32 += 1
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    # ...as should clearing a field.
+    self.first_proto.ClearField('optional_int32')
+    self.assertNotEqual(self.first_proto, self.second_proto)
+
+  def testNonRepeatedComposite(self):
+    # Change a nonrepeated composite field.
+    self.first_proto.optional_nested_message.bb += 1
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    self.first_proto.optional_nested_message.bb -= 1
+    self.assertEqual(self.first_proto, self.second_proto)
+    # Clear a field in the nested message.
+    self.first_proto.optional_nested_message.ClearField('bb')
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    self.first_proto.optional_nested_message.bb = (
+        self.second_proto.optional_nested_message.bb)
+    self.assertEqual(self.first_proto, self.second_proto)
+    # Remove the nested message entirely.
+    self.first_proto.ClearField('optional_nested_message')
+    self.assertNotEqual(self.first_proto, self.second_proto)
+
+  def testRepeatedScalar(self):
+    # Change a repeated scalar field.
+    self.first_proto.repeated_int32.append(5)
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    self.first_proto.ClearField('repeated_int32')
+    self.assertNotEqual(self.first_proto, self.second_proto)
+
+  def testRepeatedComposite(self):
+    # Change value within a repeated composite field.
+    self.first_proto.repeated_nested_message[0].bb += 1
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    self.first_proto.repeated_nested_message[0].bb -= 1
+    self.assertEqual(self.first_proto, self.second_proto)
+    # Add a value to a repeated composite field.
+    self.first_proto.repeated_nested_message.add()
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    self.second_proto.repeated_nested_message.add()
+    self.assertEqual(self.first_proto, self.second_proto)
+
+  def testNonRepeatedScalarHasBits(self):
+    # Ensure that we test "has" bits as well as value for
+    # nonrepeated scalar field.
+    self.first_proto.ClearField('optional_int32')
+    self.second_proto.optional_int32 = 0
+    self.assertNotEqual(self.first_proto, self.second_proto)
+
+  def testNonRepeatedCompositeHasBits(self):
+    # Ensure that we test "has" bits as well as value for
+    # nonrepeated composite field.
+    self.first_proto.ClearField('optional_nested_message')
+    self.second_proto.optional_nested_message.ClearField('bb')
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    self.first_proto.optional_nested_message.bb = 0
+    self.first_proto.optional_nested_message.ClearField('bb')
+    self.assertEqual(self.first_proto, self.second_proto)
+
+
+class ExtensionEqualityTest(unittest.TestCase):
+
+  def testExtensionEquality(self):
+    first_proto = unittest_pb2.TestAllExtensions()
+    second_proto = unittest_pb2.TestAllExtensions()
+    self.assertEqual(first_proto, second_proto)
+    test_util.SetAllExtensions(first_proto)
+    self.assertNotEqual(first_proto, second_proto)
+    test_util.SetAllExtensions(second_proto)
+    self.assertEqual(first_proto, second_proto)
+
+    # Ensure that we check value equality.
+    first_proto.Extensions[unittest_pb2.optional_int32_extension] += 1
+    self.assertNotEqual(first_proto, second_proto)
+    first_proto.Extensions[unittest_pb2.optional_int32_extension] -= 1
+    self.assertEqual(first_proto, second_proto)
+
+    # Ensure that we also look at "has" bits.
+    first_proto.ClearExtension(unittest_pb2.optional_int32_extension)
+    second_proto.Extensions[unittest_pb2.optional_int32_extension] = 0
+    self.assertNotEqual(first_proto, second_proto)
+    first_proto.Extensions[unittest_pb2.optional_int32_extension] = 0
+    self.assertEqual(first_proto, second_proto)
+
+    # Ensure that differences in cached values
+    # don't matter if "has" bits are both false.
+    first_proto = unittest_pb2.TestAllExtensions()
+    second_proto = unittest_pb2.TestAllExtensions()
+    self.assertEqual(
+        0, first_proto.Extensions[unittest_pb2.optional_int32_extension])
+    self.assertEqual(first_proto, second_proto)
+
+
+class MutualRecursionEqualityTest(unittest.TestCase):
+
+  def testEqualityWithMutualRecursion(self):
+    first_proto = unittest_pb2.TestMutualRecursionA()
+    second_proto = unittest_pb2.TestMutualRecursionA()
+    self.assertEqual(first_proto, second_proto)
+    first_proto.bb.a.bb.optional_int32 = 23
+    self.assertNotEqual(first_proto, second_proto)
+    second_proto.bb.a.bb.optional_int32 = 23
+    self.assertEqual(first_proto, second_proto)
+
+
+class ByteSizeTest(unittest.TestCase):
+
+  def setUp(self):
+    self.proto = unittest_pb2.TestAllTypes()
+    self.extended_proto = more_extensions_pb2.ExtendedMessage()
+    self.packed_proto = unittest_pb2.TestPackedTypes()
+    self.packed_extended_proto = unittest_pb2.TestPackedExtensions()
+
+  def Size(self):
+    return self.proto.ByteSize()
+
+  def testEmptyMessage(self):
+    self.assertEqual(0, self.proto.ByteSize())
+
+  def testSizedOnKwargs(self):
+    # Use a separate message to ensure testing right after creation.
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(0, proto.ByteSize())
+    proto_kwargs = unittest_pb2.TestAllTypes(optional_int64 = 1)
+    # One byte for the tag, one to encode varint 1.
+    self.assertEqual(2, proto_kwargs.ByteSize())
+
+  def testVarints(self):
+    def Test(i, expected_varint_size):
+      self.proto.Clear()
+      self.proto.optional_int64 = i
+      # Add one to the varint size for the tag info
+      # for tag 1.
+      self.assertEqual(expected_varint_size + 1, self.Size())
+    Test(0, 1)
+    Test(1, 1)
+    for i, num_bytes in zip(range(7, 63, 7), range(1, 10000)):
+      Test((1 << i) - 1, num_bytes)
+    Test(-1, 10)
+    Test(-2, 10)
+    Test(-(1 << 63), 10)
+
+  def testStrings(self):
+    self.proto.optional_string = ''
+    # Need one byte for tag info (tag #14), and one byte for length.
+    self.assertEqual(2, self.Size())
+
+    self.proto.optional_string = 'abc'
+    # Need one byte for tag info (tag #14), and one byte for length.
+    self.assertEqual(2 + len(self.proto.optional_string), self.Size())
+
+    self.proto.optional_string = 'x' * 128
+    # Need one byte for tag info (tag #14), and TWO bytes for length.
+    self.assertEqual(3 + len(self.proto.optional_string), self.Size())
+
+  def testOtherNumerics(self):
+    self.proto.optional_fixed32 = 1234
+    # One byte for tag and 4 bytes for fixed32.
+    self.assertEqual(5, self.Size())
+    self.proto = unittest_pb2.TestAllTypes()
+
+    self.proto.optional_fixed64 = 1234
+    # One byte for tag and 8 bytes for fixed64.
+    self.assertEqual(9, self.Size())
+    self.proto = unittest_pb2.TestAllTypes()
+
+    self.proto.optional_float = 1.234
+    # One byte for tag and 4 bytes for float.
+    self.assertEqual(5, self.Size())
+    self.proto = unittest_pb2.TestAllTypes()
+
+    self.proto.optional_double = 1.234
+    # One byte for tag and 8 bytes for float.
+    self.assertEqual(9, self.Size())
+    self.proto = unittest_pb2.TestAllTypes()
+
+    self.proto.optional_sint32 = 64
+    # One byte for tag and 2 bytes for zig-zag-encoded 64.
+    self.assertEqual(3, self.Size())
+    self.proto = unittest_pb2.TestAllTypes()
+
+  def testComposites(self):
+    # 3 bytes.
+    self.proto.optional_nested_message.bb = (1 << 14)
+    # Plus one byte for bb tag.
+    # Plus 1 byte for optional_nested_message serialized size.
+    # Plus two bytes for optional_nested_message tag.
+    self.assertEqual(3 + 1 + 1 + 2, self.Size())
+
+  def testGroups(self):
+    # 4 bytes.
+    self.proto.optionalgroup.a = (1 << 21)
+    # Plus two bytes for |a| tag.
+    # Plus 2 * two bytes for START_GROUP and END_GROUP tags.
+    self.assertEqual(4 + 2 + 2*2, self.Size())
+
+  def testRepeatedScalars(self):
+    self.proto.repeated_int32.append(10)  # 1 byte.
+    self.proto.repeated_int32.append(128)  # 2 bytes.
+    # Also need 2 bytes for each entry for tag.
+    self.assertEqual(1 + 2 + 2*2, self.Size())
+
+  def testRepeatedScalarsExtend(self):
+    self.proto.repeated_int32.extend([10, 128])  # 3 bytes.
+    # Also need 2 bytes for each entry for tag.
+    self.assertEqual(1 + 2 + 2*2, self.Size())
+
+  def testRepeatedScalarsRemove(self):
+    self.proto.repeated_int32.append(10)  # 1 byte.
+    self.proto.repeated_int32.append(128)  # 2 bytes.
+    # Also need 2 bytes for each entry for tag.
+    self.assertEqual(1 + 2 + 2*2, self.Size())
+    self.proto.repeated_int32.remove(128)
+    self.assertEqual(1 + 2, self.Size())
+
+  def testRepeatedComposites(self):
+    # Empty message.  2 bytes tag plus 1 byte length.
+    foreign_message_0 = self.proto.repeated_nested_message.add()
+    # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+    foreign_message_1 = self.proto.repeated_nested_message.add()
+    foreign_message_1.bb = 7
+    self.assertEqual(2 + 1 + 2 + 1 + 1 + 1, self.Size())
+
+  def testRepeatedCompositesDelete(self):
+    # Empty message.  2 bytes tag plus 1 byte length.
+    foreign_message_0 = self.proto.repeated_nested_message.add()
+    # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+    foreign_message_1 = self.proto.repeated_nested_message.add()
+    foreign_message_1.bb = 9
+    self.assertEqual(2 + 1 + 2 + 1 + 1 + 1, self.Size())
+
+    # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+    del self.proto.repeated_nested_message[0]
+    self.assertEqual(2 + 1 + 1 + 1, self.Size())
+
+    # Now add a new message.
+    foreign_message_2 = self.proto.repeated_nested_message.add()
+    foreign_message_2.bb = 12
+
+    # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+    # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+    self.assertEqual(2 + 1 + 1 + 1 + 2 + 1 + 1 + 1, self.Size())
+
+    # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+    del self.proto.repeated_nested_message[1]
+    self.assertEqual(2 + 1 + 1 + 1, self.Size())
+
+    del self.proto.repeated_nested_message[0]
+    self.assertEqual(0, self.Size())
+
+  def testRepeatedGroups(self):
+    # 2-byte START_GROUP plus 2-byte END_GROUP.
+    group_0 = self.proto.repeatedgroup.add()
+    # 2-byte START_GROUP plus 2-byte |a| tag + 1-byte |a|
+    # plus 2-byte END_GROUP.
+    group_1 = self.proto.repeatedgroup.add()
+    group_1.a =  7
+    self.assertEqual(2 + 2 + 2 + 2 + 1 + 2, self.Size())
+
+  def testExtensions(self):
+    proto = unittest_pb2.TestAllExtensions()
+    self.assertEqual(0, proto.ByteSize())
+    extension = unittest_pb2.optional_int32_extension  # Field #1, 1 byte.
+    proto.Extensions[extension] = 23
+    # 1 byte for tag, 1 byte for value.
+    self.assertEqual(2, proto.ByteSize())
+
+  def testCacheInvalidationForNonrepeatedScalar(self):
+    # Test non-extension.
+    self.proto.optional_int32 = 1
+    self.assertEqual(2, self.proto.ByteSize())
+    self.proto.optional_int32 = 128
+    self.assertEqual(3, self.proto.ByteSize())
+    self.proto.ClearField('optional_int32')
+    self.assertEqual(0, self.proto.ByteSize())
+
+    # Test within extension.
+    extension = more_extensions_pb2.optional_int_extension
+    self.extended_proto.Extensions[extension] = 1
+    self.assertEqual(2, self.extended_proto.ByteSize())
+    self.extended_proto.Extensions[extension] = 128
+    self.assertEqual(3, self.extended_proto.ByteSize())
+    self.extended_proto.ClearExtension(extension)
+    self.assertEqual(0, self.extended_proto.ByteSize())
+
+  def testCacheInvalidationForRepeatedScalar(self):
+    # Test non-extension.
+    self.proto.repeated_int32.append(1)
+    self.assertEqual(3, self.proto.ByteSize())
+    self.proto.repeated_int32.append(1)
+    self.assertEqual(6, self.proto.ByteSize())
+    self.proto.repeated_int32[1] = 128
+    self.assertEqual(7, self.proto.ByteSize())
+    self.proto.ClearField('repeated_int32')
+    self.assertEqual(0, self.proto.ByteSize())
+
+    # Test within extension.
+    extension = more_extensions_pb2.repeated_int_extension
+    repeated = self.extended_proto.Extensions[extension]
+    repeated.append(1)
+    self.assertEqual(2, self.extended_proto.ByteSize())
+    repeated.append(1)
+    self.assertEqual(4, self.extended_proto.ByteSize())
+    repeated[1] = 128
+    self.assertEqual(5, self.extended_proto.ByteSize())
+    self.extended_proto.ClearExtension(extension)
+    self.assertEqual(0, self.extended_proto.ByteSize())
+
+  def testCacheInvalidationForNonrepeatedMessage(self):
+    # Test non-extension.
+    self.proto.optional_foreign_message.c = 1
+    self.assertEqual(5, self.proto.ByteSize())
+    self.proto.optional_foreign_message.c = 128
+    self.assertEqual(6, self.proto.ByteSize())
+    self.proto.optional_foreign_message.ClearField('c')
+    self.assertEqual(3, self.proto.ByteSize())
+    self.proto.ClearField('optional_foreign_message')
+    self.assertEqual(0, self.proto.ByteSize())
+
+    if api_implementation.Type() == 'python':
+      # This is only possible in pure-Python implementation of the API.
+      child = self.proto.optional_foreign_message
+      self.proto.ClearField('optional_foreign_message')
+      child.c = 128
+      self.assertEqual(0, self.proto.ByteSize())
+
+    # Test within extension.
+    extension = more_extensions_pb2.optional_message_extension
+    child = self.extended_proto.Extensions[extension]
+    self.assertEqual(0, self.extended_proto.ByteSize())
+    child.foreign_message_int = 1
+    self.assertEqual(4, self.extended_proto.ByteSize())
+    child.foreign_message_int = 128
+    self.assertEqual(5, self.extended_proto.ByteSize())
+    self.extended_proto.ClearExtension(extension)
+    self.assertEqual(0, self.extended_proto.ByteSize())
+
+  def testCacheInvalidationForRepeatedMessage(self):
+    # Test non-extension.
+    child0 = self.proto.repeated_foreign_message.add()
+    self.assertEqual(3, self.proto.ByteSize())
+    self.proto.repeated_foreign_message.add()
+    self.assertEqual(6, self.proto.ByteSize())
+    child0.c = 1
+    self.assertEqual(8, self.proto.ByteSize())
+    self.proto.ClearField('repeated_foreign_message')
+    self.assertEqual(0, self.proto.ByteSize())
+
+    # Test within extension.
+    extension = more_extensions_pb2.repeated_message_extension
+    child_list = self.extended_proto.Extensions[extension]
+    child0 = child_list.add()
+    self.assertEqual(2, self.extended_proto.ByteSize())
+    child_list.add()
+    self.assertEqual(4, self.extended_proto.ByteSize())
+    child0.foreign_message_int = 1
+    self.assertEqual(6, self.extended_proto.ByteSize())
+    child0.ClearField('foreign_message_int')
+    self.assertEqual(4, self.extended_proto.ByteSize())
+    self.extended_proto.ClearExtension(extension)
+    self.assertEqual(0, self.extended_proto.ByteSize())
+
+  def testPackedRepeatedScalars(self):
+    self.assertEqual(0, self.packed_proto.ByteSize())
+
+    self.packed_proto.packed_int32.append(10)   # 1 byte.
+    self.packed_proto.packed_int32.append(128)  # 2 bytes.
+    # The tag is 2 bytes (the field number is 90), and the varint
+    # storing the length is 1 byte.
+    int_size = 1 + 2 + 3
+    self.assertEqual(int_size, self.packed_proto.ByteSize())
+
+    self.packed_proto.packed_double.append(4.2)   # 8 bytes
+    self.packed_proto.packed_double.append(3.25)  # 8 bytes
+    # 2 more tag bytes, 1 more length byte.
+    double_size = 8 + 8 + 3
+    self.assertEqual(int_size+double_size, self.packed_proto.ByteSize())
+
+    self.packed_proto.ClearField('packed_int32')
+    self.assertEqual(double_size, self.packed_proto.ByteSize())
+
+  def testPackedExtensions(self):
+    self.assertEqual(0, self.packed_extended_proto.ByteSize())
+    extension = self.packed_extended_proto.Extensions[
+        unittest_pb2.packed_fixed32_extension]
+    extension.extend([1, 2, 3, 4])   # 16 bytes
+    # Tag is 3 bytes.
+    self.assertEqual(19, self.packed_extended_proto.ByteSize())
+
+
+# Issues to be sure to cover include:
+#   * Handling of unrecognized tags ("uninterpreted_bytes").
+#   * Handling of MessageSets.
+#   * Consistent ordering of tags in the wire format,
+#     including ordering between extensions and non-extension
+#     fields.
+#   * Consistent serialization of negative numbers, especially
+#     negative int32s.
+#   * Handling of empty submessages (with and without "has"
+#     bits set).
+
+class SerializationTest(unittest.TestCase):
+
+  def testSerializeEmtpyMessage(self):
+    first_proto = unittest_pb2.TestAllTypes()
+    second_proto = unittest_pb2.TestAllTypes()
+    serialized = first_proto.SerializeToString()
+    self.assertEqual(first_proto.ByteSize(), len(serialized))
+    self.assertEqual(
+        len(serialized),
+        second_proto.MergeFromString(serialized))
+    self.assertEqual(first_proto, second_proto)
+
+  def testSerializeAllFields(self):
+    first_proto = unittest_pb2.TestAllTypes()
+    second_proto = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(first_proto)
+    serialized = first_proto.SerializeToString()
+    self.assertEqual(first_proto.ByteSize(), len(serialized))
+    self.assertEqual(
+        len(serialized),
+        second_proto.MergeFromString(serialized))
+    self.assertEqual(first_proto, second_proto)
+
+  def testSerializeAllExtensions(self):
+    first_proto = unittest_pb2.TestAllExtensions()
+    second_proto = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(first_proto)
+    serialized = first_proto.SerializeToString()
+    self.assertEqual(
+        len(serialized),
+        second_proto.MergeFromString(serialized))
+    self.assertEqual(first_proto, second_proto)
+
+  def testSerializeWithOptionalGroup(self):
+    first_proto = unittest_pb2.TestAllTypes()
+    second_proto = unittest_pb2.TestAllTypes()
+    first_proto.optionalgroup.a = 242
+    serialized = first_proto.SerializeToString()
+    self.assertEqual(
+        len(serialized),
+        second_proto.MergeFromString(serialized))
+    self.assertEqual(first_proto, second_proto)
+
+  def testSerializeNegativeValues(self):
+    first_proto = unittest_pb2.TestAllTypes()
+
+    first_proto.optional_int32 = -1
+    first_proto.optional_int64 = -(2 << 40)
+    first_proto.optional_sint32 = -3
+    first_proto.optional_sint64 = -(4 << 40)
+    first_proto.optional_sfixed32 = -5
+    first_proto.optional_sfixed64 = -(6 << 40)
+
+    second_proto = unittest_pb2.TestAllTypes.FromString(
+        first_proto.SerializeToString())
+
+    self.assertEqual(first_proto, second_proto)
+
+  def testParseTruncated(self):
+    # This test is only applicable for the Python implementation of the API.
+    if api_implementation.Type() != 'python':
+      return
+
+    first_proto = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(first_proto)
+    serialized = first_proto.SerializeToString()
+
+    for truncation_point in range(len(serialized) + 1):
+      try:
+        second_proto = unittest_pb2.TestAllTypes()
+        unknown_fields = unittest_pb2.TestEmptyMessage()
+        pos = second_proto._InternalParse(serialized, 0, truncation_point)
+        # If we didn't raise an error then we read exactly the amount expected.
+        self.assertEqual(truncation_point, pos)
+
+        # Parsing to unknown fields should not throw if parsing to known fields
+        # did not.
+        try:
+          pos2 = unknown_fields._InternalParse(serialized, 0, truncation_point)
+          self.assertEqual(truncation_point, pos2)
+        except message.DecodeError:
+          self.fail('Parsing unknown fields failed when parsing known fields '
+                    'did not.')
+      except message.DecodeError:
+        # Parsing unknown fields should also fail.
+        self.assertRaises(message.DecodeError, unknown_fields._InternalParse,
+                          serialized, 0, truncation_point)
+
+  def testCanonicalSerializationOrder(self):
+    proto = more_messages_pb2.OutOfOrderFields()
+    # These are also their tag numbers.  Even though we're setting these in
+    # reverse-tag order AND they're listed in reverse tag-order in the .proto
+    # file, they should nonetheless be serialized in tag order.
+    proto.optional_sint32 = 5
+    proto.Extensions[more_messages_pb2.optional_uint64] = 4
+    proto.optional_uint32 = 3
+    proto.Extensions[more_messages_pb2.optional_int64] = 2
+    proto.optional_int32 = 1
+    serialized = proto.SerializeToString()
+    self.assertEqual(proto.ByteSize(), len(serialized))
+    d = _MiniDecoder(serialized)
+    ReadTag = d.ReadFieldNumberAndWireType
+    self.assertEqual((1, wire_format.WIRETYPE_VARINT), ReadTag())
+    self.assertEqual(1, d.ReadInt32())
+    self.assertEqual((2, wire_format.WIRETYPE_VARINT), ReadTag())
+    self.assertEqual(2, d.ReadInt64())
+    self.assertEqual((3, wire_format.WIRETYPE_VARINT), ReadTag())
+    self.assertEqual(3, d.ReadUInt32())
+    self.assertEqual((4, wire_format.WIRETYPE_VARINT), ReadTag())
+    self.assertEqual(4, d.ReadUInt64())
+    self.assertEqual((5, wire_format.WIRETYPE_VARINT), ReadTag())
+    self.assertEqual(5, d.ReadSInt32())
+
+  def testCanonicalSerializationOrderSameAsCpp(self):
+    # Copy of the same test we use for C++.
+    proto = unittest_pb2.TestFieldOrderings()
+    test_util.SetAllFieldsAndExtensions(proto)
+    serialized = proto.SerializeToString()
+    test_util.ExpectAllFieldsAndExtensionsInOrder(serialized)
+
+  def testMergeFromStringWhenFieldsAlreadySet(self):
+    first_proto = unittest_pb2.TestAllTypes()
+    first_proto.repeated_string.append('foobar')
+    first_proto.optional_int32 = 23
+    first_proto.optional_nested_message.bb = 42
+    serialized = first_proto.SerializeToString()
+
+    second_proto = unittest_pb2.TestAllTypes()
+    second_proto.repeated_string.append('baz')
+    second_proto.optional_int32 = 100
+    second_proto.optional_nested_message.bb = 999
+
+    bytes_parsed = second_proto.MergeFromString(serialized)
+    self.assertEqual(len(serialized), bytes_parsed)
+
+    # Ensure that we append to repeated fields.
+    self.assertEqual(['baz', 'foobar'], list(second_proto.repeated_string))
+    # Ensure that we overwrite nonrepeatd scalars.
+    self.assertEqual(23, second_proto.optional_int32)
+    # Ensure that we recursively call MergeFromString() on
+    # submessages.
+    self.assertEqual(42, second_proto.optional_nested_message.bb)
+
+  def testMessageSetWireFormat(self):
+    proto = message_set_extensions_pb2.TestMessageSet()
+    extension_message1 = message_set_extensions_pb2.TestMessageSetExtension1
+    extension_message2 = message_set_extensions_pb2.TestMessageSetExtension2
+    extension1 = extension_message1.message_set_extension
+    extension2 = extension_message2.message_set_extension
+    extension3 = message_set_extensions_pb2.message_set_extension3
+    proto.Extensions[extension1].i = 123
+    proto.Extensions[extension2].str = 'foo'
+    proto.Extensions[extension3].text = 'bar'
+
+    # Serialize using the MessageSet wire format (this is specified in the
+    # .proto file).
+    serialized = proto.SerializeToString()
+
+    raw = unittest_mset_pb2.RawMessageSet()
+    self.assertEqual(False,
+                     raw.DESCRIPTOR.GetOptions().message_set_wire_format)
+    self.assertEqual(
+        len(serialized),
+        raw.MergeFromString(serialized))
+    self.assertEqual(3, len(raw.item))
+
+    message1 = message_set_extensions_pb2.TestMessageSetExtension1()
+    self.assertEqual(
+        len(raw.item[0].message),
+        message1.MergeFromString(raw.item[0].message))
+    self.assertEqual(123, message1.i)
+
+    message2 = message_set_extensions_pb2.TestMessageSetExtension2()
+    self.assertEqual(
+        len(raw.item[1].message),
+        message2.MergeFromString(raw.item[1].message))
+    self.assertEqual('foo', message2.str)
+
+    message3 = message_set_extensions_pb2.TestMessageSetExtension3()
+    self.assertEqual(
+        len(raw.item[2].message),
+        message3.MergeFromString(raw.item[2].message))
+    self.assertEqual('bar', message3.text)
+
+    # Deserialize using the MessageSet wire format.
+    proto2 = message_set_extensions_pb2.TestMessageSet()
+    self.assertEqual(
+        len(serialized),
+        proto2.MergeFromString(serialized))
+    self.assertEqual(123, proto2.Extensions[extension1].i)
+    self.assertEqual('foo', proto2.Extensions[extension2].str)
+    self.assertEqual('bar', proto2.Extensions[extension3].text)
+
+    # Check byte size.
+    self.assertEqual(proto2.ByteSize(), len(serialized))
+    self.assertEqual(proto.ByteSize(), len(serialized))
+
+  def testMessageSetWireFormatUnknownExtension(self):
+    # Create a message using the message set wire format with an unknown
+    # message.
+    raw = unittest_mset_pb2.RawMessageSet()
+
+    # Add an item.
+    item = raw.item.add()
+    item.type_id = 98418603
+    extension_message1 = message_set_extensions_pb2.TestMessageSetExtension1
+    message1 = message_set_extensions_pb2.TestMessageSetExtension1()
+    message1.i = 12345
+    item.message = message1.SerializeToString()
+
+    # Add a second, unknown extension.
+    item = raw.item.add()
+    item.type_id = 98418604
+    extension_message1 = message_set_extensions_pb2.TestMessageSetExtension1
+    message1 = message_set_extensions_pb2.TestMessageSetExtension1()
+    message1.i = 12346
+    item.message = message1.SerializeToString()
+
+    # Add another unknown extension.
+    item = raw.item.add()
+    item.type_id = 98418605
+    message1 = message_set_extensions_pb2.TestMessageSetExtension2()
+    message1.str = 'foo'
+    item.message = message1.SerializeToString()
+
+    serialized = raw.SerializeToString()
+
+    # Parse message using the message set wire format.
+    proto = message_set_extensions_pb2.TestMessageSet()
+    self.assertEqual(
+        len(serialized),
+        proto.MergeFromString(serialized))
+
+    # Check that the message parsed well.
+    extension_message1 = message_set_extensions_pb2.TestMessageSetExtension1
+    extension1 = extension_message1.message_set_extension
+    self.assertEqual(12345, proto.Extensions[extension1].i)
+
+  def testUnknownFields(self):
+    proto = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(proto)
+
+    serialized = proto.SerializeToString()
+
+    # The empty message should be parsable with all of the fields
+    # unknown.
+    proto2 = unittest_pb2.TestEmptyMessage()
+
+    # Parsing this message should succeed.
+    self.assertEqual(
+        len(serialized),
+        proto2.MergeFromString(serialized))
+
+    # Now test with a int64 field set.
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_int64 = 0x0fffffffffffffff
+    serialized = proto.SerializeToString()
+    # The empty message should be parsable with all of the fields
+    # unknown.
+    proto2 = unittest_pb2.TestEmptyMessage()
+    # Parsing this message should succeed.
+    self.assertEqual(
+        len(serialized),
+        proto2.MergeFromString(serialized))
+
+  def _CheckRaises(self, exc_class, callable_obj, exception):
+    """This method checks if the excpetion type and message are as expected."""
+    try:
+      callable_obj()
+    except exc_class as ex:
+      # Check if the exception message is the right one.
+      self.assertEqual(exception, str(ex))
+      return
+    else:
+      raise self.failureException('%s not raised' % str(exc_class))
+
+  def testSerializeUninitialized(self):
+    proto = unittest_pb2.TestRequired()
+    self._CheckRaises(
+        message.EncodeError,
+        proto.SerializeToString,
+        'Message protobuf_unittest.TestRequired is missing required fields: '
+        'a,b,c')
+    # Shouldn't raise exceptions.
+    partial = proto.SerializePartialToString()
+
+    proto2 = unittest_pb2.TestRequired()
+    self.assertFalse(proto2.HasField('a'))
+    # proto2 ParseFromString does not check that required fields are set.
+    proto2.ParseFromString(partial)
+    self.assertFalse(proto2.HasField('a'))
+
+    proto.a = 1
+    self._CheckRaises(
+        message.EncodeError,
+        proto.SerializeToString,
+        'Message protobuf_unittest.TestRequired is missing required fields: b,c')
+    # Shouldn't raise exceptions.
+    partial = proto.SerializePartialToString()
+
+    proto.b = 2
+    self._CheckRaises(
+        message.EncodeError,
+        proto.SerializeToString,
+        'Message protobuf_unittest.TestRequired is missing required fields: c')
+    # Shouldn't raise exceptions.
+    partial = proto.SerializePartialToString()
+
+    proto.c = 3
+    serialized = proto.SerializeToString()
+    # Shouldn't raise exceptions.
+    partial = proto.SerializePartialToString()
+
+    proto2 = unittest_pb2.TestRequired()
+    self.assertEqual(
+        len(serialized),
+        proto2.MergeFromString(serialized))
+    self.assertEqual(1, proto2.a)
+    self.assertEqual(2, proto2.b)
+    self.assertEqual(3, proto2.c)
+    self.assertEqual(
+        len(partial),
+        proto2.MergeFromString(partial))
+    self.assertEqual(1, proto2.a)
+    self.assertEqual(2, proto2.b)
+    self.assertEqual(3, proto2.c)
+
+  def testSerializeUninitializedSubMessage(self):
+    proto = unittest_pb2.TestRequiredForeign()
+
+    # Sub-message doesn't exist yet, so this succeeds.
+    proto.SerializeToString()
+
+    proto.optional_message.a = 1
+    self._CheckRaises(
+        message.EncodeError,
+        proto.SerializeToString,
+        'Message protobuf_unittest.TestRequiredForeign '
+        'is missing required fields: '
+        'optional_message.b,optional_message.c')
+
+    proto.optional_message.b = 2
+    proto.optional_message.c = 3
+    proto.SerializeToString()
+
+    proto.repeated_message.add().a = 1
+    proto.repeated_message.add().b = 2
+    self._CheckRaises(
+        message.EncodeError,
+        proto.SerializeToString,
+        'Message protobuf_unittest.TestRequiredForeign is missing required fields: '
+        'repeated_message[0].b,repeated_message[0].c,'
+        'repeated_message[1].a,repeated_message[1].c')
+
+    proto.repeated_message[0].b = 2
+    proto.repeated_message[0].c = 3
+    proto.repeated_message[1].a = 1
+    proto.repeated_message[1].c = 3
+    proto.SerializeToString()
+
+  def testSerializeAllPackedFields(self):
+    first_proto = unittest_pb2.TestPackedTypes()
+    second_proto = unittest_pb2.TestPackedTypes()
+    test_util.SetAllPackedFields(first_proto)
+    serialized = first_proto.SerializeToString()
+    self.assertEqual(first_proto.ByteSize(), len(serialized))
+    bytes_read = second_proto.MergeFromString(serialized)
+    self.assertEqual(second_proto.ByteSize(), bytes_read)
+    self.assertEqual(first_proto, second_proto)
+
+  def testSerializeAllPackedExtensions(self):
+    first_proto = unittest_pb2.TestPackedExtensions()
+    second_proto = unittest_pb2.TestPackedExtensions()
+    test_util.SetAllPackedExtensions(first_proto)
+    serialized = first_proto.SerializeToString()
+    bytes_read = second_proto.MergeFromString(serialized)
+    self.assertEqual(second_proto.ByteSize(), bytes_read)
+    self.assertEqual(first_proto, second_proto)
+
+  def testMergePackedFromStringWhenSomeFieldsAlreadySet(self):
+    first_proto = unittest_pb2.TestPackedTypes()
+    first_proto.packed_int32.extend([1, 2])
+    first_proto.packed_double.append(3.0)
+    serialized = first_proto.SerializeToString()
+
+    second_proto = unittest_pb2.TestPackedTypes()
+    second_proto.packed_int32.append(3)
+    second_proto.packed_double.extend([1.0, 2.0])
+    second_proto.packed_sint32.append(4)
+
+    self.assertEqual(
+        len(serialized),
+        second_proto.MergeFromString(serialized))
+    self.assertEqual([3, 1, 2], second_proto.packed_int32)
+    self.assertEqual([1.0, 2.0, 3.0], second_proto.packed_double)
+    self.assertEqual([4], second_proto.packed_sint32)
+
+  def testPackedFieldsWireFormat(self):
+    proto = unittest_pb2.TestPackedTypes()
+    proto.packed_int32.extend([1, 2, 150, 3])  # 1 + 1 + 2 + 1 bytes
+    proto.packed_double.extend([1.0, 1000.0])  # 8 + 8 bytes
+    proto.packed_float.append(2.0)             # 4 bytes, will be before double
+    serialized = proto.SerializeToString()
+    self.assertEqual(proto.ByteSize(), len(serialized))
+    d = _MiniDecoder(serialized)
+    ReadTag = d.ReadFieldNumberAndWireType
+    self.assertEqual((90, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
+    self.assertEqual(1+1+1+2, d.ReadInt32())
+    self.assertEqual(1, d.ReadInt32())
+    self.assertEqual(2, d.ReadInt32())
+    self.assertEqual(150, d.ReadInt32())
+    self.assertEqual(3, d.ReadInt32())
+    self.assertEqual((100, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
+    self.assertEqual(4, d.ReadInt32())
+    self.assertEqual(2.0, d.ReadFloat())
+    self.assertEqual((101, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
+    self.assertEqual(8+8, d.ReadInt32())
+    self.assertEqual(1.0, d.ReadDouble())
+    self.assertEqual(1000.0, d.ReadDouble())
+    self.assertTrue(d.EndOfStream())
+
+  def testParsePackedFromUnpacked(self):
+    unpacked = unittest_pb2.TestUnpackedTypes()
+    test_util.SetAllUnpackedFields(unpacked)
+    packed = unittest_pb2.TestPackedTypes()
+    serialized = unpacked.SerializeToString()
+    self.assertEqual(
+        len(serialized),
+        packed.MergeFromString(serialized))
+    expected = unittest_pb2.TestPackedTypes()
+    test_util.SetAllPackedFields(expected)
+    self.assertEqual(expected, packed)
+
+  def testParseUnpackedFromPacked(self):
+    packed = unittest_pb2.TestPackedTypes()
+    test_util.SetAllPackedFields(packed)
+    unpacked = unittest_pb2.TestUnpackedTypes()
+    serialized = packed.SerializeToString()
+    self.assertEqual(
+        len(serialized),
+        unpacked.MergeFromString(serialized))
+    expected = unittest_pb2.TestUnpackedTypes()
+    test_util.SetAllUnpackedFields(expected)
+    self.assertEqual(expected, unpacked)
+
+  def testFieldNumbers(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(unittest_pb2.TestAllTypes.NestedMessage.BB_FIELD_NUMBER, 1)
+    self.assertEqual(unittest_pb2.TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER, 1)
+    self.assertEqual(unittest_pb2.TestAllTypes.OPTIONALGROUP_FIELD_NUMBER, 16)
+    self.assertEqual(
+      unittest_pb2.TestAllTypes.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER, 18)
+    self.assertEqual(
+      unittest_pb2.TestAllTypes.OPTIONAL_NESTED_ENUM_FIELD_NUMBER, 21)
+    self.assertEqual(unittest_pb2.TestAllTypes.REPEATED_INT32_FIELD_NUMBER, 31)
+    self.assertEqual(unittest_pb2.TestAllTypes.REPEATEDGROUP_FIELD_NUMBER, 46)
+    self.assertEqual(
+      unittest_pb2.TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER, 48)
+    self.assertEqual(
+      unittest_pb2.TestAllTypes.REPEATED_NESTED_ENUM_FIELD_NUMBER, 51)
+
+  def testExtensionFieldNumbers(self):
+    self.assertEqual(unittest_pb2.TestRequired.single.number, 1000)
+    self.assertEqual(unittest_pb2.TestRequired.SINGLE_FIELD_NUMBER, 1000)
+    self.assertEqual(unittest_pb2.TestRequired.multi.number, 1001)
+    self.assertEqual(unittest_pb2.TestRequired.MULTI_FIELD_NUMBER, 1001)
+    self.assertEqual(unittest_pb2.optional_int32_extension.number, 1)
+    self.assertEqual(unittest_pb2.OPTIONAL_INT32_EXTENSION_FIELD_NUMBER, 1)
+    self.assertEqual(unittest_pb2.optionalgroup_extension.number, 16)
+    self.assertEqual(unittest_pb2.OPTIONALGROUP_EXTENSION_FIELD_NUMBER, 16)
+    self.assertEqual(unittest_pb2.optional_nested_message_extension.number, 18)
+    self.assertEqual(
+      unittest_pb2.OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 18)
+    self.assertEqual(unittest_pb2.optional_nested_enum_extension.number, 21)
+    self.assertEqual(unittest_pb2.OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER,
+      21)
+    self.assertEqual(unittest_pb2.repeated_int32_extension.number, 31)
+    self.assertEqual(unittest_pb2.REPEATED_INT32_EXTENSION_FIELD_NUMBER, 31)
+    self.assertEqual(unittest_pb2.repeatedgroup_extension.number, 46)
+    self.assertEqual(unittest_pb2.REPEATEDGROUP_EXTENSION_FIELD_NUMBER, 46)
+    self.assertEqual(unittest_pb2.repeated_nested_message_extension.number, 48)
+    self.assertEqual(
+      unittest_pb2.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 48)
+    self.assertEqual(unittest_pb2.repeated_nested_enum_extension.number, 51)
+    self.assertEqual(unittest_pb2.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER,
+      51)
+
+  def testInitKwargs(self):
+    proto = unittest_pb2.TestAllTypes(
+        optional_int32=1,
+        optional_string='foo',
+        optional_bool=True,
+        optional_bytes=b'bar',
+        optional_nested_message=unittest_pb2.TestAllTypes.NestedMessage(bb=1),
+        optional_foreign_message=unittest_pb2.ForeignMessage(c=1),
+        optional_nested_enum=unittest_pb2.TestAllTypes.FOO,
+        optional_foreign_enum=unittest_pb2.FOREIGN_FOO,
+        repeated_int32=[1, 2, 3])
+    self.assertTrue(proto.IsInitialized())
+    self.assertTrue(proto.HasField('optional_int32'))
+    self.assertTrue(proto.HasField('optional_string'))
+    self.assertTrue(proto.HasField('optional_bool'))
+    self.assertTrue(proto.HasField('optional_bytes'))
+    self.assertTrue(proto.HasField('optional_nested_message'))
+    self.assertTrue(proto.HasField('optional_foreign_message'))
+    self.assertTrue(proto.HasField('optional_nested_enum'))
+    self.assertTrue(proto.HasField('optional_foreign_enum'))
+    self.assertEqual(1, proto.optional_int32)
+    self.assertEqual('foo', proto.optional_string)
+    self.assertEqual(True, proto.optional_bool)
+    self.assertEqual(b'bar', proto.optional_bytes)
+    self.assertEqual(1, proto.optional_nested_message.bb)
+    self.assertEqual(1, proto.optional_foreign_message.c)
+    self.assertEqual(unittest_pb2.TestAllTypes.FOO,
+                     proto.optional_nested_enum)
+    self.assertEqual(unittest_pb2.FOREIGN_FOO, proto.optional_foreign_enum)
+    self.assertEqual([1, 2, 3], proto.repeated_int32)
+
+  def testInitArgsUnknownFieldName(self):
+    def InitalizeEmptyMessageWithExtraKeywordArg():
+      unused_proto = unittest_pb2.TestEmptyMessage(unknown='unknown')
+    self._CheckRaises(
+        ValueError,
+        InitalizeEmptyMessageWithExtraKeywordArg,
+        'Protocol message TestEmptyMessage has no "unknown" field.')
+
+  def testInitRequiredKwargs(self):
+    proto = unittest_pb2.TestRequired(a=1, b=1, c=1)
+    self.assertTrue(proto.IsInitialized())
+    self.assertTrue(proto.HasField('a'))
+    self.assertTrue(proto.HasField('b'))
+    self.assertTrue(proto.HasField('c'))
+    self.assertTrue(not proto.HasField('dummy2'))
+    self.assertEqual(1, proto.a)
+    self.assertEqual(1, proto.b)
+    self.assertEqual(1, proto.c)
+
+  def testInitRequiredForeignKwargs(self):
+    proto = unittest_pb2.TestRequiredForeign(
+        optional_message=unittest_pb2.TestRequired(a=1, b=1, c=1))
+    self.assertTrue(proto.IsInitialized())
+    self.assertTrue(proto.HasField('optional_message'))
+    self.assertTrue(proto.optional_message.IsInitialized())
+    self.assertTrue(proto.optional_message.HasField('a'))
+    self.assertTrue(proto.optional_message.HasField('b'))
+    self.assertTrue(proto.optional_message.HasField('c'))
+    self.assertTrue(not proto.optional_message.HasField('dummy2'))
+    self.assertEqual(unittest_pb2.TestRequired(a=1, b=1, c=1),
+                     proto.optional_message)
+    self.assertEqual(1, proto.optional_message.a)
+    self.assertEqual(1, proto.optional_message.b)
+    self.assertEqual(1, proto.optional_message.c)
+
+  def testInitRepeatedKwargs(self):
+    proto = unittest_pb2.TestAllTypes(repeated_int32=[1, 2, 3])
+    self.assertTrue(proto.IsInitialized())
+    self.assertEqual(1, proto.repeated_int32[0])
+    self.assertEqual(2, proto.repeated_int32[1])
+    self.assertEqual(3, proto.repeated_int32[2])
+
+
+class OptionsTest(unittest.TestCase):
+
+  def testMessageOptions(self):
+    proto = message_set_extensions_pb2.TestMessageSet()
+    self.assertEqual(True,
+                     proto.DESCRIPTOR.GetOptions().message_set_wire_format)
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(False,
+                     proto.DESCRIPTOR.GetOptions().message_set_wire_format)
+
+  def testPackedOptions(self):
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_int32 = 1
+    proto.optional_double = 3.0
+    for field_descriptor, _ in proto.ListFields():
+      self.assertEqual(False, field_descriptor.GetOptions().packed)
+
+    proto = unittest_pb2.TestPackedTypes()
+    proto.packed_int32.append(1)
+    proto.packed_double.append(3.0)
+    for field_descriptor, _ in proto.ListFields():
+      self.assertEqual(True, field_descriptor.GetOptions().packed)
+      self.assertEqual(descriptor.FieldDescriptor.LABEL_REPEATED,
+                       field_descriptor.label)
+
+
+
+class ClassAPITest(unittest.TestCase):
+
+  @unittest.skipIf(
+      api_implementation.Type() == 'cpp' and api_implementation.Version() == 2,
+      'C++ implementation requires a call to MakeDescriptor()')
+  def testMakeClassWithNestedDescriptor(self):
+    leaf_desc = descriptor.Descriptor('leaf', 'package.parent.child.leaf', '',
+                                      containing_type=None, fields=[],
+                                      nested_types=[], enum_types=[],
+                                      extensions=[])
+    child_desc = descriptor.Descriptor('child', 'package.parent.child', '',
+                                       containing_type=None, fields=[],
+                                       nested_types=[leaf_desc], enum_types=[],
+                                       extensions=[])
+    sibling_desc = descriptor.Descriptor('sibling', 'package.parent.sibling',
+                                         '', containing_type=None, fields=[],
+                                         nested_types=[], enum_types=[],
+                                         extensions=[])
+    parent_desc = descriptor.Descriptor('parent', 'package.parent', '',
+                                        containing_type=None, fields=[],
+                                        nested_types=[child_desc, sibling_desc],
+                                        enum_types=[], extensions=[])
+    message_class = reflection.MakeClass(parent_desc)
+    self.assertIn('child', message_class.__dict__)
+    self.assertIn('sibling', message_class.__dict__)
+    self.assertIn('leaf', message_class.child.__dict__)
+
+  def _GetSerializedFileDescriptor(self, name):
+    """Get a serialized representation of a test FileDescriptorProto.
+
+    Args:
+      name: All calls to this must use a unique message name, to avoid
+          collisions in the cpp descriptor pool.
+    Returns:
+      A string containing the serialized form of a test FileDescriptorProto.
+    """
+    file_descriptor_str = (
+        'message_type {'
+        '  name: "' + name + '"'
+        '  field {'
+        '    name: "flat"'
+        '    number: 1'
+        '    label: LABEL_REPEATED'
+        '    type: TYPE_UINT32'
+        '  }'
+        '  field {'
+        '    name: "bar"'
+        '    number: 2'
+        '    label: LABEL_OPTIONAL'
+        '    type: TYPE_MESSAGE'
+        '    type_name: "Bar"'
+        '  }'
+        '  nested_type {'
+        '    name: "Bar"'
+        '    field {'
+        '      name: "baz"'
+        '      number: 3'
+        '      label: LABEL_OPTIONAL'
+        '      type: TYPE_MESSAGE'
+        '      type_name: "Baz"'
+        '    }'
+        '    nested_type {'
+        '      name: "Baz"'
+        '      enum_type {'
+        '        name: "deep_enum"'
+        '        value {'
+        '          name: "VALUE_A"'
+        '          number: 0'
+        '        }'
+        '      }'
+        '      field {'
+        '        name: "deep"'
+        '        number: 4'
+        '        label: LABEL_OPTIONAL'
+        '        type: TYPE_UINT32'
+        '      }'
+        '    }'
+        '  }'
+        '}')
+    file_descriptor = descriptor_pb2.FileDescriptorProto()
+    text_format.Merge(file_descriptor_str, file_descriptor)
+    return file_descriptor.SerializeToString()
+
+  def testParsingFlatClassWithExplicitClassDeclaration(self):
+    """Test that the generated class can parse a flat message."""
+    # TODO(xiaofeng): This test fails with cpp implemetnation in the call
+    # of six.with_metaclass(). The other two callsites of with_metaclass
+    # in this file are both excluded from cpp test, so it might be expected
+    # to fail. Need someone more familiar with the python code to take a
+    # look at this.
+    if api_implementation.Type() != 'python':
+      return
+    file_descriptor = descriptor_pb2.FileDescriptorProto()
+    file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('A'))
+    msg_descriptor = descriptor.MakeDescriptor(
+        file_descriptor.message_type[0])
+
+    class MessageClass(six.with_metaclass(reflection.GeneratedProtocolMessageType, message.Message)):
+      DESCRIPTOR = msg_descriptor
+    msg = MessageClass()
+    msg_str = (
+        'flat: 0 '
+        'flat: 1 '
+        'flat: 2 ')
+    text_format.Merge(msg_str, msg)
+    self.assertEqual(msg.flat, [0, 1, 2])
+
+  def testParsingFlatClass(self):
+    """Test that the generated class can parse a flat message."""
+    file_descriptor = descriptor_pb2.FileDescriptorProto()
+    file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('B'))
+    msg_descriptor = descriptor.MakeDescriptor(
+        file_descriptor.message_type[0])
+    msg_class = reflection.MakeClass(msg_descriptor)
+    msg = msg_class()
+    msg_str = (
+        'flat: 0 '
+        'flat: 1 '
+        'flat: 2 ')
+    text_format.Merge(msg_str, msg)
+    self.assertEqual(msg.flat, [0, 1, 2])
+
+  def testParsingNestedClass(self):
+    """Test that the generated class can parse a nested message."""
+    file_descriptor = descriptor_pb2.FileDescriptorProto()
+    file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('C'))
+    msg_descriptor = descriptor.MakeDescriptor(
+        file_descriptor.message_type[0])
+    msg_class = reflection.MakeClass(msg_descriptor)
+    msg = msg_class()
+    msg_str = (
+        'bar {'
+        '  baz {'
+        '    deep: 4'
+        '  }'
+        '}')
+    text_format.Merge(msg_str, msg)
+    self.assertEqual(msg.bar.baz.deep, 4)
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/service_reflection_test.py b/generator/google/protobuf/internal/service_reflection_test.py
new file mode 100644
index 0000000..62900b1
--- /dev/null
+++ b/generator/google/protobuf/internal/service_reflection_test.py
@@ -0,0 +1,140 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Tests for google.protobuf.internal.service_reflection."""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+
+from google.protobuf import unittest_pb2
+from google.protobuf import service_reflection
+from google.protobuf import service
+
+
+class FooUnitTest(unittest.TestCase):
+
+  def testService(self):
+    class MockRpcChannel(service.RpcChannel):
+      def CallMethod(self, method, controller, request, response, callback):
+        self.method = method
+        self.controller = controller
+        self.request = request
+        callback(response)
+
+    class MockRpcController(service.RpcController):
+      def SetFailed(self, msg):
+        self.failure_message = msg
+
+    self.callback_response = None
+
+    class MyService(unittest_pb2.TestService):
+      pass
+
+    self.callback_response = None
+
+    def MyCallback(response):
+      self.callback_response = response
+
+    rpc_controller = MockRpcController()
+    channel = MockRpcChannel()
+    srvc = MyService()
+    srvc.Foo(rpc_controller, unittest_pb2.FooRequest(), MyCallback)
+    self.assertEqual('Method Foo not implemented.',
+                     rpc_controller.failure_message)
+    self.assertEqual(None, self.callback_response)
+
+    rpc_controller.failure_message = None
+
+    service_descriptor = unittest_pb2.TestService.GetDescriptor()
+    srvc.CallMethod(service_descriptor.methods[1], rpc_controller,
+                    unittest_pb2.BarRequest(), MyCallback)
+    self.assertEqual('Method Bar not implemented.',
+                     rpc_controller.failure_message)
+    self.assertEqual(None, self.callback_response)
+
+    class MyServiceImpl(unittest_pb2.TestService):
+      def Foo(self, rpc_controller, request, done):
+        self.foo_called = True
+      def Bar(self, rpc_controller, request, done):
+        self.bar_called = True
+
+    srvc = MyServiceImpl()
+    rpc_controller.failure_message = None
+    srvc.Foo(rpc_controller, unittest_pb2.FooRequest(), MyCallback)
+    self.assertEqual(None, rpc_controller.failure_message)
+    self.assertEqual(True, srvc.foo_called)
+
+    rpc_controller.failure_message = None
+    srvc.CallMethod(service_descriptor.methods[1], rpc_controller,
+                    unittest_pb2.BarRequest(), MyCallback)
+    self.assertEqual(None, rpc_controller.failure_message)
+    self.assertEqual(True, srvc.bar_called)
+
+  def testServiceStub(self):
+    class MockRpcChannel(service.RpcChannel):
+      def CallMethod(self, method, controller, request,
+                     response_class, callback):
+        self.method = method
+        self.controller = controller
+        self.request = request
+        callback(response_class())
+
+    self.callback_response = None
+
+    def MyCallback(response):
+      self.callback_response = response
+
+    channel = MockRpcChannel()
+    stub = unittest_pb2.TestService_Stub(channel)
+    rpc_controller = 'controller'
+    request = 'request'
+
+    # GetDescriptor now static, still works as instance method for compatibility
+    self.assertEqual(unittest_pb2.TestService_Stub.GetDescriptor(),
+                     stub.GetDescriptor())
+
+    # Invoke method.
+    stub.Foo(rpc_controller, request, MyCallback)
+
+    self.assertIsInstance(self.callback_response, unittest_pb2.FooResponse)
+    self.assertEqual(request, channel.request)
+    self.assertEqual(rpc_controller, channel.controller)
+    self.assertEqual(stub.GetDescriptor().methods[0], channel.method)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/symbol_database_test.py b/generator/google/protobuf/internal/symbol_database_test.py
new file mode 100644
index 0000000..4f5173b
--- /dev/null
+++ b/generator/google/protobuf/internal/symbol_database_test.py
@@ -0,0 +1,131 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Tests for google.protobuf.symbol_database."""
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+
+from google.protobuf import unittest_pb2
+from google.protobuf import descriptor
+from google.protobuf import descriptor_pool
+from google.protobuf import symbol_database
+
+
+class SymbolDatabaseTest(unittest.TestCase):
+
+  def _Database(self):
+    if descriptor._USE_C_DESCRIPTORS:
+      # The C++ implementation does not allow mixing descriptors from
+      # different pools.
+      db = symbol_database.SymbolDatabase(pool=descriptor_pool.Default())
+    else:
+      db = symbol_database.SymbolDatabase()
+    # Register representative types from unittest_pb2.
+    db.RegisterFileDescriptor(unittest_pb2.DESCRIPTOR)
+    db.RegisterMessage(unittest_pb2.TestAllTypes)
+    db.RegisterMessage(unittest_pb2.TestAllTypes.NestedMessage)
+    db.RegisterMessage(unittest_pb2.TestAllTypes.OptionalGroup)
+    db.RegisterMessage(unittest_pb2.TestAllTypes.RepeatedGroup)
+    db.RegisterEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR)
+    db.RegisterEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR)
+    return db
+
+  def testGetPrototype(self):
+    instance = self._Database().GetPrototype(
+        unittest_pb2.TestAllTypes.DESCRIPTOR)
+    self.assertTrue(instance is unittest_pb2.TestAllTypes)
+
+  def testGetMessages(self):
+    messages = self._Database().GetMessages(
+        ['google/protobuf/unittest.proto'])
+    self.assertTrue(
+        unittest_pb2.TestAllTypes is
+        messages['protobuf_unittest.TestAllTypes'])
+
+  def testGetSymbol(self):
+    self.assertEqual(
+        unittest_pb2.TestAllTypes, self._Database().GetSymbol(
+            'protobuf_unittest.TestAllTypes'))
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.NestedMessage, self._Database().GetSymbol(
+            'protobuf_unittest.TestAllTypes.NestedMessage'))
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.OptionalGroup, self._Database().GetSymbol(
+            'protobuf_unittest.TestAllTypes.OptionalGroup'))
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.RepeatedGroup, self._Database().GetSymbol(
+            'protobuf_unittest.TestAllTypes.RepeatedGroup'))
+
+  def testEnums(self):
+    # Check registration of types in the pool.
+    self.assertEqual(
+        'protobuf_unittest.ForeignEnum',
+        self._Database().pool.FindEnumTypeByName(
+            'protobuf_unittest.ForeignEnum').full_name)
+    self.assertEqual(
+        'protobuf_unittest.TestAllTypes.NestedEnum',
+        self._Database().pool.FindEnumTypeByName(
+            'protobuf_unittest.TestAllTypes.NestedEnum').full_name)
+
+  def testFindMessageTypeByName(self):
+    self.assertEqual(
+        'protobuf_unittest.TestAllTypes',
+        self._Database().pool.FindMessageTypeByName(
+            'protobuf_unittest.TestAllTypes').full_name)
+    self.assertEqual(
+        'protobuf_unittest.TestAllTypes.NestedMessage',
+        self._Database().pool.FindMessageTypeByName(
+            'protobuf_unittest.TestAllTypes.NestedMessage').full_name)
+
+  def testFindFindContainingSymbol(self):
+    # Lookup based on either enum or message.
+    self.assertEqual(
+        'google/protobuf/unittest.proto',
+        self._Database().pool.FindFileContainingSymbol(
+            'protobuf_unittest.TestAllTypes.NestedEnum').name)
+    self.assertEqual(
+        'google/protobuf/unittest.proto',
+        self._Database().pool.FindFileContainingSymbol(
+            'protobuf_unittest.TestAllTypes').name)
+
+  def testFindFileByName(self):
+    self.assertEqual(
+        'google/protobuf/unittest.proto',
+        self._Database().pool.FindFileByName(
+            'google/protobuf/unittest.proto').name)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/test_bad_identifiers_pb2.py b/generator/google/protobuf/internal/test_bad_identifiers_pb2.py
new file mode 100644
index 0000000..306b576
--- /dev/null
+++ b/generator/google/protobuf/internal/test_bad_identifiers_pb2.py
@@ -0,0 +1,161 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/internal/test_bad_identifiers.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import service as _service
+from google.protobuf import service_reflection
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/internal/test_bad_identifiers.proto',
+  package='protobuf_unittest',
+  syntax='proto2',
+  serialized_pb=_b('\n3google/protobuf/internal/test_bad_identifiers.proto\x12\x11protobuf_unittest\"\x1e\n\x12TestBadIdentifiers*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"\x10\n\x0e\x41notherMessage2\x10\n\x0e\x41notherService:;\n\x07message\x12%.protobuf_unittest.TestBadIdentifiers\x18\x64 \x01(\t:\x03\x66oo:>\n\ndescriptor\x12%.protobuf_unittest.TestBadIdentifiers\x18\x65 \x01(\t:\x03\x62\x61r:>\n\nreflection\x12%.protobuf_unittest.TestBadIdentifiers\x18\x66 \x01(\t:\x03\x62\x61z:;\n\x07service\x12%.protobuf_unittest.TestBadIdentifiers\x18g \x01(\t:\x03quxB\x03\x90\x01\x01')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+MESSAGE_FIELD_NUMBER = 100
+message = _descriptor.FieldDescriptor(
+  name='message', full_name='protobuf_unittest.message', index=0,
+  number=100, type=9, cpp_type=9, label=1,
+  has_default_value=True, default_value=_b("foo").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DESCRIPTOR_FIELD_NUMBER = 101
+descriptor = _descriptor.FieldDescriptor(
+  name='descriptor', full_name='protobuf_unittest.descriptor', index=1,
+  number=101, type=9, cpp_type=9, label=1,
+  has_default_value=True, default_value=_b("bar").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REFLECTION_FIELD_NUMBER = 102
+reflection = _descriptor.FieldDescriptor(
+  name='reflection', full_name='protobuf_unittest.reflection', index=2,
+  number=102, type=9, cpp_type=9, label=1,
+  has_default_value=True, default_value=_b("baz").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+SERVICE_FIELD_NUMBER = 103
+service = _descriptor.FieldDescriptor(
+  name='service', full_name='protobuf_unittest.service', index=3,
+  number=103, type=9, cpp_type=9, label=1,
+  has_default_value=True, default_value=_b("qux").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+
+
+_TESTBADIDENTIFIERS = _descriptor.Descriptor(
+  name='TestBadIdentifiers',
+  full_name='protobuf_unittest.TestBadIdentifiers',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(100, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=74,
+  serialized_end=104,
+)
+
+
+_ANOTHERMESSAGE = _descriptor.Descriptor(
+  name='AnotherMessage',
+  full_name='protobuf_unittest.AnotherMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=106,
+  serialized_end=122,
+)
+
+DESCRIPTOR.message_types_by_name['TestBadIdentifiers'] = _TESTBADIDENTIFIERS
+DESCRIPTOR.message_types_by_name['AnotherMessage'] = _ANOTHERMESSAGE
+DESCRIPTOR.extensions_by_name['message'] = message
+DESCRIPTOR.extensions_by_name['descriptor'] = descriptor
+DESCRIPTOR.extensions_by_name['reflection'] = reflection
+DESCRIPTOR.extensions_by_name['service'] = service
+
+TestBadIdentifiers = _reflection.GeneratedProtocolMessageType('TestBadIdentifiers', (_message.Message,), dict(
+  DESCRIPTOR = _TESTBADIDENTIFIERS,
+  __module__ = 'google.protobuf.internal.test_bad_identifiers_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestBadIdentifiers)
+  ))
+_sym_db.RegisterMessage(TestBadIdentifiers)
+
+AnotherMessage = _reflection.GeneratedProtocolMessageType('AnotherMessage', (_message.Message,), dict(
+  DESCRIPTOR = _ANOTHERMESSAGE,
+  __module__ = 'google.protobuf.internal.test_bad_identifiers_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.AnotherMessage)
+  ))
+_sym_db.RegisterMessage(AnotherMessage)
+
+TestBadIdentifiers.RegisterExtension(message)
+TestBadIdentifiers.RegisterExtension(descriptor)
+TestBadIdentifiers.RegisterExtension(reflection)
+TestBadIdentifiers.RegisterExtension(service)
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\220\001\001'))
+
+_ANOTHERSERVICE = _descriptor.ServiceDescriptor(
+  name='AnotherService',
+  full_name='protobuf_unittest.AnotherService',
+  file=DESCRIPTOR,
+  index=0,
+  options=None,
+  serialized_start=124,
+  serialized_end=140,
+  methods=[
+])
+
+AnotherService = service_reflection.GeneratedServiceType('AnotherService', (_service.Service,), dict(
+  DESCRIPTOR = _ANOTHERSERVICE,
+  __module__ = 'google.protobuf.internal.test_bad_identifiers_pb2'
+  ))
+
+AnotherService_Stub = service_reflection.GeneratedServiceStubType('AnotherService_Stub', (AnotherService,), dict(
+  DESCRIPTOR = _ANOTHERSERVICE,
+  __module__ = 'google.protobuf.internal.test_bad_identifiers_pb2'
+  ))
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/internal/test_util.py b/generator/google/protobuf/internal/test_util.py
new file mode 100644
index 0000000..2c80559
--- /dev/null
+++ b/generator/google/protobuf/internal/test_util.py
@@ -0,0 +1,696 @@
+# 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.
+
+"""Utilities for Python proto2 tests.
+
+This is intentionally modeled on C++ code in
+//google/protobuf/test_util.*.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import os.path
+
+import sys
+
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import descriptor_pb2
+
+# Tests whether the given TestAllTypes message is proto2 or not.
+# This is used to gate several fields/features that only exist
+# for the proto2 version of the message.
+def IsProto2(message):
+  return message.DESCRIPTOR.syntax == "proto2"
+
+def SetAllNonLazyFields(message):
+  """Sets every non-lazy field in the message to a unique value.
+
+  Args:
+    message: A TestAllTypes instance.
+  """
+
+  #
+  # Optional fields.
+  #
+
+  message.optional_int32    = 101
+  message.optional_int64    = 102
+  message.optional_uint32   = 103
+  message.optional_uint64   = 104
+  message.optional_sint32   = 105
+  message.optional_sint64   = 106
+  message.optional_fixed32  = 107
+  message.optional_fixed64  = 108
+  message.optional_sfixed32 = 109
+  message.optional_sfixed64 = 110
+  message.optional_float    = 111
+  message.optional_double   = 112
+  message.optional_bool     = True
+  message.optional_string   = u'115'
+  message.optional_bytes    = b'116'
+
+  if IsProto2(message):
+    message.optionalgroup.a = 117
+  message.optional_nested_message.bb = 118
+  message.optional_foreign_message.c = 119
+  message.optional_import_message.d = 120
+  message.optional_public_import_message.e = 126
+
+  message.optional_nested_enum = unittest_pb2.TestAllTypes.BAZ
+  message.optional_foreign_enum = unittest_pb2.FOREIGN_BAZ
+  if IsProto2(message):
+    message.optional_import_enum = unittest_import_pb2.IMPORT_BAZ
+
+  message.optional_string_piece = u'124'
+  message.optional_cord = u'125'
+
+  #
+  # Repeated fields.
+  #
+
+  message.repeated_int32.append(201)
+  message.repeated_int64.append(202)
+  message.repeated_uint32.append(203)
+  message.repeated_uint64.append(204)
+  message.repeated_sint32.append(205)
+  message.repeated_sint64.append(206)
+  message.repeated_fixed32.append(207)
+  message.repeated_fixed64.append(208)
+  message.repeated_sfixed32.append(209)
+  message.repeated_sfixed64.append(210)
+  message.repeated_float.append(211)
+  message.repeated_double.append(212)
+  message.repeated_bool.append(True)
+  message.repeated_string.append(u'215')
+  message.repeated_bytes.append(b'216')
+
+  if IsProto2(message):
+    message.repeatedgroup.add().a = 217
+  message.repeated_nested_message.add().bb = 218
+  message.repeated_foreign_message.add().c = 219
+  message.repeated_import_message.add().d = 220
+  message.repeated_lazy_message.add().bb = 227
+
+  message.repeated_nested_enum.append(unittest_pb2.TestAllTypes.BAR)
+  message.repeated_foreign_enum.append(unittest_pb2.FOREIGN_BAR)
+  if IsProto2(message):
+    message.repeated_import_enum.append(unittest_import_pb2.IMPORT_BAR)
+
+  message.repeated_string_piece.append(u'224')
+  message.repeated_cord.append(u'225')
+
+  # Add a second one of each field.
+  message.repeated_int32.append(301)
+  message.repeated_int64.append(302)
+  message.repeated_uint32.append(303)
+  message.repeated_uint64.append(304)
+  message.repeated_sint32.append(305)
+  message.repeated_sint64.append(306)
+  message.repeated_fixed32.append(307)
+  message.repeated_fixed64.append(308)
+  message.repeated_sfixed32.append(309)
+  message.repeated_sfixed64.append(310)
+  message.repeated_float.append(311)
+  message.repeated_double.append(312)
+  message.repeated_bool.append(False)
+  message.repeated_string.append(u'315')
+  message.repeated_bytes.append(b'316')
+
+  if IsProto2(message):
+    message.repeatedgroup.add().a = 317
+  message.repeated_nested_message.add().bb = 318
+  message.repeated_foreign_message.add().c = 319
+  message.repeated_import_message.add().d = 320
+  message.repeated_lazy_message.add().bb = 327
+
+  message.repeated_nested_enum.append(unittest_pb2.TestAllTypes.BAZ)
+  message.repeated_foreign_enum.append(unittest_pb2.FOREIGN_BAZ)
+  if IsProto2(message):
+    message.repeated_import_enum.append(unittest_import_pb2.IMPORT_BAZ)
+
+  message.repeated_string_piece.append(u'324')
+  message.repeated_cord.append(u'325')
+
+  #
+  # Fields that have defaults.
+  #
+
+  if IsProto2(message):
+    message.default_int32 = 401
+    message.default_int64 = 402
+    message.default_uint32 = 403
+    message.default_uint64 = 404
+    message.default_sint32 = 405
+    message.default_sint64 = 406
+    message.default_fixed32 = 407
+    message.default_fixed64 = 408
+    message.default_sfixed32 = 409
+    message.default_sfixed64 = 410
+    message.default_float = 411
+    message.default_double = 412
+    message.default_bool = False
+    message.default_string = '415'
+    message.default_bytes = b'416'
+
+    message.default_nested_enum = unittest_pb2.TestAllTypes.FOO
+    message.default_foreign_enum = unittest_pb2.FOREIGN_FOO
+    message.default_import_enum = unittest_import_pb2.IMPORT_FOO
+
+    message.default_string_piece = '424'
+    message.default_cord = '425'
+
+  message.oneof_uint32 = 601
+  message.oneof_nested_message.bb = 602
+  message.oneof_string = '603'
+  message.oneof_bytes = b'604'
+
+
+def SetAllFields(message):
+  SetAllNonLazyFields(message)
+  message.optional_lazy_message.bb = 127
+
+
+def SetAllExtensions(message):
+  """Sets every extension in the message to a unique value.
+
+  Args:
+    message: A unittest_pb2.TestAllExtensions instance.
+  """
+
+  extensions = message.Extensions
+  pb2 = unittest_pb2
+  import_pb2 = unittest_import_pb2
+
+  #
+  # Optional fields.
+  #
+
+  extensions[pb2.optional_int32_extension] = 101
+  extensions[pb2.optional_int64_extension] = 102
+  extensions[pb2.optional_uint32_extension] = 103
+  extensions[pb2.optional_uint64_extension] = 104
+  extensions[pb2.optional_sint32_extension] = 105
+  extensions[pb2.optional_sint64_extension] = 106
+  extensions[pb2.optional_fixed32_extension] = 107
+  extensions[pb2.optional_fixed64_extension] = 108
+  extensions[pb2.optional_sfixed32_extension] = 109
+  extensions[pb2.optional_sfixed64_extension] = 110
+  extensions[pb2.optional_float_extension] = 111
+  extensions[pb2.optional_double_extension] = 112
+  extensions[pb2.optional_bool_extension] = True
+  extensions[pb2.optional_string_extension] = u'115'
+  extensions[pb2.optional_bytes_extension] = b'116'
+
+  extensions[pb2.optionalgroup_extension].a = 117
+  extensions[pb2.optional_nested_message_extension].bb = 118
+  extensions[pb2.optional_foreign_message_extension].c = 119
+  extensions[pb2.optional_import_message_extension].d = 120
+  extensions[pb2.optional_public_import_message_extension].e = 126
+  extensions[pb2.optional_lazy_message_extension].bb = 127
+
+  extensions[pb2.optional_nested_enum_extension] = pb2.TestAllTypes.BAZ
+  extensions[pb2.optional_nested_enum_extension] = pb2.TestAllTypes.BAZ
+  extensions[pb2.optional_foreign_enum_extension] = pb2.FOREIGN_BAZ
+  extensions[pb2.optional_import_enum_extension] = import_pb2.IMPORT_BAZ
+
+  extensions[pb2.optional_string_piece_extension] = u'124'
+  extensions[pb2.optional_cord_extension] = u'125'
+
+  #
+  # Repeated fields.
+  #
+
+  extensions[pb2.repeated_int32_extension].append(201)
+  extensions[pb2.repeated_int64_extension].append(202)
+  extensions[pb2.repeated_uint32_extension].append(203)
+  extensions[pb2.repeated_uint64_extension].append(204)
+  extensions[pb2.repeated_sint32_extension].append(205)
+  extensions[pb2.repeated_sint64_extension].append(206)
+  extensions[pb2.repeated_fixed32_extension].append(207)
+  extensions[pb2.repeated_fixed64_extension].append(208)
+  extensions[pb2.repeated_sfixed32_extension].append(209)
+  extensions[pb2.repeated_sfixed64_extension].append(210)
+  extensions[pb2.repeated_float_extension].append(211)
+  extensions[pb2.repeated_double_extension].append(212)
+  extensions[pb2.repeated_bool_extension].append(True)
+  extensions[pb2.repeated_string_extension].append(u'215')
+  extensions[pb2.repeated_bytes_extension].append(b'216')
+
+  extensions[pb2.repeatedgroup_extension].add().a = 217
+  extensions[pb2.repeated_nested_message_extension].add().bb = 218
+  extensions[pb2.repeated_foreign_message_extension].add().c = 219
+  extensions[pb2.repeated_import_message_extension].add().d = 220
+  extensions[pb2.repeated_lazy_message_extension].add().bb = 227
+
+  extensions[pb2.repeated_nested_enum_extension].append(pb2.TestAllTypes.BAR)
+  extensions[pb2.repeated_foreign_enum_extension].append(pb2.FOREIGN_BAR)
+  extensions[pb2.repeated_import_enum_extension].append(import_pb2.IMPORT_BAR)
+
+  extensions[pb2.repeated_string_piece_extension].append(u'224')
+  extensions[pb2.repeated_cord_extension].append(u'225')
+
+  # Append a second one of each field.
+  extensions[pb2.repeated_int32_extension].append(301)
+  extensions[pb2.repeated_int64_extension].append(302)
+  extensions[pb2.repeated_uint32_extension].append(303)
+  extensions[pb2.repeated_uint64_extension].append(304)
+  extensions[pb2.repeated_sint32_extension].append(305)
+  extensions[pb2.repeated_sint64_extension].append(306)
+  extensions[pb2.repeated_fixed32_extension].append(307)
+  extensions[pb2.repeated_fixed64_extension].append(308)
+  extensions[pb2.repeated_sfixed32_extension].append(309)
+  extensions[pb2.repeated_sfixed64_extension].append(310)
+  extensions[pb2.repeated_float_extension].append(311)
+  extensions[pb2.repeated_double_extension].append(312)
+  extensions[pb2.repeated_bool_extension].append(False)
+  extensions[pb2.repeated_string_extension].append(u'315')
+  extensions[pb2.repeated_bytes_extension].append(b'316')
+
+  extensions[pb2.repeatedgroup_extension].add().a = 317
+  extensions[pb2.repeated_nested_message_extension].add().bb = 318
+  extensions[pb2.repeated_foreign_message_extension].add().c = 319
+  extensions[pb2.repeated_import_message_extension].add().d = 320
+  extensions[pb2.repeated_lazy_message_extension].add().bb = 327
+
+  extensions[pb2.repeated_nested_enum_extension].append(pb2.TestAllTypes.BAZ)
+  extensions[pb2.repeated_foreign_enum_extension].append(pb2.FOREIGN_BAZ)
+  extensions[pb2.repeated_import_enum_extension].append(import_pb2.IMPORT_BAZ)
+
+  extensions[pb2.repeated_string_piece_extension].append(u'324')
+  extensions[pb2.repeated_cord_extension].append(u'325')
+
+  #
+  # Fields with defaults.
+  #
+
+  extensions[pb2.default_int32_extension] = 401
+  extensions[pb2.default_int64_extension] = 402
+  extensions[pb2.default_uint32_extension] = 403
+  extensions[pb2.default_uint64_extension] = 404
+  extensions[pb2.default_sint32_extension] = 405
+  extensions[pb2.default_sint64_extension] = 406
+  extensions[pb2.default_fixed32_extension] = 407
+  extensions[pb2.default_fixed64_extension] = 408
+  extensions[pb2.default_sfixed32_extension] = 409
+  extensions[pb2.default_sfixed64_extension] = 410
+  extensions[pb2.default_float_extension] = 411
+  extensions[pb2.default_double_extension] = 412
+  extensions[pb2.default_bool_extension] = False
+  extensions[pb2.default_string_extension] = u'415'
+  extensions[pb2.default_bytes_extension] = b'416'
+
+  extensions[pb2.default_nested_enum_extension] = pb2.TestAllTypes.FOO
+  extensions[pb2.default_foreign_enum_extension] = pb2.FOREIGN_FOO
+  extensions[pb2.default_import_enum_extension] = import_pb2.IMPORT_FOO
+
+  extensions[pb2.default_string_piece_extension] = u'424'
+  extensions[pb2.default_cord_extension] = '425'
+
+  extensions[pb2.oneof_uint32_extension] = 601
+  extensions[pb2.oneof_nested_message_extension].bb = 602
+  extensions[pb2.oneof_string_extension] = u'603'
+  extensions[pb2.oneof_bytes_extension] = b'604'
+
+
+def SetAllFieldsAndExtensions(message):
+  """Sets every field and extension in the message to a unique value.
+
+  Args:
+    message: A unittest_pb2.TestAllExtensions message.
+  """
+  message.my_int = 1
+  message.my_string = 'foo'
+  message.my_float = 1.0
+  message.Extensions[unittest_pb2.my_extension_int] = 23
+  message.Extensions[unittest_pb2.my_extension_string] = 'bar'
+
+
+def ExpectAllFieldsAndExtensionsInOrder(serialized):
+  """Ensures that serialized is the serialization we expect for a message
+  filled with SetAllFieldsAndExtensions().  (Specifically, ensures that the
+  serialization is in canonical, tag-number order).
+  """
+  my_extension_int = unittest_pb2.my_extension_int
+  my_extension_string = unittest_pb2.my_extension_string
+  expected_strings = []
+  message = unittest_pb2.TestFieldOrderings()
+  message.my_int = 1  # Field 1.
+  expected_strings.append(message.SerializeToString())
+  message.Clear()
+  message.Extensions[my_extension_int] = 23  # Field 5.
+  expected_strings.append(message.SerializeToString())
+  message.Clear()
+  message.my_string = 'foo'  # Field 11.
+  expected_strings.append(message.SerializeToString())
+  message.Clear()
+  message.Extensions[my_extension_string] = 'bar'  # Field 50.
+  expected_strings.append(message.SerializeToString())
+  message.Clear()
+  message.my_float = 1.0
+  expected_strings.append(message.SerializeToString())
+  message.Clear()
+  expected = b''.join(expected_strings)
+
+  if expected != serialized:
+    raise ValueError('Expected %r, found %r' % (expected, serialized))
+
+
+def ExpectAllFieldsSet(test_case, message):
+  """Check all fields for correct values have after Set*Fields() is called."""
+  test_case.assertTrue(message.HasField('optional_int32'))
+  test_case.assertTrue(message.HasField('optional_int64'))
+  test_case.assertTrue(message.HasField('optional_uint32'))
+  test_case.assertTrue(message.HasField('optional_uint64'))
+  test_case.assertTrue(message.HasField('optional_sint32'))
+  test_case.assertTrue(message.HasField('optional_sint64'))
+  test_case.assertTrue(message.HasField('optional_fixed32'))
+  test_case.assertTrue(message.HasField('optional_fixed64'))
+  test_case.assertTrue(message.HasField('optional_sfixed32'))
+  test_case.assertTrue(message.HasField('optional_sfixed64'))
+  test_case.assertTrue(message.HasField('optional_float'))
+  test_case.assertTrue(message.HasField('optional_double'))
+  test_case.assertTrue(message.HasField('optional_bool'))
+  test_case.assertTrue(message.HasField('optional_string'))
+  test_case.assertTrue(message.HasField('optional_bytes'))
+
+  if IsProto2(message):
+    test_case.assertTrue(message.HasField('optionalgroup'))
+  test_case.assertTrue(message.HasField('optional_nested_message'))
+  test_case.assertTrue(message.HasField('optional_foreign_message'))
+  test_case.assertTrue(message.HasField('optional_import_message'))
+
+  test_case.assertTrue(message.optionalgroup.HasField('a'))
+  test_case.assertTrue(message.optional_nested_message.HasField('bb'))
+  test_case.assertTrue(message.optional_foreign_message.HasField('c'))
+  test_case.assertTrue(message.optional_import_message.HasField('d'))
+
+  test_case.assertTrue(message.HasField('optional_nested_enum'))
+  test_case.assertTrue(message.HasField('optional_foreign_enum'))
+  if IsProto2(message):
+    test_case.assertTrue(message.HasField('optional_import_enum'))
+
+  test_case.assertTrue(message.HasField('optional_string_piece'))
+  test_case.assertTrue(message.HasField('optional_cord'))
+
+  test_case.assertEqual(101, message.optional_int32)
+  test_case.assertEqual(102, message.optional_int64)
+  test_case.assertEqual(103, message.optional_uint32)
+  test_case.assertEqual(104, message.optional_uint64)
+  test_case.assertEqual(105, message.optional_sint32)
+  test_case.assertEqual(106, message.optional_sint64)
+  test_case.assertEqual(107, message.optional_fixed32)
+  test_case.assertEqual(108, message.optional_fixed64)
+  test_case.assertEqual(109, message.optional_sfixed32)
+  test_case.assertEqual(110, message.optional_sfixed64)
+  test_case.assertEqual(111, message.optional_float)
+  test_case.assertEqual(112, message.optional_double)
+  test_case.assertEqual(True, message.optional_bool)
+  test_case.assertEqual('115', message.optional_string)
+  test_case.assertEqual(b'116', message.optional_bytes)
+
+  if IsProto2(message):
+    test_case.assertEqual(117, message.optionalgroup.a)
+  test_case.assertEqual(118, message.optional_nested_message.bb)
+  test_case.assertEqual(119, message.optional_foreign_message.c)
+  test_case.assertEqual(120, message.optional_import_message.d)
+  test_case.assertEqual(126, message.optional_public_import_message.e)
+  test_case.assertEqual(127, message.optional_lazy_message.bb)
+
+  test_case.assertEqual(unittest_pb2.TestAllTypes.BAZ,
+                        message.optional_nested_enum)
+  test_case.assertEqual(unittest_pb2.FOREIGN_BAZ,
+                        message.optional_foreign_enum)
+  if IsProto2(message):
+    test_case.assertEqual(unittest_import_pb2.IMPORT_BAZ,
+                          message.optional_import_enum)
+
+  # -----------------------------------------------------------------
+
+  test_case.assertEqual(2, len(message.repeated_int32))
+  test_case.assertEqual(2, len(message.repeated_int64))
+  test_case.assertEqual(2, len(message.repeated_uint32))
+  test_case.assertEqual(2, len(message.repeated_uint64))
+  test_case.assertEqual(2, len(message.repeated_sint32))
+  test_case.assertEqual(2, len(message.repeated_sint64))
+  test_case.assertEqual(2, len(message.repeated_fixed32))
+  test_case.assertEqual(2, len(message.repeated_fixed64))
+  test_case.assertEqual(2, len(message.repeated_sfixed32))
+  test_case.assertEqual(2, len(message.repeated_sfixed64))
+  test_case.assertEqual(2, len(message.repeated_float))
+  test_case.assertEqual(2, len(message.repeated_double))
+  test_case.assertEqual(2, len(message.repeated_bool))
+  test_case.assertEqual(2, len(message.repeated_string))
+  test_case.assertEqual(2, len(message.repeated_bytes))
+
+  if IsProto2(message):
+    test_case.assertEqual(2, len(message.repeatedgroup))
+  test_case.assertEqual(2, len(message.repeated_nested_message))
+  test_case.assertEqual(2, len(message.repeated_foreign_message))
+  test_case.assertEqual(2, len(message.repeated_import_message))
+  test_case.assertEqual(2, len(message.repeated_nested_enum))
+  test_case.assertEqual(2, len(message.repeated_foreign_enum))
+  if IsProto2(message):
+    test_case.assertEqual(2, len(message.repeated_import_enum))
+
+  test_case.assertEqual(2, len(message.repeated_string_piece))
+  test_case.assertEqual(2, len(message.repeated_cord))
+
+  test_case.assertEqual(201, message.repeated_int32[0])
+  test_case.assertEqual(202, message.repeated_int64[0])
+  test_case.assertEqual(203, message.repeated_uint32[0])
+  test_case.assertEqual(204, message.repeated_uint64[0])
+  test_case.assertEqual(205, message.repeated_sint32[0])
+  test_case.assertEqual(206, message.repeated_sint64[0])
+  test_case.assertEqual(207, message.repeated_fixed32[0])
+  test_case.assertEqual(208, message.repeated_fixed64[0])
+  test_case.assertEqual(209, message.repeated_sfixed32[0])
+  test_case.assertEqual(210, message.repeated_sfixed64[0])
+  test_case.assertEqual(211, message.repeated_float[0])
+  test_case.assertEqual(212, message.repeated_double[0])
+  test_case.assertEqual(True, message.repeated_bool[0])
+  test_case.assertEqual('215', message.repeated_string[0])
+  test_case.assertEqual(b'216', message.repeated_bytes[0])
+
+  if IsProto2(message):
+    test_case.assertEqual(217, message.repeatedgroup[0].a)
+  test_case.assertEqual(218, message.repeated_nested_message[0].bb)
+  test_case.assertEqual(219, message.repeated_foreign_message[0].c)
+  test_case.assertEqual(220, message.repeated_import_message[0].d)
+  test_case.assertEqual(227, message.repeated_lazy_message[0].bb)
+
+  test_case.assertEqual(unittest_pb2.TestAllTypes.BAR,
+                        message.repeated_nested_enum[0])
+  test_case.assertEqual(unittest_pb2.FOREIGN_BAR,
+                        message.repeated_foreign_enum[0])
+  if IsProto2(message):
+    test_case.assertEqual(unittest_import_pb2.IMPORT_BAR,
+                          message.repeated_import_enum[0])
+
+  test_case.assertEqual(301, message.repeated_int32[1])
+  test_case.assertEqual(302, message.repeated_int64[1])
+  test_case.assertEqual(303, message.repeated_uint32[1])
+  test_case.assertEqual(304, message.repeated_uint64[1])
+  test_case.assertEqual(305, message.repeated_sint32[1])
+  test_case.assertEqual(306, message.repeated_sint64[1])
+  test_case.assertEqual(307, message.repeated_fixed32[1])
+  test_case.assertEqual(308, message.repeated_fixed64[1])
+  test_case.assertEqual(309, message.repeated_sfixed32[1])
+  test_case.assertEqual(310, message.repeated_sfixed64[1])
+  test_case.assertEqual(311, message.repeated_float[1])
+  test_case.assertEqual(312, message.repeated_double[1])
+  test_case.assertEqual(False, message.repeated_bool[1])
+  test_case.assertEqual('315', message.repeated_string[1])
+  test_case.assertEqual(b'316', message.repeated_bytes[1])
+
+  if IsProto2(message):
+    test_case.assertEqual(317, message.repeatedgroup[1].a)
+  test_case.assertEqual(318, message.repeated_nested_message[1].bb)
+  test_case.assertEqual(319, message.repeated_foreign_message[1].c)
+  test_case.assertEqual(320, message.repeated_import_message[1].d)
+  test_case.assertEqual(327, message.repeated_lazy_message[1].bb)
+
+  test_case.assertEqual(unittest_pb2.TestAllTypes.BAZ,
+                        message.repeated_nested_enum[1])
+  test_case.assertEqual(unittest_pb2.FOREIGN_BAZ,
+                        message.repeated_foreign_enum[1])
+  if IsProto2(message):
+    test_case.assertEqual(unittest_import_pb2.IMPORT_BAZ,
+                          message.repeated_import_enum[1])
+
+  # -----------------------------------------------------------------
+
+  if IsProto2(message):
+    test_case.assertTrue(message.HasField('default_int32'))
+    test_case.assertTrue(message.HasField('default_int64'))
+    test_case.assertTrue(message.HasField('default_uint32'))
+    test_case.assertTrue(message.HasField('default_uint64'))
+    test_case.assertTrue(message.HasField('default_sint32'))
+    test_case.assertTrue(message.HasField('default_sint64'))
+    test_case.assertTrue(message.HasField('default_fixed32'))
+    test_case.assertTrue(message.HasField('default_fixed64'))
+    test_case.assertTrue(message.HasField('default_sfixed32'))
+    test_case.assertTrue(message.HasField('default_sfixed64'))
+    test_case.assertTrue(message.HasField('default_float'))
+    test_case.assertTrue(message.HasField('default_double'))
+    test_case.assertTrue(message.HasField('default_bool'))
+    test_case.assertTrue(message.HasField('default_string'))
+    test_case.assertTrue(message.HasField('default_bytes'))
+
+    test_case.assertTrue(message.HasField('default_nested_enum'))
+    test_case.assertTrue(message.HasField('default_foreign_enum'))
+    test_case.assertTrue(message.HasField('default_import_enum'))
+
+    test_case.assertEqual(401, message.default_int32)
+    test_case.assertEqual(402, message.default_int64)
+    test_case.assertEqual(403, message.default_uint32)
+    test_case.assertEqual(404, message.default_uint64)
+    test_case.assertEqual(405, message.default_sint32)
+    test_case.assertEqual(406, message.default_sint64)
+    test_case.assertEqual(407, message.default_fixed32)
+    test_case.assertEqual(408, message.default_fixed64)
+    test_case.assertEqual(409, message.default_sfixed32)
+    test_case.assertEqual(410, message.default_sfixed64)
+    test_case.assertEqual(411, message.default_float)
+    test_case.assertEqual(412, message.default_double)
+    test_case.assertEqual(False, message.default_bool)
+    test_case.assertEqual('415', message.default_string)
+    test_case.assertEqual(b'416', message.default_bytes)
+
+    test_case.assertEqual(unittest_pb2.TestAllTypes.FOO,
+                          message.default_nested_enum)
+    test_case.assertEqual(unittest_pb2.FOREIGN_FOO,
+                          message.default_foreign_enum)
+    test_case.assertEqual(unittest_import_pb2.IMPORT_FOO,
+                          message.default_import_enum)
+
+
+def GoldenFile(filename):
+  """Finds the given golden file and returns a file object representing it."""
+
+  # Search up the directory tree looking for the C++ protobuf source code.
+  path = '.'
+  while os.path.exists(path):
+    if os.path.exists(os.path.join(path, 'src/google/protobuf')):
+      # Found it.  Load the golden file from the testdata directory.
+      full_path = os.path.join(path, 'src/google/protobuf/testdata', filename)
+      return open(full_path, 'rb')
+    path = os.path.join(path, '..')
+
+  # Search internally.
+  path = '.'
+  full_path = os.path.join(path, 'third_party/py/google/protobuf/testdata',
+                           filename)
+  if os.path.exists(full_path):
+    # Found it.  Load the golden file from the testdata directory.
+    return open(full_path, 'rb')
+
+  raise RuntimeError(
+      'Could not find golden files.  This test must be run from within the '
+      'protobuf source package so that it can read test data files from the '
+      'C++ source tree.')
+
+
+def GoldenFileData(filename):
+  """Finds the given golden file and returns its contents."""
+  with GoldenFile(filename) as f:
+    return f.read()
+
+
+def SetAllPackedFields(message):
+  """Sets every field in the message to a unique value.
+
+  Args:
+    message: A TestPackedTypes instance.
+  """
+  message.packed_int32.extend([601, 701])
+  message.packed_int64.extend([602, 702])
+  message.packed_uint32.extend([603, 703])
+  message.packed_uint64.extend([604, 704])
+  message.packed_sint32.extend([605, 705])
+  message.packed_sint64.extend([606, 706])
+  message.packed_fixed32.extend([607, 707])
+  message.packed_fixed64.extend([608, 708])
+  message.packed_sfixed32.extend([609, 709])
+  message.packed_sfixed64.extend([610, 710])
+  message.packed_float.extend([611.0, 711.0])
+  message.packed_double.extend([612.0, 712.0])
+  message.packed_bool.extend([True, False])
+  message.packed_enum.extend([unittest_pb2.FOREIGN_BAR,
+                              unittest_pb2.FOREIGN_BAZ])
+
+
+def SetAllPackedExtensions(message):
+  """Sets every extension in the message to a unique value.
+
+  Args:
+    message: A unittest_pb2.TestPackedExtensions instance.
+  """
+  extensions = message.Extensions
+  pb2 = unittest_pb2
+
+  extensions[pb2.packed_int32_extension].extend([601, 701])
+  extensions[pb2.packed_int64_extension].extend([602, 702])
+  extensions[pb2.packed_uint32_extension].extend([603, 703])
+  extensions[pb2.packed_uint64_extension].extend([604, 704])
+  extensions[pb2.packed_sint32_extension].extend([605, 705])
+  extensions[pb2.packed_sint64_extension].extend([606, 706])
+  extensions[pb2.packed_fixed32_extension].extend([607, 707])
+  extensions[pb2.packed_fixed64_extension].extend([608, 708])
+  extensions[pb2.packed_sfixed32_extension].extend([609, 709])
+  extensions[pb2.packed_sfixed64_extension].extend([610, 710])
+  extensions[pb2.packed_float_extension].extend([611.0, 711.0])
+  extensions[pb2.packed_double_extension].extend([612.0, 712.0])
+  extensions[pb2.packed_bool_extension].extend([True, False])
+  extensions[pb2.packed_enum_extension].extend([unittest_pb2.FOREIGN_BAR,
+                                                unittest_pb2.FOREIGN_BAZ])
+
+
+def SetAllUnpackedFields(message):
+  """Sets every field in the message to a unique value.
+
+  Args:
+    message: A unittest_pb2.TestUnpackedTypes instance.
+  """
+  message.unpacked_int32.extend([601, 701])
+  message.unpacked_int64.extend([602, 702])
+  message.unpacked_uint32.extend([603, 703])
+  message.unpacked_uint64.extend([604, 704])
+  message.unpacked_sint32.extend([605, 705])
+  message.unpacked_sint64.extend([606, 706])
+  message.unpacked_fixed32.extend([607, 707])
+  message.unpacked_fixed64.extend([608, 708])
+  message.unpacked_sfixed32.extend([609, 709])
+  message.unpacked_sfixed64.extend([610, 710])
+  message.unpacked_float.extend([611.0, 711.0])
+  message.unpacked_double.extend([612.0, 712.0])
+  message.unpacked_bool.extend([True, False])
+  message.unpacked_enum.extend([unittest_pb2.FOREIGN_BAR,
+                                unittest_pb2.FOREIGN_BAZ])
diff --git a/generator/google/protobuf/internal/text_encoding_test.py b/generator/google/protobuf/internal/text_encoding_test.py
new file mode 100644
index 0000000..c7d182c
--- /dev/null
+++ b/generator/google/protobuf/internal/text_encoding_test.py
@@ -0,0 +1,72 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Tests for google.protobuf.text_encoding."""
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+
+from google.protobuf import text_encoding
+
+TEST_VALUES = [
+    ("foo\\rbar\\nbaz\\t",
+     "foo\\rbar\\nbaz\\t",
+     b"foo\rbar\nbaz\t"),
+    ("\\'full of \\\"sound\\\" and \\\"fury\\\"\\'",
+     "\\'full of \\\"sound\\\" and \\\"fury\\\"\\'",
+     b"'full of \"sound\" and \"fury\"'"),
+    ("signi\\\\fying\\\\ nothing\\\\",
+     "signi\\\\fying\\\\ nothing\\\\",
+     b"signi\\fying\\ nothing\\"),
+    ("\\010\\t\\n\\013\\014\\r",
+     "\x08\\t\\n\x0b\x0c\\r",
+     b"\010\011\012\013\014\015")]
+
+
+class TextEncodingTestCase(unittest.TestCase):
+  def testCEscape(self):
+    for escaped, escaped_utf8, unescaped in TEST_VALUES:
+      self.assertEqual(escaped,
+                        text_encoding.CEscape(unescaped, as_utf8=False))
+      self.assertEqual(escaped_utf8,
+                        text_encoding.CEscape(unescaped, as_utf8=True))
+
+  def testCUnescape(self):
+    for escaped, escaped_utf8, unescaped in TEST_VALUES:
+      self.assertEqual(unescaped, text_encoding.CUnescape(escaped))
+      self.assertEqual(unescaped, text_encoding.CUnescape(escaped_utf8))
+
+
+if __name__ == "__main__":
+  unittest.main()
diff --git a/generator/google/protobuf/internal/text_format_test.py b/generator/google/protobuf/internal/text_format_test.py
new file mode 100644
index 0000000..0e38e0e
--- /dev/null
+++ b/generator/google/protobuf/internal/text_format_test.py
@@ -0,0 +1,1359 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Test for google.protobuf.text_format."""
+
+__author__ = 'kenton@google.com (Kenton Varda)'
+
+
+import re
+import six
+import string
+
+try:
+  import unittest2 as unittest  # PY26, pylint: disable=g-import-not-at-top
+except ImportError:
+  import unittest  # pylint: disable=g-import-not-at-top
+
+from google.protobuf.internal import _parameterized
+
+from google.protobuf import any_test_pb2
+from google.protobuf import map_unittest_pb2
+from google.protobuf import unittest_mset_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import unittest_proto3_arena_pb2
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import test_util
+from google.protobuf.internal import message_set_extensions_pb2
+from google.protobuf import descriptor_pool
+from google.protobuf import text_format
+
+
+# Low-level nuts-n-bolts tests.
+class SimpleTextFormatTests(unittest.TestCase):
+
+  # The members of _QUOTES are formatted into a regexp template that
+  # expects single characters.  Therefore it's an error (in addition to being
+  # non-sensical in the first place) to try to specify a "quote mark" that is
+  # more than one character.
+  def testQuoteMarksAreSingleChars(self):
+    for quote in text_format._QUOTES:
+      self.assertEqual(1, len(quote))
+
+
+# Base class with some common functionality.
+class TextFormatBase(unittest.TestCase):
+
+  def ReadGolden(self, golden_filename):
+    with test_util.GoldenFile(golden_filename) as f:
+      return (f.readlines() if str is bytes else  # PY3
+              [golden_line.decode('utf-8') for golden_line in f])
+
+  def CompareToGoldenFile(self, text, golden_filename):
+    golden_lines = self.ReadGolden(golden_filename)
+    self.assertMultiLineEqual(text, ''.join(golden_lines))
+
+  def CompareToGoldenText(self, text, golden_text):
+    self.assertEqual(text, golden_text)
+
+  def RemoveRedundantZeros(self, text):
+    # Some platforms print 1e+5 as 1e+005.  This is fine, but we need to remove
+    # these zeros in order to match the golden file.
+    text = text.replace('e+0','e+').replace('e+0','e+') \
+               .replace('e-0','e-').replace('e-0','e-')
+    # Floating point fields are printed with .0 suffix even if they are
+    # actualy integer numbers.
+    text = re.compile(r'\.0$', re.MULTILINE).sub('', text)
+    return text
+
+
+@_parameterized.Parameters((unittest_pb2), (unittest_proto3_arena_pb2))
+class TextFormatTest(TextFormatBase):
+
+  def testPrintExotic(self, message_module):
+    message = message_module.TestAllTypes()
+    message.repeated_int64.append(-9223372036854775808)
+    message.repeated_uint64.append(18446744073709551615)
+    message.repeated_double.append(123.456)
+    message.repeated_double.append(1.23e22)
+    message.repeated_double.append(1.23e-18)
+    message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
+    message.repeated_string.append(u'\u00fc\ua71f')
+    self.CompareToGoldenText(
+        self.RemoveRedundantZeros(text_format.MessageToString(message)),
+        'repeated_int64: -9223372036854775808\n'
+        'repeated_uint64: 18446744073709551615\n'
+        'repeated_double: 123.456\n'
+        'repeated_double: 1.23e+22\n'
+        'repeated_double: 1.23e-18\n'
+        'repeated_string:'
+        ' "\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n'
+        'repeated_string: "\\303\\274\\352\\234\\237"\n')
+
+  def testPrintExoticUnicodeSubclass(self, message_module):
+
+    class UnicodeSub(six.text_type):
+      pass
+
+    message = message_module.TestAllTypes()
+    message.repeated_string.append(UnicodeSub(u'\u00fc\ua71f'))
+    self.CompareToGoldenText(
+        text_format.MessageToString(message),
+        'repeated_string: "\\303\\274\\352\\234\\237"\n')
+
+  def testPrintNestedMessageAsOneLine(self, message_module):
+    message = message_module.TestAllTypes()
+    msg = message.repeated_nested_message.add()
+    msg.bb = 42
+    self.CompareToGoldenText(
+        text_format.MessageToString(message, as_one_line=True),
+        'repeated_nested_message { bb: 42 }')
+
+  def testPrintRepeatedFieldsAsOneLine(self, message_module):
+    message = message_module.TestAllTypes()
+    message.repeated_int32.append(1)
+    message.repeated_int32.append(1)
+    message.repeated_int32.append(3)
+    message.repeated_string.append('Google')
+    message.repeated_string.append('Zurich')
+    self.CompareToGoldenText(
+        text_format.MessageToString(message, as_one_line=True),
+        'repeated_int32: 1 repeated_int32: 1 repeated_int32: 3 '
+        'repeated_string: "Google" repeated_string: "Zurich"')
+
+  def testPrintNestedNewLineInStringAsOneLine(self, message_module):
+    message = message_module.TestAllTypes()
+    message.optional_string = 'a\nnew\nline'
+    self.CompareToGoldenText(
+        text_format.MessageToString(message, as_one_line=True),
+        'optional_string: "a\\nnew\\nline"')
+
+  def testPrintExoticAsOneLine(self, message_module):
+    message = message_module.TestAllTypes()
+    message.repeated_int64.append(-9223372036854775808)
+    message.repeated_uint64.append(18446744073709551615)
+    message.repeated_double.append(123.456)
+    message.repeated_double.append(1.23e22)
+    message.repeated_double.append(1.23e-18)
+    message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
+    message.repeated_string.append(u'\u00fc\ua71f')
+    self.CompareToGoldenText(
+        self.RemoveRedundantZeros(text_format.MessageToString(
+            message, as_one_line=True)),
+        'repeated_int64: -9223372036854775808'
+        ' repeated_uint64: 18446744073709551615'
+        ' repeated_double: 123.456'
+        ' repeated_double: 1.23e+22'
+        ' repeated_double: 1.23e-18'
+        ' repeated_string: '
+        '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""'
+        ' repeated_string: "\\303\\274\\352\\234\\237"')
+
+  def testRoundTripExoticAsOneLine(self, message_module):
+    message = message_module.TestAllTypes()
+    message.repeated_int64.append(-9223372036854775808)
+    message.repeated_uint64.append(18446744073709551615)
+    message.repeated_double.append(123.456)
+    message.repeated_double.append(1.23e22)
+    message.repeated_double.append(1.23e-18)
+    message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
+    message.repeated_string.append(u'\u00fc\ua71f')
+
+    # Test as_utf8 = False.
+    wire_text = text_format.MessageToString(message,
+                                            as_one_line=True,
+                                            as_utf8=False)
+    parsed_message = message_module.TestAllTypes()
+    r = text_format.Parse(wire_text, parsed_message)
+    self.assertIs(r, parsed_message)
+    self.assertEqual(message, parsed_message)
+
+    # Test as_utf8 = True.
+    wire_text = text_format.MessageToString(message,
+                                            as_one_line=True,
+                                            as_utf8=True)
+    parsed_message = message_module.TestAllTypes()
+    r = text_format.Parse(wire_text, parsed_message)
+    self.assertIs(r, parsed_message)
+    self.assertEqual(message, parsed_message,
+                     '\n%s != %s' % (message, parsed_message))
+
+  def testPrintRawUtf8String(self, message_module):
+    message = message_module.TestAllTypes()
+    message.repeated_string.append(u'\u00fc\ua71f')
+    text = text_format.MessageToString(message, as_utf8=True)
+    self.CompareToGoldenText(text, 'repeated_string: "\303\274\352\234\237"\n')
+    parsed_message = message_module.TestAllTypes()
+    text_format.Parse(text, parsed_message)
+    self.assertEqual(message, parsed_message,
+                     '\n%s != %s' % (message, parsed_message))
+
+  def testPrintFloatFormat(self, message_module):
+    # Check that float_format argument is passed to sub-message formatting.
+    message = message_module.NestedTestAllTypes()
+    # We use 1.25 as it is a round number in binary.  The proto 32-bit float
+    # will not gain additional imprecise digits as a 64-bit Python float and
+    # show up in its str.  32-bit 1.2 is noisy when extended to 64-bit:
+    #  >>> struct.unpack('f', struct.pack('f', 1.2))[0]
+    #  1.2000000476837158
+    #  >>> struct.unpack('f', struct.pack('f', 1.25))[0]
+    #  1.25
+    message.payload.optional_float = 1.25
+    # Check rounding at 15 significant digits
+    message.payload.optional_double = -.000003456789012345678
+    # Check no decimal point.
+    message.payload.repeated_float.append(-5642)
+    # Check no trailing zeros.
+    message.payload.repeated_double.append(.000078900)
+    formatted_fields = ['optional_float: 1.25',
+                        'optional_double: -3.45678901234568e-6',
+                        'repeated_float: -5642', 'repeated_double: 7.89e-5']
+    text_message = text_format.MessageToString(message, float_format='.15g')
+    self.CompareToGoldenText(
+        self.RemoveRedundantZeros(text_message),
+        'payload {{\n  {0}\n  {1}\n  {2}\n  {3}\n}}\n'.format(
+            *formatted_fields))
+    # as_one_line=True is a separate code branch where float_format is passed.
+    text_message = text_format.MessageToString(message,
+                                               as_one_line=True,
+                                               float_format='.15g')
+    self.CompareToGoldenText(
+        self.RemoveRedundantZeros(text_message),
+        'payload {{ {0} {1} {2} {3} }}'.format(*formatted_fields))
+
+  def testMessageToString(self, message_module):
+    message = message_module.ForeignMessage()
+    message.c = 123
+    self.assertEqual('c: 123\n', str(message))
+
+  def testPrintField(self, message_module):
+    message = message_module.TestAllTypes()
+    field = message.DESCRIPTOR.fields_by_name['optional_float']
+    value = message.optional_float
+    out = text_format.TextWriter(False)
+    text_format.PrintField(field, value, out)
+    self.assertEqual('optional_float: 0.0\n', out.getvalue())
+    out.close()
+    # Test Printer
+    out = text_format.TextWriter(False)
+    printer = text_format._Printer(out)
+    printer.PrintField(field, value)
+    self.assertEqual('optional_float: 0.0\n', out.getvalue())
+    out.close()
+
+  def testPrintFieldValue(self, message_module):
+    message = message_module.TestAllTypes()
+    field = message.DESCRIPTOR.fields_by_name['optional_float']
+    value = message.optional_float
+    out = text_format.TextWriter(False)
+    text_format.PrintFieldValue(field, value, out)
+    self.assertEqual('0.0', out.getvalue())
+    out.close()
+    # Test Printer
+    out = text_format.TextWriter(False)
+    printer = text_format._Printer(out)
+    printer.PrintFieldValue(field, value)
+    self.assertEqual('0.0', out.getvalue())
+    out.close()
+
+  def testParseAllFields(self, message_module):
+    message = message_module.TestAllTypes()
+    test_util.SetAllFields(message)
+    ascii_text = text_format.MessageToString(message)
+
+    parsed_message = message_module.TestAllTypes()
+    text_format.Parse(ascii_text, parsed_message)
+    self.assertEqual(message, parsed_message)
+    if message_module is unittest_pb2:
+      test_util.ExpectAllFieldsSet(self, message)
+
+  def testParseExotic(self, message_module):
+    message = message_module.TestAllTypes()
+    text = ('repeated_int64: -9223372036854775808\n'
+            'repeated_uint64: 18446744073709551615\n'
+            'repeated_double: 123.456\n'
+            'repeated_double: 1.23e+22\n'
+            'repeated_double: 1.23e-18\n'
+            'repeated_string: \n'
+            '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n'
+            'repeated_string: "foo" \'corge\' "grault"\n'
+            'repeated_string: "\\303\\274\\352\\234\\237"\n'
+            'repeated_string: "\\xc3\\xbc"\n'
+            'repeated_string: "\xc3\xbc"\n')
+    text_format.Parse(text, message)
+
+    self.assertEqual(-9223372036854775808, message.repeated_int64[0])
+    self.assertEqual(18446744073709551615, message.repeated_uint64[0])
+    self.assertEqual(123.456, message.repeated_double[0])
+    self.assertEqual(1.23e22, message.repeated_double[1])
+    self.assertEqual(1.23e-18, message.repeated_double[2])
+    self.assertEqual('\000\001\a\b\f\n\r\t\v\\\'"', message.repeated_string[0])
+    self.assertEqual('foocorgegrault', message.repeated_string[1])
+    self.assertEqual(u'\u00fc\ua71f', message.repeated_string[2])
+    self.assertEqual(u'\u00fc', message.repeated_string[3])
+
+  def testParseTrailingCommas(self, message_module):
+    message = message_module.TestAllTypes()
+    text = ('repeated_int64: 100;\n'
+            'repeated_int64: 200;\n'
+            'repeated_int64: 300,\n'
+            'repeated_string: "one",\n'
+            'repeated_string: "two";\n')
+    text_format.Parse(text, message)
+
+    self.assertEqual(100, message.repeated_int64[0])
+    self.assertEqual(200, message.repeated_int64[1])
+    self.assertEqual(300, message.repeated_int64[2])
+    self.assertEqual(u'one', message.repeated_string[0])
+    self.assertEqual(u'two', message.repeated_string[1])
+
+  def testParseRepeatedScalarShortFormat(self, message_module):
+    message = message_module.TestAllTypes()
+    text = ('repeated_int64: [100, 200];\n'
+            'repeated_int64: 300,\n'
+            'repeated_string: ["one", "two"];\n')
+    text_format.Parse(text, message)
+
+    self.assertEqual(100, message.repeated_int64[0])
+    self.assertEqual(200, message.repeated_int64[1])
+    self.assertEqual(300, message.repeated_int64[2])
+    self.assertEqual(u'one', message.repeated_string[0])
+    self.assertEqual(u'two', message.repeated_string[1])
+
+  def testParseRepeatedMessageShortFormat(self, message_module):
+    message = message_module.TestAllTypes()
+    text = ('repeated_nested_message: [{bb: 100}, {bb: 200}],\n'
+            'repeated_nested_message: {bb: 300}\n'
+            'repeated_nested_message [{bb: 400}];\n')
+    text_format.Parse(text, message)
+
+    self.assertEqual(100, message.repeated_nested_message[0].bb)
+    self.assertEqual(200, message.repeated_nested_message[1].bb)
+    self.assertEqual(300, message.repeated_nested_message[2].bb)
+    self.assertEqual(400, message.repeated_nested_message[3].bb)
+
+  def testParseEmptyText(self, message_module):
+    message = message_module.TestAllTypes()
+    text = ''
+    text_format.Parse(text, message)
+    self.assertEqual(message_module.TestAllTypes(), message)
+
+  def testParseInvalidUtf8(self, message_module):
+    message = message_module.TestAllTypes()
+    text = 'repeated_string: "\\xc3\\xc3"'
+    self.assertRaises(text_format.ParseError, text_format.Parse, text, message)
+
+  def testParseSingleWord(self, message_module):
+    message = message_module.TestAllTypes()
+    text = 'foo'
+    six.assertRaisesRegex(self, text_format.ParseError, (
+        r'1:1 : Message type "\w+.TestAllTypes" has no field named '
+        r'"foo".'), text_format.Parse, text, message)
+
+  def testParseUnknownField(self, message_module):
+    message = message_module.TestAllTypes()
+    text = 'unknown_field: 8\n'
+    six.assertRaisesRegex(self, text_format.ParseError, (
+        r'1:1 : Message type "\w+.TestAllTypes" has no field named '
+        r'"unknown_field".'), text_format.Parse, text, message)
+
+  def testParseBadEnumValue(self, message_module):
+    message = message_module.TestAllTypes()
+    text = 'optional_nested_enum: BARR'
+    six.assertRaisesRegex(self, text_format.ParseError,
+                          (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" '
+                           r'has no value named BARR.'), text_format.Parse,
+                          text, message)
+
+    message = message_module.TestAllTypes()
+    text = 'optional_nested_enum: 100'
+    six.assertRaisesRegex(self, text_format.ParseError,
+                          (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" '
+                           r'has no value with number 100.'), text_format.Parse,
+                          text, message)
+
+  def testParseBadIntValue(self, message_module):
+    message = message_module.TestAllTypes()
+    text = 'optional_int32: bork'
+    six.assertRaisesRegex(self, text_format.ParseError,
+                          ('1:17 : Couldn\'t parse integer: bork'),
+                          text_format.Parse, text, message)
+
+  def testParseStringFieldUnescape(self, message_module):
+    message = message_module.TestAllTypes()
+    text = r'''repeated_string: "\xf\x62"
+               repeated_string: "\\xf\\x62"
+               repeated_string: "\\\xf\\\x62"
+               repeated_string: "\\\\xf\\\\x62"
+               repeated_string: "\\\\\xf\\\\\x62"
+               repeated_string: "\x5cx20"'''
+
+    text_format.Parse(text, message)
+
+    SLASH = '\\'
+    self.assertEqual('\x0fb', message.repeated_string[0])
+    self.assertEqual(SLASH + 'xf' + SLASH + 'x62', message.repeated_string[1])
+    self.assertEqual(SLASH + '\x0f' + SLASH + 'b', message.repeated_string[2])
+    self.assertEqual(SLASH + SLASH + 'xf' + SLASH + SLASH + 'x62',
+                     message.repeated_string[3])
+    self.assertEqual(SLASH + SLASH + '\x0f' + SLASH + SLASH + 'b',
+                     message.repeated_string[4])
+    self.assertEqual(SLASH + 'x20', message.repeated_string[5])
+
+  def testMergeDuplicateScalars(self, message_module):
+    message = message_module.TestAllTypes()
+    text = ('optional_int32: 42 ' 'optional_int32: 67')
+    r = text_format.Merge(text, message)
+    self.assertIs(r, message)
+    self.assertEqual(67, message.optional_int32)
+
+  def testMergeDuplicateNestedMessageScalars(self, message_module):
+    message = message_module.TestAllTypes()
+    text = ('optional_nested_message { bb: 1 } '
+            'optional_nested_message { bb: 2 }')
+    r = text_format.Merge(text, message)
+    self.assertTrue(r is message)
+    self.assertEqual(2, message.optional_nested_message.bb)
+
+  def testParseOneof(self, message_module):
+    m = message_module.TestAllTypes()
+    m.oneof_uint32 = 11
+    m2 = message_module.TestAllTypes()
+    text_format.Parse(text_format.MessageToString(m), m2)
+    self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
+
+  def testParseMultipleOneof(self, message_module):
+    m_string = '\n'.join(['oneof_uint32: 11', 'oneof_string: "foo"'])
+    m2 = message_module.TestAllTypes()
+    if message_module is unittest_pb2:
+      with self.assertRaisesRegexp(text_format.ParseError,
+                                   ' is specified along with field '):
+        text_format.Parse(m_string, m2)
+    else:
+      text_format.Parse(m_string, m2)
+      self.assertEqual('oneof_string', m2.WhichOneof('oneof_field'))
+
+
+# These are tests that aren't fundamentally specific to proto2, but are at
+# the moment because of differences between the proto2 and proto3 test schemas.
+# Ideally the schemas would be made more similar so these tests could pass.
+class OnlyWorksWithProto2RightNowTests(TextFormatBase):
+
+  def testPrintAllFieldsPointy(self):
+    message = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(message)
+    self.CompareToGoldenFile(
+        self.RemoveRedundantZeros(text_format.MessageToString(
+            message, pointy_brackets=True)),
+        'text_format_unittest_data_pointy_oneof.txt')
+
+  def testParseGolden(self):
+    golden_text = '\n'.join(self.ReadGolden(
+        'text_format_unittest_data_oneof_implemented.txt'))
+    parsed_message = unittest_pb2.TestAllTypes()
+    r = text_format.Parse(golden_text, parsed_message)
+    self.assertIs(r, parsed_message)
+
+    message = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(message)
+    self.assertEqual(message, parsed_message)
+
+  def testPrintAllFields(self):
+    message = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(message)
+    self.CompareToGoldenFile(
+        self.RemoveRedundantZeros(text_format.MessageToString(message)),
+        'text_format_unittest_data_oneof_implemented.txt')
+
+  def testPrintInIndexOrder(self):
+    message = unittest_pb2.TestFieldOrderings()
+    message.my_string = '115'
+    message.my_int = 101
+    message.my_float = 111
+    message.optional_nested_message.oo = 0
+    message.optional_nested_message.bb = 1
+    self.CompareToGoldenText(
+        self.RemoveRedundantZeros(text_format.MessageToString(
+            message, use_index_order=True)),
+        'my_string: \"115\"\nmy_int: 101\nmy_float: 111\n'
+        'optional_nested_message {\n  oo: 0\n  bb: 1\n}\n')
+    self.CompareToGoldenText(
+        self.RemoveRedundantZeros(text_format.MessageToString(message)),
+        'my_int: 101\nmy_string: \"115\"\nmy_float: 111\n'
+        'optional_nested_message {\n  bb: 1\n  oo: 0\n}\n')
+
+  def testMergeLinesGolden(self):
+    opened = self.ReadGolden('text_format_unittest_data_oneof_implemented.txt')
+    parsed_message = unittest_pb2.TestAllTypes()
+    r = text_format.MergeLines(opened, parsed_message)
+    self.assertIs(r, parsed_message)
+
+    message = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(message)
+    self.assertEqual(message, parsed_message)
+
+  def testParseLinesGolden(self):
+    opened = self.ReadGolden('text_format_unittest_data_oneof_implemented.txt')
+    parsed_message = unittest_pb2.TestAllTypes()
+    r = text_format.ParseLines(opened, parsed_message)
+    self.assertIs(r, parsed_message)
+
+    message = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(message)
+    self.assertEqual(message, parsed_message)
+
+  def testPrintMap(self):
+    message = map_unittest_pb2.TestMap()
+
+    message.map_int32_int32[-123] = -456
+    message.map_int64_int64[-2**33] = -2**34
+    message.map_uint32_uint32[123] = 456
+    message.map_uint64_uint64[2**33] = 2**34
+    message.map_string_string['abc'] = '123'
+    message.map_int32_foreign_message[111].c = 5
+
+    # Maps are serialized to text format using their underlying repeated
+    # representation.
+    self.CompareToGoldenText(
+        text_format.MessageToString(message), 'map_int32_int32 {\n'
+        '  key: -123\n'
+        '  value: -456\n'
+        '}\n'
+        'map_int64_int64 {\n'
+        '  key: -8589934592\n'
+        '  value: -17179869184\n'
+        '}\n'
+        'map_uint32_uint32 {\n'
+        '  key: 123\n'
+        '  value: 456\n'
+        '}\n'
+        'map_uint64_uint64 {\n'
+        '  key: 8589934592\n'
+        '  value: 17179869184\n'
+        '}\n'
+        'map_string_string {\n'
+        '  key: "abc"\n'
+        '  value: "123"\n'
+        '}\n'
+        'map_int32_foreign_message {\n'
+        '  key: 111\n'
+        '  value {\n'
+        '    c: 5\n'
+        '  }\n'
+        '}\n')
+
+  def testMapOrderEnforcement(self):
+    message = map_unittest_pb2.TestMap()
+    for letter in string.ascii_uppercase[13:26]:
+      message.map_string_string[letter] = 'dummy'
+    for letter in reversed(string.ascii_uppercase[0:13]):
+      message.map_string_string[letter] = 'dummy'
+    golden = ''.join(('map_string_string {\n  key: "%c"\n  value: "dummy"\n}\n'
+                      % (letter,) for letter in string.ascii_uppercase))
+    self.CompareToGoldenText(text_format.MessageToString(message), golden)
+
+  def testMapOrderSemantics(self):
+    golden_lines = self.ReadGolden('map_test_data.txt')
+    # The C++ implementation emits defaulted-value fields, while the Python
+    # implementation does not.  Adjusting for this is awkward, but it is
+    # valuable to test against a common golden file.
+    line_blacklist = ('  key: 0\n', '  value: 0\n', '  key: false\n',
+                      '  value: false\n')
+    golden_lines = [line for line in golden_lines if line not in line_blacklist]
+
+    message = map_unittest_pb2.TestMap()
+    text_format.ParseLines(golden_lines, message)
+    candidate = text_format.MessageToString(message)
+    # The Python implementation emits "1.0" for the double value that the C++
+    # implementation emits as "1".
+    candidate = candidate.replace('1.0', '1', 2)
+    self.assertMultiLineEqual(candidate, ''.join(golden_lines))
+
+
+# Tests of proto2-only features (MessageSet, extensions, etc.).
+class Proto2Tests(TextFormatBase):
+
+  def testPrintMessageSet(self):
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+    ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+    message.message_set.Extensions[ext1].i = 23
+    message.message_set.Extensions[ext2].str = 'foo'
+    self.CompareToGoldenText(
+        text_format.MessageToString(message), 'message_set {\n'
+        '  [protobuf_unittest.TestMessageSetExtension1] {\n'
+        '    i: 23\n'
+        '  }\n'
+        '  [protobuf_unittest.TestMessageSetExtension2] {\n'
+        '    str: \"foo\"\n'
+        '  }\n'
+        '}\n')
+
+    message = message_set_extensions_pb2.TestMessageSet()
+    ext = message_set_extensions_pb2.message_set_extension3
+    message.Extensions[ext].text = 'bar'
+    self.CompareToGoldenText(
+        text_format.MessageToString(message),
+        '[google.protobuf.internal.TestMessageSetExtension3] {\n'
+        '  text: \"bar\"\n'
+        '}\n')
+
+  def testPrintMessageSetByFieldNumber(self):
+    out = text_format.TextWriter(False)
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+    ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+    message.message_set.Extensions[ext1].i = 23
+    message.message_set.Extensions[ext2].str = 'foo'
+    text_format.PrintMessage(message, out, use_field_number=True)
+    self.CompareToGoldenText(out.getvalue(), '1 {\n'
+                             '  1545008 {\n'
+                             '    15: 23\n'
+                             '  }\n'
+                             '  1547769 {\n'
+                             '    25: \"foo\"\n'
+                             '  }\n'
+                             '}\n')
+    out.close()
+
+  def testPrintMessageSetAsOneLine(self):
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+    ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+    message.message_set.Extensions[ext1].i = 23
+    message.message_set.Extensions[ext2].str = 'foo'
+    self.CompareToGoldenText(
+        text_format.MessageToString(message, as_one_line=True),
+        'message_set {'
+        ' [protobuf_unittest.TestMessageSetExtension1] {'
+        ' i: 23'
+        ' }'
+        ' [protobuf_unittest.TestMessageSetExtension2] {'
+        ' str: \"foo\"'
+        ' }'
+        ' }')
+
+  def testParseMessageSet(self):
+    message = unittest_pb2.TestAllTypes()
+    text = ('repeated_uint64: 1\n' 'repeated_uint64: 2\n')
+    text_format.Parse(text, message)
+    self.assertEqual(1, message.repeated_uint64[0])
+    self.assertEqual(2, message.repeated_uint64[1])
+
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    text = ('message_set {\n'
+            '  [protobuf_unittest.TestMessageSetExtension1] {\n'
+            '    i: 23\n'
+            '  }\n'
+            '  [protobuf_unittest.TestMessageSetExtension2] {\n'
+            '    str: \"foo\"\n'
+            '  }\n'
+            '}\n')
+    text_format.Parse(text, message)
+    ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+    ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+    self.assertEqual(23, message.message_set.Extensions[ext1].i)
+    self.assertEqual('foo', message.message_set.Extensions[ext2].str)
+
+  def testParseMessageByFieldNumber(self):
+    message = unittest_pb2.TestAllTypes()
+    text = ('34: 1\n' 'repeated_uint64: 2\n')
+    text_format.Parse(text, message, allow_field_number=True)
+    self.assertEqual(1, message.repeated_uint64[0])
+    self.assertEqual(2, message.repeated_uint64[1])
+
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    text = ('1 {\n'
+            '  1545008 {\n'
+            '    15: 23\n'
+            '  }\n'
+            '  1547769 {\n'
+            '    25: \"foo\"\n'
+            '  }\n'
+            '}\n')
+    text_format.Parse(text, message, allow_field_number=True)
+    ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+    ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+    self.assertEqual(23, message.message_set.Extensions[ext1].i)
+    self.assertEqual('foo', message.message_set.Extensions[ext2].str)
+
+    # Can't parse field number without set allow_field_number=True.
+    message = unittest_pb2.TestAllTypes()
+    text = '34:1\n'
+    six.assertRaisesRegex(self, text_format.ParseError, (
+        r'1:1 : Message type "\w+.TestAllTypes" has no field named '
+        r'"34".'), text_format.Parse, text, message)
+
+    # Can't parse if field number is not found.
+    text = '1234:1\n'
+    six.assertRaisesRegex(
+        self,
+        text_format.ParseError,
+        (r'1:1 : Message type "\w+.TestAllTypes" has no field named '
+         r'"1234".'),
+        text_format.Parse,
+        text,
+        message,
+        allow_field_number=True)
+
+  def testPrintAllExtensions(self):
+    message = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(message)
+    self.CompareToGoldenFile(
+        self.RemoveRedundantZeros(text_format.MessageToString(message)),
+        'text_format_unittest_extensions_data.txt')
+
+  def testPrintAllExtensionsPointy(self):
+    message = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(message)
+    self.CompareToGoldenFile(
+        self.RemoveRedundantZeros(text_format.MessageToString(
+            message, pointy_brackets=True)),
+        'text_format_unittest_extensions_data_pointy.txt')
+
+  def testParseGoldenExtensions(self):
+    golden_text = '\n'.join(self.ReadGolden(
+        'text_format_unittest_extensions_data.txt'))
+    parsed_message = unittest_pb2.TestAllExtensions()
+    text_format.Parse(golden_text, parsed_message)
+
+    message = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(message)
+    self.assertEqual(message, parsed_message)
+
+  def testParseAllExtensions(self):
+    message = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(message)
+    ascii_text = text_format.MessageToString(message)
+
+    parsed_message = unittest_pb2.TestAllExtensions()
+    text_format.Parse(ascii_text, parsed_message)
+    self.assertEqual(message, parsed_message)
+
+  def testParseAllowedUnknownExtension(self):
+    # Skip over unknown extension correctly.
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    text = ('message_set {\n'
+            '  [unknown_extension] {\n'
+            '    i: 23\n'
+            '    bin: "\xe0"'
+            '    [nested_unknown_ext]: {\n'
+            '      i: 23\n'
+            '      test: "test_string"\n'
+            '      floaty_float: -0.315\n'
+            '      num: -inf\n'
+            '      multiline_str: "abc"\n'
+            '          "def"\n'
+            '          "xyz."\n'
+            '      [nested_unknown_ext]: <\n'
+            '        i: 23\n'
+            '        i: 24\n'
+            '        pointfloat: .3\n'
+            '        test: "test_string"\n'
+            '        floaty_float: -0.315\n'
+            '        num: -inf\n'
+            '        long_string: "test" "test2" \n'
+            '      >\n'
+            '    }\n'
+            '  }\n'
+            '  [unknown_extension]: 5\n'
+            '}\n')
+    text_format.Parse(text, message, allow_unknown_extension=True)
+    golden = 'message_set {\n}\n'
+    self.CompareToGoldenText(text_format.MessageToString(message), golden)
+
+    # Catch parse errors in unknown extension.
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    malformed = ('message_set {\n'
+                 '  [unknown_extension] {\n'
+                 '    i:\n'  # Missing value.
+                 '  }\n'
+                 '}\n')
+    six.assertRaisesRegex(self,
+                          text_format.ParseError,
+                          'Invalid field value: }',
+                          text_format.Parse,
+                          malformed,
+                          message,
+                          allow_unknown_extension=True)
+
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    malformed = ('message_set {\n'
+                 '  [unknown_extension] {\n'
+                 '    str: "malformed string\n'  # Missing closing quote.
+                 '  }\n'
+                 '}\n')
+    six.assertRaisesRegex(self,
+                          text_format.ParseError,
+                          'Invalid field value: "',
+                          text_format.Parse,
+                          malformed,
+                          message,
+                          allow_unknown_extension=True)
+
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    malformed = ('message_set {\n'
+                 '  [unknown_extension] {\n'
+                 '    str: "malformed\n multiline\n string\n'
+                 '  }\n'
+                 '}\n')
+    six.assertRaisesRegex(self,
+                          text_format.ParseError,
+                          'Invalid field value: "',
+                          text_format.Parse,
+                          malformed,
+                          message,
+                          allow_unknown_extension=True)
+
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    malformed = ('message_set {\n'
+                 '  [malformed_extension] <\n'
+                 '    i: -5\n'
+                 '  \n'  # Missing '>' here.
+                 '}\n')
+    six.assertRaisesRegex(self,
+                          text_format.ParseError,
+                          '5:1 : Expected ">".',
+                          text_format.Parse,
+                          malformed,
+                          message,
+                          allow_unknown_extension=True)
+
+    # Don't allow unknown fields with allow_unknown_extension=True.
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    malformed = ('message_set {\n'
+                 '  unknown_field: true\n'
+                 '  \n'  # Missing '>' here.
+                 '}\n')
+    six.assertRaisesRegex(self,
+                          text_format.ParseError,
+                          ('2:3 : Message type '
+                           '"proto2_wireformat_unittest.TestMessageSet" has no'
+                           ' field named "unknown_field".'),
+                          text_format.Parse,
+                          malformed,
+                          message,
+                          allow_unknown_extension=True)
+
+    # Parse known extension correcty.
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    text = ('message_set {\n'
+            '  [protobuf_unittest.TestMessageSetExtension1] {\n'
+            '    i: 23\n'
+            '  }\n'
+            '  [protobuf_unittest.TestMessageSetExtension2] {\n'
+            '    str: \"foo\"\n'
+            '  }\n'
+            '}\n')
+    text_format.Parse(text, message, allow_unknown_extension=True)
+    ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+    ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+    self.assertEqual(23, message.message_set.Extensions[ext1].i)
+    self.assertEqual('foo', message.message_set.Extensions[ext2].str)
+
+  def testParseBadExtension(self):
+    message = unittest_pb2.TestAllExtensions()
+    text = '[unknown_extension]: 8\n'
+    six.assertRaisesRegex(self, text_format.ParseError,
+                          '1:2 : Extension "unknown_extension" not registered.',
+                          text_format.Parse, text, message)
+    message = unittest_pb2.TestAllTypes()
+    six.assertRaisesRegex(self, text_format.ParseError, (
+        '1:2 : Message type "protobuf_unittest.TestAllTypes" does not have '
+        'extensions.'), text_format.Parse, text, message)
+
+  def testMergeDuplicateExtensionScalars(self):
+    message = unittest_pb2.TestAllExtensions()
+    text = ('[protobuf_unittest.optional_int32_extension]: 42 '
+            '[protobuf_unittest.optional_int32_extension]: 67')
+    text_format.Merge(text, message)
+    self.assertEqual(67,
+                     message.Extensions[unittest_pb2.optional_int32_extension])
+
+  def testParseDuplicateExtensionScalars(self):
+    message = unittest_pb2.TestAllExtensions()
+    text = ('[protobuf_unittest.optional_int32_extension]: 42 '
+            '[protobuf_unittest.optional_int32_extension]: 67')
+    six.assertRaisesRegex(self, text_format.ParseError, (
+        '1:96 : Message type "protobuf_unittest.TestAllExtensions" '
+        'should not have multiple '
+        '"protobuf_unittest.optional_int32_extension" extensions.'),
+                          text_format.Parse, text, message)
+
+  def testParseDuplicateNestedMessageScalars(self):
+    message = unittest_pb2.TestAllTypes()
+    text = ('optional_nested_message { bb: 1 } '
+            'optional_nested_message { bb: 2 }')
+    six.assertRaisesRegex(self, text_format.ParseError, (
+        '1:65 : Message type "protobuf_unittest.TestAllTypes.NestedMessage" '
+        'should not have multiple "bb" fields.'), text_format.Parse, text,
+                          message)
+
+  def testParseDuplicateScalars(self):
+    message = unittest_pb2.TestAllTypes()
+    text = ('optional_int32: 42 ' 'optional_int32: 67')
+    six.assertRaisesRegex(self, text_format.ParseError, (
+        '1:36 : Message type "protobuf_unittest.TestAllTypes" should not '
+        'have multiple "optional_int32" fields.'), text_format.Parse, text,
+                          message)
+
+  def testParseGroupNotClosed(self):
+    message = unittest_pb2.TestAllTypes()
+    text = 'RepeatedGroup: <'
+    six.assertRaisesRegex(self, text_format.ParseError, '1:16 : Expected ">".',
+                          text_format.Parse, text, message)
+    text = 'RepeatedGroup: {'
+    six.assertRaisesRegex(self, text_format.ParseError, '1:16 : Expected "}".',
+                          text_format.Parse, text, message)
+
+  def testParseEmptyGroup(self):
+    message = unittest_pb2.TestAllTypes()
+    text = 'OptionalGroup: {}'
+    text_format.Parse(text, message)
+    self.assertTrue(message.HasField('optionalgroup'))
+
+    message.Clear()
+
+    message = unittest_pb2.TestAllTypes()
+    text = 'OptionalGroup: <>'
+    text_format.Parse(text, message)
+    self.assertTrue(message.HasField('optionalgroup'))
+
+  # Maps aren't really proto2-only, but our test schema only has maps for
+  # proto2.
+  def testParseMap(self):
+    text = ('map_int32_int32 {\n'
+            '  key: -123\n'
+            '  value: -456\n'
+            '}\n'
+            'map_int64_int64 {\n'
+            '  key: -8589934592\n'
+            '  value: -17179869184\n'
+            '}\n'
+            'map_uint32_uint32 {\n'
+            '  key: 123\n'
+            '  value: 456\n'
+            '}\n'
+            'map_uint64_uint64 {\n'
+            '  key: 8589934592\n'
+            '  value: 17179869184\n'
+            '}\n'
+            'map_string_string {\n'
+            '  key: "abc"\n'
+            '  value: "123"\n'
+            '}\n'
+            'map_int32_foreign_message {\n'
+            '  key: 111\n'
+            '  value {\n'
+            '    c: 5\n'
+            '  }\n'
+            '}\n')
+    message = map_unittest_pb2.TestMap()
+    text_format.Parse(text, message)
+
+    self.assertEqual(-456, message.map_int32_int32[-123])
+    self.assertEqual(-2**34, message.map_int64_int64[-2**33])
+    self.assertEqual(456, message.map_uint32_uint32[123])
+    self.assertEqual(2**34, message.map_uint64_uint64[2**33])
+    self.assertEqual('123', message.map_string_string['abc'])
+    self.assertEqual(5, message.map_int32_foreign_message[111].c)
+
+
+class Proto3Tests(unittest.TestCase):
+
+  def testPrintMessageExpandAny(self):
+    packed_message = unittest_pb2.OneString()
+    packed_message.data = 'string'
+    message = any_test_pb2.TestAny()
+    message.any_value.Pack(packed_message)
+    self.assertEqual(
+        text_format.MessageToString(message,
+                                    descriptor_pool=descriptor_pool.Default()),
+        'any_value {\n'
+        '  [type.googleapis.com/protobuf_unittest.OneString] {\n'
+        '    data: "string"\n'
+        '  }\n'
+        '}\n')
+
+  def testPrintMessageExpandAnyRepeated(self):
+    packed_message = unittest_pb2.OneString()
+    message = any_test_pb2.TestAny()
+    packed_message.data = 'string0'
+    message.repeated_any_value.add().Pack(packed_message)
+    packed_message.data = 'string1'
+    message.repeated_any_value.add().Pack(packed_message)
+    self.assertEqual(
+        text_format.MessageToString(message,
+                                    descriptor_pool=descriptor_pool.Default()),
+        'repeated_any_value {\n'
+        '  [type.googleapis.com/protobuf_unittest.OneString] {\n'
+        '    data: "string0"\n'
+        '  }\n'
+        '}\n'
+        'repeated_any_value {\n'
+        '  [type.googleapis.com/protobuf_unittest.OneString] {\n'
+        '    data: "string1"\n'
+        '  }\n'
+        '}\n')
+
+  def testPrintMessageExpandAnyNoDescriptorPool(self):
+    packed_message = unittest_pb2.OneString()
+    packed_message.data = 'string'
+    message = any_test_pb2.TestAny()
+    message.any_value.Pack(packed_message)
+    self.assertEqual(
+        text_format.MessageToString(message, descriptor_pool=None),
+        'any_value {\n'
+        '  type_url: "type.googleapis.com/protobuf_unittest.OneString"\n'
+        '  value: "\\n\\006string"\n'
+        '}\n')
+
+  def testPrintMessageExpandAnyDescriptorPoolMissingType(self):
+    packed_message = unittest_pb2.OneString()
+    packed_message.data = 'string'
+    message = any_test_pb2.TestAny()
+    message.any_value.Pack(packed_message)
+    empty_pool = descriptor_pool.DescriptorPool()
+    self.assertEqual(
+        text_format.MessageToString(message, descriptor_pool=empty_pool),
+        'any_value {\n'
+        '  type_url: "type.googleapis.com/protobuf_unittest.OneString"\n'
+        '  value: "\\n\\006string"\n'
+        '}\n')
+
+  def testPrintMessageExpandAnyPointyBrackets(self):
+    packed_message = unittest_pb2.OneString()
+    packed_message.data = 'string'
+    message = any_test_pb2.TestAny()
+    message.any_value.Pack(packed_message)
+    self.assertEqual(
+        text_format.MessageToString(message,
+                                    pointy_brackets=True,
+                                    descriptor_pool=descriptor_pool.Default()),
+        'any_value <\n'
+        '  [type.googleapis.com/protobuf_unittest.OneString] <\n'
+        '    data: "string"\n'
+        '  >\n'
+        '>\n')
+
+  def testPrintMessageExpandAnyAsOneLine(self):
+    packed_message = unittest_pb2.OneString()
+    packed_message.data = 'string'
+    message = any_test_pb2.TestAny()
+    message.any_value.Pack(packed_message)
+    self.assertEqual(
+        text_format.MessageToString(message,
+                                    as_one_line=True,
+                                    descriptor_pool=descriptor_pool.Default()),
+        'any_value {'
+        ' [type.googleapis.com/protobuf_unittest.OneString]'
+        ' { data: "string" } '
+        '}')
+
+  def testPrintMessageExpandAnyAsOneLinePointyBrackets(self):
+    packed_message = unittest_pb2.OneString()
+    packed_message.data = 'string'
+    message = any_test_pb2.TestAny()
+    message.any_value.Pack(packed_message)
+    self.assertEqual(
+        text_format.MessageToString(message,
+                                    as_one_line=True,
+                                    pointy_brackets=True,
+                                    descriptor_pool=descriptor_pool.Default()),
+        'any_value <'
+        ' [type.googleapis.com/protobuf_unittest.OneString]'
+        ' < data: "string" > '
+        '>')
+
+  def testMergeExpandedAny(self):
+    message = any_test_pb2.TestAny()
+    text = ('any_value {\n'
+            '  [type.googleapis.com/protobuf_unittest.OneString] {\n'
+            '    data: "string"\n'
+            '  }\n'
+            '}\n')
+    text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default())
+    packed_message = unittest_pb2.OneString()
+    message.any_value.Unpack(packed_message)
+    self.assertEqual('string', packed_message.data)
+
+  def testMergeExpandedAnyRepeated(self):
+    message = any_test_pb2.TestAny()
+    text = ('repeated_any_value {\n'
+            '  [type.googleapis.com/protobuf_unittest.OneString] {\n'
+            '    data: "string0"\n'
+            '  }\n'
+            '}\n'
+            'repeated_any_value {\n'
+            '  [type.googleapis.com/protobuf_unittest.OneString] {\n'
+            '    data: "string1"\n'
+            '  }\n'
+            '}\n')
+    text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default())
+    packed_message = unittest_pb2.OneString()
+    message.repeated_any_value[0].Unpack(packed_message)
+    self.assertEqual('string0', packed_message.data)
+    message.repeated_any_value[1].Unpack(packed_message)
+    self.assertEqual('string1', packed_message.data)
+
+  def testMergeExpandedAnyPointyBrackets(self):
+    message = any_test_pb2.TestAny()
+    text = ('any_value {\n'
+            '  [type.googleapis.com/protobuf_unittest.OneString] <\n'
+            '    data: "string"\n'
+            '  >\n'
+            '}\n')
+    text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default())
+    packed_message = unittest_pb2.OneString()
+    message.any_value.Unpack(packed_message)
+    self.assertEqual('string', packed_message.data)
+
+  def testMergeExpandedAnyNoDescriptorPool(self):
+    message = any_test_pb2.TestAny()
+    text = ('any_value {\n'
+            '  [type.googleapis.com/protobuf_unittest.OneString] {\n'
+            '    data: "string"\n'
+            '  }\n'
+            '}\n')
+    with self.assertRaises(text_format.ParseError) as e:
+      text_format.Merge(text, message, descriptor_pool=None)
+    self.assertEqual(str(e.exception),
+                     'Descriptor pool required to parse expanded Any field')
+
+  def testMergeExpandedAnyDescriptorPoolMissingType(self):
+    message = any_test_pb2.TestAny()
+    text = ('any_value {\n'
+            '  [type.googleapis.com/protobuf_unittest.OneString] {\n'
+            '    data: "string"\n'
+            '  }\n'
+            '}\n')
+    with self.assertRaises(text_format.ParseError) as e:
+      empty_pool = descriptor_pool.DescriptorPool()
+      text_format.Merge(text, message, descriptor_pool=empty_pool)
+    self.assertEqual(
+        str(e.exception),
+        'Type protobuf_unittest.OneString not found in descriptor pool')
+
+  def testMergeUnexpandedAny(self):
+    text = ('any_value {\n'
+            '  type_url: "type.googleapis.com/protobuf_unittest.OneString"\n'
+            '  value: "\\n\\006string"\n'
+            '}\n')
+    message = any_test_pb2.TestAny()
+    text_format.Merge(text, message)
+    packed_message = unittest_pb2.OneString()
+    message.any_value.Unpack(packed_message)
+    self.assertEqual('string', packed_message.data)
+
+
+class TokenizerTest(unittest.TestCase):
+
+  def testSimpleTokenCases(self):
+    text = ('identifier1:"string1"\n     \n\n'
+            'identifier2 : \n \n123  \n  identifier3 :\'string\'\n'
+            'identifiER_4 : 1.1e+2 ID5:-0.23 ID6:\'aaaa\\\'bbbb\'\n'
+            'ID7 : "aa\\"bb"\n\n\n\n ID8: {A:inf B:-inf C:true D:false}\n'
+            'ID9: 22 ID10: -111111111111111111 ID11: -22\n'
+            'ID12: 2222222222222222222 ID13: 1.23456f ID14: 1.2e+2f '
+            'false_bool:  0 true_BOOL:t \n true_bool1:  1 false_BOOL1:f ')
+    tokenizer = text_format.Tokenizer(text.splitlines())
+    methods = [(tokenizer.ConsumeIdentifier, 'identifier1'), ':',
+               (tokenizer.ConsumeString, 'string1'),
+               (tokenizer.ConsumeIdentifier, 'identifier2'), ':',
+               (tokenizer.ConsumeInteger, 123),
+               (tokenizer.ConsumeIdentifier, 'identifier3'), ':',
+               (tokenizer.ConsumeString, 'string'),
+               (tokenizer.ConsumeIdentifier, 'identifiER_4'), ':',
+               (tokenizer.ConsumeFloat, 1.1e+2),
+               (tokenizer.ConsumeIdentifier, 'ID5'), ':',
+               (tokenizer.ConsumeFloat, -0.23),
+               (tokenizer.ConsumeIdentifier, 'ID6'), ':',
+               (tokenizer.ConsumeString, 'aaaa\'bbbb'),
+               (tokenizer.ConsumeIdentifier, 'ID7'), ':',
+               (tokenizer.ConsumeString, 'aa\"bb'),
+               (tokenizer.ConsumeIdentifier, 'ID8'), ':', '{',
+               (tokenizer.ConsumeIdentifier, 'A'), ':',
+               (tokenizer.ConsumeFloat, float('inf')),
+               (tokenizer.ConsumeIdentifier, 'B'), ':',
+               (tokenizer.ConsumeFloat, -float('inf')),
+               (tokenizer.ConsumeIdentifier, 'C'), ':',
+               (tokenizer.ConsumeBool, True),
+               (tokenizer.ConsumeIdentifier, 'D'), ':',
+               (tokenizer.ConsumeBool, False), '}',
+               (tokenizer.ConsumeIdentifier, 'ID9'), ':',
+               (tokenizer.ConsumeInteger, 22),
+               (tokenizer.ConsumeIdentifier, 'ID10'), ':',
+               (tokenizer.ConsumeInteger, -111111111111111111),
+               (tokenizer.ConsumeIdentifier, 'ID11'), ':',
+               (tokenizer.ConsumeInteger, -22),
+               (tokenizer.ConsumeIdentifier, 'ID12'), ':',
+               (tokenizer.ConsumeInteger, 2222222222222222222),
+               (tokenizer.ConsumeIdentifier, 'ID13'), ':',
+               (tokenizer.ConsumeFloat, 1.23456),
+               (tokenizer.ConsumeIdentifier, 'ID14'), ':',
+               (tokenizer.ConsumeFloat, 1.2e+2),
+               (tokenizer.ConsumeIdentifier, 'false_bool'), ':',
+               (tokenizer.ConsumeBool, False),
+               (tokenizer.ConsumeIdentifier, 'true_BOOL'), ':',
+               (tokenizer.ConsumeBool, True),
+               (tokenizer.ConsumeIdentifier, 'true_bool1'), ':',
+               (tokenizer.ConsumeBool, True),
+               (tokenizer.ConsumeIdentifier, 'false_BOOL1'), ':',
+               (tokenizer.ConsumeBool, False)]
+
+    i = 0
+    while not tokenizer.AtEnd():
+      m = methods[i]
+      if isinstance(m, str):
+        token = tokenizer.token
+        self.assertEqual(token, m)
+        tokenizer.NextToken()
+      else:
+        self.assertEqual(m[1], m[0]())
+      i += 1
+
+  def testConsumeAbstractIntegers(self):
+    # This test only tests the failures in the integer parsing methods as well
+    # as the '0' special cases.
+    int64_max = (1 << 63) - 1
+    uint32_max = (1 << 32) - 1
+    text = '-1 %d %d' % (uint32_max + 1, int64_max + 1)
+    tokenizer = text_format.Tokenizer(text.splitlines())
+    self.assertEqual(-1, tokenizer.ConsumeInteger())
+
+    self.assertEqual(uint32_max + 1, tokenizer.ConsumeInteger())
+
+    self.assertEqual(int64_max + 1, tokenizer.ConsumeInteger())
+    self.assertTrue(tokenizer.AtEnd())
+
+    text = '-0 0'
+    tokenizer = text_format.Tokenizer(text.splitlines())
+    self.assertEqual(0, tokenizer.ConsumeInteger())
+    self.assertEqual(0, tokenizer.ConsumeInteger())
+    self.assertTrue(tokenizer.AtEnd())
+
+  def testConsumeIntegers(self):
+    # This test only tests the failures in the integer parsing methods as well
+    # as the '0' special cases.
+    int64_max = (1 << 63) - 1
+    uint32_max = (1 << 32) - 1
+    text = '-1 %d %d' % (uint32_max + 1, int64_max + 1)
+    tokenizer = text_format.Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError,
+                      text_format._ConsumeUint32, tokenizer)
+    self.assertRaises(text_format.ParseError,
+                      text_format._ConsumeUint64, tokenizer)
+    self.assertEqual(-1, text_format._ConsumeInt32(tokenizer))
+
+    self.assertRaises(text_format.ParseError,
+                      text_format._ConsumeUint32, tokenizer)
+    self.assertRaises(text_format.ParseError,
+                      text_format._ConsumeInt32, tokenizer)
+    self.assertEqual(uint32_max + 1, text_format._ConsumeInt64(tokenizer))
+
+    self.assertRaises(text_format.ParseError,
+                      text_format._ConsumeInt64, tokenizer)
+    self.assertEqual(int64_max + 1, text_format._ConsumeUint64(tokenizer))
+    self.assertTrue(tokenizer.AtEnd())
+
+    text = '-0 -0 0 0'
+    tokenizer = text_format.Tokenizer(text.splitlines())
+    self.assertEqual(0, text_format._ConsumeUint32(tokenizer))
+    self.assertEqual(0, text_format._ConsumeUint64(tokenizer))
+    self.assertEqual(0, text_format._ConsumeUint32(tokenizer))
+    self.assertEqual(0, text_format._ConsumeUint64(tokenizer))
+    self.assertTrue(tokenizer.AtEnd())
+
+  def testConsumeByteString(self):
+    text = '"string1\''
+    tokenizer = text_format.Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+    text = 'string1"'
+    tokenizer = text_format.Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+    text = '\n"\\xt"'
+    tokenizer = text_format.Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+    text = '\n"\\"'
+    tokenizer = text_format.Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+    text = '\n"\\x"'
+    tokenizer = text_format.Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+  def testConsumeBool(self):
+    text = 'not-a-bool'
+    tokenizer = text_format.Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeBool)
+
+  def testSkipComment(self):
+    tokenizer = text_format.Tokenizer('# some comment'.splitlines())
+    self.assertTrue(tokenizer.AtEnd())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeComment)
+
+  def testConsumeComment(self):
+    tokenizer = text_format.Tokenizer('# some comment'.splitlines(),
+                                      skip_comments=False)
+    self.assertFalse(tokenizer.AtEnd())
+    self.assertEqual('# some comment', tokenizer.ConsumeComment())
+    self.assertTrue(tokenizer.AtEnd())
+
+  def testConsumeTwoComments(self):
+    text = '# some comment\n# another comment'
+    tokenizer = text_format.Tokenizer(text.splitlines(), skip_comments=False)
+    self.assertEqual('# some comment', tokenizer.ConsumeComment())
+    self.assertFalse(tokenizer.AtEnd())
+    self.assertEqual('# another comment', tokenizer.ConsumeComment())
+    self.assertTrue(tokenizer.AtEnd())
+
+  def testConsumeTrailingComment(self):
+    text = 'some_number: 4\n# some comment'
+    tokenizer = text_format.Tokenizer(text.splitlines(), skip_comments=False)
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeComment)
+
+    self.assertEqual('some_number', tokenizer.ConsumeIdentifier())
+    self.assertEqual(tokenizer.token, ':')
+    tokenizer.NextToken()
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeComment)
+    self.assertEqual(4, tokenizer.ConsumeInteger())
+    self.assertFalse(tokenizer.AtEnd())
+
+    self.assertEqual('# some comment', tokenizer.ConsumeComment())
+    self.assertTrue(tokenizer.AtEnd())
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/type_checkers.py b/generator/google/protobuf/internal/type_checkers.py
index 2b3cd4d..1be3ad9 100644
--- a/generator/google/protobuf/internal/type_checkers.py
+++ b/generator/google/protobuf/internal/type_checkers.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -45,6 +45,12 @@
 
 __author__ = 'robinson@google.com (Will Robinson)'
 
+import six
+
+if six.PY3:
+  long = int
+
+from google.protobuf.internal import api_implementation
 from google.protobuf.internal import decoder
 from google.protobuf.internal import encoder
 from google.protobuf.internal import wire_format
@@ -52,22 +58,29 @@
 
 _FieldDescriptor = descriptor.FieldDescriptor
 
+def SupportsOpenEnums(field_descriptor):
+  return field_descriptor.containing_type.syntax == "proto3"
 
-def GetTypeChecker(cpp_type, field_type):
+def GetTypeChecker(field):
   """Returns a type checker for a message field of the specified types.
 
   Args:
-    cpp_type: C++ type of the field (see descriptor.py).
-    field_type: Protocol message field type (see descriptor.py).
+    field: FieldDescriptor object for this field.
 
   Returns:
     An instance of TypeChecker which can be used to verify the types
     of values assigned to a field of the specified type.
   """
-  if (cpp_type == _FieldDescriptor.CPPTYPE_STRING and
-      field_type == _FieldDescriptor.TYPE_STRING):
+  if (field.cpp_type == _FieldDescriptor.CPPTYPE_STRING and
+      field.type == _FieldDescriptor.TYPE_STRING):
     return UnicodeValueChecker()
-  return _VALUE_CHECKERS[cpp_type]
+  if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM:
+    if SupportsOpenEnums(field):
+      # When open enums are supported, any int32 can be assigned.
+      return _VALUE_CHECKERS[_FieldDescriptor.CPPTYPE_INT32]
+    else:
+      return EnumValueChecker(field.enum_type)
+  return _VALUE_CHECKERS[field.cpp_type]
 
 
 # None of the typecheckers below make any attempt to guard against people
@@ -85,10 +98,25 @@
     self._acceptable_types = acceptable_types
 
   def CheckValue(self, proposed_value):
+    """Type check the provided value and return it.
+
+    The returned value might have been normalized to another type.
+    """
     if not isinstance(proposed_value, self._acceptable_types):
       message = ('%.1024r has type %s, but expected one of: %s' %
                  (proposed_value, type(proposed_value), self._acceptable_types))
       raise TypeError(message)
+    return proposed_value
+
+
+class TypeCheckerWithDefault(TypeChecker):
+
+  def __init__(self, default_value, *acceptable_types):
+    TypeChecker.__init__(self, acceptable_types)
+    self._default_value = default_value
+
+  def DefaultValue(self):
+    return self._default_value
 
 
 # IntValueChecker and its subclasses perform integer type-checks
@@ -98,34 +126,68 @@
   """Checker used for integer fields.  Performs type-check and range check."""
 
   def CheckValue(self, proposed_value):
-    if not isinstance(proposed_value, (int, long)):
+    if not isinstance(proposed_value, six.integer_types):
       message = ('%.1024r has type %s, but expected one of: %s' %
-                 (proposed_value, type(proposed_value), (int, long)))
+                 (proposed_value, type(proposed_value), six.integer_types))
       raise TypeError(message)
     if not self._MIN <= proposed_value <= self._MAX:
       raise ValueError('Value out of range: %d' % proposed_value)
+    # We force 32-bit values to int and 64-bit values to long to make
+    # alternate implementations where the distinction is more significant
+    # (e.g. the C++ implementation) simpler.
+    proposed_value = self._TYPE(proposed_value)
+    return proposed_value
+
+  def DefaultValue(self):
+    return 0
+
+
+class EnumValueChecker(object):
+
+  """Checker used for enum fields.  Performs type-check and range check."""
+
+  def __init__(self, enum_type):
+    self._enum_type = enum_type
+
+  def CheckValue(self, proposed_value):
+    if not isinstance(proposed_value, six.integer_types):
+      message = ('%.1024r has type %s, but expected one of: %s' %
+                 (proposed_value, type(proposed_value), six.integer_types))
+      raise TypeError(message)
+    if proposed_value not in self._enum_type.values_by_number:
+      raise ValueError('Unknown enum value: %d' % proposed_value)
+    return proposed_value
+
+  def DefaultValue(self):
+    return self._enum_type.values[0].number
 
 
 class UnicodeValueChecker(object):
 
-  """Checker used for string fields."""
+  """Checker used for string fields.
+
+  Always returns a unicode value, even if the input is of type str.
+  """
 
   def CheckValue(self, proposed_value):
-    if not isinstance(proposed_value, (str, unicode)):
+    if not isinstance(proposed_value, (bytes, six.text_type)):
       message = ('%.1024r has type %s, but expected one of: %s' %
-                 (proposed_value, type(proposed_value), (str, unicode)))
+                 (proposed_value, type(proposed_value), (bytes, six.text_type)))
       raise TypeError(message)
 
-    # If the value is of type 'str' make sure that it is in 7-bit ASCII
-    # encoding.
-    if isinstance(proposed_value, str):
+    # If the value is of type 'bytes' make sure that it is valid UTF-8 data.
+    if isinstance(proposed_value, bytes):
       try:
-        unicode(proposed_value, 'ascii')
+        proposed_value = proposed_value.decode('utf-8')
       except UnicodeDecodeError:
-        raise ValueError('%.1024r has type str, but isn\'t in 7-bit ASCII '
-                         'encoding. Non-ASCII strings must be converted to '
+        raise ValueError('%.1024r has type bytes, but isn\'t valid UTF-8 '
+                         'encoding. Non-UTF-8 strings must be converted to '
                          'unicode objects before being added.' %
                          (proposed_value))
+    return proposed_value
+
+  def DefaultValue(self):
+    return u""
 
 
 class Int32ValueChecker(IntValueChecker):
@@ -133,21 +195,25 @@
   # efficient.
   _MIN = -2147483648
   _MAX = 2147483647
+  _TYPE = int
 
 
 class Uint32ValueChecker(IntValueChecker):
   _MIN = 0
   _MAX = (1 << 32) - 1
+  _TYPE = int
 
 
 class Int64ValueChecker(IntValueChecker):
   _MIN = -(1 << 63)
   _MAX = (1 << 63) - 1
+  _TYPE = long
 
 
 class Uint64ValueChecker(IntValueChecker):
   _MIN = 0
   _MAX = (1 << 64) - 1
+  _TYPE = long
 
 
 # Type-checkers for all scalar CPPTYPEs.
@@ -156,13 +222,13 @@
     _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(),
     _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(),
     _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(),
-    _FieldDescriptor.CPPTYPE_DOUBLE: TypeChecker(
-        float, int, long),
-    _FieldDescriptor.CPPTYPE_FLOAT: TypeChecker(
-        float, int, long),
-    _FieldDescriptor.CPPTYPE_BOOL: TypeChecker(bool, int),
-    _FieldDescriptor.CPPTYPE_ENUM: Int32ValueChecker(),
-    _FieldDescriptor.CPPTYPE_STRING: TypeChecker(str),
+    _FieldDescriptor.CPPTYPE_DOUBLE: TypeCheckerWithDefault(
+        0.0, float, int, long),
+    _FieldDescriptor.CPPTYPE_FLOAT: TypeCheckerWithDefault(
+        0.0, float, int, long),
+    _FieldDescriptor.CPPTYPE_BOOL: TypeCheckerWithDefault(
+        False, bool, int),
+    _FieldDescriptor.CPPTYPE_STRING: TypeCheckerWithDefault(b'', bytes),
     }
 
 
diff --git a/generator/google/protobuf/internal/unknown_fields_test.py b/generator/google/protobuf/internal/unknown_fields_test.py
new file mode 100644
index 0000000..84073f1
--- /dev/null
+++ b/generator/google/protobuf/internal/unknown_fields_test.py
@@ -0,0 +1,320 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# 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.
+
+"""Test for preservation of unknown fields in the pure Python implementation."""
+
+__author__ = 'bohdank@google.com (Bohdan Koval)'
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+from google.protobuf import unittest_mset_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import unittest_proto3_arena_pb2
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import encoder
+from google.protobuf.internal import message_set_extensions_pb2
+from google.protobuf.internal import missing_enum_values_pb2
+from google.protobuf.internal import test_util
+from google.protobuf.internal import type_checkers
+
+
+def SkipIfCppImplementation(func):
+  return unittest.skipIf(
+      api_implementation.Type() == 'cpp' and api_implementation.Version() == 2,
+      'C++ implementation does not expose unknown fields to Python')(func)
+
+
+class UnknownFieldsTest(unittest.TestCase):
+
+  def setUp(self):
+    self.descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
+    self.all_fields = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(self.all_fields)
+    self.all_fields_data = self.all_fields.SerializeToString()
+    self.empty_message = unittest_pb2.TestEmptyMessage()
+    self.empty_message.ParseFromString(self.all_fields_data)
+
+  def testSerialize(self):
+    data = self.empty_message.SerializeToString()
+
+    # Don't use assertEqual because we don't want to dump raw binary data to
+    # stdout.
+    self.assertTrue(data == self.all_fields_data)
+
+  def testSerializeProto3(self):
+    # Verify that proto3 doesn't preserve unknown fields.
+    message = unittest_proto3_arena_pb2.TestEmptyMessage()
+    message.ParseFromString(self.all_fields_data)
+    self.assertEqual(0, len(message.SerializeToString()))
+
+  def testByteSize(self):
+    self.assertEqual(self.all_fields.ByteSize(), self.empty_message.ByteSize())
+
+  def testListFields(self):
+    # Make sure ListFields doesn't return unknown fields.
+    self.assertEqual(0, len(self.empty_message.ListFields()))
+
+  def testSerializeMessageSetWireFormatUnknownExtension(self):
+    # Create a message using the message set wire format with an unknown
+    # message.
+    raw = unittest_mset_pb2.RawMessageSet()
+
+    # Add an unknown extension.
+    item = raw.item.add()
+    item.type_id = 98418603
+    message1 = message_set_extensions_pb2.TestMessageSetExtension1()
+    message1.i = 12345
+    item.message = message1.SerializeToString()
+
+    serialized = raw.SerializeToString()
+
+    # Parse message using the message set wire format.
+    proto = message_set_extensions_pb2.TestMessageSet()
+    proto.MergeFromString(serialized)
+
+    # Verify that the unknown extension is serialized unchanged
+    reserialized = proto.SerializeToString()
+    new_raw = unittest_mset_pb2.RawMessageSet()
+    new_raw.MergeFromString(reserialized)
+    self.assertEqual(raw, new_raw)
+
+  def testEquals(self):
+    message = unittest_pb2.TestEmptyMessage()
+    message.ParseFromString(self.all_fields_data)
+    self.assertEqual(self.empty_message, message)
+
+    self.all_fields.ClearField('optional_string')
+    message.ParseFromString(self.all_fields.SerializeToString())
+    self.assertNotEqual(self.empty_message, message)
+
+  def testDiscardUnknownFields(self):
+    self.empty_message.DiscardUnknownFields()
+    self.assertEqual(b'', self.empty_message.SerializeToString())
+    # Test message field and repeated message field.
+    message = unittest_pb2.TestAllTypes()
+    other_message = unittest_pb2.TestAllTypes()
+    other_message.optional_string = 'discard'
+    message.optional_nested_message.ParseFromString(
+        other_message.SerializeToString())
+    message.repeated_nested_message.add().ParseFromString(
+        other_message.SerializeToString())
+    self.assertNotEqual(
+        b'', message.optional_nested_message.SerializeToString())
+    self.assertNotEqual(
+        b'', message.repeated_nested_message[0].SerializeToString())
+    message.DiscardUnknownFields()
+    self.assertEqual(b'', message.optional_nested_message.SerializeToString())
+    self.assertEqual(
+        b'', message.repeated_nested_message[0].SerializeToString())
+
+
+class UnknownFieldsAccessorsTest(unittest.TestCase):
+
+  def setUp(self):
+    self.descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
+    self.all_fields = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(self.all_fields)
+    self.all_fields_data = self.all_fields.SerializeToString()
+    self.empty_message = unittest_pb2.TestEmptyMessage()
+    self.empty_message.ParseFromString(self.all_fields_data)
+    if api_implementation.Type() != 'cpp':
+      # _unknown_fields is an implementation detail.
+      self.unknown_fields = self.empty_message._unknown_fields
+
+  # All the tests that use GetField() check an implementation detail of the
+  # Python implementation, which stores unknown fields as serialized strings.
+  # These tests are skipped by the C++ implementation: it's enough to check that
+  # the message is correctly serialized.
+
+  def GetField(self, name):
+    field_descriptor = self.descriptor.fields_by_name[name]
+    wire_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type]
+    field_tag = encoder.TagBytes(field_descriptor.number, wire_type)
+    result_dict = {}
+    for tag_bytes, value in self.unknown_fields:
+      if tag_bytes == field_tag:
+        decoder = unittest_pb2.TestAllTypes._decoders_by_tag[tag_bytes][0]
+        decoder(value, 0, len(value), self.all_fields, result_dict)
+    return result_dict[field_descriptor]
+
+  @SkipIfCppImplementation
+  def testEnum(self):
+    value = self.GetField('optional_nested_enum')
+    self.assertEqual(self.all_fields.optional_nested_enum, value)
+
+  @SkipIfCppImplementation
+  def testRepeatedEnum(self):
+    value = self.GetField('repeated_nested_enum')
+    self.assertEqual(self.all_fields.repeated_nested_enum, value)
+
+  @SkipIfCppImplementation
+  def testVarint(self):
+    value = self.GetField('optional_int32')
+    self.assertEqual(self.all_fields.optional_int32, value)
+
+  @SkipIfCppImplementation
+  def testFixed32(self):
+    value = self.GetField('optional_fixed32')
+    self.assertEqual(self.all_fields.optional_fixed32, value)
+
+  @SkipIfCppImplementation
+  def testFixed64(self):
+    value = self.GetField('optional_fixed64')
+    self.assertEqual(self.all_fields.optional_fixed64, value)
+
+  @SkipIfCppImplementation
+  def testLengthDelimited(self):
+    value = self.GetField('optional_string')
+    self.assertEqual(self.all_fields.optional_string, value)
+
+  @SkipIfCppImplementation
+  def testGroup(self):
+    value = self.GetField('optionalgroup')
+    self.assertEqual(self.all_fields.optionalgroup, value)
+
+  def testCopyFrom(self):
+    message = unittest_pb2.TestEmptyMessage()
+    message.CopyFrom(self.empty_message)
+    self.assertEqual(message.SerializeToString(), self.all_fields_data)
+
+  def testMergeFrom(self):
+    message = unittest_pb2.TestAllTypes()
+    message.optional_int32 = 1
+    message.optional_uint32 = 2
+    source = unittest_pb2.TestEmptyMessage()
+    source.ParseFromString(message.SerializeToString())
+
+    message.ClearField('optional_int32')
+    message.optional_int64 = 3
+    message.optional_uint32 = 4
+    destination = unittest_pb2.TestEmptyMessage()
+    destination.ParseFromString(message.SerializeToString())
+
+    destination.MergeFrom(source)
+    # Check that the fields where correctly merged, even stored in the unknown
+    # fields set.
+    message.ParseFromString(destination.SerializeToString())
+    self.assertEqual(message.optional_int32, 1)
+    self.assertEqual(message.optional_uint32, 2)
+    self.assertEqual(message.optional_int64, 3)
+
+  def testClear(self):
+    self.empty_message.Clear()
+    # All cleared, even unknown fields.
+    self.assertEqual(self.empty_message.SerializeToString(), b'')
+
+  def testUnknownExtensions(self):
+    message = unittest_pb2.TestEmptyMessageWithExtensions()
+    message.ParseFromString(self.all_fields_data)
+    self.assertEqual(message.SerializeToString(), self.all_fields_data)
+
+
+class UnknownEnumValuesTest(unittest.TestCase):
+
+  def setUp(self):
+    self.descriptor = missing_enum_values_pb2.TestEnumValues.DESCRIPTOR
+
+    self.message = missing_enum_values_pb2.TestEnumValues()
+    self.message.optional_nested_enum = (
+      missing_enum_values_pb2.TestEnumValues.ZERO)
+    self.message.repeated_nested_enum.extend([
+      missing_enum_values_pb2.TestEnumValues.ZERO,
+      missing_enum_values_pb2.TestEnumValues.ONE,
+      ])
+    self.message.packed_nested_enum.extend([
+      missing_enum_values_pb2.TestEnumValues.ZERO,
+      missing_enum_values_pb2.TestEnumValues.ONE,
+      ])
+    self.message_data = self.message.SerializeToString()
+    self.missing_message = missing_enum_values_pb2.TestMissingEnumValues()
+    self.missing_message.ParseFromString(self.message_data)
+    if api_implementation.Type() != 'cpp':
+      # _unknown_fields is an implementation detail.
+      self.unknown_fields = self.missing_message._unknown_fields
+
+  # All the tests that use GetField() check an implementation detail of the
+  # Python implementation, which stores unknown fields as serialized strings.
+  # These tests are skipped by the C++ implementation: it's enough to check that
+  # the message is correctly serialized.
+
+  def GetField(self, name):
+    field_descriptor = self.descriptor.fields_by_name[name]
+    wire_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type]
+    field_tag = encoder.TagBytes(field_descriptor.number, wire_type)
+    result_dict = {}
+    for tag_bytes, value in self.unknown_fields:
+      if tag_bytes == field_tag:
+        decoder = missing_enum_values_pb2.TestEnumValues._decoders_by_tag[
+          tag_bytes][0]
+        decoder(value, 0, len(value), self.message, result_dict)
+    return result_dict[field_descriptor]
+
+  def testUnknownParseMismatchEnumValue(self):
+    just_string = missing_enum_values_pb2.JustString()
+    just_string.dummy = 'blah'
+
+    missing = missing_enum_values_pb2.TestEnumValues()
+    # The parse is invalid, storing the string proto into the set of
+    # unknown fields.
+    missing.ParseFromString(just_string.SerializeToString())
+
+    # Fetching the enum field shouldn't crash, instead returning the
+    # default value.
+    self.assertEqual(missing.optional_nested_enum, 0)
+
+  @SkipIfCppImplementation
+  def testUnknownEnumValue(self):
+    self.assertFalse(self.missing_message.HasField('optional_nested_enum'))
+    value = self.GetField('optional_nested_enum')
+    self.assertEqual(self.message.optional_nested_enum, value)
+
+  @SkipIfCppImplementation
+  def testUnknownRepeatedEnumValue(self):
+    value = self.GetField('repeated_nested_enum')
+    self.assertEqual(self.message.repeated_nested_enum, value)
+
+  @SkipIfCppImplementation
+  def testUnknownPackedEnumValue(self):
+    value = self.GetField('packed_nested_enum')
+    self.assertEqual(self.message.packed_nested_enum, value)
+
+  def testRoundTrip(self):
+    new_message = missing_enum_values_pb2.TestEnumValues()
+    new_message.ParseFromString(self.missing_message.SerializeToString())
+    self.assertEqual(self.message, new_message)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/well_known_types.py b/generator/google/protobuf/internal/well_known_types.py
new file mode 100644
index 0000000..7c5dffd
--- /dev/null
+++ b/generator/google/protobuf/internal/well_known_types.py
@@ -0,0 +1,724 @@
+# 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.
+
+"""Contains well known classes.
+
+This files defines well known classes which need extra maintenance including:
+  - Any
+  - Duration
+  - FieldMask
+  - Struct
+  - Timestamp
+"""
+
+__author__ = 'jieluo@google.com (Jie Luo)'
+
+from datetime import datetime
+from datetime import timedelta
+import six
+
+from google.protobuf.descriptor import FieldDescriptor
+
+_TIMESTAMPFOMAT = '%Y-%m-%dT%H:%M:%S'
+_NANOS_PER_SECOND = 1000000000
+_NANOS_PER_MILLISECOND = 1000000
+_NANOS_PER_MICROSECOND = 1000
+_MILLIS_PER_SECOND = 1000
+_MICROS_PER_SECOND = 1000000
+_SECONDS_PER_DAY = 24 * 3600
+
+
+class Error(Exception):
+  """Top-level module error."""
+
+
+class ParseError(Error):
+  """Thrown in case of parsing error."""
+
+
+class Any(object):
+  """Class for Any Message type."""
+
+  def Pack(self, msg, type_url_prefix='type.googleapis.com/'):
+    """Packs the specified message into current Any message."""
+    if len(type_url_prefix) < 1 or type_url_prefix[-1] != '/':
+      self.type_url = '%s/%s' % (type_url_prefix, msg.DESCRIPTOR.full_name)
+    else:
+      self.type_url = '%s%s' % (type_url_prefix, msg.DESCRIPTOR.full_name)
+    self.value = msg.SerializeToString()
+
+  def Unpack(self, msg):
+    """Unpacks the current Any message into specified message."""
+    descriptor = msg.DESCRIPTOR
+    if not self.Is(descriptor):
+      return False
+    msg.ParseFromString(self.value)
+    return True
+
+  def TypeName(self):
+    """Returns the protobuf type name of the inner message."""
+    # Only last part is to be used: b/25630112
+    return self.type_url.split('/')[-1]
+
+  def Is(self, descriptor):
+    """Checks if this Any represents the given protobuf type."""
+    return self.TypeName() == descriptor.full_name
+
+
+class Timestamp(object):
+  """Class for Timestamp message type."""
+
+  def ToJsonString(self):
+    """Converts Timestamp to RFC 3339 date string format.
+
+    Returns:
+      A string converted from timestamp. The string is always Z-normalized
+      and uses 3, 6 or 9 fractional digits as required to represent the
+      exact time. Example of the return format: '1972-01-01T10:00:20.021Z'
+    """
+    nanos = self.nanos % _NANOS_PER_SECOND
+    total_sec = self.seconds + (self.nanos - nanos) // _NANOS_PER_SECOND
+    seconds = total_sec % _SECONDS_PER_DAY
+    days = (total_sec - seconds) // _SECONDS_PER_DAY
+    dt = datetime(1970, 1, 1) + timedelta(days, seconds)
+
+    result = dt.isoformat()
+    if (nanos % 1e9) == 0:
+      # If there are 0 fractional digits, the fractional
+      # point '.' should be omitted when serializing.
+      return result + 'Z'
+    if (nanos % 1e6) == 0:
+      # Serialize 3 fractional digits.
+      return result + '.%03dZ' % (nanos / 1e6)
+    if (nanos % 1e3) == 0:
+      # Serialize 6 fractional digits.
+      return result + '.%06dZ' % (nanos / 1e3)
+    # Serialize 9 fractional digits.
+    return result + '.%09dZ' % nanos
+
+  def FromJsonString(self, value):
+    """Parse a RFC 3339 date string format to Timestamp.
+
+    Args:
+      value: A date string. Any fractional digits (or none) and any offset are
+          accepted as long as they fit into nano-seconds precision.
+          Example of accepted format: '1972-01-01T10:00:20.021-05:00'
+
+    Raises:
+      ParseError: On parsing problems.
+    """
+    timezone_offset = value.find('Z')
+    if timezone_offset == -1:
+      timezone_offset = value.find('+')
+    if timezone_offset == -1:
+      timezone_offset = value.rfind('-')
+    if timezone_offset == -1:
+      raise ParseError(
+          'Failed to parse timestamp: missing valid timezone offset.')
+    time_value = value[0:timezone_offset]
+    # Parse datetime and nanos.
+    point_position = time_value.find('.')
+    if point_position == -1:
+      second_value = time_value
+      nano_value = ''
+    else:
+      second_value = time_value[:point_position]
+      nano_value = time_value[point_position + 1:]
+    date_object = datetime.strptime(second_value, _TIMESTAMPFOMAT)
+    td = date_object - datetime(1970, 1, 1)
+    seconds = td.seconds + td.days * _SECONDS_PER_DAY
+    if len(nano_value) > 9:
+      raise ParseError(
+          'Failed to parse Timestamp: nanos {0} more than '
+          '9 fractional digits.'.format(nano_value))
+    if nano_value:
+      nanos = round(float('0.' + nano_value) * 1e9)
+    else:
+      nanos = 0
+    # Parse timezone offsets.
+    if value[timezone_offset] == 'Z':
+      if len(value) != timezone_offset + 1:
+        raise ParseError('Failed to parse timestamp: invalid trailing'
+                         ' data {0}.'.format(value))
+    else:
+      timezone = value[timezone_offset:]
+      pos = timezone.find(':')
+      if pos == -1:
+        raise ParseError(
+            'Invalid timezone offset value: {0}.'.format(timezone))
+      if timezone[0] == '+':
+        seconds -= (int(timezone[1:pos])*60+int(timezone[pos+1:]))*60
+      else:
+        seconds += (int(timezone[1:pos])*60+int(timezone[pos+1:]))*60
+    # Set seconds and nanos
+    self.seconds = int(seconds)
+    self.nanos = int(nanos)
+
+  def GetCurrentTime(self):
+    """Get the current UTC into Timestamp."""
+    self.FromDatetime(datetime.utcnow())
+
+  def ToNanoseconds(self):
+    """Converts Timestamp to nanoseconds since epoch."""
+    return self.seconds * _NANOS_PER_SECOND + self.nanos
+
+  def ToMicroseconds(self):
+    """Converts Timestamp to microseconds since epoch."""
+    return (self.seconds * _MICROS_PER_SECOND +
+            self.nanos // _NANOS_PER_MICROSECOND)
+
+  def ToMilliseconds(self):
+    """Converts Timestamp to milliseconds since epoch."""
+    return (self.seconds * _MILLIS_PER_SECOND +
+            self.nanos // _NANOS_PER_MILLISECOND)
+
+  def ToSeconds(self):
+    """Converts Timestamp to seconds since epoch."""
+    return self.seconds
+
+  def FromNanoseconds(self, nanos):
+    """Converts nanoseconds since epoch to Timestamp."""
+    self.seconds = nanos // _NANOS_PER_SECOND
+    self.nanos = nanos % _NANOS_PER_SECOND
+
+  def FromMicroseconds(self, micros):
+    """Converts microseconds since epoch to Timestamp."""
+    self.seconds = micros // _MICROS_PER_SECOND
+    self.nanos = (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND
+
+  def FromMilliseconds(self, millis):
+    """Converts milliseconds since epoch to Timestamp."""
+    self.seconds = millis // _MILLIS_PER_SECOND
+    self.nanos = (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND
+
+  def FromSeconds(self, seconds):
+    """Converts seconds since epoch to Timestamp."""
+    self.seconds = seconds
+    self.nanos = 0
+
+  def ToDatetime(self):
+    """Converts Timestamp to datetime."""
+    return datetime.utcfromtimestamp(
+        self.seconds + self.nanos / float(_NANOS_PER_SECOND))
+
+  def FromDatetime(self, dt):
+    """Converts datetime to Timestamp."""
+    td = dt - datetime(1970, 1, 1)
+    self.seconds = td.seconds + td.days * _SECONDS_PER_DAY
+    self.nanos = td.microseconds * _NANOS_PER_MICROSECOND
+
+
+class Duration(object):
+  """Class for Duration message type."""
+
+  def ToJsonString(self):
+    """Converts Duration to string format.
+
+    Returns:
+      A string converted from self. 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"
+    """
+    if self.seconds < 0 or self.nanos < 0:
+      result = '-'
+      seconds = - self.seconds + int((0 - self.nanos) // 1e9)
+      nanos = (0 - self.nanos) % 1e9
+    else:
+      result = ''
+      seconds = self.seconds + int(self.nanos // 1e9)
+      nanos = self.nanos % 1e9
+    result += '%d' % seconds
+    if (nanos % 1e9) == 0:
+      # If there are 0 fractional digits, the fractional
+      # point '.' should be omitted when serializing.
+      return result + 's'
+    if (nanos % 1e6) == 0:
+      # Serialize 3 fractional digits.
+      return result + '.%03ds' % (nanos / 1e6)
+    if (nanos % 1e3) == 0:
+      # Serialize 6 fractional digits.
+      return result + '.%06ds' % (nanos / 1e3)
+    # Serialize 9 fractional digits.
+    return result + '.%09ds' % nanos
+
+  def FromJsonString(self, value):
+    """Converts a string to Duration.
+
+    Args:
+      value: A string to be converted. The string must end with 's'. Any
+          fractional digits (or none) are accepted as long as they fit into
+          precision. For example: "1s", "1.01s", "1.0000001s", "-3.100s
+
+    Raises:
+      ParseError: On parsing problems.
+    """
+    if len(value) < 1 or value[-1] != 's':
+      raise ParseError(
+          'Duration must end with letter "s": {0}.'.format(value))
+    try:
+      pos = value.find('.')
+      if pos == -1:
+        self.seconds = int(value[:-1])
+        self.nanos = 0
+      else:
+        self.seconds = int(value[:pos])
+        if value[0] == '-':
+          self.nanos = int(round(float('-0{0}'.format(value[pos: -1])) *1e9))
+        else:
+          self.nanos = int(round(float('0{0}'.format(value[pos: -1])) *1e9))
+    except ValueError:
+      raise ParseError(
+          'Couldn\'t parse duration: {0}.'.format(value))
+
+  def ToNanoseconds(self):
+    """Converts a Duration to nanoseconds."""
+    return self.seconds * _NANOS_PER_SECOND + self.nanos
+
+  def ToMicroseconds(self):
+    """Converts a Duration to microseconds."""
+    micros = _RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND)
+    return self.seconds * _MICROS_PER_SECOND + micros
+
+  def ToMilliseconds(self):
+    """Converts a Duration to milliseconds."""
+    millis = _RoundTowardZero(self.nanos, _NANOS_PER_MILLISECOND)
+    return self.seconds * _MILLIS_PER_SECOND + millis
+
+  def ToSeconds(self):
+    """Converts a Duration to seconds."""
+    return self.seconds
+
+  def FromNanoseconds(self, nanos):
+    """Converts nanoseconds to Duration."""
+    self._NormalizeDuration(nanos // _NANOS_PER_SECOND,
+                            nanos % _NANOS_PER_SECOND)
+
+  def FromMicroseconds(self, micros):
+    """Converts microseconds to Duration."""
+    self._NormalizeDuration(
+        micros // _MICROS_PER_SECOND,
+        (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND)
+
+  def FromMilliseconds(self, millis):
+    """Converts milliseconds to Duration."""
+    self._NormalizeDuration(
+        millis // _MILLIS_PER_SECOND,
+        (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND)
+
+  def FromSeconds(self, seconds):
+    """Converts seconds to Duration."""
+    self.seconds = seconds
+    self.nanos = 0
+
+  def ToTimedelta(self):
+    """Converts Duration to timedelta."""
+    return timedelta(
+        seconds=self.seconds, microseconds=_RoundTowardZero(
+            self.nanos, _NANOS_PER_MICROSECOND))
+
+  def FromTimedelta(self, td):
+    """Convertd timedelta to Duration."""
+    self._NormalizeDuration(td.seconds + td.days * _SECONDS_PER_DAY,
+                            td.microseconds * _NANOS_PER_MICROSECOND)
+
+  def _NormalizeDuration(self, seconds, nanos):
+    """Set Duration by seconds and nonas."""
+    # Force nanos to be negative if the duration is negative.
+    if seconds < 0 and nanos > 0:
+      seconds += 1
+      nanos -= _NANOS_PER_SECOND
+    self.seconds = seconds
+    self.nanos = nanos
+
+
+def _RoundTowardZero(value, divider):
+  """Truncates the remainder part after division."""
+  # For some languanges, the sign of the remainder is implementation
+  # dependent if any of the operands is negative. Here we enforce
+  # "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).
+  result = value // divider
+  remainder = value % divider
+  if result < 0 and remainder > 0:
+    return result + 1
+  else:
+    return result
+
+
+class FieldMask(object):
+  """Class for FieldMask message type."""
+
+  def ToJsonString(self):
+    """Converts FieldMask to string according to proto3 JSON spec."""
+    return ','.join(self.paths)
+
+  def FromJsonString(self, value):
+    """Converts string to FieldMask according to proto3 JSON spec."""
+    self.Clear()
+    for path in value.split(','):
+      self.paths.append(path)
+
+  def IsValidForDescriptor(self, message_descriptor):
+    """Checks whether the FieldMask is valid for Message Descriptor."""
+    for path in self.paths:
+      if not _IsValidPath(message_descriptor, path):
+        return False
+    return True
+
+  def AllFieldsFromDescriptor(self, message_descriptor):
+    """Gets all direct fields of Message Descriptor to FieldMask."""
+    self.Clear()
+    for field in message_descriptor.fields:
+      self.paths.append(field.name)
+
+  def CanonicalFormFromMask(self, mask):
+    """Converts a FieldMask to the canonical form.
+
+    Removes 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. Then sorts all paths in alphabetical order.
+
+    Args:
+      mask: The original FieldMask to be converted.
+    """
+    tree = _FieldMaskTree(mask)
+    tree.ToFieldMask(self)
+
+  def Union(self, mask1, mask2):
+    """Merges mask1 and mask2 into this FieldMask."""
+    _CheckFieldMaskMessage(mask1)
+    _CheckFieldMaskMessage(mask2)
+    tree = _FieldMaskTree(mask1)
+    tree.MergeFromFieldMask(mask2)
+    tree.ToFieldMask(self)
+
+  def Intersect(self, mask1, mask2):
+    """Intersects mask1 and mask2 into this FieldMask."""
+    _CheckFieldMaskMessage(mask1)
+    _CheckFieldMaskMessage(mask2)
+    tree = _FieldMaskTree(mask1)
+    intersection = _FieldMaskTree()
+    for path in mask2.paths:
+      tree.IntersectPath(path, intersection)
+    intersection.ToFieldMask(self)
+
+  def MergeMessage(
+      self, source, destination,
+      replace_message_field=False, replace_repeated_field=False):
+    """Merges fields specified in FieldMask from source to destination.
+
+    Args:
+      source: Source message.
+      destination: The destination message to be merged into.
+      replace_message_field: Replace message field if True. Merge message
+          field if False.
+      replace_repeated_field: Replace repeated field if True. Append
+          elements of repeated field if False.
+    """
+    tree = _FieldMaskTree(self)
+    tree.MergeMessage(
+        source, destination, replace_message_field, replace_repeated_field)
+
+
+def _IsValidPath(message_descriptor, path):
+  """Checks whether the path is valid for Message Descriptor."""
+  parts = path.split('.')
+  last = parts.pop()
+  for name in parts:
+    field = message_descriptor.fields_by_name[name]
+    if (field is None or
+        field.label == FieldDescriptor.LABEL_REPEATED or
+        field.type != FieldDescriptor.TYPE_MESSAGE):
+      return False
+    message_descriptor = field.message_type
+  return last in message_descriptor.fields_by_name
+
+
+def _CheckFieldMaskMessage(message):
+  """Raises ValueError if message is not a FieldMask."""
+  message_descriptor = message.DESCRIPTOR
+  if (message_descriptor.name != 'FieldMask' or
+      message_descriptor.file.name != 'google/protobuf/field_mask.proto'):
+    raise ValueError('Message {0} is not a FieldMask.'.format(
+        message_descriptor.full_name))
+
+
+class _FieldMaskTree(object):
+  """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.
+  """
+
+  def __init__(self, field_mask=None):
+    """Initializes the tree by FieldMask."""
+    self._root = {}
+    if field_mask:
+      self.MergeFromFieldMask(field_mask)
+
+  def MergeFromFieldMask(self, field_mask):
+    """Merges a FieldMask to the tree."""
+    for path in field_mask.paths:
+      self.AddPath(path)
+
+  def AddPath(self, path):
+    """Adds a field path into the tree.
+
+    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 matches
+    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. Otherwise, a new path will
+    be added.
+
+    Args:
+      path: The field path to add.
+    """
+    node = self._root
+    for name in path.split('.'):
+      if name not in node:
+        node[name] = {}
+      elif not node[name]:
+        # Pre-existing empty node implies we already have this entire tree.
+        return
+      node = node[name]
+    # Remove any sub-trees we might have had.
+    node.clear()
+
+  def ToFieldMask(self, field_mask):
+    """Converts the tree to a FieldMask."""
+    field_mask.Clear()
+    _AddFieldPaths(self._root, '', field_mask)
+
+  def IntersectPath(self, path, intersection):
+    """Calculates the intersection part of a field path with this tree.
+
+    Args:
+      path: The field path to calculates.
+      intersection: The out tree to record the intersection part.
+    """
+    node = self._root
+    for name in path.split('.'):
+      if name not in node:
+        return
+      elif not node[name]:
+        intersection.AddPath(path)
+        return
+      node = node[name]
+    intersection.AddLeafNodes(path, node)
+
+  def AddLeafNodes(self, prefix, node):
+    """Adds leaf nodes begin with prefix to this tree."""
+    if not node:
+      self.AddPath(prefix)
+    for name in node:
+      child_path = prefix + '.' + name
+      self.AddLeafNodes(child_path, node[name])
+
+  def MergeMessage(
+      self, source, destination,
+      replace_message, replace_repeated):
+    """Merge all fields specified by this tree from source to destination."""
+    _MergeMessage(
+        self._root, source, destination, replace_message, replace_repeated)
+
+
+def _StrConvert(value):
+  """Converts value to str if it is not."""
+  # This file is imported by c extension and some methods like ClearField
+  # requires string for the field name. py2/py3 has different text
+  # type and may use unicode.
+  if not isinstance(value, str):
+    return value.encode('utf-8')
+  return value
+
+
+def _MergeMessage(
+    node, source, destination, replace_message, replace_repeated):
+  """Merge all fields specified by a sub-tree from source to destination."""
+  source_descriptor = source.DESCRIPTOR
+  for name in node:
+    child = node[name]
+    field = source_descriptor.fields_by_name[name]
+    if field is None:
+      raise ValueError('Error: Can\'t find field {0} in message {1}.'.format(
+          name, source_descriptor.full_name))
+    if child:
+      # Sub-paths are only allowed for singular message fields.
+      if (field.label == FieldDescriptor.LABEL_REPEATED or
+          field.cpp_type != FieldDescriptor.CPPTYPE_MESSAGE):
+        raise ValueError('Error: Field {0} in message {1} is not a singular '
+                         'message field and cannot have sub-fields.'.format(
+                             name, source_descriptor.full_name))
+      _MergeMessage(
+          child, getattr(source, name), getattr(destination, name),
+          replace_message, replace_repeated)
+      continue
+    if field.label == FieldDescriptor.LABEL_REPEATED:
+      if replace_repeated:
+        destination.ClearField(_StrConvert(name))
+      repeated_source = getattr(source, name)
+      repeated_destination = getattr(destination, name)
+      if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE:
+        for item in repeated_source:
+          repeated_destination.add().MergeFrom(item)
+      else:
+        repeated_destination.extend(repeated_source)
+    else:
+      if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE:
+        if replace_message:
+          destination.ClearField(_StrConvert(name))
+        if source.HasField(name):
+          getattr(destination, name).MergeFrom(getattr(source, name))
+      else:
+        setattr(destination, name, getattr(source, name))
+
+
+def _AddFieldPaths(node, prefix, field_mask):
+  """Adds the field paths descended from node to field_mask."""
+  if not node:
+    field_mask.paths.append(prefix)
+    return
+  for name in sorted(node):
+    if prefix:
+      child_path = prefix + '.' + name
+    else:
+      child_path = name
+    _AddFieldPaths(node[name], child_path, field_mask)
+
+
+_INT_OR_FLOAT = six.integer_types + (float,)
+
+
+def _SetStructValue(struct_value, value):
+  if value is None:
+    struct_value.null_value = 0
+  elif isinstance(value, bool):
+    # Note: this check must come before the number check because in Python
+    # True and False are also considered numbers.
+    struct_value.bool_value = value
+  elif isinstance(value, six.string_types):
+    struct_value.string_value = value
+  elif isinstance(value, _INT_OR_FLOAT):
+    struct_value.number_value = value
+  else:
+    raise ValueError('Unexpected type')
+
+
+def _GetStructValue(struct_value):
+  which = struct_value.WhichOneof('kind')
+  if which == 'struct_value':
+    return struct_value.struct_value
+  elif which == 'null_value':
+    return None
+  elif which == 'number_value':
+    return struct_value.number_value
+  elif which == 'string_value':
+    return struct_value.string_value
+  elif which == 'bool_value':
+    return struct_value.bool_value
+  elif which == 'list_value':
+    return struct_value.list_value
+  elif which is None:
+    raise ValueError('Value not set')
+
+
+class Struct(object):
+  """Class for Struct message type."""
+
+  __slots__ = []
+
+  def __getitem__(self, key):
+    return _GetStructValue(self.fields[key])
+
+  def __setitem__(self, key, value):
+    _SetStructValue(self.fields[key], value)
+
+  def get_or_create_list(self, key):
+    """Returns a list for this key, creating if it didn't exist already."""
+    return self.fields[key].list_value
+
+  def get_or_create_struct(self, key):
+    """Returns a struct for this key, creating if it didn't exist already."""
+    return self.fields[key].struct_value
+
+  # TODO(haberman): allow constructing/merging from dict.
+
+
+class ListValue(object):
+  """Class for ListValue message type."""
+
+  def __len__(self):
+    return len(self.values)
+
+  def append(self, value):
+    _SetStructValue(self.values.add(), value)
+
+  def extend(self, elem_seq):
+    for value in elem_seq:
+      self.append(value)
+
+  def __getitem__(self, index):
+    """Retrieves item by the specified index."""
+    return _GetStructValue(self.values.__getitem__(index))
+
+  def __setitem__(self, index, value):
+    _SetStructValue(self.values.__getitem__(index), value)
+
+  def items(self):
+    for i in range(len(self)):
+      yield self[i]
+
+  def add_struct(self):
+    """Appends and returns a struct value as the next value in the list."""
+    return self.values.add().struct_value
+
+  def add_list(self):
+    """Appends and returns a list value as the next value in the list."""
+    return self.values.add().list_value
+
+
+WKTBASES = {
+    'google.protobuf.Any': Any,
+    'google.protobuf.Duration': Duration,
+    'google.protobuf.FieldMask': FieldMask,
+    'google.protobuf.ListValue': ListValue,
+    'google.protobuf.Struct': Struct,
+    'google.protobuf.Timestamp': Timestamp,
+}
diff --git a/generator/google/protobuf/internal/well_known_types_test.py b/generator/google/protobuf/internal/well_known_types_test.py
new file mode 100644
index 0000000..2f32ac9
--- /dev/null
+++ b/generator/google/protobuf/internal/well_known_types_test.py
@@ -0,0 +1,644 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Test for google.protobuf.internal.well_known_types."""
+
+__author__ = 'jieluo@google.com (Jie Luo)'
+
+from datetime import datetime
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+
+from google.protobuf import any_pb2
+from google.protobuf import duration_pb2
+from google.protobuf import field_mask_pb2
+from google.protobuf import struct_pb2
+from google.protobuf import timestamp_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf.internal import any_test_pb2
+from google.protobuf.internal import test_util
+from google.protobuf.internal import well_known_types
+from google.protobuf import descriptor
+from google.protobuf import text_format
+
+
+class TimeUtilTestBase(unittest.TestCase):
+
+  def CheckTimestampConversion(self, message, text):
+    self.assertEqual(text, message.ToJsonString())
+    parsed_message = timestamp_pb2.Timestamp()
+    parsed_message.FromJsonString(text)
+    self.assertEqual(message, parsed_message)
+
+  def CheckDurationConversion(self, message, text):
+    self.assertEqual(text, message.ToJsonString())
+    parsed_message = duration_pb2.Duration()
+    parsed_message.FromJsonString(text)
+    self.assertEqual(message, parsed_message)
+
+
+class TimeUtilTest(TimeUtilTestBase):
+
+  def testTimestampSerializeAndParse(self):
+    message = timestamp_pb2.Timestamp()
+    # Generated output should contain 3, 6, or 9 fractional digits.
+    message.seconds = 0
+    message.nanos = 0
+    self.CheckTimestampConversion(message, '1970-01-01T00:00:00Z')
+    message.nanos = 10000000
+    self.CheckTimestampConversion(message, '1970-01-01T00:00:00.010Z')
+    message.nanos = 10000
+    self.CheckTimestampConversion(message, '1970-01-01T00:00:00.000010Z')
+    message.nanos = 10
+    self.CheckTimestampConversion(message, '1970-01-01T00:00:00.000000010Z')
+    # Test min timestamps.
+    message.seconds = -62135596800
+    message.nanos = 0
+    self.CheckTimestampConversion(message, '0001-01-01T00:00:00Z')
+    # Test max timestamps.
+    message.seconds = 253402300799
+    message.nanos = 999999999
+    self.CheckTimestampConversion(message, '9999-12-31T23:59:59.999999999Z')
+    # Test negative timestamps.
+    message.seconds = -1
+    self.CheckTimestampConversion(message, '1969-12-31T23:59:59.999999999Z')
+
+    # Parsing accepts an fractional digits as long as they fit into nano
+    # precision.
+    message.FromJsonString('1970-01-01T00:00:00.1Z')
+    self.assertEqual(0, message.seconds)
+    self.assertEqual(100000000, message.nanos)
+    # Parsing accpets offsets.
+    message.FromJsonString('1970-01-01T00:00:00-08:00')
+    self.assertEqual(8 * 3600, message.seconds)
+    self.assertEqual(0, message.nanos)
+
+  def testDurationSerializeAndParse(self):
+    message = duration_pb2.Duration()
+    # Generated output should contain 3, 6, or 9 fractional digits.
+    message.seconds = 0
+    message.nanos = 0
+    self.CheckDurationConversion(message, '0s')
+    message.nanos = 10000000
+    self.CheckDurationConversion(message, '0.010s')
+    message.nanos = 10000
+    self.CheckDurationConversion(message, '0.000010s')
+    message.nanos = 10
+    self.CheckDurationConversion(message, '0.000000010s')
+
+    # Test min and max
+    message.seconds = 315576000000
+    message.nanos = 999999999
+    self.CheckDurationConversion(message, '315576000000.999999999s')
+    message.seconds = -315576000000
+    message.nanos = -999999999
+    self.CheckDurationConversion(message, '-315576000000.999999999s')
+
+    # Parsing accepts an fractional digits as long as they fit into nano
+    # precision.
+    message.FromJsonString('0.1s')
+    self.assertEqual(100000000, message.nanos)
+    message.FromJsonString('0.0000001s')
+    self.assertEqual(100, message.nanos)
+
+  def testTimestampIntegerConversion(self):
+    message = timestamp_pb2.Timestamp()
+    message.FromNanoseconds(1)
+    self.assertEqual('1970-01-01T00:00:00.000000001Z',
+                     message.ToJsonString())
+    self.assertEqual(1, message.ToNanoseconds())
+
+    message.FromNanoseconds(-1)
+    self.assertEqual('1969-12-31T23:59:59.999999999Z',
+                     message.ToJsonString())
+    self.assertEqual(-1, message.ToNanoseconds())
+
+    message.FromMicroseconds(1)
+    self.assertEqual('1970-01-01T00:00:00.000001Z',
+                     message.ToJsonString())
+    self.assertEqual(1, message.ToMicroseconds())
+
+    message.FromMicroseconds(-1)
+    self.assertEqual('1969-12-31T23:59:59.999999Z',
+                     message.ToJsonString())
+    self.assertEqual(-1, message.ToMicroseconds())
+
+    message.FromMilliseconds(1)
+    self.assertEqual('1970-01-01T00:00:00.001Z',
+                     message.ToJsonString())
+    self.assertEqual(1, message.ToMilliseconds())
+
+    message.FromMilliseconds(-1)
+    self.assertEqual('1969-12-31T23:59:59.999Z',
+                     message.ToJsonString())
+    self.assertEqual(-1, message.ToMilliseconds())
+
+    message.FromSeconds(1)
+    self.assertEqual('1970-01-01T00:00:01Z',
+                     message.ToJsonString())
+    self.assertEqual(1, message.ToSeconds())
+
+    message.FromSeconds(-1)
+    self.assertEqual('1969-12-31T23:59:59Z',
+                     message.ToJsonString())
+    self.assertEqual(-1, message.ToSeconds())
+
+    message.FromNanoseconds(1999)
+    self.assertEqual(1, message.ToMicroseconds())
+    # 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).
+    message.FromNanoseconds(-1999)
+    self.assertEqual(-2, message.ToMicroseconds())
+
+  def testDurationIntegerConversion(self):
+    message = duration_pb2.Duration()
+    message.FromNanoseconds(1)
+    self.assertEqual('0.000000001s',
+                     message.ToJsonString())
+    self.assertEqual(1, message.ToNanoseconds())
+
+    message.FromNanoseconds(-1)
+    self.assertEqual('-0.000000001s',
+                     message.ToJsonString())
+    self.assertEqual(-1, message.ToNanoseconds())
+
+    message.FromMicroseconds(1)
+    self.assertEqual('0.000001s',
+                     message.ToJsonString())
+    self.assertEqual(1, message.ToMicroseconds())
+
+    message.FromMicroseconds(-1)
+    self.assertEqual('-0.000001s',
+                     message.ToJsonString())
+    self.assertEqual(-1, message.ToMicroseconds())
+
+    message.FromMilliseconds(1)
+    self.assertEqual('0.001s',
+                     message.ToJsonString())
+    self.assertEqual(1, message.ToMilliseconds())
+
+    message.FromMilliseconds(-1)
+    self.assertEqual('-0.001s',
+                     message.ToJsonString())
+    self.assertEqual(-1, message.ToMilliseconds())
+
+    message.FromSeconds(1)
+    self.assertEqual('1s', message.ToJsonString())
+    self.assertEqual(1, message.ToSeconds())
+
+    message.FromSeconds(-1)
+    self.assertEqual('-1s',
+                     message.ToJsonString())
+    self.assertEqual(-1, message.ToSeconds())
+
+    # Test truncation behavior.
+    message.FromNanoseconds(1999)
+    self.assertEqual(1, message.ToMicroseconds())
+
+    # For negative values, Duration will be rounded towards 0.
+    message.FromNanoseconds(-1999)
+    self.assertEqual(-1, message.ToMicroseconds())
+
+  def testDatetimeConverison(self):
+    message = timestamp_pb2.Timestamp()
+    dt = datetime(1970, 1, 1)
+    message.FromDatetime(dt)
+    self.assertEqual(dt, message.ToDatetime())
+
+    message.FromMilliseconds(1999)
+    self.assertEqual(datetime(1970, 1, 1, 0, 0, 1, 999000),
+                     message.ToDatetime())
+
+  def testTimedeltaConversion(self):
+    message = duration_pb2.Duration()
+    message.FromNanoseconds(1999999999)
+    td = message.ToTimedelta()
+    self.assertEqual(1, td.seconds)
+    self.assertEqual(999999, td.microseconds)
+
+    message.FromNanoseconds(-1999999999)
+    td = message.ToTimedelta()
+    self.assertEqual(-1, td.days)
+    self.assertEqual(86398, td.seconds)
+    self.assertEqual(1, td.microseconds)
+
+    message.FromMicroseconds(-1)
+    td = message.ToTimedelta()
+    self.assertEqual(-1, td.days)
+    self.assertEqual(86399, td.seconds)
+    self.assertEqual(999999, td.microseconds)
+    converted_message = duration_pb2.Duration()
+    converted_message.FromTimedelta(td)
+    self.assertEqual(message, converted_message)
+
+  def testInvalidTimestamp(self):
+    message = timestamp_pb2.Timestamp()
+    self.assertRaisesRegexp(
+        ValueError,
+        'time data \'10000-01-01T00:00:00\' does not match'
+        ' format \'%Y-%m-%dT%H:%M:%S\'',
+        message.FromJsonString, '10000-01-01T00:00:00.00Z')
+    self.assertRaisesRegexp(
+        well_known_types.ParseError,
+        'nanos 0123456789012 more than 9 fractional digits.',
+        message.FromJsonString,
+        '1970-01-01T00:00:00.0123456789012Z')
+    self.assertRaisesRegexp(
+        well_known_types.ParseError,
+        (r'Invalid timezone offset value: \+08.'),
+        message.FromJsonString,
+        '1972-01-01T01:00:00.01+08',)
+    self.assertRaisesRegexp(
+        ValueError,
+        'year is out of range',
+        message.FromJsonString,
+        '0000-01-01T00:00:00Z')
+    message.seconds = 253402300800
+    self.assertRaisesRegexp(
+        OverflowError,
+        'date value out of range',
+        message.ToJsonString)
+
+  def testInvalidDuration(self):
+    message = duration_pb2.Duration()
+    self.assertRaisesRegexp(
+        well_known_types.ParseError,
+        'Duration must end with letter "s": 1.',
+        message.FromJsonString, '1')
+    self.assertRaisesRegexp(
+        well_known_types.ParseError,
+        'Couldn\'t parse duration: 1...2s.',
+        message.FromJsonString, '1...2s')
+
+
+class FieldMaskTest(unittest.TestCase):
+
+  def testStringFormat(self):
+    mask = field_mask_pb2.FieldMask()
+    self.assertEqual('', mask.ToJsonString())
+    mask.paths.append('foo')
+    self.assertEqual('foo', mask.ToJsonString())
+    mask.paths.append('bar')
+    self.assertEqual('foo,bar', mask.ToJsonString())
+
+    mask.FromJsonString('')
+    self.assertEqual('', mask.ToJsonString())
+    mask.FromJsonString('foo')
+    self.assertEqual(['foo'], mask.paths)
+    mask.FromJsonString('foo,bar')
+    self.assertEqual(['foo', 'bar'], mask.paths)
+
+  def testDescriptorToFieldMask(self):
+    mask = field_mask_pb2.FieldMask()
+    msg_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
+    mask.AllFieldsFromDescriptor(msg_descriptor)
+    self.assertEqual(75, len(mask.paths))
+    self.assertTrue(mask.IsValidForDescriptor(msg_descriptor))
+    for field in msg_descriptor.fields:
+      self.assertTrue(field.name in mask.paths)
+    mask.paths.append('optional_nested_message.bb')
+    self.assertTrue(mask.IsValidForDescriptor(msg_descriptor))
+    mask.paths.append('repeated_nested_message.bb')
+    self.assertFalse(mask.IsValidForDescriptor(msg_descriptor))
+
+  def testCanonicalFrom(self):
+    mask = field_mask_pb2.FieldMask()
+    out_mask = field_mask_pb2.FieldMask()
+    # Paths will be sorted.
+    mask.FromJsonString('baz.quz,bar,foo')
+    out_mask.CanonicalFormFromMask(mask)
+    self.assertEqual('bar,baz.quz,foo', out_mask.ToJsonString())
+    # Duplicated paths will be removed.
+    mask.FromJsonString('foo,bar,foo')
+    out_mask.CanonicalFormFromMask(mask)
+    self.assertEqual('bar,foo', out_mask.ToJsonString())
+    # Sub-paths of other paths will be removed.
+    mask.FromJsonString('foo.b1,bar.b1,foo.b2,bar')
+    out_mask.CanonicalFormFromMask(mask)
+    self.assertEqual('bar,foo.b1,foo.b2', out_mask.ToJsonString())
+
+    # Test more deeply nested cases.
+    mask.FromJsonString(
+        'foo.bar.baz1,foo.bar.baz2.quz,foo.bar.baz2')
+    out_mask.CanonicalFormFromMask(mask)
+    self.assertEqual('foo.bar.baz1,foo.bar.baz2',
+                     out_mask.ToJsonString())
+    mask.FromJsonString(
+        'foo.bar.baz1,foo.bar.baz2,foo.bar.baz2.quz')
+    out_mask.CanonicalFormFromMask(mask)
+    self.assertEqual('foo.bar.baz1,foo.bar.baz2',
+                     out_mask.ToJsonString())
+    mask.FromJsonString(
+        'foo.bar.baz1,foo.bar.baz2,foo.bar.baz2.quz,foo.bar')
+    out_mask.CanonicalFormFromMask(mask)
+    self.assertEqual('foo.bar', out_mask.ToJsonString())
+    mask.FromJsonString(
+        'foo.bar.baz1,foo.bar.baz2,foo.bar.baz2.quz,foo')
+    out_mask.CanonicalFormFromMask(mask)
+    self.assertEqual('foo', out_mask.ToJsonString())
+
+  def testUnion(self):
+    mask1 = field_mask_pb2.FieldMask()
+    mask2 = field_mask_pb2.FieldMask()
+    out_mask = field_mask_pb2.FieldMask()
+    mask1.FromJsonString('foo,baz')
+    mask2.FromJsonString('bar,quz')
+    out_mask.Union(mask1, mask2)
+    self.assertEqual('bar,baz,foo,quz', out_mask.ToJsonString())
+    # Overlap with duplicated paths.
+    mask1.FromJsonString('foo,baz.bb')
+    mask2.FromJsonString('baz.bb,quz')
+    out_mask.Union(mask1, mask2)
+    self.assertEqual('baz.bb,foo,quz', out_mask.ToJsonString())
+    # Overlap with paths covering some other paths.
+    mask1.FromJsonString('foo.bar.baz,quz')
+    mask2.FromJsonString('foo.bar,bar')
+    out_mask.Union(mask1, mask2)
+    self.assertEqual('bar,foo.bar,quz', out_mask.ToJsonString())
+
+  def testIntersect(self):
+    mask1 = field_mask_pb2.FieldMask()
+    mask2 = field_mask_pb2.FieldMask()
+    out_mask = field_mask_pb2.FieldMask()
+    # Test cases without overlapping.
+    mask1.FromJsonString('foo,baz')
+    mask2.FromJsonString('bar,quz')
+    out_mask.Intersect(mask1, mask2)
+    self.assertEqual('', out_mask.ToJsonString())
+    # Overlap with duplicated paths.
+    mask1.FromJsonString('foo,baz.bb')
+    mask2.FromJsonString('baz.bb,quz')
+    out_mask.Intersect(mask1, mask2)
+    self.assertEqual('baz.bb', out_mask.ToJsonString())
+    # Overlap with paths covering some other paths.
+    mask1.FromJsonString('foo.bar.baz,quz')
+    mask2.FromJsonString('foo.bar,bar')
+    out_mask.Intersect(mask1, mask2)
+    self.assertEqual('foo.bar.baz', out_mask.ToJsonString())
+    mask1.FromJsonString('foo.bar,bar')
+    mask2.FromJsonString('foo.bar.baz,quz')
+    out_mask.Intersect(mask1, mask2)
+    self.assertEqual('foo.bar.baz', out_mask.ToJsonString())
+
+  def testMergeMessage(self):
+    # Test merge one field.
+    src = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(src)
+    for field in src.DESCRIPTOR.fields:
+      if field.containing_oneof:
+        continue
+      field_name = field.name
+      dst = unittest_pb2.TestAllTypes()
+      # Only set one path to mask.
+      mask = field_mask_pb2.FieldMask()
+      mask.paths.append(field_name)
+      mask.MergeMessage(src, dst)
+      # The expected result message.
+      msg = unittest_pb2.TestAllTypes()
+      if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+        repeated_src = getattr(src, field_name)
+        repeated_msg = getattr(msg, field_name)
+        if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+          for item in repeated_src:
+            repeated_msg.add().CopyFrom(item)
+        else:
+          repeated_msg.extend(repeated_src)
+      elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+        getattr(msg, field_name).CopyFrom(getattr(src, field_name))
+      else:
+        setattr(msg, field_name, getattr(src, field_name))
+      # Only field specified in mask is merged.
+      self.assertEqual(msg, dst)
+
+    # Test merge nested fields.
+    nested_src = unittest_pb2.NestedTestAllTypes()
+    nested_dst = unittest_pb2.NestedTestAllTypes()
+    nested_src.child.payload.optional_int32 = 1234
+    nested_src.child.child.payload.optional_int32 = 5678
+    mask = field_mask_pb2.FieldMask()
+    mask.FromJsonString('child.payload')
+    mask.MergeMessage(nested_src, nested_dst)
+    self.assertEqual(1234, nested_dst.child.payload.optional_int32)
+    self.assertEqual(0, nested_dst.child.child.payload.optional_int32)
+
+    mask.FromJsonString('child.child.payload')
+    mask.MergeMessage(nested_src, nested_dst)
+    self.assertEqual(1234, nested_dst.child.payload.optional_int32)
+    self.assertEqual(5678, nested_dst.child.child.payload.optional_int32)
+
+    nested_dst.Clear()
+    mask.FromJsonString('child.child.payload')
+    mask.MergeMessage(nested_src, nested_dst)
+    self.assertEqual(0, nested_dst.child.payload.optional_int32)
+    self.assertEqual(5678, nested_dst.child.child.payload.optional_int32)
+
+    nested_dst.Clear()
+    mask.FromJsonString('child')
+    mask.MergeMessage(nested_src, nested_dst)
+    self.assertEqual(1234, nested_dst.child.payload.optional_int32)
+    self.assertEqual(5678, nested_dst.child.child.payload.optional_int32)
+
+    # Test MergeOptions.
+    nested_dst.Clear()
+    nested_dst.child.payload.optional_int64 = 4321
+    # Message fields will be merged by default.
+    mask.FromJsonString('child.payload')
+    mask.MergeMessage(nested_src, nested_dst)
+    self.assertEqual(1234, nested_dst.child.payload.optional_int32)
+    self.assertEqual(4321, nested_dst.child.payload.optional_int64)
+    # Change the behavior to replace message fields.
+    mask.FromJsonString('child.payload')
+    mask.MergeMessage(nested_src, nested_dst, True, False)
+    self.assertEqual(1234, nested_dst.child.payload.optional_int32)
+    self.assertEqual(0, nested_dst.child.payload.optional_int64)
+
+    # By default, fields missing in source are not cleared in destination.
+    nested_dst.payload.optional_int32 = 1234
+    self.assertTrue(nested_dst.HasField('payload'))
+    mask.FromJsonString('payload')
+    mask.MergeMessage(nested_src, nested_dst)
+    self.assertTrue(nested_dst.HasField('payload'))
+    # But they are cleared when replacing message fields.
+    nested_dst.Clear()
+    nested_dst.payload.optional_int32 = 1234
+    mask.FromJsonString('payload')
+    mask.MergeMessage(nested_src, nested_dst, True, False)
+    self.assertFalse(nested_dst.HasField('payload'))
+
+    nested_src.payload.repeated_int32.append(1234)
+    nested_dst.payload.repeated_int32.append(5678)
+    # Repeated fields will be appended by default.
+    mask.FromJsonString('payload.repeated_int32')
+    mask.MergeMessage(nested_src, nested_dst)
+    self.assertEqual(2, len(nested_dst.payload.repeated_int32))
+    self.assertEqual(5678, nested_dst.payload.repeated_int32[0])
+    self.assertEqual(1234, nested_dst.payload.repeated_int32[1])
+    # Change the behavior to replace repeated fields.
+    mask.FromJsonString('payload.repeated_int32')
+    mask.MergeMessage(nested_src, nested_dst, False, True)
+    self.assertEqual(1, len(nested_dst.payload.repeated_int32))
+    self.assertEqual(1234, nested_dst.payload.repeated_int32[0])
+
+
+class StructTest(unittest.TestCase):
+
+  def testStruct(self):
+    struct = struct_pb2.Struct()
+    struct_class = struct.__class__
+
+    struct['key1'] = 5
+    struct['key2'] = 'abc'
+    struct['key3'] = True
+    struct.get_or_create_struct('key4')['subkey'] = 11.0
+    struct_list = struct.get_or_create_list('key5')
+    struct_list.extend([6, 'seven', True, False, None])
+    struct_list.add_struct()['subkey2'] = 9
+
+    self.assertTrue(isinstance(struct, well_known_types.Struct))
+    self.assertEquals(5, struct['key1'])
+    self.assertEquals('abc', struct['key2'])
+    self.assertIs(True, struct['key3'])
+    self.assertEquals(11, struct['key4']['subkey'])
+    inner_struct = struct_class()
+    inner_struct['subkey2'] = 9
+    self.assertEquals([6, 'seven', True, False, None, inner_struct],
+                      list(struct['key5'].items()))
+
+    serialized = struct.SerializeToString()
+
+    struct2 = struct_pb2.Struct()
+    struct2.ParseFromString(serialized)
+
+    self.assertEquals(struct, struct2)
+
+    self.assertTrue(isinstance(struct2, well_known_types.Struct))
+    self.assertEquals(5, struct2['key1'])
+    self.assertEquals('abc', struct2['key2'])
+    self.assertIs(True, struct2['key3'])
+    self.assertEquals(11, struct2['key4']['subkey'])
+    self.assertEquals([6, 'seven', True, False, None, inner_struct],
+                      list(struct2['key5'].items()))
+
+    struct_list = struct2['key5']
+    self.assertEquals(6, struct_list[0])
+    self.assertEquals('seven', struct_list[1])
+    self.assertEquals(True, struct_list[2])
+    self.assertEquals(False, struct_list[3])
+    self.assertEquals(None, struct_list[4])
+    self.assertEquals(inner_struct, struct_list[5])
+
+    struct_list[1] = 7
+    self.assertEquals(7, struct_list[1])
+
+    struct_list.add_list().extend([1, 'two', True, False, None])
+    self.assertEquals([1, 'two', True, False, None],
+                      list(struct_list[6].items()))
+
+    text_serialized = str(struct)
+    struct3 = struct_pb2.Struct()
+    text_format.Merge(text_serialized, struct3)
+    self.assertEquals(struct, struct3)
+
+    struct.get_or_create_struct('key3')['replace'] = 12
+    self.assertEquals(12, struct['key3']['replace'])
+
+
+class AnyTest(unittest.TestCase):
+
+  def testAnyMessage(self):
+    # Creates and sets message.
+    msg = any_test_pb2.TestAny()
+    msg_descriptor = msg.DESCRIPTOR
+    all_types = unittest_pb2.TestAllTypes()
+    all_descriptor = all_types.DESCRIPTOR
+    all_types.repeated_string.append(u'\u00fc\ua71f')
+    # Packs to Any.
+    msg.value.Pack(all_types)
+    self.assertEqual(msg.value.type_url,
+                     'type.googleapis.com/%s' % all_descriptor.full_name)
+    self.assertEqual(msg.value.value,
+                     all_types.SerializeToString())
+    # Tests Is() method.
+    self.assertTrue(msg.value.Is(all_descriptor))
+    self.assertFalse(msg.value.Is(msg_descriptor))
+    # Unpacks Any.
+    unpacked_message = unittest_pb2.TestAllTypes()
+    self.assertTrue(msg.value.Unpack(unpacked_message))
+    self.assertEqual(all_types, unpacked_message)
+    # Unpacks to different type.
+    self.assertFalse(msg.value.Unpack(msg))
+    # Only Any messages have Pack method.
+    try:
+      msg.Pack(all_types)
+    except AttributeError:
+      pass
+    else:
+      raise AttributeError('%s should not have Pack method.' %
+                           msg_descriptor.full_name)
+
+  def testMessageName(self):
+    # Creates and sets message.
+    submessage = any_test_pb2.TestAny()
+    submessage.int_value = 12345
+    msg = any_pb2.Any()
+    msg.Pack(submessage)
+    self.assertEqual(msg.TypeName(), 'google.protobuf.internal.TestAny')
+
+  def testPackWithCustomTypeUrl(self):
+    submessage = any_test_pb2.TestAny()
+    submessage.int_value = 12345
+    msg = any_pb2.Any()
+    # Pack with a custom type URL prefix.
+    msg.Pack(submessage, 'type.myservice.com')
+    self.assertEqual(msg.type_url,
+                     'type.myservice.com/%s' % submessage.DESCRIPTOR.full_name)
+    # Pack with a custom type URL prefix ending with '/'.
+    msg.Pack(submessage, 'type.myservice.com/')
+    self.assertEqual(msg.type_url,
+                     'type.myservice.com/%s' % submessage.DESCRIPTOR.full_name)
+    # Pack with an empty type URL prefix.
+    msg.Pack(submessage, '')
+    self.assertEqual(msg.type_url,
+                     '/%s' % submessage.DESCRIPTOR.full_name)
+    # Test unpacking the type.
+    unpacked_message = any_test_pb2.TestAny()
+    self.assertTrue(msg.Unpack(unpacked_message))
+    self.assertEqual(submessage, unpacked_message)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/internal/wire_format.py b/generator/google/protobuf/internal/wire_format.py
index c941fe1..883f525 100644
--- a/generator/google/protobuf/internal/wire_format.py
+++ b/generator/google/protobuf/internal/wire_format.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
diff --git a/generator/google/protobuf/internal/wire_format_test.py b/generator/google/protobuf/internal/wire_format_test.py
new file mode 100644
index 0000000..da120f3
--- /dev/null
+++ b/generator/google/protobuf/internal/wire_format_test.py
@@ -0,0 +1,257 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Test for google.protobuf.internal.wire_format."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+try:
+  import unittest2 as unittest  #PY26
+except ImportError:
+  import unittest
+
+from google.protobuf import message
+from google.protobuf.internal import wire_format
+
+
+class WireFormatTest(unittest.TestCase):
+
+  def testPackTag(self):
+    field_number = 0xabc
+    tag_type = 2
+    self.assertEqual((field_number << 3) | tag_type,
+                     wire_format.PackTag(field_number, tag_type))
+    PackTag = wire_format.PackTag
+    # Number too high.
+    self.assertRaises(message.EncodeError, PackTag, field_number, 6)
+    # Number too low.
+    self.assertRaises(message.EncodeError, PackTag, field_number, -1)
+
+  def testUnpackTag(self):
+    # Test field numbers that will require various varint sizes.
+    for expected_field_number in (1, 15, 16, 2047, 2048):
+      for expected_wire_type in range(6):  # Highest-numbered wiretype is 5.
+        field_number, wire_type = wire_format.UnpackTag(
+            wire_format.PackTag(expected_field_number, expected_wire_type))
+        self.assertEqual(expected_field_number, field_number)
+        self.assertEqual(expected_wire_type, wire_type)
+
+    self.assertRaises(TypeError, wire_format.UnpackTag, None)
+    self.assertRaises(TypeError, wire_format.UnpackTag, 'abc')
+    self.assertRaises(TypeError, wire_format.UnpackTag, 0.0)
+    self.assertRaises(TypeError, wire_format.UnpackTag, object())
+
+  def testZigZagEncode(self):
+    Z = wire_format.ZigZagEncode
+    self.assertEqual(0, Z(0))
+    self.assertEqual(1, Z(-1))
+    self.assertEqual(2, Z(1))
+    self.assertEqual(3, Z(-2))
+    self.assertEqual(4, Z(2))
+    self.assertEqual(0xfffffffe, Z(0x7fffffff))
+    self.assertEqual(0xffffffff, Z(-0x80000000))
+    self.assertEqual(0xfffffffffffffffe, Z(0x7fffffffffffffff))
+    self.assertEqual(0xffffffffffffffff, Z(-0x8000000000000000))
+
+    self.assertRaises(TypeError, Z, None)
+    self.assertRaises(TypeError, Z, 'abcd')
+    self.assertRaises(TypeError, Z, 0.0)
+    self.assertRaises(TypeError, Z, object())
+
+  def testZigZagDecode(self):
+    Z = wire_format.ZigZagDecode
+    self.assertEqual(0, Z(0))
+    self.assertEqual(-1, Z(1))
+    self.assertEqual(1, Z(2))
+    self.assertEqual(-2, Z(3))
+    self.assertEqual(2, Z(4))
+    self.assertEqual(0x7fffffff, Z(0xfffffffe))
+    self.assertEqual(-0x80000000, Z(0xffffffff))
+    self.assertEqual(0x7fffffffffffffff, Z(0xfffffffffffffffe))
+    self.assertEqual(-0x8000000000000000, Z(0xffffffffffffffff))
+
+    self.assertRaises(TypeError, Z, None)
+    self.assertRaises(TypeError, Z, 'abcd')
+    self.assertRaises(TypeError, Z, 0.0)
+    self.assertRaises(TypeError, Z, object())
+
+  def NumericByteSizeTestHelper(self, byte_size_fn, value, expected_value_size):
+    # Use field numbers that cause various byte sizes for the tag information.
+    for field_number, tag_bytes in ((15, 1), (16, 2), (2047, 2), (2048, 3)):
+      expected_size = expected_value_size + tag_bytes
+      actual_size = byte_size_fn(field_number, value)
+      self.assertEqual(expected_size, actual_size,
+                       'byte_size_fn: %s, field_number: %d, value: %r\n'
+                       'Expected: %d, Actual: %d'% (
+          byte_size_fn, field_number, value, expected_size, actual_size))
+
+  def testByteSizeFunctions(self):
+    # Test all numeric *ByteSize() functions.
+    NUMERIC_ARGS = [
+        # Int32ByteSize().
+        [wire_format.Int32ByteSize, 0, 1],
+        [wire_format.Int32ByteSize, 127, 1],
+        [wire_format.Int32ByteSize, 128, 2],
+        [wire_format.Int32ByteSize, -1, 10],
+        # Int64ByteSize().
+        [wire_format.Int64ByteSize, 0, 1],
+        [wire_format.Int64ByteSize, 127, 1],
+        [wire_format.Int64ByteSize, 128, 2],
+        [wire_format.Int64ByteSize, -1, 10],
+        # UInt32ByteSize().
+        [wire_format.UInt32ByteSize, 0, 1],
+        [wire_format.UInt32ByteSize, 127, 1],
+        [wire_format.UInt32ByteSize, 128, 2],
+        [wire_format.UInt32ByteSize, wire_format.UINT32_MAX, 5],
+        # UInt64ByteSize().
+        [wire_format.UInt64ByteSize, 0, 1],
+        [wire_format.UInt64ByteSize, 127, 1],
+        [wire_format.UInt64ByteSize, 128, 2],
+        [wire_format.UInt64ByteSize, wire_format.UINT64_MAX, 10],
+        # SInt32ByteSize().
+        [wire_format.SInt32ByteSize, 0, 1],
+        [wire_format.SInt32ByteSize, -1, 1],
+        [wire_format.SInt32ByteSize, 1, 1],
+        [wire_format.SInt32ByteSize, -63, 1],
+        [wire_format.SInt32ByteSize, 63, 1],
+        [wire_format.SInt32ByteSize, -64, 1],
+        [wire_format.SInt32ByteSize, 64, 2],
+        # SInt64ByteSize().
+        [wire_format.SInt64ByteSize, 0, 1],
+        [wire_format.SInt64ByteSize, -1, 1],
+        [wire_format.SInt64ByteSize, 1, 1],
+        [wire_format.SInt64ByteSize, -63, 1],
+        [wire_format.SInt64ByteSize, 63, 1],
+        [wire_format.SInt64ByteSize, -64, 1],
+        [wire_format.SInt64ByteSize, 64, 2],
+        # Fixed32ByteSize().
+        [wire_format.Fixed32ByteSize, 0, 4],
+        [wire_format.Fixed32ByteSize, wire_format.UINT32_MAX, 4],
+        # Fixed64ByteSize().
+        [wire_format.Fixed64ByteSize, 0, 8],
+        [wire_format.Fixed64ByteSize, wire_format.UINT64_MAX, 8],
+        # SFixed32ByteSize().
+        [wire_format.SFixed32ByteSize, 0, 4],
+        [wire_format.SFixed32ByteSize, wire_format.INT32_MIN, 4],
+        [wire_format.SFixed32ByteSize, wire_format.INT32_MAX, 4],
+        # SFixed64ByteSize().
+        [wire_format.SFixed64ByteSize, 0, 8],
+        [wire_format.SFixed64ByteSize, wire_format.INT64_MIN, 8],
+        [wire_format.SFixed64ByteSize, wire_format.INT64_MAX, 8],
+        # FloatByteSize().
+        [wire_format.FloatByteSize, 0.0, 4],
+        [wire_format.FloatByteSize, 1000000000.0, 4],
+        [wire_format.FloatByteSize, -1000000000.0, 4],
+        # DoubleByteSize().
+        [wire_format.DoubleByteSize, 0.0, 8],
+        [wire_format.DoubleByteSize, 1000000000.0, 8],
+        [wire_format.DoubleByteSize, -1000000000.0, 8],
+        # BoolByteSize().
+        [wire_format.BoolByteSize, False, 1],
+        [wire_format.BoolByteSize, True, 1],
+        # EnumByteSize().
+        [wire_format.EnumByteSize, 0, 1],
+        [wire_format.EnumByteSize, 127, 1],
+        [wire_format.EnumByteSize, 128, 2],
+        [wire_format.EnumByteSize, wire_format.UINT32_MAX, 5],
+        ]
+    for args in NUMERIC_ARGS:
+      self.NumericByteSizeTestHelper(*args)
+
+    # Test strings and bytes.
+    for byte_size_fn in (wire_format.StringByteSize, wire_format.BytesByteSize):
+      # 1 byte for tag, 1 byte for length, 3 bytes for contents.
+      self.assertEqual(5, byte_size_fn(10, 'abc'))
+      # 2 bytes for tag, 1 byte for length, 3 bytes for contents.
+      self.assertEqual(6, byte_size_fn(16, 'abc'))
+      # 2 bytes for tag, 2 bytes for length, 128 bytes for contents.
+      self.assertEqual(132, byte_size_fn(16, 'a' * 128))
+
+    # Test UTF-8 string byte size calculation.
+    # 1 byte for tag, 1 byte for length, 8 bytes for content.
+    self.assertEqual(10, wire_format.StringByteSize(
+        5, b'\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82'.decode('utf-8')))
+
+    class MockMessage(object):
+      def __init__(self, byte_size):
+        self.byte_size = byte_size
+      def ByteSize(self):
+        return self.byte_size
+
+    message_byte_size = 10
+    mock_message = MockMessage(byte_size=message_byte_size)
+    # Test groups.
+    # (2 * 1) bytes for begin and end tags, plus message_byte_size.
+    self.assertEqual(2 + message_byte_size,
+                     wire_format.GroupByteSize(1, mock_message))
+    # (2 * 2) bytes for begin and end tags, plus message_byte_size.
+    self.assertEqual(4 + message_byte_size,
+                     wire_format.GroupByteSize(16, mock_message))
+
+    # Test messages.
+    # 1 byte for tag, plus 1 byte for length, plus contents.
+    self.assertEqual(2 + mock_message.byte_size,
+                     wire_format.MessageByteSize(1, mock_message))
+    # 2 bytes for tag, plus 1 byte for length, plus contents.
+    self.assertEqual(3 + mock_message.byte_size,
+                     wire_format.MessageByteSize(16, mock_message))
+    # 2 bytes for tag, plus 2 bytes for length, plus contents.
+    mock_message.byte_size = 128
+    self.assertEqual(4 + mock_message.byte_size,
+                     wire_format.MessageByteSize(16, mock_message))
+
+
+    # Test message set item byte size.
+    # 4 bytes for tags, plus 1 byte for length, plus 1 byte for type_id,
+    # plus contents.
+    mock_message.byte_size = 10
+    self.assertEqual(mock_message.byte_size + 6,
+                     wire_format.MessageSetItemByteSize(1, mock_message))
+
+    # 4 bytes for tags, plus 2 bytes for length, plus 1 byte for type_id,
+    # plus contents.
+    mock_message.byte_size = 128
+    self.assertEqual(mock_message.byte_size + 7,
+                     wire_format.MessageSetItemByteSize(1, mock_message))
+
+    # 4 bytes for tags, plus 2 bytes for length, plus 2 byte for type_id,
+    # plus contents.
+    self.assertEqual(mock_message.byte_size + 8,
+                     wire_format.MessageSetItemByteSize(128, mock_message))
+
+    # Too-long varint.
+    self.assertRaises(message.EncodeError,
+                      wire_format.UInt64ByteSize, 1, 1 << 128)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/generator/google/protobuf/json_format.py b/generator/google/protobuf/json_format.py
new file mode 100644
index 0000000..bb6a199
--- /dev/null
+++ b/generator/google/protobuf/json_format.py
@@ -0,0 +1,664 @@
+# 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.
+
+"""Contains routines for printing protocol messages in JSON format.
+
+Simple usage example:
+
+  # Create a proto object and serialize it to a json format string.
+  message = my_proto_pb2.MyMessage(foo='bar')
+  json_string = json_format.MessageToJson(message)
+
+  # Parse a json format string to proto object.
+  message = json_format.Parse(json_string, my_proto_pb2.MyMessage())
+"""
+
+__author__ = 'jieluo@google.com (Jie Luo)'
+
+try:
+    from collections import OrderedDict
+except ImportError:
+    from ordereddict import OrderedDict  #PY26
+import base64
+import json
+import math
+import re
+import six
+import sys
+
+from operator import methodcaller
+from google.protobuf import descriptor
+from google.protobuf import symbol_database
+
+_TIMESTAMPFOMAT = '%Y-%m-%dT%H:%M:%S'
+_INT_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_INT32,
+                        descriptor.FieldDescriptor.CPPTYPE_UINT32,
+                        descriptor.FieldDescriptor.CPPTYPE_INT64,
+                        descriptor.FieldDescriptor.CPPTYPE_UINT64])
+_INT64_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_INT64,
+                          descriptor.FieldDescriptor.CPPTYPE_UINT64])
+_FLOAT_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_FLOAT,
+                          descriptor.FieldDescriptor.CPPTYPE_DOUBLE])
+_INFINITY = 'Infinity'
+_NEG_INFINITY = '-Infinity'
+_NAN = 'NaN'
+
+_UNPAIRED_SURROGATE_PATTERN = re.compile(six.u(
+    r'[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]'
+))
+
+class Error(Exception):
+  """Top-level module error for json_format."""
+
+
+class SerializeToJsonError(Error):
+  """Thrown if serialization to JSON fails."""
+
+
+class ParseError(Error):
+  """Thrown in case of parsing error."""
+
+
+def MessageToJson(message, including_default_value_fields=False):
+  """Converts protobuf message to JSON format.
+
+  Args:
+    message: The protocol buffers message instance to serialize.
+    including_default_value_fields: If True, singular primitive fields,
+        repeated fields, and map fields will always be serialized.  If
+        False, only serialize non-empty fields.  Singular message fields
+        and oneof fields are not affected by this option.
+
+  Returns:
+    A string containing the JSON formatted protocol buffer message.
+  """
+  printer = _Printer(including_default_value_fields)
+  return printer.ToJsonString(message)
+
+
+def _IsMapEntry(field):
+  return (field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
+          field.message_type.has_options and
+          field.message_type.GetOptions().map_entry)
+
+
+class _Printer(object):
+  """JSON format printer for protocol message."""
+
+  def __init__(self,
+               including_default_value_fields=False):
+    self.including_default_value_fields = including_default_value_fields
+
+  def ToJsonString(self, message):
+    js = self._MessageToJsonObject(message)
+    return json.dumps(js, indent=2)
+
+  def _MessageToJsonObject(self, message):
+    """Converts message to an object according to Proto3 JSON Specification."""
+    message_descriptor = message.DESCRIPTOR
+    full_name = message_descriptor.full_name
+    if _IsWrapperMessage(message_descriptor):
+      return self._WrapperMessageToJsonObject(message)
+    if full_name in _WKTJSONMETHODS:
+      return methodcaller(_WKTJSONMETHODS[full_name][0], message)(self)
+    js = {}
+    return self._RegularMessageToJsonObject(message, js)
+
+  def _RegularMessageToJsonObject(self, message, js):
+    """Converts normal message according to Proto3 JSON Specification."""
+    fields = message.ListFields()
+
+    try:
+      for field, value in fields:
+        name = field.camelcase_name
+        if _IsMapEntry(field):
+          # Convert a map field.
+          v_field = field.message_type.fields_by_name['value']
+          js_map = {}
+          for key in value:
+            if isinstance(key, bool):
+              if key:
+                recorded_key = 'true'
+              else:
+                recorded_key = 'false'
+            else:
+              recorded_key = key
+            js_map[recorded_key] = self._FieldToJsonObject(
+                v_field, value[key])
+          js[name] = js_map
+        elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+          # Convert a repeated field.
+          js[name] = [self._FieldToJsonObject(field, k)
+                      for k in value]
+        else:
+          js[name] = self._FieldToJsonObject(field, value)
+
+      # Serialize default value if including_default_value_fields is True.
+      if self.including_default_value_fields:
+        message_descriptor = message.DESCRIPTOR
+        for field in message_descriptor.fields:
+          # Singular message fields and oneof fields will not be affected.
+          if ((field.label != descriptor.FieldDescriptor.LABEL_REPEATED and
+               field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE) or
+              field.containing_oneof):
+            continue
+          name = field.camelcase_name
+          if name in js:
+            # Skip the field which has been serailized already.
+            continue
+          if _IsMapEntry(field):
+            js[name] = {}
+          elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+            js[name] = []
+          else:
+            js[name] = self._FieldToJsonObject(field, field.default_value)
+
+    except ValueError as e:
+      raise SerializeToJsonError(
+          'Failed to serialize {0} field: {1}.'.format(field.name, e))
+
+    return js
+
+  def _FieldToJsonObject(self, field, value):
+    """Converts field value according to Proto3 JSON Specification."""
+    if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+      return self._MessageToJsonObject(value)
+    elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
+      enum_value = field.enum_type.values_by_number.get(value, None)
+      if enum_value is not None:
+        return enum_value.name
+      else:
+        raise SerializeToJsonError('Enum field contains an integer value '
+                                   'which can not mapped to an enum value.')
+    elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING:
+      if field.type == descriptor.FieldDescriptor.TYPE_BYTES:
+        # Use base64 Data encoding for bytes
+        return base64.b64encode(value).decode('utf-8')
+      else:
+        return value
+    elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL:
+      return bool(value)
+    elif field.cpp_type in _INT64_TYPES:
+      return str(value)
+    elif field.cpp_type in _FLOAT_TYPES:
+      if math.isinf(value):
+        if value < 0.0:
+          return _NEG_INFINITY
+        else:
+          return _INFINITY
+      if math.isnan(value):
+        return _NAN
+    return value
+
+  def _AnyMessageToJsonObject(self, message):
+    """Converts Any message according to Proto3 JSON Specification."""
+    if not message.ListFields():
+      return {}
+    # Must print @type first, use OrderedDict instead of {}
+    js = OrderedDict()
+    type_url = message.type_url
+    js['@type'] = type_url
+    sub_message = _CreateMessageFromTypeUrl(type_url)
+    sub_message.ParseFromString(message.value)
+    message_descriptor = sub_message.DESCRIPTOR
+    full_name = message_descriptor.full_name
+    if _IsWrapperMessage(message_descriptor):
+      js['value'] = self._WrapperMessageToJsonObject(sub_message)
+      return js
+    if full_name in _WKTJSONMETHODS:
+      js['value'] = methodcaller(_WKTJSONMETHODS[full_name][0],
+                                 sub_message)(self)
+      return js
+    return self._RegularMessageToJsonObject(sub_message, js)
+
+  def _GenericMessageToJsonObject(self, message):
+    """Converts message according to Proto3 JSON Specification."""
+    # Duration, Timestamp and FieldMask have ToJsonString method to do the
+    # convert. Users can also call the method directly.
+    return message.ToJsonString()
+
+  def _ValueMessageToJsonObject(self, message):
+    """Converts Value message according to Proto3 JSON Specification."""
+    which = message.WhichOneof('kind')
+    # If the Value message is not set treat as null_value when serialize
+    # to JSON. The parse back result will be different from original message.
+    if which is None or which == 'null_value':
+      return None
+    if which == 'list_value':
+      return self._ListValueMessageToJsonObject(message.list_value)
+    if which == 'struct_value':
+      value = message.struct_value
+    else:
+      value = getattr(message, which)
+    oneof_descriptor = message.DESCRIPTOR.fields_by_name[which]
+    return self._FieldToJsonObject(oneof_descriptor, value)
+
+  def _ListValueMessageToJsonObject(self, message):
+    """Converts ListValue message according to Proto3 JSON Specification."""
+    return [self._ValueMessageToJsonObject(value)
+            for value in message.values]
+
+  def _StructMessageToJsonObject(self, message):
+    """Converts Struct message according to Proto3 JSON Specification."""
+    fields = message.fields
+    ret = {}
+    for key in fields:
+      ret[key] = self._ValueMessageToJsonObject(fields[key])
+    return ret
+
+  def _WrapperMessageToJsonObject(self, message):
+    return self._FieldToJsonObject(
+        message.DESCRIPTOR.fields_by_name['value'], message.value)
+
+
+def _IsWrapperMessage(message_descriptor):
+  return message_descriptor.file.name == 'google/protobuf/wrappers.proto'
+
+
+def _DuplicateChecker(js):
+  result = {}
+  for name, value in js:
+    if name in result:
+      raise ParseError('Failed to load JSON: duplicate key {0}.'.format(name))
+    result[name] = value
+  return result
+
+
+def _CreateMessageFromTypeUrl(type_url):
+  # TODO(jieluo): Should add a way that users can register the type resolver
+  # instead of the default one.
+  db = symbol_database.Default()
+  type_name = type_url.split('/')[-1]
+  try:
+    message_descriptor = db.pool.FindMessageTypeByName(type_name)
+  except KeyError:
+    raise TypeError(
+        'Can not find message descriptor by type_url: {0}.'.format(type_url))
+  message_class = db.GetPrototype(message_descriptor)
+  return message_class()
+
+
+def Parse(text, message, ignore_unknown_fields=False):
+  """Parses a JSON representation of a protocol message into a message.
+
+  Args:
+    text: Message JSON representation.
+    message: A protocol beffer message to merge into.
+    ignore_unknown_fields: If True, do not raise errors for unknown fields.
+
+  Returns:
+    The same message passed as argument.
+
+  Raises::
+    ParseError: On JSON parsing problems.
+  """
+  if not isinstance(text, six.text_type): text = text.decode('utf-8')
+  try:
+    if sys.version_info < (2, 7):
+      # object_pair_hook is not supported before python2.7
+      js = json.loads(text)
+    else:
+      js = json.loads(text, object_pairs_hook=_DuplicateChecker)
+  except ValueError as e:
+    raise ParseError('Failed to load JSON: {0}.'.format(str(e)))
+  parser = _Parser(ignore_unknown_fields)
+  parser.ConvertMessage(js, message)
+  return message
+
+
+_INT_OR_FLOAT = six.integer_types + (float,)
+
+
+class _Parser(object):
+  """JSON format parser for protocol message."""
+
+  def __init__(self,
+               ignore_unknown_fields):
+    self.ignore_unknown_fields = ignore_unknown_fields
+
+  def ConvertMessage(self, value, message):
+    """Convert a JSON object into a message.
+
+    Args:
+      value: A JSON object.
+      message: A WKT or regular protocol message to record the data.
+
+    Raises:
+      ParseError: In case of convert problems.
+    """
+    message_descriptor = message.DESCRIPTOR
+    full_name = message_descriptor.full_name
+    if _IsWrapperMessage(message_descriptor):
+      self._ConvertWrapperMessage(value, message)
+    elif full_name in _WKTJSONMETHODS:
+      methodcaller(_WKTJSONMETHODS[full_name][1], value, message)(self)
+    else:
+      self._ConvertFieldValuePair(value, message)
+
+  def _ConvertFieldValuePair(self, js, message):
+    """Convert field value pairs into regular message.
+
+    Args:
+      js: A JSON object to convert the field value pairs.
+      message: A regular protocol message to record the data.
+
+    Raises:
+      ParseError: In case of problems converting.
+    """
+    names = []
+    message_descriptor = message.DESCRIPTOR
+    for name in js:
+      try:
+        field = message_descriptor.fields_by_camelcase_name.get(name, None)
+        if not field:
+          if self.ignore_unknown_fields:
+            continue
+          raise ParseError(
+              'Message type "{0}" has no field named "{1}".'.format(
+                  message_descriptor.full_name, name))
+        if name in names:
+          raise ParseError('Message type "{0}" should not have multiple '
+                           '"{1}" fields.'.format(
+                               message.DESCRIPTOR.full_name, name))
+        names.append(name)
+        # Check no other oneof field is parsed.
+        if field.containing_oneof is not None:
+          oneof_name = field.containing_oneof.name
+          if oneof_name in names:
+            raise ParseError('Message type "{0}" should not have multiple '
+                             '"{1}" oneof fields.'.format(
+                                 message.DESCRIPTOR.full_name, oneof_name))
+          names.append(oneof_name)
+
+        value = js[name]
+        if value is None:
+          message.ClearField(field.name)
+          continue
+
+        # Parse field value.
+        if _IsMapEntry(field):
+          message.ClearField(field.name)
+          self._ConvertMapFieldValue(value, message, field)
+        elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+          message.ClearField(field.name)
+          if not isinstance(value, list):
+            raise ParseError('repeated field {0} must be in [] which is '
+                             '{1}.'.format(name, value))
+          if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+            # Repeated message field.
+            for item in value:
+              sub_message = getattr(message, field.name).add()
+              # None is a null_value in Value.
+              if (item is None and
+                  sub_message.DESCRIPTOR.full_name != 'google.protobuf.Value'):
+                raise ParseError('null is not allowed to be used as an element'
+                                 ' in a repeated field.')
+              self.ConvertMessage(item, sub_message)
+          else:
+            # Repeated scalar field.
+            for item in value:
+              if item is None:
+                raise ParseError('null is not allowed to be used as an element'
+                                 ' in a repeated field.')
+              getattr(message, field.name).append(
+                  _ConvertScalarFieldValue(item, field))
+        elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+          sub_message = getattr(message, field.name)
+          self.ConvertMessage(value, sub_message)
+        else:
+          setattr(message, field.name, _ConvertScalarFieldValue(value, field))
+      except ParseError as e:
+        if field and field.containing_oneof is None:
+          raise ParseError('Failed to parse {0} field: {1}'.format(name, e))
+        else:
+          raise ParseError(str(e))
+      except ValueError as e:
+        raise ParseError('Failed to parse {0} field: {1}.'.format(name, e))
+      except TypeError as e:
+        raise ParseError('Failed to parse {0} field: {1}.'.format(name, e))
+
+  def _ConvertAnyMessage(self, value, message):
+    """Convert a JSON representation into Any message."""
+    if isinstance(value, dict) and not value:
+      return
+    try:
+      type_url = value['@type']
+    except KeyError:
+      raise ParseError('@type is missing when parsing any message.')
+
+    sub_message = _CreateMessageFromTypeUrl(type_url)
+    message_descriptor = sub_message.DESCRIPTOR
+    full_name = message_descriptor.full_name
+    if _IsWrapperMessage(message_descriptor):
+      self._ConvertWrapperMessage(value['value'], sub_message)
+    elif full_name in _WKTJSONMETHODS:
+      methodcaller(
+          _WKTJSONMETHODS[full_name][1], value['value'], sub_message)(self)
+    else:
+      del value['@type']
+      self._ConvertFieldValuePair(value, sub_message)
+    # Sets Any message
+    message.value = sub_message.SerializeToString()
+    message.type_url = type_url
+
+  def _ConvertGenericMessage(self, value, message):
+    """Convert a JSON representation into message with FromJsonString."""
+    # Durantion, Timestamp, FieldMask have FromJsonString method to do the
+    # convert. Users can also call the method directly.
+    message.FromJsonString(value)
+
+  def _ConvertValueMessage(self, value, message):
+    """Convert a JSON representation into Value message."""
+    if isinstance(value, dict):
+      self._ConvertStructMessage(value, message.struct_value)
+    elif isinstance(value, list):
+      self. _ConvertListValueMessage(value, message.list_value)
+    elif value is None:
+      message.null_value = 0
+    elif isinstance(value, bool):
+      message.bool_value = value
+    elif isinstance(value, six.string_types):
+      message.string_value = value
+    elif isinstance(value, _INT_OR_FLOAT):
+      message.number_value = value
+    else:
+      raise ParseError('Unexpected type for Value message.')
+
+  def _ConvertListValueMessage(self, value, message):
+    """Convert a JSON representation into ListValue message."""
+    if not isinstance(value, list):
+      raise ParseError(
+          'ListValue must be in [] which is {0}.'.format(value))
+    message.ClearField('values')
+    for item in value:
+      self._ConvertValueMessage(item, message.values.add())
+
+  def _ConvertStructMessage(self, value, message):
+    """Convert a JSON representation into Struct message."""
+    if not isinstance(value, dict):
+      raise ParseError(
+          'Struct must be in a dict which is {0}.'.format(value))
+    for key in value:
+      self._ConvertValueMessage(value[key], message.fields[key])
+    return
+
+  def _ConvertWrapperMessage(self, value, message):
+    """Convert a JSON representation into Wrapper message."""
+    field = message.DESCRIPTOR.fields_by_name['value']
+    setattr(message, 'value', _ConvertScalarFieldValue(value, field))
+
+  def _ConvertMapFieldValue(self, value, message, field):
+    """Convert map field value for a message map field.
+
+    Args:
+      value: A JSON object to convert the map field value.
+      message: A protocol message to record the converted data.
+      field: The descriptor of the map field to be converted.
+
+    Raises:
+      ParseError: In case of convert problems.
+    """
+    if not isinstance(value, dict):
+      raise ParseError(
+          'Map field {0} must be in a dict which is {1}.'.format(
+              field.name, value))
+    key_field = field.message_type.fields_by_name['key']
+    value_field = field.message_type.fields_by_name['value']
+    for key in value:
+      key_value = _ConvertScalarFieldValue(key, key_field, True)
+      if value_field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+        self.ConvertMessage(value[key], getattr(
+            message, field.name)[key_value])
+      else:
+        getattr(message, field.name)[key_value] = _ConvertScalarFieldValue(
+            value[key], value_field)
+
+
+def _ConvertScalarFieldValue(value, field, require_str=False):
+  """Convert a single scalar field value.
+
+  Args:
+    value: A scalar value to convert the scalar field value.
+    field: The descriptor of the field to convert.
+    require_str: If True, the field value must be a str.
+
+  Returns:
+    The converted scalar field value
+
+  Raises:
+    ParseError: In case of convert problems.
+  """
+  if field.cpp_type in _INT_TYPES:
+    return _ConvertInteger(value)
+  elif field.cpp_type in _FLOAT_TYPES:
+    return _ConvertFloat(value)
+  elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL:
+    return _ConvertBool(value, require_str)
+  elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING:
+    if field.type == descriptor.FieldDescriptor.TYPE_BYTES:
+      return base64.b64decode(value)
+    else:
+      # Checking for unpaired surrogates appears to be unreliable,
+      # depending on the specific Python version, so we check manually.
+      if _UNPAIRED_SURROGATE_PATTERN.search(value):
+        raise ParseError('Unpaired surrogate')
+      return value
+  elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
+    # Convert an enum value.
+    enum_value = field.enum_type.values_by_name.get(value, None)
+    if enum_value is None:
+      raise ParseError(
+          'Enum value must be a string literal with double quotes. '
+          'Type "{0}" has no value named {1}.'.format(
+              field.enum_type.full_name, value))
+    return enum_value.number
+
+
+def _ConvertInteger(value):
+  """Convert an integer.
+
+  Args:
+    value: A scalar value to convert.
+
+  Returns:
+    The integer value.
+
+  Raises:
+    ParseError: If an integer couldn't be consumed.
+  """
+  if isinstance(value, float):
+    raise ParseError('Couldn\'t parse integer: {0}.'.format(value))
+
+  if isinstance(value, six.text_type) and value.find(' ') != -1:
+    raise ParseError('Couldn\'t parse integer: "{0}".'.format(value))
+
+  return int(value)
+
+
+def _ConvertFloat(value):
+  """Convert an floating point number."""
+  if value == 'nan':
+    raise ParseError('Couldn\'t parse float "nan", use "NaN" instead.')
+  try:
+    # Assume Python compatible syntax.
+    return float(value)
+  except ValueError:
+    # Check alternative spellings.
+    if value == _NEG_INFINITY:
+      return float('-inf')
+    elif value == _INFINITY:
+      return float('inf')
+    elif value == _NAN:
+      return float('nan')
+    else:
+      raise ParseError('Couldn\'t parse float: {0}.'.format(value))
+
+
+def _ConvertBool(value, require_str):
+  """Convert a boolean value.
+
+  Args:
+    value: A scalar value to convert.
+    require_str: If True, value must be a str.
+
+  Returns:
+    The bool parsed.
+
+  Raises:
+    ParseError: If a boolean value couldn't be consumed.
+  """
+  if require_str:
+    if value == 'true':
+      return True
+    elif value == 'false':
+      return False
+    else:
+      raise ParseError('Expected "true" or "false", not {0}.'.format(value))
+
+  if not isinstance(value, bool):
+    raise ParseError('Expected true or false without quotes.')
+  return value
+
+_WKTJSONMETHODS = {
+    'google.protobuf.Any': ['_AnyMessageToJsonObject',
+                            '_ConvertAnyMessage'],
+    'google.protobuf.Duration': ['_GenericMessageToJsonObject',
+                                 '_ConvertGenericMessage'],
+    'google.protobuf.FieldMask': ['_GenericMessageToJsonObject',
+                                  '_ConvertGenericMessage'],
+    'google.protobuf.ListValue': ['_ListValueMessageToJsonObject',
+                                  '_ConvertListValueMessage'],
+    'google.protobuf.Struct': ['_StructMessageToJsonObject',
+                               '_ConvertStructMessage'],
+    'google.protobuf.Timestamp': ['_GenericMessageToJsonObject',
+                                  '_ConvertGenericMessage'],
+    'google.protobuf.Value': ['_ValueMessageToJsonObject',
+                              '_ConvertValueMessage']
+}
diff --git a/generator/google/protobuf/map_unittest_pb2.py b/generator/google/protobuf/map_unittest_pb2.py
new file mode 100644
index 0000000..a9384f7
--- /dev/null
+++ b/generator/google/protobuf/map_unittest_pb2.py
@@ -0,0 +1,2801 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/map_unittest.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import unittest_pb2 as google_dot_protobuf_dot_unittest__pb2
+from google.protobuf import unittest_no_arena_pb2 as google_dot_protobuf_dot_unittest__no__arena__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/map_unittest.proto',
+  package='protobuf_unittest',
+  syntax='proto3',
+  serialized_pb=_b('\n\"google/protobuf/map_unittest.proto\x12\x11protobuf_unittest\x1a\x1egoogle/protobuf/unittest.proto\x1a\'google/protobuf/unittest_no_arena.proto\"\xd6\x13\n\x07TestMap\x12\x46\n\x0fmap_int32_int32\x18\x01 \x03(\x0b\x32-.protobuf_unittest.TestMap.MapInt32Int32Entry\x12\x46\n\x0fmap_int64_int64\x18\x02 \x03(\x0b\x32-.protobuf_unittest.TestMap.MapInt64Int64Entry\x12J\n\x11map_uint32_uint32\x18\x03 \x03(\x0b\x32/.protobuf_unittest.TestMap.MapUint32Uint32Entry\x12J\n\x11map_uint64_uint64\x18\x04 \x03(\x0b\x32/.protobuf_unittest.TestMap.MapUint64Uint64Entry\x12J\n\x11map_sint32_sint32\x18\x05 \x03(\x0b\x32/.protobuf_unittest.TestMap.MapSint32Sint32Entry\x12J\n\x11map_sint64_sint64\x18\x06 \x03(\x0b\x32/.protobuf_unittest.TestMap.MapSint64Sint64Entry\x12N\n\x13map_fixed32_fixed32\x18\x07 \x03(\x0b\x32\x31.protobuf_unittest.TestMap.MapFixed32Fixed32Entry\x12N\n\x13map_fixed64_fixed64\x18\x08 \x03(\x0b\x32\x31.protobuf_unittest.TestMap.MapFixed64Fixed64Entry\x12R\n\x15map_sfixed32_sfixed32\x18\t \x03(\x0b\x32\x33.protobuf_unittest.TestMap.MapSfixed32Sfixed32Entry\x12R\n\x15map_sfixed64_sfixed64\x18\n \x03(\x0b\x32\x33.protobuf_unittest.TestMap.MapSfixed64Sfixed64Entry\x12\x46\n\x0fmap_int32_float\x18\x0b \x03(\x0b\x32-.protobuf_unittest.TestMap.MapInt32FloatEntry\x12H\n\x10map_int32_double\x18\x0c \x03(\x0b\x32..protobuf_unittest.TestMap.MapInt32DoubleEntry\x12\x42\n\rmap_bool_bool\x18\r \x03(\x0b\x32+.protobuf_unittest.TestMap.MapBoolBoolEntry\x12J\n\x11map_string_string\x18\x0e \x03(\x0b\x32/.protobuf_unittest.TestMap.MapStringStringEntry\x12\x46\n\x0fmap_int32_bytes\x18\x0f \x03(\x0b\x32-.protobuf_unittest.TestMap.MapInt32BytesEntry\x12\x44\n\x0emap_int32_enum\x18\x10 \x03(\x0b\x32,.protobuf_unittest.TestMap.MapInt32EnumEntry\x12Y\n\x19map_int32_foreign_message\x18\x11 \x03(\x0b\x32\x36.protobuf_unittest.TestMap.MapInt32ForeignMessageEntry\x12[\n\x1amap_string_foreign_message\x18\x12 \x03(\x0b\x32\x37.protobuf_unittest.TestMap.MapStringForeignMessageEntry\x1a\x34\n\x12MapInt32Int32Entry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x34\n\x12MapInt64Int64Entry\x12\x0b\n\x03key\x18\x01 \x01(\x03\x12\r\n\x05value\x18\x02 \x01(\x03:\x02\x38\x01\x1a\x36\n\x14MapUint32Uint32Entry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12\r\n\x05value\x18\x02 \x01(\r:\x02\x38\x01\x1a\x36\n\x14MapUint64Uint64Entry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\x04:\x02\x38\x01\x1a\x36\n\x14MapSint32Sint32Entry\x12\x0b\n\x03key\x18\x01 \x01(\x11\x12\r\n\x05value\x18\x02 \x01(\x11:\x02\x38\x01\x1a\x36\n\x14MapSint64Sint64Entry\x12\x0b\n\x03key\x18\x01 \x01(\x12\x12\r\n\x05value\x18\x02 \x01(\x12:\x02\x38\x01\x1a\x38\n\x16MapFixed32Fixed32Entry\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05value\x18\x02 \x01(\x07:\x02\x38\x01\x1a\x38\n\x16MapFixed64Fixed64Entry\x12\x0b\n\x03key\x18\x01 \x01(\x06\x12\r\n\x05value\x18\x02 \x01(\x06:\x02\x38\x01\x1a:\n\x18MapSfixed32Sfixed32Entry\x12\x0b\n\x03key\x18\x01 \x01(\x0f\x12\r\n\x05value\x18\x02 \x01(\x0f:\x02\x38\x01\x1a:\n\x18MapSfixed64Sfixed64Entry\x12\x0b\n\x03key\x18\x01 \x01(\x10\x12\r\n\x05value\x18\x02 \x01(\x10:\x02\x38\x01\x1a\x34\n\x12MapInt32FloatEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x02:\x02\x38\x01\x1a\x35\n\x13MapInt32DoubleEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x01:\x02\x38\x01\x1a\x32\n\x10MapBoolBoolEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x08:\x02\x38\x01\x1a\x36\n\x14MapStringStringEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x34\n\x12MapInt32BytesEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\x1aO\n\x11MapInt32EnumEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12)\n\x05value\x18\x02 \x01(\x0e\x32\x1a.protobuf_unittest.MapEnum:\x02\x38\x01\x1a`\n\x1bMapInt32ForeignMessageEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\x30\n\x05value\x18\x02 \x01(\x0b\x32!.protobuf_unittest.ForeignMessage:\x02\x38\x01\x1a\x61\n\x1cMapStringForeignMessageEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x30\n\x05value\x18\x02 \x01(\x0b\x32!.protobuf_unittest.ForeignMessage:\x02\x38\x01\"A\n\x11TestMapSubmessage\x12,\n\x08test_map\x18\x01 \x01(\x0b\x32\x1a.protobuf_unittest.TestMap\"\xbc\x01\n\x0eTestMessageMap\x12Q\n\x11map_int32_message\x18\x01 \x03(\x0b\x32\x36.protobuf_unittest.TestMessageMap.MapInt32MessageEntry\x1aW\n\x14MapInt32MessageEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.protobuf_unittest.TestAllTypes:\x02\x38\x01\"\xe3\x01\n\x0fTestSameTypeMap\x12:\n\x04map1\x18\x01 \x03(\x0b\x32,.protobuf_unittest.TestSameTypeMap.Map1Entry\x12:\n\x04map2\x18\x02 \x03(\x0b\x32,.protobuf_unittest.TestSameTypeMap.Map2Entry\x1a+\n\tMap1Entry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a+\n\tMap2Entry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"\xb6\x01\n\x16TestRequiredMessageMap\x12J\n\tmap_field\x18\x01 \x03(\x0b\x32\x37.protobuf_unittest.TestRequiredMessageMap.MapFieldEntry\x1aP\n\rMapFieldEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.protobuf_unittest.TestRequired:\x02\x38\x01\"\xd2\x14\n\x0cTestArenaMap\x12K\n\x0fmap_int32_int32\x18\x01 \x03(\x0b\x32\x32.protobuf_unittest.TestArenaMap.MapInt32Int32Entry\x12K\n\x0fmap_int64_int64\x18\x02 \x03(\x0b\x32\x32.protobuf_unittest.TestArenaMap.MapInt64Int64Entry\x12O\n\x11map_uint32_uint32\x18\x03 \x03(\x0b\x32\x34.protobuf_unittest.TestArenaMap.MapUint32Uint32Entry\x12O\n\x11map_uint64_uint64\x18\x04 \x03(\x0b\x32\x34.protobuf_unittest.TestArenaMap.MapUint64Uint64Entry\x12O\n\x11map_sint32_sint32\x18\x05 \x03(\x0b\x32\x34.protobuf_unittest.TestArenaMap.MapSint32Sint32Entry\x12O\n\x11map_sint64_sint64\x18\x06 \x03(\x0b\x32\x34.protobuf_unittest.TestArenaMap.MapSint64Sint64Entry\x12S\n\x13map_fixed32_fixed32\x18\x07 \x03(\x0b\x32\x36.protobuf_unittest.TestArenaMap.MapFixed32Fixed32Entry\x12S\n\x13map_fixed64_fixed64\x18\x08 \x03(\x0b\x32\x36.protobuf_unittest.TestArenaMap.MapFixed64Fixed64Entry\x12W\n\x15map_sfixed32_sfixed32\x18\t \x03(\x0b\x32\x38.protobuf_unittest.TestArenaMap.MapSfixed32Sfixed32Entry\x12W\n\x15map_sfixed64_sfixed64\x18\n \x03(\x0b\x32\x38.protobuf_unittest.TestArenaMap.MapSfixed64Sfixed64Entry\x12K\n\x0fmap_int32_float\x18\x0b \x03(\x0b\x32\x32.protobuf_unittest.TestArenaMap.MapInt32FloatEntry\x12M\n\x10map_int32_double\x18\x0c \x03(\x0b\x32\x33.protobuf_unittest.TestArenaMap.MapInt32DoubleEntry\x12G\n\rmap_bool_bool\x18\r \x03(\x0b\x32\x30.protobuf_unittest.TestArenaMap.MapBoolBoolEntry\x12O\n\x11map_string_string\x18\x0e \x03(\x0b\x32\x34.protobuf_unittest.TestArenaMap.MapStringStringEntry\x12K\n\x0fmap_int32_bytes\x18\x0f \x03(\x0b\x32\x32.protobuf_unittest.TestArenaMap.MapInt32BytesEntry\x12I\n\x0emap_int32_enum\x18\x10 \x03(\x0b\x32\x31.protobuf_unittest.TestArenaMap.MapInt32EnumEntry\x12^\n\x19map_int32_foreign_message\x18\x11 \x03(\x0b\x32;.protobuf_unittest.TestArenaMap.MapInt32ForeignMessageEntry\x12n\n\"map_int32_foreign_message_no_arena\x18\x12 \x03(\x0b\x32\x42.protobuf_unittest.TestArenaMap.MapInt32ForeignMessageNoArenaEntry\x1a\x34\n\x12MapInt32Int32Entry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x34\n\x12MapInt64Int64Entry\x12\x0b\n\x03key\x18\x01 \x01(\x03\x12\r\n\x05value\x18\x02 \x01(\x03:\x02\x38\x01\x1a\x36\n\x14MapUint32Uint32Entry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12\r\n\x05value\x18\x02 \x01(\r:\x02\x38\x01\x1a\x36\n\x14MapUint64Uint64Entry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\x04:\x02\x38\x01\x1a\x36\n\x14MapSint32Sint32Entry\x12\x0b\n\x03key\x18\x01 \x01(\x11\x12\r\n\x05value\x18\x02 \x01(\x11:\x02\x38\x01\x1a\x36\n\x14MapSint64Sint64Entry\x12\x0b\n\x03key\x18\x01 \x01(\x12\x12\r\n\x05value\x18\x02 \x01(\x12:\x02\x38\x01\x1a\x38\n\x16MapFixed32Fixed32Entry\x12\x0b\n\x03key\x18\x01 \x01(\x07\x12\r\n\x05value\x18\x02 \x01(\x07:\x02\x38\x01\x1a\x38\n\x16MapFixed64Fixed64Entry\x12\x0b\n\x03key\x18\x01 \x01(\x06\x12\r\n\x05value\x18\x02 \x01(\x06:\x02\x38\x01\x1a:\n\x18MapSfixed32Sfixed32Entry\x12\x0b\n\x03key\x18\x01 \x01(\x0f\x12\r\n\x05value\x18\x02 \x01(\x0f:\x02\x38\x01\x1a:\n\x18MapSfixed64Sfixed64Entry\x12\x0b\n\x03key\x18\x01 \x01(\x10\x12\r\n\x05value\x18\x02 \x01(\x10:\x02\x38\x01\x1a\x34\n\x12MapInt32FloatEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x02:\x02\x38\x01\x1a\x35\n\x13MapInt32DoubleEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x01:\x02\x38\x01\x1a\x32\n\x10MapBoolBoolEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x08:\x02\x38\x01\x1a\x36\n\x14MapStringStringEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x34\n\x12MapInt32BytesEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\x1aO\n\x11MapInt32EnumEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12)\n\x05value\x18\x02 \x01(\x0e\x32\x1a.protobuf_unittest.MapEnum:\x02\x38\x01\x1a`\n\x1bMapInt32ForeignMessageEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\x30\n\x05value\x18\x02 \x01(\x0b\x32!.protobuf_unittest.ForeignMessage:\x02\x38\x01\x1ap\n\"MapInt32ForeignMessageNoArenaEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\x39\n\x05value\x18\x02 \x01(\x0b\x32*.protobuf_unittest_no_arena.ForeignMessage:\x02\x38\x01\"\xe4\x01\n\x1fMessageContainingEnumCalledType\x12J\n\x04type\x18\x01 \x03(\x0b\x32<.protobuf_unittest.MessageContainingEnumCalledType.TypeEntry\x1a_\n\tTypeEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x41\n\x05value\x18\x02 \x01(\x0b\x32\x32.protobuf_unittest.MessageContainingEnumCalledType:\x02\x38\x01\"\x14\n\x04Type\x12\x0c\n\x08TYPE_FOO\x10\x00\"\x9d\x01\n\x1fMessageContainingMapCalledEntry\x12L\n\x05\x65ntry\x18\x01 \x03(\x0b\x32=.protobuf_unittest.MessageContainingMapCalledEntry.EntryEntry\x1a,\n\nEntryEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"\xad\x01\n\x17TestRecursiveMapMessage\x12<\n\x01\x61\x18\x01 \x03(\x0b\x32\x31.protobuf_unittest.TestRecursiveMapMessage.AEntry\x1aT\n\x06\x41\x45ntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x39\n\x05value\x18\x02 \x01(\x0b\x32*.protobuf_unittest.TestRecursiveMapMessage:\x02\x38\x01*?\n\x07MapEnum\x12\x10\n\x0cMAP_ENUM_FOO\x10\x00\x12\x10\n\x0cMAP_ENUM_BAR\x10\x01\x12\x10\n\x0cMAP_ENUM_BAZ\x10\x02\x42\x03\xf8\x01\x01\x62\x06proto3')
+  ,
+  dependencies=[google_dot_protobuf_dot_unittest__pb2.DESCRIPTOR,google_dot_protobuf_dot_unittest__no__arena__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+_MAPENUM = _descriptor.EnumDescriptor(
+  name='MapEnum',
+  full_name='protobuf_unittest.MapEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='MAP_ENUM_FOO', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='MAP_ENUM_BAR', index=1, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='MAP_ENUM_BAZ', index=2, number=2,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=6536,
+  serialized_end=6599,
+)
+_sym_db.RegisterEnumDescriptor(_MAPENUM)
+
+MapEnum = enum_type_wrapper.EnumTypeWrapper(_MAPENUM)
+MAP_ENUM_FOO = 0
+MAP_ENUM_BAR = 1
+MAP_ENUM_BAZ = 2
+
+
+_MESSAGECONTAININGENUMCALLEDTYPE_TYPE = _descriptor.EnumDescriptor(
+  name='Type',
+  full_name='protobuf_unittest.MessageContainingEnumCalledType.Type',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_FOO', index=0, number=0,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=6178,
+  serialized_end=6198,
+)
+_sym_db.RegisterEnumDescriptor(_MESSAGECONTAININGENUMCALLEDTYPE_TYPE)
+
+
+_TESTMAP_MAPINT32INT32ENTRY = _descriptor.Descriptor(
+  name='MapInt32Int32Entry',
+  full_name='protobuf_unittest.TestMap.MapInt32Int32Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapInt32Int32Entry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapInt32Int32Entry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1534,
+  serialized_end=1586,
+)
+
+_TESTMAP_MAPINT64INT64ENTRY = _descriptor.Descriptor(
+  name='MapInt64Int64Entry',
+  full_name='protobuf_unittest.TestMap.MapInt64Int64Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapInt64Int64Entry.key', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapInt64Int64Entry.value', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1588,
+  serialized_end=1640,
+)
+
+_TESTMAP_MAPUINT32UINT32ENTRY = _descriptor.Descriptor(
+  name='MapUint32Uint32Entry',
+  full_name='protobuf_unittest.TestMap.MapUint32Uint32Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapUint32Uint32Entry.key', index=0,
+      number=1, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapUint32Uint32Entry.value', index=1,
+      number=2, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1642,
+  serialized_end=1696,
+)
+
+_TESTMAP_MAPUINT64UINT64ENTRY = _descriptor.Descriptor(
+  name='MapUint64Uint64Entry',
+  full_name='protobuf_unittest.TestMap.MapUint64Uint64Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapUint64Uint64Entry.key', index=0,
+      number=1, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapUint64Uint64Entry.value', index=1,
+      number=2, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1698,
+  serialized_end=1752,
+)
+
+_TESTMAP_MAPSINT32SINT32ENTRY = _descriptor.Descriptor(
+  name='MapSint32Sint32Entry',
+  full_name='protobuf_unittest.TestMap.MapSint32Sint32Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapSint32Sint32Entry.key', index=0,
+      number=1, type=17, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapSint32Sint32Entry.value', index=1,
+      number=2, type=17, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1754,
+  serialized_end=1808,
+)
+
+_TESTMAP_MAPSINT64SINT64ENTRY = _descriptor.Descriptor(
+  name='MapSint64Sint64Entry',
+  full_name='protobuf_unittest.TestMap.MapSint64Sint64Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapSint64Sint64Entry.key', index=0,
+      number=1, type=18, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapSint64Sint64Entry.value', index=1,
+      number=2, type=18, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1810,
+  serialized_end=1864,
+)
+
+_TESTMAP_MAPFIXED32FIXED32ENTRY = _descriptor.Descriptor(
+  name='MapFixed32Fixed32Entry',
+  full_name='protobuf_unittest.TestMap.MapFixed32Fixed32Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapFixed32Fixed32Entry.key', index=0,
+      number=1, type=7, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapFixed32Fixed32Entry.value', index=1,
+      number=2, type=7, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1866,
+  serialized_end=1922,
+)
+
+_TESTMAP_MAPFIXED64FIXED64ENTRY = _descriptor.Descriptor(
+  name='MapFixed64Fixed64Entry',
+  full_name='protobuf_unittest.TestMap.MapFixed64Fixed64Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapFixed64Fixed64Entry.key', index=0,
+      number=1, type=6, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapFixed64Fixed64Entry.value', index=1,
+      number=2, type=6, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1924,
+  serialized_end=1980,
+)
+
+_TESTMAP_MAPSFIXED32SFIXED32ENTRY = _descriptor.Descriptor(
+  name='MapSfixed32Sfixed32Entry',
+  full_name='protobuf_unittest.TestMap.MapSfixed32Sfixed32Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapSfixed32Sfixed32Entry.key', index=0,
+      number=1, type=15, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapSfixed32Sfixed32Entry.value', index=1,
+      number=2, type=15, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1982,
+  serialized_end=2040,
+)
+
+_TESTMAP_MAPSFIXED64SFIXED64ENTRY = _descriptor.Descriptor(
+  name='MapSfixed64Sfixed64Entry',
+  full_name='protobuf_unittest.TestMap.MapSfixed64Sfixed64Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapSfixed64Sfixed64Entry.key', index=0,
+      number=1, type=16, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapSfixed64Sfixed64Entry.value', index=1,
+      number=2, type=16, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2042,
+  serialized_end=2100,
+)
+
+_TESTMAP_MAPINT32FLOATENTRY = _descriptor.Descriptor(
+  name='MapInt32FloatEntry',
+  full_name='protobuf_unittest.TestMap.MapInt32FloatEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapInt32FloatEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapInt32FloatEntry.value', index=1,
+      number=2, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2102,
+  serialized_end=2154,
+)
+
+_TESTMAP_MAPINT32DOUBLEENTRY = _descriptor.Descriptor(
+  name='MapInt32DoubleEntry',
+  full_name='protobuf_unittest.TestMap.MapInt32DoubleEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapInt32DoubleEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapInt32DoubleEntry.value', index=1,
+      number=2, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2156,
+  serialized_end=2209,
+)
+
+_TESTMAP_MAPBOOLBOOLENTRY = _descriptor.Descriptor(
+  name='MapBoolBoolEntry',
+  full_name='protobuf_unittest.TestMap.MapBoolBoolEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapBoolBoolEntry.key', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapBoolBoolEntry.value', index=1,
+      number=2, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2211,
+  serialized_end=2261,
+)
+
+_TESTMAP_MAPSTRINGSTRINGENTRY = _descriptor.Descriptor(
+  name='MapStringStringEntry',
+  full_name='protobuf_unittest.TestMap.MapStringStringEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapStringStringEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapStringStringEntry.value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2263,
+  serialized_end=2317,
+)
+
+_TESTMAP_MAPINT32BYTESENTRY = _descriptor.Descriptor(
+  name='MapInt32BytesEntry',
+  full_name='protobuf_unittest.TestMap.MapInt32BytesEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapInt32BytesEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapInt32BytesEntry.value', index=1,
+      number=2, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2319,
+  serialized_end=2371,
+)
+
+_TESTMAP_MAPINT32ENUMENTRY = _descriptor.Descriptor(
+  name='MapInt32EnumEntry',
+  full_name='protobuf_unittest.TestMap.MapInt32EnumEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapInt32EnumEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapInt32EnumEntry.value', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2373,
+  serialized_end=2452,
+)
+
+_TESTMAP_MAPINT32FOREIGNMESSAGEENTRY = _descriptor.Descriptor(
+  name='MapInt32ForeignMessageEntry',
+  full_name='protobuf_unittest.TestMap.MapInt32ForeignMessageEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapInt32ForeignMessageEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapInt32ForeignMessageEntry.value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2454,
+  serialized_end=2550,
+)
+
+_TESTMAP_MAPSTRINGFOREIGNMESSAGEENTRY = _descriptor.Descriptor(
+  name='MapStringForeignMessageEntry',
+  full_name='protobuf_unittest.TestMap.MapStringForeignMessageEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMap.MapStringForeignMessageEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMap.MapStringForeignMessageEntry.value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2552,
+  serialized_end=2649,
+)
+
+_TESTMAP = _descriptor.Descriptor(
+  name='TestMap',
+  full_name='protobuf_unittest.TestMap',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='map_int32_int32', full_name='protobuf_unittest.TestMap.map_int32_int32', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_int64_int64', full_name='protobuf_unittest.TestMap.map_int64_int64', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_uint32_uint32', full_name='protobuf_unittest.TestMap.map_uint32_uint32', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_uint64_uint64', full_name='protobuf_unittest.TestMap.map_uint64_uint64', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_sint32_sint32', full_name='protobuf_unittest.TestMap.map_sint32_sint32', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_sint64_sint64', full_name='protobuf_unittest.TestMap.map_sint64_sint64', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_fixed32_fixed32', full_name='protobuf_unittest.TestMap.map_fixed32_fixed32', index=6,
+      number=7, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_fixed64_fixed64', full_name='protobuf_unittest.TestMap.map_fixed64_fixed64', index=7,
+      number=8, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_sfixed32_sfixed32', full_name='protobuf_unittest.TestMap.map_sfixed32_sfixed32', index=8,
+      number=9, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_sfixed64_sfixed64', full_name='protobuf_unittest.TestMap.map_sfixed64_sfixed64', index=9,
+      number=10, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_int32_float', full_name='protobuf_unittest.TestMap.map_int32_float', index=10,
+      number=11, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_int32_double', full_name='protobuf_unittest.TestMap.map_int32_double', index=11,
+      number=12, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_bool_bool', full_name='protobuf_unittest.TestMap.map_bool_bool', index=12,
+      number=13, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_string_string', full_name='protobuf_unittest.TestMap.map_string_string', index=13,
+      number=14, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_int32_bytes', full_name='protobuf_unittest.TestMap.map_int32_bytes', index=14,
+      number=15, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_int32_enum', full_name='protobuf_unittest.TestMap.map_int32_enum', index=15,
+      number=16, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_int32_foreign_message', full_name='protobuf_unittest.TestMap.map_int32_foreign_message', index=16,
+      number=17, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_string_foreign_message', full_name='protobuf_unittest.TestMap.map_string_foreign_message', index=17,
+      number=18, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTMAP_MAPINT32INT32ENTRY, _TESTMAP_MAPINT64INT64ENTRY, _TESTMAP_MAPUINT32UINT32ENTRY, _TESTMAP_MAPUINT64UINT64ENTRY, _TESTMAP_MAPSINT32SINT32ENTRY, _TESTMAP_MAPSINT64SINT64ENTRY, _TESTMAP_MAPFIXED32FIXED32ENTRY, _TESTMAP_MAPFIXED64FIXED64ENTRY, _TESTMAP_MAPSFIXED32SFIXED32ENTRY, _TESTMAP_MAPSFIXED64SFIXED64ENTRY, _TESTMAP_MAPINT32FLOATENTRY, _TESTMAP_MAPINT32DOUBLEENTRY, _TESTMAP_MAPBOOLBOOLENTRY, _TESTMAP_MAPSTRINGSTRINGENTRY, _TESTMAP_MAPINT32BYTESENTRY, _TESTMAP_MAPINT32ENUMENTRY, _TESTMAP_MAPINT32FOREIGNMESSAGEENTRY, _TESTMAP_MAPSTRINGFOREIGNMESSAGEENTRY, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=131,
+  serialized_end=2649,
+)
+
+
+_TESTMAPSUBMESSAGE = _descriptor.Descriptor(
+  name='TestMapSubmessage',
+  full_name='protobuf_unittest.TestMapSubmessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='test_map', full_name='protobuf_unittest.TestMapSubmessage.test_map', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2651,
+  serialized_end=2716,
+)
+
+
+_TESTMESSAGEMAP_MAPINT32MESSAGEENTRY = _descriptor.Descriptor(
+  name='MapInt32MessageEntry',
+  full_name='protobuf_unittest.TestMessageMap.MapInt32MessageEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestMessageMap.MapInt32MessageEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestMessageMap.MapInt32MessageEntry.value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2820,
+  serialized_end=2907,
+)
+
+_TESTMESSAGEMAP = _descriptor.Descriptor(
+  name='TestMessageMap',
+  full_name='protobuf_unittest.TestMessageMap',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='map_int32_message', full_name='protobuf_unittest.TestMessageMap.map_int32_message', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTMESSAGEMAP_MAPINT32MESSAGEENTRY, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2719,
+  serialized_end=2907,
+)
+
+
+_TESTSAMETYPEMAP_MAP1ENTRY = _descriptor.Descriptor(
+  name='Map1Entry',
+  full_name='protobuf_unittest.TestSameTypeMap.Map1Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestSameTypeMap.Map1Entry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestSameTypeMap.Map1Entry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3049,
+  serialized_end=3092,
+)
+
+_TESTSAMETYPEMAP_MAP2ENTRY = _descriptor.Descriptor(
+  name='Map2Entry',
+  full_name='protobuf_unittest.TestSameTypeMap.Map2Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestSameTypeMap.Map2Entry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestSameTypeMap.Map2Entry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3094,
+  serialized_end=3137,
+)
+
+_TESTSAMETYPEMAP = _descriptor.Descriptor(
+  name='TestSameTypeMap',
+  full_name='protobuf_unittest.TestSameTypeMap',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='map1', full_name='protobuf_unittest.TestSameTypeMap.map1', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map2', full_name='protobuf_unittest.TestSameTypeMap.map2', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTSAMETYPEMAP_MAP1ENTRY, _TESTSAMETYPEMAP_MAP2ENTRY, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2910,
+  serialized_end=3137,
+)
+
+
+_TESTREQUIREDMESSAGEMAP_MAPFIELDENTRY = _descriptor.Descriptor(
+  name='MapFieldEntry',
+  full_name='protobuf_unittest.TestRequiredMessageMap.MapFieldEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestRequiredMessageMap.MapFieldEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestRequiredMessageMap.MapFieldEntry.value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3242,
+  serialized_end=3322,
+)
+
+_TESTREQUIREDMESSAGEMAP = _descriptor.Descriptor(
+  name='TestRequiredMessageMap',
+  full_name='protobuf_unittest.TestRequiredMessageMap',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='map_field', full_name='protobuf_unittest.TestRequiredMessageMap.map_field', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTREQUIREDMESSAGEMAP_MAPFIELDENTRY, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3140,
+  serialized_end=3322,
+)
+
+
+_TESTARENAMAP_MAPINT32INT32ENTRY = _descriptor.Descriptor(
+  name='MapInt32Int32Entry',
+  full_name='protobuf_unittest.TestArenaMap.MapInt32Int32Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapInt32Int32Entry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapInt32Int32Entry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1534,
+  serialized_end=1586,
+)
+
+_TESTARENAMAP_MAPINT64INT64ENTRY = _descriptor.Descriptor(
+  name='MapInt64Int64Entry',
+  full_name='protobuf_unittest.TestArenaMap.MapInt64Int64Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapInt64Int64Entry.key', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapInt64Int64Entry.value', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1588,
+  serialized_end=1640,
+)
+
+_TESTARENAMAP_MAPUINT32UINT32ENTRY = _descriptor.Descriptor(
+  name='MapUint32Uint32Entry',
+  full_name='protobuf_unittest.TestArenaMap.MapUint32Uint32Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapUint32Uint32Entry.key', index=0,
+      number=1, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapUint32Uint32Entry.value', index=1,
+      number=2, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1642,
+  serialized_end=1696,
+)
+
+_TESTARENAMAP_MAPUINT64UINT64ENTRY = _descriptor.Descriptor(
+  name='MapUint64Uint64Entry',
+  full_name='protobuf_unittest.TestArenaMap.MapUint64Uint64Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapUint64Uint64Entry.key', index=0,
+      number=1, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapUint64Uint64Entry.value', index=1,
+      number=2, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1698,
+  serialized_end=1752,
+)
+
+_TESTARENAMAP_MAPSINT32SINT32ENTRY = _descriptor.Descriptor(
+  name='MapSint32Sint32Entry',
+  full_name='protobuf_unittest.TestArenaMap.MapSint32Sint32Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapSint32Sint32Entry.key', index=0,
+      number=1, type=17, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapSint32Sint32Entry.value', index=1,
+      number=2, type=17, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1754,
+  serialized_end=1808,
+)
+
+_TESTARENAMAP_MAPSINT64SINT64ENTRY = _descriptor.Descriptor(
+  name='MapSint64Sint64Entry',
+  full_name='protobuf_unittest.TestArenaMap.MapSint64Sint64Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapSint64Sint64Entry.key', index=0,
+      number=1, type=18, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapSint64Sint64Entry.value', index=1,
+      number=2, type=18, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1810,
+  serialized_end=1864,
+)
+
+_TESTARENAMAP_MAPFIXED32FIXED32ENTRY = _descriptor.Descriptor(
+  name='MapFixed32Fixed32Entry',
+  full_name='protobuf_unittest.TestArenaMap.MapFixed32Fixed32Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapFixed32Fixed32Entry.key', index=0,
+      number=1, type=7, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapFixed32Fixed32Entry.value', index=1,
+      number=2, type=7, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1866,
+  serialized_end=1922,
+)
+
+_TESTARENAMAP_MAPFIXED64FIXED64ENTRY = _descriptor.Descriptor(
+  name='MapFixed64Fixed64Entry',
+  full_name='protobuf_unittest.TestArenaMap.MapFixed64Fixed64Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapFixed64Fixed64Entry.key', index=0,
+      number=1, type=6, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapFixed64Fixed64Entry.value', index=1,
+      number=2, type=6, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1924,
+  serialized_end=1980,
+)
+
+_TESTARENAMAP_MAPSFIXED32SFIXED32ENTRY = _descriptor.Descriptor(
+  name='MapSfixed32Sfixed32Entry',
+  full_name='protobuf_unittest.TestArenaMap.MapSfixed32Sfixed32Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapSfixed32Sfixed32Entry.key', index=0,
+      number=1, type=15, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapSfixed32Sfixed32Entry.value', index=1,
+      number=2, type=15, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1982,
+  serialized_end=2040,
+)
+
+_TESTARENAMAP_MAPSFIXED64SFIXED64ENTRY = _descriptor.Descriptor(
+  name='MapSfixed64Sfixed64Entry',
+  full_name='protobuf_unittest.TestArenaMap.MapSfixed64Sfixed64Entry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapSfixed64Sfixed64Entry.key', index=0,
+      number=1, type=16, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapSfixed64Sfixed64Entry.value', index=1,
+      number=2, type=16, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2042,
+  serialized_end=2100,
+)
+
+_TESTARENAMAP_MAPINT32FLOATENTRY = _descriptor.Descriptor(
+  name='MapInt32FloatEntry',
+  full_name='protobuf_unittest.TestArenaMap.MapInt32FloatEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapInt32FloatEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapInt32FloatEntry.value', index=1,
+      number=2, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2102,
+  serialized_end=2154,
+)
+
+_TESTARENAMAP_MAPINT32DOUBLEENTRY = _descriptor.Descriptor(
+  name='MapInt32DoubleEntry',
+  full_name='protobuf_unittest.TestArenaMap.MapInt32DoubleEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapInt32DoubleEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapInt32DoubleEntry.value', index=1,
+      number=2, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2156,
+  serialized_end=2209,
+)
+
+_TESTARENAMAP_MAPBOOLBOOLENTRY = _descriptor.Descriptor(
+  name='MapBoolBoolEntry',
+  full_name='protobuf_unittest.TestArenaMap.MapBoolBoolEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapBoolBoolEntry.key', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapBoolBoolEntry.value', index=1,
+      number=2, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2211,
+  serialized_end=2261,
+)
+
+_TESTARENAMAP_MAPSTRINGSTRINGENTRY = _descriptor.Descriptor(
+  name='MapStringStringEntry',
+  full_name='protobuf_unittest.TestArenaMap.MapStringStringEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapStringStringEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapStringStringEntry.value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2263,
+  serialized_end=2317,
+)
+
+_TESTARENAMAP_MAPINT32BYTESENTRY = _descriptor.Descriptor(
+  name='MapInt32BytesEntry',
+  full_name='protobuf_unittest.TestArenaMap.MapInt32BytesEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapInt32BytesEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapInt32BytesEntry.value', index=1,
+      number=2, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2319,
+  serialized_end=2371,
+)
+
+_TESTARENAMAP_MAPINT32ENUMENTRY = _descriptor.Descriptor(
+  name='MapInt32EnumEntry',
+  full_name='protobuf_unittest.TestArenaMap.MapInt32EnumEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapInt32EnumEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapInt32EnumEntry.value', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2373,
+  serialized_end=2452,
+)
+
+_TESTARENAMAP_MAPINT32FOREIGNMESSAGEENTRY = _descriptor.Descriptor(
+  name='MapInt32ForeignMessageEntry',
+  full_name='protobuf_unittest.TestArenaMap.MapInt32ForeignMessageEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapInt32ForeignMessageEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapInt32ForeignMessageEntry.value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2454,
+  serialized_end=2550,
+)
+
+_TESTARENAMAP_MAPINT32FOREIGNMESSAGENOARENAENTRY = _descriptor.Descriptor(
+  name='MapInt32ForeignMessageNoArenaEntry',
+  full_name='protobuf_unittest.TestArenaMap.MapInt32ForeignMessageNoArenaEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestArenaMap.MapInt32ForeignMessageNoArenaEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestArenaMap.MapInt32ForeignMessageNoArenaEntry.value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5855,
+  serialized_end=5967,
+)
+
+_TESTARENAMAP = _descriptor.Descriptor(
+  name='TestArenaMap',
+  full_name='protobuf_unittest.TestArenaMap',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='map_int32_int32', full_name='protobuf_unittest.TestArenaMap.map_int32_int32', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_int64_int64', full_name='protobuf_unittest.TestArenaMap.map_int64_int64', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_uint32_uint32', full_name='protobuf_unittest.TestArenaMap.map_uint32_uint32', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_uint64_uint64', full_name='protobuf_unittest.TestArenaMap.map_uint64_uint64', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_sint32_sint32', full_name='protobuf_unittest.TestArenaMap.map_sint32_sint32', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_sint64_sint64', full_name='protobuf_unittest.TestArenaMap.map_sint64_sint64', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_fixed32_fixed32', full_name='protobuf_unittest.TestArenaMap.map_fixed32_fixed32', index=6,
+      number=7, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_fixed64_fixed64', full_name='protobuf_unittest.TestArenaMap.map_fixed64_fixed64', index=7,
+      number=8, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_sfixed32_sfixed32', full_name='protobuf_unittest.TestArenaMap.map_sfixed32_sfixed32', index=8,
+      number=9, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_sfixed64_sfixed64', full_name='protobuf_unittest.TestArenaMap.map_sfixed64_sfixed64', index=9,
+      number=10, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_int32_float', full_name='protobuf_unittest.TestArenaMap.map_int32_float', index=10,
+      number=11, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_int32_double', full_name='protobuf_unittest.TestArenaMap.map_int32_double', index=11,
+      number=12, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_bool_bool', full_name='protobuf_unittest.TestArenaMap.map_bool_bool', index=12,
+      number=13, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_string_string', full_name='protobuf_unittest.TestArenaMap.map_string_string', index=13,
+      number=14, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_int32_bytes', full_name='protobuf_unittest.TestArenaMap.map_int32_bytes', index=14,
+      number=15, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_int32_enum', full_name='protobuf_unittest.TestArenaMap.map_int32_enum', index=15,
+      number=16, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_int32_foreign_message', full_name='protobuf_unittest.TestArenaMap.map_int32_foreign_message', index=16,
+      number=17, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_int32_foreign_message_no_arena', full_name='protobuf_unittest.TestArenaMap.map_int32_foreign_message_no_arena', index=17,
+      number=18, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTARENAMAP_MAPINT32INT32ENTRY, _TESTARENAMAP_MAPINT64INT64ENTRY, _TESTARENAMAP_MAPUINT32UINT32ENTRY, _TESTARENAMAP_MAPUINT64UINT64ENTRY, _TESTARENAMAP_MAPSINT32SINT32ENTRY, _TESTARENAMAP_MAPSINT64SINT64ENTRY, _TESTARENAMAP_MAPFIXED32FIXED32ENTRY, _TESTARENAMAP_MAPFIXED64FIXED64ENTRY, _TESTARENAMAP_MAPSFIXED32SFIXED32ENTRY, _TESTARENAMAP_MAPSFIXED64SFIXED64ENTRY, _TESTARENAMAP_MAPINT32FLOATENTRY, _TESTARENAMAP_MAPINT32DOUBLEENTRY, _TESTARENAMAP_MAPBOOLBOOLENTRY, _TESTARENAMAP_MAPSTRINGSTRINGENTRY, _TESTARENAMAP_MAPINT32BYTESENTRY, _TESTARENAMAP_MAPINT32ENUMENTRY, _TESTARENAMAP_MAPINT32FOREIGNMESSAGEENTRY, _TESTARENAMAP_MAPINT32FOREIGNMESSAGENOARENAENTRY, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3325,
+  serialized_end=5967,
+)
+
+
+_MESSAGECONTAININGENUMCALLEDTYPE_TYPEENTRY = _descriptor.Descriptor(
+  name='TypeEntry',
+  full_name='protobuf_unittest.MessageContainingEnumCalledType.TypeEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.MessageContainingEnumCalledType.TypeEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.MessageContainingEnumCalledType.TypeEntry.value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=6081,
+  serialized_end=6176,
+)
+
+_MESSAGECONTAININGENUMCALLEDTYPE = _descriptor.Descriptor(
+  name='MessageContainingEnumCalledType',
+  full_name='protobuf_unittest.MessageContainingEnumCalledType',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='type', full_name='protobuf_unittest.MessageContainingEnumCalledType.type', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_MESSAGECONTAININGENUMCALLEDTYPE_TYPEENTRY, ],
+  enum_types=[
+    _MESSAGECONTAININGENUMCALLEDTYPE_TYPE,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5970,
+  serialized_end=6198,
+)
+
+
+_MESSAGECONTAININGMAPCALLEDENTRY_ENTRYENTRY = _descriptor.Descriptor(
+  name='EntryEntry',
+  full_name='protobuf_unittest.MessageContainingMapCalledEntry.EntryEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.MessageContainingMapCalledEntry.EntryEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.MessageContainingMapCalledEntry.EntryEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=6314,
+  serialized_end=6358,
+)
+
+_MESSAGECONTAININGMAPCALLEDENTRY = _descriptor.Descriptor(
+  name='MessageContainingMapCalledEntry',
+  full_name='protobuf_unittest.MessageContainingMapCalledEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='entry', full_name='protobuf_unittest.MessageContainingMapCalledEntry.entry', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_MESSAGECONTAININGMAPCALLEDENTRY_ENTRYENTRY, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=6201,
+  serialized_end=6358,
+)
+
+
+_TESTRECURSIVEMAPMESSAGE_AENTRY = _descriptor.Descriptor(
+  name='AEntry',
+  full_name='protobuf_unittest.TestRecursiveMapMessage.AEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='protobuf_unittest.TestRecursiveMapMessage.AEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.TestRecursiveMapMessage.AEntry.value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=6450,
+  serialized_end=6534,
+)
+
+_TESTRECURSIVEMAPMESSAGE = _descriptor.Descriptor(
+  name='TestRecursiveMapMessage',
+  full_name='protobuf_unittest.TestRecursiveMapMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestRecursiveMapMessage.a', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTRECURSIVEMAPMESSAGE_AENTRY, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=6361,
+  serialized_end=6534,
+)
+
+_TESTMAP_MAPINT32INT32ENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPINT64INT64ENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPUINT32UINT32ENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPUINT64UINT64ENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPSINT32SINT32ENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPSINT64SINT64ENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPFIXED32FIXED32ENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPFIXED64FIXED64ENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPSFIXED32SFIXED32ENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPSFIXED64SFIXED64ENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPINT32FLOATENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPINT32DOUBLEENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPBOOLBOOLENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPSTRINGSTRINGENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPINT32BYTESENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPINT32ENUMENTRY.fields_by_name['value'].enum_type = _MAPENUM
+_TESTMAP_MAPINT32ENUMENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPINT32FOREIGNMESSAGEENTRY.fields_by_name['value'].message_type = google_dot_protobuf_dot_unittest__pb2._FOREIGNMESSAGE
+_TESTMAP_MAPINT32FOREIGNMESSAGEENTRY.containing_type = _TESTMAP
+_TESTMAP_MAPSTRINGFOREIGNMESSAGEENTRY.fields_by_name['value'].message_type = google_dot_protobuf_dot_unittest__pb2._FOREIGNMESSAGE
+_TESTMAP_MAPSTRINGFOREIGNMESSAGEENTRY.containing_type = _TESTMAP
+_TESTMAP.fields_by_name['map_int32_int32'].message_type = _TESTMAP_MAPINT32INT32ENTRY
+_TESTMAP.fields_by_name['map_int64_int64'].message_type = _TESTMAP_MAPINT64INT64ENTRY
+_TESTMAP.fields_by_name['map_uint32_uint32'].message_type = _TESTMAP_MAPUINT32UINT32ENTRY
+_TESTMAP.fields_by_name['map_uint64_uint64'].message_type = _TESTMAP_MAPUINT64UINT64ENTRY
+_TESTMAP.fields_by_name['map_sint32_sint32'].message_type = _TESTMAP_MAPSINT32SINT32ENTRY
+_TESTMAP.fields_by_name['map_sint64_sint64'].message_type = _TESTMAP_MAPSINT64SINT64ENTRY
+_TESTMAP.fields_by_name['map_fixed32_fixed32'].message_type = _TESTMAP_MAPFIXED32FIXED32ENTRY
+_TESTMAP.fields_by_name['map_fixed64_fixed64'].message_type = _TESTMAP_MAPFIXED64FIXED64ENTRY
+_TESTMAP.fields_by_name['map_sfixed32_sfixed32'].message_type = _TESTMAP_MAPSFIXED32SFIXED32ENTRY
+_TESTMAP.fields_by_name['map_sfixed64_sfixed64'].message_type = _TESTMAP_MAPSFIXED64SFIXED64ENTRY
+_TESTMAP.fields_by_name['map_int32_float'].message_type = _TESTMAP_MAPINT32FLOATENTRY
+_TESTMAP.fields_by_name['map_int32_double'].message_type = _TESTMAP_MAPINT32DOUBLEENTRY
+_TESTMAP.fields_by_name['map_bool_bool'].message_type = _TESTMAP_MAPBOOLBOOLENTRY
+_TESTMAP.fields_by_name['map_string_string'].message_type = _TESTMAP_MAPSTRINGSTRINGENTRY
+_TESTMAP.fields_by_name['map_int32_bytes'].message_type = _TESTMAP_MAPINT32BYTESENTRY
+_TESTMAP.fields_by_name['map_int32_enum'].message_type = _TESTMAP_MAPINT32ENUMENTRY
+_TESTMAP.fields_by_name['map_int32_foreign_message'].message_type = _TESTMAP_MAPINT32FOREIGNMESSAGEENTRY
+_TESTMAP.fields_by_name['map_string_foreign_message'].message_type = _TESTMAP_MAPSTRINGFOREIGNMESSAGEENTRY
+_TESTMAPSUBMESSAGE.fields_by_name['test_map'].message_type = _TESTMAP
+_TESTMESSAGEMAP_MAPINT32MESSAGEENTRY.fields_by_name['value'].message_type = google_dot_protobuf_dot_unittest__pb2._TESTALLTYPES
+_TESTMESSAGEMAP_MAPINT32MESSAGEENTRY.containing_type = _TESTMESSAGEMAP
+_TESTMESSAGEMAP.fields_by_name['map_int32_message'].message_type = _TESTMESSAGEMAP_MAPINT32MESSAGEENTRY
+_TESTSAMETYPEMAP_MAP1ENTRY.containing_type = _TESTSAMETYPEMAP
+_TESTSAMETYPEMAP_MAP2ENTRY.containing_type = _TESTSAMETYPEMAP
+_TESTSAMETYPEMAP.fields_by_name['map1'].message_type = _TESTSAMETYPEMAP_MAP1ENTRY
+_TESTSAMETYPEMAP.fields_by_name['map2'].message_type = _TESTSAMETYPEMAP_MAP2ENTRY
+_TESTREQUIREDMESSAGEMAP_MAPFIELDENTRY.fields_by_name['value'].message_type = google_dot_protobuf_dot_unittest__pb2._TESTREQUIRED
+_TESTREQUIREDMESSAGEMAP_MAPFIELDENTRY.containing_type = _TESTREQUIREDMESSAGEMAP
+_TESTREQUIREDMESSAGEMAP.fields_by_name['map_field'].message_type = _TESTREQUIREDMESSAGEMAP_MAPFIELDENTRY
+_TESTARENAMAP_MAPINT32INT32ENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPINT64INT64ENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPUINT32UINT32ENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPUINT64UINT64ENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPSINT32SINT32ENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPSINT64SINT64ENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPFIXED32FIXED32ENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPFIXED64FIXED64ENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPSFIXED32SFIXED32ENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPSFIXED64SFIXED64ENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPINT32FLOATENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPINT32DOUBLEENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPBOOLBOOLENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPSTRINGSTRINGENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPINT32BYTESENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPINT32ENUMENTRY.fields_by_name['value'].enum_type = _MAPENUM
+_TESTARENAMAP_MAPINT32ENUMENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPINT32FOREIGNMESSAGEENTRY.fields_by_name['value'].message_type = google_dot_protobuf_dot_unittest__pb2._FOREIGNMESSAGE
+_TESTARENAMAP_MAPINT32FOREIGNMESSAGEENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP_MAPINT32FOREIGNMESSAGENOARENAENTRY.fields_by_name['value'].message_type = google_dot_protobuf_dot_unittest__no__arena__pb2._FOREIGNMESSAGE
+_TESTARENAMAP_MAPINT32FOREIGNMESSAGENOARENAENTRY.containing_type = _TESTARENAMAP
+_TESTARENAMAP.fields_by_name['map_int32_int32'].message_type = _TESTARENAMAP_MAPINT32INT32ENTRY
+_TESTARENAMAP.fields_by_name['map_int64_int64'].message_type = _TESTARENAMAP_MAPINT64INT64ENTRY
+_TESTARENAMAP.fields_by_name['map_uint32_uint32'].message_type = _TESTARENAMAP_MAPUINT32UINT32ENTRY
+_TESTARENAMAP.fields_by_name['map_uint64_uint64'].message_type = _TESTARENAMAP_MAPUINT64UINT64ENTRY
+_TESTARENAMAP.fields_by_name['map_sint32_sint32'].message_type = _TESTARENAMAP_MAPSINT32SINT32ENTRY
+_TESTARENAMAP.fields_by_name['map_sint64_sint64'].message_type = _TESTARENAMAP_MAPSINT64SINT64ENTRY
+_TESTARENAMAP.fields_by_name['map_fixed32_fixed32'].message_type = _TESTARENAMAP_MAPFIXED32FIXED32ENTRY
+_TESTARENAMAP.fields_by_name['map_fixed64_fixed64'].message_type = _TESTARENAMAP_MAPFIXED64FIXED64ENTRY
+_TESTARENAMAP.fields_by_name['map_sfixed32_sfixed32'].message_type = _TESTARENAMAP_MAPSFIXED32SFIXED32ENTRY
+_TESTARENAMAP.fields_by_name['map_sfixed64_sfixed64'].message_type = _TESTARENAMAP_MAPSFIXED64SFIXED64ENTRY
+_TESTARENAMAP.fields_by_name['map_int32_float'].message_type = _TESTARENAMAP_MAPINT32FLOATENTRY
+_TESTARENAMAP.fields_by_name['map_int32_double'].message_type = _TESTARENAMAP_MAPINT32DOUBLEENTRY
+_TESTARENAMAP.fields_by_name['map_bool_bool'].message_type = _TESTARENAMAP_MAPBOOLBOOLENTRY
+_TESTARENAMAP.fields_by_name['map_string_string'].message_type = _TESTARENAMAP_MAPSTRINGSTRINGENTRY
+_TESTARENAMAP.fields_by_name['map_int32_bytes'].message_type = _TESTARENAMAP_MAPINT32BYTESENTRY
+_TESTARENAMAP.fields_by_name['map_int32_enum'].message_type = _TESTARENAMAP_MAPINT32ENUMENTRY
+_TESTARENAMAP.fields_by_name['map_int32_foreign_message'].message_type = _TESTARENAMAP_MAPINT32FOREIGNMESSAGEENTRY
+_TESTARENAMAP.fields_by_name['map_int32_foreign_message_no_arena'].message_type = _TESTARENAMAP_MAPINT32FOREIGNMESSAGENOARENAENTRY
+_MESSAGECONTAININGENUMCALLEDTYPE_TYPEENTRY.fields_by_name['value'].message_type = _MESSAGECONTAININGENUMCALLEDTYPE
+_MESSAGECONTAININGENUMCALLEDTYPE_TYPEENTRY.containing_type = _MESSAGECONTAININGENUMCALLEDTYPE
+_MESSAGECONTAININGENUMCALLEDTYPE.fields_by_name['type'].message_type = _MESSAGECONTAININGENUMCALLEDTYPE_TYPEENTRY
+_MESSAGECONTAININGENUMCALLEDTYPE_TYPE.containing_type = _MESSAGECONTAININGENUMCALLEDTYPE
+_MESSAGECONTAININGMAPCALLEDENTRY_ENTRYENTRY.containing_type = _MESSAGECONTAININGMAPCALLEDENTRY
+_MESSAGECONTAININGMAPCALLEDENTRY.fields_by_name['entry'].message_type = _MESSAGECONTAININGMAPCALLEDENTRY_ENTRYENTRY
+_TESTRECURSIVEMAPMESSAGE_AENTRY.fields_by_name['value'].message_type = _TESTRECURSIVEMAPMESSAGE
+_TESTRECURSIVEMAPMESSAGE_AENTRY.containing_type = _TESTRECURSIVEMAPMESSAGE
+_TESTRECURSIVEMAPMESSAGE.fields_by_name['a'].message_type = _TESTRECURSIVEMAPMESSAGE_AENTRY
+DESCRIPTOR.message_types_by_name['TestMap'] = _TESTMAP
+DESCRIPTOR.message_types_by_name['TestMapSubmessage'] = _TESTMAPSUBMESSAGE
+DESCRIPTOR.message_types_by_name['TestMessageMap'] = _TESTMESSAGEMAP
+DESCRIPTOR.message_types_by_name['TestSameTypeMap'] = _TESTSAMETYPEMAP
+DESCRIPTOR.message_types_by_name['TestRequiredMessageMap'] = _TESTREQUIREDMESSAGEMAP
+DESCRIPTOR.message_types_by_name['TestArenaMap'] = _TESTARENAMAP
+DESCRIPTOR.message_types_by_name['MessageContainingEnumCalledType'] = _MESSAGECONTAININGENUMCALLEDTYPE
+DESCRIPTOR.message_types_by_name['MessageContainingMapCalledEntry'] = _MESSAGECONTAININGMAPCALLEDENTRY
+DESCRIPTOR.message_types_by_name['TestRecursiveMapMessage'] = _TESTRECURSIVEMAPMESSAGE
+DESCRIPTOR.enum_types_by_name['MapEnum'] = _MAPENUM
+
+TestMap = _reflection.GeneratedProtocolMessageType('TestMap', (_message.Message,), dict(
+
+  MapInt32Int32Entry = _reflection.GeneratedProtocolMessageType('MapInt32Int32Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPINT32INT32ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapInt32Int32Entry)
+    ))
+  ,
+
+  MapInt64Int64Entry = _reflection.GeneratedProtocolMessageType('MapInt64Int64Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPINT64INT64ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapInt64Int64Entry)
+    ))
+  ,
+
+  MapUint32Uint32Entry = _reflection.GeneratedProtocolMessageType('MapUint32Uint32Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPUINT32UINT32ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapUint32Uint32Entry)
+    ))
+  ,
+
+  MapUint64Uint64Entry = _reflection.GeneratedProtocolMessageType('MapUint64Uint64Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPUINT64UINT64ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapUint64Uint64Entry)
+    ))
+  ,
+
+  MapSint32Sint32Entry = _reflection.GeneratedProtocolMessageType('MapSint32Sint32Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPSINT32SINT32ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapSint32Sint32Entry)
+    ))
+  ,
+
+  MapSint64Sint64Entry = _reflection.GeneratedProtocolMessageType('MapSint64Sint64Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPSINT64SINT64ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapSint64Sint64Entry)
+    ))
+  ,
+
+  MapFixed32Fixed32Entry = _reflection.GeneratedProtocolMessageType('MapFixed32Fixed32Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPFIXED32FIXED32ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapFixed32Fixed32Entry)
+    ))
+  ,
+
+  MapFixed64Fixed64Entry = _reflection.GeneratedProtocolMessageType('MapFixed64Fixed64Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPFIXED64FIXED64ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapFixed64Fixed64Entry)
+    ))
+  ,
+
+  MapSfixed32Sfixed32Entry = _reflection.GeneratedProtocolMessageType('MapSfixed32Sfixed32Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPSFIXED32SFIXED32ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapSfixed32Sfixed32Entry)
+    ))
+  ,
+
+  MapSfixed64Sfixed64Entry = _reflection.GeneratedProtocolMessageType('MapSfixed64Sfixed64Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPSFIXED64SFIXED64ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapSfixed64Sfixed64Entry)
+    ))
+  ,
+
+  MapInt32FloatEntry = _reflection.GeneratedProtocolMessageType('MapInt32FloatEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPINT32FLOATENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapInt32FloatEntry)
+    ))
+  ,
+
+  MapInt32DoubleEntry = _reflection.GeneratedProtocolMessageType('MapInt32DoubleEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPINT32DOUBLEENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapInt32DoubleEntry)
+    ))
+  ,
+
+  MapBoolBoolEntry = _reflection.GeneratedProtocolMessageType('MapBoolBoolEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPBOOLBOOLENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapBoolBoolEntry)
+    ))
+  ,
+
+  MapStringStringEntry = _reflection.GeneratedProtocolMessageType('MapStringStringEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPSTRINGSTRINGENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapStringStringEntry)
+    ))
+  ,
+
+  MapInt32BytesEntry = _reflection.GeneratedProtocolMessageType('MapInt32BytesEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPINT32BYTESENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapInt32BytesEntry)
+    ))
+  ,
+
+  MapInt32EnumEntry = _reflection.GeneratedProtocolMessageType('MapInt32EnumEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPINT32ENUMENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapInt32EnumEntry)
+    ))
+  ,
+
+  MapInt32ForeignMessageEntry = _reflection.GeneratedProtocolMessageType('MapInt32ForeignMessageEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPINT32FOREIGNMESSAGEENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapInt32ForeignMessageEntry)
+    ))
+  ,
+
+  MapStringForeignMessageEntry = _reflection.GeneratedProtocolMessageType('MapStringForeignMessageEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_MAPSTRINGFOREIGNMESSAGEENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap.MapStringForeignMessageEntry)
+    ))
+  ,
+  DESCRIPTOR = _TESTMAP,
+  __module__ = 'google.protobuf.map_unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMap)
+  ))
+_sym_db.RegisterMessage(TestMap)
+_sym_db.RegisterMessage(TestMap.MapInt32Int32Entry)
+_sym_db.RegisterMessage(TestMap.MapInt64Int64Entry)
+_sym_db.RegisterMessage(TestMap.MapUint32Uint32Entry)
+_sym_db.RegisterMessage(TestMap.MapUint64Uint64Entry)
+_sym_db.RegisterMessage(TestMap.MapSint32Sint32Entry)
+_sym_db.RegisterMessage(TestMap.MapSint64Sint64Entry)
+_sym_db.RegisterMessage(TestMap.MapFixed32Fixed32Entry)
+_sym_db.RegisterMessage(TestMap.MapFixed64Fixed64Entry)
+_sym_db.RegisterMessage(TestMap.MapSfixed32Sfixed32Entry)
+_sym_db.RegisterMessage(TestMap.MapSfixed64Sfixed64Entry)
+_sym_db.RegisterMessage(TestMap.MapInt32FloatEntry)
+_sym_db.RegisterMessage(TestMap.MapInt32DoubleEntry)
+_sym_db.RegisterMessage(TestMap.MapBoolBoolEntry)
+_sym_db.RegisterMessage(TestMap.MapStringStringEntry)
+_sym_db.RegisterMessage(TestMap.MapInt32BytesEntry)
+_sym_db.RegisterMessage(TestMap.MapInt32EnumEntry)
+_sym_db.RegisterMessage(TestMap.MapInt32ForeignMessageEntry)
+_sym_db.RegisterMessage(TestMap.MapStringForeignMessageEntry)
+
+TestMapSubmessage = _reflection.GeneratedProtocolMessageType('TestMapSubmessage', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMAPSUBMESSAGE,
+  __module__ = 'google.protobuf.map_unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMapSubmessage)
+  ))
+_sym_db.RegisterMessage(TestMapSubmessage)
+
+TestMessageMap = _reflection.GeneratedProtocolMessageType('TestMessageMap', (_message.Message,), dict(
+
+  MapInt32MessageEntry = _reflection.GeneratedProtocolMessageType('MapInt32MessageEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMESSAGEMAP_MAPINT32MESSAGEENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMessageMap.MapInt32MessageEntry)
+    ))
+  ,
+  DESCRIPTOR = _TESTMESSAGEMAP,
+  __module__ = 'google.protobuf.map_unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMessageMap)
+  ))
+_sym_db.RegisterMessage(TestMessageMap)
+_sym_db.RegisterMessage(TestMessageMap.MapInt32MessageEntry)
+
+TestSameTypeMap = _reflection.GeneratedProtocolMessageType('TestSameTypeMap', (_message.Message,), dict(
+
+  Map1Entry = _reflection.GeneratedProtocolMessageType('Map1Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTSAMETYPEMAP_MAP1ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestSameTypeMap.Map1Entry)
+    ))
+  ,
+
+  Map2Entry = _reflection.GeneratedProtocolMessageType('Map2Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTSAMETYPEMAP_MAP2ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestSameTypeMap.Map2Entry)
+    ))
+  ,
+  DESCRIPTOR = _TESTSAMETYPEMAP,
+  __module__ = 'google.protobuf.map_unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestSameTypeMap)
+  ))
+_sym_db.RegisterMessage(TestSameTypeMap)
+_sym_db.RegisterMessage(TestSameTypeMap.Map1Entry)
+_sym_db.RegisterMessage(TestSameTypeMap.Map2Entry)
+
+TestRequiredMessageMap = _reflection.GeneratedProtocolMessageType('TestRequiredMessageMap', (_message.Message,), dict(
+
+  MapFieldEntry = _reflection.GeneratedProtocolMessageType('MapFieldEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTREQUIREDMESSAGEMAP_MAPFIELDENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestRequiredMessageMap.MapFieldEntry)
+    ))
+  ,
+  DESCRIPTOR = _TESTREQUIREDMESSAGEMAP,
+  __module__ = 'google.protobuf.map_unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestRequiredMessageMap)
+  ))
+_sym_db.RegisterMessage(TestRequiredMessageMap)
+_sym_db.RegisterMessage(TestRequiredMessageMap.MapFieldEntry)
+
+TestArenaMap = _reflection.GeneratedProtocolMessageType('TestArenaMap', (_message.Message,), dict(
+
+  MapInt32Int32Entry = _reflection.GeneratedProtocolMessageType('MapInt32Int32Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPINT32INT32ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapInt32Int32Entry)
+    ))
+  ,
+
+  MapInt64Int64Entry = _reflection.GeneratedProtocolMessageType('MapInt64Int64Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPINT64INT64ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapInt64Int64Entry)
+    ))
+  ,
+
+  MapUint32Uint32Entry = _reflection.GeneratedProtocolMessageType('MapUint32Uint32Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPUINT32UINT32ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapUint32Uint32Entry)
+    ))
+  ,
+
+  MapUint64Uint64Entry = _reflection.GeneratedProtocolMessageType('MapUint64Uint64Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPUINT64UINT64ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapUint64Uint64Entry)
+    ))
+  ,
+
+  MapSint32Sint32Entry = _reflection.GeneratedProtocolMessageType('MapSint32Sint32Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPSINT32SINT32ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapSint32Sint32Entry)
+    ))
+  ,
+
+  MapSint64Sint64Entry = _reflection.GeneratedProtocolMessageType('MapSint64Sint64Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPSINT64SINT64ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapSint64Sint64Entry)
+    ))
+  ,
+
+  MapFixed32Fixed32Entry = _reflection.GeneratedProtocolMessageType('MapFixed32Fixed32Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPFIXED32FIXED32ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapFixed32Fixed32Entry)
+    ))
+  ,
+
+  MapFixed64Fixed64Entry = _reflection.GeneratedProtocolMessageType('MapFixed64Fixed64Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPFIXED64FIXED64ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapFixed64Fixed64Entry)
+    ))
+  ,
+
+  MapSfixed32Sfixed32Entry = _reflection.GeneratedProtocolMessageType('MapSfixed32Sfixed32Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPSFIXED32SFIXED32ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapSfixed32Sfixed32Entry)
+    ))
+  ,
+
+  MapSfixed64Sfixed64Entry = _reflection.GeneratedProtocolMessageType('MapSfixed64Sfixed64Entry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPSFIXED64SFIXED64ENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapSfixed64Sfixed64Entry)
+    ))
+  ,
+
+  MapInt32FloatEntry = _reflection.GeneratedProtocolMessageType('MapInt32FloatEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPINT32FLOATENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapInt32FloatEntry)
+    ))
+  ,
+
+  MapInt32DoubleEntry = _reflection.GeneratedProtocolMessageType('MapInt32DoubleEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPINT32DOUBLEENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapInt32DoubleEntry)
+    ))
+  ,
+
+  MapBoolBoolEntry = _reflection.GeneratedProtocolMessageType('MapBoolBoolEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPBOOLBOOLENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapBoolBoolEntry)
+    ))
+  ,
+
+  MapStringStringEntry = _reflection.GeneratedProtocolMessageType('MapStringStringEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPSTRINGSTRINGENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapStringStringEntry)
+    ))
+  ,
+
+  MapInt32BytesEntry = _reflection.GeneratedProtocolMessageType('MapInt32BytesEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPINT32BYTESENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapInt32BytesEntry)
+    ))
+  ,
+
+  MapInt32EnumEntry = _reflection.GeneratedProtocolMessageType('MapInt32EnumEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPINT32ENUMENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapInt32EnumEntry)
+    ))
+  ,
+
+  MapInt32ForeignMessageEntry = _reflection.GeneratedProtocolMessageType('MapInt32ForeignMessageEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPINT32FOREIGNMESSAGEENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapInt32ForeignMessageEntry)
+    ))
+  ,
+
+  MapInt32ForeignMessageNoArenaEntry = _reflection.GeneratedProtocolMessageType('MapInt32ForeignMessageNoArenaEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTARENAMAP_MAPINT32FOREIGNMESSAGENOARENAENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap.MapInt32ForeignMessageNoArenaEntry)
+    ))
+  ,
+  DESCRIPTOR = _TESTARENAMAP,
+  __module__ = 'google.protobuf.map_unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestArenaMap)
+  ))
+_sym_db.RegisterMessage(TestArenaMap)
+_sym_db.RegisterMessage(TestArenaMap.MapInt32Int32Entry)
+_sym_db.RegisterMessage(TestArenaMap.MapInt64Int64Entry)
+_sym_db.RegisterMessage(TestArenaMap.MapUint32Uint32Entry)
+_sym_db.RegisterMessage(TestArenaMap.MapUint64Uint64Entry)
+_sym_db.RegisterMessage(TestArenaMap.MapSint32Sint32Entry)
+_sym_db.RegisterMessage(TestArenaMap.MapSint64Sint64Entry)
+_sym_db.RegisterMessage(TestArenaMap.MapFixed32Fixed32Entry)
+_sym_db.RegisterMessage(TestArenaMap.MapFixed64Fixed64Entry)
+_sym_db.RegisterMessage(TestArenaMap.MapSfixed32Sfixed32Entry)
+_sym_db.RegisterMessage(TestArenaMap.MapSfixed64Sfixed64Entry)
+_sym_db.RegisterMessage(TestArenaMap.MapInt32FloatEntry)
+_sym_db.RegisterMessage(TestArenaMap.MapInt32DoubleEntry)
+_sym_db.RegisterMessage(TestArenaMap.MapBoolBoolEntry)
+_sym_db.RegisterMessage(TestArenaMap.MapStringStringEntry)
+_sym_db.RegisterMessage(TestArenaMap.MapInt32BytesEntry)
+_sym_db.RegisterMessage(TestArenaMap.MapInt32EnumEntry)
+_sym_db.RegisterMessage(TestArenaMap.MapInt32ForeignMessageEntry)
+_sym_db.RegisterMessage(TestArenaMap.MapInt32ForeignMessageNoArenaEntry)
+
+MessageContainingEnumCalledType = _reflection.GeneratedProtocolMessageType('MessageContainingEnumCalledType', (_message.Message,), dict(
+
+  TypeEntry = _reflection.GeneratedProtocolMessageType('TypeEntry', (_message.Message,), dict(
+    DESCRIPTOR = _MESSAGECONTAININGENUMCALLEDTYPE_TYPEENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.MessageContainingEnumCalledType.TypeEntry)
+    ))
+  ,
+  DESCRIPTOR = _MESSAGECONTAININGENUMCALLEDTYPE,
+  __module__ = 'google.protobuf.map_unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.MessageContainingEnumCalledType)
+  ))
+_sym_db.RegisterMessage(MessageContainingEnumCalledType)
+_sym_db.RegisterMessage(MessageContainingEnumCalledType.TypeEntry)
+
+MessageContainingMapCalledEntry = _reflection.GeneratedProtocolMessageType('MessageContainingMapCalledEntry', (_message.Message,), dict(
+
+  EntryEntry = _reflection.GeneratedProtocolMessageType('EntryEntry', (_message.Message,), dict(
+    DESCRIPTOR = _MESSAGECONTAININGMAPCALLEDENTRY_ENTRYENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.MessageContainingMapCalledEntry.EntryEntry)
+    ))
+  ,
+  DESCRIPTOR = _MESSAGECONTAININGMAPCALLEDENTRY,
+  __module__ = 'google.protobuf.map_unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.MessageContainingMapCalledEntry)
+  ))
+_sym_db.RegisterMessage(MessageContainingMapCalledEntry)
+_sym_db.RegisterMessage(MessageContainingMapCalledEntry.EntryEntry)
+
+TestRecursiveMapMessage = _reflection.GeneratedProtocolMessageType('TestRecursiveMapMessage', (_message.Message,), dict(
+
+  AEntry = _reflection.GeneratedProtocolMessageType('AEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTRECURSIVEMAPMESSAGE_AENTRY,
+    __module__ = 'google.protobuf.map_unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestRecursiveMapMessage.AEntry)
+    ))
+  ,
+  DESCRIPTOR = _TESTRECURSIVEMAPMESSAGE,
+  __module__ = 'google.protobuf.map_unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestRecursiveMapMessage)
+  ))
+_sym_db.RegisterMessage(TestRecursiveMapMessage)
+_sym_db.RegisterMessage(TestRecursiveMapMessage.AEntry)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\370\001\001'))
+_TESTMAP_MAPINT32INT32ENTRY.has_options = True
+_TESTMAP_MAPINT32INT32ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPINT64INT64ENTRY.has_options = True
+_TESTMAP_MAPINT64INT64ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPUINT32UINT32ENTRY.has_options = True
+_TESTMAP_MAPUINT32UINT32ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPUINT64UINT64ENTRY.has_options = True
+_TESTMAP_MAPUINT64UINT64ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPSINT32SINT32ENTRY.has_options = True
+_TESTMAP_MAPSINT32SINT32ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPSINT64SINT64ENTRY.has_options = True
+_TESTMAP_MAPSINT64SINT64ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPFIXED32FIXED32ENTRY.has_options = True
+_TESTMAP_MAPFIXED32FIXED32ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPFIXED64FIXED64ENTRY.has_options = True
+_TESTMAP_MAPFIXED64FIXED64ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPSFIXED32SFIXED32ENTRY.has_options = True
+_TESTMAP_MAPSFIXED32SFIXED32ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPSFIXED64SFIXED64ENTRY.has_options = True
+_TESTMAP_MAPSFIXED64SFIXED64ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPINT32FLOATENTRY.has_options = True
+_TESTMAP_MAPINT32FLOATENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPINT32DOUBLEENTRY.has_options = True
+_TESTMAP_MAPINT32DOUBLEENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPBOOLBOOLENTRY.has_options = True
+_TESTMAP_MAPBOOLBOOLENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPSTRINGSTRINGENTRY.has_options = True
+_TESTMAP_MAPSTRINGSTRINGENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPINT32BYTESENTRY.has_options = True
+_TESTMAP_MAPINT32BYTESENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPINT32ENUMENTRY.has_options = True
+_TESTMAP_MAPINT32ENUMENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPINT32FOREIGNMESSAGEENTRY.has_options = True
+_TESTMAP_MAPINT32FOREIGNMESSAGEENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_MAPSTRINGFOREIGNMESSAGEENTRY.has_options = True
+_TESTMAP_MAPSTRINGFOREIGNMESSAGEENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMESSAGEMAP_MAPINT32MESSAGEENTRY.has_options = True
+_TESTMESSAGEMAP_MAPINT32MESSAGEENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTSAMETYPEMAP_MAP1ENTRY.has_options = True
+_TESTSAMETYPEMAP_MAP1ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTSAMETYPEMAP_MAP2ENTRY.has_options = True
+_TESTSAMETYPEMAP_MAP2ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTREQUIREDMESSAGEMAP_MAPFIELDENTRY.has_options = True
+_TESTREQUIREDMESSAGEMAP_MAPFIELDENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPINT32INT32ENTRY.has_options = True
+_TESTARENAMAP_MAPINT32INT32ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPINT64INT64ENTRY.has_options = True
+_TESTARENAMAP_MAPINT64INT64ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPUINT32UINT32ENTRY.has_options = True
+_TESTARENAMAP_MAPUINT32UINT32ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPUINT64UINT64ENTRY.has_options = True
+_TESTARENAMAP_MAPUINT64UINT64ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPSINT32SINT32ENTRY.has_options = True
+_TESTARENAMAP_MAPSINT32SINT32ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPSINT64SINT64ENTRY.has_options = True
+_TESTARENAMAP_MAPSINT64SINT64ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPFIXED32FIXED32ENTRY.has_options = True
+_TESTARENAMAP_MAPFIXED32FIXED32ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPFIXED64FIXED64ENTRY.has_options = True
+_TESTARENAMAP_MAPFIXED64FIXED64ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPSFIXED32SFIXED32ENTRY.has_options = True
+_TESTARENAMAP_MAPSFIXED32SFIXED32ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPSFIXED64SFIXED64ENTRY.has_options = True
+_TESTARENAMAP_MAPSFIXED64SFIXED64ENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPINT32FLOATENTRY.has_options = True
+_TESTARENAMAP_MAPINT32FLOATENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPINT32DOUBLEENTRY.has_options = True
+_TESTARENAMAP_MAPINT32DOUBLEENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPBOOLBOOLENTRY.has_options = True
+_TESTARENAMAP_MAPBOOLBOOLENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPSTRINGSTRINGENTRY.has_options = True
+_TESTARENAMAP_MAPSTRINGSTRINGENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPINT32BYTESENTRY.has_options = True
+_TESTARENAMAP_MAPINT32BYTESENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPINT32ENUMENTRY.has_options = True
+_TESTARENAMAP_MAPINT32ENUMENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPINT32FOREIGNMESSAGEENTRY.has_options = True
+_TESTARENAMAP_MAPINT32FOREIGNMESSAGEENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTARENAMAP_MAPINT32FOREIGNMESSAGENOARENAENTRY.has_options = True
+_TESTARENAMAP_MAPINT32FOREIGNMESSAGENOARENAENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_MESSAGECONTAININGENUMCALLEDTYPE_TYPEENTRY.has_options = True
+_MESSAGECONTAININGENUMCALLEDTYPE_TYPEENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_MESSAGECONTAININGMAPCALLEDENTRY_ENTRYENTRY.has_options = True
+_MESSAGECONTAININGMAPCALLEDENTRY_ENTRYENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTRECURSIVEMAPMESSAGE_AENTRY.has_options = True
+_TESTRECURSIVEMAPMESSAGE_AENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/message.py b/generator/google/protobuf/message.py
index 6ec2f8b..606f735 100644
--- a/generator/google/protobuf/message.py
+++ b/generator/google/protobuf/message.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -36,7 +36,6 @@
 
 __author__ = 'robinson@google.com (Will Robinson)'
 
-
 class Error(Exception): pass
 class DecodeError(Error): pass
 class EncodeError(Error): pass
@@ -177,7 +176,11 @@
     raise NotImplementedError
 
   def ParseFromString(self, serialized):
-    """Like MergeFromString(), except we clear the object first."""
+    """Parse serialized protocol buffer data into this message.
+
+    Like MergeFromString(), except we clear the object first and
+    do not return the value that MergeFromString returns.
+    """
     self.Clear()
     self.MergeFromString(serialized)
 
@@ -229,12 +232,21 @@
     raise NotImplementedError
 
   def HasField(self, field_name):
-    """Checks if a certain field is set for the message. Note if the
-    field_name is not defined in the message descriptor, ValueError will be
-    raised."""
+    """Checks if a certain field is set for the message, or if any field inside
+    a oneof group is set.  Note that if the field_name is not defined in the
+    message descriptor, ValueError will be raised."""
     raise NotImplementedError
 
   def ClearField(self, field_name):
+    """Clears the contents of a given field, or the field set inside a oneof
+    group.  If the name neither refers to a defined field or oneof group,
+    ValueError is raised."""
+    raise NotImplementedError
+
+  def WhichOneof(self, oneof_group):
+    """Returns the name of the field that is set inside a oneof group, or
+    None if no field is set.  If no group with the given name exists, ValueError
+    will be raised."""
     raise NotImplementedError
 
   def HasExtension(self, extension_handle):
@@ -243,6 +255,9 @@
   def ClearExtension(self, extension_handle):
     raise NotImplementedError
 
+  def DiscardUnknownFields(self):
+    raise NotImplementedError
+
   def ByteSize(self):
     """Returns the serialized size of this message.
     Recursively calls ByteSize() on all contained messages.
diff --git a/generator/google/protobuf/message_factory.py b/generator/google/protobuf/message_factory.py
index 36e2fef..1b059d1 100644
--- a/generator/google/protobuf/message_factory.py
+++ b/generator/google/protobuf/message_factory.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -28,11 +28,17 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-"""Provides a factory class for generating dynamic messages."""
+"""Provides a factory class for generating dynamic messages.
+
+The easiest way to use this class is if you have access to the FileDescriptor
+protos containing the messages you want to create you can just do the following:
+
+message_classes = message_factory.GetMessages(iterable_of_file_descriptors)
+my_proto_instance = message_classes['some.proto.package.MessageName']()
+"""
 
 __author__ = 'matthewtoia@google.com (Matt Toia)'
 
-from google.protobuf import descriptor_database
 from google.protobuf import descriptor_pool
 from google.protobuf import message
 from google.protobuf import reflection
@@ -41,8 +47,11 @@
 class MessageFactory(object):
   """Factory for creating Proto2 messages from descriptors in a pool."""
 
-  def __init__(self):
+  def __init__(self, pool=None):
     """Initializes a new factory."""
+    self.pool = pool or descriptor_pool.DescriptorPool()
+
+    # local cache of all classes built from protobuf descriptors
     self._classes = {}
 
   def GetPrototype(self, descriptor):
@@ -57,21 +66,68 @@
     Returns:
       A class describing the passed in descriptor.
     """
-
     if descriptor.full_name not in self._classes:
+      descriptor_name = descriptor.name
+      if str is bytes:  # PY2
+        descriptor_name = descriptor.name.encode('ascii', 'ignore')
       result_class = reflection.GeneratedProtocolMessageType(
-          descriptor.name.encode('ascii', 'ignore'),
+          descriptor_name,
           (message.Message,),
-          {'DESCRIPTOR': descriptor})
+          {'DESCRIPTOR': descriptor, '__module__': None})
+          # If module not set, it wrongly points to the reflection.py module.
       self._classes[descriptor.full_name] = result_class
       for field in descriptor.fields:
         if field.message_type:
           self.GetPrototype(field.message_type)
+      for extension in result_class.DESCRIPTOR.extensions:
+        if extension.containing_type.full_name not in self._classes:
+          self.GetPrototype(extension.containing_type)
+        extended_class = self._classes[extension.containing_type.full_name]
+        extended_class.RegisterExtension(extension)
     return self._classes[descriptor.full_name]
 
+  def GetMessages(self, files):
+    """Gets all the messages from a specified file.
 
-_DB = descriptor_database.DescriptorDatabase()
-_POOL = descriptor_pool.DescriptorPool(_DB)
+    This will find and resolve dependencies, failing if the descriptor
+    pool cannot satisfy them.
+
+    Args:
+      files: The file names to extract messages from.
+
+    Returns:
+      A dictionary mapping proto names to the message classes. This will include
+      any dependent messages as well as any messages defined in the same file as
+      a specified message.
+    """
+    result = {}
+    for file_name in files:
+      file_desc = self.pool.FindFileByName(file_name)
+      for name, msg in file_desc.message_types_by_name.items():
+        if file_desc.package:
+          full_name = '.'.join([file_desc.package, name])
+        else:
+          full_name = msg.name
+        result[full_name] = self.GetPrototype(
+            self.pool.FindMessageTypeByName(full_name))
+
+      # While the extension FieldDescriptors are created by the descriptor pool,
+      # the python classes created in the factory need them to be registered
+      # explicitly, which is done below.
+      #
+      # The call to RegisterExtension will specifically check if the
+      # extension was already registered on the object and either
+      # ignore the registration if the original was the same, or raise
+      # an error if they were different.
+
+      for name, extension in file_desc.extensions_by_name.items():
+        if extension.containing_type.full_name not in self._classes:
+          self.GetPrototype(extension.containing_type)
+        extended_class = self._classes[extension.containing_type.full_name]
+        extended_class.RegisterExtension(extension)
+    return result
+
+
 _FACTORY = MessageFactory()
 
 
@@ -82,32 +138,10 @@
     file_protos: A sequence of file protos to build messages out of.
 
   Returns:
-    A dictionary containing all the message types in the files mapping the
-    fully qualified name to a Message subclass for the descriptor.
+    A dictionary mapping proto names to the message classes. This will include
+    any dependent messages as well as any messages defined in the same file as
+    a specified message.
   """
-
-  result = {}
   for file_proto in file_protos:
-    _DB.Add(file_proto)
-  for file_proto in file_protos:
-    for desc in _GetAllDescriptors(file_proto.message_type, file_proto.package):
-      result[desc.full_name] = _FACTORY.GetPrototype(desc)
-  return result
-
-
-def _GetAllDescriptors(desc_protos, package):
-  """Gets all levels of nested message types as a flattened list of descriptors.
-
-  Args:
-    desc_protos: The descriptor protos to process.
-    package: The package where the protos are defined.
-
-  Yields:
-    Each message descriptor for each nested type.
-  """
-
-  for desc_proto in desc_protos:
-    name = '.'.join((package, desc_proto.name))
-    yield _POOL.FindMessageTypeByName(name)
-    for nested_desc in _GetAllDescriptors(desc_proto.nested_type, name):
-      yield nested_desc
+    _FACTORY.pool.Add(file_proto)
+  return _FACTORY.GetMessages([file_proto.name for file_proto in file_protos])
diff --git a/generator/google/protobuf/proto_builder.py b/generator/google/protobuf/proto_builder.py
new file mode 100644
index 0000000..736caed
--- /dev/null
+++ b/generator/google/protobuf/proto_builder.py
@@ -0,0 +1,130 @@
+# 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.
+
+"""Dynamic Protobuf class creator."""
+
+try:
+    from collections import OrderedDict
+except ImportError:
+    from ordereddict import OrderedDict  #PY26
+import hashlib
+import os
+
+from google.protobuf import descriptor_pb2
+from google.protobuf import message_factory
+
+
+def _GetMessageFromFactory(factory, full_name):
+  """Get a proto class from the MessageFactory by name.
+
+  Args:
+    factory: a MessageFactory instance.
+    full_name: str, the fully qualified name of the proto type.
+  Returns:
+    A class, for the type identified by full_name.
+  Raises:
+    KeyError, if the proto is not found in the factory's descriptor pool.
+  """
+  proto_descriptor = factory.pool.FindMessageTypeByName(full_name)
+  proto_cls = factory.GetPrototype(proto_descriptor)
+  return proto_cls
+
+
+def MakeSimpleProtoClass(fields, full_name=None, pool=None):
+  """Create a Protobuf class whose fields are basic types.
+
+  Note: this doesn't validate field names!
+
+  Args:
+    fields: dict of {name: field_type} mappings for each field in the proto. If
+        this is an OrderedDict the order will be maintained, otherwise the
+        fields will be sorted by name.
+    full_name: optional str, the fully-qualified name of the proto type.
+    pool: optional DescriptorPool instance.
+  Returns:
+    a class, the new protobuf class with a FileDescriptor.
+  """
+  factory = message_factory.MessageFactory(pool=pool)
+
+  if full_name is not None:
+    try:
+      proto_cls = _GetMessageFromFactory(factory, full_name)
+      return proto_cls
+    except KeyError:
+      # The factory's DescriptorPool doesn't know about this class yet.
+      pass
+
+  # Get a list of (name, field_type) tuples from the fields dict. If fields was
+  # an OrderedDict we keep the order, but otherwise we sort the field to ensure
+  # consistent ordering.
+  field_items = fields.items()
+  if not isinstance(fields, OrderedDict):
+    field_items = sorted(field_items)
+
+  # Use a consistent file name that is unlikely to conflict with any imported
+  # proto files.
+  fields_hash = hashlib.sha1()
+  for f_name, f_type in field_items:
+    fields_hash.update(f_name.encode('utf-8'))
+    fields_hash.update(str(f_type).encode('utf-8'))
+  proto_file_name = fields_hash.hexdigest() + '.proto'
+
+  # If the proto is anonymous, use the same hash to name it.
+  if full_name is None:
+    full_name = ('net.proto2.python.public.proto_builder.AnonymousProto_' +
+                 fields_hash.hexdigest())
+    try:
+      proto_cls = _GetMessageFromFactory(factory, full_name)
+      return proto_cls
+    except KeyError:
+      # The factory's DescriptorPool doesn't know about this class yet.
+      pass
+
+  # This is the first time we see this proto: add a new descriptor to the pool.
+  factory.pool.Add(
+      _MakeFileDescriptorProto(proto_file_name, full_name, field_items))
+  return _GetMessageFromFactory(factory, full_name)
+
+
+def _MakeFileDescriptorProto(proto_file_name, full_name, field_items):
+  """Populate FileDescriptorProto for MessageFactory's DescriptorPool."""
+  package, name = full_name.rsplit('.', 1)
+  file_proto = descriptor_pb2.FileDescriptorProto()
+  file_proto.name = os.path.join(package.replace('.', '/'), proto_file_name)
+  file_proto.package = package
+  desc_proto = file_proto.message_type.add()
+  desc_proto.name = name
+  for f_number, (f_name, f_type) in enumerate(field_items, 1):
+    field_proto = desc_proto.field.add()
+    field_proto.name = f_name
+    field_proto.number = f_number
+    field_proto.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL
+    field_proto.type = f_type
+  return file_proto
diff --git a/generator/google/protobuf/pyext/__init__.py b/generator/google/protobuf/pyext/__init__.py
new file mode 100644
index 0000000..5585614
--- /dev/null
+++ b/generator/google/protobuf/pyext/__init__.py
@@ -0,0 +1,4 @@
+try:
+  __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+  __path__ = __import__('pkgutil').extend_path(__path__, __name__)
diff --git a/generator/google/protobuf/pyext/cpp_message.py b/generator/google/protobuf/pyext/cpp_message.py
new file mode 100644
index 0000000..fc8eb32
--- /dev/null
+++ b/generator/google/protobuf/pyext/cpp_message.py
@@ -0,0 +1,65 @@
+# 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.
+
+"""Protocol message implementation hooks for C++ implementation.
+
+Contains helper functions used to create protocol message classes from
+Descriptor objects at runtime backed by the protocol buffer C++ API.
+"""
+
+__author__ = 'tibell@google.com (Johan Tibell)'
+
+from google.protobuf.pyext import _message
+
+
+class GeneratedProtocolMessageType(_message.MessageMeta):
+
+  """Metaclass for protocol message classes created at runtime from Descriptors.
+
+  The protocol compiler currently uses this metaclass to create protocol
+  message classes at runtime.  Clients can also manually create their own
+  classes at runtime, as in this example:
+
+  mydescriptor = Descriptor(.....)
+  factory = symbol_database.Default()
+  factory.pool.AddDescriptor(mydescriptor)
+  MyProtoClass = factory.GetPrototype(mydescriptor)
+  myproto_instance = MyProtoClass()
+  myproto.foo_field = 23
+  ...
+
+  The above example will not work for nested types. If you wish to include them,
+  use reflection.MakeClass() instead of manually instantiating the class in
+  order to create the appropriate class structure.
+  """
+
+  # Must be consistent with the protocol-compiler code in
+  # proto2/compiler/internal/generator.*.
+  _DESCRIPTOR_KEY = 'DESCRIPTOR'
diff --git a/generator/google/protobuf/pyext/python_pb2.py b/generator/google/protobuf/pyext/python_pb2.py
new file mode 100644
index 0000000..3750682
--- /dev/null
+++ b/generator/google/protobuf/pyext/python_pb2.py
@@ -0,0 +1,234 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/pyext/python.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/pyext/python.proto',
+  package='google.protobuf.python.internal',
+  syntax='proto2',
+  serialized_pb=_b('\n\"google/protobuf/pyext/python.proto\x12\x1fgoogle.protobuf.python.internal\"\xbc\x02\n\x0cTestAllTypes\x12\\\n\x17repeated_nested_message\x18\x01 \x03(\x0b\x32;.google.protobuf.python.internal.TestAllTypes.NestedMessage\x12\\\n\x17optional_nested_message\x18\x02 \x01(\x0b\x32;.google.protobuf.python.internal.TestAllTypes.NestedMessage\x12\x16\n\x0eoptional_int32\x18\x03 \x01(\x05\x1aX\n\rNestedMessage\x12\n\n\x02\x62\x62\x18\x01 \x01(\x05\x12;\n\x02\x63\x63\x18\x02 \x01(\x0b\x32/.google.protobuf.python.internal.ForeignMessage\"&\n\x0e\x46oreignMessage\x12\t\n\x01\x63\x18\x01 \x01(\x05\x12\t\n\x01\x64\x18\x02 \x03(\x05\"\x1d\n\x11TestAllExtensions*\x08\x08\x01\x10\x80\x80\x80\x80\x02:\x9a\x01\n!optional_nested_message_extension\x12\x32.google.protobuf.python.internal.TestAllExtensions\x18\x01 \x01(\x0b\x32;.google.protobuf.python.internal.TestAllTypes.NestedMessage:\x9a\x01\n!repeated_nested_message_extension\x12\x32.google.protobuf.python.internal.TestAllExtensions\x18\x02 \x03(\x0b\x32;.google.protobuf.python.internal.TestAllTypes.NestedMessageB\x02H\x01')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER = 1
+optional_nested_message_extension = _descriptor.FieldDescriptor(
+  name='optional_nested_message_extension', full_name='google.protobuf.python.internal.optional_nested_message_extension', index=0,
+  number=1, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER = 2
+repeated_nested_message_extension = _descriptor.FieldDescriptor(
+  name='repeated_nested_message_extension', full_name='google.protobuf.python.internal.repeated_nested_message_extension', index=1,
+  number=2, type=11, cpp_type=10, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+
+
+_TESTALLTYPES_NESTEDMESSAGE = _descriptor.Descriptor(
+  name='NestedMessage',
+  full_name='google.protobuf.python.internal.TestAllTypes.NestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='bb', full_name='google.protobuf.python.internal.TestAllTypes.NestedMessage.bb', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='cc', full_name='google.protobuf.python.internal.TestAllTypes.NestedMessage.cc', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=300,
+  serialized_end=388,
+)
+
+_TESTALLTYPES = _descriptor.Descriptor(
+  name='TestAllTypes',
+  full_name='google.protobuf.python.internal.TestAllTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='repeated_nested_message', full_name='google.protobuf.python.internal.TestAllTypes.repeated_nested_message', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_nested_message', full_name='google.protobuf.python.internal.TestAllTypes.optional_nested_message', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_int32', full_name='google.protobuf.python.internal.TestAllTypes.optional_int32', index=2,
+      number=3, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTALLTYPES_NESTEDMESSAGE, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=72,
+  serialized_end=388,
+)
+
+
+_FOREIGNMESSAGE = _descriptor.Descriptor(
+  name='ForeignMessage',
+  full_name='google.protobuf.python.internal.ForeignMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='c', full_name='google.protobuf.python.internal.ForeignMessage.c', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='d', full_name='google.protobuf.python.internal.ForeignMessage.d', index=1,
+      number=2, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=390,
+  serialized_end=428,
+)
+
+
+_TESTALLEXTENSIONS = _descriptor.Descriptor(
+  name='TestAllExtensions',
+  full_name='google.protobuf.python.internal.TestAllExtensions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(1, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=430,
+  serialized_end=459,
+)
+
+_TESTALLTYPES_NESTEDMESSAGE.fields_by_name['cc'].message_type = _FOREIGNMESSAGE
+_TESTALLTYPES_NESTEDMESSAGE.containing_type = _TESTALLTYPES
+_TESTALLTYPES.fields_by_name['repeated_nested_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['optional_nested_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+DESCRIPTOR.message_types_by_name['TestAllTypes'] = _TESTALLTYPES
+DESCRIPTOR.message_types_by_name['ForeignMessage'] = _FOREIGNMESSAGE
+DESCRIPTOR.message_types_by_name['TestAllExtensions'] = _TESTALLEXTENSIONS
+DESCRIPTOR.extensions_by_name['optional_nested_message_extension'] = optional_nested_message_extension
+DESCRIPTOR.extensions_by_name['repeated_nested_message_extension'] = repeated_nested_message_extension
+
+TestAllTypes = _reflection.GeneratedProtocolMessageType('TestAllTypes', (_message.Message,), dict(
+
+  NestedMessage = _reflection.GeneratedProtocolMessageType('NestedMessage', (_message.Message,), dict(
+    DESCRIPTOR = _TESTALLTYPES_NESTEDMESSAGE,
+    __module__ = 'google.protobuf.pyext.python_pb2'
+    # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.TestAllTypes.NestedMessage)
+    ))
+  ,
+  DESCRIPTOR = _TESTALLTYPES,
+  __module__ = 'google.protobuf.pyext.python_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.TestAllTypes)
+  ))
+_sym_db.RegisterMessage(TestAllTypes)
+_sym_db.RegisterMessage(TestAllTypes.NestedMessage)
+
+ForeignMessage = _reflection.GeneratedProtocolMessageType('ForeignMessage', (_message.Message,), dict(
+  DESCRIPTOR = _FOREIGNMESSAGE,
+  __module__ = 'google.protobuf.pyext.python_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.ForeignMessage)
+  ))
+_sym_db.RegisterMessage(ForeignMessage)
+
+TestAllExtensions = _reflection.GeneratedProtocolMessageType('TestAllExtensions', (_message.Message,), dict(
+  DESCRIPTOR = _TESTALLEXTENSIONS,
+  __module__ = 'google.protobuf.pyext.python_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.python.internal.TestAllExtensions)
+  ))
+_sym_db.RegisterMessage(TestAllExtensions)
+
+optional_nested_message_extension.message_type = _TESTALLTYPES_NESTEDMESSAGE
+TestAllExtensions.RegisterExtension(optional_nested_message_extension)
+repeated_nested_message_extension.message_type = _TESTALLTYPES_NESTEDMESSAGE
+TestAllExtensions.RegisterExtension(repeated_nested_message_extension)
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('H\001'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/reflection.py b/generator/google/protobuf/reflection.py
index 9570fd5..51c8332 100644
--- a/generator/google/protobuf/reflection.py
+++ b/generator/google/protobuf/reflection.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -49,104 +49,17 @@
 
 
 from google.protobuf.internal import api_implementation
-from google.protobuf import descriptor as descriptor_mod
 from google.protobuf import message
 
-_FieldDescriptor = descriptor_mod.FieldDescriptor
-
 
 if api_implementation.Type() == 'cpp':
-  if api_implementation.Version() == 2:
-    from google.protobuf.internal.cpp import cpp_message
-    _NewMessage = cpp_message.NewMessage
-    _InitMessage = cpp_message.InitMessage
-  else:
-    from google.protobuf.internal import cpp_message
-    _NewMessage = cpp_message.NewMessage
-    _InitMessage = cpp_message.InitMessage
+  from google.protobuf.pyext import cpp_message as message_impl
 else:
-  from google.protobuf.internal import python_message
-  _NewMessage = python_message.NewMessage
-  _InitMessage = python_message.InitMessage
+  from google.protobuf.internal import python_message as message_impl
 
-
-class GeneratedProtocolMessageType(type):
-
-  """Metaclass for protocol message classes created at runtime from Descriptors.
-
-  We add implementations for all methods described in the Message class.  We
-  also create properties to allow getting/setting all fields in the protocol
-  message.  Finally, we create slots to prevent users from accidentally
-  "setting" nonexistent fields in the protocol message, which then wouldn't get
-  serialized / deserialized properly.
-
-  The protocol compiler currently uses this metaclass to create protocol
-  message classes at runtime.  Clients can also manually create their own
-  classes at runtime, as in this example:
-
-  mydescriptor = Descriptor(.....)
-  class MyProtoClass(Message):
-    __metaclass__ = GeneratedProtocolMessageType
-    DESCRIPTOR = mydescriptor
-  myproto_instance = MyProtoClass()
-  myproto.foo_field = 23
-  ...
-  """
-
-  # Must be consistent with the protocol-compiler code in
-  # proto2/compiler/internal/generator.*.
-  _DESCRIPTOR_KEY = 'DESCRIPTOR'
-
-  def __new__(cls, name, bases, dictionary):
-    """Custom allocation for runtime-generated class types.
-
-    We override __new__ because this is apparently the only place
-    where we can meaningfully set __slots__ on the class we're creating(?).
-    (The interplay between metaclasses and slots is not very well-documented).
-
-    Args:
-      name: Name of the class (ignored, but required by the
-        metaclass protocol).
-      bases: Base classes of the class we're constructing.
-        (Should be message.Message).  We ignore this field, but
-        it's required by the metaclass protocol
-      dictionary: The class dictionary of the class we're
-        constructing.  dictionary[_DESCRIPTOR_KEY] must contain
-        a Descriptor object describing this protocol message
-        type.
-
-    Returns:
-      Newly-allocated class.
-    """
-    descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
-    bases = _NewMessage(bases, descriptor, dictionary)
-    superclass = super(GeneratedProtocolMessageType, cls)
-
-    new_class = superclass.__new__(cls, name, bases, dictionary)
-    setattr(descriptor, '_concrete_class', new_class)
-    return new_class
-
-  def __init__(cls, name, bases, dictionary):
-    """Here we perform the majority of our work on the class.
-    We add enum getters, an __init__ method, implementations
-    of all Message methods, and properties for all fields
-    in the protocol type.
-
-    Args:
-      name: Name of the class (ignored, but required by the
-        metaclass protocol).
-      bases: Base classes of the class we're constructing.
-        (Should be message.Message).  We ignore this field, but
-        it's required by the metaclass protocol
-      dictionary: The class dictionary of the class we're
-        constructing.  dictionary[_DESCRIPTOR_KEY] must contain
-        a Descriptor object describing this protocol message
-        type.
-    """
-    descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
-    _InitMessage(descriptor, cls)
-    superclass = super(GeneratedProtocolMessageType, cls)
-    superclass.__init__(name, bases, dictionary)
+# The type of all Message classes.
+# Part of the public interface, but normally only used by message factories.
+GeneratedProtocolMessageType = message_impl.GeneratedProtocolMessageType
 
 
 def ParseMessage(descriptor, byte_str):
@@ -159,11 +72,43 @@
   Returns:
     Newly created protobuf Message object.
   """
-
-  class _ResultClass(message.Message):
-    __metaclass__ = GeneratedProtocolMessageType
-    DESCRIPTOR = descriptor
-
-  new_msg = _ResultClass()
+  result_class = MakeClass(descriptor)
+  new_msg = result_class()
   new_msg.ParseFromString(byte_str)
   return new_msg
+
+
+def MakeClass(descriptor):
+  """Construct a class object for a protobuf described by descriptor.
+
+  Composite descriptors are handled by defining the new class as a member of the
+  parent class, recursing as deep as necessary.
+  This is the dynamic equivalent to:
+
+  class Parent(message.Message):
+    __metaclass__ = GeneratedProtocolMessageType
+    DESCRIPTOR = descriptor
+    class Child(message.Message):
+      __metaclass__ = GeneratedProtocolMessageType
+      DESCRIPTOR = descriptor.nested_types[0]
+
+  Sample usage:
+    file_descriptor = descriptor_pb2.FileDescriptorProto()
+    file_descriptor.ParseFromString(proto2_string)
+    msg_descriptor = descriptor.MakeDescriptor(file_descriptor.message_type[0])
+    msg_class = reflection.MakeClass(msg_descriptor)
+    msg = msg_class()
+
+  Args:
+    descriptor: A descriptor.Descriptor object describing the protobuf.
+  Returns:
+    The Message class object described by the descriptor.
+  """
+  attributes = {}
+  for name, nested_type in descriptor.nested_types_by_name.items():
+    attributes[name] = MakeClass(nested_type)
+
+  attributes[GeneratedProtocolMessageType._DESCRIPTOR_KEY] = descriptor
+
+  return GeneratedProtocolMessageType(str(descriptor.name), (message.Message,),
+                                      attributes)
diff --git a/generator/google/protobuf/service.py b/generator/google/protobuf/service.py
index 180b70e..9e00de7 100644
--- a/generator/google/protobuf/service.py
+++ b/generator/google/protobuf/service.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
diff --git a/generator/google/protobuf/service_reflection.py b/generator/google/protobuf/service_reflection.py
index 851e83e..1c3636a 100644
--- a/generator/google/protobuf/service_reflection.py
+++ b/generator/google/protobuf/service_reflection.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
diff --git a/generator/google/protobuf/source_context_pb2.py b/generator/google/protobuf/source_context_pb2.py
new file mode 100644
index 0000000..6527294
--- /dev/null
+++ b/generator/google/protobuf/source_context_pb2.py
@@ -0,0 +1,71 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/source_context.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/source_context.proto',
+  package='google.protobuf',
+  syntax='proto3',
+  serialized_pb=_b('\n$google/protobuf/source_context.proto\x12\x0fgoogle.protobuf\"\"\n\rSourceContext\x12\x11\n\tfile_name\x18\x01 \x01(\tBU\n\x13\x63om.google.protobufB\x12SourceContextProtoP\x01\xa0\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_SOURCECONTEXT = _descriptor.Descriptor(
+  name='SourceContext',
+  full_name='google.protobuf.SourceContext',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='file_name', full_name='google.protobuf.SourceContext.file_name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=57,
+  serialized_end=91,
+)
+
+DESCRIPTOR.message_types_by_name['SourceContext'] = _SOURCECONTEXT
+
+SourceContext = _reflection.GeneratedProtocolMessageType('SourceContext', (_message.Message,), dict(
+  DESCRIPTOR = _SOURCECONTEXT,
+  __module__ = 'google.protobuf.source_context_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.SourceContext)
+  ))
+_sym_db.RegisterMessage(SourceContext)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\023com.google.protobufB\022SourceContextProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/struct_pb2.py b/generator/google/protobuf/struct_pb2.py
new file mode 100644
index 0000000..b38975a
--- /dev/null
+++ b/generator/google/protobuf/struct_pb2.py
@@ -0,0 +1,281 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/struct.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/struct.proto',
+  package='google.protobuf',
+  syntax='proto3',
+  serialized_pb=_b('\n\x1cgoogle/protobuf/struct.proto\x12\x0fgoogle.protobuf\"\x84\x01\n\x06Struct\x12\x33\n\x06\x66ields\x18\x01 \x03(\x0b\x32#.google.protobuf.Struct.FieldsEntry\x1a\x45\n\x0b\x46ieldsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.Value:\x02\x38\x01\"\xea\x01\n\x05Value\x12\x30\n\nnull_value\x18\x01 \x01(\x0e\x32\x1a.google.protobuf.NullValueH\x00\x12\x16\n\x0cnumber_value\x18\x02 \x01(\x01H\x00\x12\x16\n\x0cstring_value\x18\x03 \x01(\tH\x00\x12\x14\n\nbool_value\x18\x04 \x01(\x08H\x00\x12/\n\x0cstruct_value\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructH\x00\x12\x30\n\nlist_value\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.ListValueH\x00\x42\x06\n\x04kind\"3\n\tListValue\x12&\n\x06values\x18\x01 \x03(\x0b\x32\x16.google.protobuf.Value*\x1b\n\tNullValue\x12\x0e\n\nNULL_VALUE\x10\x00\x42\x81\x01\n\x13\x63om.google.protobufB\x0bStructProtoP\x01Z1github.com/golang/protobuf/ptypes/struct;structpb\xa0\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+_NULLVALUE = _descriptor.EnumDescriptor(
+  name='NullValue',
+  full_name='google.protobuf.NullValue',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='NULL_VALUE', index=0, number=0,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=474,
+  serialized_end=501,
+)
+_sym_db.RegisterEnumDescriptor(_NULLVALUE)
+
+NullValue = enum_type_wrapper.EnumTypeWrapper(_NULLVALUE)
+NULL_VALUE = 0
+
+
+
+_STRUCT_FIELDSENTRY = _descriptor.Descriptor(
+  name='FieldsEntry',
+  full_name='google.protobuf.Struct.FieldsEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='google.protobuf.Struct.FieldsEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.Struct.FieldsEntry.value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=113,
+  serialized_end=182,
+)
+
+_STRUCT = _descriptor.Descriptor(
+  name='Struct',
+  full_name='google.protobuf.Struct',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='fields', full_name='google.protobuf.Struct.fields', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_STRUCT_FIELDSENTRY, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=50,
+  serialized_end=182,
+)
+
+
+_VALUE = _descriptor.Descriptor(
+  name='Value',
+  full_name='google.protobuf.Value',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='null_value', full_name='google.protobuf.Value.null_value', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='number_value', full_name='google.protobuf.Value.number_value', index=1,
+      number=2, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='string_value', full_name='google.protobuf.Value.string_value', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bool_value', full_name='google.protobuf.Value.bool_value', index=3,
+      number=4, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='struct_value', full_name='google.protobuf.Value.struct_value', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='list_value', full_name='google.protobuf.Value.list_value', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='kind', full_name='google.protobuf.Value.kind',
+      index=0, containing_type=None, fields=[]),
+  ],
+  serialized_start=185,
+  serialized_end=419,
+)
+
+
+_LISTVALUE = _descriptor.Descriptor(
+  name='ListValue',
+  full_name='google.protobuf.ListValue',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='values', full_name='google.protobuf.ListValue.values', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=421,
+  serialized_end=472,
+)
+
+_STRUCT_FIELDSENTRY.fields_by_name['value'].message_type = _VALUE
+_STRUCT_FIELDSENTRY.containing_type = _STRUCT
+_STRUCT.fields_by_name['fields'].message_type = _STRUCT_FIELDSENTRY
+_VALUE.fields_by_name['null_value'].enum_type = _NULLVALUE
+_VALUE.fields_by_name['struct_value'].message_type = _STRUCT
+_VALUE.fields_by_name['list_value'].message_type = _LISTVALUE
+_VALUE.oneofs_by_name['kind'].fields.append(
+  _VALUE.fields_by_name['null_value'])
+_VALUE.fields_by_name['null_value'].containing_oneof = _VALUE.oneofs_by_name['kind']
+_VALUE.oneofs_by_name['kind'].fields.append(
+  _VALUE.fields_by_name['number_value'])
+_VALUE.fields_by_name['number_value'].containing_oneof = _VALUE.oneofs_by_name['kind']
+_VALUE.oneofs_by_name['kind'].fields.append(
+  _VALUE.fields_by_name['string_value'])
+_VALUE.fields_by_name['string_value'].containing_oneof = _VALUE.oneofs_by_name['kind']
+_VALUE.oneofs_by_name['kind'].fields.append(
+  _VALUE.fields_by_name['bool_value'])
+_VALUE.fields_by_name['bool_value'].containing_oneof = _VALUE.oneofs_by_name['kind']
+_VALUE.oneofs_by_name['kind'].fields.append(
+  _VALUE.fields_by_name['struct_value'])
+_VALUE.fields_by_name['struct_value'].containing_oneof = _VALUE.oneofs_by_name['kind']
+_VALUE.oneofs_by_name['kind'].fields.append(
+  _VALUE.fields_by_name['list_value'])
+_VALUE.fields_by_name['list_value'].containing_oneof = _VALUE.oneofs_by_name['kind']
+_LISTVALUE.fields_by_name['values'].message_type = _VALUE
+DESCRIPTOR.message_types_by_name['Struct'] = _STRUCT
+DESCRIPTOR.message_types_by_name['Value'] = _VALUE
+DESCRIPTOR.message_types_by_name['ListValue'] = _LISTVALUE
+DESCRIPTOR.enum_types_by_name['NullValue'] = _NULLVALUE
+
+Struct = _reflection.GeneratedProtocolMessageType('Struct', (_message.Message,), dict(
+
+  FieldsEntry = _reflection.GeneratedProtocolMessageType('FieldsEntry', (_message.Message,), dict(
+    DESCRIPTOR = _STRUCT_FIELDSENTRY,
+    __module__ = 'google.protobuf.struct_pb2'
+    # @@protoc_insertion_point(class_scope:google.protobuf.Struct.FieldsEntry)
+    ))
+  ,
+  DESCRIPTOR = _STRUCT,
+  __module__ = 'google.protobuf.struct_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Struct)
+  ))
+_sym_db.RegisterMessage(Struct)
+_sym_db.RegisterMessage(Struct.FieldsEntry)
+
+Value = _reflection.GeneratedProtocolMessageType('Value', (_message.Message,), dict(
+  DESCRIPTOR = _VALUE,
+  __module__ = 'google.protobuf.struct_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Value)
+  ))
+_sym_db.RegisterMessage(Value)
+
+ListValue = _reflection.GeneratedProtocolMessageType('ListValue', (_message.Message,), dict(
+  DESCRIPTOR = _LISTVALUE,
+  __module__ = 'google.protobuf.struct_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.ListValue)
+  ))
+_sym_db.RegisterMessage(ListValue)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\023com.google.protobufB\013StructProtoP\001Z1github.com/golang/protobuf/ptypes/struct;structpb\240\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes'))
+_STRUCT_FIELDSENTRY.has_options = True
+_STRUCT_FIELDSENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/symbol_database.py b/generator/google/protobuf/symbol_database.py
new file mode 100644
index 0000000..aa466ab
--- /dev/null
+++ b/generator/google/protobuf/symbol_database.py
@@ -0,0 +1,169 @@
+# 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.
+
+"""A database of Python protocol buffer generated symbols.
+
+SymbolDatabase is the MessageFactory for messages generated at compile time,
+and makes it easy to create new instances of a registered type, given only the
+type's protocol buffer symbol name.
+
+Example usage:
+
+  db = symbol_database.SymbolDatabase()
+
+  # Register symbols of interest, from one or multiple files.
+  db.RegisterFileDescriptor(my_proto_pb2.DESCRIPTOR)
+  db.RegisterMessage(my_proto_pb2.MyMessage)
+  db.RegisterEnumDescriptor(my_proto_pb2.MyEnum.DESCRIPTOR)
+
+  # The database can be used as a MessageFactory, to generate types based on
+  # their name:
+  types = db.GetMessages(['my_proto.proto'])
+  my_message_instance = types['MyMessage']()
+
+  # The database's underlying descriptor pool can be queried, so it's not
+  # necessary to know a type's filename to be able to generate it:
+  filename = db.pool.FindFileContainingSymbol('MyMessage')
+  my_message_instance = db.GetMessages([filename])['MyMessage']()
+
+  # This functionality is also provided directly via a convenience method:
+  my_message_instance = db.GetSymbol('MyMessage')()
+"""
+
+
+from google.protobuf import descriptor_pool
+from google.protobuf import message_factory
+
+
+class SymbolDatabase(message_factory.MessageFactory):
+  """A database of Python generated symbols."""
+
+  def RegisterMessage(self, message):
+    """Registers the given message type in the local database.
+
+    Calls to GetSymbol() and GetMessages() will return messages registered here.
+
+    Args:
+      message: a message.Message, to be registered.
+
+    Returns:
+      The provided message.
+    """
+
+    desc = message.DESCRIPTOR
+    self._classes[desc.full_name] = message
+    self.pool.AddDescriptor(desc)
+    return message
+
+  def RegisterEnumDescriptor(self, enum_descriptor):
+    """Registers the given enum descriptor in the local database.
+
+    Args:
+      enum_descriptor: a descriptor.EnumDescriptor.
+
+    Returns:
+      The provided descriptor.
+    """
+    self.pool.AddEnumDescriptor(enum_descriptor)
+    return enum_descriptor
+
+  def RegisterFileDescriptor(self, file_descriptor):
+    """Registers the given file descriptor in the local database.
+
+    Args:
+      file_descriptor: a descriptor.FileDescriptor.
+
+    Returns:
+      The provided descriptor.
+    """
+    self.pool.AddFileDescriptor(file_descriptor)
+
+  def GetSymbol(self, symbol):
+    """Tries to find a symbol in the local database.
+
+    Currently, this method only returns message.Message instances, however, if
+    may be extended in future to support other symbol types.
+
+    Args:
+      symbol: A str, a protocol buffer symbol.
+
+    Returns:
+      A Python class corresponding to the symbol.
+
+    Raises:
+      KeyError: if the symbol could not be found.
+    """
+
+    return self._classes[symbol]
+
+  def GetMessages(self, files):
+    # TODO(amauryfa): Fix the differences with MessageFactory.
+    """Gets all registered messages from a specified file.
+
+    Only messages already created and registered will be returned; (this is the
+    case for imported _pb2 modules)
+    But unlike MessageFactory, this version also returns nested messages.
+
+    Args:
+      files: The file names to extract messages from.
+
+    Returns:
+      A dictionary mapping proto names to the message classes.
+
+    Raises:
+      KeyError: if a file could not be found.
+    """
+
+    def _GetAllMessageNames(desc):
+      """Walk a message Descriptor and recursively yields all message names."""
+      yield desc.full_name
+      for msg_desc in desc.nested_types:
+        for full_name in _GetAllMessageNames(msg_desc):
+          yield full_name
+
+    result = {}
+    for file_name in files:
+      file_desc = self.pool.FindFileByName(file_name)
+      for msg_desc in file_desc.message_types_by_name.values():
+        for full_name in _GetAllMessageNames(msg_desc):
+          try:
+            result[full_name] = self._classes[full_name]
+          except KeyError:
+            # This descriptor has no registered class, skip it.
+            pass
+    return result
+
+
+_DEFAULT = SymbolDatabase(pool=descriptor_pool.Default())
+
+
+def Default():
+  """Returns the default SymbolDatabase."""
+  return _DEFAULT
diff --git a/generator/google/protobuf/text_encoding.py b/generator/google/protobuf/text_encoding.py
new file mode 100644
index 0000000..9899563
--- /dev/null
+++ b/generator/google/protobuf/text_encoding.py
@@ -0,0 +1,107 @@
+# 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.
+
+"""Encoding related utilities."""
+import re
+
+import six
+
+# Lookup table for utf8
+_cescape_utf8_to_str = [chr(i) for i in range(0, 256)]
+_cescape_utf8_to_str[9] = r'\t'  # optional escape
+_cescape_utf8_to_str[10] = r'\n'  # optional escape
+_cescape_utf8_to_str[13] = r'\r'  # optional escape
+_cescape_utf8_to_str[39] = r"\'"  # optional escape
+
+_cescape_utf8_to_str[34] = r'\"'  # necessary escape
+_cescape_utf8_to_str[92] = r'\\'  # necessary escape
+
+# Lookup table for non-utf8, with necessary escapes at (o >= 127 or o < 32)
+_cescape_byte_to_str = ([r'\%03o' % i for i in range(0, 32)] +
+                        [chr(i) for i in range(32, 127)] +
+                        [r'\%03o' % i for i in range(127, 256)])
+_cescape_byte_to_str[9] = r'\t'  # optional escape
+_cescape_byte_to_str[10] = r'\n'  # optional escape
+_cescape_byte_to_str[13] = r'\r'  # optional escape
+_cescape_byte_to_str[39] = r"\'"  # optional escape
+
+_cescape_byte_to_str[34] = r'\"'  # necessary escape
+_cescape_byte_to_str[92] = r'\\'  # necessary escape
+
+
+def CEscape(text, as_utf8):
+  """Escape a bytes string for use in an ascii protocol buffer.
+
+  text.encode('string_escape') does not seem to satisfy our needs as it
+  encodes unprintable characters using two-digit hex escapes whereas our
+  C++ unescaping function allows hex escapes to be any length.  So,
+  "\0011".encode('string_escape') ends up being "\\x011", which will be
+  decoded in C++ as a single-character string with char code 0x11.
+
+  Args:
+    text: A byte string to be escaped
+    as_utf8: Specifies if result should be returned in UTF-8 encoding
+  Returns:
+    Escaped string
+  """
+  # PY3 hack: make Ord work for str and bytes:
+  # //platforms/networking/data uses unicode here, hence basestring.
+  Ord = ord if isinstance(text, six.string_types) else lambda x: x
+  if as_utf8:
+    return ''.join(_cescape_utf8_to_str[Ord(c)] for c in text)
+  return ''.join(_cescape_byte_to_str[Ord(c)] for c in text)
+
+
+_CUNESCAPE_HEX = re.compile(r'(\\+)x([0-9a-fA-F])(?![0-9a-fA-F])')
+_cescape_highbit_to_str = ([chr(i) for i in range(0, 127)] +
+                           [r'\%03o' % i for i in range(127, 256)])
+
+
+def CUnescape(text):
+  """Unescape a text string with C-style escape sequences to UTF-8 bytes."""
+
+  def ReplaceHex(m):
+    # Only replace the match if the number of leading back slashes is odd. i.e.
+    # the slash itself is not escaped.
+    if len(m.group(1)) & 1:
+      return m.group(1) + 'x0' + m.group(2)
+    return m.group(0)
+
+  # This is required because the 'string_escape' encoding doesn't
+  # allow single-digit hex escapes (like '\xf').
+  result = _CUNESCAPE_HEX.sub(ReplaceHex, text)
+
+  if str is bytes:  # PY2
+    return result.decode('string_escape')
+  result = ''.join(_cescape_highbit_to_str[ord(c)] for c in result)
+  return (result.encode('ascii')  # Make it bytes to allow decode.
+          .decode('unicode_escape')
+          # Make it bytes again to return the proper type.
+          .encode('raw_unicode_escape'))
diff --git a/generator/google/protobuf/text_format.py b/generator/google/protobuf/text_format.py
index 24dd07f..06b79d7 100644
--- a/generator/google/protobuf/text_format.py
+++ b/generator/google/protobuf/text_format.py
@@ -1,6 +1,6 @@
 # Protocol Buffers - Google's data interchange format
 # Copyright 2008 Google Inc.  All rights reserved.
-# http://code.google.com/p/protobuf/
+# 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
@@ -28,20 +28,35 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-"""Contains routines for printing protocol messages in text format."""
+"""Contains routines for printing protocol messages in text format.
+
+Simple usage example:
+
+  # Create a proto object and serialize it to a text proto string.
+  message = my_proto_pb2.MyMessage(foo='bar')
+  text_proto = text_format.MessageToString(message)
+
+  # Parse a text proto string.
+  message = text_format.Parse(text_proto, my_proto_pb2.MyMessage())
+"""
 
 __author__ = 'kenton@google.com (Kenton Varda)'
 
-import cStringIO
+import io
 import re
 
-from collections import deque
+import six
+
+if six.PY3:
+  long = int  # pylint: disable=redefined-builtin,invalid-name
+
+# pylint: disable=g-import-not-at-top
 from google.protobuf.internal import type_checkers
 from google.protobuf import descriptor
+from google.protobuf import text_encoding
 
-__all__ = [ 'MessageToString', 'PrintMessage', 'PrintField',
-            'PrintFieldValue', 'Merge' ]
-
+__all__ = ['MessageToString', 'PrintMessage', 'PrintField', 'PrintFieldValue',
+           'Merge']
 
 _INTEGER_CHECKERS = (type_checkers.Uint32ValueChecker(),
                      type_checkers.Int32ValueChecker(),
@@ -49,15 +64,99 @@
                      type_checkers.Int64ValueChecker())
 _FLOAT_INFINITY = re.compile('-?inf(?:inity)?f?', re.IGNORECASE)
 _FLOAT_NAN = re.compile('nanf?', re.IGNORECASE)
+_FLOAT_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_FLOAT,
+                          descriptor.FieldDescriptor.CPPTYPE_DOUBLE])
+_QUOTES = frozenset(("'", '"'))
+_ANY_FULL_TYPE_NAME = 'google.protobuf.Any'
 
 
-class ParseError(Exception):
-  """Thrown in case of ASCII parsing error."""
+class Error(Exception):
+  """Top-level module error for text_format."""
 
 
-def MessageToString(message, as_utf8=False, as_one_line=False):
-  out = cStringIO.StringIO()
-  PrintMessage(message, out, as_utf8=as_utf8, as_one_line=as_one_line)
+class ParseError(Error):
+  """Thrown in case of text parsing or tokenizing error."""
+
+  def __init__(self, message=None, line=None, column=None):
+    if message is not None and line is not None:
+      loc = str(line)
+      if column is not None:
+        loc += ':{0}'.format(column)
+      message = '{0} : {1}'.format(loc, message)
+    if message is not None:
+      super(ParseError, self).__init__(message)
+    else:
+      super(ParseError, self).__init__()
+    self._line = line
+    self._column = column
+
+  def GetLine(self):
+    return self._line
+
+  def GetColumn(self):
+    return self._column
+
+
+class TextWriter(object):
+
+  def __init__(self, as_utf8):
+    if six.PY2:
+      self._writer = io.BytesIO()
+    else:
+      self._writer = io.StringIO()
+
+  def write(self, val):
+    if six.PY2:
+      if isinstance(val, six.text_type):
+        val = val.encode('utf-8')
+    return self._writer.write(val)
+
+  def close(self):
+    return self._writer.close()
+
+  def getvalue(self):
+    return self._writer.getvalue()
+
+
+def MessageToString(message,
+                    as_utf8=False,
+                    as_one_line=False,
+                    pointy_brackets=False,
+                    use_index_order=False,
+                    float_format=None,
+                    use_field_number=False,
+                    descriptor_pool=None,
+                    indent=0):
+  """Convert protobuf message to text format.
+
+  Floating point values can be formatted compactly with 15 digits of
+  precision (which is the most that IEEE 754 "double" can guarantee)
+  using float_format='.15g'. To ensure that converting to text and back to a
+  proto will result in an identical value, float_format='.17g' should be used.
+
+  Args:
+    message: The protocol buffers message.
+    as_utf8: Produce text output in UTF8 format.
+    as_one_line: Don't introduce newlines between fields.
+    pointy_brackets: If True, use angle brackets instead of curly braces for
+      nesting.
+    use_index_order: If True, print fields of a proto message using the order
+      defined in source code instead of the field number. By default, use the
+      field number order.
+    float_format: If set, use this to specify floating point number formatting
+      (per the "Format Specification Mini-Language"); otherwise, str() is used.
+    use_field_number: If True, print field numbers instead of names.
+    descriptor_pool: A DescriptorPool used to resolve Any types.
+    indent: The indent level, in terms of spaces, for pretty print.
+
+  Returns:
+    A string of the text formatted protocol buffer message.
+  """
+  out = TextWriter(as_utf8)
+  printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets,
+                     use_index_order, float_format, use_field_number,
+                     descriptor_pool)
+  printer.PrintMessage(message)
   result = out.getvalue()
   out.close()
   if as_one_line:
@@ -65,152 +164,553 @@
   return result
 
 
-def PrintMessage(message, out, indent=0, as_utf8=False, as_one_line=False):
-  for field, value in message.ListFields():
-    if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
-      for element in value:
-        PrintField(field, element, out, indent, as_utf8, as_one_line)
+def _IsMapEntry(field):
+  return (field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
+          field.message_type.has_options and
+          field.message_type.GetOptions().map_entry)
+
+
+def PrintMessage(message,
+                 out,
+                 indent=0,
+                 as_utf8=False,
+                 as_one_line=False,
+                 pointy_brackets=False,
+                 use_index_order=False,
+                 float_format=None,
+                 use_field_number=False,
+                 descriptor_pool=None):
+  printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets,
+                     use_index_order, float_format, use_field_number,
+                     descriptor_pool)
+  printer.PrintMessage(message)
+
+
+def PrintField(field,
+               value,
+               out,
+               indent=0,
+               as_utf8=False,
+               as_one_line=False,
+               pointy_brackets=False,
+               use_index_order=False,
+               float_format=None):
+  """Print a single field name/value pair."""
+  printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets,
+                     use_index_order, float_format)
+  printer.PrintField(field, value)
+
+
+def PrintFieldValue(field,
+                    value,
+                    out,
+                    indent=0,
+                    as_utf8=False,
+                    as_one_line=False,
+                    pointy_brackets=False,
+                    use_index_order=False,
+                    float_format=None):
+  """Print a single field value (not including name)."""
+  printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets,
+                     use_index_order, float_format)
+  printer.PrintFieldValue(field, value)
+
+
+def _BuildMessageFromTypeName(type_name, descriptor_pool):
+  """Returns a protobuf message instance.
+
+  Args:
+    type_name: Fully-qualified protobuf  message type name string.
+    descriptor_pool: DescriptorPool instance.
+
+  Returns:
+    A Message instance of type matching type_name, or None if the a Descriptor
+    wasn't found matching type_name.
+  """
+  # pylint: disable=g-import-not-at-top
+  from google.protobuf import message_factory
+  factory = message_factory.MessageFactory(descriptor_pool)
+  try:
+    message_descriptor = descriptor_pool.FindMessageTypeByName(type_name)
+  except KeyError:
+    return None
+  message_type = factory.GetPrototype(message_descriptor)
+  return message_type()
+
+
+class _Printer(object):
+  """Text format printer for protocol message."""
+
+  def __init__(self,
+               out,
+               indent=0,
+               as_utf8=False,
+               as_one_line=False,
+               pointy_brackets=False,
+               use_index_order=False,
+               float_format=None,
+               use_field_number=False,
+               descriptor_pool=None):
+    """Initialize the Printer.
+
+    Floating point values can be formatted compactly with 15 digits of
+    precision (which is the most that IEEE 754 "double" can guarantee)
+    using float_format='.15g'. To ensure that converting to text and back to a
+    proto will result in an identical value, float_format='.17g' should be used.
+
+    Args:
+      out: To record the text format result.
+      indent: The indent level for pretty print.
+      as_utf8: Produce text output in UTF8 format.
+      as_one_line: Don't introduce newlines between fields.
+      pointy_brackets: If True, use angle brackets instead of curly braces for
+        nesting.
+      use_index_order: If True, print fields of a proto message using the order
+        defined in source code instead of the field number. By default, use the
+        field number order.
+      float_format: If set, use this to specify floating point number formatting
+        (per the "Format Specification Mini-Language"); otherwise, str() is
+        used.
+      use_field_number: If True, print field numbers instead of names.
+      descriptor_pool: A DescriptorPool used to resolve Any types.
+    """
+    self.out = out
+    self.indent = indent
+    self.as_utf8 = as_utf8
+    self.as_one_line = as_one_line
+    self.pointy_brackets = pointy_brackets
+    self.use_index_order = use_index_order
+    self.float_format = float_format
+    self.use_field_number = use_field_number
+    self.descriptor_pool = descriptor_pool
+
+  def _TryPrintAsAnyMessage(self, message):
+    """Serializes if message is a google.protobuf.Any field."""
+    packed_message = _BuildMessageFromTypeName(message.TypeName(),
+                                               self.descriptor_pool)
+    if packed_message:
+      packed_message.MergeFromString(message.value)
+      self.out.write('%s[%s]' % (self.indent * ' ', message.type_url))
+      self._PrintMessageFieldValue(packed_message)
+      self.out.write(' ' if self.as_one_line else '\n')
+      return True
     else:
-      PrintField(field, value, out, indent, as_utf8, as_one_line)
+      return False
 
+  def PrintMessage(self, message):
+    """Convert protobuf message to text format.
 
-def PrintField(field, value, out, indent=0, as_utf8=False, as_one_line=False):
-  """Print a single field name/value pair.  For repeated fields, the value
-  should be a single element."""
+    Args:
+      message: The protocol buffers message.
+    """
+    if (message.DESCRIPTOR.full_name == _ANY_FULL_TYPE_NAME and
+        self.descriptor_pool and self._TryPrintAsAnyMessage(message)):
+      return
+    fields = message.ListFields()
+    if self.use_index_order:
+      fields.sort(key=lambda x: x[0].index)
+    for field, value in fields:
+      if _IsMapEntry(field):
+        for key in sorted(value):
+          # This is slow for maps with submessage entires because it copies the
+          # entire tree.  Unfortunately this would take significant refactoring
+          # of this file to work around.
+          #
+          # TODO(haberman): refactor and optimize if this becomes an issue.
+          entry_submsg = field.message_type._concrete_class(key=key,
+                                                            value=value[key])
+          self.PrintField(field, entry_submsg)
+      elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+        for element in value:
+          self.PrintField(field, element)
+      else:
+        self.PrintField(field, value)
 
-  out.write(' ' * indent);
-  if field.is_extension:
-    out.write('[')
-    if (field.containing_type.GetOptions().message_set_wire_format and
-        field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
-        field.message_type == field.extension_scope and
-        field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL):
-      out.write(field.message_type.full_name)
+  def PrintField(self, field, value):
+    """Print a single field name/value pair."""
+    out = self.out
+    out.write(' ' * self.indent)
+    if self.use_field_number:
+      out.write(str(field.number))
     else:
-      out.write(field.full_name)
-    out.write(']')
-  elif field.type == descriptor.FieldDescriptor.TYPE_GROUP:
-    # For groups, use the capitalized name.
-    out.write(field.message_type.name)
-  else:
-    out.write(field.name)
+      if field.is_extension:
+        out.write('[')
+        if (field.containing_type.GetOptions().message_set_wire_format and
+            field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
+            field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL):
+          out.write(field.message_type.full_name)
+        else:
+          out.write(field.full_name)
+        out.write(']')
+      elif field.type == descriptor.FieldDescriptor.TYPE_GROUP:
+        # For groups, use the capitalized name.
+        out.write(field.message_type.name)
+      else:
+        out.write(field.name)
 
-  if field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
-    # The colon is optional in this case, but our cross-language golden files
-    # don't include it.
-    out.write(': ')
+    if field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+      # The colon is optional in this case, but our cross-language golden files
+      # don't include it.
+      out.write(': ')
 
-  PrintFieldValue(field, value, out, indent, as_utf8, as_one_line)
-  if as_one_line:
-    out.write(' ')
-  else:
-    out.write('\n')
-
-
-def PrintFieldValue(field, value, out, indent=0,
-                    as_utf8=False, as_one_line=False):
-  """Print a single field value (not including name).  For repeated fields,
-  the value should be a single element."""
-
-  if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
-    if as_one_line:
-      out.write(' { ')
-      PrintMessage(value, out, indent, as_utf8, as_one_line)
-      out.write('}')
+    self.PrintFieldValue(field, value)
+    if self.as_one_line:
+      out.write(' ')
     else:
-      out.write(' {\n')
-      PrintMessage(value, out, indent + 2, as_utf8, as_one_line)
-      out.write(' ' * indent + '}')
-  elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
-    enum_value = field.enum_type.values_by_number.get(value, None)
-    if enum_value is not None:
-      out.write(enum_value.name)
+      out.write('\n')
+
+  def _PrintMessageFieldValue(self, value):
+    if self.pointy_brackets:
+      openb = '<'
+      closeb = '>'
+    else:
+      openb = '{'
+      closeb = '}'
+
+    if self.as_one_line:
+      self.out.write(' %s ' % openb)
+      self.PrintMessage(value)
+      self.out.write(closeb)
+    else:
+      self.out.write(' %s\n' % openb)
+      self.indent += 2
+      self.PrintMessage(value)
+      self.indent -= 2
+      self.out.write(' ' * self.indent + closeb)
+
+  def PrintFieldValue(self, field, value):
+    """Print a single field value (not including name).
+
+    For repeated fields, the value should be a single element.
+
+    Args:
+      field: The descriptor of the field to be printed.
+      value: The value of the field.
+    """
+    out = self.out
+    if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+      self._PrintMessageFieldValue(value)
+    elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
+      enum_value = field.enum_type.values_by_number.get(value, None)
+      if enum_value is not None:
+        out.write(enum_value.name)
+      else:
+        out.write(str(value))
+    elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING:
+      out.write('\"')
+      if isinstance(value, six.text_type):
+        out_value = value.encode('utf-8')
+      else:
+        out_value = value
+      if field.type == descriptor.FieldDescriptor.TYPE_BYTES:
+        # We need to escape non-UTF8 chars in TYPE_BYTES field.
+        out_as_utf8 = False
+      else:
+        out_as_utf8 = self.as_utf8
+      out.write(text_encoding.CEscape(out_value, out_as_utf8))
+      out.write('\"')
+    elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL:
+      if value:
+        out.write('true')
+      else:
+        out.write('false')
+    elif field.cpp_type in _FLOAT_TYPES and self.float_format is not None:
+      out.write('{1:{0}}'.format(self.float_format, value))
     else:
       out.write(str(value))
-  elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING:
-    out.write('\"')
-    if type(value) is unicode:
-      out.write(_CEscape(value.encode('utf-8'), as_utf8))
-    else:
-      out.write(_CEscape(value, as_utf8))
-    out.write('\"')
-  elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL:
-    if value:
-      out.write("true")
-    else:
-      out.write("false")
-  else:
-    out.write(str(value))
 
 
-def Merge(text, message):
-  """Merges an ASCII representation of a protocol message into a message.
+def Parse(text,
+          message,
+          allow_unknown_extension=False,
+          allow_field_number=False):
+  """Parses a text representation of a protocol message into a message.
 
   Args:
-    text: Message ASCII representation.
+    text: Message text representation.
     message: A protocol buffer message to merge into.
+    allow_unknown_extension: if True, skip over missing extensions and keep
+      parsing
+    allow_field_number: if True, both field number and field name are allowed.
+
+  Returns:
+    The same message passed as argument.
 
   Raises:
-    ParseError: On ASCII parsing problems.
+    ParseError: On text parsing problems.
   """
-  tokenizer = _Tokenizer(text)
-  while not tokenizer.AtEnd():
-    _MergeField(tokenizer, message)
+  if not isinstance(text, str):
+    text = text.decode('utf-8')
+  return ParseLines(
+      text.split('\n'), message, allow_unknown_extension, allow_field_number)
 
 
-def _MergeField(tokenizer, message):
-  """Merges a single protocol message field into a message.
+def Merge(text,
+          message,
+          allow_unknown_extension=False,
+          allow_field_number=False,
+          descriptor_pool=None):
+  """Parses a text representation of a protocol message into a message.
+
+  Like Parse(), but allows repeated values for a non-repeated field, and uses
+  the last one.
 
   Args:
-    tokenizer: A tokenizer to parse the field name and values.
-    message: A protocol message to record the data.
+    text: Message text representation.
+    message: A protocol buffer message to merge into.
+    allow_unknown_extension: if True, skip over missing extensions and keep
+      parsing
+    allow_field_number: if True, both field number and field name are allowed.
+    descriptor_pool: A DescriptorPool used to resolve Any types.
+
+  Returns:
+    The same message passed as argument.
 
   Raises:
-    ParseError: In case of ASCII parsing problems.
+    ParseError: On text parsing problems.
   """
-  message_descriptor = message.DESCRIPTOR
-  if tokenizer.TryConsume('['):
+  return MergeLines(
+      text.split('\n'),
+      message,
+      allow_unknown_extension,
+      allow_field_number,
+      descriptor_pool=descriptor_pool)
+
+
+def ParseLines(lines,
+               message,
+               allow_unknown_extension=False,
+               allow_field_number=False):
+  """Parses a text representation of a protocol message into a message.
+
+  Args:
+    lines: An iterable of lines of a message's text representation.
+    message: A protocol buffer message to merge into.
+    allow_unknown_extension: if True, skip over missing extensions and keep
+      parsing
+    allow_field_number: if True, both field number and field name are allowed.
+    descriptor_pool: A DescriptorPool used to resolve Any types.
+
+  Returns:
+    The same message passed as argument.
+
+  Raises:
+    ParseError: On text parsing problems.
+  """
+  parser = _Parser(allow_unknown_extension, allow_field_number)
+  return parser.ParseLines(lines, message)
+
+
+def MergeLines(lines,
+               message,
+               allow_unknown_extension=False,
+               allow_field_number=False,
+               descriptor_pool=None):
+  """Parses a text representation of a protocol message into a message.
+
+  Args:
+    lines: An iterable of lines of a message's text representation.
+    message: A protocol buffer message to merge into.
+    allow_unknown_extension: if True, skip over missing extensions and keep
+      parsing
+    allow_field_number: if True, both field number and field name are allowed.
+
+  Returns:
+    The same message passed as argument.
+
+  Raises:
+    ParseError: On text parsing problems.
+  """
+  parser = _Parser(allow_unknown_extension,
+                   allow_field_number,
+                   descriptor_pool=descriptor_pool)
+  return parser.MergeLines(lines, message)
+
+
+class _Parser(object):
+  """Text format parser for protocol message."""
+
+  def __init__(self,
+               allow_unknown_extension=False,
+               allow_field_number=False,
+               descriptor_pool=None):
+    self.allow_unknown_extension = allow_unknown_extension
+    self.allow_field_number = allow_field_number
+    self.descriptor_pool = descriptor_pool
+
+  def ParseFromString(self, text, message):
+    """Parses a text representation of a protocol message into a message."""
+    if not isinstance(text, str):
+      text = text.decode('utf-8')
+    return self.ParseLines(text.split('\n'), message)
+
+  def ParseLines(self, lines, message):
+    """Parses a text representation of a protocol message into a message."""
+    self._allow_multiple_scalars = False
+    self._ParseOrMerge(lines, message)
+    return message
+
+  def MergeFromString(self, text, message):
+    """Merges a text representation of a protocol message into a message."""
+    return self._MergeLines(text.split('\n'), message)
+
+  def MergeLines(self, lines, message):
+    """Merges a text representation of a protocol message into a message."""
+    self._allow_multiple_scalars = True
+    self._ParseOrMerge(lines, message)
+    return message
+
+  def _ParseOrMerge(self, lines, message):
+    """Converts a text representation of a protocol message into a message.
+
+    Args:
+      lines: Lines of a message's text representation.
+      message: A protocol buffer message to merge into.
+
+    Raises:
+      ParseError: On text parsing problems.
+    """
+    tokenizer = Tokenizer(lines)
+    while not tokenizer.AtEnd():
+      self._MergeField(tokenizer, message)
+
+  def _MergeField(self, tokenizer, message):
+    """Merges a single protocol message field into a message.
+
+    Args:
+      tokenizer: A tokenizer to parse the field name and values.
+      message: A protocol message to record the data.
+
+    Raises:
+      ParseError: In case of text parsing problems.
+    """
+    message_descriptor = message.DESCRIPTOR
+    if (hasattr(message_descriptor, 'syntax') and
+        message_descriptor.syntax == 'proto3'):
+      # Proto3 doesn't represent presence so we can't test if multiple
+      # scalars have occurred.  We have to allow them.
+      self._allow_multiple_scalars = True
+    if tokenizer.TryConsume('['):
+      name = [tokenizer.ConsumeIdentifier()]
+      while tokenizer.TryConsume('.'):
+        name.append(tokenizer.ConsumeIdentifier())
+      name = '.'.join(name)
+
+      if not message_descriptor.is_extendable:
+        raise tokenizer.ParseErrorPreviousToken(
+            'Message type "%s" does not have extensions.' %
+            message_descriptor.full_name)
+      # pylint: disable=protected-access
+      field = message.Extensions._FindExtensionByName(name)
+      # pylint: enable=protected-access
+      if not field:
+        if self.allow_unknown_extension:
+          field = None
+        else:
+          raise tokenizer.ParseErrorPreviousToken(
+              'Extension "%s" not registered.' % name)
+      elif message_descriptor != field.containing_type:
+        raise tokenizer.ParseErrorPreviousToken(
+            'Extension "%s" does not extend message type "%s".' %
+            (name, message_descriptor.full_name))
+
+      tokenizer.Consume(']')
+
+    else:
+      name = tokenizer.ConsumeIdentifierOrNumber()
+      if self.allow_field_number and name.isdigit():
+        number = ParseInteger(name, True, True)
+        field = message_descriptor.fields_by_number.get(number, None)
+        if not field and message_descriptor.is_extendable:
+          field = message.Extensions._FindExtensionByNumber(number)
+      else:
+        field = message_descriptor.fields_by_name.get(name, None)
+
+        # Group names are expected to be capitalized as they appear in the
+        # .proto file, which actually matches their type names, not their field
+        # names.
+        if not field:
+          field = message_descriptor.fields_by_name.get(name.lower(), None)
+          if field and field.type != descriptor.FieldDescriptor.TYPE_GROUP:
+            field = None
+
+        if (field and field.type == descriptor.FieldDescriptor.TYPE_GROUP and
+            field.message_type.name != name):
+          field = None
+
+      if not field:
+        raise tokenizer.ParseErrorPreviousToken(
+            'Message type "%s" has no field named "%s".' %
+            (message_descriptor.full_name, name))
+
+    if field:
+      if not self._allow_multiple_scalars and field.containing_oneof:
+        # Check if there's a different field set in this oneof.
+        # Note that we ignore the case if the same field was set before, and we
+        # apply _allow_multiple_scalars to non-scalar fields as well.
+        which_oneof = message.WhichOneof(field.containing_oneof.name)
+        if which_oneof is not None and which_oneof != field.name:
+          raise tokenizer.ParseErrorPreviousToken(
+              'Field "%s" is specified along with field "%s", another member '
+              'of oneof "%s" for message type "%s".' %
+              (field.name, which_oneof, field.containing_oneof.name,
+               message_descriptor.full_name))
+
+      if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+        tokenizer.TryConsume(':')
+        merger = self._MergeMessageField
+      else:
+        tokenizer.Consume(':')
+        merger = self._MergeScalarField
+
+      if (field.label == descriptor.FieldDescriptor.LABEL_REPEATED and
+          tokenizer.TryConsume('[')):
+        # Short repeated format, e.g. "foo: [1, 2, 3]"
+        while True:
+          merger(tokenizer, message, field)
+          if tokenizer.TryConsume(']'):
+            break
+          tokenizer.Consume(',')
+
+      else:
+        merger(tokenizer, message, field)
+
+    else:  # Proto field is unknown.
+      assert self.allow_unknown_extension
+      _SkipFieldContents(tokenizer)
+
+    # For historical reasons, fields may optionally be separated by commas or
+    # semicolons.
+    if not tokenizer.TryConsume(','):
+      tokenizer.TryConsume(';')
+
+  def _ConsumeAnyTypeUrl(self, tokenizer):
+    """Consumes a google.protobuf.Any type URL and returns the type name."""
+    # Consume "type.googleapis.com/".
+    tokenizer.ConsumeIdentifier()
+    tokenizer.Consume('.')
+    tokenizer.ConsumeIdentifier()
+    tokenizer.Consume('.')
+    tokenizer.ConsumeIdentifier()
+    tokenizer.Consume('/')
+    # Consume the fully-qualified type name.
     name = [tokenizer.ConsumeIdentifier()]
     while tokenizer.TryConsume('.'):
       name.append(tokenizer.ConsumeIdentifier())
-    name = '.'.join(name)
+    return '.'.join(name)
 
-    if not message_descriptor.is_extendable:
-      raise tokenizer.ParseErrorPreviousToken(
-          'Message type "%s" does not have extensions.' %
-          message_descriptor.full_name)
-    field = message.Extensions._FindExtensionByName(name)
-    if not field:
-      raise tokenizer.ParseErrorPreviousToken(
-          'Extension "%s" not registered.' % name)
-    elif message_descriptor != field.containing_type:
-      raise tokenizer.ParseErrorPreviousToken(
-          'Extension "%s" does not extend message type "%s".' % (
-              name, message_descriptor.full_name))
-    tokenizer.Consume(']')
-  else:
-    name = tokenizer.ConsumeIdentifier()
-    field = message_descriptor.fields_by_name.get(name, None)
+  def _MergeMessageField(self, tokenizer, message, field):
+    """Merges a single scalar field into a message.
 
-    # Group names are expected to be capitalized as they appear in the
-    # .proto file, which actually matches their type names, not their field
-    # names.
-    if not field:
-      field = message_descriptor.fields_by_name.get(name.lower(), None)
-      if field and field.type != descriptor.FieldDescriptor.TYPE_GROUP:
-        field = None
+    Args:
+      tokenizer: A tokenizer to parse the field value.
+      message: The message of which field is a member.
+      field: The descriptor of the field to be merged.
 
-    if (field and field.type == descriptor.FieldDescriptor.TYPE_GROUP and
-        field.message_type.name != name):
-      field = None
-
-    if not field:
-      raise tokenizer.ParseErrorPreviousToken(
-          'Message type "%s" has no field named "%s".' % (
-              message_descriptor.full_name, name))
-
-  if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
-    tokenizer.TryConsume(':')
+    Raises:
+      ParseError: In case of text parsing problems.
+    """
+    is_map_entry = _IsMapEntry(field)
 
     if tokenizer.TryConsume('<'):
       end_token = '>'
@@ -218,9 +718,39 @@
       tokenizer.Consume('{')
       end_token = '}'
 
-    if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+    if (field.message_type.full_name == _ANY_FULL_TYPE_NAME and
+        tokenizer.TryConsume('[')):
+      packed_type_name = self._ConsumeAnyTypeUrl(tokenizer)
+      tokenizer.Consume(']')
+      tokenizer.TryConsume(':')
+      if tokenizer.TryConsume('<'):
+        expanded_any_end_token = '>'
+      else:
+        tokenizer.Consume('{')
+        expanded_any_end_token = '}'
+      if not self.descriptor_pool:
+        raise ParseError('Descriptor pool required to parse expanded Any field')
+      expanded_any_sub_message = _BuildMessageFromTypeName(packed_type_name,
+                                                           self.descriptor_pool)
+      if not expanded_any_sub_message:
+        raise ParseError('Type %s not found in descriptor pool' %
+                         packed_type_name)
+      while not tokenizer.TryConsume(expanded_any_end_token):
+        if tokenizer.AtEnd():
+          raise tokenizer.ParseErrorPreviousToken('Expected "%s".' %
+                                                  (expanded_any_end_token,))
+        self._MergeField(tokenizer, expanded_any_sub_message)
+      if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+        any_message = getattr(message, field.name).add()
+      else:
+        any_message = getattr(message, field.name)
+      any_message.Pack(expanded_any_sub_message)
+    elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
       if field.is_extension:
         sub_message = message.Extensions[field].add()
+      elif is_map_entry:
+        # pylint: disable=protected-access
+        sub_message = field.message_type._concrete_class()
       else:
         sub_message = getattr(message, field.name).add()
     else:
@@ -232,69 +762,167 @@
 
     while not tokenizer.TryConsume(end_token):
       if tokenizer.AtEnd():
-        raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token))
-      _MergeField(tokenizer, sub_message)
-  else:
-    _MergeScalarField(tokenizer, message, field)
+        raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token,))
+      self._MergeField(tokenizer, sub_message)
+
+    if is_map_entry:
+      value_cpptype = field.message_type.fields_by_name['value'].cpp_type
+      if value_cpptype == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+        value = getattr(message, field.name)[sub_message.key]
+        value.MergeFrom(sub_message.value)
+      else:
+        getattr(message, field.name)[sub_message.key] = sub_message.value
+
+  def _MergeScalarField(self, tokenizer, message, field):
+    """Merges a single scalar field into a message.
+
+    Args:
+      tokenizer: A tokenizer to parse the field value.
+      message: A protocol message to record the data.
+      field: The descriptor of the field to be merged.
+
+    Raises:
+      ParseError: In case of text parsing problems.
+      RuntimeError: On runtime errors.
+    """
+    _ = self.allow_unknown_extension
+    value = None
+
+    if field.type in (descriptor.FieldDescriptor.TYPE_INT32,
+                      descriptor.FieldDescriptor.TYPE_SINT32,
+                      descriptor.FieldDescriptor.TYPE_SFIXED32):
+      value = _ConsumeInt32(tokenizer)
+    elif field.type in (descriptor.FieldDescriptor.TYPE_INT64,
+                        descriptor.FieldDescriptor.TYPE_SINT64,
+                        descriptor.FieldDescriptor.TYPE_SFIXED64):
+      value = _ConsumeInt64(tokenizer)
+    elif field.type in (descriptor.FieldDescriptor.TYPE_UINT32,
+                        descriptor.FieldDescriptor.TYPE_FIXED32):
+      value = _ConsumeUint32(tokenizer)
+    elif field.type in (descriptor.FieldDescriptor.TYPE_UINT64,
+                        descriptor.FieldDescriptor.TYPE_FIXED64):
+      value = _ConsumeUint64(tokenizer)
+    elif field.type in (descriptor.FieldDescriptor.TYPE_FLOAT,
+                        descriptor.FieldDescriptor.TYPE_DOUBLE):
+      value = tokenizer.ConsumeFloat()
+    elif field.type == descriptor.FieldDescriptor.TYPE_BOOL:
+      value = tokenizer.ConsumeBool()
+    elif field.type == descriptor.FieldDescriptor.TYPE_STRING:
+      value = tokenizer.ConsumeString()
+    elif field.type == descriptor.FieldDescriptor.TYPE_BYTES:
+      value = tokenizer.ConsumeByteString()
+    elif field.type == descriptor.FieldDescriptor.TYPE_ENUM:
+      value = tokenizer.ConsumeEnum(field)
+    else:
+      raise RuntimeError('Unknown field type %d' % field.type)
+
+    if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+      if field.is_extension:
+        message.Extensions[field].append(value)
+      else:
+        getattr(message, field.name).append(value)
+    else:
+      if field.is_extension:
+        if not self._allow_multiple_scalars and message.HasExtension(field):
+          raise tokenizer.ParseErrorPreviousToken(
+              'Message type "%s" should not have multiple "%s" extensions.' %
+              (message.DESCRIPTOR.full_name, field.full_name))
+        else:
+          message.Extensions[field] = value
+      else:
+        if not self._allow_multiple_scalars and message.HasField(field.name):
+          raise tokenizer.ParseErrorPreviousToken(
+              'Message type "%s" should not have multiple "%s" fields.' %
+              (message.DESCRIPTOR.full_name, field.name))
+        else:
+          setattr(message, field.name, value)
 
 
-def _MergeScalarField(tokenizer, message, field):
-  """Merges a single protocol message scalar field into a message.
+def _SkipFieldContents(tokenizer):
+  """Skips over contents (value or message) of a field.
 
   Args:
-    tokenizer: A tokenizer to parse the field value.
-    message: A protocol message to record the data.
-    field: The descriptor of the field to be merged.
+    tokenizer: A tokenizer to parse the field name and values.
+  """
+  # Try to guess the type of this field.
+  # If this field is not a message, there should be a ":" between the
+  # field name and the field value and also the field value should not
+  # start with "{" or "<" which indicates the beginning of a message body.
+  # If there is no ":" or there is a "{" or "<" after ":", this field has
+  # to be a message or the input is ill-formed.
+  if tokenizer.TryConsume(':') and not tokenizer.LookingAt(
+      '{') and not tokenizer.LookingAt('<'):
+    _SkipFieldValue(tokenizer)
+  else:
+    _SkipFieldMessage(tokenizer)
+
+
+def _SkipField(tokenizer):
+  """Skips over a complete field (name and value/message).
+
+  Args:
+    tokenizer: A tokenizer to parse the field name and values.
+  """
+  if tokenizer.TryConsume('['):
+    # Consume extension name.
+    tokenizer.ConsumeIdentifier()
+    while tokenizer.TryConsume('.'):
+      tokenizer.ConsumeIdentifier()
+    tokenizer.Consume(']')
+  else:
+    tokenizer.ConsumeIdentifier()
+
+  _SkipFieldContents(tokenizer)
+
+  # For historical reasons, fields may optionally be separated by commas or
+  # semicolons.
+  if not tokenizer.TryConsume(','):
+    tokenizer.TryConsume(';')
+
+
+def _SkipFieldMessage(tokenizer):
+  """Skips over a field message.
+
+  Args:
+    tokenizer: A tokenizer to parse the field name and values.
+  """
+
+  if tokenizer.TryConsume('<'):
+    delimiter = '>'
+  else:
+    tokenizer.Consume('{')
+    delimiter = '}'
+
+  while not tokenizer.LookingAt('>') and not tokenizer.LookingAt('}'):
+    _SkipField(tokenizer)
+
+  tokenizer.Consume(delimiter)
+
+
+def _SkipFieldValue(tokenizer):
+  """Skips over a field value.
+
+  Args:
+    tokenizer: A tokenizer to parse the field name and values.
 
   Raises:
-    ParseError: In case of ASCII parsing problems.
-    RuntimeError: On runtime errors.
+    ParseError: In case an invalid field value is found.
   """
-  tokenizer.Consume(':')
-  value = None
+  # String/bytes tokens can come in multiple adjacent string literals.
+  # If we can consume one, consume as many as we can.
+  if tokenizer.TryConsumeByteString():
+    while tokenizer.TryConsumeByteString():
+      pass
+    return
 
-  if field.type in (descriptor.FieldDescriptor.TYPE_INT32,
-                    descriptor.FieldDescriptor.TYPE_SINT32,
-                    descriptor.FieldDescriptor.TYPE_SFIXED32):
-    value = tokenizer.ConsumeInt32()
-  elif field.type in (descriptor.FieldDescriptor.TYPE_INT64,
-                      descriptor.FieldDescriptor.TYPE_SINT64,
-                      descriptor.FieldDescriptor.TYPE_SFIXED64):
-    value = tokenizer.ConsumeInt64()
-  elif field.type in (descriptor.FieldDescriptor.TYPE_UINT32,
-                      descriptor.FieldDescriptor.TYPE_FIXED32):
-    value = tokenizer.ConsumeUint32()
-  elif field.type in (descriptor.FieldDescriptor.TYPE_UINT64,
-                      descriptor.FieldDescriptor.TYPE_FIXED64):
-    value = tokenizer.ConsumeUint64()
-  elif field.type in (descriptor.FieldDescriptor.TYPE_FLOAT,
-                      descriptor.FieldDescriptor.TYPE_DOUBLE):
-    value = tokenizer.ConsumeFloat()
-  elif field.type == descriptor.FieldDescriptor.TYPE_BOOL:
-    value = tokenizer.ConsumeBool()
-  elif field.type == descriptor.FieldDescriptor.TYPE_STRING:
-    value = tokenizer.ConsumeString()
-  elif field.type == descriptor.FieldDescriptor.TYPE_BYTES:
-    value = tokenizer.ConsumeByteString()
-  elif field.type == descriptor.FieldDescriptor.TYPE_ENUM:
-    value = tokenizer.ConsumeEnum(field)
-  else:
-    raise RuntimeError('Unknown field type %d' % field.type)
-
-  if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
-    if field.is_extension:
-      message.Extensions[field].append(value)
-    else:
-      getattr(message, field.name).append(value)
-  else:
-    if field.is_extension:
-      message.Extensions[field] = value
-    else:
-      setattr(message, field.name, value)
+  if (not tokenizer.TryConsumeIdentifier() and
+      not _TryConsumeInt64(tokenizer) and not _TryConsumeUint64(tokenizer) and
+      not tokenizer.TryConsumeFloat()):
+    raise ParseError('Invalid field value: ' + tokenizer.token)
 
 
-class _Tokenizer(object):
-  """Protocol buffer ASCII representation tokenizer.
+class Tokenizer(object):
+  """Protocol buffer text representation tokenizer.
 
   This class handles the lower level string parsing by splitting it into
   meaningful tokens.
@@ -302,50 +930,63 @@
   It was directly ported from the Java protocol buffer API.
   """
 
-  _WHITESPACE = re.compile('(\\s|(#.*$))+', re.MULTILINE)
-  _TOKEN = re.compile(
-      '[a-zA-Z_][0-9a-zA-Z_+-]*|'           # an identifier
-      '[0-9+-][0-9a-zA-Z_.+-]*|'            # a number
-      '\"([^\"\n\\\\]|\\\\.)*(\"|\\\\?$)|'  # a double-quoted string
-      '\'([^\'\n\\\\]|\\\\.)*(\'|\\\\?$)')  # a single-quoted string
-  _IDENTIFIER = re.compile('\w+')
+  _WHITESPACE = re.compile(r'\s+')
+  _COMMENT = re.compile(r'(\s*#.*$)', re.MULTILINE)
+  _WHITESPACE_OR_COMMENT = re.compile(r'(\s|(#.*$))+', re.MULTILINE)
+  _TOKEN = re.compile('|'.join([
+      r'[a-zA-Z_][0-9a-zA-Z_+-]*',  # an identifier
+      r'([0-9+-]|(\.[0-9]))[0-9a-zA-Z_.+-]*',  # a number
+  ] + [  # quoted str for each quote mark
+      r'{qt}([^{qt}\n\\]|\\.)*({qt}|\\?$)'.format(qt=mark) for mark in _QUOTES
+  ]))
 
-  def __init__(self, text_message):
-    self._text_message = text_message
+  _IDENTIFIER = re.compile(r'[^\d\W]\w*')
+  _IDENTIFIER_OR_NUMBER = re.compile(r'\w+')
 
+  def __init__(self, lines, skip_comments=True):
     self._position = 0
     self._line = -1
     self._column = 0
     self._token_start = None
     self.token = ''
-    self._lines = deque(text_message.split('\n'))
+    self._lines = iter(lines)
     self._current_line = ''
     self._previous_line = 0
     self._previous_column = 0
+    self._more_lines = True
+    self._skip_comments = skip_comments
+    self._whitespace_pattern = (skip_comments and self._WHITESPACE_OR_COMMENT
+                                or self._WHITESPACE)
     self._SkipWhitespace()
     self.NextToken()
 
+  def LookingAt(self, token):
+    return self.token == token
+
   def AtEnd(self):
     """Checks the end of the text was reached.
 
     Returns:
       True iff the end was reached.
     """
-    return self.token == ''
+    return not self.token
 
   def _PopLine(self):
     while len(self._current_line) <= self._column:
-      if not self._lines:
+      try:
+        self._current_line = next(self._lines)
+      except StopIteration:
         self._current_line = ''
+        self._more_lines = False
         return
-      self._line += 1
-      self._column = 0
-      self._current_line = self._lines.popleft()
+      else:
+        self._line += 1
+        self._column = 0
 
   def _SkipWhitespace(self):
     while True:
       self._PopLine()
-      match = self._WHITESPACE.match(self._current_line, self._column)
+      match = self._whitespace_pattern.match(self._current_line, self._column)
       if not match:
         break
       length = len(match.group(0))
@@ -375,7 +1016,21 @@
       ParseError: If the text couldn't be consumed.
     """
     if not self.TryConsume(token):
-      raise self._ParseError('Expected "%s".' % token)
+      raise self.ParseError('Expected "%s".' % token)
+
+  def ConsumeComment(self):
+    result = self.token
+    if not self._COMMENT.match(result):
+      raise self.ParseError('Expected comment.')
+    self.NextToken()
+    return result
+
+  def TryConsumeIdentifier(self):
+    try:
+      self.ConsumeIdentifier()
+      return True
+    except ParseError:
+      return False
 
   def ConsumeIdentifier(self):
     """Consumes protocol message field identifier.
@@ -388,73 +1043,64 @@
     """
     result = self.token
     if not self._IDENTIFIER.match(result):
-      raise self._ParseError('Expected identifier.')
+      raise self.ParseError('Expected identifier.')
     self.NextToken()
     return result
 
-  def ConsumeInt32(self):
-    """Consumes a signed 32bit integer number.
+  def TryConsumeIdentifierOrNumber(self):
+    try:
+      self.ConsumeIdentifierOrNumber()
+      return True
+    except ParseError:
+      return False
 
+  def ConsumeIdentifierOrNumber(self):
+    """Consumes protocol message field identifier.
+
+    Returns:
+      Identifier string.
+
+    Raises:
+      ParseError: If an identifier couldn't be consumed.
+    """
+    result = self.token
+    if not self._IDENTIFIER_OR_NUMBER.match(result):
+      raise self.ParseError('Expected identifier or number.')
+    self.NextToken()
+    return result
+
+  def TryConsumeInteger(self):
+    try:
+      # Note: is_long only affects value type, not whether an error is raised.
+      self.ConsumeInteger()
+      return True
+    except ParseError:
+      return False
+
+  def ConsumeInteger(self, is_long=False):
+    """Consumes an integer number.
+
+    Args:
+      is_long: True if the value should be returned as a long integer.
     Returns:
       The integer parsed.
 
     Raises:
-      ParseError: If a signed 32bit integer couldn't be consumed.
+      ParseError: If an integer couldn't be consumed.
     """
     try:
-      result = ParseInteger(self.token, is_signed=True, is_long=False)
-    except ValueError, e:
-      raise self._ParseError(str(e))
+      result = _ParseAbstractInteger(self.token, is_long=is_long)
+    except ValueError as e:
+      raise self.ParseError(str(e))
     self.NextToken()
     return result
 
-  def ConsumeUint32(self):
-    """Consumes an unsigned 32bit integer number.
-
-    Returns:
-      The integer parsed.
-
-    Raises:
-      ParseError: If an unsigned 32bit integer couldn't be consumed.
-    """
+  def TryConsumeFloat(self):
     try:
-      result = ParseInteger(self.token, is_signed=False, is_long=False)
-    except ValueError, e:
-      raise self._ParseError(str(e))
-    self.NextToken()
-    return result
-
-  def ConsumeInt64(self):
-    """Consumes a signed 64bit integer number.
-
-    Returns:
-      The integer parsed.
-
-    Raises:
-      ParseError: If a signed 64bit integer couldn't be consumed.
-    """
-    try:
-      result = ParseInteger(self.token, is_signed=True, is_long=True)
-    except ValueError, e:
-      raise self._ParseError(str(e))
-    self.NextToken()
-    return result
-
-  def ConsumeUint64(self):
-    """Consumes an unsigned 64bit integer number.
-
-    Returns:
-      The integer parsed.
-
-    Raises:
-      ParseError: If an unsigned 64bit integer couldn't be consumed.
-    """
-    try:
-      result = ParseInteger(self.token, is_signed=False, is_long=True)
-    except ValueError, e:
-      raise self._ParseError(str(e))
-    self.NextToken()
-    return result
+      self.ConsumeFloat()
+      return True
+    except ParseError:
+      return False
 
   def ConsumeFloat(self):
     """Consumes an floating point number.
@@ -467,8 +1113,8 @@
     """
     try:
       result = ParseFloat(self.token)
-    except ValueError, e:
-      raise self._ParseError(str(e))
+    except ValueError as e:
+      raise self.ParseError(str(e))
     self.NextToken()
     return result
 
@@ -483,11 +1129,18 @@
     """
     try:
       result = ParseBool(self.token)
-    except ValueError, e:
-      raise self._ParseError(str(e))
+    except ValueError as e:
+      raise self.ParseError(str(e))
     self.NextToken()
     return result
 
+  def TryConsumeByteString(self):
+    try:
+      self.ConsumeByteString()
+      return True
+    except ParseError:
+      return False
+
   def ConsumeString(self):
     """Consumes a string value.
 
@@ -497,10 +1150,10 @@
     Raises:
       ParseError: If a string value couldn't be consumed.
     """
-    bytes = self.ConsumeByteString()
+    the_bytes = self.ConsumeByteString()
     try:
-      return unicode(bytes, 'utf-8')
-    except UnicodeDecodeError, e:
+      return six.text_type(the_bytes, 'utf-8')
+    except UnicodeDecodeError as e:
       raise self._StringParseError(e)
 
   def ConsumeByteString(self):
@@ -512,10 +1165,10 @@
     Raises:
       ParseError: If a byte array value couldn't be consumed.
     """
-    list = [self._ConsumeSingleByteString()]
-    while len(self.token) > 0 and self.token[0] in ('\'', '"'):
-      list.append(self._ConsumeSingleByteString())
-    return "".join(list)
+    the_list = [self._ConsumeSingleByteString()]
+    while self.token and self.token[0] in _QUOTES:
+      the_list.append(self._ConsumeSingleByteString())
+    return b''.join(the_list)
 
   def _ConsumeSingleByteString(self):
     """Consume one token of a string literal.
@@ -523,26 +1176,31 @@
     String literals (whether bytes or text) can come in multiple adjacent
     tokens which are automatically concatenated, like in C or Python.  This
     method only consumes one token.
+
+    Returns:
+      The token parsed.
+    Raises:
+      ParseError: When the wrong format data is found.
     """
     text = self.token
-    if len(text) < 1 or text[0] not in ('\'', '"'):
-      raise self._ParseError('Expected string.')
+    if len(text) < 1 or text[0] not in _QUOTES:
+      raise self.ParseError('Expected string but found: %r' % (text,))
 
     if len(text) < 2 or text[-1] != text[0]:
-      raise self._ParseError('String missing ending quote.')
+      raise self.ParseError('String missing ending quote: %r' % (text,))
 
     try:
-      result = _CUnescape(text[1:-1])
-    except ValueError, e:
-      raise self._ParseError(str(e))
+      result = text_encoding.CUnescape(text[1:-1])
+    except ValueError as e:
+      raise self.ParseError(str(e))
     self.NextToken()
     return result
 
   def ConsumeEnum(self, field):
     try:
       result = ParseEnum(field, self.token)
-    except ValueError, e:
-      raise self._ParseError(str(e))
+    except ValueError as e:
+      raise self.ParseError(str(e))
     self.NextToken()
     return result
 
@@ -555,16 +1213,15 @@
     Returns:
       A ParseError instance.
     """
-    return ParseError('%d:%d : %s' % (
-        self._previous_line + 1, self._previous_column + 1, message))
+    return ParseError(message, self._previous_line + 1,
+                      self._previous_column + 1)
 
-  def _ParseError(self, message):
+  def ParseError(self, message):
     """Creates and *returns* a ParseError for the current token."""
-    return ParseError('%d:%d : %s' % (
-        self._line + 1, self._column + 1, message))
+    return ParseError(message, self._line + 1, self._column + 1)
 
   def _StringParseError(self, e):
-    return self._ParseError('Couldn\'t parse string: ' + str(e))
+    return self.ParseError('Couldn\'t parse string: ' + str(e))
 
   def NextToken(self):
     """Reads the next meaningful token."""
@@ -574,55 +1231,128 @@
     self._column += len(self.token)
     self._SkipWhitespace()
 
-    if not self._lines and len(self._current_line) <= self._column:
+    if not self._more_lines:
       self.token = ''
       return
 
     match = self._TOKEN.match(self._current_line, self._column)
+    if not match and not self._skip_comments:
+      match = self._COMMENT.match(self._current_line, self._column)
     if match:
       token = match.group(0)
       self.token = token
     else:
       self.token = self._current_line[self._column]
 
-
-# text.encode('string_escape') does not seem to satisfy our needs as it
-# encodes unprintable characters using two-digit hex escapes whereas our
-# C++ unescaping function allows hex escapes to be any length.  So,
-# "\0011".encode('string_escape') ends up being "\\x011", which will be
-# decoded in C++ as a single-character string with char code 0x11.
-def _CEscape(text, as_utf8):
-  def escape(c):
-    o = ord(c)
-    if o == 10: return r"\n"   # optional escape
-    if o == 13: return r"\r"   # optional escape
-    if o ==  9: return r"\t"   # optional escape
-    if o == 39: return r"\'"   # optional escape
-
-    if o == 34: return r'\"'   # necessary escape
-    if o == 92: return r"\\"   # necessary escape
-
-    # necessary escapes
-    if not as_utf8 and (o >= 127 or o < 32): return "\\%03o" % o
-    return c
-  return "".join([escape(c) for c in text])
+# Aliased so it can still be accessed by current visibility violators.
+# TODO(dbarnett): Migrate violators to textformat_tokenizer.
+_Tokenizer = Tokenizer  # pylint: disable=invalid-name
 
 
-_CUNESCAPE_HEX = re.compile(r'(\\+)x([0-9a-fA-F])(?![0-9a-fA-F])')
+def _ConsumeInt32(tokenizer):
+  """Consumes a signed 32bit integer number from tokenizer.
+
+  Args:
+    tokenizer: A tokenizer used to parse the number.
+
+  Returns:
+    The integer parsed.
+
+  Raises:
+    ParseError: If a signed 32bit integer couldn't be consumed.
+  """
+  return _ConsumeInteger(tokenizer, is_signed=True, is_long=False)
 
 
-def _CUnescape(text):
-  def ReplaceHex(m):
-    # Only replace the match if the number of leading back slashes is odd. i.e.
-    # the slash itself is not escaped.
-    if len(m.group(1)) & 1:
-      return m.group(1) + 'x0' + m.group(2)
-    return m.group(0)
+def _ConsumeUint32(tokenizer):
+  """Consumes an unsigned 32bit integer number from tokenizer.
 
-  # This is required because the 'string_escape' encoding doesn't
-  # allow single-digit hex escapes (like '\xf').
-  result = _CUNESCAPE_HEX.sub(ReplaceHex, text)
-  return result.decode('string_escape')
+  Args:
+    tokenizer: A tokenizer used to parse the number.
+
+  Returns:
+    The integer parsed.
+
+  Raises:
+    ParseError: If an unsigned 32bit integer couldn't be consumed.
+  """
+  return _ConsumeInteger(tokenizer, is_signed=False, is_long=False)
+
+
+def _TryConsumeInt64(tokenizer):
+  try:
+    _ConsumeInt64(tokenizer)
+    return True
+  except ParseError:
+    return False
+
+
+def _ConsumeInt64(tokenizer):
+  """Consumes a signed 32bit integer number from tokenizer.
+
+  Args:
+    tokenizer: A tokenizer used to parse the number.
+
+  Returns:
+    The integer parsed.
+
+  Raises:
+    ParseError: If a signed 32bit integer couldn't be consumed.
+  """
+  return _ConsumeInteger(tokenizer, is_signed=True, is_long=True)
+
+
+def _TryConsumeUint64(tokenizer):
+  try:
+    _ConsumeUint64(tokenizer)
+    return True
+  except ParseError:
+    return False
+
+
+def _ConsumeUint64(tokenizer):
+  """Consumes an unsigned 64bit integer number from tokenizer.
+
+  Args:
+    tokenizer: A tokenizer used to parse the number.
+
+  Returns:
+    The integer parsed.
+
+  Raises:
+    ParseError: If an unsigned 64bit integer couldn't be consumed.
+  """
+  return _ConsumeInteger(tokenizer, is_signed=False, is_long=True)
+
+
+def _TryConsumeInteger(tokenizer, is_signed=False, is_long=False):
+  try:
+    _ConsumeInteger(tokenizer, is_signed=is_signed, is_long=is_long)
+    return True
+  except ParseError:
+    return False
+
+
+def _ConsumeInteger(tokenizer, is_signed=False, is_long=False):
+  """Consumes an integer number from tokenizer.
+
+  Args:
+    tokenizer: A tokenizer used to parse the number.
+    is_signed: True if a signed integer must be parsed.
+    is_long: True if a long integer must be parsed.
+
+  Returns:
+    The integer parsed.
+
+  Raises:
+    ParseError: If an integer with given characteristics couldn't be consumed.
+  """
+  try:
+    result = ParseInteger(tokenizer.token, is_signed=is_signed, is_long=is_long)
+  except ValueError as e:
+    raise tokenizer.ParseError(str(e))
+  tokenizer.NextToken()
+  return result
 
 
 def ParseInteger(text, is_signed=False, is_long=False):
@@ -640,10 +1370,7 @@
     ValueError: Thrown Iff the text is not a valid integer.
   """
   # Do the actual parsing. Exception handling is propagated to caller.
-  try:
-    result = int(text, 0)
-  except ValueError:
-    raise ValueError('Couldn\'t parse integer: %s' % text)
+  result = _ParseAbstractInteger(text, is_long=is_long)
 
   # Check if the integer is sane. Exceptions handled by callers.
   checker = _INTEGER_CHECKERS[2 * int(is_long) + int(is_signed)]
@@ -651,6 +1378,32 @@
   return result
 
 
+def _ParseAbstractInteger(text, is_long=False):
+  """Parses an integer without checking size/signedness.
+
+  Args:
+    text: The text to parse.
+    is_long: True if the value should be returned as a long integer.
+
+  Returns:
+    The integer value.
+
+  Raises:
+    ValueError: Thrown Iff the text is not a valid integer.
+  """
+  # Do the actual parsing. Exception handling is propagated to caller.
+  try:
+    # We force 32-bit values to int and 64-bit values to long to make
+    # alternate implementations where the distinction is more significant
+    # (e.g. the C++ implementation) simpler.
+    if is_long:
+      return long(text, 0)
+    else:
+      return int(text, 0)
+  except ValueError:
+    raise ValueError('Couldn\'t parse integer: %s' % text)
+
+
 def ParseFloat(text):
   """Parse a floating point number.
 
@@ -726,14 +1479,12 @@
     # Identifier.
     enum_value = enum_descriptor.values_by_name.get(value, None)
     if enum_value is None:
-      raise ValueError(
-          'Enum type "%s" has no value named %s.' % (
-              enum_descriptor.full_name, value))
+      raise ValueError('Enum type "%s" has no value named %s.' %
+                       (enum_descriptor.full_name, value))
   else:
     # Numeric value.
     enum_value = enum_descriptor.values_by_number.get(number, None)
     if enum_value is None:
-      raise ValueError(
-          'Enum type "%s" has no value with number %d.' % (
-              enum_descriptor.full_name, number))
+      raise ValueError('Enum type "%s" has no value with number %d.' %
+                       (enum_descriptor.full_name, number))
   return enum_value.number
diff --git a/generator/google/protobuf/timestamp_pb2.py b/generator/google/protobuf/timestamp_pb2.py
new file mode 100644
index 0000000..bd61186
--- /dev/null
+++ b/generator/google/protobuf/timestamp_pb2.py
@@ -0,0 +1,78 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/timestamp.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/timestamp.proto',
+  package='google.protobuf',
+  syntax='proto3',
+  serialized_pb=_b('\n\x1fgoogle/protobuf/timestamp.proto\x12\x0fgoogle.protobuf\"+\n\tTimestamp\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x42\x81\x01\n\x13\x63om.google.protobufB\x0eTimestampProtoP\x01Z+github.com/golang/protobuf/ptypes/timestamp\xa0\x01\x01\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_TIMESTAMP = _descriptor.Descriptor(
+  name='Timestamp',
+  full_name='google.protobuf.Timestamp',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='seconds', full_name='google.protobuf.Timestamp.seconds', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nanos', full_name='google.protobuf.Timestamp.nanos', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=52,
+  serialized_end=95,
+)
+
+DESCRIPTOR.message_types_by_name['Timestamp'] = _TIMESTAMP
+
+Timestamp = _reflection.GeneratedProtocolMessageType('Timestamp', (_message.Message,), dict(
+  DESCRIPTOR = _TIMESTAMP,
+  __module__ = 'google.protobuf.timestamp_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Timestamp)
+  ))
+_sym_db.RegisterMessage(Timestamp)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\023com.google.protobufB\016TimestampProtoP\001Z+github.com/golang/protobuf/ptypes/timestamp\240\001\001\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/type_pb2.py b/generator/google/protobuf/type_pb2.py
new file mode 100644
index 0000000..737493f
--- /dev/null
+++ b/generator/google/protobuf/type_pb2.py
@@ -0,0 +1,541 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/type.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
+from google.protobuf import source_context_pb2 as google_dot_protobuf_dot_source__context__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/type.proto',
+  package='google.protobuf',
+  syntax='proto3',
+  serialized_pb=_b('\n\x1agoogle/protobuf/type.proto\x12\x0fgoogle.protobuf\x1a\x19google/protobuf/any.proto\x1a$google/protobuf/source_context.proto\"\xd7\x01\n\x04Type\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x06\x66ields\x18\x02 \x03(\x0b\x32\x16.google.protobuf.Field\x12\x0e\n\x06oneofs\x18\x03 \x03(\t\x12(\n\x07options\x18\x04 \x03(\x0b\x32\x17.google.protobuf.Option\x12\x36\n\x0esource_context\x18\x05 \x01(\x0b\x32\x1e.google.protobuf.SourceContext\x12\'\n\x06syntax\x18\x06 \x01(\x0e\x32\x17.google.protobuf.Syntax\"\xd5\x05\n\x05\x46ield\x12)\n\x04kind\x18\x01 \x01(\x0e\x32\x1b.google.protobuf.Field.Kind\x12\x37\n\x0b\x63\x61rdinality\x18\x02 \x01(\x0e\x32\".google.protobuf.Field.Cardinality\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x10\n\x08type_url\x18\x06 \x01(\t\x12\x13\n\x0boneof_index\x18\x07 \x01(\x05\x12\x0e\n\x06packed\x18\x08 \x01(\x08\x12(\n\x07options\x18\t \x03(\x0b\x32\x17.google.protobuf.Option\x12\x11\n\tjson_name\x18\n \x01(\t\x12\x15\n\rdefault_value\x18\x0b \x01(\t\"\xc8\x02\n\x04Kind\x12\x10\n\x0cTYPE_UNKNOWN\x10\x00\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"t\n\x0b\x43\x61rdinality\x12\x17\n\x13\x43\x41RDINALITY_UNKNOWN\x10\x00\x12\x18\n\x14\x43\x41RDINALITY_OPTIONAL\x10\x01\x12\x18\n\x14\x43\x41RDINALITY_REQUIRED\x10\x02\x12\x18\n\x14\x43\x41RDINALITY_REPEATED\x10\x03\"\xce\x01\n\x04\x45num\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\tenumvalue\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.EnumValue\x12(\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.Option\x12\x36\n\x0esource_context\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.SourceContext\x12\'\n\x06syntax\x18\x05 \x01(\x0e\x32\x17.google.protobuf.Syntax\"S\n\tEnumValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12(\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.Option\";\n\x06Option\x12\x0c\n\x04name\x18\x01 \x01(\t\x12#\n\x05value\x18\x02 \x01(\x0b\x32\x14.google.protobuf.Any*.\n\x06Syntax\x12\x11\n\rSYNTAX_PROTO2\x10\x00\x12\x11\n\rSYNTAX_PROTO3\x10\x01\x42L\n\x13\x63om.google.protobufB\tTypeProtoP\x01\xa0\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3')
+  ,
+  dependencies=[google_dot_protobuf_dot_any__pb2.DESCRIPTOR,google_dot_protobuf_dot_source__context__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+_SYNTAX = _descriptor.EnumDescriptor(
+  name='Syntax',
+  full_name='google.protobuf.Syntax',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SYNTAX_PROTO2', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='SYNTAX_PROTO3', index=1, number=1,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=1413,
+  serialized_end=1459,
+)
+_sym_db.RegisterEnumDescriptor(_SYNTAX)
+
+Syntax = enum_type_wrapper.EnumTypeWrapper(_SYNTAX)
+SYNTAX_PROTO2 = 0
+SYNTAX_PROTO3 = 1
+
+
+_FIELD_KIND = _descriptor.EnumDescriptor(
+  name='Kind',
+  full_name='google.protobuf.Field.Kind',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_UNKNOWN', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_DOUBLE', index=1, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_FLOAT', index=2, number=2,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_INT64', index=3, number=3,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_UINT64', index=4, number=4,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_INT32', index=5, number=5,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_FIXED64', index=6, number=6,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_FIXED32', index=7, number=7,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_BOOL', index=8, number=8,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_STRING', index=9, number=9,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_GROUP', index=10, number=10,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_MESSAGE', index=11, number=11,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_BYTES', index=12, number=12,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_UINT32', index=13, number=13,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_ENUM', index=14, number=14,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_SFIXED32', index=15, number=15,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_SFIXED64', index=16, number=16,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_SINT32', index=17, number=17,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TYPE_SINT64', index=18, number=18,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=610,
+  serialized_end=938,
+)
+_sym_db.RegisterEnumDescriptor(_FIELD_KIND)
+
+_FIELD_CARDINALITY = _descriptor.EnumDescriptor(
+  name='Cardinality',
+  full_name='google.protobuf.Field.Cardinality',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='CARDINALITY_UNKNOWN', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='CARDINALITY_OPTIONAL', index=1, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='CARDINALITY_REQUIRED', index=2, number=2,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='CARDINALITY_REPEATED', index=3, number=3,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=940,
+  serialized_end=1056,
+)
+_sym_db.RegisterEnumDescriptor(_FIELD_CARDINALITY)
+
+
+_TYPE = _descriptor.Descriptor(
+  name='Type',
+  full_name='google.protobuf.Type',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='google.protobuf.Type.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='fields', full_name='google.protobuf.Type.fields', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneofs', full_name='google.protobuf.Type.oneofs', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='options', full_name='google.protobuf.Type.options', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='source_context', full_name='google.protobuf.Type.source_context', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='syntax', full_name='google.protobuf.Type.syntax', index=5,
+      number=6, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=113,
+  serialized_end=328,
+)
+
+
+_FIELD = _descriptor.Descriptor(
+  name='Field',
+  full_name='google.protobuf.Field',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='kind', full_name='google.protobuf.Field.kind', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='cardinality', full_name='google.protobuf.Field.cardinality', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='number', full_name='google.protobuf.Field.number', index=2,
+      number=3, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='name', full_name='google.protobuf.Field.name', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='type_url', full_name='google.protobuf.Field.type_url', index=4,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_index', full_name='google.protobuf.Field.oneof_index', index=5,
+      number=7, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='packed', full_name='google.protobuf.Field.packed', index=6,
+      number=8, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='options', full_name='google.protobuf.Field.options', index=7,
+      number=9, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='json_name', full_name='google.protobuf.Field.json_name', index=8,
+      number=10, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_value', full_name='google.protobuf.Field.default_value', index=9,
+      number=11, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _FIELD_KIND,
+    _FIELD_CARDINALITY,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=331,
+  serialized_end=1056,
+)
+
+
+_ENUM = _descriptor.Descriptor(
+  name='Enum',
+  full_name='google.protobuf.Enum',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='google.protobuf.Enum.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='enumvalue', full_name='google.protobuf.Enum.enumvalue', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='options', full_name='google.protobuf.Enum.options', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='source_context', full_name='google.protobuf.Enum.source_context', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='syntax', full_name='google.protobuf.Enum.syntax', index=4,
+      number=5, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1059,
+  serialized_end=1265,
+)
+
+
+_ENUMVALUE = _descriptor.Descriptor(
+  name='EnumValue',
+  full_name='google.protobuf.EnumValue',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='google.protobuf.EnumValue.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='number', full_name='google.protobuf.EnumValue.number', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='options', full_name='google.protobuf.EnumValue.options', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1267,
+  serialized_end=1350,
+)
+
+
+_OPTION = _descriptor.Descriptor(
+  name='Option',
+  full_name='google.protobuf.Option',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='google.protobuf.Option.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.Option.value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1352,
+  serialized_end=1411,
+)
+
+_TYPE.fields_by_name['fields'].message_type = _FIELD
+_TYPE.fields_by_name['options'].message_type = _OPTION
+_TYPE.fields_by_name['source_context'].message_type = google_dot_protobuf_dot_source__context__pb2._SOURCECONTEXT
+_TYPE.fields_by_name['syntax'].enum_type = _SYNTAX
+_FIELD.fields_by_name['kind'].enum_type = _FIELD_KIND
+_FIELD.fields_by_name['cardinality'].enum_type = _FIELD_CARDINALITY
+_FIELD.fields_by_name['options'].message_type = _OPTION
+_FIELD_KIND.containing_type = _FIELD
+_FIELD_CARDINALITY.containing_type = _FIELD
+_ENUM.fields_by_name['enumvalue'].message_type = _ENUMVALUE
+_ENUM.fields_by_name['options'].message_type = _OPTION
+_ENUM.fields_by_name['source_context'].message_type = google_dot_protobuf_dot_source__context__pb2._SOURCECONTEXT
+_ENUM.fields_by_name['syntax'].enum_type = _SYNTAX
+_ENUMVALUE.fields_by_name['options'].message_type = _OPTION
+_OPTION.fields_by_name['value'].message_type = google_dot_protobuf_dot_any__pb2._ANY
+DESCRIPTOR.message_types_by_name['Type'] = _TYPE
+DESCRIPTOR.message_types_by_name['Field'] = _FIELD
+DESCRIPTOR.message_types_by_name['Enum'] = _ENUM
+DESCRIPTOR.message_types_by_name['EnumValue'] = _ENUMVALUE
+DESCRIPTOR.message_types_by_name['Option'] = _OPTION
+DESCRIPTOR.enum_types_by_name['Syntax'] = _SYNTAX
+
+Type = _reflection.GeneratedProtocolMessageType('Type', (_message.Message,), dict(
+  DESCRIPTOR = _TYPE,
+  __module__ = 'google.protobuf.type_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Type)
+  ))
+_sym_db.RegisterMessage(Type)
+
+Field = _reflection.GeneratedProtocolMessageType('Field', (_message.Message,), dict(
+  DESCRIPTOR = _FIELD,
+  __module__ = 'google.protobuf.type_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Field)
+  ))
+_sym_db.RegisterMessage(Field)
+
+Enum = _reflection.GeneratedProtocolMessageType('Enum', (_message.Message,), dict(
+  DESCRIPTOR = _ENUM,
+  __module__ = 'google.protobuf.type_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Enum)
+  ))
+_sym_db.RegisterMessage(Enum)
+
+EnumValue = _reflection.GeneratedProtocolMessageType('EnumValue', (_message.Message,), dict(
+  DESCRIPTOR = _ENUMVALUE,
+  __module__ = 'google.protobuf.type_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.EnumValue)
+  ))
+_sym_db.RegisterMessage(EnumValue)
+
+Option = _reflection.GeneratedProtocolMessageType('Option', (_message.Message,), dict(
+  DESCRIPTOR = _OPTION,
+  __module__ = 'google.protobuf.type_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Option)
+  ))
+_sym_db.RegisterMessage(Option)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\023com.google.protobufB\tTypeProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/unittest_arena_pb2.py b/generator/google/protobuf/unittest_arena_pb2.py
new file mode 100644
index 0000000..f843190
--- /dev/null
+++ b/generator/google/protobuf/unittest_arena_pb2.py
@@ -0,0 +1,121 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/unittest_arena.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import unittest_no_arena_import_pb2 as google_dot_protobuf_dot_unittest__no__arena__import__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/unittest_arena.proto',
+  package='proto2_arena_unittest',
+  syntax='proto2',
+  serialized_pb=_b('\n$google/protobuf/unittest_arena.proto\x12\x15proto2_arena_unittest\x1a.google/protobuf/unittest_no_arena_import.proto\"\x1a\n\rNestedMessage\x12\t\n\x01\x64\x18\x01 \x01(\x05\"\xb2\x01\n\x0c\x41renaMessage\x12\x45\n\x17repeated_nested_message\x18\x01 \x03(\x0b\x32$.proto2_arena_unittest.NestedMessage\x12[\n repeated_import_no_arena_message\x18\x02 \x03(\x0b\x32\x31.proto2_arena_unittest.ImportNoArenaNestedMessageB\x03\xf8\x01\x01')
+  ,
+  dependencies=[google_dot_protobuf_dot_unittest__no__arena__import__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_NESTEDMESSAGE = _descriptor.Descriptor(
+  name='NestedMessage',
+  full_name='proto2_arena_unittest.NestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='d', full_name='proto2_arena_unittest.NestedMessage.d', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=111,
+  serialized_end=137,
+)
+
+
+_ARENAMESSAGE = _descriptor.Descriptor(
+  name='ArenaMessage',
+  full_name='proto2_arena_unittest.ArenaMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='repeated_nested_message', full_name='proto2_arena_unittest.ArenaMessage.repeated_nested_message', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_import_no_arena_message', full_name='proto2_arena_unittest.ArenaMessage.repeated_import_no_arena_message', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=140,
+  serialized_end=318,
+)
+
+_ARENAMESSAGE.fields_by_name['repeated_nested_message'].message_type = _NESTEDMESSAGE
+_ARENAMESSAGE.fields_by_name['repeated_import_no_arena_message'].message_type = google_dot_protobuf_dot_unittest__no__arena__import__pb2._IMPORTNOARENANESTEDMESSAGE
+DESCRIPTOR.message_types_by_name['NestedMessage'] = _NESTEDMESSAGE
+DESCRIPTOR.message_types_by_name['ArenaMessage'] = _ARENAMESSAGE
+
+NestedMessage = _reflection.GeneratedProtocolMessageType('NestedMessage', (_message.Message,), dict(
+  DESCRIPTOR = _NESTEDMESSAGE,
+  __module__ = 'google.protobuf.unittest_arena_pb2'
+  # @@protoc_insertion_point(class_scope:proto2_arena_unittest.NestedMessage)
+  ))
+_sym_db.RegisterMessage(NestedMessage)
+
+ArenaMessage = _reflection.GeneratedProtocolMessageType('ArenaMessage', (_message.Message,), dict(
+  DESCRIPTOR = _ARENAMESSAGE,
+  __module__ = 'google.protobuf.unittest_arena_pb2'
+  # @@protoc_insertion_point(class_scope:proto2_arena_unittest.ArenaMessage)
+  ))
+_sym_db.RegisterMessage(ArenaMessage)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\370\001\001'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/unittest_custom_options_pb2.py b/generator/google/protobuf/unittest_custom_options_pb2.py
new file mode 100644
index 0000000..4e39e1d
--- /dev/null
+++ b/generator/google/protobuf/unittest_custom_options_pb2.py
@@ -0,0 +1,1862 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/unittest_custom_options.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import service as _service
+from google.protobuf import service_reflection
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/unittest_custom_options.proto',
+  package='protobuf_unittest',
+  syntax='proto2',
+  serialized_pb=_b('\n-google/protobuf/unittest_custom_options.proto\x12\x11protobuf_unittest\x1a google/protobuf/descriptor.proto\"\xbf\x01\n\x1cTestMessageWithCustomOptions\x12\x1e\n\x06\x66ield1\x18\x01 \x01(\tB\x0e\x08\x01\xc1\xe0\xc3\x1d-\xe1u\n\x02\x00\x00\x00\x12\x15\n\x0boneof_field\x18\x02 \x01(\x05H\x00\";\n\x06\x41nEnum\x12\x0f\n\x0b\x41NENUM_VAL1\x10\x01\x12\x16\n\x0b\x41NENUM_VAL2\x10\x02\x1a\x05\xb0\x86\xfa\x05{\x1a\x08\xc5\xf6\xc9\x1d\xeb\xfc\xff\xff:\x10\x08\x00\xe0\xe9\xc2\x1d\xc8\xff\xff\xff\xff\xff\xff\xff\xff\x01\x42\x19\n\x07\x41nOneof\x12\x0e\xf8\xac\xc3\x1d\x9d\xff\xff\xff\xff\xff\xff\xff\xff\x01\"\x18\n\x16\x43ustomOptionFooRequest\"\x19\n\x17\x43ustomOptionFooResponse\"\x1e\n\x1c\x43ustomOptionFooClientMessage\"\x1e\n\x1c\x43ustomOptionFooServerMessage\"m\n\x1a\x44ummyMessageContainingEnum\"O\n\x0cTestEnumType\x12\x1a\n\x16TEST_OPTION_ENUM_TYPE1\x10\x16\x12#\n\x16TEST_OPTION_ENUM_TYPE2\x10\xe9\xff\xff\xff\xff\xff\xff\xff\xff\x01\"!\n\x1f\x44ummyMessageInvalidAsOptionType\"\x8a\x01\n\x1c\x43ustomOptionMinIntegerValues:j\xd0\xde\xb2\x1d\x00\xe8\xc6\xb2\x1d\x80\x80\x80\x80\xf8\xff\xff\xff\xff\x01\xb0\xbc\xb2\x1d\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01\x80\x93\xb2\x1d\x00\xf8\xf5\xb0\x1d\x00\x80\xc4\xb0\x1d\xff\xff\xff\xff\x0f\xf8\x97\xb0\x1d\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x9d\xf5\xaf\x1d\x00\x00\x00\x00\x91\xee\xaf\x1d\x00\x00\x00\x00\x00\x00\x00\x00\xad\x8d\xaf\x1d\x00\x00\x00\x80\x99\xd6\xa8\x1d\x00\x00\x00\x00\x00\x00\x00\x80\"\x91\x01\n\x1c\x43ustomOptionMaxIntegerValues:q\xd0\xde\xb2\x1d\x01\xe8\xc6\xb2\x1d\xff\xff\xff\xff\x07\xb0\xbc\xb2\x1d\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x80\x93\xb2\x1d\xff\xff\xff\xff\x0f\xf8\xf5\xb0\x1d\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x80\xc4\xb0\x1d\xfe\xff\xff\xff\x0f\xf8\x97\xb0\x1d\xfe\xff\xff\xff\xff\xff\xff\xff\xff\x01\x9d\xf5\xaf\x1d\xff\xff\xff\xff\x91\xee\xaf\x1d\xff\xff\xff\xff\xff\xff\xff\xff\xad\x8d\xaf\x1d\xff\xff\xff\x7f\x99\xd6\xa8\x1d\xff\xff\xff\xff\xff\xff\xff\x7f\"n\n\x17\x43ustomOptionOtherValues:S\xe8\xc6\xb2\x1d\x9c\xff\xff\xff\xff\xff\xff\xff\xff\x01\xf5\xdf\xa3\x1d\xe7\x87\x45\x41\xe9\xdc\xa2\x1d\xfbY\x8c\x42\xca\xc0\xf3?\xaa\xdc\xa2\x1d\x0eHello, \"World\"\xb2\xd9\xa2\x1d\x0bHello\x00World\x88\xd9\xa2\x1d\xe9\xff\xff\xff\xff\xff\xff\xff\xff\x01\"4\n\x1cSettingRealsFromPositiveInts:\x14\xf5\xdf\xa3\x1d\x00\x00@A\xe9\xdc\xa2\x1d\x00\x00\x00\x00\x00@c@\"4\n\x1cSettingRealsFromNegativeInts:\x14\xf5\xdf\xa3\x1d\x00\x00@\xc1\xe9\xdc\xa2\x1d\x00\x00\x00\x00\x00@c\xc0\"U\n\x12\x43omplexOptionType1\x12\x0b\n\x03\x66oo\x18\x01 \x01(\x05\x12\x0c\n\x04\x66oo2\x18\x02 \x01(\x05\x12\x0c\n\x04\x66oo3\x18\x03 \x01(\x05\x12\x0c\n\x04\x66oo4\x18\x04 \x03(\x05*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"\x8b\x03\n\x12\x43omplexOptionType2\x12\x32\n\x03\x62\x61r\x18\x01 \x01(\x0b\x32%.protobuf_unittest.ComplexOptionType1\x12\x0b\n\x03\x62\x61z\x18\x02 \x01(\x05\x12\x46\n\x04\x66red\x18\x03 \x01(\x0b\x32\x38.protobuf_unittest.ComplexOptionType2.ComplexOptionType4\x12H\n\x06\x62\x61rney\x18\x04 \x03(\x0b\x32\x38.protobuf_unittest.ComplexOptionType2.ComplexOptionType4\x1a\x97\x01\n\x12\x43omplexOptionType4\x12\r\n\x05waldo\x18\x01 \x01(\x05\x32r\n\x0c\x63omplex_opt4\x12\x1f.google.protobuf.MessageOptions\x18\x8a\xf5\xd1\x03 \x01(\x0b\x32\x38.protobuf_unittest.ComplexOptionType2.ComplexOptionType4*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"\x9c\x01\n\x12\x43omplexOptionType3\x12\x0b\n\x03qux\x18\x01 \x01(\x05\x12T\n\x12\x63omplexoptiontype5\x18\x02 \x01(\n28.protobuf_unittest.ComplexOptionType3.ComplexOptionType5\x1a#\n\x12\x43omplexOptionType5\x12\r\n\x05plugh\x18\x03 \x01(\x05\"\x1f\n\x0b\x43omplexOpt6\x12\x10\n\x05xyzzy\x18\xdf\xbf\xcf\x03 \x01(\x05\"\xf1\x01\n\x15VariousComplexOptions:\xd7\x01\xa2\xe2\x95\x1d\x02\x08*\xa2\xe2\x95\x1d\x06\xd8\x85\x9e\x1d\xc4\x02\xa2\xe2\x95\x1d\x08\x92\xf5\x9d\x1d\x03\x08\xec\x06\xa2\xe2\x95\x1d\x02 c\xa2\xe2\x95\x1d\x02 X\xaa\xfd\x90\x1d\x03\x10\xdb\x07\xaa\xfd\x90\x1d\x06\xf8\xe6\x97\x1d\x8e\x05\xaa\xfd\x90\x1d\x05\n\x03\x08\xe7\x05\xaa\xfd\x90\x1d\x08\n\x06\xd8\x85\x9e\x1d\xcf\x0f\xaa\xfd\x90\x1d\n\n\x08\x92\xf5\x9d\x1d\x03\x08\xd8\x0f\xaa\xfd\x90\x1d\x08\xc2\xac\x97\x1d\x03\x08\xe5\x05\xaa\xfd\x90\x1d\x0b\xc2\xac\x97\x1d\x06\xd8\x85\x9e\x1d\xce\x0f\xaa\xfd\x90\x1d\r\xc2\xac\x97\x1d\x08\x92\xf5\x9d\x1d\x03\x08\xc9\x10\xd2\xa8\x8f\x1d\x03\x08\xb3\x0f\xaa\xfd\x90\x1d\x05\x1a\x03\x08\xc1\x02\xaa\xfd\x90\x1d\x04\"\x02\x08\x65\xaa\xfd\x90\x1d\x05\"\x03\x08\xd4\x01\xfa\xde\x90\x1d\x02\x08\t\xfa\xde\x90\x1d\x04\x13\x18\x16\x14\xe3\xdc\xfc\x1c\xf8\xfd\xfb\x1c\x18\xe4\xdc\xfc\x1c\"#\n\x13\x41ggregateMessageSet*\x08\x08\x04\x10\xff\xff\xff\xff\x07:\x02\x08\x01\"\xa0\x01\n\x1a\x41ggregateMessageSetElement\x12\t\n\x01s\x18\x01 \x01(\t2w\n\x15message_set_extension\x12&.protobuf_unittest.AggregateMessageSet\x18\xf6\xeb\xae\x07 \x01(\x0b\x32-.protobuf_unittest.AggregateMessageSetElement\"\xfd\x01\n\tAggregate\x12\t\n\x01i\x18\x01 \x01(\x05\x12\t\n\x01s\x18\x02 \x01(\t\x12)\n\x03sub\x18\x03 \x01(\x0b\x32\x1c.protobuf_unittest.Aggregate\x12*\n\x04\x66ile\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.FileOptions\x12\x34\n\x04mset\x18\x05 \x01(\x0b\x32&.protobuf_unittest.AggregateMessageSet2M\n\x06nested\x12\x1c.google.protobuf.FileOptions\x18\xa7\xd1\xb0\x07 \x01(\x0b\x32\x1c.protobuf_unittest.Aggregate\"Y\n\x10\x41ggregateMessage\x12)\n\tfieldname\x18\x01 \x01(\x05\x42\x16\xf2\xa1\x87;\x11\x12\x0f\x46ieldAnnotation:\x1a\xc2\xd1\x86;\x15\x08\x65\x12\x11MessageAnnotation\"\xc9\x01\n\x10NestedOptionType\x1a;\n\rNestedMessage\x12\"\n\x0cnested_field\x18\x01 \x01(\x05\x42\x0c\xc1\xe0\xc3\x1d\xea\x03\x00\x00\x00\x00\x00\x00:\x06\xe0\xe9\xc2\x1d\xe9\x07\"5\n\nNestedEnum\x12\x1d\n\x11NESTED_ENUM_VALUE\x10\x01\x1a\x06\xb0\x86\xfa\x05\xec\x07\x1a\x08\xc5\xf6\xc9\x1d\xeb\x03\x00\x00\x32\x41\n\x10nested_extension\x12\x1c.google.protobuf.FileOptions\x18\xfd\xf8\xe2\x03 \x01(\x05\x42\x06\xc8\x8b\xca\x1d\xed\x07\"d\n\rOldOptionType\x12\x38\n\x05value\x18\x01 \x02(\x0e\x32).protobuf_unittest.OldOptionType.TestEnum\"\x19\n\x08TestEnum\x12\r\n\tOLD_VALUE\x10\x00\"s\n\rNewOptionType\x12\x38\n\x05value\x18\x01 \x02(\x0e\x32).protobuf_unittest.NewOptionType.TestEnum\"(\n\x08TestEnum\x12\r\n\tOLD_VALUE\x10\x00\x12\r\n\tNEW_VALUE\x10\x01\"-\n!TestMessageWithRequiredEnumOption:\x08\xfa\xe8\xfc\x94\x03\x02\x08\x00*6\n\nMethodOpt1\x12\x13\n\x0fMETHODOPT1_VAL1\x10\x01\x12\x13\n\x0fMETHODOPT1_VAL2\x10\x02*M\n\rAggregateEnum\x12%\n\x05VALUE\x10\x01\x1a\x1a\xca\xfc\x89;\x15\x12\x13\x45numValueAnnotation\x1a\x15\x92\x95\x88;\x10\x12\x0e\x45numAnnotation2\x8e\x01\n\x1cTestServiceWithCustomOptions\x12\x63\n\x03\x46oo\x12).protobuf_unittest.CustomOptionFooRequest\x1a*.protobuf_unittest.CustomOptionFooResponse\"\x05\xe0\xfa\x8c\x1e\x02\x1a\t\x90\xb2\x8b\x1e\xd3\xdb\x80\xcbI2\x99\x01\n\x10\x41ggregateService\x12k\n\x06Method\x12#.protobuf_unittest.AggregateMessage\x1a#.protobuf_unittest.AggregateMessage\"\x17\xca\xc8\x96;\x12\x12\x10MethodAnnotation\x1a\x18\xca\xfb\x8e;\x13\x12\x11ServiceAnnotation:2\n\tfile_opt1\x12\x1c.google.protobuf.FileOptions\x18\x8e\x9d\xd8\x03 \x01(\x04:8\n\x0cmessage_opt1\x12\x1f.google.protobuf.MessageOptions\x18\x9c\xad\xd8\x03 \x01(\x05:4\n\nfield_opt1\x12\x1d.google.protobuf.FieldOptions\x18\x88\xbc\xd8\x03 \x01(\x06:8\n\nfield_opt2\x12\x1d.google.protobuf.FieldOptions\x18\xb9\xa1\xd9\x03 \x01(\x05:\x02\x34\x32:4\n\noneof_opt1\x12\x1d.google.protobuf.OneofOptions\x18\xcf\xb5\xd8\x03 \x01(\x05:2\n\tenum_opt1\x12\x1c.google.protobuf.EnumOptions\x18\xe8\x9e\xd9\x03 \x01(\x0f:<\n\x0f\x65num_value_opt1\x12!.google.protobuf.EnumValueOptions\x18\xe6\xa0_ \x01(\x05:8\n\x0cservice_opt1\x12\x1f.google.protobuf.ServiceOptions\x18\xa2\xb6\xe1\x03 \x01(\x12:U\n\x0bmethod_opt1\x12\x1e.google.protobuf.MethodOptions\x18\xac\xcf\xe1\x03 \x01(\x0e\x32\x1d.protobuf_unittest.MethodOpt1:4\n\x08\x62ool_opt\x12\x1f.google.protobuf.MessageOptions\x18\xea\xab\xd6\x03 \x01(\x08:5\n\tint32_opt\x12\x1f.google.protobuf.MessageOptions\x18\xed\xa8\xd6\x03 \x01(\x05:5\n\tint64_opt\x12\x1f.google.protobuf.MessageOptions\x18\xc6\xa7\xd6\x03 \x01(\x03:6\n\nuint32_opt\x12\x1f.google.protobuf.MessageOptions\x18\xb0\xa2\xd6\x03 \x01(\r:6\n\nuint64_opt\x12\x1f.google.protobuf.MessageOptions\x18\xdf\x8e\xd6\x03 \x01(\x04:6\n\nsint32_opt\x12\x1f.google.protobuf.MessageOptions\x18\xc0\x88\xd6\x03 \x01(\x11:6\n\nsint64_opt\x12\x1f.google.protobuf.MessageOptions\x18\xff\x82\xd6\x03 \x01(\x12:7\n\x0b\x66ixed32_opt\x12\x1f.google.protobuf.MessageOptions\x18\xd3\xfe\xd5\x03 \x01(\x07:7\n\x0b\x66ixed64_opt\x12\x1f.google.protobuf.MessageOptions\x18\xe2\xfd\xd5\x03 \x01(\x06:8\n\x0csfixed32_opt\x12\x1f.google.protobuf.MessageOptions\x18\xd5\xf1\xd5\x03 \x01(\x0f:8\n\x0csfixed64_opt\x12\x1f.google.protobuf.MessageOptions\x18\xe3\x8a\xd5\x03 \x01(\x10:5\n\tfloat_opt\x12\x1f.google.protobuf.MessageOptions\x18\xfe\xbb\xd4\x03 \x01(\x02:6\n\ndouble_opt\x12\x1f.google.protobuf.MessageOptions\x18\xcd\xab\xd4\x03 \x01(\x01:6\n\nstring_opt\x12\x1f.google.protobuf.MessageOptions\x18\xc5\xab\xd4\x03 \x01(\t:5\n\tbytes_opt\x12\x1f.google.protobuf.MessageOptions\x18\x96\xab\xd4\x03 \x01(\x0c:p\n\x08\x65num_opt\x12\x1f.google.protobuf.MessageOptions\x18\x91\xab\xd4\x03 \x01(\x0e\x32:.protobuf_unittest.DummyMessageContainingEnum.TestEnumType:p\n\x10message_type_opt\x12\x1f.google.protobuf.MessageOptions\x18\xaf\xf2\xd3\x03 \x01(\x0b\x32\x32.protobuf_unittest.DummyMessageInvalidAsOptionType:6\n\x04quux\x12%.protobuf_unittest.ComplexOptionType1\x18\xdb\xe0\xd3\x03 \x01(\x05:^\n\x05\x63orge\x12%.protobuf_unittest.ComplexOptionType1\x18\xd2\xde\xd3\x03 \x01(\x0b\x32%.protobuf_unittest.ComplexOptionType3:8\n\x06grault\x12%.protobuf_unittest.ComplexOptionType2\x18\xef\xfc\xd2\x03 \x01(\x05:_\n\x06garply\x12%.protobuf_unittest.ComplexOptionType2\x18\xc8\xf5\xd2\x03 \x01(\x0b\x32%.protobuf_unittest.ComplexOptionType1:_\n\x0c\x63omplex_opt1\x12\x1f.google.protobuf.MessageOptions\x18\xa4\xdc\xd2\x03 \x01(\x0b\x32%.protobuf_unittest.ComplexOptionType1:_\n\x0c\x63omplex_opt2\x12\x1f.google.protobuf.MessageOptions\x18\xd5\x8f\xd2\x03 \x01(\x0b\x32%.protobuf_unittest.ComplexOptionType2:_\n\x0c\x63omplex_opt3\x12\x1f.google.protobuf.MessageOptions\x18\xef\x8b\xd2\x03 \x01(\x0b\x32%.protobuf_unittest.ComplexOptionType3:W\n\x0b\x63omplexopt6\x12\x1f.google.protobuf.MessageOptions\x18\xcc\xcb\xcf\x03 \x01(\n2\x1e.protobuf_unittest.ComplexOpt6:N\n\x07\x66ileopt\x12\x1c.google.protobuf.FileOptions\x18\xcf\xdd\xb0\x07 \x01(\x0b\x32\x1c.protobuf_unittest.Aggregate:P\n\x06msgopt\x12\x1f.google.protobuf.MessageOptions\x18\x98\xea\xb0\x07 \x01(\x0b\x32\x1c.protobuf_unittest.Aggregate:P\n\x08\x66ieldopt\x12\x1d.google.protobuf.FieldOptions\x18\x9e\xf4\xb0\x07 \x01(\x0b\x32\x1c.protobuf_unittest.Aggregate:N\n\x07\x65numopt\x12\x1c.google.protobuf.EnumOptions\x18\xd2\x82\xb1\x07 \x01(\x0b\x32\x1c.protobuf_unittest.Aggregate:V\n\nenumvalopt\x12!.google.protobuf.EnumValueOptions\x18\xc9\x9f\xb1\x07 \x01(\x0b\x32\x1c.protobuf_unittest.Aggregate:T\n\nserviceopt\x12\x1f.google.protobuf.ServiceOptions\x18\xb9\xef\xb1\x07 \x01(\x0b\x32\x1c.protobuf_unittest.Aggregate:R\n\tmethodopt\x12\x1e.google.protobuf.MethodOptions\x18\x89\xe9\xb2\x07 \x01(\x0b\x32\x1c.protobuf_unittest.Aggregate:_\n\x11required_enum_opt\x12\x1f.google.protobuf.MessageOptions\x18\x8f\xcd\xcf\x32 \x01(\x0b\x32 .protobuf_unittest.OldOptionTypeB\x87\x01\x80\x01\x01\x88\x01\x01\x90\x01\x01\xf0\xe8\xc1\x1d\xea\xad\xc0\xe5$\xfa\xec\x85;p\x08\x64\x12\x0e\x46ileAnnotation\x1a\x16\x12\x14NestedFileAnnotation\"\x1e\xfa\xec\x85;\x19\x12\x17\x46ileExtensionAnnotation*$\x0b\x10\xf6\xeb\xae\x07\x1a\x1b\n\x19\x45mbeddedMessageSetElement\x0c')
+  ,
+  dependencies=[google_dot_protobuf_dot_descriptor__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+_METHODOPT1 = _descriptor.EnumDescriptor(
+  name='MethodOpt1',
+  full_name='protobuf_unittest.MethodOpt1',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='METHODOPT1_VAL1', index=0, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='METHODOPT1_VAL2', index=1, number=2,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=3006,
+  serialized_end=3060,
+)
+_sym_db.RegisterEnumDescriptor(_METHODOPT1)
+
+MethodOpt1 = enum_type_wrapper.EnumTypeWrapper(_METHODOPT1)
+_AGGREGATEENUM = _descriptor.EnumDescriptor(
+  name='AggregateEnum',
+  full_name='protobuf_unittest.AggregateEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='VALUE', index=0, number=1,
+      options=_descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\312\374\211;\025\022\023EnumValueAnnotation')),
+      type=None),
+  ],
+  containing_type=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\222\225\210;\020\022\016EnumAnnotation')),
+  serialized_start=3062,
+  serialized_end=3139,
+)
+_sym_db.RegisterEnumDescriptor(_AGGREGATEENUM)
+
+AggregateEnum = enum_type_wrapper.EnumTypeWrapper(_AGGREGATEENUM)
+METHODOPT1_VAL1 = 1
+METHODOPT1_VAL2 = 2
+VALUE = 1
+
+FILE_OPT1_FIELD_NUMBER = 7736974
+file_opt1 = _descriptor.FieldDescriptor(
+  name='file_opt1', full_name='protobuf_unittest.file_opt1', index=0,
+  number=7736974, type=4, cpp_type=4, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+MESSAGE_OPT1_FIELD_NUMBER = 7739036
+message_opt1 = _descriptor.FieldDescriptor(
+  name='message_opt1', full_name='protobuf_unittest.message_opt1', index=1,
+  number=7739036, type=5, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+FIELD_OPT1_FIELD_NUMBER = 7740936
+field_opt1 = _descriptor.FieldDescriptor(
+  name='field_opt1', full_name='protobuf_unittest.field_opt1', index=2,
+  number=7740936, type=6, cpp_type=4, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+FIELD_OPT2_FIELD_NUMBER = 7753913
+field_opt2 = _descriptor.FieldDescriptor(
+  name='field_opt2', full_name='protobuf_unittest.field_opt2', index=3,
+  number=7753913, type=5, cpp_type=1, label=1,
+  has_default_value=True, default_value=42,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+ONEOF_OPT1_FIELD_NUMBER = 7740111
+oneof_opt1 = _descriptor.FieldDescriptor(
+  name='oneof_opt1', full_name='protobuf_unittest.oneof_opt1', index=4,
+  number=7740111, type=5, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+ENUM_OPT1_FIELD_NUMBER = 7753576
+enum_opt1 = _descriptor.FieldDescriptor(
+  name='enum_opt1', full_name='protobuf_unittest.enum_opt1', index=5,
+  number=7753576, type=15, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+ENUM_VALUE_OPT1_FIELD_NUMBER = 1560678
+enum_value_opt1 = _descriptor.FieldDescriptor(
+  name='enum_value_opt1', full_name='protobuf_unittest.enum_value_opt1', index=6,
+  number=1560678, type=5, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+SERVICE_OPT1_FIELD_NUMBER = 7887650
+service_opt1 = _descriptor.FieldDescriptor(
+  name='service_opt1', full_name='protobuf_unittest.service_opt1', index=7,
+  number=7887650, type=18, cpp_type=2, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+METHOD_OPT1_FIELD_NUMBER = 7890860
+method_opt1 = _descriptor.FieldDescriptor(
+  name='method_opt1', full_name='protobuf_unittest.method_opt1', index=8,
+  number=7890860, type=14, cpp_type=8, label=1,
+  has_default_value=False, default_value=1,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+BOOL_OPT_FIELD_NUMBER = 7706090
+bool_opt = _descriptor.FieldDescriptor(
+  name='bool_opt', full_name='protobuf_unittest.bool_opt', index=9,
+  number=7706090, type=8, cpp_type=7, label=1,
+  has_default_value=False, default_value=False,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+INT32_OPT_FIELD_NUMBER = 7705709
+int32_opt = _descriptor.FieldDescriptor(
+  name='int32_opt', full_name='protobuf_unittest.int32_opt', index=10,
+  number=7705709, type=5, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+INT64_OPT_FIELD_NUMBER = 7705542
+int64_opt = _descriptor.FieldDescriptor(
+  name='int64_opt', full_name='protobuf_unittest.int64_opt', index=11,
+  number=7705542, type=3, cpp_type=2, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+UINT32_OPT_FIELD_NUMBER = 7704880
+uint32_opt = _descriptor.FieldDescriptor(
+  name='uint32_opt', full_name='protobuf_unittest.uint32_opt', index=12,
+  number=7704880, type=13, cpp_type=3, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+UINT64_OPT_FIELD_NUMBER = 7702367
+uint64_opt = _descriptor.FieldDescriptor(
+  name='uint64_opt', full_name='protobuf_unittest.uint64_opt', index=13,
+  number=7702367, type=4, cpp_type=4, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+SINT32_OPT_FIELD_NUMBER = 7701568
+sint32_opt = _descriptor.FieldDescriptor(
+  name='sint32_opt', full_name='protobuf_unittest.sint32_opt', index=14,
+  number=7701568, type=17, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+SINT64_OPT_FIELD_NUMBER = 7700863
+sint64_opt = _descriptor.FieldDescriptor(
+  name='sint64_opt', full_name='protobuf_unittest.sint64_opt', index=15,
+  number=7700863, type=18, cpp_type=2, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+FIXED32_OPT_FIELD_NUMBER = 7700307
+fixed32_opt = _descriptor.FieldDescriptor(
+  name='fixed32_opt', full_name='protobuf_unittest.fixed32_opt', index=16,
+  number=7700307, type=7, cpp_type=3, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+FIXED64_OPT_FIELD_NUMBER = 7700194
+fixed64_opt = _descriptor.FieldDescriptor(
+  name='fixed64_opt', full_name='protobuf_unittest.fixed64_opt', index=17,
+  number=7700194, type=6, cpp_type=4, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+SFIXED32_OPT_FIELD_NUMBER = 7698645
+sfixed32_opt = _descriptor.FieldDescriptor(
+  name='sfixed32_opt', full_name='protobuf_unittest.sfixed32_opt', index=18,
+  number=7698645, type=15, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+SFIXED64_OPT_FIELD_NUMBER = 7685475
+sfixed64_opt = _descriptor.FieldDescriptor(
+  name='sfixed64_opt', full_name='protobuf_unittest.sfixed64_opt', index=19,
+  number=7685475, type=16, cpp_type=2, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+FLOAT_OPT_FIELD_NUMBER = 7675390
+float_opt = _descriptor.FieldDescriptor(
+  name='float_opt', full_name='protobuf_unittest.float_opt', index=20,
+  number=7675390, type=2, cpp_type=6, label=1,
+  has_default_value=False, default_value=float(0),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DOUBLE_OPT_FIELD_NUMBER = 7673293
+double_opt = _descriptor.FieldDescriptor(
+  name='double_opt', full_name='protobuf_unittest.double_opt', index=21,
+  number=7673293, type=1, cpp_type=5, label=1,
+  has_default_value=False, default_value=float(0),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+STRING_OPT_FIELD_NUMBER = 7673285
+string_opt = _descriptor.FieldDescriptor(
+  name='string_opt', full_name='protobuf_unittest.string_opt', index=22,
+  number=7673285, type=9, cpp_type=9, label=1,
+  has_default_value=False, default_value=_b("").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+BYTES_OPT_FIELD_NUMBER = 7673238
+bytes_opt = _descriptor.FieldDescriptor(
+  name='bytes_opt', full_name='protobuf_unittest.bytes_opt', index=23,
+  number=7673238, type=12, cpp_type=9, label=1,
+  has_default_value=False, default_value=_b(""),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+ENUM_OPT_FIELD_NUMBER = 7673233
+enum_opt = _descriptor.FieldDescriptor(
+  name='enum_opt', full_name='protobuf_unittest.enum_opt', index=24,
+  number=7673233, type=14, cpp_type=8, label=1,
+  has_default_value=False, default_value=22,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+MESSAGE_TYPE_OPT_FIELD_NUMBER = 7665967
+message_type_opt = _descriptor.FieldDescriptor(
+  name='message_type_opt', full_name='protobuf_unittest.message_type_opt', index=25,
+  number=7665967, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+QUUX_FIELD_NUMBER = 7663707
+quux = _descriptor.FieldDescriptor(
+  name='quux', full_name='protobuf_unittest.quux', index=26,
+  number=7663707, type=5, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+CORGE_FIELD_NUMBER = 7663442
+corge = _descriptor.FieldDescriptor(
+  name='corge', full_name='protobuf_unittest.corge', index=27,
+  number=7663442, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+GRAULT_FIELD_NUMBER = 7650927
+grault = _descriptor.FieldDescriptor(
+  name='grault', full_name='protobuf_unittest.grault', index=28,
+  number=7650927, type=5, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+GARPLY_FIELD_NUMBER = 7649992
+garply = _descriptor.FieldDescriptor(
+  name='garply', full_name='protobuf_unittest.garply', index=29,
+  number=7649992, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+COMPLEX_OPT1_FIELD_NUMBER = 7646756
+complex_opt1 = _descriptor.FieldDescriptor(
+  name='complex_opt1', full_name='protobuf_unittest.complex_opt1', index=30,
+  number=7646756, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+COMPLEX_OPT2_FIELD_NUMBER = 7636949
+complex_opt2 = _descriptor.FieldDescriptor(
+  name='complex_opt2', full_name='protobuf_unittest.complex_opt2', index=31,
+  number=7636949, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+COMPLEX_OPT3_FIELD_NUMBER = 7636463
+complex_opt3 = _descriptor.FieldDescriptor(
+  name='complex_opt3', full_name='protobuf_unittest.complex_opt3', index=32,
+  number=7636463, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+COMPLEXOPT6_FIELD_NUMBER = 7595468
+complexopt6 = _descriptor.FieldDescriptor(
+  name='complexopt6', full_name='protobuf_unittest.complexopt6', index=33,
+  number=7595468, type=10, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+FILEOPT_FIELD_NUMBER = 15478479
+fileopt = _descriptor.FieldDescriptor(
+  name='fileopt', full_name='protobuf_unittest.fileopt', index=34,
+  number=15478479, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+MSGOPT_FIELD_NUMBER = 15480088
+msgopt = _descriptor.FieldDescriptor(
+  name='msgopt', full_name='protobuf_unittest.msgopt', index=35,
+  number=15480088, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+FIELDOPT_FIELD_NUMBER = 15481374
+fieldopt = _descriptor.FieldDescriptor(
+  name='fieldopt', full_name='protobuf_unittest.fieldopt', index=36,
+  number=15481374, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+ENUMOPT_FIELD_NUMBER = 15483218
+enumopt = _descriptor.FieldDescriptor(
+  name='enumopt', full_name='protobuf_unittest.enumopt', index=37,
+  number=15483218, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+ENUMVALOPT_FIELD_NUMBER = 15486921
+enumvalopt = _descriptor.FieldDescriptor(
+  name='enumvalopt', full_name='protobuf_unittest.enumvalopt', index=38,
+  number=15486921, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+SERVICEOPT_FIELD_NUMBER = 15497145
+serviceopt = _descriptor.FieldDescriptor(
+  name='serviceopt', full_name='protobuf_unittest.serviceopt', index=39,
+  number=15497145, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+METHODOPT_FIELD_NUMBER = 15512713
+methodopt = _descriptor.FieldDescriptor(
+  name='methodopt', full_name='protobuf_unittest.methodopt', index=40,
+  number=15512713, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REQUIRED_ENUM_OPT_FIELD_NUMBER = 106161807
+required_enum_opt = _descriptor.FieldDescriptor(
+  name='required_enum_opt', full_name='protobuf_unittest.required_enum_opt', index=41,
+  number=106161807, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+
+_TESTMESSAGEWITHCUSTOMOPTIONS_ANENUM = _descriptor.EnumDescriptor(
+  name='AnEnum',
+  full_name='protobuf_unittest.TestMessageWithCustomOptions.AnEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='ANENUM_VAL1', index=0, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='ANENUM_VAL2', index=1, number=2,
+      options=_descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\260\206\372\005{')),
+      type=None),
+  ],
+  containing_type=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\305\366\311\035\353\374\377\377')),
+  serialized_start=190,
+  serialized_end=249,
+)
+_sym_db.RegisterEnumDescriptor(_TESTMESSAGEWITHCUSTOMOPTIONS_ANENUM)
+
+_DUMMYMESSAGECONTAININGENUM_TESTENUMTYPE = _descriptor.EnumDescriptor(
+  name='TestEnumType',
+  full_name='protobuf_unittest.DummyMessageContainingEnum.TestEnumType',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='TEST_OPTION_ENUM_TYPE1', index=0, number=22,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TEST_OPTION_ENUM_TYPE2', index=1, number=-23,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=443,
+  serialized_end=522,
+)
+_sym_db.RegisterEnumDescriptor(_DUMMYMESSAGECONTAININGENUM_TESTENUMTYPE)
+
+_NESTEDOPTIONTYPE_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='protobuf_unittest.NestedOptionType.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='NESTED_ENUM_VALUE', index=0, number=1,
+      options=_descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\260\206\372\005\354\007')),
+      type=None),
+  ],
+  containing_type=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\305\366\311\035\353\003\000\000')),
+  serialized_start=2618,
+  serialized_end=2671,
+)
+_sym_db.RegisterEnumDescriptor(_NESTEDOPTIONTYPE_NESTEDENUM)
+
+_OLDOPTIONTYPE_TESTENUM = _descriptor.EnumDescriptor(
+  name='TestEnum',
+  full_name='protobuf_unittest.OldOptionType.TestEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='OLD_VALUE', index=0, number=0,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=2815,
+  serialized_end=2840,
+)
+_sym_db.RegisterEnumDescriptor(_OLDOPTIONTYPE_TESTENUM)
+
+_NEWOPTIONTYPE_TESTENUM = _descriptor.EnumDescriptor(
+  name='TestEnum',
+  full_name='protobuf_unittest.NewOptionType.TestEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='OLD_VALUE', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='NEW_VALUE', index=1, number=1,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=2917,
+  serialized_end=2957,
+)
+_sym_db.RegisterEnumDescriptor(_NEWOPTIONTYPE_TESTENUM)
+
+
+_TESTMESSAGEWITHCUSTOMOPTIONS = _descriptor.Descriptor(
+  name='TestMessageWithCustomOptions',
+  full_name='protobuf_unittest.TestMessageWithCustomOptions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='field1', full_name='protobuf_unittest.TestMessageWithCustomOptions.field1', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001\301\340\303\035-\341u\n\002\000\000\000'))),
+    _descriptor.FieldDescriptor(
+      name='oneof_field', full_name='protobuf_unittest.TestMessageWithCustomOptions.oneof_field', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _TESTMESSAGEWITHCUSTOMOPTIONS_ANENUM,
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\010\000\340\351\302\035\310\377\377\377\377\377\377\377\377\001')),
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='AnOneof', full_name='protobuf_unittest.TestMessageWithCustomOptions.AnOneof',
+      index=0, containing_type=None, fields=[], options=_descriptor._ParseOptions(descriptor_pb2.OneofOptions(), _b('\370\254\303\035\235\377\377\377\377\377\377\377\377\001'))),
+  ],
+  serialized_start=103,
+  serialized_end=294,
+)
+
+
+_CUSTOMOPTIONFOOREQUEST = _descriptor.Descriptor(
+  name='CustomOptionFooRequest',
+  full_name='protobuf_unittest.CustomOptionFooRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=296,
+  serialized_end=320,
+)
+
+
+_CUSTOMOPTIONFOORESPONSE = _descriptor.Descriptor(
+  name='CustomOptionFooResponse',
+  full_name='protobuf_unittest.CustomOptionFooResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=322,
+  serialized_end=347,
+)
+
+
+_CUSTOMOPTIONFOOCLIENTMESSAGE = _descriptor.Descriptor(
+  name='CustomOptionFooClientMessage',
+  full_name='protobuf_unittest.CustomOptionFooClientMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=349,
+  serialized_end=379,
+)
+
+
+_CUSTOMOPTIONFOOSERVERMESSAGE = _descriptor.Descriptor(
+  name='CustomOptionFooServerMessage',
+  full_name='protobuf_unittest.CustomOptionFooServerMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=381,
+  serialized_end=411,
+)
+
+
+_DUMMYMESSAGECONTAININGENUM = _descriptor.Descriptor(
+  name='DummyMessageContainingEnum',
+  full_name='protobuf_unittest.DummyMessageContainingEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _DUMMYMESSAGECONTAININGENUM_TESTENUMTYPE,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=413,
+  serialized_end=522,
+)
+
+
+_DUMMYMESSAGEINVALIDASOPTIONTYPE = _descriptor.Descriptor(
+  name='DummyMessageInvalidAsOptionType',
+  full_name='protobuf_unittest.DummyMessageInvalidAsOptionType',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=524,
+  serialized_end=557,
+)
+
+
+_CUSTOMOPTIONMININTEGERVALUES = _descriptor.Descriptor(
+  name='CustomOptionMinIntegerValues',
+  full_name='protobuf_unittest.CustomOptionMinIntegerValues',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\320\336\262\035\000\350\306\262\035\200\200\200\200\370\377\377\377\377\001\260\274\262\035\200\200\200\200\200\200\200\200\200\001\200\223\262\035\000\370\365\260\035\000\200\304\260\035\377\377\377\377\017\370\227\260\035\377\377\377\377\377\377\377\377\377\001\235\365\257\035\000\000\000\000\221\356\257\035\000\000\000\000\000\000\000\000\255\215\257\035\000\000\000\200\231\326\250\035\000\000\000\000\000\000\000\200')),
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=560,
+  serialized_end=698,
+)
+
+
+_CUSTOMOPTIONMAXINTEGERVALUES = _descriptor.Descriptor(
+  name='CustomOptionMaxIntegerValues',
+  full_name='protobuf_unittest.CustomOptionMaxIntegerValues',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\320\336\262\035\001\350\306\262\035\377\377\377\377\007\260\274\262\035\377\377\377\377\377\377\377\377\177\200\223\262\035\377\377\377\377\017\370\365\260\035\377\377\377\377\377\377\377\377\377\001\200\304\260\035\376\377\377\377\017\370\227\260\035\376\377\377\377\377\377\377\377\377\001\235\365\257\035\377\377\377\377\221\356\257\035\377\377\377\377\377\377\377\377\255\215\257\035\377\377\377\177\231\326\250\035\377\377\377\377\377\377\377\177')),
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=701,
+  serialized_end=846,
+)
+
+
+_CUSTOMOPTIONOTHERVALUES = _descriptor.Descriptor(
+  name='CustomOptionOtherValues',
+  full_name='protobuf_unittest.CustomOptionOtherValues',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\350\306\262\035\234\377\377\377\377\377\377\377\377\001\365\337\243\035\347\207EA\351\334\242\035\373Y\214B\312\300\363?\252\334\242\035\016Hello, \"World\"\262\331\242\035\013Hello\000World\210\331\242\035\351\377\377\377\377\377\377\377\377\001')),
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=848,
+  serialized_end=958,
+)
+
+
+_SETTINGREALSFROMPOSITIVEINTS = _descriptor.Descriptor(
+  name='SettingRealsFromPositiveInts',
+  full_name='protobuf_unittest.SettingRealsFromPositiveInts',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\365\337\243\035\000\000@A\351\334\242\035\000\000\000\000\000@c@')),
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=960,
+  serialized_end=1012,
+)
+
+
+_SETTINGREALSFROMNEGATIVEINTS = _descriptor.Descriptor(
+  name='SettingRealsFromNegativeInts',
+  full_name='protobuf_unittest.SettingRealsFromNegativeInts',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\365\337\243\035\000\000@\301\351\334\242\035\000\000\000\000\000@c\300')),
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1014,
+  serialized_end=1066,
+)
+
+
+_COMPLEXOPTIONTYPE1 = _descriptor.Descriptor(
+  name='ComplexOptionType1',
+  full_name='protobuf_unittest.ComplexOptionType1',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='foo', full_name='protobuf_unittest.ComplexOptionType1.foo', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo2', full_name='protobuf_unittest.ComplexOptionType1.foo2', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo3', full_name='protobuf_unittest.ComplexOptionType1.foo3', index=2,
+      number=3, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo4', full_name='protobuf_unittest.ComplexOptionType1.foo4', index=3,
+      number=4, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(100, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=1068,
+  serialized_end=1153,
+)
+
+
+_COMPLEXOPTIONTYPE2_COMPLEXOPTIONTYPE4 = _descriptor.Descriptor(
+  name='ComplexOptionType4',
+  full_name='protobuf_unittest.ComplexOptionType2.ComplexOptionType4',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='waldo', full_name='protobuf_unittest.ComplexOptionType2.ComplexOptionType4.waldo', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+    _descriptor.FieldDescriptor(
+      name='complex_opt4', full_name='protobuf_unittest.ComplexOptionType2.ComplexOptionType4.complex_opt4', index=0,
+      number=7633546, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1390,
+  serialized_end=1541,
+)
+
+_COMPLEXOPTIONTYPE2 = _descriptor.Descriptor(
+  name='ComplexOptionType2',
+  full_name='protobuf_unittest.ComplexOptionType2',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='bar', full_name='protobuf_unittest.ComplexOptionType2.bar', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='baz', full_name='protobuf_unittest.ComplexOptionType2.baz', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='fred', full_name='protobuf_unittest.ComplexOptionType2.fred', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='barney', full_name='protobuf_unittest.ComplexOptionType2.barney', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_COMPLEXOPTIONTYPE2_COMPLEXOPTIONTYPE4, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(100, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=1156,
+  serialized_end=1551,
+)
+
+
+_COMPLEXOPTIONTYPE3_COMPLEXOPTIONTYPE5 = _descriptor.Descriptor(
+  name='ComplexOptionType5',
+  full_name='protobuf_unittest.ComplexOptionType3.ComplexOptionType5',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='plugh', full_name='protobuf_unittest.ComplexOptionType3.ComplexOptionType5.plugh', index=0,
+      number=3, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1675,
+  serialized_end=1710,
+)
+
+_COMPLEXOPTIONTYPE3 = _descriptor.Descriptor(
+  name='ComplexOptionType3',
+  full_name='protobuf_unittest.ComplexOptionType3',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='qux', full_name='protobuf_unittest.ComplexOptionType3.qux', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='complexoptiontype5', full_name='protobuf_unittest.ComplexOptionType3.complexoptiontype5', index=1,
+      number=2, type=10, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_COMPLEXOPTIONTYPE3_COMPLEXOPTIONTYPE5, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1554,
+  serialized_end=1710,
+)
+
+
+_COMPLEXOPT6 = _descriptor.Descriptor(
+  name='ComplexOpt6',
+  full_name='protobuf_unittest.ComplexOpt6',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='xyzzy', full_name='protobuf_unittest.ComplexOpt6.xyzzy', index=0,
+      number=7593951, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1712,
+  serialized_end=1743,
+)
+
+
+_VARIOUSCOMPLEXOPTIONS = _descriptor.Descriptor(
+  name='VariousComplexOptions',
+  full_name='protobuf_unittest.VariousComplexOptions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\242\342\225\035\002\010*\242\342\225\035\006\330\205\236\035\304\002\242\342\225\035\010\222\365\235\035\003\010\354\006\242\342\225\035\002 c\242\342\225\035\002 X\252\375\220\035\003\020\333\007\252\375\220\035\006\370\346\227\035\216\005\252\375\220\035\005\n\003\010\347\005\252\375\220\035\010\n\006\330\205\236\035\317\017\252\375\220\035\n\n\010\222\365\235\035\003\010\330\017\252\375\220\035\010\302\254\227\035\003\010\345\005\252\375\220\035\013\302\254\227\035\006\330\205\236\035\316\017\252\375\220\035\r\302\254\227\035\010\222\365\235\035\003\010\311\020\322\250\217\035\003\010\263\017\252\375\220\035\005\032\003\010\301\002\252\375\220\035\004\"\002\010e\252\375\220\035\005\"\003\010\324\001\372\336\220\035\002\010\t\372\336\220\035\004\023\030\026\024\343\334\374\034\370\375\373\034\030\344\334\374\034')),
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1746,
+  serialized_end=1987,
+)
+
+
+_AGGREGATEMESSAGESET = _descriptor.Descriptor(
+  name='AggregateMessageSet',
+  full_name='protobuf_unittest.AggregateMessageSet',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\010\001')),
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(4, 2147483647), ],
+  oneofs=[
+  ],
+  serialized_start=1989,
+  serialized_end=2024,
+)
+
+
+_AGGREGATEMESSAGESETELEMENT = _descriptor.Descriptor(
+  name='AggregateMessageSetElement',
+  full_name='protobuf_unittest.AggregateMessageSetElement',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='s', full_name='protobuf_unittest.AggregateMessageSetElement.s', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+    _descriptor.FieldDescriptor(
+      name='message_set_extension', full_name='protobuf_unittest.AggregateMessageSetElement.message_set_extension', index=0,
+      number=15447542, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2027,
+  serialized_end=2187,
+)
+
+
+_AGGREGATE = _descriptor.Descriptor(
+  name='Aggregate',
+  full_name='protobuf_unittest.Aggregate',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='i', full_name='protobuf_unittest.Aggregate.i', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='s', full_name='protobuf_unittest.Aggregate.s', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='sub', full_name='protobuf_unittest.Aggregate.sub', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='file', full_name='protobuf_unittest.Aggregate.file', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='mset', full_name='protobuf_unittest.Aggregate.mset', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+    _descriptor.FieldDescriptor(
+      name='nested', full_name='protobuf_unittest.Aggregate.nested', index=0,
+      number=15476903, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2190,
+  serialized_end=2443,
+)
+
+
+_AGGREGATEMESSAGE = _descriptor.Descriptor(
+  name='AggregateMessage',
+  full_name='protobuf_unittest.AggregateMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='fieldname', full_name='protobuf_unittest.AggregateMessage.fieldname', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\362\241\207;\021\022\017FieldAnnotation'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\302\321\206;\025\010e\022\021MessageAnnotation')),
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2445,
+  serialized_end=2534,
+)
+
+
+_NESTEDOPTIONTYPE_NESTEDMESSAGE = _descriptor.Descriptor(
+  name='NestedMessage',
+  full_name='protobuf_unittest.NestedOptionType.NestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='nested_field', full_name='protobuf_unittest.NestedOptionType.NestedMessage.nested_field', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\301\340\303\035\352\003\000\000\000\000\000\000'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\340\351\302\035\351\007')),
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2557,
+  serialized_end=2616,
+)
+
+_NESTEDOPTIONTYPE = _descriptor.Descriptor(
+  name='NestedOptionType',
+  full_name='protobuf_unittest.NestedOptionType',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+    _descriptor.FieldDescriptor(
+      name='nested_extension', full_name='protobuf_unittest.NestedOptionType.nested_extension', index=0,
+      number=7912573, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\310\213\312\035\355\007'))),
+  ],
+  nested_types=[_NESTEDOPTIONTYPE_NESTEDMESSAGE, ],
+  enum_types=[
+    _NESTEDOPTIONTYPE_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2537,
+  serialized_end=2738,
+)
+
+
+_OLDOPTIONTYPE = _descriptor.Descriptor(
+  name='OldOptionType',
+  full_name='protobuf_unittest.OldOptionType',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.OldOptionType.value', index=0,
+      number=1, type=14, cpp_type=8, label=2,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _OLDOPTIONTYPE_TESTENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2740,
+  serialized_end=2840,
+)
+
+
+_NEWOPTIONTYPE = _descriptor.Descriptor(
+  name='NewOptionType',
+  full_name='protobuf_unittest.NewOptionType',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='protobuf_unittest.NewOptionType.value', index=0,
+      number=1, type=14, cpp_type=8, label=2,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _NEWOPTIONTYPE_TESTENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2842,
+  serialized_end=2957,
+)
+
+
+_TESTMESSAGEWITHREQUIREDENUMOPTION = _descriptor.Descriptor(
+  name='TestMessageWithRequiredEnumOption',
+  full_name='protobuf_unittest.TestMessageWithRequiredEnumOption',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\372\350\374\224\003\002\010\000')),
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2959,
+  serialized_end=3004,
+)
+
+_TESTMESSAGEWITHCUSTOMOPTIONS_ANENUM.containing_type = _TESTMESSAGEWITHCUSTOMOPTIONS
+_TESTMESSAGEWITHCUSTOMOPTIONS.oneofs_by_name['AnOneof'].fields.append(
+  _TESTMESSAGEWITHCUSTOMOPTIONS.fields_by_name['oneof_field'])
+_TESTMESSAGEWITHCUSTOMOPTIONS.fields_by_name['oneof_field'].containing_oneof = _TESTMESSAGEWITHCUSTOMOPTIONS.oneofs_by_name['AnOneof']
+_DUMMYMESSAGECONTAININGENUM_TESTENUMTYPE.containing_type = _DUMMYMESSAGECONTAININGENUM
+_COMPLEXOPTIONTYPE2_COMPLEXOPTIONTYPE4.containing_type = _COMPLEXOPTIONTYPE2
+_COMPLEXOPTIONTYPE2.fields_by_name['bar'].message_type = _COMPLEXOPTIONTYPE1
+_COMPLEXOPTIONTYPE2.fields_by_name['fred'].message_type = _COMPLEXOPTIONTYPE2_COMPLEXOPTIONTYPE4
+_COMPLEXOPTIONTYPE2.fields_by_name['barney'].message_type = _COMPLEXOPTIONTYPE2_COMPLEXOPTIONTYPE4
+_COMPLEXOPTIONTYPE3_COMPLEXOPTIONTYPE5.containing_type = _COMPLEXOPTIONTYPE3
+_COMPLEXOPTIONTYPE3.fields_by_name['complexoptiontype5'].message_type = _COMPLEXOPTIONTYPE3_COMPLEXOPTIONTYPE5
+_AGGREGATE.fields_by_name['sub'].message_type = _AGGREGATE
+_AGGREGATE.fields_by_name['file'].message_type = google_dot_protobuf_dot_descriptor__pb2._FILEOPTIONS
+_AGGREGATE.fields_by_name['mset'].message_type = _AGGREGATEMESSAGESET
+_NESTEDOPTIONTYPE_NESTEDMESSAGE.containing_type = _NESTEDOPTIONTYPE
+_NESTEDOPTIONTYPE_NESTEDENUM.containing_type = _NESTEDOPTIONTYPE
+_OLDOPTIONTYPE.fields_by_name['value'].enum_type = _OLDOPTIONTYPE_TESTENUM
+_OLDOPTIONTYPE_TESTENUM.containing_type = _OLDOPTIONTYPE
+_NEWOPTIONTYPE.fields_by_name['value'].enum_type = _NEWOPTIONTYPE_TESTENUM
+_NEWOPTIONTYPE_TESTENUM.containing_type = _NEWOPTIONTYPE
+DESCRIPTOR.message_types_by_name['TestMessageWithCustomOptions'] = _TESTMESSAGEWITHCUSTOMOPTIONS
+DESCRIPTOR.message_types_by_name['CustomOptionFooRequest'] = _CUSTOMOPTIONFOOREQUEST
+DESCRIPTOR.message_types_by_name['CustomOptionFooResponse'] = _CUSTOMOPTIONFOORESPONSE
+DESCRIPTOR.message_types_by_name['CustomOptionFooClientMessage'] = _CUSTOMOPTIONFOOCLIENTMESSAGE
+DESCRIPTOR.message_types_by_name['CustomOptionFooServerMessage'] = _CUSTOMOPTIONFOOSERVERMESSAGE
+DESCRIPTOR.message_types_by_name['DummyMessageContainingEnum'] = _DUMMYMESSAGECONTAININGENUM
+DESCRIPTOR.message_types_by_name['DummyMessageInvalidAsOptionType'] = _DUMMYMESSAGEINVALIDASOPTIONTYPE
+DESCRIPTOR.message_types_by_name['CustomOptionMinIntegerValues'] = _CUSTOMOPTIONMININTEGERVALUES
+DESCRIPTOR.message_types_by_name['CustomOptionMaxIntegerValues'] = _CUSTOMOPTIONMAXINTEGERVALUES
+DESCRIPTOR.message_types_by_name['CustomOptionOtherValues'] = _CUSTOMOPTIONOTHERVALUES
+DESCRIPTOR.message_types_by_name['SettingRealsFromPositiveInts'] = _SETTINGREALSFROMPOSITIVEINTS
+DESCRIPTOR.message_types_by_name['SettingRealsFromNegativeInts'] = _SETTINGREALSFROMNEGATIVEINTS
+DESCRIPTOR.message_types_by_name['ComplexOptionType1'] = _COMPLEXOPTIONTYPE1
+DESCRIPTOR.message_types_by_name['ComplexOptionType2'] = _COMPLEXOPTIONTYPE2
+DESCRIPTOR.message_types_by_name['ComplexOptionType3'] = _COMPLEXOPTIONTYPE3
+DESCRIPTOR.message_types_by_name['ComplexOpt6'] = _COMPLEXOPT6
+DESCRIPTOR.message_types_by_name['VariousComplexOptions'] = _VARIOUSCOMPLEXOPTIONS
+DESCRIPTOR.message_types_by_name['AggregateMessageSet'] = _AGGREGATEMESSAGESET
+DESCRIPTOR.message_types_by_name['AggregateMessageSetElement'] = _AGGREGATEMESSAGESETELEMENT
+DESCRIPTOR.message_types_by_name['Aggregate'] = _AGGREGATE
+DESCRIPTOR.message_types_by_name['AggregateMessage'] = _AGGREGATEMESSAGE
+DESCRIPTOR.message_types_by_name['NestedOptionType'] = _NESTEDOPTIONTYPE
+DESCRIPTOR.message_types_by_name['OldOptionType'] = _OLDOPTIONTYPE
+DESCRIPTOR.message_types_by_name['NewOptionType'] = _NEWOPTIONTYPE
+DESCRIPTOR.message_types_by_name['TestMessageWithRequiredEnumOption'] = _TESTMESSAGEWITHREQUIREDENUMOPTION
+DESCRIPTOR.enum_types_by_name['MethodOpt1'] = _METHODOPT1
+DESCRIPTOR.enum_types_by_name['AggregateEnum'] = _AGGREGATEENUM
+DESCRIPTOR.extensions_by_name['file_opt1'] = file_opt1
+DESCRIPTOR.extensions_by_name['message_opt1'] = message_opt1
+DESCRIPTOR.extensions_by_name['field_opt1'] = field_opt1
+DESCRIPTOR.extensions_by_name['field_opt2'] = field_opt2
+DESCRIPTOR.extensions_by_name['oneof_opt1'] = oneof_opt1
+DESCRIPTOR.extensions_by_name['enum_opt1'] = enum_opt1
+DESCRIPTOR.extensions_by_name['enum_value_opt1'] = enum_value_opt1
+DESCRIPTOR.extensions_by_name['service_opt1'] = service_opt1
+DESCRIPTOR.extensions_by_name['method_opt1'] = method_opt1
+DESCRIPTOR.extensions_by_name['bool_opt'] = bool_opt
+DESCRIPTOR.extensions_by_name['int32_opt'] = int32_opt
+DESCRIPTOR.extensions_by_name['int64_opt'] = int64_opt
+DESCRIPTOR.extensions_by_name['uint32_opt'] = uint32_opt
+DESCRIPTOR.extensions_by_name['uint64_opt'] = uint64_opt
+DESCRIPTOR.extensions_by_name['sint32_opt'] = sint32_opt
+DESCRIPTOR.extensions_by_name['sint64_opt'] = sint64_opt
+DESCRIPTOR.extensions_by_name['fixed32_opt'] = fixed32_opt
+DESCRIPTOR.extensions_by_name['fixed64_opt'] = fixed64_opt
+DESCRIPTOR.extensions_by_name['sfixed32_opt'] = sfixed32_opt
+DESCRIPTOR.extensions_by_name['sfixed64_opt'] = sfixed64_opt
+DESCRIPTOR.extensions_by_name['float_opt'] = float_opt
+DESCRIPTOR.extensions_by_name['double_opt'] = double_opt
+DESCRIPTOR.extensions_by_name['string_opt'] = string_opt
+DESCRIPTOR.extensions_by_name['bytes_opt'] = bytes_opt
+DESCRIPTOR.extensions_by_name['enum_opt'] = enum_opt
+DESCRIPTOR.extensions_by_name['message_type_opt'] = message_type_opt
+DESCRIPTOR.extensions_by_name['quux'] = quux
+DESCRIPTOR.extensions_by_name['corge'] = corge
+DESCRIPTOR.extensions_by_name['grault'] = grault
+DESCRIPTOR.extensions_by_name['garply'] = garply
+DESCRIPTOR.extensions_by_name['complex_opt1'] = complex_opt1
+DESCRIPTOR.extensions_by_name['complex_opt2'] = complex_opt2
+DESCRIPTOR.extensions_by_name['complex_opt3'] = complex_opt3
+DESCRIPTOR.extensions_by_name['complexopt6'] = complexopt6
+DESCRIPTOR.extensions_by_name['fileopt'] = fileopt
+DESCRIPTOR.extensions_by_name['msgopt'] = msgopt
+DESCRIPTOR.extensions_by_name['fieldopt'] = fieldopt
+DESCRIPTOR.extensions_by_name['enumopt'] = enumopt
+DESCRIPTOR.extensions_by_name['enumvalopt'] = enumvalopt
+DESCRIPTOR.extensions_by_name['serviceopt'] = serviceopt
+DESCRIPTOR.extensions_by_name['methodopt'] = methodopt
+DESCRIPTOR.extensions_by_name['required_enum_opt'] = required_enum_opt
+
+TestMessageWithCustomOptions = _reflection.GeneratedProtocolMessageType('TestMessageWithCustomOptions', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMESSAGEWITHCUSTOMOPTIONS,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMessageWithCustomOptions)
+  ))
+_sym_db.RegisterMessage(TestMessageWithCustomOptions)
+
+CustomOptionFooRequest = _reflection.GeneratedProtocolMessageType('CustomOptionFooRequest', (_message.Message,), dict(
+  DESCRIPTOR = _CUSTOMOPTIONFOOREQUEST,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.CustomOptionFooRequest)
+  ))
+_sym_db.RegisterMessage(CustomOptionFooRequest)
+
+CustomOptionFooResponse = _reflection.GeneratedProtocolMessageType('CustomOptionFooResponse', (_message.Message,), dict(
+  DESCRIPTOR = _CUSTOMOPTIONFOORESPONSE,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.CustomOptionFooResponse)
+  ))
+_sym_db.RegisterMessage(CustomOptionFooResponse)
+
+CustomOptionFooClientMessage = _reflection.GeneratedProtocolMessageType('CustomOptionFooClientMessage', (_message.Message,), dict(
+  DESCRIPTOR = _CUSTOMOPTIONFOOCLIENTMESSAGE,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.CustomOptionFooClientMessage)
+  ))
+_sym_db.RegisterMessage(CustomOptionFooClientMessage)
+
+CustomOptionFooServerMessage = _reflection.GeneratedProtocolMessageType('CustomOptionFooServerMessage', (_message.Message,), dict(
+  DESCRIPTOR = _CUSTOMOPTIONFOOSERVERMESSAGE,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.CustomOptionFooServerMessage)
+  ))
+_sym_db.RegisterMessage(CustomOptionFooServerMessage)
+
+DummyMessageContainingEnum = _reflection.GeneratedProtocolMessageType('DummyMessageContainingEnum', (_message.Message,), dict(
+  DESCRIPTOR = _DUMMYMESSAGECONTAININGENUM,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.DummyMessageContainingEnum)
+  ))
+_sym_db.RegisterMessage(DummyMessageContainingEnum)
+
+DummyMessageInvalidAsOptionType = _reflection.GeneratedProtocolMessageType('DummyMessageInvalidAsOptionType', (_message.Message,), dict(
+  DESCRIPTOR = _DUMMYMESSAGEINVALIDASOPTIONTYPE,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.DummyMessageInvalidAsOptionType)
+  ))
+_sym_db.RegisterMessage(DummyMessageInvalidAsOptionType)
+
+CustomOptionMinIntegerValues = _reflection.GeneratedProtocolMessageType('CustomOptionMinIntegerValues', (_message.Message,), dict(
+  DESCRIPTOR = _CUSTOMOPTIONMININTEGERVALUES,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.CustomOptionMinIntegerValues)
+  ))
+_sym_db.RegisterMessage(CustomOptionMinIntegerValues)
+
+CustomOptionMaxIntegerValues = _reflection.GeneratedProtocolMessageType('CustomOptionMaxIntegerValues', (_message.Message,), dict(
+  DESCRIPTOR = _CUSTOMOPTIONMAXINTEGERVALUES,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.CustomOptionMaxIntegerValues)
+  ))
+_sym_db.RegisterMessage(CustomOptionMaxIntegerValues)
+
+CustomOptionOtherValues = _reflection.GeneratedProtocolMessageType('CustomOptionOtherValues', (_message.Message,), dict(
+  DESCRIPTOR = _CUSTOMOPTIONOTHERVALUES,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.CustomOptionOtherValues)
+  ))
+_sym_db.RegisterMessage(CustomOptionOtherValues)
+
+SettingRealsFromPositiveInts = _reflection.GeneratedProtocolMessageType('SettingRealsFromPositiveInts', (_message.Message,), dict(
+  DESCRIPTOR = _SETTINGREALSFROMPOSITIVEINTS,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.SettingRealsFromPositiveInts)
+  ))
+_sym_db.RegisterMessage(SettingRealsFromPositiveInts)
+
+SettingRealsFromNegativeInts = _reflection.GeneratedProtocolMessageType('SettingRealsFromNegativeInts', (_message.Message,), dict(
+  DESCRIPTOR = _SETTINGREALSFROMNEGATIVEINTS,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.SettingRealsFromNegativeInts)
+  ))
+_sym_db.RegisterMessage(SettingRealsFromNegativeInts)
+
+ComplexOptionType1 = _reflection.GeneratedProtocolMessageType('ComplexOptionType1', (_message.Message,), dict(
+  DESCRIPTOR = _COMPLEXOPTIONTYPE1,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.ComplexOptionType1)
+  ))
+_sym_db.RegisterMessage(ComplexOptionType1)
+
+ComplexOptionType2 = _reflection.GeneratedProtocolMessageType('ComplexOptionType2', (_message.Message,), dict(
+
+  ComplexOptionType4 = _reflection.GeneratedProtocolMessageType('ComplexOptionType4', (_message.Message,), dict(
+    DESCRIPTOR = _COMPLEXOPTIONTYPE2_COMPLEXOPTIONTYPE4,
+    __module__ = 'google.protobuf.unittest_custom_options_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.ComplexOptionType2.ComplexOptionType4)
+    ))
+  ,
+  DESCRIPTOR = _COMPLEXOPTIONTYPE2,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.ComplexOptionType2)
+  ))
+_sym_db.RegisterMessage(ComplexOptionType2)
+_sym_db.RegisterMessage(ComplexOptionType2.ComplexOptionType4)
+
+ComplexOptionType3 = _reflection.GeneratedProtocolMessageType('ComplexOptionType3', (_message.Message,), dict(
+
+  ComplexOptionType5 = _reflection.GeneratedProtocolMessageType('ComplexOptionType5', (_message.Message,), dict(
+    DESCRIPTOR = _COMPLEXOPTIONTYPE3_COMPLEXOPTIONTYPE5,
+    __module__ = 'google.protobuf.unittest_custom_options_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.ComplexOptionType3.ComplexOptionType5)
+    ))
+  ,
+  DESCRIPTOR = _COMPLEXOPTIONTYPE3,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.ComplexOptionType3)
+  ))
+_sym_db.RegisterMessage(ComplexOptionType3)
+_sym_db.RegisterMessage(ComplexOptionType3.ComplexOptionType5)
+
+ComplexOpt6 = _reflection.GeneratedProtocolMessageType('ComplexOpt6', (_message.Message,), dict(
+  DESCRIPTOR = _COMPLEXOPT6,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.ComplexOpt6)
+  ))
+_sym_db.RegisterMessage(ComplexOpt6)
+
+VariousComplexOptions = _reflection.GeneratedProtocolMessageType('VariousComplexOptions', (_message.Message,), dict(
+  DESCRIPTOR = _VARIOUSCOMPLEXOPTIONS,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.VariousComplexOptions)
+  ))
+_sym_db.RegisterMessage(VariousComplexOptions)
+
+AggregateMessageSet = _reflection.GeneratedProtocolMessageType('AggregateMessageSet', (_message.Message,), dict(
+  DESCRIPTOR = _AGGREGATEMESSAGESET,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.AggregateMessageSet)
+  ))
+_sym_db.RegisterMessage(AggregateMessageSet)
+
+AggregateMessageSetElement = _reflection.GeneratedProtocolMessageType('AggregateMessageSetElement', (_message.Message,), dict(
+  DESCRIPTOR = _AGGREGATEMESSAGESETELEMENT,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.AggregateMessageSetElement)
+  ))
+_sym_db.RegisterMessage(AggregateMessageSetElement)
+
+Aggregate = _reflection.GeneratedProtocolMessageType('Aggregate', (_message.Message,), dict(
+  DESCRIPTOR = _AGGREGATE,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.Aggregate)
+  ))
+_sym_db.RegisterMessage(Aggregate)
+
+AggregateMessage = _reflection.GeneratedProtocolMessageType('AggregateMessage', (_message.Message,), dict(
+  DESCRIPTOR = _AGGREGATEMESSAGE,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.AggregateMessage)
+  ))
+_sym_db.RegisterMessage(AggregateMessage)
+
+NestedOptionType = _reflection.GeneratedProtocolMessageType('NestedOptionType', (_message.Message,), dict(
+
+  NestedMessage = _reflection.GeneratedProtocolMessageType('NestedMessage', (_message.Message,), dict(
+    DESCRIPTOR = _NESTEDOPTIONTYPE_NESTEDMESSAGE,
+    __module__ = 'google.protobuf.unittest_custom_options_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.NestedOptionType.NestedMessage)
+    ))
+  ,
+  DESCRIPTOR = _NESTEDOPTIONTYPE,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.NestedOptionType)
+  ))
+_sym_db.RegisterMessage(NestedOptionType)
+_sym_db.RegisterMessage(NestedOptionType.NestedMessage)
+
+OldOptionType = _reflection.GeneratedProtocolMessageType('OldOptionType', (_message.Message,), dict(
+  DESCRIPTOR = _OLDOPTIONTYPE,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.OldOptionType)
+  ))
+_sym_db.RegisterMessage(OldOptionType)
+
+NewOptionType = _reflection.GeneratedProtocolMessageType('NewOptionType', (_message.Message,), dict(
+  DESCRIPTOR = _NEWOPTIONTYPE,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.NewOptionType)
+  ))
+_sym_db.RegisterMessage(NewOptionType)
+
+TestMessageWithRequiredEnumOption = _reflection.GeneratedProtocolMessageType('TestMessageWithRequiredEnumOption', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMESSAGEWITHREQUIREDENUMOPTION,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMessageWithRequiredEnumOption)
+  ))
+_sym_db.RegisterMessage(TestMessageWithRequiredEnumOption)
+
+google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(file_opt1)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(message_opt1)
+google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(field_opt1)
+google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(field_opt2)
+google_dot_protobuf_dot_descriptor__pb2.OneofOptions.RegisterExtension(oneof_opt1)
+google_dot_protobuf_dot_descriptor__pb2.EnumOptions.RegisterExtension(enum_opt1)
+google_dot_protobuf_dot_descriptor__pb2.EnumValueOptions.RegisterExtension(enum_value_opt1)
+google_dot_protobuf_dot_descriptor__pb2.ServiceOptions.RegisterExtension(service_opt1)
+method_opt1.enum_type = _METHODOPT1
+google_dot_protobuf_dot_descriptor__pb2.MethodOptions.RegisterExtension(method_opt1)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(bool_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(int32_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(int64_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(uint32_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(uint64_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(sint32_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(sint64_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(fixed32_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(fixed64_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(sfixed32_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(sfixed64_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(float_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(double_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(string_opt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(bytes_opt)
+enum_opt.enum_type = _DUMMYMESSAGECONTAININGENUM_TESTENUMTYPE
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(enum_opt)
+message_type_opt.message_type = _DUMMYMESSAGEINVALIDASOPTIONTYPE
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(message_type_opt)
+ComplexOptionType1.RegisterExtension(quux)
+corge.message_type = _COMPLEXOPTIONTYPE3
+ComplexOptionType1.RegisterExtension(corge)
+ComplexOptionType2.RegisterExtension(grault)
+garply.message_type = _COMPLEXOPTIONTYPE1
+ComplexOptionType2.RegisterExtension(garply)
+complex_opt1.message_type = _COMPLEXOPTIONTYPE1
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(complex_opt1)
+complex_opt2.message_type = _COMPLEXOPTIONTYPE2
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(complex_opt2)
+complex_opt3.message_type = _COMPLEXOPTIONTYPE3
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(complex_opt3)
+complexopt6.message_type = _COMPLEXOPT6
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(complexopt6)
+fileopt.message_type = _AGGREGATE
+google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(fileopt)
+msgopt.message_type = _AGGREGATE
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(msgopt)
+fieldopt.message_type = _AGGREGATE
+google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(fieldopt)
+enumopt.message_type = _AGGREGATE
+google_dot_protobuf_dot_descriptor__pb2.EnumOptions.RegisterExtension(enumopt)
+enumvalopt.message_type = _AGGREGATE
+google_dot_protobuf_dot_descriptor__pb2.EnumValueOptions.RegisterExtension(enumvalopt)
+serviceopt.message_type = _AGGREGATE
+google_dot_protobuf_dot_descriptor__pb2.ServiceOptions.RegisterExtension(serviceopt)
+methodopt.message_type = _AGGREGATE
+google_dot_protobuf_dot_descriptor__pb2.MethodOptions.RegisterExtension(methodopt)
+required_enum_opt.message_type = _OLDOPTIONTYPE
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(required_enum_opt)
+_COMPLEXOPTIONTYPE2_COMPLEXOPTIONTYPE4.extensions_by_name['complex_opt4'].message_type = _COMPLEXOPTIONTYPE2_COMPLEXOPTIONTYPE4
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(_COMPLEXOPTIONTYPE2_COMPLEXOPTIONTYPE4.extensions_by_name['complex_opt4'])
+_AGGREGATEMESSAGESETELEMENT.extensions_by_name['message_set_extension'].message_type = _AGGREGATEMESSAGESETELEMENT
+AggregateMessageSet.RegisterExtension(_AGGREGATEMESSAGESETELEMENT.extensions_by_name['message_set_extension'])
+_AGGREGATE.extensions_by_name['nested'].message_type = _AGGREGATE
+google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(_AGGREGATE.extensions_by_name['nested'])
+google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(_NESTEDOPTIONTYPE.extensions_by_name['nested_extension'])
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\200\001\001\210\001\001\220\001\001\360\350\301\035\352\255\300\345$\372\354\205;p\010d\022\016FileAnnotation\032\026\022\024NestedFileAnnotation\"\036\372\354\205;\031\022\027FileExtensionAnnotation*$\013\020\366\353\256\007\032\033\n\031EmbeddedMessageSetElement\014'))
+_AGGREGATEENUM.has_options = True
+_AGGREGATEENUM._options = _descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\222\225\210;\020\022\016EnumAnnotation'))
+_AGGREGATEENUM.values_by_name["VALUE"].has_options = True
+_AGGREGATEENUM.values_by_name["VALUE"]._options = _descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\312\374\211;\025\022\023EnumValueAnnotation'))
+_TESTMESSAGEWITHCUSTOMOPTIONS.oneofs_by_name['AnOneof'].has_options = True
+_TESTMESSAGEWITHCUSTOMOPTIONS.oneofs_by_name['AnOneof']._options = _descriptor._ParseOptions(descriptor_pb2.OneofOptions(), _b('\370\254\303\035\235\377\377\377\377\377\377\377\377\001'))
+_TESTMESSAGEWITHCUSTOMOPTIONS_ANENUM.has_options = True
+_TESTMESSAGEWITHCUSTOMOPTIONS_ANENUM._options = _descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\305\366\311\035\353\374\377\377'))
+_TESTMESSAGEWITHCUSTOMOPTIONS_ANENUM.values_by_name["ANENUM_VAL2"].has_options = True
+_TESTMESSAGEWITHCUSTOMOPTIONS_ANENUM.values_by_name["ANENUM_VAL2"]._options = _descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\260\206\372\005{'))
+_TESTMESSAGEWITHCUSTOMOPTIONS.fields_by_name['field1'].has_options = True
+_TESTMESSAGEWITHCUSTOMOPTIONS.fields_by_name['field1']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001\301\340\303\035-\341u\n\002\000\000\000'))
+_TESTMESSAGEWITHCUSTOMOPTIONS.has_options = True
+_TESTMESSAGEWITHCUSTOMOPTIONS._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\010\000\340\351\302\035\310\377\377\377\377\377\377\377\377\001'))
+_CUSTOMOPTIONMININTEGERVALUES.has_options = True
+_CUSTOMOPTIONMININTEGERVALUES._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\320\336\262\035\000\350\306\262\035\200\200\200\200\370\377\377\377\377\001\260\274\262\035\200\200\200\200\200\200\200\200\200\001\200\223\262\035\000\370\365\260\035\000\200\304\260\035\377\377\377\377\017\370\227\260\035\377\377\377\377\377\377\377\377\377\001\235\365\257\035\000\000\000\000\221\356\257\035\000\000\000\000\000\000\000\000\255\215\257\035\000\000\000\200\231\326\250\035\000\000\000\000\000\000\000\200'))
+_CUSTOMOPTIONMAXINTEGERVALUES.has_options = True
+_CUSTOMOPTIONMAXINTEGERVALUES._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\320\336\262\035\001\350\306\262\035\377\377\377\377\007\260\274\262\035\377\377\377\377\377\377\377\377\177\200\223\262\035\377\377\377\377\017\370\365\260\035\377\377\377\377\377\377\377\377\377\001\200\304\260\035\376\377\377\377\017\370\227\260\035\376\377\377\377\377\377\377\377\377\001\235\365\257\035\377\377\377\377\221\356\257\035\377\377\377\377\377\377\377\377\255\215\257\035\377\377\377\177\231\326\250\035\377\377\377\377\377\377\377\177'))
+_CUSTOMOPTIONOTHERVALUES.has_options = True
+_CUSTOMOPTIONOTHERVALUES._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\350\306\262\035\234\377\377\377\377\377\377\377\377\001\365\337\243\035\347\207EA\351\334\242\035\373Y\214B\312\300\363?\252\334\242\035\016Hello, \"World\"\262\331\242\035\013Hello\000World\210\331\242\035\351\377\377\377\377\377\377\377\377\001'))
+_SETTINGREALSFROMPOSITIVEINTS.has_options = True
+_SETTINGREALSFROMPOSITIVEINTS._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\365\337\243\035\000\000@A\351\334\242\035\000\000\000\000\000@c@'))
+_SETTINGREALSFROMNEGATIVEINTS.has_options = True
+_SETTINGREALSFROMNEGATIVEINTS._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\365\337\243\035\000\000@\301\351\334\242\035\000\000\000\000\000@c\300'))
+_VARIOUSCOMPLEXOPTIONS.has_options = True
+_VARIOUSCOMPLEXOPTIONS._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\242\342\225\035\002\010*\242\342\225\035\006\330\205\236\035\304\002\242\342\225\035\010\222\365\235\035\003\010\354\006\242\342\225\035\002 c\242\342\225\035\002 X\252\375\220\035\003\020\333\007\252\375\220\035\006\370\346\227\035\216\005\252\375\220\035\005\n\003\010\347\005\252\375\220\035\010\n\006\330\205\236\035\317\017\252\375\220\035\n\n\010\222\365\235\035\003\010\330\017\252\375\220\035\010\302\254\227\035\003\010\345\005\252\375\220\035\013\302\254\227\035\006\330\205\236\035\316\017\252\375\220\035\r\302\254\227\035\010\222\365\235\035\003\010\311\020\322\250\217\035\003\010\263\017\252\375\220\035\005\032\003\010\301\002\252\375\220\035\004\"\002\010e\252\375\220\035\005\"\003\010\324\001\372\336\220\035\002\010\t\372\336\220\035\004\023\030\026\024\343\334\374\034\370\375\373\034\030\344\334\374\034'))
+_AGGREGATEMESSAGESET.has_options = True
+_AGGREGATEMESSAGESET._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\010\001'))
+_AGGREGATEMESSAGE.fields_by_name['fieldname'].has_options = True
+_AGGREGATEMESSAGE.fields_by_name['fieldname']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\362\241\207;\021\022\017FieldAnnotation'))
+_AGGREGATEMESSAGE.has_options = True
+_AGGREGATEMESSAGE._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\302\321\206;\025\010e\022\021MessageAnnotation'))
+_NESTEDOPTIONTYPE_NESTEDMESSAGE.fields_by_name['nested_field'].has_options = True
+_NESTEDOPTIONTYPE_NESTEDMESSAGE.fields_by_name['nested_field']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\301\340\303\035\352\003\000\000\000\000\000\000'))
+_NESTEDOPTIONTYPE_NESTEDMESSAGE.has_options = True
+_NESTEDOPTIONTYPE_NESTEDMESSAGE._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\340\351\302\035\351\007'))
+_NESTEDOPTIONTYPE_NESTEDENUM.has_options = True
+_NESTEDOPTIONTYPE_NESTEDENUM._options = _descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\305\366\311\035\353\003\000\000'))
+_NESTEDOPTIONTYPE_NESTEDENUM.values_by_name["NESTED_ENUM_VALUE"].has_options = True
+_NESTEDOPTIONTYPE_NESTEDENUM.values_by_name["NESTED_ENUM_VALUE"]._options = _descriptor._ParseOptions(descriptor_pb2.EnumValueOptions(), _b('\260\206\372\005\354\007'))
+_NESTEDOPTIONTYPE.extensions_by_name['nested_extension'].has_options = True
+_NESTEDOPTIONTYPE.extensions_by_name['nested_extension']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\310\213\312\035\355\007'))
+_TESTMESSAGEWITHREQUIREDENUMOPTION.has_options = True
+_TESTMESSAGEWITHREQUIREDENUMOPTION._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\372\350\374\224\003\002\010\000'))
+
+_TESTSERVICEWITHCUSTOMOPTIONS = _descriptor.ServiceDescriptor(
+  name='TestServiceWithCustomOptions',
+  full_name='protobuf_unittest.TestServiceWithCustomOptions',
+  file=DESCRIPTOR,
+  index=0,
+  options=_descriptor._ParseOptions(descriptor_pb2.ServiceOptions(), _b('\220\262\213\036\323\333\200\313I')),
+  serialized_start=3142,
+  serialized_end=3284,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='Foo',
+    full_name='protobuf_unittest.TestServiceWithCustomOptions.Foo',
+    index=0,
+    containing_service=None,
+    input_type=_CUSTOMOPTIONFOOREQUEST,
+    output_type=_CUSTOMOPTIONFOORESPONSE,
+    options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\340\372\214\036\002')),
+  ),
+])
+
+TestServiceWithCustomOptions = service_reflection.GeneratedServiceType('TestServiceWithCustomOptions', (_service.Service,), dict(
+  DESCRIPTOR = _TESTSERVICEWITHCUSTOMOPTIONS,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  ))
+
+TestServiceWithCustomOptions_Stub = service_reflection.GeneratedServiceStubType('TestServiceWithCustomOptions_Stub', (TestServiceWithCustomOptions,), dict(
+  DESCRIPTOR = _TESTSERVICEWITHCUSTOMOPTIONS,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  ))
+
+
+
+_AGGREGATESERVICE = _descriptor.ServiceDescriptor(
+  name='AggregateService',
+  full_name='protobuf_unittest.AggregateService',
+  file=DESCRIPTOR,
+  index=1,
+  options=_descriptor._ParseOptions(descriptor_pb2.ServiceOptions(), _b('\312\373\216;\023\022\021ServiceAnnotation')),
+  serialized_start=3287,
+  serialized_end=3440,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='Method',
+    full_name='protobuf_unittest.AggregateService.Method',
+    index=0,
+    containing_service=None,
+    input_type=_AGGREGATEMESSAGE,
+    output_type=_AGGREGATEMESSAGE,
+    options=_descriptor._ParseOptions(descriptor_pb2.MethodOptions(), _b('\312\310\226;\022\022\020MethodAnnotation')),
+  ),
+])
+
+AggregateService = service_reflection.GeneratedServiceType('AggregateService', (_service.Service,), dict(
+  DESCRIPTOR = _AGGREGATESERVICE,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  ))
+
+AggregateService_Stub = service_reflection.GeneratedServiceStubType('AggregateService_Stub', (AggregateService,), dict(
+  DESCRIPTOR = _AGGREGATESERVICE,
+  __module__ = 'google.protobuf.unittest_custom_options_pb2'
+  ))
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/unittest_import_pb2.py b/generator/google/protobuf/unittest_import_pb2.py
new file mode 100644
index 0000000..0e80b85
--- /dev/null
+++ b/generator/google/protobuf/unittest_import_pb2.py
@@ -0,0 +1,137 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/unittest_import.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import unittest_import_public_pb2 as google_dot_protobuf_dot_unittest__import__public__pb2
+
+from google.protobuf.unittest_import_public_pb2 import *
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/unittest_import.proto',
+  package='protobuf_unittest_import',
+  syntax='proto2',
+  serialized_pb=_b('\n%google/protobuf/unittest_import.proto\x12\x18protobuf_unittest_import\x1a,google/protobuf/unittest_import_public.proto\"\x1a\n\rImportMessage\x12\t\n\x01\x64\x18\x01 \x01(\x05*<\n\nImportEnum\x12\x0e\n\nIMPORT_FOO\x10\x07\x12\x0e\n\nIMPORT_BAR\x10\x08\x12\x0e\n\nIMPORT_BAZ\x10\t*1\n\x10ImportEnumForMap\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03\x46OO\x10\x01\x12\x07\n\x03\x42\x41R\x10\x02\x42\x1f\n\x18\x63om.google.protobuf.testH\x01\xf8\x01\x01P\x00')
+  ,
+  dependencies=[google_dot_protobuf_dot_unittest__import__public__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+_IMPORTENUM = _descriptor.EnumDescriptor(
+  name='ImportEnum',
+  full_name='protobuf_unittest_import.ImportEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='IMPORT_FOO', index=0, number=7,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='IMPORT_BAR', index=1, number=8,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='IMPORT_BAZ', index=2, number=9,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=141,
+  serialized_end=201,
+)
+_sym_db.RegisterEnumDescriptor(_IMPORTENUM)
+
+ImportEnum = enum_type_wrapper.EnumTypeWrapper(_IMPORTENUM)
+_IMPORTENUMFORMAP = _descriptor.EnumDescriptor(
+  name='ImportEnumForMap',
+  full_name='protobuf_unittest_import.ImportEnumForMap',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='UNKNOWN', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FOO', index=1, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAR', index=2, number=2,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=203,
+  serialized_end=252,
+)
+_sym_db.RegisterEnumDescriptor(_IMPORTENUMFORMAP)
+
+ImportEnumForMap = enum_type_wrapper.EnumTypeWrapper(_IMPORTENUMFORMAP)
+IMPORT_FOO = 7
+IMPORT_BAR = 8
+IMPORT_BAZ = 9
+UNKNOWN = 0
+FOO = 1
+BAR = 2
+
+
+
+_IMPORTMESSAGE = _descriptor.Descriptor(
+  name='ImportMessage',
+  full_name='protobuf_unittest_import.ImportMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='d', full_name='protobuf_unittest_import.ImportMessage.d', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=113,
+  serialized_end=139,
+)
+
+DESCRIPTOR.message_types_by_name['ImportMessage'] = _IMPORTMESSAGE
+DESCRIPTOR.enum_types_by_name['ImportEnum'] = _IMPORTENUM
+DESCRIPTOR.enum_types_by_name['ImportEnumForMap'] = _IMPORTENUMFORMAP
+
+ImportMessage = _reflection.GeneratedProtocolMessageType('ImportMessage', (_message.Message,), dict(
+  DESCRIPTOR = _IMPORTMESSAGE,
+  __module__ = 'google.protobuf.unittest_import_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest_import.ImportMessage)
+  ))
+_sym_db.RegisterMessage(ImportMessage)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\030com.google.protobuf.testH\001\370\001\001'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/unittest_import_public_pb2.py b/generator/google/protobuf/unittest_import_public_pb2.py
new file mode 100644
index 0000000..8627385
--- /dev/null
+++ b/generator/google/protobuf/unittest_import_public_pb2.py
@@ -0,0 +1,71 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/unittest_import_public.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/unittest_import_public.proto',
+  package='protobuf_unittest_import',
+  syntax='proto2',
+  serialized_pb=_b('\n,google/protobuf/unittest_import_public.proto\x12\x18protobuf_unittest_import\" \n\x13PublicImportMessage\x12\t\n\x01\x65\x18\x01 \x01(\x05\x42\x1a\n\x18\x63om.google.protobuf.test')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_PUBLICIMPORTMESSAGE = _descriptor.Descriptor(
+  name='PublicImportMessage',
+  full_name='protobuf_unittest_import.PublicImportMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='e', full_name='protobuf_unittest_import.PublicImportMessage.e', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=74,
+  serialized_end=106,
+)
+
+DESCRIPTOR.message_types_by_name['PublicImportMessage'] = _PUBLICIMPORTMESSAGE
+
+PublicImportMessage = _reflection.GeneratedProtocolMessageType('PublicImportMessage', (_message.Message,), dict(
+  DESCRIPTOR = _PUBLICIMPORTMESSAGE,
+  __module__ = 'google.protobuf.unittest_import_public_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest_import.PublicImportMessage)
+  ))
+_sym_db.RegisterMessage(PublicImportMessage)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\030com.google.protobuf.test'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/unittest_mset_pb2.py b/generator/google/protobuf/unittest_mset_pb2.py
new file mode 100644
index 0000000..c76e484
--- /dev/null
+++ b/generator/google/protobuf/unittest_mset_pb2.py
@@ -0,0 +1,256 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/unittest_mset.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import unittest_mset_wire_format_pb2 as google_dot_protobuf_dot_unittest__mset__wire__format__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/unittest_mset.proto',
+  package='protobuf_unittest',
+  syntax='proto2',
+  serialized_pb=_b('\n#google/protobuf/unittest_mset.proto\x12\x11protobuf_unittest\x1a/google/protobuf/unittest_mset_wire_format.proto\"Z\n\x17TestMessageSetContainer\x12?\n\x0bmessage_set\x18\x01 \x01(\x0b\x32*.proto2_wireformat_unittest.TestMessageSet\"\x9f\x01\n\x18TestMessageSetExtension1\x12\t\n\x01i\x18\x0f \x01(\x05\x32x\n\x15message_set_extension\x12*.proto2_wireformat_unittest.TestMessageSet\x18\xb0\xa6^ \x01(\x0b\x32+.protobuf_unittest.TestMessageSetExtension1\"\xa1\x01\n\x18TestMessageSetExtension2\x12\x0b\n\x03str\x18\x19 \x01(\t2x\n\x15message_set_extension\x12*.proto2_wireformat_unittest.TestMessageSet\x18\xf9\xbb^ \x01(\x0b\x32+.protobuf_unittest.TestMessageSetExtension2\"n\n\rRawMessageSet\x12\x33\n\x04item\x18\x01 \x03(\n2%.protobuf_unittest.RawMessageSet.Item\x1a(\n\x04Item\x12\x0f\n\x07type_id\x18\x02 \x02(\x05\x12\x0f\n\x07message\x18\x03 \x02(\x0c\x42\x05H\x01\xf8\x01\x01')
+  ,
+  dependencies=[google_dot_protobuf_dot_unittest__mset__wire__format__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_TESTMESSAGESETCONTAINER = _descriptor.Descriptor(
+  name='TestMessageSetContainer',
+  full_name='protobuf_unittest.TestMessageSetContainer',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='message_set', full_name='protobuf_unittest.TestMessageSetContainer.message_set', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=107,
+  serialized_end=197,
+)
+
+
+_TESTMESSAGESETEXTENSION1 = _descriptor.Descriptor(
+  name='TestMessageSetExtension1',
+  full_name='protobuf_unittest.TestMessageSetExtension1',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='i', full_name='protobuf_unittest.TestMessageSetExtension1.i', index=0,
+      number=15, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+    _descriptor.FieldDescriptor(
+      name='message_set_extension', full_name='protobuf_unittest.TestMessageSetExtension1.message_set_extension', index=0,
+      number=1545008, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=200,
+  serialized_end=359,
+)
+
+
+_TESTMESSAGESETEXTENSION2 = _descriptor.Descriptor(
+  name='TestMessageSetExtension2',
+  full_name='protobuf_unittest.TestMessageSetExtension2',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='str', full_name='protobuf_unittest.TestMessageSetExtension2.str', index=0,
+      number=25, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+    _descriptor.FieldDescriptor(
+      name='message_set_extension', full_name='protobuf_unittest.TestMessageSetExtension2.message_set_extension', index=0,
+      number=1547769, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=362,
+  serialized_end=523,
+)
+
+
+_RAWMESSAGESET_ITEM = _descriptor.Descriptor(
+  name='Item',
+  full_name='protobuf_unittest.RawMessageSet.Item',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='type_id', full_name='protobuf_unittest.RawMessageSet.Item.type_id', index=0,
+      number=2, type=5, cpp_type=1, label=2,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='message', full_name='protobuf_unittest.RawMessageSet.Item.message', index=1,
+      number=3, type=12, cpp_type=9, label=2,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=595,
+  serialized_end=635,
+)
+
+_RAWMESSAGESET = _descriptor.Descriptor(
+  name='RawMessageSet',
+  full_name='protobuf_unittest.RawMessageSet',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='item', full_name='protobuf_unittest.RawMessageSet.item', index=0,
+      number=1, type=10, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_RAWMESSAGESET_ITEM, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=525,
+  serialized_end=635,
+)
+
+_TESTMESSAGESETCONTAINER.fields_by_name['message_set'].message_type = google_dot_protobuf_dot_unittest__mset__wire__format__pb2._TESTMESSAGESET
+_RAWMESSAGESET_ITEM.containing_type = _RAWMESSAGESET
+_RAWMESSAGESET.fields_by_name['item'].message_type = _RAWMESSAGESET_ITEM
+DESCRIPTOR.message_types_by_name['TestMessageSetContainer'] = _TESTMESSAGESETCONTAINER
+DESCRIPTOR.message_types_by_name['TestMessageSetExtension1'] = _TESTMESSAGESETEXTENSION1
+DESCRIPTOR.message_types_by_name['TestMessageSetExtension2'] = _TESTMESSAGESETEXTENSION2
+DESCRIPTOR.message_types_by_name['RawMessageSet'] = _RAWMESSAGESET
+
+TestMessageSetContainer = _reflection.GeneratedProtocolMessageType('TestMessageSetContainer', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMESSAGESETCONTAINER,
+  __module__ = 'google.protobuf.unittest_mset_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMessageSetContainer)
+  ))
+_sym_db.RegisterMessage(TestMessageSetContainer)
+
+TestMessageSetExtension1 = _reflection.GeneratedProtocolMessageType('TestMessageSetExtension1', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMESSAGESETEXTENSION1,
+  __module__ = 'google.protobuf.unittest_mset_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMessageSetExtension1)
+  ))
+_sym_db.RegisterMessage(TestMessageSetExtension1)
+
+TestMessageSetExtension2 = _reflection.GeneratedProtocolMessageType('TestMessageSetExtension2', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMESSAGESETEXTENSION2,
+  __module__ = 'google.protobuf.unittest_mset_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMessageSetExtension2)
+  ))
+_sym_db.RegisterMessage(TestMessageSetExtension2)
+
+RawMessageSet = _reflection.GeneratedProtocolMessageType('RawMessageSet', (_message.Message,), dict(
+
+  Item = _reflection.GeneratedProtocolMessageType('Item', (_message.Message,), dict(
+    DESCRIPTOR = _RAWMESSAGESET_ITEM,
+    __module__ = 'google.protobuf.unittest_mset_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.RawMessageSet.Item)
+    ))
+  ,
+  DESCRIPTOR = _RAWMESSAGESET,
+  __module__ = 'google.protobuf.unittest_mset_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.RawMessageSet)
+  ))
+_sym_db.RegisterMessage(RawMessageSet)
+_sym_db.RegisterMessage(RawMessageSet.Item)
+
+_TESTMESSAGESETEXTENSION1.extensions_by_name['message_set_extension'].message_type = _TESTMESSAGESETEXTENSION1
+google_dot_protobuf_dot_unittest__mset__wire__format__pb2.TestMessageSet.RegisterExtension(_TESTMESSAGESETEXTENSION1.extensions_by_name['message_set_extension'])
+_TESTMESSAGESETEXTENSION2.extensions_by_name['message_set_extension'].message_type = _TESTMESSAGESETEXTENSION2
+google_dot_protobuf_dot_unittest__mset__wire__format__pb2.TestMessageSet.RegisterExtension(_TESTMESSAGESETEXTENSION2.extensions_by_name['message_set_extension'])
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('H\001\370\001\001'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/unittest_mset_wire_format_pb2.py b/generator/google/protobuf/unittest_mset_wire_format_pb2.py
new file mode 100644
index 0000000..acab49c
--- /dev/null
+++ b/generator/google/protobuf/unittest_mset_wire_format_pb2.py
@@ -0,0 +1,106 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/unittest_mset_wire_format.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/unittest_mset_wire_format.proto',
+  package='proto2_wireformat_unittest',
+  syntax='proto2',
+  serialized_pb=_b('\n/google/protobuf/unittest_mset_wire_format.proto\x12\x1aproto2_wireformat_unittest\"\x1e\n\x0eTestMessageSet*\x08\x08\x04\x10\xff\xff\xff\xff\x07:\x02\x08\x01\"d\n!TestMessageSetWireFormatContainer\x12?\n\x0bmessage_set\x18\x01 \x01(\x0b\x32*.proto2_wireformat_unittest.TestMessageSetB)H\x01\xf8\x01\x01\xaa\x02!Google.ProtocolBuffers.TestProtos')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_TESTMESSAGESET = _descriptor.Descriptor(
+  name='TestMessageSet',
+  full_name='proto2_wireformat_unittest.TestMessageSet',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\010\001')),
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(4, 2147483647), ],
+  oneofs=[
+  ],
+  serialized_start=79,
+  serialized_end=109,
+)
+
+
+_TESTMESSAGESETWIREFORMATCONTAINER = _descriptor.Descriptor(
+  name='TestMessageSetWireFormatContainer',
+  full_name='proto2_wireformat_unittest.TestMessageSetWireFormatContainer',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='message_set', full_name='proto2_wireformat_unittest.TestMessageSetWireFormatContainer.message_set', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=111,
+  serialized_end=211,
+)
+
+_TESTMESSAGESETWIREFORMATCONTAINER.fields_by_name['message_set'].message_type = _TESTMESSAGESET
+DESCRIPTOR.message_types_by_name['TestMessageSet'] = _TESTMESSAGESET
+DESCRIPTOR.message_types_by_name['TestMessageSetWireFormatContainer'] = _TESTMESSAGESETWIREFORMATCONTAINER
+
+TestMessageSet = _reflection.GeneratedProtocolMessageType('TestMessageSet', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMESSAGESET,
+  __module__ = 'google.protobuf.unittest_mset_wire_format_pb2'
+  # @@protoc_insertion_point(class_scope:proto2_wireformat_unittest.TestMessageSet)
+  ))
+_sym_db.RegisterMessage(TestMessageSet)
+
+TestMessageSetWireFormatContainer = _reflection.GeneratedProtocolMessageType('TestMessageSetWireFormatContainer', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMESSAGESETWIREFORMATCONTAINER,
+  __module__ = 'google.protobuf.unittest_mset_wire_format_pb2'
+  # @@protoc_insertion_point(class_scope:proto2_wireformat_unittest.TestMessageSetWireFormatContainer)
+  ))
+_sym_db.RegisterMessage(TestMessageSetWireFormatContainer)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('H\001\370\001\001\252\002!Google.ProtocolBuffers.TestProtos'))
+_TESTMESSAGESET.has_options = True
+_TESTMESSAGESET._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\010\001'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/unittest_no_arena_import_pb2.py b/generator/google/protobuf/unittest_no_arena_import_pb2.py
new file mode 100644
index 0000000..fb3ddc7
--- /dev/null
+++ b/generator/google/protobuf/unittest_no_arena_import_pb2.py
@@ -0,0 +1,69 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/unittest_no_arena_import.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/unittest_no_arena_import.proto',
+  package='proto2_arena_unittest',
+  syntax='proto2',
+  serialized_pb=_b('\n.google/protobuf/unittest_no_arena_import.proto\x12\x15proto2_arena_unittest\"\'\n\x1aImportNoArenaNestedMessage\x12\t\n\x01\x64\x18\x01 \x01(\x05')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_IMPORTNOARENANESTEDMESSAGE = _descriptor.Descriptor(
+  name='ImportNoArenaNestedMessage',
+  full_name='proto2_arena_unittest.ImportNoArenaNestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='d', full_name='proto2_arena_unittest.ImportNoArenaNestedMessage.d', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=73,
+  serialized_end=112,
+)
+
+DESCRIPTOR.message_types_by_name['ImportNoArenaNestedMessage'] = _IMPORTNOARENANESTEDMESSAGE
+
+ImportNoArenaNestedMessage = _reflection.GeneratedProtocolMessageType('ImportNoArenaNestedMessage', (_message.Message,), dict(
+  DESCRIPTOR = _IMPORTNOARENANESTEDMESSAGE,
+  __module__ = 'google.protobuf.unittest_no_arena_import_pb2'
+  # @@protoc_insertion_point(class_scope:proto2_arena_unittest.ImportNoArenaNestedMessage)
+  ))
+_sym_db.RegisterMessage(ImportNoArenaNestedMessage)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/unittest_no_arena_pb2.py b/generator/google/protobuf/unittest_no_arena_pb2.py
new file mode 100644
index 0000000..ba6523e
--- /dev/null
+++ b/generator/google/protobuf/unittest_no_arena_pb2.py
@@ -0,0 +1,918 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/unittest_no_arena.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import unittest_import_pb2 as google_dot_protobuf_dot_unittest__import__pb2
+google_dot_protobuf_dot_unittest__import__public__pb2 = google_dot_protobuf_dot_unittest__import__pb2.google_dot_protobuf_dot_unittest__import__public__pb2
+from google.protobuf import unittest_arena_pb2 as google_dot_protobuf_dot_unittest__arena__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/unittest_no_arena.proto',
+  package='protobuf_unittest_no_arena',
+  syntax='proto2',
+  serialized_pb=_b('\n\'google/protobuf/unittest_no_arena.proto\x12\x1aprotobuf_unittest_no_arena\x1a%google/protobuf/unittest_import.proto\x1a$google/protobuf/unittest_arena.proto\"\xd0\x1a\n\x0cTestAllTypes\x12\x16\n\x0eoptional_int32\x18\x01 \x01(\x05\x12\x16\n\x0eoptional_int64\x18\x02 \x01(\x03\x12\x17\n\x0foptional_uint32\x18\x03 \x01(\r\x12\x17\n\x0foptional_uint64\x18\x04 \x01(\x04\x12\x17\n\x0foptional_sint32\x18\x05 \x01(\x11\x12\x17\n\x0foptional_sint64\x18\x06 \x01(\x12\x12\x18\n\x10optional_fixed32\x18\x07 \x01(\x07\x12\x18\n\x10optional_fixed64\x18\x08 \x01(\x06\x12\x19\n\x11optional_sfixed32\x18\t \x01(\x0f\x12\x19\n\x11optional_sfixed64\x18\n \x01(\x10\x12\x16\n\x0eoptional_float\x18\x0b \x01(\x02\x12\x17\n\x0foptional_double\x18\x0c \x01(\x01\x12\x15\n\roptional_bool\x18\r \x01(\x08\x12\x17\n\x0foptional_string\x18\x0e \x01(\t\x12\x16\n\x0eoptional_bytes\x18\x0f \x01(\x0c\x12M\n\roptionalgroup\x18\x10 \x01(\n26.protobuf_unittest_no_arena.TestAllTypes.OptionalGroup\x12W\n\x17optional_nested_message\x18\x12 \x01(\x0b\x32\x36.protobuf_unittest_no_arena.TestAllTypes.NestedMessage\x12L\n\x18optional_foreign_message\x18\x13 \x01(\x0b\x32*.protobuf_unittest_no_arena.ForeignMessage\x12H\n\x17optional_import_message\x18\x14 \x01(\x0b\x32\'.protobuf_unittest_import.ImportMessage\x12Q\n\x14optional_nested_enum\x18\x15 \x01(\x0e\x32\x33.protobuf_unittest_no_arena.TestAllTypes.NestedEnum\x12\x46\n\x15optional_foreign_enum\x18\x16 \x01(\x0e\x32\'.protobuf_unittest_no_arena.ForeignEnum\x12\x42\n\x14optional_import_enum\x18\x17 \x01(\x0e\x32$.protobuf_unittest_import.ImportEnum\x12!\n\x15optional_string_piece\x18\x18 \x01(\tB\x02\x08\x02\x12\x19\n\roptional_cord\x18\x19 \x01(\tB\x02\x08\x01\x12U\n\x1eoptional_public_import_message\x18\x1a \x01(\x0b\x32-.protobuf_unittest_import.PublicImportMessage\x12T\n\x10optional_message\x18\x1b \x01(\x0b\x32\x36.protobuf_unittest_no_arena.TestAllTypes.NestedMessageB\x02(\x01\x12\x16\n\x0erepeated_int32\x18\x1f \x03(\x05\x12\x16\n\x0erepeated_int64\x18  \x03(\x03\x12\x17\n\x0frepeated_uint32\x18! \x03(\r\x12\x17\n\x0frepeated_uint64\x18\" \x03(\x04\x12\x17\n\x0frepeated_sint32\x18# \x03(\x11\x12\x17\n\x0frepeated_sint64\x18$ \x03(\x12\x12\x18\n\x10repeated_fixed32\x18% \x03(\x07\x12\x18\n\x10repeated_fixed64\x18& \x03(\x06\x12\x19\n\x11repeated_sfixed32\x18\' \x03(\x0f\x12\x19\n\x11repeated_sfixed64\x18( \x03(\x10\x12\x16\n\x0erepeated_float\x18) \x03(\x02\x12\x17\n\x0frepeated_double\x18* \x03(\x01\x12\x15\n\rrepeated_bool\x18+ \x03(\x08\x12\x17\n\x0frepeated_string\x18, \x03(\t\x12\x16\n\x0erepeated_bytes\x18- \x03(\x0c\x12M\n\rrepeatedgroup\x18. \x03(\n26.protobuf_unittest_no_arena.TestAllTypes.RepeatedGroup\x12W\n\x17repeated_nested_message\x18\x30 \x03(\x0b\x32\x36.protobuf_unittest_no_arena.TestAllTypes.NestedMessage\x12L\n\x18repeated_foreign_message\x18\x31 \x03(\x0b\x32*.protobuf_unittest_no_arena.ForeignMessage\x12H\n\x17repeated_import_message\x18\x32 \x03(\x0b\x32\'.protobuf_unittest_import.ImportMessage\x12Q\n\x14repeated_nested_enum\x18\x33 \x03(\x0e\x32\x33.protobuf_unittest_no_arena.TestAllTypes.NestedEnum\x12\x46\n\x15repeated_foreign_enum\x18\x34 \x03(\x0e\x32\'.protobuf_unittest_no_arena.ForeignEnum\x12\x42\n\x14repeated_import_enum\x18\x35 \x03(\x0e\x32$.protobuf_unittest_import.ImportEnum\x12!\n\x15repeated_string_piece\x18\x36 \x03(\tB\x02\x08\x02\x12\x19\n\rrepeated_cord\x18\x37 \x03(\tB\x02\x08\x01\x12Y\n\x15repeated_lazy_message\x18\x39 \x03(\x0b\x32\x36.protobuf_unittest_no_arena.TestAllTypes.NestedMessageB\x02(\x01\x12\x19\n\rdefault_int32\x18= \x01(\x05:\x02\x34\x31\x12\x19\n\rdefault_int64\x18> \x01(\x03:\x02\x34\x32\x12\x1a\n\x0e\x64\x65\x66\x61ult_uint32\x18? \x01(\r:\x02\x34\x33\x12\x1a\n\x0e\x64\x65\x66\x61ult_uint64\x18@ \x01(\x04:\x02\x34\x34\x12\x1b\n\x0e\x64\x65\x66\x61ult_sint32\x18\x41 \x01(\x11:\x03-45\x12\x1a\n\x0e\x64\x65\x66\x61ult_sint64\x18\x42 \x01(\x12:\x02\x34\x36\x12\x1b\n\x0f\x64\x65\x66\x61ult_fixed32\x18\x43 \x01(\x07:\x02\x34\x37\x12\x1b\n\x0f\x64\x65\x66\x61ult_fixed64\x18\x44 \x01(\x06:\x02\x34\x38\x12\x1c\n\x10\x64\x65\x66\x61ult_sfixed32\x18\x45 \x01(\x0f:\x02\x34\x39\x12\x1d\n\x10\x64\x65\x66\x61ult_sfixed64\x18\x46 \x01(\x10:\x03-50\x12\x1b\n\rdefault_float\x18G \x01(\x02:\x04\x35\x31.5\x12\x1d\n\x0e\x64\x65\x66\x61ult_double\x18H \x01(\x01:\x05\x35\x32\x30\x30\x30\x12\x1a\n\x0c\x64\x65\x66\x61ult_bool\x18I \x01(\x08:\x04true\x12\x1d\n\x0e\x64\x65\x66\x61ult_string\x18J \x01(\t:\x05hello\x12\x1c\n\rdefault_bytes\x18K \x01(\x0c:\x05world\x12U\n\x13\x64\x65\x66\x61ult_nested_enum\x18Q \x01(\x0e\x32\x33.protobuf_unittest_no_arena.TestAllTypes.NestedEnum:\x03\x42\x41R\x12R\n\x14\x64\x65\x66\x61ult_foreign_enum\x18R \x01(\x0e\x32\'.protobuf_unittest_no_arena.ForeignEnum:\x0b\x46OREIGN_BAR\x12M\n\x13\x64\x65\x66\x61ult_import_enum\x18S \x01(\x0e\x32$.protobuf_unittest_import.ImportEnum:\nIMPORT_BAR\x12%\n\x14\x64\x65\x66\x61ult_string_piece\x18T \x01(\t:\x03\x61\x62\x63\x42\x02\x08\x02\x12\x1d\n\x0c\x64\x65\x66\x61ult_cord\x18U \x01(\t:\x03\x31\x32\x33\x42\x02\x08\x01\x12\x16\n\x0coneof_uint32\x18o \x01(\rH\x00\x12V\n\x14oneof_nested_message\x18p \x01(\x0b\x32\x36.protobuf_unittest_no_arena.TestAllTypes.NestedMessageH\x00\x12\x16\n\x0coneof_string\x18q \x01(\tH\x00\x12\x15\n\x0boneof_bytes\x18r \x01(\x0cH\x00\x12_\n\x19lazy_oneof_nested_message\x18s \x01(\x0b\x32\x36.protobuf_unittest_no_arena.TestAllTypes.NestedMessageB\x02(\x01H\x00\x1a\x1b\n\rNestedMessage\x12\n\n\x02\x62\x62\x18\x01 \x01(\x05\x1a\x1a\n\rOptionalGroup\x12\t\n\x01\x61\x18\x11 \x01(\x05\x1a\x1a\n\rRepeatedGroup\x12\t\n\x01\x61\x18/ \x01(\x05\"9\n\nNestedEnum\x12\x07\n\x03\x46OO\x10\x01\x12\x07\n\x03\x42\x41R\x10\x02\x12\x07\n\x03\x42\x41Z\x10\x03\x12\x10\n\x03NEG\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x42\r\n\x0boneof_field\"\x1b\n\x0e\x46oreignMessage\x12\t\n\x01\x63\x18\x01 \x01(\x05\"P\n\x12TestNoArenaMessage\x12:\n\rarena_message\x18\x01 \x01(\x0b\x32#.proto2_arena_unittest.ArenaMessage*@\n\x0b\x46oreignEnum\x12\x0f\n\x0b\x46OREIGN_FOO\x10\x04\x12\x0f\n\x0b\x46OREIGN_BAR\x10\x05\x12\x0f\n\x0b\x46OREIGN_BAZ\x10\x06\x42%B\rUnittestProtoH\x01\x80\x01\x01\x88\x01\x01\x90\x01\x01\xf8\x01\x00\xa2\x02\x05NOARN')
+  ,
+  dependencies=[google_dot_protobuf_dot_unittest__import__pb2.DESCRIPTOR,google_dot_protobuf_dot_unittest__arena__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+_FOREIGNENUM = _descriptor.EnumDescriptor(
+  name='ForeignEnum',
+  full_name='protobuf_unittest_no_arena.ForeignEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='FOREIGN_FOO', index=0, number=4,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FOREIGN_BAR', index=1, number=5,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FOREIGN_BAZ', index=2, number=6,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=3670,
+  serialized_end=3734,
+)
+_sym_db.RegisterEnumDescriptor(_FOREIGNENUM)
+
+ForeignEnum = enum_type_wrapper.EnumTypeWrapper(_FOREIGNENUM)
+FOREIGN_FOO = 4
+FOREIGN_BAR = 5
+FOREIGN_BAZ = 6
+
+
+_TESTALLTYPES_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='protobuf_unittest_no_arena.TestAllTypes.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='FOO', index=0, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAR', index=1, number=2,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAZ', index=2, number=3,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='NEG', index=3, number=-1,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=3485,
+  serialized_end=3542,
+)
+_sym_db.RegisterEnumDescriptor(_TESTALLTYPES_NESTEDENUM)
+
+
+_TESTALLTYPES_NESTEDMESSAGE = _descriptor.Descriptor(
+  name='NestedMessage',
+  full_name='protobuf_unittest_no_arena.TestAllTypes.NestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='bb', full_name='protobuf_unittest_no_arena.TestAllTypes.NestedMessage.bb', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3400,
+  serialized_end=3427,
+)
+
+_TESTALLTYPES_OPTIONALGROUP = _descriptor.Descriptor(
+  name='OptionalGroup',
+  full_name='protobuf_unittest_no_arena.TestAllTypes.OptionalGroup',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest_no_arena.TestAllTypes.OptionalGroup.a', index=0,
+      number=17, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3429,
+  serialized_end=3455,
+)
+
+_TESTALLTYPES_REPEATEDGROUP = _descriptor.Descriptor(
+  name='RepeatedGroup',
+  full_name='protobuf_unittest_no_arena.TestAllTypes.RepeatedGroup',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest_no_arena.TestAllTypes.RepeatedGroup.a', index=0,
+      number=47, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3457,
+  serialized_end=3483,
+)
+
+_TESTALLTYPES = _descriptor.Descriptor(
+  name='TestAllTypes',
+  full_name='protobuf_unittest_no_arena.TestAllTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='optional_int32', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_int32', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_int64', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_int64', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_uint32', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_uint32', index=2,
+      number=3, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_uint64', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_uint64', index=3,
+      number=4, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_sint32', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_sint32', index=4,
+      number=5, type=17, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_sint64', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_sint64', index=5,
+      number=6, type=18, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_fixed32', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_fixed32', index=6,
+      number=7, type=7, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_fixed64', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_fixed64', index=7,
+      number=8, type=6, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_sfixed32', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_sfixed32', index=8,
+      number=9, type=15, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_sfixed64', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_sfixed64', index=9,
+      number=10, type=16, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_float', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_float', index=10,
+      number=11, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_double', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_double', index=11,
+      number=12, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_bool', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_bool', index=12,
+      number=13, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_string', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_string', index=13,
+      number=14, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_bytes', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_bytes', index=14,
+      number=15, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optionalgroup', full_name='protobuf_unittest_no_arena.TestAllTypes.optionalgroup', index=15,
+      number=16, type=10, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_nested_message', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_nested_message', index=16,
+      number=18, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_foreign_message', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_foreign_message', index=17,
+      number=19, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_import_message', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_import_message', index=18,
+      number=20, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_nested_enum', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_nested_enum', index=19,
+      number=21, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=1,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_foreign_enum', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_foreign_enum', index=20,
+      number=22, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=4,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_import_enum', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_import_enum', index=21,
+      number=23, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=7,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_string_piece', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_string_piece', index=22,
+      number=24, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))),
+    _descriptor.FieldDescriptor(
+      name='optional_cord', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_cord', index=23,
+      number=25, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))),
+    _descriptor.FieldDescriptor(
+      name='optional_public_import_message', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_public_import_message', index=24,
+      number=26, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_message', full_name='protobuf_unittest_no_arena.TestAllTypes.optional_message', index=25,
+      number=27, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_int32', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_int32', index=26,
+      number=31, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_int64', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_int64', index=27,
+      number=32, type=3, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint32', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_uint32', index=28,
+      number=33, type=13, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint64', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_uint64', index=29,
+      number=34, type=4, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sint32', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_sint32', index=30,
+      number=35, type=17, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sint64', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_sint64', index=31,
+      number=36, type=18, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed32', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_fixed32', index=32,
+      number=37, type=7, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed64', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_fixed64', index=33,
+      number=38, type=6, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sfixed32', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_sfixed32', index=34,
+      number=39, type=15, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sfixed64', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_sfixed64', index=35,
+      number=40, type=16, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_float', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_float', index=36,
+      number=41, type=2, cpp_type=6, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_double', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_double', index=37,
+      number=42, type=1, cpp_type=5, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_bool', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_bool', index=38,
+      number=43, type=8, cpp_type=7, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_string', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_string', index=39,
+      number=44, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_bytes', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_bytes', index=40,
+      number=45, type=12, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeatedgroup', full_name='protobuf_unittest_no_arena.TestAllTypes.repeatedgroup', index=41,
+      number=46, type=10, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_nested_message', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_nested_message', index=42,
+      number=48, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_foreign_message', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_foreign_message', index=43,
+      number=49, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_import_message', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_import_message', index=44,
+      number=50, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_nested_enum', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_nested_enum', index=45,
+      number=51, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_foreign_enum', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_foreign_enum', index=46,
+      number=52, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_import_enum', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_import_enum', index=47,
+      number=53, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_string_piece', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_string_piece', index=48,
+      number=54, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_cord', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_cord', index=49,
+      number=55, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_lazy_message', full_name='protobuf_unittest_no_arena.TestAllTypes.repeated_lazy_message', index=50,
+      number=57, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))),
+    _descriptor.FieldDescriptor(
+      name='default_int32', full_name='protobuf_unittest_no_arena.TestAllTypes.default_int32', index=51,
+      number=61, type=5, cpp_type=1, label=1,
+      has_default_value=True, default_value=41,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_int64', full_name='protobuf_unittest_no_arena.TestAllTypes.default_int64', index=52,
+      number=62, type=3, cpp_type=2, label=1,
+      has_default_value=True, default_value=42,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_uint32', full_name='protobuf_unittest_no_arena.TestAllTypes.default_uint32', index=53,
+      number=63, type=13, cpp_type=3, label=1,
+      has_default_value=True, default_value=43,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_uint64', full_name='protobuf_unittest_no_arena.TestAllTypes.default_uint64', index=54,
+      number=64, type=4, cpp_type=4, label=1,
+      has_default_value=True, default_value=44,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_sint32', full_name='protobuf_unittest_no_arena.TestAllTypes.default_sint32', index=55,
+      number=65, type=17, cpp_type=1, label=1,
+      has_default_value=True, default_value=-45,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_sint64', full_name='protobuf_unittest_no_arena.TestAllTypes.default_sint64', index=56,
+      number=66, type=18, cpp_type=2, label=1,
+      has_default_value=True, default_value=46,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_fixed32', full_name='protobuf_unittest_no_arena.TestAllTypes.default_fixed32', index=57,
+      number=67, type=7, cpp_type=3, label=1,
+      has_default_value=True, default_value=47,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_fixed64', full_name='protobuf_unittest_no_arena.TestAllTypes.default_fixed64', index=58,
+      number=68, type=6, cpp_type=4, label=1,
+      has_default_value=True, default_value=48,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_sfixed32', full_name='protobuf_unittest_no_arena.TestAllTypes.default_sfixed32', index=59,
+      number=69, type=15, cpp_type=1, label=1,
+      has_default_value=True, default_value=49,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_sfixed64', full_name='protobuf_unittest_no_arena.TestAllTypes.default_sfixed64', index=60,
+      number=70, type=16, cpp_type=2, label=1,
+      has_default_value=True, default_value=-50,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_float', full_name='protobuf_unittest_no_arena.TestAllTypes.default_float', index=61,
+      number=71, type=2, cpp_type=6, label=1,
+      has_default_value=True, default_value=float(51.5),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_double', full_name='protobuf_unittest_no_arena.TestAllTypes.default_double', index=62,
+      number=72, type=1, cpp_type=5, label=1,
+      has_default_value=True, default_value=float(52000),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_bool', full_name='protobuf_unittest_no_arena.TestAllTypes.default_bool', index=63,
+      number=73, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=True,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_string', full_name='protobuf_unittest_no_arena.TestAllTypes.default_string', index=64,
+      number=74, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("hello").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_bytes', full_name='protobuf_unittest_no_arena.TestAllTypes.default_bytes', index=65,
+      number=75, type=12, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("world"),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_nested_enum', full_name='protobuf_unittest_no_arena.TestAllTypes.default_nested_enum', index=66,
+      number=81, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=2,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_foreign_enum', full_name='protobuf_unittest_no_arena.TestAllTypes.default_foreign_enum', index=67,
+      number=82, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=5,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_import_enum', full_name='protobuf_unittest_no_arena.TestAllTypes.default_import_enum', index=68,
+      number=83, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=8,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_string_piece', full_name='protobuf_unittest_no_arena.TestAllTypes.default_string_piece', index=69,
+      number=84, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("abc").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))),
+    _descriptor.FieldDescriptor(
+      name='default_cord', full_name='protobuf_unittest_no_arena.TestAllTypes.default_cord', index=70,
+      number=85, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("123").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))),
+    _descriptor.FieldDescriptor(
+      name='oneof_uint32', full_name='protobuf_unittest_no_arena.TestAllTypes.oneof_uint32', index=71,
+      number=111, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_nested_message', full_name='protobuf_unittest_no_arena.TestAllTypes.oneof_nested_message', index=72,
+      number=112, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_string', full_name='protobuf_unittest_no_arena.TestAllTypes.oneof_string', index=73,
+      number=113, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_bytes', full_name='protobuf_unittest_no_arena.TestAllTypes.oneof_bytes', index=74,
+      number=114, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='lazy_oneof_nested_message', full_name='protobuf_unittest_no_arena.TestAllTypes.lazy_oneof_nested_message', index=75,
+      number=115, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTALLTYPES_NESTEDMESSAGE, _TESTALLTYPES_OPTIONALGROUP, _TESTALLTYPES_REPEATEDGROUP, ],
+  enum_types=[
+    _TESTALLTYPES_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='oneof_field', full_name='protobuf_unittest_no_arena.TestAllTypes.oneof_field',
+      index=0, containing_type=None, fields=[]),
+  ],
+  serialized_start=149,
+  serialized_end=3557,
+)
+
+
+_FOREIGNMESSAGE = _descriptor.Descriptor(
+  name='ForeignMessage',
+  full_name='protobuf_unittest_no_arena.ForeignMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='c', full_name='protobuf_unittest_no_arena.ForeignMessage.c', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3559,
+  serialized_end=3586,
+)
+
+
+_TESTNOARENAMESSAGE = _descriptor.Descriptor(
+  name='TestNoArenaMessage',
+  full_name='protobuf_unittest_no_arena.TestNoArenaMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='arena_message', full_name='protobuf_unittest_no_arena.TestNoArenaMessage.arena_message', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3588,
+  serialized_end=3668,
+)
+
+_TESTALLTYPES_NESTEDMESSAGE.containing_type = _TESTALLTYPES
+_TESTALLTYPES_OPTIONALGROUP.containing_type = _TESTALLTYPES
+_TESTALLTYPES_REPEATEDGROUP.containing_type = _TESTALLTYPES
+_TESTALLTYPES.fields_by_name['optionalgroup'].message_type = _TESTALLTYPES_OPTIONALGROUP
+_TESTALLTYPES.fields_by_name['optional_nested_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['optional_foreign_message'].message_type = _FOREIGNMESSAGE
+_TESTALLTYPES.fields_by_name['optional_import_message'].message_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTMESSAGE
+_TESTALLTYPES.fields_by_name['optional_nested_enum'].enum_type = _TESTALLTYPES_NESTEDENUM
+_TESTALLTYPES.fields_by_name['optional_foreign_enum'].enum_type = _FOREIGNENUM
+_TESTALLTYPES.fields_by_name['optional_import_enum'].enum_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTENUM
+_TESTALLTYPES.fields_by_name['optional_public_import_message'].message_type = google_dot_protobuf_dot_unittest__import__public__pb2._PUBLICIMPORTMESSAGE
+_TESTALLTYPES.fields_by_name['optional_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['repeatedgroup'].message_type = _TESTALLTYPES_REPEATEDGROUP
+_TESTALLTYPES.fields_by_name['repeated_nested_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['repeated_foreign_message'].message_type = _FOREIGNMESSAGE
+_TESTALLTYPES.fields_by_name['repeated_import_message'].message_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTMESSAGE
+_TESTALLTYPES.fields_by_name['repeated_nested_enum'].enum_type = _TESTALLTYPES_NESTEDENUM
+_TESTALLTYPES.fields_by_name['repeated_foreign_enum'].enum_type = _FOREIGNENUM
+_TESTALLTYPES.fields_by_name['repeated_import_enum'].enum_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTENUM
+_TESTALLTYPES.fields_by_name['repeated_lazy_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['default_nested_enum'].enum_type = _TESTALLTYPES_NESTEDENUM
+_TESTALLTYPES.fields_by_name['default_foreign_enum'].enum_type = _FOREIGNENUM
+_TESTALLTYPES.fields_by_name['default_import_enum'].enum_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTENUM
+_TESTALLTYPES.fields_by_name['oneof_nested_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['lazy_oneof_nested_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES_NESTEDENUM.containing_type = _TESTALLTYPES
+_TESTALLTYPES.oneofs_by_name['oneof_field'].fields.append(
+  _TESTALLTYPES.fields_by_name['oneof_uint32'])
+_TESTALLTYPES.fields_by_name['oneof_uint32'].containing_oneof = _TESTALLTYPES.oneofs_by_name['oneof_field']
+_TESTALLTYPES.oneofs_by_name['oneof_field'].fields.append(
+  _TESTALLTYPES.fields_by_name['oneof_nested_message'])
+_TESTALLTYPES.fields_by_name['oneof_nested_message'].containing_oneof = _TESTALLTYPES.oneofs_by_name['oneof_field']
+_TESTALLTYPES.oneofs_by_name['oneof_field'].fields.append(
+  _TESTALLTYPES.fields_by_name['oneof_string'])
+_TESTALLTYPES.fields_by_name['oneof_string'].containing_oneof = _TESTALLTYPES.oneofs_by_name['oneof_field']
+_TESTALLTYPES.oneofs_by_name['oneof_field'].fields.append(
+  _TESTALLTYPES.fields_by_name['oneof_bytes'])
+_TESTALLTYPES.fields_by_name['oneof_bytes'].containing_oneof = _TESTALLTYPES.oneofs_by_name['oneof_field']
+_TESTALLTYPES.oneofs_by_name['oneof_field'].fields.append(
+  _TESTALLTYPES.fields_by_name['lazy_oneof_nested_message'])
+_TESTALLTYPES.fields_by_name['lazy_oneof_nested_message'].containing_oneof = _TESTALLTYPES.oneofs_by_name['oneof_field']
+_TESTNOARENAMESSAGE.fields_by_name['arena_message'].message_type = google_dot_protobuf_dot_unittest__arena__pb2._ARENAMESSAGE
+DESCRIPTOR.message_types_by_name['TestAllTypes'] = _TESTALLTYPES
+DESCRIPTOR.message_types_by_name['ForeignMessage'] = _FOREIGNMESSAGE
+DESCRIPTOR.message_types_by_name['TestNoArenaMessage'] = _TESTNOARENAMESSAGE
+DESCRIPTOR.enum_types_by_name['ForeignEnum'] = _FOREIGNENUM
+
+TestAllTypes = _reflection.GeneratedProtocolMessageType('TestAllTypes', (_message.Message,), dict(
+
+  NestedMessage = _reflection.GeneratedProtocolMessageType('NestedMessage', (_message.Message,), dict(
+    DESCRIPTOR = _TESTALLTYPES_NESTEDMESSAGE,
+    __module__ = 'google.protobuf.unittest_no_arena_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest_no_arena.TestAllTypes.NestedMessage)
+    ))
+  ,
+
+  OptionalGroup = _reflection.GeneratedProtocolMessageType('OptionalGroup', (_message.Message,), dict(
+    DESCRIPTOR = _TESTALLTYPES_OPTIONALGROUP,
+    __module__ = 'google.protobuf.unittest_no_arena_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest_no_arena.TestAllTypes.OptionalGroup)
+    ))
+  ,
+
+  RepeatedGroup = _reflection.GeneratedProtocolMessageType('RepeatedGroup', (_message.Message,), dict(
+    DESCRIPTOR = _TESTALLTYPES_REPEATEDGROUP,
+    __module__ = 'google.protobuf.unittest_no_arena_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest_no_arena.TestAllTypes.RepeatedGroup)
+    ))
+  ,
+  DESCRIPTOR = _TESTALLTYPES,
+  __module__ = 'google.protobuf.unittest_no_arena_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest_no_arena.TestAllTypes)
+  ))
+_sym_db.RegisterMessage(TestAllTypes)
+_sym_db.RegisterMessage(TestAllTypes.NestedMessage)
+_sym_db.RegisterMessage(TestAllTypes.OptionalGroup)
+_sym_db.RegisterMessage(TestAllTypes.RepeatedGroup)
+
+ForeignMessage = _reflection.GeneratedProtocolMessageType('ForeignMessage', (_message.Message,), dict(
+  DESCRIPTOR = _FOREIGNMESSAGE,
+  __module__ = 'google.protobuf.unittest_no_arena_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest_no_arena.ForeignMessage)
+  ))
+_sym_db.RegisterMessage(ForeignMessage)
+
+TestNoArenaMessage = _reflection.GeneratedProtocolMessageType('TestNoArenaMessage', (_message.Message,), dict(
+  DESCRIPTOR = _TESTNOARENAMESSAGE,
+  __module__ = 'google.protobuf.unittest_no_arena_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest_no_arena.TestNoArenaMessage)
+  ))
+_sym_db.RegisterMessage(TestNoArenaMessage)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('B\rUnittestProtoH\001\200\001\001\210\001\001\220\001\001\370\001\000\242\002\005NOARN'))
+_TESTALLTYPES.fields_by_name['optional_string_piece'].has_options = True
+_TESTALLTYPES.fields_by_name['optional_string_piece']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+_TESTALLTYPES.fields_by_name['optional_cord'].has_options = True
+_TESTALLTYPES.fields_by_name['optional_cord']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+_TESTALLTYPES.fields_by_name['optional_message'].has_options = True
+_TESTALLTYPES.fields_by_name['optional_message']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))
+_TESTALLTYPES.fields_by_name['repeated_string_piece'].has_options = True
+_TESTALLTYPES.fields_by_name['repeated_string_piece']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+_TESTALLTYPES.fields_by_name['repeated_cord'].has_options = True
+_TESTALLTYPES.fields_by_name['repeated_cord']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+_TESTALLTYPES.fields_by_name['repeated_lazy_message'].has_options = True
+_TESTALLTYPES.fields_by_name['repeated_lazy_message']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))
+_TESTALLTYPES.fields_by_name['default_string_piece'].has_options = True
+_TESTALLTYPES.fields_by_name['default_string_piece']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+_TESTALLTYPES.fields_by_name['default_cord'].has_options = True
+_TESTALLTYPES.fields_by_name['default_cord']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+_TESTALLTYPES.fields_by_name['lazy_oneof_nested_message'].has_options = True
+_TESTALLTYPES.fields_by_name['lazy_oneof_nested_message']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/unittest_no_generic_services_pb2.py b/generator/google/protobuf/unittest_no_generic_services_pb2.py
new file mode 100644
index 0000000..d40ba3b
--- /dev/null
+++ b/generator/google/protobuf/unittest_no_generic_services_pb2.py
@@ -0,0 +1,101 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/unittest_no_generic_services.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/unittest_no_generic_services.proto',
+  package='google.protobuf.no_generic_services_test',
+  syntax='proto2',
+  serialized_pb=_b('\n2google/protobuf/unittest_no_generic_services.proto\x12(google.protobuf.no_generic_services_test\"#\n\x0bTestMessage\x12\t\n\x01\x61\x18\x01 \x01(\x05*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02*\x13\n\x08TestEnum\x12\x07\n\x03\x46OO\x10\x01\x32\x82\x01\n\x0bTestService\x12s\n\x03\x46oo\x12\x35.google.protobuf.no_generic_services_test.TestMessage\x1a\x35.google.protobuf.no_generic_services_test.TestMessage:N\n\x0etest_extension\x12\x35.google.protobuf.no_generic_services_test.TestMessage\x18\xe8\x07 \x01(\x05')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+_TESTENUM = _descriptor.EnumDescriptor(
+  name='TestEnum',
+  full_name='google.protobuf.no_generic_services_test.TestEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='FOO', index=0, number=1,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=133,
+  serialized_end=152,
+)
+_sym_db.RegisterEnumDescriptor(_TESTENUM)
+
+TestEnum = enum_type_wrapper.EnumTypeWrapper(_TESTENUM)
+FOO = 1
+
+TEST_EXTENSION_FIELD_NUMBER = 1000
+test_extension = _descriptor.FieldDescriptor(
+  name='test_extension', full_name='google.protobuf.no_generic_services_test.test_extension', index=0,
+  number=1000, type=5, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+
+
+_TESTMESSAGE = _descriptor.Descriptor(
+  name='TestMessage',
+  full_name='google.protobuf.no_generic_services_test.TestMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='google.protobuf.no_generic_services_test.TestMessage.a', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(1000, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=96,
+  serialized_end=131,
+)
+
+DESCRIPTOR.message_types_by_name['TestMessage'] = _TESTMESSAGE
+DESCRIPTOR.enum_types_by_name['TestEnum'] = _TESTENUM
+DESCRIPTOR.extensions_by_name['test_extension'] = test_extension
+
+TestMessage = _reflection.GeneratedProtocolMessageType('TestMessage', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMESSAGE,
+  __module__ = 'google.protobuf.unittest_no_generic_services_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.no_generic_services_test.TestMessage)
+  ))
+_sym_db.RegisterMessage(TestMessage)
+
+TestMessage.RegisterExtension(test_extension)
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/unittest_pb2.py b/generator/google/protobuf/unittest_pb2.py
new file mode 100644
index 0000000..d82d56f
--- /dev/null
+++ b/generator/google/protobuf/unittest_pb2.py
@@ -0,0 +1,6099 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/unittest.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import service as _service
+from google.protobuf import service_reflection
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import unittest_import_pb2 as google_dot_protobuf_dot_unittest__import__pb2
+google_dot_protobuf_dot_unittest__import__public__pb2 = google_dot_protobuf_dot_unittest__import__pb2.google_dot_protobuf_dot_unittest__import__public__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/unittest.proto',
+  package='protobuf_unittest',
+  syntax='proto2',
+  serialized_pb=_b('\n\x1egoogle/protobuf/unittest.proto\x12\x11protobuf_unittest\x1a%google/protobuf/unittest_import.proto\"\xed\x18\n\x0cTestAllTypes\x12\x16\n\x0eoptional_int32\x18\x01 \x01(\x05\x12\x16\n\x0eoptional_int64\x18\x02 \x01(\x03\x12\x17\n\x0foptional_uint32\x18\x03 \x01(\r\x12\x17\n\x0foptional_uint64\x18\x04 \x01(\x04\x12\x17\n\x0foptional_sint32\x18\x05 \x01(\x11\x12\x17\n\x0foptional_sint64\x18\x06 \x01(\x12\x12\x18\n\x10optional_fixed32\x18\x07 \x01(\x07\x12\x18\n\x10optional_fixed64\x18\x08 \x01(\x06\x12\x19\n\x11optional_sfixed32\x18\t \x01(\x0f\x12\x19\n\x11optional_sfixed64\x18\n \x01(\x10\x12\x16\n\x0eoptional_float\x18\x0b \x01(\x02\x12\x17\n\x0foptional_double\x18\x0c \x01(\x01\x12\x15\n\roptional_bool\x18\r \x01(\x08\x12\x17\n\x0foptional_string\x18\x0e \x01(\t\x12\x16\n\x0eoptional_bytes\x18\x0f \x01(\x0c\x12\x44\n\roptionalgroup\x18\x10 \x01(\n2-.protobuf_unittest.TestAllTypes.OptionalGroup\x12N\n\x17optional_nested_message\x18\x12 \x01(\x0b\x32-.protobuf_unittest.TestAllTypes.NestedMessage\x12\x43\n\x18optional_foreign_message\x18\x13 \x01(\x0b\x32!.protobuf_unittest.ForeignMessage\x12H\n\x17optional_import_message\x18\x14 \x01(\x0b\x32\'.protobuf_unittest_import.ImportMessage\x12H\n\x14optional_nested_enum\x18\x15 \x01(\x0e\x32*.protobuf_unittest.TestAllTypes.NestedEnum\x12=\n\x15optional_foreign_enum\x18\x16 \x01(\x0e\x32\x1e.protobuf_unittest.ForeignEnum\x12\x42\n\x14optional_import_enum\x18\x17 \x01(\x0e\x32$.protobuf_unittest_import.ImportEnum\x12!\n\x15optional_string_piece\x18\x18 \x01(\tB\x02\x08\x02\x12\x19\n\roptional_cord\x18\x19 \x01(\tB\x02\x08\x01\x12U\n\x1eoptional_public_import_message\x18\x1a \x01(\x0b\x32-.protobuf_unittest_import.PublicImportMessage\x12P\n\x15optional_lazy_message\x18\x1b \x01(\x0b\x32-.protobuf_unittest.TestAllTypes.NestedMessageB\x02(\x01\x12\x16\n\x0erepeated_int32\x18\x1f \x03(\x05\x12\x16\n\x0erepeated_int64\x18  \x03(\x03\x12\x17\n\x0frepeated_uint32\x18! \x03(\r\x12\x17\n\x0frepeated_uint64\x18\" \x03(\x04\x12\x17\n\x0frepeated_sint32\x18# \x03(\x11\x12\x17\n\x0frepeated_sint64\x18$ \x03(\x12\x12\x18\n\x10repeated_fixed32\x18% \x03(\x07\x12\x18\n\x10repeated_fixed64\x18& \x03(\x06\x12\x19\n\x11repeated_sfixed32\x18\' \x03(\x0f\x12\x19\n\x11repeated_sfixed64\x18( \x03(\x10\x12\x16\n\x0erepeated_float\x18) \x03(\x02\x12\x17\n\x0frepeated_double\x18* \x03(\x01\x12\x15\n\rrepeated_bool\x18+ \x03(\x08\x12\x17\n\x0frepeated_string\x18, \x03(\t\x12\x16\n\x0erepeated_bytes\x18- \x03(\x0c\x12\x44\n\rrepeatedgroup\x18. \x03(\n2-.protobuf_unittest.TestAllTypes.RepeatedGroup\x12N\n\x17repeated_nested_message\x18\x30 \x03(\x0b\x32-.protobuf_unittest.TestAllTypes.NestedMessage\x12\x43\n\x18repeated_foreign_message\x18\x31 \x03(\x0b\x32!.protobuf_unittest.ForeignMessage\x12H\n\x17repeated_import_message\x18\x32 \x03(\x0b\x32\'.protobuf_unittest_import.ImportMessage\x12H\n\x14repeated_nested_enum\x18\x33 \x03(\x0e\x32*.protobuf_unittest.TestAllTypes.NestedEnum\x12=\n\x15repeated_foreign_enum\x18\x34 \x03(\x0e\x32\x1e.protobuf_unittest.ForeignEnum\x12\x42\n\x14repeated_import_enum\x18\x35 \x03(\x0e\x32$.protobuf_unittest_import.ImportEnum\x12!\n\x15repeated_string_piece\x18\x36 \x03(\tB\x02\x08\x02\x12\x19\n\rrepeated_cord\x18\x37 \x03(\tB\x02\x08\x01\x12P\n\x15repeated_lazy_message\x18\x39 \x03(\x0b\x32-.protobuf_unittest.TestAllTypes.NestedMessageB\x02(\x01\x12\x19\n\rdefault_int32\x18= \x01(\x05:\x02\x34\x31\x12\x19\n\rdefault_int64\x18> \x01(\x03:\x02\x34\x32\x12\x1a\n\x0e\x64\x65\x66\x61ult_uint32\x18? \x01(\r:\x02\x34\x33\x12\x1a\n\x0e\x64\x65\x66\x61ult_uint64\x18@ \x01(\x04:\x02\x34\x34\x12\x1b\n\x0e\x64\x65\x66\x61ult_sint32\x18\x41 \x01(\x11:\x03-45\x12\x1a\n\x0e\x64\x65\x66\x61ult_sint64\x18\x42 \x01(\x12:\x02\x34\x36\x12\x1b\n\x0f\x64\x65\x66\x61ult_fixed32\x18\x43 \x01(\x07:\x02\x34\x37\x12\x1b\n\x0f\x64\x65\x66\x61ult_fixed64\x18\x44 \x01(\x06:\x02\x34\x38\x12\x1c\n\x10\x64\x65\x66\x61ult_sfixed32\x18\x45 \x01(\x0f:\x02\x34\x39\x12\x1d\n\x10\x64\x65\x66\x61ult_sfixed64\x18\x46 \x01(\x10:\x03-50\x12\x1b\n\rdefault_float\x18G \x01(\x02:\x04\x35\x31.5\x12\x1d\n\x0e\x64\x65\x66\x61ult_double\x18H \x01(\x01:\x05\x35\x32\x30\x30\x30\x12\x1a\n\x0c\x64\x65\x66\x61ult_bool\x18I \x01(\x08:\x04true\x12\x1d\n\x0e\x64\x65\x66\x61ult_string\x18J \x01(\t:\x05hello\x12\x1c\n\rdefault_bytes\x18K \x01(\x0c:\x05world\x12L\n\x13\x64\x65\x66\x61ult_nested_enum\x18Q \x01(\x0e\x32*.protobuf_unittest.TestAllTypes.NestedEnum:\x03\x42\x41R\x12I\n\x14\x64\x65\x66\x61ult_foreign_enum\x18R \x01(\x0e\x32\x1e.protobuf_unittest.ForeignEnum:\x0b\x46OREIGN_BAR\x12M\n\x13\x64\x65\x66\x61ult_import_enum\x18S \x01(\x0e\x32$.protobuf_unittest_import.ImportEnum:\nIMPORT_BAR\x12%\n\x14\x64\x65\x66\x61ult_string_piece\x18T \x01(\t:\x03\x61\x62\x63\x42\x02\x08\x02\x12\x1d\n\x0c\x64\x65\x66\x61ult_cord\x18U \x01(\t:\x03\x31\x32\x33\x42\x02\x08\x01\x12\x16\n\x0coneof_uint32\x18o \x01(\rH\x00\x12M\n\x14oneof_nested_message\x18p \x01(\x0b\x32-.protobuf_unittest.TestAllTypes.NestedMessageH\x00\x12\x16\n\x0coneof_string\x18q \x01(\tH\x00\x12\x15\n\x0boneof_bytes\x18r \x01(\x0cH\x00\x1a\x1b\n\rNestedMessage\x12\n\n\x02\x62\x62\x18\x01 \x01(\x05\x1a\x1a\n\rOptionalGroup\x12\t\n\x01\x61\x18\x11 \x01(\x05\x1a\x1a\n\rRepeatedGroup\x12\t\n\x01\x61\x18/ \x01(\x05\"9\n\nNestedEnum\x12\x07\n\x03\x46OO\x10\x01\x12\x07\n\x03\x42\x41R\x10\x02\x12\x07\n\x03\x42\x41Z\x10\x03\x12\x10\n\x03NEG\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x42\r\n\x0boneof_field\"\xbb\x01\n\x12NestedTestAllTypes\x12\x34\n\x05\x63hild\x18\x01 \x01(\x0b\x32%.protobuf_unittest.NestedTestAllTypes\x12\x30\n\x07payload\x18\x02 \x01(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\x12=\n\x0erepeated_child\x18\x03 \x03(\x0b\x32%.protobuf_unittest.NestedTestAllTypes\"4\n\x14TestDeprecatedFields\x12\x1c\n\x10\x64\x65precated_int32\x18\x01 \x01(\x05\x42\x02\x18\x01\"&\n\x0e\x46oreignMessage\x12\t\n\x01\x63\x18\x01 \x01(\x05\x12\t\n\x01\x64\x18\x02 \x01(\x05\"0\n\x12TestReservedFieldsJ\x04\x08\x02\x10\x03J\x04\x08\x0f\x10\x10J\x04\x08\t\x10\x0cR\x03\x62\x61rR\x03\x62\x61z\"\x1d\n\x11TestAllExtensions*\x08\x08\x01\x10\x80\x80\x80\x80\x02\"$\n\x17OptionalGroup_extension\x12\t\n\x01\x61\x18\x11 \x01(\x05\"$\n\x17RepeatedGroup_extension\x12\t\n\x01\x61\x18/ \x01(\x05\"\x98\x01\n\x13TestNestedExtension29\n\x04test\x12$.protobuf_unittest.TestAllExtensions\x18\xea\x07 \x01(\t:\x04test2F\n\x17nested_string_extension\x12$.protobuf_unittest.TestAllExtensions\x18\xeb\x07 \x01(\t\"\xd5\x05\n\x0cTestRequired\x12\t\n\x01\x61\x18\x01 \x02(\x05\x12\x0e\n\x06\x64ummy2\x18\x02 \x01(\x05\x12\t\n\x01\x62\x18\x03 \x02(\x05\x12\x0e\n\x06\x64ummy4\x18\x04 \x01(\x05\x12\x0e\n\x06\x64ummy5\x18\x05 \x01(\x05\x12\x0e\n\x06\x64ummy6\x18\x06 \x01(\x05\x12\x0e\n\x06\x64ummy7\x18\x07 \x01(\x05\x12\x0e\n\x06\x64ummy8\x18\x08 \x01(\x05\x12\x0e\n\x06\x64ummy9\x18\t \x01(\x05\x12\x0f\n\x07\x64ummy10\x18\n \x01(\x05\x12\x0f\n\x07\x64ummy11\x18\x0b \x01(\x05\x12\x0f\n\x07\x64ummy12\x18\x0c \x01(\x05\x12\x0f\n\x07\x64ummy13\x18\r \x01(\x05\x12\x0f\n\x07\x64ummy14\x18\x0e \x01(\x05\x12\x0f\n\x07\x64ummy15\x18\x0f \x01(\x05\x12\x0f\n\x07\x64ummy16\x18\x10 \x01(\x05\x12\x0f\n\x07\x64ummy17\x18\x11 \x01(\x05\x12\x0f\n\x07\x64ummy18\x18\x12 \x01(\x05\x12\x0f\n\x07\x64ummy19\x18\x13 \x01(\x05\x12\x0f\n\x07\x64ummy20\x18\x14 \x01(\x05\x12\x0f\n\x07\x64ummy21\x18\x15 \x01(\x05\x12\x0f\n\x07\x64ummy22\x18\x16 \x01(\x05\x12\x0f\n\x07\x64ummy23\x18\x17 \x01(\x05\x12\x0f\n\x07\x64ummy24\x18\x18 \x01(\x05\x12\x0f\n\x07\x64ummy25\x18\x19 \x01(\x05\x12\x0f\n\x07\x64ummy26\x18\x1a \x01(\x05\x12\x0f\n\x07\x64ummy27\x18\x1b \x01(\x05\x12\x0f\n\x07\x64ummy28\x18\x1c \x01(\x05\x12\x0f\n\x07\x64ummy29\x18\x1d \x01(\x05\x12\x0f\n\x07\x64ummy30\x18\x1e \x01(\x05\x12\x0f\n\x07\x64ummy31\x18\x1f \x01(\x05\x12\x0f\n\x07\x64ummy32\x18  \x01(\x05\x12\t\n\x01\x63\x18! \x02(\x05\x32V\n\x06single\x12$.protobuf_unittest.TestAllExtensions\x18\xe8\x07 \x01(\x0b\x32\x1f.protobuf_unittest.TestRequired2U\n\x05multi\x12$.protobuf_unittest.TestAllExtensions\x18\xe9\x07 \x03(\x0b\x32\x1f.protobuf_unittest.TestRequired\"\x9a\x01\n\x13TestRequiredForeign\x12\x39\n\x10optional_message\x18\x01 \x01(\x0b\x32\x1f.protobuf_unittest.TestRequired\x12\x39\n\x10repeated_message\x18\x02 \x03(\x0b\x32\x1f.protobuf_unittest.TestRequired\x12\r\n\x05\x64ummy\x18\x03 \x01(\x05\"Z\n\x11TestForeignNested\x12\x45\n\x0e\x66oreign_nested\x18\x01 \x01(\x0b\x32-.protobuf_unittest.TestAllTypes.NestedMessage\"\x12\n\x10TestEmptyMessage\"*\n\x1eTestEmptyMessageWithExtensions*\x08\x08\x01\x10\x80\x80\x80\x80\x02\"7\n\x1bTestMultipleExtensionRanges*\x04\x08*\x10+*\x06\x08\xaf \x10\x94!*\n\x08\x80\x80\x04\x10\x80\x80\x80\x80\x02\"4\n\x18TestReallyLargeTagNumber\x12\t\n\x01\x61\x18\x01 \x01(\x05\x12\r\n\x02\x62\x62\x18\xff\xff\xff\x7f \x01(\x05\"U\n\x14TestRecursiveMessage\x12\x32\n\x01\x61\x18\x01 \x01(\x0b\x32\'.protobuf_unittest.TestRecursiveMessage\x12\t\n\x01i\x18\x02 \x01(\x05\"K\n\x14TestMutualRecursionA\x12\x33\n\x02\x62\x62\x18\x01 \x01(\x0b\x32\'.protobuf_unittest.TestMutualRecursionB\"b\n\x14TestMutualRecursionB\x12\x32\n\x01\x61\x18\x01 \x01(\x0b\x32\'.protobuf_unittest.TestMutualRecursionA\x12\x16\n\x0eoptional_int32\x18\x02 \x01(\x05\"\xb3\x01\n\x12TestDupFieldNumber\x12\t\n\x01\x61\x18\x01 \x01(\x05\x12\x36\n\x03\x66oo\x18\x02 \x01(\n2).protobuf_unittest.TestDupFieldNumber.Foo\x12\x36\n\x03\x62\x61r\x18\x03 \x01(\n2).protobuf_unittest.TestDupFieldNumber.Bar\x1a\x10\n\x03\x46oo\x12\t\n\x01\x61\x18\x01 \x01(\x05\x1a\x10\n\x03\x42\x61r\x12\t\n\x01\x61\x18\x01 \x01(\x05\"L\n\x10TestEagerMessage\x12\x38\n\x0bsub_message\x18\x01 \x01(\x0b\x32\x1f.protobuf_unittest.TestAllTypesB\x02(\x00\"K\n\x0fTestLazyMessage\x12\x38\n\x0bsub_message\x18\x01 \x01(\x0b\x32\x1f.protobuf_unittest.TestAllTypesB\x02(\x01\"\x80\x02\n\x18TestNestedMessageHasBits\x12Z\n\x17optional_nested_message\x18\x01 \x01(\x0b\x32\x39.protobuf_unittest.TestNestedMessageHasBits.NestedMessage\x1a\x87\x01\n\rNestedMessage\x12$\n\x1cnestedmessage_repeated_int32\x18\x01 \x03(\x05\x12P\n%nestedmessage_repeated_foreignmessage\x18\x02 \x03(\x0b\x32!.protobuf_unittest.ForeignMessage\"\xe5\x03\n\x17TestCamelCaseFieldNames\x12\x16\n\x0ePrimitiveField\x18\x01 \x01(\x05\x12\x13\n\x0bStringField\x18\x02 \x01(\t\x12\x31\n\tEnumField\x18\x03 \x01(\x0e\x32\x1e.protobuf_unittest.ForeignEnum\x12\x37\n\x0cMessageField\x18\x04 \x01(\x0b\x32!.protobuf_unittest.ForeignMessage\x12\x1c\n\x10StringPieceField\x18\x05 \x01(\tB\x02\x08\x02\x12\x15\n\tCordField\x18\x06 \x01(\tB\x02\x08\x01\x12\x1e\n\x16RepeatedPrimitiveField\x18\x07 \x03(\x05\x12\x1b\n\x13RepeatedStringField\x18\x08 \x03(\t\x12\x39\n\x11RepeatedEnumField\x18\t \x03(\x0e\x32\x1e.protobuf_unittest.ForeignEnum\x12?\n\x14RepeatedMessageField\x18\n \x03(\x0b\x32!.protobuf_unittest.ForeignMessage\x12$\n\x18RepeatedStringPieceField\x18\x0b \x03(\tB\x02\x08\x02\x12\x1d\n\x11RepeatedCordField\x18\x0c \x03(\tB\x02\x08\x01\"\xd5\x01\n\x12TestFieldOrderings\x12\x11\n\tmy_string\x18\x0b \x01(\t\x12\x0e\n\x06my_int\x18\x01 \x01(\x03\x12\x10\n\x08my_float\x18\x65 \x01(\x02\x12U\n\x17optional_nested_message\x18\xc8\x01 \x01(\x0b\x32\x33.protobuf_unittest.TestFieldOrderings.NestedMessage\x1a\'\n\rNestedMessage\x12\n\n\x02oo\x18\x02 \x01(\x03\x12\n\n\x02\x62\x62\x18\x01 \x01(\x05*\x04\x08\x02\x10\x0b*\x04\x08\x0c\x10\x65\"\xb6\x07\n\x18TestExtremeDefaultValues\x12?\n\rescaped_bytes\x18\x01 \x01(\x0c:(\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\\"\\376\x12 \n\x0clarge_uint32\x18\x02 \x01(\r:\n4294967295\x12*\n\x0clarge_uint64\x18\x03 \x01(\x04:\x14\x31\x38\x34\x34\x36\x37\x34\x34\x30\x37\x33\x37\x30\x39\x35\x35\x31\x36\x31\x35\x12 \n\x0bsmall_int32\x18\x04 \x01(\x05:\x0b-2147483647\x12)\n\x0bsmall_int64\x18\x05 \x01(\x03:\x14-9223372036854775807\x12\'\n\x12really_small_int32\x18\x15 \x01(\x05:\x0b-2147483648\x12\x30\n\x12really_small_int64\x18\x16 \x01(\x03:\x14-9223372036854775808\x12\x18\n\x0butf8_string\x18\x06 \x01(\t:\x03\xe1\x88\xb4\x12\x15\n\nzero_float\x18\x07 \x01(\x02:\x01\x30\x12\x14\n\tone_float\x18\x08 \x01(\x02:\x01\x31\x12\x18\n\x0bsmall_float\x18\t \x01(\x02:\x03\x31.5\x12\x1e\n\x12negative_one_float\x18\n \x01(\x02:\x02-1\x12\x1c\n\x0enegative_float\x18\x0b \x01(\x02:\x04-1.5\x12\x1a\n\x0blarge_float\x18\x0c \x01(\x02:\x05\x32\x65+08\x12$\n\x14small_negative_float\x18\r \x01(\x02:\x06-8e-28\x12\x17\n\ninf_double\x18\x0e \x01(\x01:\x03inf\x12\x1c\n\x0eneg_inf_double\x18\x0f \x01(\x01:\x04-inf\x12\x17\n\nnan_double\x18\x10 \x01(\x01:\x03nan\x12\x16\n\tinf_float\x18\x11 \x01(\x02:\x03inf\x12\x1b\n\rneg_inf_float\x18\x12 \x01(\x02:\x04-inf\x12\x16\n\tnan_float\x18\x13 \x01(\x02:\x03nan\x12+\n\x0c\x63pp_trigraph\x18\x14 \x01(\t:\x15? ? ?? ?? ??? ??/ ??-\x12 \n\x10string_with_zero\x18\x17 \x01(\t:\x06hel\x00lo\x12\"\n\x0f\x62ytes_with_zero\x18\x18 \x01(\x0c:\twor\\000ld\x12(\n\x16string_piece_with_zero\x18\x19 \x01(\t:\x04\x61\x62\x00\x63\x42\x02\x08\x02\x12 \n\x0e\x63ord_with_zero\x18\x1a \x01(\t:\x04\x31\x32\x00\x33\x42\x02\x08\x01\x12&\n\x12replacement_string\x18\x1b \x01(\t:\n${unknown}\"K\n\x11SparseEnumMessage\x12\x36\n\x0bsparse_enum\x18\x01 \x01(\x0e\x32!.protobuf_unittest.TestSparseEnum\"\x19\n\tOneString\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\t\"\x1a\n\nMoreString\x12\x0c\n\x04\x64\x61ta\x18\x01 \x03(\t\"\x18\n\x08OneBytes\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\"\x19\n\tMoreBytes\x12\x0c\n\x04\x64\x61ta\x18\x01 \x03(\x0c\"\x1c\n\x0cInt32Message\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x05\"\x1d\n\rUint32Message\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\r\"\x1c\n\x0cInt64Message\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x03\"\x1d\n\rUint64Message\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x04\"\x1b\n\x0b\x42oolMessage\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x08\"\xd0\x01\n\tTestOneof\x12\x11\n\x07\x66oo_int\x18\x01 \x01(\x05H\x00\x12\x14\n\nfoo_string\x18\x02 \x01(\tH\x00\x12\x36\n\x0b\x66oo_message\x18\x03 \x01(\x0b\x32\x1f.protobuf_unittest.TestAllTypesH\x00\x12\x39\n\x08\x66oogroup\x18\x04 \x01(\n2%.protobuf_unittest.TestOneof.FooGroupH\x00\x1a \n\x08\x46ooGroup\x12\t\n\x01\x61\x18\x05 \x01(\x05\x12\t\n\x01\x62\x18\x06 \x01(\tB\x05\n\x03\x66oo\"\xe7\x01\n\x1cTestOneofBackwardsCompatible\x12\x0f\n\x07\x66oo_int\x18\x01 \x01(\x05\x12\x12\n\nfoo_string\x18\x02 \x01(\t\x12\x34\n\x0b\x66oo_message\x18\x03 \x01(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\x12J\n\x08\x66oogroup\x18\x04 \x01(\n28.protobuf_unittest.TestOneofBackwardsCompatible.FooGroup\x1a \n\x08\x46ooGroup\x12\t\n\x01\x61\x18\x05 \x01(\x05\x12\t\n\x01\x62\x18\x06 \x01(\t\"\x9e\x06\n\nTestOneof2\x12\x11\n\x07\x66oo_int\x18\x01 \x01(\x05H\x00\x12\x14\n\nfoo_string\x18\x02 \x01(\tH\x00\x12\x16\n\x08\x66oo_cord\x18\x03 \x01(\tB\x02\x08\x01H\x00\x12\x1e\n\x10\x66oo_string_piece\x18\x04 \x01(\tB\x02\x08\x02H\x00\x12\x13\n\tfoo_bytes\x18\x05 \x01(\x0cH\x00\x12<\n\x08\x66oo_enum\x18\x06 \x01(\x0e\x32(.protobuf_unittest.TestOneof2.NestedEnumH\x00\x12\x42\n\x0b\x66oo_message\x18\x07 \x01(\x0b\x32+.protobuf_unittest.TestOneof2.NestedMessageH\x00\x12:\n\x08\x66oogroup\x18\x08 \x01(\n2&.protobuf_unittest.TestOneof2.FooGroupH\x00\x12K\n\x10\x66oo_lazy_message\x18\x0b \x01(\x0b\x32+.protobuf_unittest.TestOneof2.NestedMessageB\x02(\x01H\x00\x12\x14\n\x07\x62\x61r_int\x18\x0c \x01(\x05:\x01\x35H\x01\x12\x1c\n\nbar_string\x18\r \x01(\t:\x06STRINGH\x01\x12\x1c\n\x08\x62\x61r_cord\x18\x0e \x01(\t:\x04\x43ORDB\x02\x08\x01H\x01\x12&\n\x10\x62\x61r_string_piece\x18\x0f \x01(\t:\x06SPIECEB\x02\x08\x02H\x01\x12\x1a\n\tbar_bytes\x18\x10 \x01(\x0c:\x05\x42YTESH\x01\x12\x41\n\x08\x62\x61r_enum\x18\x11 \x01(\x0e\x32(.protobuf_unittest.TestOneof2.NestedEnum:\x03\x42\x41RH\x01\x12\x0f\n\x07\x62\x61z_int\x18\x12 \x01(\x05\x12\x17\n\nbaz_string\x18\x13 \x01(\t:\x03\x42\x41Z\x1a \n\x08\x46ooGroup\x12\t\n\x01\x61\x18\t \x01(\x05\x12\t\n\x01\x62\x18\n \x01(\t\x1a\x33\n\rNestedMessage\x12\x0f\n\x07qux_int\x18\x01 \x01(\x03\x12\x11\n\tcorge_int\x18\x02 \x03(\x05\"\'\n\nNestedEnum\x12\x07\n\x03\x46OO\x10\x01\x12\x07\n\x03\x42\x41R\x10\x02\x12\x07\n\x03\x42\x41Z\x10\x03\x42\x05\n\x03\x66ooB\x05\n\x03\x62\x61r\"\xb8\x01\n\x11TestRequiredOneof\x12\x11\n\x07\x66oo_int\x18\x01 \x01(\x05H\x00\x12\x14\n\nfoo_string\x18\x02 \x01(\tH\x00\x12I\n\x0b\x66oo_message\x18\x03 \x01(\x0b\x32\x32.protobuf_unittest.TestRequiredOneof.NestedMessageH\x00\x1a(\n\rNestedMessage\x12\x17\n\x0frequired_double\x18\x01 \x02(\x01\x42\x05\n\x03\x66oo\"\xaa\x03\n\x0fTestPackedTypes\x12\x18\n\x0cpacked_int32\x18Z \x03(\x05\x42\x02\x10\x01\x12\x18\n\x0cpacked_int64\x18[ \x03(\x03\x42\x02\x10\x01\x12\x19\n\rpacked_uint32\x18\\ \x03(\rB\x02\x10\x01\x12\x19\n\rpacked_uint64\x18] \x03(\x04\x42\x02\x10\x01\x12\x19\n\rpacked_sint32\x18^ \x03(\x11\x42\x02\x10\x01\x12\x19\n\rpacked_sint64\x18_ \x03(\x12\x42\x02\x10\x01\x12\x1a\n\x0epacked_fixed32\x18` \x03(\x07\x42\x02\x10\x01\x12\x1a\n\x0epacked_fixed64\x18\x61 \x03(\x06\x42\x02\x10\x01\x12\x1b\n\x0fpacked_sfixed32\x18\x62 \x03(\x0f\x42\x02\x10\x01\x12\x1b\n\x0fpacked_sfixed64\x18\x63 \x03(\x10\x42\x02\x10\x01\x12\x18\n\x0cpacked_float\x18\x64 \x03(\x02\x42\x02\x10\x01\x12\x19\n\rpacked_double\x18\x65 \x03(\x01\x42\x02\x10\x01\x12\x17\n\x0bpacked_bool\x18\x66 \x03(\x08\x42\x02\x10\x01\x12\x37\n\x0bpacked_enum\x18g \x03(\x0e\x32\x1e.protobuf_unittest.ForeignEnumB\x02\x10\x01\"\xc8\x03\n\x11TestUnpackedTypes\x12\x1a\n\x0eunpacked_int32\x18Z \x03(\x05\x42\x02\x10\x00\x12\x1a\n\x0eunpacked_int64\x18[ \x03(\x03\x42\x02\x10\x00\x12\x1b\n\x0funpacked_uint32\x18\\ \x03(\rB\x02\x10\x00\x12\x1b\n\x0funpacked_uint64\x18] \x03(\x04\x42\x02\x10\x00\x12\x1b\n\x0funpacked_sint32\x18^ \x03(\x11\x42\x02\x10\x00\x12\x1b\n\x0funpacked_sint64\x18_ \x03(\x12\x42\x02\x10\x00\x12\x1c\n\x10unpacked_fixed32\x18` \x03(\x07\x42\x02\x10\x00\x12\x1c\n\x10unpacked_fixed64\x18\x61 \x03(\x06\x42\x02\x10\x00\x12\x1d\n\x11unpacked_sfixed32\x18\x62 \x03(\x0f\x42\x02\x10\x00\x12\x1d\n\x11unpacked_sfixed64\x18\x63 \x03(\x10\x42\x02\x10\x00\x12\x1a\n\x0eunpacked_float\x18\x64 \x03(\x02\x42\x02\x10\x00\x12\x1b\n\x0funpacked_double\x18\x65 \x03(\x01\x42\x02\x10\x00\x12\x19\n\runpacked_bool\x18\x66 \x03(\x08\x42\x02\x10\x00\x12\x39\n\runpacked_enum\x18g \x03(\x0e\x32\x1e.protobuf_unittest.ForeignEnumB\x02\x10\x00\" \n\x14TestPackedExtensions*\x08\x08\x01\x10\x80\x80\x80\x80\x02\"\"\n\x16TestUnpackedExtensions*\x08\x08\x01\x10\x80\x80\x80\x80\x02\"\x99\x04\n\x15TestDynamicExtensions\x12\x19\n\x10scalar_extension\x18\xd0\x0f \x01(\x07\x12\x37\n\x0e\x65num_extension\x18\xd1\x0f \x01(\x0e\x32\x1e.protobuf_unittest.ForeignEnum\x12Y\n\x16\x64ynamic_enum_extension\x18\xd2\x0f \x01(\x0e\x32\x38.protobuf_unittest.TestDynamicExtensions.DynamicEnumType\x12=\n\x11message_extension\x18\xd3\x0f \x01(\x0b\x32!.protobuf_unittest.ForeignMessage\x12_\n\x19\x64ynamic_message_extension\x18\xd4\x0f \x01(\x0b\x32;.protobuf_unittest.TestDynamicExtensions.DynamicMessageType\x12\x1b\n\x12repeated_extension\x18\xd5\x0f \x03(\t\x12\x1d\n\x10packed_extension\x18\xd6\x0f \x03(\x11\x42\x02\x10\x01\x1a,\n\x12\x44ynamicMessageType\x12\x16\n\rdynamic_field\x18\xb4\x10 \x01(\x05\"G\n\x0f\x44ynamicEnumType\x12\x10\n\x0b\x44YNAMIC_FOO\x10\x98\x11\x12\x10\n\x0b\x44YNAMIC_BAR\x10\x99\x11\x12\x10\n\x0b\x44YNAMIC_BAZ\x10\x9a\x11\"\xc0\x01\n#TestRepeatedScalarDifferentTagSizes\x12\x18\n\x10repeated_fixed32\x18\x0c \x03(\x07\x12\x16\n\x0erepeated_int32\x18\r \x03(\x05\x12\x19\n\x10repeated_fixed64\x18\xfe\x0f \x03(\x06\x12\x17\n\x0erepeated_int64\x18\xff\x0f \x03(\x03\x12\x18\n\x0erepeated_float\x18\xfe\xff\x0f \x03(\x02\x12\x19\n\x0frepeated_uint64\x18\xff\xff\x0f \x03(\x04\"\xf7\t\n\x10TestParsingMerge\x12;\n\x12required_all_types\x18\x01 \x02(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\x12;\n\x12optional_all_types\x18\x02 \x01(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\x12;\n\x12repeated_all_types\x18\x03 \x03(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\x12H\n\roptionalgroup\x18\n \x01(\n21.protobuf_unittest.TestParsingMerge.OptionalGroup\x12H\n\rrepeatedgroup\x18\x14 \x03(\n21.protobuf_unittest.TestParsingMerge.RepeatedGroup\x1a\xaa\x04\n\x17RepeatedFieldsGenerator\x12/\n\x06\x66ield1\x18\x01 \x03(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\x12/\n\x06\x66ield2\x18\x02 \x03(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\x12/\n\x06\x66ield3\x18\x03 \x03(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\x12R\n\x06group1\x18\n \x03(\n2B.protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group1\x12R\n\x06group2\x18\x14 \x03(\n2B.protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group2\x12.\n\x04\x65xt1\x18\xe8\x07 \x03(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\x12.\n\x04\x65xt2\x18\xe9\x07 \x03(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\x1a\x39\n\x06Group1\x12/\n\x06\x66ield1\x18\x0b \x01(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\x1a\x39\n\x06Group2\x12/\n\x06\x66ield1\x18\x15 \x01(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\x1aR\n\rOptionalGroup\x12\x41\n\x18optional_group_all_types\x18\x0b \x01(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\x1aR\n\rRepeatedGroup\x12\x41\n\x18repeated_group_all_types\x18\x15 \x01(\x0b\x32\x1f.protobuf_unittest.TestAllTypes*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\x32[\n\x0coptional_ext\x12#.protobuf_unittest.TestParsingMerge\x18\xe8\x07 \x01(\x0b\x32\x1f.protobuf_unittest.TestAllTypes2[\n\x0crepeated_ext\x12#.protobuf_unittest.TestParsingMerge\x18\xe9\x07 \x03(\x0b\x32\x1f.protobuf_unittest.TestAllTypes\"D\n\x1bTestCommentInjectionMessage\x12%\n\x01\x61\x18\x01 \x01(\t:\x1a*/ <- Neither should this.\"\x0c\n\nFooRequest\"\r\n\x0b\x46ooResponse\"\x12\n\x10\x46ooClientMessage\"\x12\n\x10\x46ooServerMessage\"\x0c\n\nBarRequest\"\r\n\x0b\x42\x61rResponse*@\n\x0b\x46oreignEnum\x12\x0f\n\x0b\x46OREIGN_FOO\x10\x04\x12\x0f\n\x0b\x46OREIGN_BAR\x10\x05\x12\x0f\n\x0b\x46OREIGN_BAZ\x10\x06*K\n\x14TestEnumWithDupValue\x12\x08\n\x04\x46OO1\x10\x01\x12\x08\n\x04\x42\x41R1\x10\x02\x12\x07\n\x03\x42\x41Z\x10\x03\x12\x08\n\x04\x46OO2\x10\x01\x12\x08\n\x04\x42\x41R2\x10\x02\x1a\x02\x10\x01*\x89\x01\n\x0eTestSparseEnum\x12\x0c\n\x08SPARSE_A\x10{\x12\x0e\n\x08SPARSE_B\x10\xa6\xe7\x03\x12\x0f\n\x08SPARSE_C\x10\xb2\xb1\x80\x06\x12\x15\n\x08SPARSE_D\x10\xf1\xff\xff\xff\xff\xff\xff\xff\xff\x01\x12\x15\n\x08SPARSE_E\x10\xb4\xde\xfc\xff\xff\xff\xff\xff\xff\x01\x12\x0c\n\x08SPARSE_F\x10\x00\x12\x0c\n\x08SPARSE_G\x10\x02\x32\x99\x01\n\x0bTestService\x12\x44\n\x03\x46oo\x12\x1d.protobuf_unittest.FooRequest\x1a\x1e.protobuf_unittest.FooResponse\x12\x44\n\x03\x42\x61r\x12\x1d.protobuf_unittest.BarRequest\x1a\x1e.protobuf_unittest.BarResponse:F\n\x18optional_int32_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x01 \x01(\x05:F\n\x18optional_int64_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x02 \x01(\x03:G\n\x19optional_uint32_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x03 \x01(\r:G\n\x19optional_uint64_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x04 \x01(\x04:G\n\x19optional_sint32_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x05 \x01(\x11:G\n\x19optional_sint64_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x06 \x01(\x12:H\n\x1aoptional_fixed32_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x07 \x01(\x07:H\n\x1aoptional_fixed64_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x08 \x01(\x06:I\n\x1boptional_sfixed32_extension\x12$.protobuf_unittest.TestAllExtensions\x18\t \x01(\x0f:I\n\x1boptional_sfixed64_extension\x12$.protobuf_unittest.TestAllExtensions\x18\n \x01(\x10:F\n\x18optional_float_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x0b \x01(\x02:G\n\x19optional_double_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x0c \x01(\x01:E\n\x17optional_bool_extension\x12$.protobuf_unittest.TestAllExtensions\x18\r \x01(\x08:G\n\x19optional_string_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x0e \x01(\t:F\n\x18optional_bytes_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x0f \x01(\x0c:q\n\x17optionalgroup_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x10 \x01(\n2*.protobuf_unittest.OptionalGroup_extension:~\n!optional_nested_message_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x12 \x01(\x0b\x32-.protobuf_unittest.TestAllTypes.NestedMessage:s\n\"optional_foreign_message_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x13 \x01(\x0b\x32!.protobuf_unittest.ForeignMessage:x\n!optional_import_message_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x14 \x01(\x0b\x32\'.protobuf_unittest_import.ImportMessage:x\n\x1eoptional_nested_enum_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x15 \x01(\x0e\x32*.protobuf_unittest.TestAllTypes.NestedEnum:m\n\x1foptional_foreign_enum_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x16 \x01(\x0e\x32\x1e.protobuf_unittest.ForeignEnum:r\n\x1eoptional_import_enum_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x17 \x01(\x0e\x32$.protobuf_unittest_import.ImportEnum:Q\n\x1foptional_string_piece_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x18 \x01(\tB\x02\x08\x02:I\n\x17optional_cord_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x19 \x01(\tB\x02\x08\x01:\x85\x01\n(optional_public_import_message_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x1a \x01(\x0b\x32-.protobuf_unittest_import.PublicImportMessage:\x80\x01\n\x1foptional_lazy_message_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x1b \x01(\x0b\x32-.protobuf_unittest.TestAllTypes.NestedMessageB\x02(\x01:F\n\x18repeated_int32_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x1f \x03(\x05:F\n\x18repeated_int64_extension\x12$.protobuf_unittest.TestAllExtensions\x18  \x03(\x03:G\n\x19repeated_uint32_extension\x12$.protobuf_unittest.TestAllExtensions\x18! \x03(\r:G\n\x19repeated_uint64_extension\x12$.protobuf_unittest.TestAllExtensions\x18\" \x03(\x04:G\n\x19repeated_sint32_extension\x12$.protobuf_unittest.TestAllExtensions\x18# \x03(\x11:G\n\x19repeated_sint64_extension\x12$.protobuf_unittest.TestAllExtensions\x18$ \x03(\x12:H\n\x1arepeated_fixed32_extension\x12$.protobuf_unittest.TestAllExtensions\x18% \x03(\x07:H\n\x1arepeated_fixed64_extension\x12$.protobuf_unittest.TestAllExtensions\x18& \x03(\x06:I\n\x1brepeated_sfixed32_extension\x12$.protobuf_unittest.TestAllExtensions\x18\' \x03(\x0f:I\n\x1brepeated_sfixed64_extension\x12$.protobuf_unittest.TestAllExtensions\x18( \x03(\x10:F\n\x18repeated_float_extension\x12$.protobuf_unittest.TestAllExtensions\x18) \x03(\x02:G\n\x19repeated_double_extension\x12$.protobuf_unittest.TestAllExtensions\x18* \x03(\x01:E\n\x17repeated_bool_extension\x12$.protobuf_unittest.TestAllExtensions\x18+ \x03(\x08:G\n\x19repeated_string_extension\x12$.protobuf_unittest.TestAllExtensions\x18, \x03(\t:F\n\x18repeated_bytes_extension\x12$.protobuf_unittest.TestAllExtensions\x18- \x03(\x0c:q\n\x17repeatedgroup_extension\x12$.protobuf_unittest.TestAllExtensions\x18. \x03(\n2*.protobuf_unittest.RepeatedGroup_extension:~\n!repeated_nested_message_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x30 \x03(\x0b\x32-.protobuf_unittest.TestAllTypes.NestedMessage:s\n\"repeated_foreign_message_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x31 \x03(\x0b\x32!.protobuf_unittest.ForeignMessage:x\n!repeated_import_message_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x32 \x03(\x0b\x32\'.protobuf_unittest_import.ImportMessage:x\n\x1erepeated_nested_enum_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x33 \x03(\x0e\x32*.protobuf_unittest.TestAllTypes.NestedEnum:m\n\x1frepeated_foreign_enum_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x34 \x03(\x0e\x32\x1e.protobuf_unittest.ForeignEnum:r\n\x1erepeated_import_enum_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x35 \x03(\x0e\x32$.protobuf_unittest_import.ImportEnum:Q\n\x1frepeated_string_piece_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x36 \x03(\tB\x02\x08\x02:I\n\x17repeated_cord_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x37 \x03(\tB\x02\x08\x01:\x80\x01\n\x1frepeated_lazy_message_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x39 \x03(\x0b\x32-.protobuf_unittest.TestAllTypes.NestedMessageB\x02(\x01:I\n\x17\x64\x65\x66\x61ult_int32_extension\x12$.protobuf_unittest.TestAllExtensions\x18= \x01(\x05:\x02\x34\x31:I\n\x17\x64\x65\x66\x61ult_int64_extension\x12$.protobuf_unittest.TestAllExtensions\x18> \x01(\x03:\x02\x34\x32:J\n\x18\x64\x65\x66\x61ult_uint32_extension\x12$.protobuf_unittest.TestAllExtensions\x18? \x01(\r:\x02\x34\x33:J\n\x18\x64\x65\x66\x61ult_uint64_extension\x12$.protobuf_unittest.TestAllExtensions\x18@ \x01(\x04:\x02\x34\x34:K\n\x18\x64\x65\x66\x61ult_sint32_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x41 \x01(\x11:\x03-45:J\n\x18\x64\x65\x66\x61ult_sint64_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x42 \x01(\x12:\x02\x34\x36:K\n\x19\x64\x65\x66\x61ult_fixed32_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x43 \x01(\x07:\x02\x34\x37:K\n\x19\x64\x65\x66\x61ult_fixed64_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x44 \x01(\x06:\x02\x34\x38:L\n\x1a\x64\x65\x66\x61ult_sfixed32_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x45 \x01(\x0f:\x02\x34\x39:M\n\x1a\x64\x65\x66\x61ult_sfixed64_extension\x12$.protobuf_unittest.TestAllExtensions\x18\x46 \x01(\x10:\x03-50:K\n\x17\x64\x65\x66\x61ult_float_extension\x12$.protobuf_unittest.TestAllExtensions\x18G \x01(\x02:\x04\x35\x31.5:M\n\x18\x64\x65\x66\x61ult_double_extension\x12$.protobuf_unittest.TestAllExtensions\x18H \x01(\x01:\x05\x35\x32\x30\x30\x30:J\n\x16\x64\x65\x66\x61ult_bool_extension\x12$.protobuf_unittest.TestAllExtensions\x18I \x01(\x08:\x04true:M\n\x18\x64\x65\x66\x61ult_string_extension\x12$.protobuf_unittest.TestAllExtensions\x18J \x01(\t:\x05hello:L\n\x17\x64\x65\x66\x61ult_bytes_extension\x12$.protobuf_unittest.TestAllExtensions\x18K \x01(\x0c:\x05world:|\n\x1d\x64\x65\x66\x61ult_nested_enum_extension\x12$.protobuf_unittest.TestAllExtensions\x18Q \x01(\x0e\x32*.protobuf_unittest.TestAllTypes.NestedEnum:\x03\x42\x41R:y\n\x1e\x64\x65\x66\x61ult_foreign_enum_extension\x12$.protobuf_unittest.TestAllExtensions\x18R \x01(\x0e\x32\x1e.protobuf_unittest.ForeignEnum:\x0b\x46OREIGN_BAR:}\n\x1d\x64\x65\x66\x61ult_import_enum_extension\x12$.protobuf_unittest.TestAllExtensions\x18S \x01(\x0e\x32$.protobuf_unittest_import.ImportEnum:\nIMPORT_BAR:U\n\x1e\x64\x65\x66\x61ult_string_piece_extension\x12$.protobuf_unittest.TestAllExtensions\x18T \x01(\t:\x03\x61\x62\x63\x42\x02\x08\x02:M\n\x16\x64\x65\x66\x61ult_cord_extension\x12$.protobuf_unittest.TestAllExtensions\x18U \x01(\t:\x03\x31\x32\x33\x42\x02\x08\x01:D\n\x16oneof_uint32_extension\x12$.protobuf_unittest.TestAllExtensions\x18o \x01(\r:{\n\x1eoneof_nested_message_extension\x12$.protobuf_unittest.TestAllExtensions\x18p \x01(\x0b\x32-.protobuf_unittest.TestAllTypes.NestedMessage:D\n\x16oneof_string_extension\x12$.protobuf_unittest.TestAllExtensions\x18q \x01(\t:C\n\x15oneof_bytes_extension\x12$.protobuf_unittest.TestAllExtensions\x18r \x01(\x0c:B\n\x13my_extension_string\x12%.protobuf_unittest.TestFieldOrderings\x18\x32 \x01(\t:?\n\x10my_extension_int\x12%.protobuf_unittest.TestFieldOrderings\x18\x05 \x01(\x05:K\n\x16packed_int32_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18Z \x03(\x05\x42\x02\x10\x01:K\n\x16packed_int64_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18[ \x03(\x03\x42\x02\x10\x01:L\n\x17packed_uint32_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18\\ \x03(\rB\x02\x10\x01:L\n\x17packed_uint64_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18] \x03(\x04\x42\x02\x10\x01:L\n\x17packed_sint32_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18^ \x03(\x11\x42\x02\x10\x01:L\n\x17packed_sint64_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18_ \x03(\x12\x42\x02\x10\x01:M\n\x18packed_fixed32_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18` \x03(\x07\x42\x02\x10\x01:M\n\x18packed_fixed64_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18\x61 \x03(\x06\x42\x02\x10\x01:N\n\x19packed_sfixed32_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18\x62 \x03(\x0f\x42\x02\x10\x01:N\n\x19packed_sfixed64_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18\x63 \x03(\x10\x42\x02\x10\x01:K\n\x16packed_float_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18\x64 \x03(\x02\x42\x02\x10\x01:L\n\x17packed_double_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18\x65 \x03(\x01\x42\x02\x10\x01:J\n\x15packed_bool_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18\x66 \x03(\x08\x42\x02\x10\x01:j\n\x15packed_enum_extension\x12\'.protobuf_unittest.TestPackedExtensions\x18g \x03(\x0e\x32\x1e.protobuf_unittest.ForeignEnumB\x02\x10\x01:O\n\x18unpacked_int32_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18Z \x03(\x05\x42\x02\x10\x00:O\n\x18unpacked_int64_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18[ \x03(\x03\x42\x02\x10\x00:P\n\x19unpacked_uint32_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18\\ \x03(\rB\x02\x10\x00:P\n\x19unpacked_uint64_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18] \x03(\x04\x42\x02\x10\x00:P\n\x19unpacked_sint32_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18^ \x03(\x11\x42\x02\x10\x00:P\n\x19unpacked_sint64_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18_ \x03(\x12\x42\x02\x10\x00:Q\n\x1aunpacked_fixed32_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18` \x03(\x07\x42\x02\x10\x00:Q\n\x1aunpacked_fixed64_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18\x61 \x03(\x06\x42\x02\x10\x00:R\n\x1bunpacked_sfixed32_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18\x62 \x03(\x0f\x42\x02\x10\x00:R\n\x1bunpacked_sfixed64_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18\x63 \x03(\x10\x42\x02\x10\x00:O\n\x18unpacked_float_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18\x64 \x03(\x02\x42\x02\x10\x00:P\n\x19unpacked_double_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18\x65 \x03(\x01\x42\x02\x10\x00:N\n\x17unpacked_bool_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18\x66 \x03(\x08\x42\x02\x10\x00:n\n\x17unpacked_enum_extension\x12).protobuf_unittest.TestUnpackedExtensions\x18g \x03(\x0e\x32\x1e.protobuf_unittest.ForeignEnumB\x02\x10\x00\x42\x1d\x42\rUnittestProtoH\x01\x80\x01\x01\x88\x01\x01\x90\x01\x01\xf8\x01\x01')
+  ,
+  dependencies=[google_dot_protobuf_dot_unittest__import__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+_FOREIGNENUM = _descriptor.EnumDescriptor(
+  name='ForeignEnum',
+  full_name='protobuf_unittest.ForeignEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='FOREIGN_FOO', index=0, number=4,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FOREIGN_BAR', index=1, number=5,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FOREIGN_BAZ', index=2, number=6,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=12445,
+  serialized_end=12509,
+)
+_sym_db.RegisterEnumDescriptor(_FOREIGNENUM)
+
+ForeignEnum = enum_type_wrapper.EnumTypeWrapper(_FOREIGNENUM)
+_TESTENUMWITHDUPVALUE = _descriptor.EnumDescriptor(
+  name='TestEnumWithDupValue',
+  full_name='protobuf_unittest.TestEnumWithDupValue',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='FOO1', index=0, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAR1', index=1, number=2,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAZ', index=2, number=3,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FOO2', index=3, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAR2', index=4, number=2,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\020\001')),
+  serialized_start=12511,
+  serialized_end=12586,
+)
+_sym_db.RegisterEnumDescriptor(_TESTENUMWITHDUPVALUE)
+
+TestEnumWithDupValue = enum_type_wrapper.EnumTypeWrapper(_TESTENUMWITHDUPVALUE)
+_TESTSPARSEENUM = _descriptor.EnumDescriptor(
+  name='TestSparseEnum',
+  full_name='protobuf_unittest.TestSparseEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SPARSE_A', index=0, number=123,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='SPARSE_B', index=1, number=62374,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='SPARSE_C', index=2, number=12589234,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='SPARSE_D', index=3, number=-15,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='SPARSE_E', index=4, number=-53452,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='SPARSE_F', index=5, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='SPARSE_G', index=6, number=2,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=12589,
+  serialized_end=12726,
+)
+_sym_db.RegisterEnumDescriptor(_TESTSPARSEENUM)
+
+TestSparseEnum = enum_type_wrapper.EnumTypeWrapper(_TESTSPARSEENUM)
+FOREIGN_FOO = 4
+FOREIGN_BAR = 5
+FOREIGN_BAZ = 6
+FOO1 = 1
+BAR1 = 2
+BAZ = 3
+FOO2 = 1
+BAR2 = 2
+SPARSE_A = 123
+SPARSE_B = 62374
+SPARSE_C = 12589234
+SPARSE_D = -15
+SPARSE_E = -53452
+SPARSE_F = 0
+SPARSE_G = 2
+
+OPTIONAL_INT32_EXTENSION_FIELD_NUMBER = 1
+optional_int32_extension = _descriptor.FieldDescriptor(
+  name='optional_int32_extension', full_name='protobuf_unittest.optional_int32_extension', index=0,
+  number=1, type=5, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_INT64_EXTENSION_FIELD_NUMBER = 2
+optional_int64_extension = _descriptor.FieldDescriptor(
+  name='optional_int64_extension', full_name='protobuf_unittest.optional_int64_extension', index=1,
+  number=2, type=3, cpp_type=2, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_UINT32_EXTENSION_FIELD_NUMBER = 3
+optional_uint32_extension = _descriptor.FieldDescriptor(
+  name='optional_uint32_extension', full_name='protobuf_unittest.optional_uint32_extension', index=2,
+  number=3, type=13, cpp_type=3, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_UINT64_EXTENSION_FIELD_NUMBER = 4
+optional_uint64_extension = _descriptor.FieldDescriptor(
+  name='optional_uint64_extension', full_name='protobuf_unittest.optional_uint64_extension', index=3,
+  number=4, type=4, cpp_type=4, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_SINT32_EXTENSION_FIELD_NUMBER = 5
+optional_sint32_extension = _descriptor.FieldDescriptor(
+  name='optional_sint32_extension', full_name='protobuf_unittest.optional_sint32_extension', index=4,
+  number=5, type=17, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_SINT64_EXTENSION_FIELD_NUMBER = 6
+optional_sint64_extension = _descriptor.FieldDescriptor(
+  name='optional_sint64_extension', full_name='protobuf_unittest.optional_sint64_extension', index=5,
+  number=6, type=18, cpp_type=2, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_FIXED32_EXTENSION_FIELD_NUMBER = 7
+optional_fixed32_extension = _descriptor.FieldDescriptor(
+  name='optional_fixed32_extension', full_name='protobuf_unittest.optional_fixed32_extension', index=6,
+  number=7, type=7, cpp_type=3, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_FIXED64_EXTENSION_FIELD_NUMBER = 8
+optional_fixed64_extension = _descriptor.FieldDescriptor(
+  name='optional_fixed64_extension', full_name='protobuf_unittest.optional_fixed64_extension', index=7,
+  number=8, type=6, cpp_type=4, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_SFIXED32_EXTENSION_FIELD_NUMBER = 9
+optional_sfixed32_extension = _descriptor.FieldDescriptor(
+  name='optional_sfixed32_extension', full_name='protobuf_unittest.optional_sfixed32_extension', index=8,
+  number=9, type=15, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_SFIXED64_EXTENSION_FIELD_NUMBER = 10
+optional_sfixed64_extension = _descriptor.FieldDescriptor(
+  name='optional_sfixed64_extension', full_name='protobuf_unittest.optional_sfixed64_extension', index=9,
+  number=10, type=16, cpp_type=2, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_FLOAT_EXTENSION_FIELD_NUMBER = 11
+optional_float_extension = _descriptor.FieldDescriptor(
+  name='optional_float_extension', full_name='protobuf_unittest.optional_float_extension', index=10,
+  number=11, type=2, cpp_type=6, label=1,
+  has_default_value=False, default_value=float(0),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_DOUBLE_EXTENSION_FIELD_NUMBER = 12
+optional_double_extension = _descriptor.FieldDescriptor(
+  name='optional_double_extension', full_name='protobuf_unittest.optional_double_extension', index=11,
+  number=12, type=1, cpp_type=5, label=1,
+  has_default_value=False, default_value=float(0),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_BOOL_EXTENSION_FIELD_NUMBER = 13
+optional_bool_extension = _descriptor.FieldDescriptor(
+  name='optional_bool_extension', full_name='protobuf_unittest.optional_bool_extension', index=12,
+  number=13, type=8, cpp_type=7, label=1,
+  has_default_value=False, default_value=False,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_STRING_EXTENSION_FIELD_NUMBER = 14
+optional_string_extension = _descriptor.FieldDescriptor(
+  name='optional_string_extension', full_name='protobuf_unittest.optional_string_extension', index=13,
+  number=14, type=9, cpp_type=9, label=1,
+  has_default_value=False, default_value=_b("").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_BYTES_EXTENSION_FIELD_NUMBER = 15
+optional_bytes_extension = _descriptor.FieldDescriptor(
+  name='optional_bytes_extension', full_name='protobuf_unittest.optional_bytes_extension', index=14,
+  number=15, type=12, cpp_type=9, label=1,
+  has_default_value=False, default_value=_b(""),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONALGROUP_EXTENSION_FIELD_NUMBER = 16
+optionalgroup_extension = _descriptor.FieldDescriptor(
+  name='optionalgroup_extension', full_name='protobuf_unittest.optionalgroup_extension', index=15,
+  number=16, type=10, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER = 18
+optional_nested_message_extension = _descriptor.FieldDescriptor(
+  name='optional_nested_message_extension', full_name='protobuf_unittest.optional_nested_message_extension', index=16,
+  number=18, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_FOREIGN_MESSAGE_EXTENSION_FIELD_NUMBER = 19
+optional_foreign_message_extension = _descriptor.FieldDescriptor(
+  name='optional_foreign_message_extension', full_name='protobuf_unittest.optional_foreign_message_extension', index=17,
+  number=19, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_IMPORT_MESSAGE_EXTENSION_FIELD_NUMBER = 20
+optional_import_message_extension = _descriptor.FieldDescriptor(
+  name='optional_import_message_extension', full_name='protobuf_unittest.optional_import_message_extension', index=18,
+  number=20, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER = 21
+optional_nested_enum_extension = _descriptor.FieldDescriptor(
+  name='optional_nested_enum_extension', full_name='protobuf_unittest.optional_nested_enum_extension', index=19,
+  number=21, type=14, cpp_type=8, label=1,
+  has_default_value=False, default_value=1,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_FOREIGN_ENUM_EXTENSION_FIELD_NUMBER = 22
+optional_foreign_enum_extension = _descriptor.FieldDescriptor(
+  name='optional_foreign_enum_extension', full_name='protobuf_unittest.optional_foreign_enum_extension', index=20,
+  number=22, type=14, cpp_type=8, label=1,
+  has_default_value=False, default_value=4,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_IMPORT_ENUM_EXTENSION_FIELD_NUMBER = 23
+optional_import_enum_extension = _descriptor.FieldDescriptor(
+  name='optional_import_enum_extension', full_name='protobuf_unittest.optional_import_enum_extension', index=21,
+  number=23, type=14, cpp_type=8, label=1,
+  has_default_value=False, default_value=7,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_STRING_PIECE_EXTENSION_FIELD_NUMBER = 24
+optional_string_piece_extension = _descriptor.FieldDescriptor(
+  name='optional_string_piece_extension', full_name='protobuf_unittest.optional_string_piece_extension', index=22,
+  number=24, type=9, cpp_type=9, label=1,
+  has_default_value=False, default_value=_b("").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002')))
+OPTIONAL_CORD_EXTENSION_FIELD_NUMBER = 25
+optional_cord_extension = _descriptor.FieldDescriptor(
+  name='optional_cord_extension', full_name='protobuf_unittest.optional_cord_extension', index=23,
+  number=25, type=9, cpp_type=9, label=1,
+  has_default_value=False, default_value=_b("").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001')))
+OPTIONAL_PUBLIC_IMPORT_MESSAGE_EXTENSION_FIELD_NUMBER = 26
+optional_public_import_message_extension = _descriptor.FieldDescriptor(
+  name='optional_public_import_message_extension', full_name='protobuf_unittest.optional_public_import_message_extension', index=24,
+  number=26, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+OPTIONAL_LAZY_MESSAGE_EXTENSION_FIELD_NUMBER = 27
+optional_lazy_message_extension = _descriptor.FieldDescriptor(
+  name='optional_lazy_message_extension', full_name='protobuf_unittest.optional_lazy_message_extension', index=25,
+  number=27, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001')))
+REPEATED_INT32_EXTENSION_FIELD_NUMBER = 31
+repeated_int32_extension = _descriptor.FieldDescriptor(
+  name='repeated_int32_extension', full_name='protobuf_unittest.repeated_int32_extension', index=26,
+  number=31, type=5, cpp_type=1, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_INT64_EXTENSION_FIELD_NUMBER = 32
+repeated_int64_extension = _descriptor.FieldDescriptor(
+  name='repeated_int64_extension', full_name='protobuf_unittest.repeated_int64_extension', index=27,
+  number=32, type=3, cpp_type=2, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_UINT32_EXTENSION_FIELD_NUMBER = 33
+repeated_uint32_extension = _descriptor.FieldDescriptor(
+  name='repeated_uint32_extension', full_name='protobuf_unittest.repeated_uint32_extension', index=28,
+  number=33, type=13, cpp_type=3, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_UINT64_EXTENSION_FIELD_NUMBER = 34
+repeated_uint64_extension = _descriptor.FieldDescriptor(
+  name='repeated_uint64_extension', full_name='protobuf_unittest.repeated_uint64_extension', index=29,
+  number=34, type=4, cpp_type=4, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_SINT32_EXTENSION_FIELD_NUMBER = 35
+repeated_sint32_extension = _descriptor.FieldDescriptor(
+  name='repeated_sint32_extension', full_name='protobuf_unittest.repeated_sint32_extension', index=30,
+  number=35, type=17, cpp_type=1, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_SINT64_EXTENSION_FIELD_NUMBER = 36
+repeated_sint64_extension = _descriptor.FieldDescriptor(
+  name='repeated_sint64_extension', full_name='protobuf_unittest.repeated_sint64_extension', index=31,
+  number=36, type=18, cpp_type=2, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_FIXED32_EXTENSION_FIELD_NUMBER = 37
+repeated_fixed32_extension = _descriptor.FieldDescriptor(
+  name='repeated_fixed32_extension', full_name='protobuf_unittest.repeated_fixed32_extension', index=32,
+  number=37, type=7, cpp_type=3, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_FIXED64_EXTENSION_FIELD_NUMBER = 38
+repeated_fixed64_extension = _descriptor.FieldDescriptor(
+  name='repeated_fixed64_extension', full_name='protobuf_unittest.repeated_fixed64_extension', index=33,
+  number=38, type=6, cpp_type=4, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_SFIXED32_EXTENSION_FIELD_NUMBER = 39
+repeated_sfixed32_extension = _descriptor.FieldDescriptor(
+  name='repeated_sfixed32_extension', full_name='protobuf_unittest.repeated_sfixed32_extension', index=34,
+  number=39, type=15, cpp_type=1, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_SFIXED64_EXTENSION_FIELD_NUMBER = 40
+repeated_sfixed64_extension = _descriptor.FieldDescriptor(
+  name='repeated_sfixed64_extension', full_name='protobuf_unittest.repeated_sfixed64_extension', index=35,
+  number=40, type=16, cpp_type=2, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_FLOAT_EXTENSION_FIELD_NUMBER = 41
+repeated_float_extension = _descriptor.FieldDescriptor(
+  name='repeated_float_extension', full_name='protobuf_unittest.repeated_float_extension', index=36,
+  number=41, type=2, cpp_type=6, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_DOUBLE_EXTENSION_FIELD_NUMBER = 42
+repeated_double_extension = _descriptor.FieldDescriptor(
+  name='repeated_double_extension', full_name='protobuf_unittest.repeated_double_extension', index=37,
+  number=42, type=1, cpp_type=5, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_BOOL_EXTENSION_FIELD_NUMBER = 43
+repeated_bool_extension = _descriptor.FieldDescriptor(
+  name='repeated_bool_extension', full_name='protobuf_unittest.repeated_bool_extension', index=38,
+  number=43, type=8, cpp_type=7, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_STRING_EXTENSION_FIELD_NUMBER = 44
+repeated_string_extension = _descriptor.FieldDescriptor(
+  name='repeated_string_extension', full_name='protobuf_unittest.repeated_string_extension', index=39,
+  number=44, type=9, cpp_type=9, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_BYTES_EXTENSION_FIELD_NUMBER = 45
+repeated_bytes_extension = _descriptor.FieldDescriptor(
+  name='repeated_bytes_extension', full_name='protobuf_unittest.repeated_bytes_extension', index=40,
+  number=45, type=12, cpp_type=9, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATEDGROUP_EXTENSION_FIELD_NUMBER = 46
+repeatedgroup_extension = _descriptor.FieldDescriptor(
+  name='repeatedgroup_extension', full_name='protobuf_unittest.repeatedgroup_extension', index=41,
+  number=46, type=10, cpp_type=10, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER = 48
+repeated_nested_message_extension = _descriptor.FieldDescriptor(
+  name='repeated_nested_message_extension', full_name='protobuf_unittest.repeated_nested_message_extension', index=42,
+  number=48, type=11, cpp_type=10, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_FOREIGN_MESSAGE_EXTENSION_FIELD_NUMBER = 49
+repeated_foreign_message_extension = _descriptor.FieldDescriptor(
+  name='repeated_foreign_message_extension', full_name='protobuf_unittest.repeated_foreign_message_extension', index=43,
+  number=49, type=11, cpp_type=10, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_IMPORT_MESSAGE_EXTENSION_FIELD_NUMBER = 50
+repeated_import_message_extension = _descriptor.FieldDescriptor(
+  name='repeated_import_message_extension', full_name='protobuf_unittest.repeated_import_message_extension', index=44,
+  number=50, type=11, cpp_type=10, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER = 51
+repeated_nested_enum_extension = _descriptor.FieldDescriptor(
+  name='repeated_nested_enum_extension', full_name='protobuf_unittest.repeated_nested_enum_extension', index=45,
+  number=51, type=14, cpp_type=8, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_FOREIGN_ENUM_EXTENSION_FIELD_NUMBER = 52
+repeated_foreign_enum_extension = _descriptor.FieldDescriptor(
+  name='repeated_foreign_enum_extension', full_name='protobuf_unittest.repeated_foreign_enum_extension', index=46,
+  number=52, type=14, cpp_type=8, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_IMPORT_ENUM_EXTENSION_FIELD_NUMBER = 53
+repeated_import_enum_extension = _descriptor.FieldDescriptor(
+  name='repeated_import_enum_extension', full_name='protobuf_unittest.repeated_import_enum_extension', index=47,
+  number=53, type=14, cpp_type=8, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+REPEATED_STRING_PIECE_EXTENSION_FIELD_NUMBER = 54
+repeated_string_piece_extension = _descriptor.FieldDescriptor(
+  name='repeated_string_piece_extension', full_name='protobuf_unittest.repeated_string_piece_extension', index=48,
+  number=54, type=9, cpp_type=9, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002')))
+REPEATED_CORD_EXTENSION_FIELD_NUMBER = 55
+repeated_cord_extension = _descriptor.FieldDescriptor(
+  name='repeated_cord_extension', full_name='protobuf_unittest.repeated_cord_extension', index=49,
+  number=55, type=9, cpp_type=9, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001')))
+REPEATED_LAZY_MESSAGE_EXTENSION_FIELD_NUMBER = 57
+repeated_lazy_message_extension = _descriptor.FieldDescriptor(
+  name='repeated_lazy_message_extension', full_name='protobuf_unittest.repeated_lazy_message_extension', index=50,
+  number=57, type=11, cpp_type=10, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001')))
+DEFAULT_INT32_EXTENSION_FIELD_NUMBER = 61
+default_int32_extension = _descriptor.FieldDescriptor(
+  name='default_int32_extension', full_name='protobuf_unittest.default_int32_extension', index=51,
+  number=61, type=5, cpp_type=1, label=1,
+  has_default_value=True, default_value=41,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_INT64_EXTENSION_FIELD_NUMBER = 62
+default_int64_extension = _descriptor.FieldDescriptor(
+  name='default_int64_extension', full_name='protobuf_unittest.default_int64_extension', index=52,
+  number=62, type=3, cpp_type=2, label=1,
+  has_default_value=True, default_value=42,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_UINT32_EXTENSION_FIELD_NUMBER = 63
+default_uint32_extension = _descriptor.FieldDescriptor(
+  name='default_uint32_extension', full_name='protobuf_unittest.default_uint32_extension', index=53,
+  number=63, type=13, cpp_type=3, label=1,
+  has_default_value=True, default_value=43,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_UINT64_EXTENSION_FIELD_NUMBER = 64
+default_uint64_extension = _descriptor.FieldDescriptor(
+  name='default_uint64_extension', full_name='protobuf_unittest.default_uint64_extension', index=54,
+  number=64, type=4, cpp_type=4, label=1,
+  has_default_value=True, default_value=44,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_SINT32_EXTENSION_FIELD_NUMBER = 65
+default_sint32_extension = _descriptor.FieldDescriptor(
+  name='default_sint32_extension', full_name='protobuf_unittest.default_sint32_extension', index=55,
+  number=65, type=17, cpp_type=1, label=1,
+  has_default_value=True, default_value=-45,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_SINT64_EXTENSION_FIELD_NUMBER = 66
+default_sint64_extension = _descriptor.FieldDescriptor(
+  name='default_sint64_extension', full_name='protobuf_unittest.default_sint64_extension', index=56,
+  number=66, type=18, cpp_type=2, label=1,
+  has_default_value=True, default_value=46,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_FIXED32_EXTENSION_FIELD_NUMBER = 67
+default_fixed32_extension = _descriptor.FieldDescriptor(
+  name='default_fixed32_extension', full_name='protobuf_unittest.default_fixed32_extension', index=57,
+  number=67, type=7, cpp_type=3, label=1,
+  has_default_value=True, default_value=47,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_FIXED64_EXTENSION_FIELD_NUMBER = 68
+default_fixed64_extension = _descriptor.FieldDescriptor(
+  name='default_fixed64_extension', full_name='protobuf_unittest.default_fixed64_extension', index=58,
+  number=68, type=6, cpp_type=4, label=1,
+  has_default_value=True, default_value=48,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_SFIXED32_EXTENSION_FIELD_NUMBER = 69
+default_sfixed32_extension = _descriptor.FieldDescriptor(
+  name='default_sfixed32_extension', full_name='protobuf_unittest.default_sfixed32_extension', index=59,
+  number=69, type=15, cpp_type=1, label=1,
+  has_default_value=True, default_value=49,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_SFIXED64_EXTENSION_FIELD_NUMBER = 70
+default_sfixed64_extension = _descriptor.FieldDescriptor(
+  name='default_sfixed64_extension', full_name='protobuf_unittest.default_sfixed64_extension', index=60,
+  number=70, type=16, cpp_type=2, label=1,
+  has_default_value=True, default_value=-50,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_FLOAT_EXTENSION_FIELD_NUMBER = 71
+default_float_extension = _descriptor.FieldDescriptor(
+  name='default_float_extension', full_name='protobuf_unittest.default_float_extension', index=61,
+  number=71, type=2, cpp_type=6, label=1,
+  has_default_value=True, default_value=float(51.5),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_DOUBLE_EXTENSION_FIELD_NUMBER = 72
+default_double_extension = _descriptor.FieldDescriptor(
+  name='default_double_extension', full_name='protobuf_unittest.default_double_extension', index=62,
+  number=72, type=1, cpp_type=5, label=1,
+  has_default_value=True, default_value=float(52000),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_BOOL_EXTENSION_FIELD_NUMBER = 73
+default_bool_extension = _descriptor.FieldDescriptor(
+  name='default_bool_extension', full_name='protobuf_unittest.default_bool_extension', index=63,
+  number=73, type=8, cpp_type=7, label=1,
+  has_default_value=True, default_value=True,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_STRING_EXTENSION_FIELD_NUMBER = 74
+default_string_extension = _descriptor.FieldDescriptor(
+  name='default_string_extension', full_name='protobuf_unittest.default_string_extension', index=64,
+  number=74, type=9, cpp_type=9, label=1,
+  has_default_value=True, default_value=_b("hello").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_BYTES_EXTENSION_FIELD_NUMBER = 75
+default_bytes_extension = _descriptor.FieldDescriptor(
+  name='default_bytes_extension', full_name='protobuf_unittest.default_bytes_extension', index=65,
+  number=75, type=12, cpp_type=9, label=1,
+  has_default_value=True, default_value=_b("world"),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_NESTED_ENUM_EXTENSION_FIELD_NUMBER = 81
+default_nested_enum_extension = _descriptor.FieldDescriptor(
+  name='default_nested_enum_extension', full_name='protobuf_unittest.default_nested_enum_extension', index=66,
+  number=81, type=14, cpp_type=8, label=1,
+  has_default_value=True, default_value=2,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_FOREIGN_ENUM_EXTENSION_FIELD_NUMBER = 82
+default_foreign_enum_extension = _descriptor.FieldDescriptor(
+  name='default_foreign_enum_extension', full_name='protobuf_unittest.default_foreign_enum_extension', index=67,
+  number=82, type=14, cpp_type=8, label=1,
+  has_default_value=True, default_value=5,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_IMPORT_ENUM_EXTENSION_FIELD_NUMBER = 83
+default_import_enum_extension = _descriptor.FieldDescriptor(
+  name='default_import_enum_extension', full_name='protobuf_unittest.default_import_enum_extension', index=68,
+  number=83, type=14, cpp_type=8, label=1,
+  has_default_value=True, default_value=8,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+DEFAULT_STRING_PIECE_EXTENSION_FIELD_NUMBER = 84
+default_string_piece_extension = _descriptor.FieldDescriptor(
+  name='default_string_piece_extension', full_name='protobuf_unittest.default_string_piece_extension', index=69,
+  number=84, type=9, cpp_type=9, label=1,
+  has_default_value=True, default_value=_b("abc").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002')))
+DEFAULT_CORD_EXTENSION_FIELD_NUMBER = 85
+default_cord_extension = _descriptor.FieldDescriptor(
+  name='default_cord_extension', full_name='protobuf_unittest.default_cord_extension', index=70,
+  number=85, type=9, cpp_type=9, label=1,
+  has_default_value=True, default_value=_b("123").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001')))
+ONEOF_UINT32_EXTENSION_FIELD_NUMBER = 111
+oneof_uint32_extension = _descriptor.FieldDescriptor(
+  name='oneof_uint32_extension', full_name='protobuf_unittest.oneof_uint32_extension', index=71,
+  number=111, type=13, cpp_type=3, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+ONEOF_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER = 112
+oneof_nested_message_extension = _descriptor.FieldDescriptor(
+  name='oneof_nested_message_extension', full_name='protobuf_unittest.oneof_nested_message_extension', index=72,
+  number=112, type=11, cpp_type=10, label=1,
+  has_default_value=False, default_value=None,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+ONEOF_STRING_EXTENSION_FIELD_NUMBER = 113
+oneof_string_extension = _descriptor.FieldDescriptor(
+  name='oneof_string_extension', full_name='protobuf_unittest.oneof_string_extension', index=73,
+  number=113, type=9, cpp_type=9, label=1,
+  has_default_value=False, default_value=_b("").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+ONEOF_BYTES_EXTENSION_FIELD_NUMBER = 114
+oneof_bytes_extension = _descriptor.FieldDescriptor(
+  name='oneof_bytes_extension', full_name='protobuf_unittest.oneof_bytes_extension', index=74,
+  number=114, type=12, cpp_type=9, label=1,
+  has_default_value=False, default_value=_b(""),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+MY_EXTENSION_STRING_FIELD_NUMBER = 50
+my_extension_string = _descriptor.FieldDescriptor(
+  name='my_extension_string', full_name='protobuf_unittest.my_extension_string', index=75,
+  number=50, type=9, cpp_type=9, label=1,
+  has_default_value=False, default_value=_b("").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+MY_EXTENSION_INT_FIELD_NUMBER = 5
+my_extension_int = _descriptor.FieldDescriptor(
+  name='my_extension_int', full_name='protobuf_unittest.my_extension_int', index=76,
+  number=5, type=5, cpp_type=1, label=1,
+  has_default_value=False, default_value=0,
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+PACKED_INT32_EXTENSION_FIELD_NUMBER = 90
+packed_int32_extension = _descriptor.FieldDescriptor(
+  name='packed_int32_extension', full_name='protobuf_unittest.packed_int32_extension', index=77,
+  number=90, type=5, cpp_type=1, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+PACKED_INT64_EXTENSION_FIELD_NUMBER = 91
+packed_int64_extension = _descriptor.FieldDescriptor(
+  name='packed_int64_extension', full_name='protobuf_unittest.packed_int64_extension', index=78,
+  number=91, type=3, cpp_type=2, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+PACKED_UINT32_EXTENSION_FIELD_NUMBER = 92
+packed_uint32_extension = _descriptor.FieldDescriptor(
+  name='packed_uint32_extension', full_name='protobuf_unittest.packed_uint32_extension', index=79,
+  number=92, type=13, cpp_type=3, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+PACKED_UINT64_EXTENSION_FIELD_NUMBER = 93
+packed_uint64_extension = _descriptor.FieldDescriptor(
+  name='packed_uint64_extension', full_name='protobuf_unittest.packed_uint64_extension', index=80,
+  number=93, type=4, cpp_type=4, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+PACKED_SINT32_EXTENSION_FIELD_NUMBER = 94
+packed_sint32_extension = _descriptor.FieldDescriptor(
+  name='packed_sint32_extension', full_name='protobuf_unittest.packed_sint32_extension', index=81,
+  number=94, type=17, cpp_type=1, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+PACKED_SINT64_EXTENSION_FIELD_NUMBER = 95
+packed_sint64_extension = _descriptor.FieldDescriptor(
+  name='packed_sint64_extension', full_name='protobuf_unittest.packed_sint64_extension', index=82,
+  number=95, type=18, cpp_type=2, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+PACKED_FIXED32_EXTENSION_FIELD_NUMBER = 96
+packed_fixed32_extension = _descriptor.FieldDescriptor(
+  name='packed_fixed32_extension', full_name='protobuf_unittest.packed_fixed32_extension', index=83,
+  number=96, type=7, cpp_type=3, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+PACKED_FIXED64_EXTENSION_FIELD_NUMBER = 97
+packed_fixed64_extension = _descriptor.FieldDescriptor(
+  name='packed_fixed64_extension', full_name='protobuf_unittest.packed_fixed64_extension', index=84,
+  number=97, type=6, cpp_type=4, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+PACKED_SFIXED32_EXTENSION_FIELD_NUMBER = 98
+packed_sfixed32_extension = _descriptor.FieldDescriptor(
+  name='packed_sfixed32_extension', full_name='protobuf_unittest.packed_sfixed32_extension', index=85,
+  number=98, type=15, cpp_type=1, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+PACKED_SFIXED64_EXTENSION_FIELD_NUMBER = 99
+packed_sfixed64_extension = _descriptor.FieldDescriptor(
+  name='packed_sfixed64_extension', full_name='protobuf_unittest.packed_sfixed64_extension', index=86,
+  number=99, type=16, cpp_type=2, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+PACKED_FLOAT_EXTENSION_FIELD_NUMBER = 100
+packed_float_extension = _descriptor.FieldDescriptor(
+  name='packed_float_extension', full_name='protobuf_unittest.packed_float_extension', index=87,
+  number=100, type=2, cpp_type=6, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+PACKED_DOUBLE_EXTENSION_FIELD_NUMBER = 101
+packed_double_extension = _descriptor.FieldDescriptor(
+  name='packed_double_extension', full_name='protobuf_unittest.packed_double_extension', index=88,
+  number=101, type=1, cpp_type=5, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+PACKED_BOOL_EXTENSION_FIELD_NUMBER = 102
+packed_bool_extension = _descriptor.FieldDescriptor(
+  name='packed_bool_extension', full_name='protobuf_unittest.packed_bool_extension', index=89,
+  number=102, type=8, cpp_type=7, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+PACKED_ENUM_EXTENSION_FIELD_NUMBER = 103
+packed_enum_extension = _descriptor.FieldDescriptor(
+  name='packed_enum_extension', full_name='protobuf_unittest.packed_enum_extension', index=90,
+  number=103, type=14, cpp_type=8, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001')))
+UNPACKED_INT32_EXTENSION_FIELD_NUMBER = 90
+unpacked_int32_extension = _descriptor.FieldDescriptor(
+  name='unpacked_int32_extension', full_name='protobuf_unittest.unpacked_int32_extension', index=91,
+  number=90, type=5, cpp_type=1, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+UNPACKED_INT64_EXTENSION_FIELD_NUMBER = 91
+unpacked_int64_extension = _descriptor.FieldDescriptor(
+  name='unpacked_int64_extension', full_name='protobuf_unittest.unpacked_int64_extension', index=92,
+  number=91, type=3, cpp_type=2, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+UNPACKED_UINT32_EXTENSION_FIELD_NUMBER = 92
+unpacked_uint32_extension = _descriptor.FieldDescriptor(
+  name='unpacked_uint32_extension', full_name='protobuf_unittest.unpacked_uint32_extension', index=93,
+  number=92, type=13, cpp_type=3, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+UNPACKED_UINT64_EXTENSION_FIELD_NUMBER = 93
+unpacked_uint64_extension = _descriptor.FieldDescriptor(
+  name='unpacked_uint64_extension', full_name='protobuf_unittest.unpacked_uint64_extension', index=94,
+  number=93, type=4, cpp_type=4, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+UNPACKED_SINT32_EXTENSION_FIELD_NUMBER = 94
+unpacked_sint32_extension = _descriptor.FieldDescriptor(
+  name='unpacked_sint32_extension', full_name='protobuf_unittest.unpacked_sint32_extension', index=95,
+  number=94, type=17, cpp_type=1, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+UNPACKED_SINT64_EXTENSION_FIELD_NUMBER = 95
+unpacked_sint64_extension = _descriptor.FieldDescriptor(
+  name='unpacked_sint64_extension', full_name='protobuf_unittest.unpacked_sint64_extension', index=96,
+  number=95, type=18, cpp_type=2, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+UNPACKED_FIXED32_EXTENSION_FIELD_NUMBER = 96
+unpacked_fixed32_extension = _descriptor.FieldDescriptor(
+  name='unpacked_fixed32_extension', full_name='protobuf_unittest.unpacked_fixed32_extension', index=97,
+  number=96, type=7, cpp_type=3, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+UNPACKED_FIXED64_EXTENSION_FIELD_NUMBER = 97
+unpacked_fixed64_extension = _descriptor.FieldDescriptor(
+  name='unpacked_fixed64_extension', full_name='protobuf_unittest.unpacked_fixed64_extension', index=98,
+  number=97, type=6, cpp_type=4, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+UNPACKED_SFIXED32_EXTENSION_FIELD_NUMBER = 98
+unpacked_sfixed32_extension = _descriptor.FieldDescriptor(
+  name='unpacked_sfixed32_extension', full_name='protobuf_unittest.unpacked_sfixed32_extension', index=99,
+  number=98, type=15, cpp_type=1, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+UNPACKED_SFIXED64_EXTENSION_FIELD_NUMBER = 99
+unpacked_sfixed64_extension = _descriptor.FieldDescriptor(
+  name='unpacked_sfixed64_extension', full_name='protobuf_unittest.unpacked_sfixed64_extension', index=100,
+  number=99, type=16, cpp_type=2, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+UNPACKED_FLOAT_EXTENSION_FIELD_NUMBER = 100
+unpacked_float_extension = _descriptor.FieldDescriptor(
+  name='unpacked_float_extension', full_name='protobuf_unittest.unpacked_float_extension', index=101,
+  number=100, type=2, cpp_type=6, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+UNPACKED_DOUBLE_EXTENSION_FIELD_NUMBER = 101
+unpacked_double_extension = _descriptor.FieldDescriptor(
+  name='unpacked_double_extension', full_name='protobuf_unittest.unpacked_double_extension', index=102,
+  number=101, type=1, cpp_type=5, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+UNPACKED_BOOL_EXTENSION_FIELD_NUMBER = 102
+unpacked_bool_extension = _descriptor.FieldDescriptor(
+  name='unpacked_bool_extension', full_name='protobuf_unittest.unpacked_bool_extension', index=103,
+  number=102, type=8, cpp_type=7, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+UNPACKED_ENUM_EXTENSION_FIELD_NUMBER = 103
+unpacked_enum_extension = _descriptor.FieldDescriptor(
+  name='unpacked_enum_extension', full_name='protobuf_unittest.unpacked_enum_extension', index=104,
+  number=103, type=14, cpp_type=8, label=3,
+  has_default_value=False, default_value=[],
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000')))
+
+_TESTALLTYPES_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='protobuf_unittest.TestAllTypes.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='FOO', index=0, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAR', index=1, number=2,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAZ', index=2, number=3,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='NEG', index=3, number=-1,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=3202,
+  serialized_end=3259,
+)
+_sym_db.RegisterEnumDescriptor(_TESTALLTYPES_NESTEDENUM)
+
+_TESTONEOF2_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='protobuf_unittest.TestOneof2.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='FOO', index=0, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAR', index=1, number=2,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAZ', index=2, number=3,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=3202,
+  serialized_end=3241,
+)
+_sym_db.RegisterEnumDescriptor(_TESTONEOF2_NESTEDENUM)
+
+_TESTDYNAMICEXTENSIONS_DYNAMICENUMTYPE = _descriptor.EnumDescriptor(
+  name='DynamicEnumType',
+  full_name='protobuf_unittest.TestDynamicExtensions.DynamicEnumType',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DYNAMIC_FOO', index=0, number=2200,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='DYNAMIC_BAR', index=1, number=2201,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='DYNAMIC_BAZ', index=2, number=2202,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=10735,
+  serialized_end=10806,
+)
+_sym_db.RegisterEnumDescriptor(_TESTDYNAMICEXTENSIONS_DYNAMICENUMTYPE)
+
+
+_TESTALLTYPES_NESTEDMESSAGE = _descriptor.Descriptor(
+  name='NestedMessage',
+  full_name='protobuf_unittest.TestAllTypes.NestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='bb', full_name='protobuf_unittest.TestAllTypes.NestedMessage.bb', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3117,
+  serialized_end=3144,
+)
+
+_TESTALLTYPES_OPTIONALGROUP = _descriptor.Descriptor(
+  name='OptionalGroup',
+  full_name='protobuf_unittest.TestAllTypes.OptionalGroup',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestAllTypes.OptionalGroup.a', index=0,
+      number=17, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3146,
+  serialized_end=3172,
+)
+
+_TESTALLTYPES_REPEATEDGROUP = _descriptor.Descriptor(
+  name='RepeatedGroup',
+  full_name='protobuf_unittest.TestAllTypes.RepeatedGroup',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestAllTypes.RepeatedGroup.a', index=0,
+      number=47, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3174,
+  serialized_end=3200,
+)
+
+_TESTALLTYPES = _descriptor.Descriptor(
+  name='TestAllTypes',
+  full_name='protobuf_unittest.TestAllTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='optional_int32', full_name='protobuf_unittest.TestAllTypes.optional_int32', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_int64', full_name='protobuf_unittest.TestAllTypes.optional_int64', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_uint32', full_name='protobuf_unittest.TestAllTypes.optional_uint32', index=2,
+      number=3, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_uint64', full_name='protobuf_unittest.TestAllTypes.optional_uint64', index=3,
+      number=4, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_sint32', full_name='protobuf_unittest.TestAllTypes.optional_sint32', index=4,
+      number=5, type=17, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_sint64', full_name='protobuf_unittest.TestAllTypes.optional_sint64', index=5,
+      number=6, type=18, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_fixed32', full_name='protobuf_unittest.TestAllTypes.optional_fixed32', index=6,
+      number=7, type=7, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_fixed64', full_name='protobuf_unittest.TestAllTypes.optional_fixed64', index=7,
+      number=8, type=6, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_sfixed32', full_name='protobuf_unittest.TestAllTypes.optional_sfixed32', index=8,
+      number=9, type=15, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_sfixed64', full_name='protobuf_unittest.TestAllTypes.optional_sfixed64', index=9,
+      number=10, type=16, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_float', full_name='protobuf_unittest.TestAllTypes.optional_float', index=10,
+      number=11, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_double', full_name='protobuf_unittest.TestAllTypes.optional_double', index=11,
+      number=12, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_bool', full_name='protobuf_unittest.TestAllTypes.optional_bool', index=12,
+      number=13, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_string', full_name='protobuf_unittest.TestAllTypes.optional_string', index=13,
+      number=14, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_bytes', full_name='protobuf_unittest.TestAllTypes.optional_bytes', index=14,
+      number=15, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optionalgroup', full_name='protobuf_unittest.TestAllTypes.optionalgroup', index=15,
+      number=16, type=10, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_nested_message', full_name='protobuf_unittest.TestAllTypes.optional_nested_message', index=16,
+      number=18, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_foreign_message', full_name='protobuf_unittest.TestAllTypes.optional_foreign_message', index=17,
+      number=19, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_import_message', full_name='protobuf_unittest.TestAllTypes.optional_import_message', index=18,
+      number=20, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_nested_enum', full_name='protobuf_unittest.TestAllTypes.optional_nested_enum', index=19,
+      number=21, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=1,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_foreign_enum', full_name='protobuf_unittest.TestAllTypes.optional_foreign_enum', index=20,
+      number=22, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=4,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_import_enum', full_name='protobuf_unittest.TestAllTypes.optional_import_enum', index=21,
+      number=23, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=7,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_string_piece', full_name='protobuf_unittest.TestAllTypes.optional_string_piece', index=22,
+      number=24, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))),
+    _descriptor.FieldDescriptor(
+      name='optional_cord', full_name='protobuf_unittest.TestAllTypes.optional_cord', index=23,
+      number=25, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))),
+    _descriptor.FieldDescriptor(
+      name='optional_public_import_message', full_name='protobuf_unittest.TestAllTypes.optional_public_import_message', index=24,
+      number=26, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_lazy_message', full_name='protobuf_unittest.TestAllTypes.optional_lazy_message', index=25,
+      number=27, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_int32', full_name='protobuf_unittest.TestAllTypes.repeated_int32', index=26,
+      number=31, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_int64', full_name='protobuf_unittest.TestAllTypes.repeated_int64', index=27,
+      number=32, type=3, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint32', full_name='protobuf_unittest.TestAllTypes.repeated_uint32', index=28,
+      number=33, type=13, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint64', full_name='protobuf_unittest.TestAllTypes.repeated_uint64', index=29,
+      number=34, type=4, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sint32', full_name='protobuf_unittest.TestAllTypes.repeated_sint32', index=30,
+      number=35, type=17, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sint64', full_name='protobuf_unittest.TestAllTypes.repeated_sint64', index=31,
+      number=36, type=18, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed32', full_name='protobuf_unittest.TestAllTypes.repeated_fixed32', index=32,
+      number=37, type=7, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed64', full_name='protobuf_unittest.TestAllTypes.repeated_fixed64', index=33,
+      number=38, type=6, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sfixed32', full_name='protobuf_unittest.TestAllTypes.repeated_sfixed32', index=34,
+      number=39, type=15, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sfixed64', full_name='protobuf_unittest.TestAllTypes.repeated_sfixed64', index=35,
+      number=40, type=16, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_float', full_name='protobuf_unittest.TestAllTypes.repeated_float', index=36,
+      number=41, type=2, cpp_type=6, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_double', full_name='protobuf_unittest.TestAllTypes.repeated_double', index=37,
+      number=42, type=1, cpp_type=5, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_bool', full_name='protobuf_unittest.TestAllTypes.repeated_bool', index=38,
+      number=43, type=8, cpp_type=7, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_string', full_name='protobuf_unittest.TestAllTypes.repeated_string', index=39,
+      number=44, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_bytes', full_name='protobuf_unittest.TestAllTypes.repeated_bytes', index=40,
+      number=45, type=12, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeatedgroup', full_name='protobuf_unittest.TestAllTypes.repeatedgroup', index=41,
+      number=46, type=10, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_nested_message', full_name='protobuf_unittest.TestAllTypes.repeated_nested_message', index=42,
+      number=48, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_foreign_message', full_name='protobuf_unittest.TestAllTypes.repeated_foreign_message', index=43,
+      number=49, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_import_message', full_name='protobuf_unittest.TestAllTypes.repeated_import_message', index=44,
+      number=50, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_nested_enum', full_name='protobuf_unittest.TestAllTypes.repeated_nested_enum', index=45,
+      number=51, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_foreign_enum', full_name='protobuf_unittest.TestAllTypes.repeated_foreign_enum', index=46,
+      number=52, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_import_enum', full_name='protobuf_unittest.TestAllTypes.repeated_import_enum', index=47,
+      number=53, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_string_piece', full_name='protobuf_unittest.TestAllTypes.repeated_string_piece', index=48,
+      number=54, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_cord', full_name='protobuf_unittest.TestAllTypes.repeated_cord', index=49,
+      number=55, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_lazy_message', full_name='protobuf_unittest.TestAllTypes.repeated_lazy_message', index=50,
+      number=57, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))),
+    _descriptor.FieldDescriptor(
+      name='default_int32', full_name='protobuf_unittest.TestAllTypes.default_int32', index=51,
+      number=61, type=5, cpp_type=1, label=1,
+      has_default_value=True, default_value=41,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_int64', full_name='protobuf_unittest.TestAllTypes.default_int64', index=52,
+      number=62, type=3, cpp_type=2, label=1,
+      has_default_value=True, default_value=42,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_uint32', full_name='protobuf_unittest.TestAllTypes.default_uint32', index=53,
+      number=63, type=13, cpp_type=3, label=1,
+      has_default_value=True, default_value=43,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_uint64', full_name='protobuf_unittest.TestAllTypes.default_uint64', index=54,
+      number=64, type=4, cpp_type=4, label=1,
+      has_default_value=True, default_value=44,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_sint32', full_name='protobuf_unittest.TestAllTypes.default_sint32', index=55,
+      number=65, type=17, cpp_type=1, label=1,
+      has_default_value=True, default_value=-45,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_sint64', full_name='protobuf_unittest.TestAllTypes.default_sint64', index=56,
+      number=66, type=18, cpp_type=2, label=1,
+      has_default_value=True, default_value=46,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_fixed32', full_name='protobuf_unittest.TestAllTypes.default_fixed32', index=57,
+      number=67, type=7, cpp_type=3, label=1,
+      has_default_value=True, default_value=47,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_fixed64', full_name='protobuf_unittest.TestAllTypes.default_fixed64', index=58,
+      number=68, type=6, cpp_type=4, label=1,
+      has_default_value=True, default_value=48,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_sfixed32', full_name='protobuf_unittest.TestAllTypes.default_sfixed32', index=59,
+      number=69, type=15, cpp_type=1, label=1,
+      has_default_value=True, default_value=49,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_sfixed64', full_name='protobuf_unittest.TestAllTypes.default_sfixed64', index=60,
+      number=70, type=16, cpp_type=2, label=1,
+      has_default_value=True, default_value=-50,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_float', full_name='protobuf_unittest.TestAllTypes.default_float', index=61,
+      number=71, type=2, cpp_type=6, label=1,
+      has_default_value=True, default_value=float(51.5),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_double', full_name='protobuf_unittest.TestAllTypes.default_double', index=62,
+      number=72, type=1, cpp_type=5, label=1,
+      has_default_value=True, default_value=float(52000),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_bool', full_name='protobuf_unittest.TestAllTypes.default_bool', index=63,
+      number=73, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=True,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_string', full_name='protobuf_unittest.TestAllTypes.default_string', index=64,
+      number=74, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("hello").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_bytes', full_name='protobuf_unittest.TestAllTypes.default_bytes', index=65,
+      number=75, type=12, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("world"),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_nested_enum', full_name='protobuf_unittest.TestAllTypes.default_nested_enum', index=66,
+      number=81, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=2,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_foreign_enum', full_name='protobuf_unittest.TestAllTypes.default_foreign_enum', index=67,
+      number=82, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=5,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_import_enum', full_name='protobuf_unittest.TestAllTypes.default_import_enum', index=68,
+      number=83, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=8,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='default_string_piece', full_name='protobuf_unittest.TestAllTypes.default_string_piece', index=69,
+      number=84, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("abc").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))),
+    _descriptor.FieldDescriptor(
+      name='default_cord', full_name='protobuf_unittest.TestAllTypes.default_cord', index=70,
+      number=85, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("123").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))),
+    _descriptor.FieldDescriptor(
+      name='oneof_uint32', full_name='protobuf_unittest.TestAllTypes.oneof_uint32', index=71,
+      number=111, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_nested_message', full_name='protobuf_unittest.TestAllTypes.oneof_nested_message', index=72,
+      number=112, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_string', full_name='protobuf_unittest.TestAllTypes.oneof_string', index=73,
+      number=113, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_bytes', full_name='protobuf_unittest.TestAllTypes.oneof_bytes', index=74,
+      number=114, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTALLTYPES_NESTEDMESSAGE, _TESTALLTYPES_OPTIONALGROUP, _TESTALLTYPES_REPEATEDGROUP, ],
+  enum_types=[
+    _TESTALLTYPES_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='oneof_field', full_name='protobuf_unittest.TestAllTypes.oneof_field',
+      index=0, containing_type=None, fields=[]),
+  ],
+  serialized_start=93,
+  serialized_end=3274,
+)
+
+
+_NESTEDTESTALLTYPES = _descriptor.Descriptor(
+  name='NestedTestAllTypes',
+  full_name='protobuf_unittest.NestedTestAllTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='child', full_name='protobuf_unittest.NestedTestAllTypes.child', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='payload', full_name='protobuf_unittest.NestedTestAllTypes.payload', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_child', full_name='protobuf_unittest.NestedTestAllTypes.repeated_child', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3277,
+  serialized_end=3464,
+)
+
+
+_TESTDEPRECATEDFIELDS = _descriptor.Descriptor(
+  name='TestDeprecatedFields',
+  full_name='protobuf_unittest.TestDeprecatedFields',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='deprecated_int32', full_name='protobuf_unittest.TestDeprecatedFields.deprecated_int32', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3466,
+  serialized_end=3518,
+)
+
+
+_FOREIGNMESSAGE = _descriptor.Descriptor(
+  name='ForeignMessage',
+  full_name='protobuf_unittest.ForeignMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='c', full_name='protobuf_unittest.ForeignMessage.c', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='d', full_name='protobuf_unittest.ForeignMessage.d', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3520,
+  serialized_end=3558,
+)
+
+
+_TESTRESERVEDFIELDS = _descriptor.Descriptor(
+  name='TestReservedFields',
+  full_name='protobuf_unittest.TestReservedFields',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3560,
+  serialized_end=3608,
+)
+
+
+_TESTALLEXTENSIONS = _descriptor.Descriptor(
+  name='TestAllExtensions',
+  full_name='protobuf_unittest.TestAllExtensions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(1, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=3610,
+  serialized_end=3639,
+)
+
+
+_OPTIONALGROUP_EXTENSION = _descriptor.Descriptor(
+  name='OptionalGroup_extension',
+  full_name='protobuf_unittest.OptionalGroup_extension',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.OptionalGroup_extension.a', index=0,
+      number=17, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3641,
+  serialized_end=3677,
+)
+
+
+_REPEATEDGROUP_EXTENSION = _descriptor.Descriptor(
+  name='RepeatedGroup_extension',
+  full_name='protobuf_unittest.RepeatedGroup_extension',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.RepeatedGroup_extension.a', index=0,
+      number=47, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3679,
+  serialized_end=3715,
+)
+
+
+_TESTNESTEDEXTENSION = _descriptor.Descriptor(
+  name='TestNestedExtension',
+  full_name='protobuf_unittest.TestNestedExtension',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+    _descriptor.FieldDescriptor(
+      name='test', full_name='protobuf_unittest.TestNestedExtension.test', index=0,
+      number=1002, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("test").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nested_string_extension', full_name='protobuf_unittest.TestNestedExtension.nested_string_extension', index=1,
+      number=1003, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3718,
+  serialized_end=3870,
+)
+
+
+_TESTREQUIRED = _descriptor.Descriptor(
+  name='TestRequired',
+  full_name='protobuf_unittest.TestRequired',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestRequired.a', index=0,
+      number=1, type=5, cpp_type=1, label=2,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy2', full_name='protobuf_unittest.TestRequired.dummy2', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='b', full_name='protobuf_unittest.TestRequired.b', index=2,
+      number=3, type=5, cpp_type=1, label=2,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy4', full_name='protobuf_unittest.TestRequired.dummy4', index=3,
+      number=4, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy5', full_name='protobuf_unittest.TestRequired.dummy5', index=4,
+      number=5, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy6', full_name='protobuf_unittest.TestRequired.dummy6', index=5,
+      number=6, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy7', full_name='protobuf_unittest.TestRequired.dummy7', index=6,
+      number=7, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy8', full_name='protobuf_unittest.TestRequired.dummy8', index=7,
+      number=8, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy9', full_name='protobuf_unittest.TestRequired.dummy9', index=8,
+      number=9, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy10', full_name='protobuf_unittest.TestRequired.dummy10', index=9,
+      number=10, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy11', full_name='protobuf_unittest.TestRequired.dummy11', index=10,
+      number=11, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy12', full_name='protobuf_unittest.TestRequired.dummy12', index=11,
+      number=12, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy13', full_name='protobuf_unittest.TestRequired.dummy13', index=12,
+      number=13, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy14', full_name='protobuf_unittest.TestRequired.dummy14', index=13,
+      number=14, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy15', full_name='protobuf_unittest.TestRequired.dummy15', index=14,
+      number=15, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy16', full_name='protobuf_unittest.TestRequired.dummy16', index=15,
+      number=16, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy17', full_name='protobuf_unittest.TestRequired.dummy17', index=16,
+      number=17, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy18', full_name='protobuf_unittest.TestRequired.dummy18', index=17,
+      number=18, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy19', full_name='protobuf_unittest.TestRequired.dummy19', index=18,
+      number=19, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy20', full_name='protobuf_unittest.TestRequired.dummy20', index=19,
+      number=20, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy21', full_name='protobuf_unittest.TestRequired.dummy21', index=20,
+      number=21, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy22', full_name='protobuf_unittest.TestRequired.dummy22', index=21,
+      number=22, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy23', full_name='protobuf_unittest.TestRequired.dummy23', index=22,
+      number=23, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy24', full_name='protobuf_unittest.TestRequired.dummy24', index=23,
+      number=24, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy25', full_name='protobuf_unittest.TestRequired.dummy25', index=24,
+      number=25, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy26', full_name='protobuf_unittest.TestRequired.dummy26', index=25,
+      number=26, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy27', full_name='protobuf_unittest.TestRequired.dummy27', index=26,
+      number=27, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy28', full_name='protobuf_unittest.TestRequired.dummy28', index=27,
+      number=28, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy29', full_name='protobuf_unittest.TestRequired.dummy29', index=28,
+      number=29, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy30', full_name='protobuf_unittest.TestRequired.dummy30', index=29,
+      number=30, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy31', full_name='protobuf_unittest.TestRequired.dummy31', index=30,
+      number=31, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy32', full_name='protobuf_unittest.TestRequired.dummy32', index=31,
+      number=32, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='c', full_name='protobuf_unittest.TestRequired.c', index=32,
+      number=33, type=5, cpp_type=1, label=2,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+    _descriptor.FieldDescriptor(
+      name='single', full_name='protobuf_unittest.TestRequired.single', index=0,
+      number=1000, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='multi', full_name='protobuf_unittest.TestRequired.multi', index=1,
+      number=1001, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3873,
+  serialized_end=4598,
+)
+
+
+_TESTREQUIREDFOREIGN = _descriptor.Descriptor(
+  name='TestRequiredForeign',
+  full_name='protobuf_unittest.TestRequiredForeign',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='optional_message', full_name='protobuf_unittest.TestRequiredForeign.optional_message', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_message', full_name='protobuf_unittest.TestRequiredForeign.repeated_message', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dummy', full_name='protobuf_unittest.TestRequiredForeign.dummy', index=2,
+      number=3, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4601,
+  serialized_end=4755,
+)
+
+
+_TESTFOREIGNNESTED = _descriptor.Descriptor(
+  name='TestForeignNested',
+  full_name='protobuf_unittest.TestForeignNested',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='foreign_nested', full_name='protobuf_unittest.TestForeignNested.foreign_nested', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4757,
+  serialized_end=4847,
+)
+
+
+_TESTEMPTYMESSAGE = _descriptor.Descriptor(
+  name='TestEmptyMessage',
+  full_name='protobuf_unittest.TestEmptyMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4849,
+  serialized_end=4867,
+)
+
+
+_TESTEMPTYMESSAGEWITHEXTENSIONS = _descriptor.Descriptor(
+  name='TestEmptyMessageWithExtensions',
+  full_name='protobuf_unittest.TestEmptyMessageWithExtensions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(1, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=4869,
+  serialized_end=4911,
+)
+
+
+_TESTMULTIPLEEXTENSIONRANGES = _descriptor.Descriptor(
+  name='TestMultipleExtensionRanges',
+  full_name='protobuf_unittest.TestMultipleExtensionRanges',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(42, 43), (4143, 4244), (65536, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=4913,
+  serialized_end=4968,
+)
+
+
+_TESTREALLYLARGETAGNUMBER = _descriptor.Descriptor(
+  name='TestReallyLargeTagNumber',
+  full_name='protobuf_unittest.TestReallyLargeTagNumber',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestReallyLargeTagNumber.a', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bb', full_name='protobuf_unittest.TestReallyLargeTagNumber.bb', index=1,
+      number=268435455, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4970,
+  serialized_end=5022,
+)
+
+
+_TESTRECURSIVEMESSAGE = _descriptor.Descriptor(
+  name='TestRecursiveMessage',
+  full_name='protobuf_unittest.TestRecursiveMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestRecursiveMessage.a', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='i', full_name='protobuf_unittest.TestRecursiveMessage.i', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5024,
+  serialized_end=5109,
+)
+
+
+_TESTMUTUALRECURSIONA = _descriptor.Descriptor(
+  name='TestMutualRecursionA',
+  full_name='protobuf_unittest.TestMutualRecursionA',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='bb', full_name='protobuf_unittest.TestMutualRecursionA.bb', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5111,
+  serialized_end=5186,
+)
+
+
+_TESTMUTUALRECURSIONB = _descriptor.Descriptor(
+  name='TestMutualRecursionB',
+  full_name='protobuf_unittest.TestMutualRecursionB',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestMutualRecursionB.a', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_int32', full_name='protobuf_unittest.TestMutualRecursionB.optional_int32', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5188,
+  serialized_end=5286,
+)
+
+
+_TESTDUPFIELDNUMBER_FOO = _descriptor.Descriptor(
+  name='Foo',
+  full_name='protobuf_unittest.TestDupFieldNumber.Foo',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestDupFieldNumber.Foo.a', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5434,
+  serialized_end=5450,
+)
+
+_TESTDUPFIELDNUMBER_BAR = _descriptor.Descriptor(
+  name='Bar',
+  full_name='protobuf_unittest.TestDupFieldNumber.Bar',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestDupFieldNumber.Bar.a', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5452,
+  serialized_end=5468,
+)
+
+_TESTDUPFIELDNUMBER = _descriptor.Descriptor(
+  name='TestDupFieldNumber',
+  full_name='protobuf_unittest.TestDupFieldNumber',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestDupFieldNumber.a', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo', full_name='protobuf_unittest.TestDupFieldNumber.foo', index=1,
+      number=2, type=10, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bar', full_name='protobuf_unittest.TestDupFieldNumber.bar', index=2,
+      number=3, type=10, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTDUPFIELDNUMBER_FOO, _TESTDUPFIELDNUMBER_BAR, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5289,
+  serialized_end=5468,
+)
+
+
+_TESTEAGERMESSAGE = _descriptor.Descriptor(
+  name='TestEagerMessage',
+  full_name='protobuf_unittest.TestEagerMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='sub_message', full_name='protobuf_unittest.TestEagerMessage.sub_message', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\000'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5470,
+  serialized_end=5546,
+)
+
+
+_TESTLAZYMESSAGE = _descriptor.Descriptor(
+  name='TestLazyMessage',
+  full_name='protobuf_unittest.TestLazyMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='sub_message', full_name='protobuf_unittest.TestLazyMessage.sub_message', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5548,
+  serialized_end=5623,
+)
+
+
+_TESTNESTEDMESSAGEHASBITS_NESTEDMESSAGE = _descriptor.Descriptor(
+  name='NestedMessage',
+  full_name='protobuf_unittest.TestNestedMessageHasBits.NestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='nestedmessage_repeated_int32', full_name='protobuf_unittest.TestNestedMessageHasBits.NestedMessage.nestedmessage_repeated_int32', index=0,
+      number=1, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nestedmessage_repeated_foreignmessage', full_name='protobuf_unittest.TestNestedMessageHasBits.NestedMessage.nestedmessage_repeated_foreignmessage', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5747,
+  serialized_end=5882,
+)
+
+_TESTNESTEDMESSAGEHASBITS = _descriptor.Descriptor(
+  name='TestNestedMessageHasBits',
+  full_name='protobuf_unittest.TestNestedMessageHasBits',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='optional_nested_message', full_name='protobuf_unittest.TestNestedMessageHasBits.optional_nested_message', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTNESTEDMESSAGEHASBITS_NESTEDMESSAGE, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5626,
+  serialized_end=5882,
+)
+
+
+_TESTCAMELCASEFIELDNAMES = _descriptor.Descriptor(
+  name='TestCamelCaseFieldNames',
+  full_name='protobuf_unittest.TestCamelCaseFieldNames',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='PrimitiveField', full_name='protobuf_unittest.TestCamelCaseFieldNames.PrimitiveField', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='StringField', full_name='protobuf_unittest.TestCamelCaseFieldNames.StringField', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='EnumField', full_name='protobuf_unittest.TestCamelCaseFieldNames.EnumField', index=2,
+      number=3, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=4,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='MessageField', full_name='protobuf_unittest.TestCamelCaseFieldNames.MessageField', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='StringPieceField', full_name='protobuf_unittest.TestCamelCaseFieldNames.StringPieceField', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))),
+    _descriptor.FieldDescriptor(
+      name='CordField', full_name='protobuf_unittest.TestCamelCaseFieldNames.CordField', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))),
+    _descriptor.FieldDescriptor(
+      name='RepeatedPrimitiveField', full_name='protobuf_unittest.TestCamelCaseFieldNames.RepeatedPrimitiveField', index=6,
+      number=7, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='RepeatedStringField', full_name='protobuf_unittest.TestCamelCaseFieldNames.RepeatedStringField', index=7,
+      number=8, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='RepeatedEnumField', full_name='protobuf_unittest.TestCamelCaseFieldNames.RepeatedEnumField', index=8,
+      number=9, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='RepeatedMessageField', full_name='protobuf_unittest.TestCamelCaseFieldNames.RepeatedMessageField', index=9,
+      number=10, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='RepeatedStringPieceField', full_name='protobuf_unittest.TestCamelCaseFieldNames.RepeatedStringPieceField', index=10,
+      number=11, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))),
+    _descriptor.FieldDescriptor(
+      name='RepeatedCordField', full_name='protobuf_unittest.TestCamelCaseFieldNames.RepeatedCordField', index=11,
+      number=12, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=5885,
+  serialized_end=6370,
+)
+
+
+_TESTFIELDORDERINGS_NESTEDMESSAGE = _descriptor.Descriptor(
+  name='NestedMessage',
+  full_name='protobuf_unittest.TestFieldOrderings.NestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='oo', full_name='protobuf_unittest.TestFieldOrderings.NestedMessage.oo', index=0,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bb', full_name='protobuf_unittest.TestFieldOrderings.NestedMessage.bb', index=1,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=6535,
+  serialized_end=6574,
+)
+
+_TESTFIELDORDERINGS = _descriptor.Descriptor(
+  name='TestFieldOrderings',
+  full_name='protobuf_unittest.TestFieldOrderings',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='my_string', full_name='protobuf_unittest.TestFieldOrderings.my_string', index=0,
+      number=11, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='my_int', full_name='protobuf_unittest.TestFieldOrderings.my_int', index=1,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='my_float', full_name='protobuf_unittest.TestFieldOrderings.my_float', index=2,
+      number=101, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_nested_message', full_name='protobuf_unittest.TestFieldOrderings.optional_nested_message', index=3,
+      number=200, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTFIELDORDERINGS_NESTEDMESSAGE, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(2, 11), (12, 101), ],
+  oneofs=[
+  ],
+  serialized_start=6373,
+  serialized_end=6586,
+)
+
+
+_TESTEXTREMEDEFAULTVALUES = _descriptor.Descriptor(
+  name='TestExtremeDefaultValues',
+  full_name='protobuf_unittest.TestExtremeDefaultValues',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='escaped_bytes', full_name='protobuf_unittest.TestExtremeDefaultValues.escaped_bytes', index=0,
+      number=1, type=12, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("\000\001\007\010\014\n\r\t\013\\\'\"\376"),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='large_uint32', full_name='protobuf_unittest.TestExtremeDefaultValues.large_uint32', index=1,
+      number=2, type=13, cpp_type=3, label=1,
+      has_default_value=True, default_value=4294967295,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='large_uint64', full_name='protobuf_unittest.TestExtremeDefaultValues.large_uint64', index=2,
+      number=3, type=4, cpp_type=4, label=1,
+      has_default_value=True, default_value=18446744073709551615,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='small_int32', full_name='protobuf_unittest.TestExtremeDefaultValues.small_int32', index=3,
+      number=4, type=5, cpp_type=1, label=1,
+      has_default_value=True, default_value=-2147483647,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='small_int64', full_name='protobuf_unittest.TestExtremeDefaultValues.small_int64', index=4,
+      number=5, type=3, cpp_type=2, label=1,
+      has_default_value=True, default_value=-9223372036854775807,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='really_small_int32', full_name='protobuf_unittest.TestExtremeDefaultValues.really_small_int32', index=5,
+      number=21, type=5, cpp_type=1, label=1,
+      has_default_value=True, default_value=-2147483648,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='really_small_int64', full_name='protobuf_unittest.TestExtremeDefaultValues.really_small_int64', index=6,
+      number=22, type=3, cpp_type=2, label=1,
+      has_default_value=True, default_value=-9223372036854775808,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='utf8_string', full_name='protobuf_unittest.TestExtremeDefaultValues.utf8_string', index=7,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("\341\210\264").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='zero_float', full_name='protobuf_unittest.TestExtremeDefaultValues.zero_float', index=8,
+      number=7, type=2, cpp_type=6, label=1,
+      has_default_value=True, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='one_float', full_name='protobuf_unittest.TestExtremeDefaultValues.one_float', index=9,
+      number=8, type=2, cpp_type=6, label=1,
+      has_default_value=True, default_value=float(1),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='small_float', full_name='protobuf_unittest.TestExtremeDefaultValues.small_float', index=10,
+      number=9, type=2, cpp_type=6, label=1,
+      has_default_value=True, default_value=float(1.5),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='negative_one_float', full_name='protobuf_unittest.TestExtremeDefaultValues.negative_one_float', index=11,
+      number=10, type=2, cpp_type=6, label=1,
+      has_default_value=True, default_value=float(-1),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='negative_float', full_name='protobuf_unittest.TestExtremeDefaultValues.negative_float', index=12,
+      number=11, type=2, cpp_type=6, label=1,
+      has_default_value=True, default_value=float(-1.5),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='large_float', full_name='protobuf_unittest.TestExtremeDefaultValues.large_float', index=13,
+      number=12, type=2, cpp_type=6, label=1,
+      has_default_value=True, default_value=float(2e+08),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='small_negative_float', full_name='protobuf_unittest.TestExtremeDefaultValues.small_negative_float', index=14,
+      number=13, type=2, cpp_type=6, label=1,
+      has_default_value=True, default_value=float(-8e-28),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='inf_double', full_name='protobuf_unittest.TestExtremeDefaultValues.inf_double', index=15,
+      number=14, type=1, cpp_type=5, label=1,
+      has_default_value=True, default_value=1e10000,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='neg_inf_double', full_name='protobuf_unittest.TestExtremeDefaultValues.neg_inf_double', index=16,
+      number=15, type=1, cpp_type=5, label=1,
+      has_default_value=True, default_value=-1e10000,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nan_double', full_name='protobuf_unittest.TestExtremeDefaultValues.nan_double', index=17,
+      number=16, type=1, cpp_type=5, label=1,
+      has_default_value=True, default_value=(1e10000 * 0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='inf_float', full_name='protobuf_unittest.TestExtremeDefaultValues.inf_float', index=18,
+      number=17, type=2, cpp_type=6, label=1,
+      has_default_value=True, default_value=1e10000,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='neg_inf_float', full_name='protobuf_unittest.TestExtremeDefaultValues.neg_inf_float', index=19,
+      number=18, type=2, cpp_type=6, label=1,
+      has_default_value=True, default_value=-1e10000,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='nan_float', full_name='protobuf_unittest.TestExtremeDefaultValues.nan_float', index=20,
+      number=19, type=2, cpp_type=6, label=1,
+      has_default_value=True, default_value=(1e10000 * 0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='cpp_trigraph', full_name='protobuf_unittest.TestExtremeDefaultValues.cpp_trigraph', index=21,
+      number=20, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("? ? ?? ?? ??? ??/ ??-").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='string_with_zero', full_name='protobuf_unittest.TestExtremeDefaultValues.string_with_zero', index=22,
+      number=23, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("hel\000lo").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bytes_with_zero', full_name='protobuf_unittest.TestExtremeDefaultValues.bytes_with_zero', index=23,
+      number=24, type=12, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("wor\000ld"),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='string_piece_with_zero', full_name='protobuf_unittest.TestExtremeDefaultValues.string_piece_with_zero', index=24,
+      number=25, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("ab\000c").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))),
+    _descriptor.FieldDescriptor(
+      name='cord_with_zero', full_name='protobuf_unittest.TestExtremeDefaultValues.cord_with_zero', index=25,
+      number=26, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("12\0003").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))),
+    _descriptor.FieldDescriptor(
+      name='replacement_string', full_name='protobuf_unittest.TestExtremeDefaultValues.replacement_string', index=26,
+      number=27, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("${unknown}").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=6589,
+  serialized_end=7539,
+)
+
+
+_SPARSEENUMMESSAGE = _descriptor.Descriptor(
+  name='SparseEnumMessage',
+  full_name='protobuf_unittest.SparseEnumMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='sparse_enum', full_name='protobuf_unittest.SparseEnumMessage.sparse_enum', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=123,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=7541,
+  serialized_end=7616,
+)
+
+
+_ONESTRING = _descriptor.Descriptor(
+  name='OneString',
+  full_name='protobuf_unittest.OneString',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='data', full_name='protobuf_unittest.OneString.data', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=7618,
+  serialized_end=7643,
+)
+
+
+_MORESTRING = _descriptor.Descriptor(
+  name='MoreString',
+  full_name='protobuf_unittest.MoreString',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='data', full_name='protobuf_unittest.MoreString.data', index=0,
+      number=1, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=7645,
+  serialized_end=7671,
+)
+
+
+_ONEBYTES = _descriptor.Descriptor(
+  name='OneBytes',
+  full_name='protobuf_unittest.OneBytes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='data', full_name='protobuf_unittest.OneBytes.data', index=0,
+      number=1, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=7673,
+  serialized_end=7697,
+)
+
+
+_MOREBYTES = _descriptor.Descriptor(
+  name='MoreBytes',
+  full_name='protobuf_unittest.MoreBytes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='data', full_name='protobuf_unittest.MoreBytes.data', index=0,
+      number=1, type=12, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=7699,
+  serialized_end=7724,
+)
+
+
+_INT32MESSAGE = _descriptor.Descriptor(
+  name='Int32Message',
+  full_name='protobuf_unittest.Int32Message',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='data', full_name='protobuf_unittest.Int32Message.data', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=7726,
+  serialized_end=7754,
+)
+
+
+_UINT32MESSAGE = _descriptor.Descriptor(
+  name='Uint32Message',
+  full_name='protobuf_unittest.Uint32Message',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='data', full_name='protobuf_unittest.Uint32Message.data', index=0,
+      number=1, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=7756,
+  serialized_end=7785,
+)
+
+
+_INT64MESSAGE = _descriptor.Descriptor(
+  name='Int64Message',
+  full_name='protobuf_unittest.Int64Message',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='data', full_name='protobuf_unittest.Int64Message.data', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=7787,
+  serialized_end=7815,
+)
+
+
+_UINT64MESSAGE = _descriptor.Descriptor(
+  name='Uint64Message',
+  full_name='protobuf_unittest.Uint64Message',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='data', full_name='protobuf_unittest.Uint64Message.data', index=0,
+      number=1, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=7817,
+  serialized_end=7846,
+)
+
+
+_BOOLMESSAGE = _descriptor.Descriptor(
+  name='BoolMessage',
+  full_name='protobuf_unittest.BoolMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='data', full_name='protobuf_unittest.BoolMessage.data', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=7848,
+  serialized_end=7875,
+)
+
+
+_TESTONEOF_FOOGROUP = _descriptor.Descriptor(
+  name='FooGroup',
+  full_name='protobuf_unittest.TestOneof.FooGroup',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestOneof.FooGroup.a', index=0,
+      number=5, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='b', full_name='protobuf_unittest.TestOneof.FooGroup.b', index=1,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=8047,
+  serialized_end=8079,
+)
+
+_TESTONEOF = _descriptor.Descriptor(
+  name='TestOneof',
+  full_name='protobuf_unittest.TestOneof',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='foo_int', full_name='protobuf_unittest.TestOneof.foo_int', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo_string', full_name='protobuf_unittest.TestOneof.foo_string', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo_message', full_name='protobuf_unittest.TestOneof.foo_message', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foogroup', full_name='protobuf_unittest.TestOneof.foogroup', index=3,
+      number=4, type=10, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTONEOF_FOOGROUP, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='foo', full_name='protobuf_unittest.TestOneof.foo',
+      index=0, containing_type=None, fields=[]),
+  ],
+  serialized_start=7878,
+  serialized_end=8086,
+)
+
+
+_TESTONEOFBACKWARDSCOMPATIBLE_FOOGROUP = _descriptor.Descriptor(
+  name='FooGroup',
+  full_name='protobuf_unittest.TestOneofBackwardsCompatible.FooGroup',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestOneofBackwardsCompatible.FooGroup.a', index=0,
+      number=5, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='b', full_name='protobuf_unittest.TestOneofBackwardsCompatible.FooGroup.b', index=1,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=8047,
+  serialized_end=8079,
+)
+
+_TESTONEOFBACKWARDSCOMPATIBLE = _descriptor.Descriptor(
+  name='TestOneofBackwardsCompatible',
+  full_name='protobuf_unittest.TestOneofBackwardsCompatible',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='foo_int', full_name='protobuf_unittest.TestOneofBackwardsCompatible.foo_int', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo_string', full_name='protobuf_unittest.TestOneofBackwardsCompatible.foo_string', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo_message', full_name='protobuf_unittest.TestOneofBackwardsCompatible.foo_message', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foogroup', full_name='protobuf_unittest.TestOneofBackwardsCompatible.foogroup', index=3,
+      number=4, type=10, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTONEOFBACKWARDSCOMPATIBLE_FOOGROUP, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=8089,
+  serialized_end=8320,
+)
+
+
+_TESTONEOF2_FOOGROUP = _descriptor.Descriptor(
+  name='FooGroup',
+  full_name='protobuf_unittest.TestOneof2.FooGroup',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestOneof2.FooGroup.a', index=0,
+      number=9, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='b', full_name='protobuf_unittest.TestOneof2.FooGroup.b', index=1,
+      number=10, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=8981,
+  serialized_end=9013,
+)
+
+_TESTONEOF2_NESTEDMESSAGE = _descriptor.Descriptor(
+  name='NestedMessage',
+  full_name='protobuf_unittest.TestOneof2.NestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='qux_int', full_name='protobuf_unittest.TestOneof2.NestedMessage.qux_int', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='corge_int', full_name='protobuf_unittest.TestOneof2.NestedMessage.corge_int', index=1,
+      number=2, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=9015,
+  serialized_end=9066,
+)
+
+_TESTONEOF2 = _descriptor.Descriptor(
+  name='TestOneof2',
+  full_name='protobuf_unittest.TestOneof2',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='foo_int', full_name='protobuf_unittest.TestOneof2.foo_int', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo_string', full_name='protobuf_unittest.TestOneof2.foo_string', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo_cord', full_name='protobuf_unittest.TestOneof2.foo_cord', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))),
+    _descriptor.FieldDescriptor(
+      name='foo_string_piece', full_name='protobuf_unittest.TestOneof2.foo_string_piece', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))),
+    _descriptor.FieldDescriptor(
+      name='foo_bytes', full_name='protobuf_unittest.TestOneof2.foo_bytes', index=4,
+      number=5, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo_enum', full_name='protobuf_unittest.TestOneof2.foo_enum', index=5,
+      number=6, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=1,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo_message', full_name='protobuf_unittest.TestOneof2.foo_message', index=6,
+      number=7, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foogroup', full_name='protobuf_unittest.TestOneof2.foogroup', index=7,
+      number=8, type=10, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo_lazy_message', full_name='protobuf_unittest.TestOneof2.foo_lazy_message', index=8,
+      number=11, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))),
+    _descriptor.FieldDescriptor(
+      name='bar_int', full_name='protobuf_unittest.TestOneof2.bar_int', index=9,
+      number=12, type=5, cpp_type=1, label=1,
+      has_default_value=True, default_value=5,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bar_string', full_name='protobuf_unittest.TestOneof2.bar_string', index=10,
+      number=13, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("STRING").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bar_cord', full_name='protobuf_unittest.TestOneof2.bar_cord', index=11,
+      number=14, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("CORD").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))),
+    _descriptor.FieldDescriptor(
+      name='bar_string_piece', full_name='protobuf_unittest.TestOneof2.bar_string_piece', index=12,
+      number=15, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("SPIECE").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))),
+    _descriptor.FieldDescriptor(
+      name='bar_bytes', full_name='protobuf_unittest.TestOneof2.bar_bytes', index=13,
+      number=16, type=12, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("BYTES"),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bar_enum', full_name='protobuf_unittest.TestOneof2.bar_enum', index=14,
+      number=17, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=2,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='baz_int', full_name='protobuf_unittest.TestOneof2.baz_int', index=15,
+      number=18, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='baz_string', full_name='protobuf_unittest.TestOneof2.baz_string', index=16,
+      number=19, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("BAZ").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTONEOF2_FOOGROUP, _TESTONEOF2_NESTEDMESSAGE, ],
+  enum_types=[
+    _TESTONEOF2_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='foo', full_name='protobuf_unittest.TestOneof2.foo',
+      index=0, containing_type=None, fields=[]),
+    _descriptor.OneofDescriptor(
+      name='bar', full_name='protobuf_unittest.TestOneof2.bar',
+      index=1, containing_type=None, fields=[]),
+  ],
+  serialized_start=8323,
+  serialized_end=9121,
+)
+
+
+_TESTREQUIREDONEOF_NESTEDMESSAGE = _descriptor.Descriptor(
+  name='NestedMessage',
+  full_name='protobuf_unittest.TestRequiredOneof.NestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='required_double', full_name='protobuf_unittest.TestRequiredOneof.NestedMessage.required_double', index=0,
+      number=1, type=1, cpp_type=5, label=2,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=9261,
+  serialized_end=9301,
+)
+
+_TESTREQUIREDONEOF = _descriptor.Descriptor(
+  name='TestRequiredOneof',
+  full_name='protobuf_unittest.TestRequiredOneof',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='foo_int', full_name='protobuf_unittest.TestRequiredOneof.foo_int', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo_string', full_name='protobuf_unittest.TestRequiredOneof.foo_string', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='foo_message', full_name='protobuf_unittest.TestRequiredOneof.foo_message', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTREQUIREDONEOF_NESTEDMESSAGE, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='foo', full_name='protobuf_unittest.TestRequiredOneof.foo',
+      index=0, containing_type=None, fields=[]),
+  ],
+  serialized_start=9124,
+  serialized_end=9308,
+)
+
+
+_TESTPACKEDTYPES = _descriptor.Descriptor(
+  name='TestPackedTypes',
+  full_name='protobuf_unittest.TestPackedTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='packed_int32', full_name='protobuf_unittest.TestPackedTypes.packed_int32', index=0,
+      number=90, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_int64', full_name='protobuf_unittest.TestPackedTypes.packed_int64', index=1,
+      number=91, type=3, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_uint32', full_name='protobuf_unittest.TestPackedTypes.packed_uint32', index=2,
+      number=92, type=13, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_uint64', full_name='protobuf_unittest.TestPackedTypes.packed_uint64', index=3,
+      number=93, type=4, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_sint32', full_name='protobuf_unittest.TestPackedTypes.packed_sint32', index=4,
+      number=94, type=17, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_sint64', full_name='protobuf_unittest.TestPackedTypes.packed_sint64', index=5,
+      number=95, type=18, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_fixed32', full_name='protobuf_unittest.TestPackedTypes.packed_fixed32', index=6,
+      number=96, type=7, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_fixed64', full_name='protobuf_unittest.TestPackedTypes.packed_fixed64', index=7,
+      number=97, type=6, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_sfixed32', full_name='protobuf_unittest.TestPackedTypes.packed_sfixed32', index=8,
+      number=98, type=15, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_sfixed64', full_name='protobuf_unittest.TestPackedTypes.packed_sfixed64', index=9,
+      number=99, type=16, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_float', full_name='protobuf_unittest.TestPackedTypes.packed_float', index=10,
+      number=100, type=2, cpp_type=6, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_double', full_name='protobuf_unittest.TestPackedTypes.packed_double', index=11,
+      number=101, type=1, cpp_type=5, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_bool', full_name='protobuf_unittest.TestPackedTypes.packed_bool', index=12,
+      number=102, type=8, cpp_type=7, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_enum', full_name='protobuf_unittest.TestPackedTypes.packed_enum', index=13,
+      number=103, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=9311,
+  serialized_end=9737,
+)
+
+
+_TESTUNPACKEDTYPES = _descriptor.Descriptor(
+  name='TestUnpackedTypes',
+  full_name='protobuf_unittest.TestUnpackedTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='unpacked_int32', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_int32', index=0,
+      number=90, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='unpacked_int64', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_int64', index=1,
+      number=91, type=3, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='unpacked_uint32', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_uint32', index=2,
+      number=92, type=13, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='unpacked_uint64', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_uint64', index=3,
+      number=93, type=4, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='unpacked_sint32', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_sint32', index=4,
+      number=94, type=17, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='unpacked_sint64', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_sint64', index=5,
+      number=95, type=18, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='unpacked_fixed32', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_fixed32', index=6,
+      number=96, type=7, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='unpacked_fixed64', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_fixed64', index=7,
+      number=97, type=6, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='unpacked_sfixed32', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_sfixed32', index=8,
+      number=98, type=15, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='unpacked_sfixed64', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_sfixed64', index=9,
+      number=99, type=16, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='unpacked_float', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_float', index=10,
+      number=100, type=2, cpp_type=6, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='unpacked_double', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_double', index=11,
+      number=101, type=1, cpp_type=5, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='unpacked_bool', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_bool', index=12,
+      number=102, type=8, cpp_type=7, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='unpacked_enum', full_name='protobuf_unittest.TestUnpackedTypes.unpacked_enum', index=13,
+      number=103, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=9740,
+  serialized_end=10196,
+)
+
+
+_TESTPACKEDEXTENSIONS = _descriptor.Descriptor(
+  name='TestPackedExtensions',
+  full_name='protobuf_unittest.TestPackedExtensions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(1, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=10198,
+  serialized_end=10230,
+)
+
+
+_TESTUNPACKEDEXTENSIONS = _descriptor.Descriptor(
+  name='TestUnpackedExtensions',
+  full_name='protobuf_unittest.TestUnpackedExtensions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(1, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=10232,
+  serialized_end=10266,
+)
+
+
+_TESTDYNAMICEXTENSIONS_DYNAMICMESSAGETYPE = _descriptor.Descriptor(
+  name='DynamicMessageType',
+  full_name='protobuf_unittest.TestDynamicExtensions.DynamicMessageType',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='dynamic_field', full_name='protobuf_unittest.TestDynamicExtensions.DynamicMessageType.dynamic_field', index=0,
+      number=2100, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=10689,
+  serialized_end=10733,
+)
+
+_TESTDYNAMICEXTENSIONS = _descriptor.Descriptor(
+  name='TestDynamicExtensions',
+  full_name='protobuf_unittest.TestDynamicExtensions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='scalar_extension', full_name='protobuf_unittest.TestDynamicExtensions.scalar_extension', index=0,
+      number=2000, type=7, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='enum_extension', full_name='protobuf_unittest.TestDynamicExtensions.enum_extension', index=1,
+      number=2001, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=4,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dynamic_enum_extension', full_name='protobuf_unittest.TestDynamicExtensions.dynamic_enum_extension', index=2,
+      number=2002, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=2200,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='message_extension', full_name='protobuf_unittest.TestDynamicExtensions.message_extension', index=3,
+      number=2003, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='dynamic_message_extension', full_name='protobuf_unittest.TestDynamicExtensions.dynamic_message_extension', index=4,
+      number=2004, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_extension', full_name='protobuf_unittest.TestDynamicExtensions.repeated_extension', index=5,
+      number=2005, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='packed_extension', full_name='protobuf_unittest.TestDynamicExtensions.packed_extension', index=6,
+      number=2006, type=17, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTDYNAMICEXTENSIONS_DYNAMICMESSAGETYPE, ],
+  enum_types=[
+    _TESTDYNAMICEXTENSIONS_DYNAMICENUMTYPE,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=10269,
+  serialized_end=10806,
+)
+
+
+_TESTREPEATEDSCALARDIFFERENTTAGSIZES = _descriptor.Descriptor(
+  name='TestRepeatedScalarDifferentTagSizes',
+  full_name='protobuf_unittest.TestRepeatedScalarDifferentTagSizes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed32', full_name='protobuf_unittest.TestRepeatedScalarDifferentTagSizes.repeated_fixed32', index=0,
+      number=12, type=7, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_int32', full_name='protobuf_unittest.TestRepeatedScalarDifferentTagSizes.repeated_int32', index=1,
+      number=13, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed64', full_name='protobuf_unittest.TestRepeatedScalarDifferentTagSizes.repeated_fixed64', index=2,
+      number=2046, type=6, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_int64', full_name='protobuf_unittest.TestRepeatedScalarDifferentTagSizes.repeated_int64', index=3,
+      number=2047, type=3, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_float', full_name='protobuf_unittest.TestRepeatedScalarDifferentTagSizes.repeated_float', index=4,
+      number=262142, type=2, cpp_type=6, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint64', full_name='protobuf_unittest.TestRepeatedScalarDifferentTagSizes.repeated_uint64', index=5,
+      number=262143, type=4, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=10809,
+  serialized_end=11001,
+)
+
+
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR_GROUP1 = _descriptor.Descriptor(
+  name='Group1',
+  full_name='protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group1',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='field1', full_name='protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group1.field1', index=0,
+      number=11, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=11794,
+  serialized_end=11851,
+)
+
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR_GROUP2 = _descriptor.Descriptor(
+  name='Group2',
+  full_name='protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group2',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='field1', full_name='protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group2.field1', index=0,
+      number=21, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=11853,
+  serialized_end=11910,
+)
+
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR = _descriptor.Descriptor(
+  name='RepeatedFieldsGenerator',
+  full_name='protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='field1', full_name='protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.field1', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='field2', full_name='protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.field2', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='field3', full_name='protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.field3', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='group1', full_name='protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.group1', index=3,
+      number=10, type=10, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='group2', full_name='protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.group2', index=4,
+      number=20, type=10, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='ext1', full_name='protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.ext1', index=5,
+      number=1000, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='ext2', full_name='protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.ext2', index=6,
+      number=1001, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR_GROUP1, _TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR_GROUP2, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=11356,
+  serialized_end=11910,
+)
+
+_TESTPARSINGMERGE_OPTIONALGROUP = _descriptor.Descriptor(
+  name='OptionalGroup',
+  full_name='protobuf_unittest.TestParsingMerge.OptionalGroup',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='optional_group_all_types', full_name='protobuf_unittest.TestParsingMerge.OptionalGroup.optional_group_all_types', index=0,
+      number=11, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=11912,
+  serialized_end=11994,
+)
+
+_TESTPARSINGMERGE_REPEATEDGROUP = _descriptor.Descriptor(
+  name='RepeatedGroup',
+  full_name='protobuf_unittest.TestParsingMerge.RepeatedGroup',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='repeated_group_all_types', full_name='protobuf_unittest.TestParsingMerge.RepeatedGroup.repeated_group_all_types', index=0,
+      number=21, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=11996,
+  serialized_end=12078,
+)
+
+_TESTPARSINGMERGE = _descriptor.Descriptor(
+  name='TestParsingMerge',
+  full_name='protobuf_unittest.TestParsingMerge',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='required_all_types', full_name='protobuf_unittest.TestParsingMerge.required_all_types', index=0,
+      number=1, type=11, cpp_type=10, label=2,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_all_types', full_name='protobuf_unittest.TestParsingMerge.optional_all_types', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_all_types', full_name='protobuf_unittest.TestParsingMerge.repeated_all_types', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optionalgroup', full_name='protobuf_unittest.TestParsingMerge.optionalgroup', index=3,
+      number=10, type=10, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeatedgroup', full_name='protobuf_unittest.TestParsingMerge.repeatedgroup', index=4,
+      number=20, type=10, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+    _descriptor.FieldDescriptor(
+      name='optional_ext', full_name='protobuf_unittest.TestParsingMerge.optional_ext', index=0,
+      number=1000, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_ext', full_name='protobuf_unittest.TestParsingMerge.repeated_ext', index=1,
+      number=1001, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=True, extension_scope=None,
+      options=None),
+  ],
+  nested_types=[_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR, _TESTPARSINGMERGE_OPTIONALGROUP, _TESTPARSINGMERGE_REPEATEDGROUP, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=True,
+  syntax='proto2',
+  extension_ranges=[(1000, 536870912), ],
+  oneofs=[
+  ],
+  serialized_start=11004,
+  serialized_end=12275,
+)
+
+
+_TESTCOMMENTINJECTIONMESSAGE = _descriptor.Descriptor(
+  name='TestCommentInjectionMessage',
+  full_name='protobuf_unittest.TestCommentInjectionMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='a', full_name='protobuf_unittest.TestCommentInjectionMessage.a', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=True, default_value=_b("*/ <- Neither should this.").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=12277,
+  serialized_end=12345,
+)
+
+
+_FOOREQUEST = _descriptor.Descriptor(
+  name='FooRequest',
+  full_name='protobuf_unittest.FooRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=12347,
+  serialized_end=12359,
+)
+
+
+_FOORESPONSE = _descriptor.Descriptor(
+  name='FooResponse',
+  full_name='protobuf_unittest.FooResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=12361,
+  serialized_end=12374,
+)
+
+
+_FOOCLIENTMESSAGE = _descriptor.Descriptor(
+  name='FooClientMessage',
+  full_name='protobuf_unittest.FooClientMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=12376,
+  serialized_end=12394,
+)
+
+
+_FOOSERVERMESSAGE = _descriptor.Descriptor(
+  name='FooServerMessage',
+  full_name='protobuf_unittest.FooServerMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=12396,
+  serialized_end=12414,
+)
+
+
+_BARREQUEST = _descriptor.Descriptor(
+  name='BarRequest',
+  full_name='protobuf_unittest.BarRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=12416,
+  serialized_end=12428,
+)
+
+
+_BARRESPONSE = _descriptor.Descriptor(
+  name='BarResponse',
+  full_name='protobuf_unittest.BarResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=12430,
+  serialized_end=12443,
+)
+
+_TESTALLTYPES_NESTEDMESSAGE.containing_type = _TESTALLTYPES
+_TESTALLTYPES_OPTIONALGROUP.containing_type = _TESTALLTYPES
+_TESTALLTYPES_REPEATEDGROUP.containing_type = _TESTALLTYPES
+_TESTALLTYPES.fields_by_name['optionalgroup'].message_type = _TESTALLTYPES_OPTIONALGROUP
+_TESTALLTYPES.fields_by_name['optional_nested_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['optional_foreign_message'].message_type = _FOREIGNMESSAGE
+_TESTALLTYPES.fields_by_name['optional_import_message'].message_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTMESSAGE
+_TESTALLTYPES.fields_by_name['optional_nested_enum'].enum_type = _TESTALLTYPES_NESTEDENUM
+_TESTALLTYPES.fields_by_name['optional_foreign_enum'].enum_type = _FOREIGNENUM
+_TESTALLTYPES.fields_by_name['optional_import_enum'].enum_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTENUM
+_TESTALLTYPES.fields_by_name['optional_public_import_message'].message_type = google_dot_protobuf_dot_unittest__import__public__pb2._PUBLICIMPORTMESSAGE
+_TESTALLTYPES.fields_by_name['optional_lazy_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['repeatedgroup'].message_type = _TESTALLTYPES_REPEATEDGROUP
+_TESTALLTYPES.fields_by_name['repeated_nested_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['repeated_foreign_message'].message_type = _FOREIGNMESSAGE
+_TESTALLTYPES.fields_by_name['repeated_import_message'].message_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTMESSAGE
+_TESTALLTYPES.fields_by_name['repeated_nested_enum'].enum_type = _TESTALLTYPES_NESTEDENUM
+_TESTALLTYPES.fields_by_name['repeated_foreign_enum'].enum_type = _FOREIGNENUM
+_TESTALLTYPES.fields_by_name['repeated_import_enum'].enum_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTENUM
+_TESTALLTYPES.fields_by_name['repeated_lazy_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['default_nested_enum'].enum_type = _TESTALLTYPES_NESTEDENUM
+_TESTALLTYPES.fields_by_name['default_foreign_enum'].enum_type = _FOREIGNENUM
+_TESTALLTYPES.fields_by_name['default_import_enum'].enum_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTENUM
+_TESTALLTYPES.fields_by_name['oneof_nested_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES_NESTEDENUM.containing_type = _TESTALLTYPES
+_TESTALLTYPES.oneofs_by_name['oneof_field'].fields.append(
+  _TESTALLTYPES.fields_by_name['oneof_uint32'])
+_TESTALLTYPES.fields_by_name['oneof_uint32'].containing_oneof = _TESTALLTYPES.oneofs_by_name['oneof_field']
+_TESTALLTYPES.oneofs_by_name['oneof_field'].fields.append(
+  _TESTALLTYPES.fields_by_name['oneof_nested_message'])
+_TESTALLTYPES.fields_by_name['oneof_nested_message'].containing_oneof = _TESTALLTYPES.oneofs_by_name['oneof_field']
+_TESTALLTYPES.oneofs_by_name['oneof_field'].fields.append(
+  _TESTALLTYPES.fields_by_name['oneof_string'])
+_TESTALLTYPES.fields_by_name['oneof_string'].containing_oneof = _TESTALLTYPES.oneofs_by_name['oneof_field']
+_TESTALLTYPES.oneofs_by_name['oneof_field'].fields.append(
+  _TESTALLTYPES.fields_by_name['oneof_bytes'])
+_TESTALLTYPES.fields_by_name['oneof_bytes'].containing_oneof = _TESTALLTYPES.oneofs_by_name['oneof_field']
+_NESTEDTESTALLTYPES.fields_by_name['child'].message_type = _NESTEDTESTALLTYPES
+_NESTEDTESTALLTYPES.fields_by_name['payload'].message_type = _TESTALLTYPES
+_NESTEDTESTALLTYPES.fields_by_name['repeated_child'].message_type = _NESTEDTESTALLTYPES
+_TESTREQUIREDFOREIGN.fields_by_name['optional_message'].message_type = _TESTREQUIRED
+_TESTREQUIREDFOREIGN.fields_by_name['repeated_message'].message_type = _TESTREQUIRED
+_TESTFOREIGNNESTED.fields_by_name['foreign_nested'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTRECURSIVEMESSAGE.fields_by_name['a'].message_type = _TESTRECURSIVEMESSAGE
+_TESTMUTUALRECURSIONA.fields_by_name['bb'].message_type = _TESTMUTUALRECURSIONB
+_TESTMUTUALRECURSIONB.fields_by_name['a'].message_type = _TESTMUTUALRECURSIONA
+_TESTDUPFIELDNUMBER_FOO.containing_type = _TESTDUPFIELDNUMBER
+_TESTDUPFIELDNUMBER_BAR.containing_type = _TESTDUPFIELDNUMBER
+_TESTDUPFIELDNUMBER.fields_by_name['foo'].message_type = _TESTDUPFIELDNUMBER_FOO
+_TESTDUPFIELDNUMBER.fields_by_name['bar'].message_type = _TESTDUPFIELDNUMBER_BAR
+_TESTEAGERMESSAGE.fields_by_name['sub_message'].message_type = _TESTALLTYPES
+_TESTLAZYMESSAGE.fields_by_name['sub_message'].message_type = _TESTALLTYPES
+_TESTNESTEDMESSAGEHASBITS_NESTEDMESSAGE.fields_by_name['nestedmessage_repeated_foreignmessage'].message_type = _FOREIGNMESSAGE
+_TESTNESTEDMESSAGEHASBITS_NESTEDMESSAGE.containing_type = _TESTNESTEDMESSAGEHASBITS
+_TESTNESTEDMESSAGEHASBITS.fields_by_name['optional_nested_message'].message_type = _TESTNESTEDMESSAGEHASBITS_NESTEDMESSAGE
+_TESTCAMELCASEFIELDNAMES.fields_by_name['EnumField'].enum_type = _FOREIGNENUM
+_TESTCAMELCASEFIELDNAMES.fields_by_name['MessageField'].message_type = _FOREIGNMESSAGE
+_TESTCAMELCASEFIELDNAMES.fields_by_name['RepeatedEnumField'].enum_type = _FOREIGNENUM
+_TESTCAMELCASEFIELDNAMES.fields_by_name['RepeatedMessageField'].message_type = _FOREIGNMESSAGE
+_TESTFIELDORDERINGS_NESTEDMESSAGE.containing_type = _TESTFIELDORDERINGS
+_TESTFIELDORDERINGS.fields_by_name['optional_nested_message'].message_type = _TESTFIELDORDERINGS_NESTEDMESSAGE
+_SPARSEENUMMESSAGE.fields_by_name['sparse_enum'].enum_type = _TESTSPARSEENUM
+_TESTONEOF_FOOGROUP.containing_type = _TESTONEOF
+_TESTONEOF.fields_by_name['foo_message'].message_type = _TESTALLTYPES
+_TESTONEOF.fields_by_name['foogroup'].message_type = _TESTONEOF_FOOGROUP
+_TESTONEOF.oneofs_by_name['foo'].fields.append(
+  _TESTONEOF.fields_by_name['foo_int'])
+_TESTONEOF.fields_by_name['foo_int'].containing_oneof = _TESTONEOF.oneofs_by_name['foo']
+_TESTONEOF.oneofs_by_name['foo'].fields.append(
+  _TESTONEOF.fields_by_name['foo_string'])
+_TESTONEOF.fields_by_name['foo_string'].containing_oneof = _TESTONEOF.oneofs_by_name['foo']
+_TESTONEOF.oneofs_by_name['foo'].fields.append(
+  _TESTONEOF.fields_by_name['foo_message'])
+_TESTONEOF.fields_by_name['foo_message'].containing_oneof = _TESTONEOF.oneofs_by_name['foo']
+_TESTONEOF.oneofs_by_name['foo'].fields.append(
+  _TESTONEOF.fields_by_name['foogroup'])
+_TESTONEOF.fields_by_name['foogroup'].containing_oneof = _TESTONEOF.oneofs_by_name['foo']
+_TESTONEOFBACKWARDSCOMPATIBLE_FOOGROUP.containing_type = _TESTONEOFBACKWARDSCOMPATIBLE
+_TESTONEOFBACKWARDSCOMPATIBLE.fields_by_name['foo_message'].message_type = _TESTALLTYPES
+_TESTONEOFBACKWARDSCOMPATIBLE.fields_by_name['foogroup'].message_type = _TESTONEOFBACKWARDSCOMPATIBLE_FOOGROUP
+_TESTONEOF2_FOOGROUP.containing_type = _TESTONEOF2
+_TESTONEOF2_NESTEDMESSAGE.containing_type = _TESTONEOF2
+_TESTONEOF2.fields_by_name['foo_enum'].enum_type = _TESTONEOF2_NESTEDENUM
+_TESTONEOF2.fields_by_name['foo_message'].message_type = _TESTONEOF2_NESTEDMESSAGE
+_TESTONEOF2.fields_by_name['foogroup'].message_type = _TESTONEOF2_FOOGROUP
+_TESTONEOF2.fields_by_name['foo_lazy_message'].message_type = _TESTONEOF2_NESTEDMESSAGE
+_TESTONEOF2.fields_by_name['bar_enum'].enum_type = _TESTONEOF2_NESTEDENUM
+_TESTONEOF2_NESTEDENUM.containing_type = _TESTONEOF2
+_TESTONEOF2.oneofs_by_name['foo'].fields.append(
+  _TESTONEOF2.fields_by_name['foo_int'])
+_TESTONEOF2.fields_by_name['foo_int'].containing_oneof = _TESTONEOF2.oneofs_by_name['foo']
+_TESTONEOF2.oneofs_by_name['foo'].fields.append(
+  _TESTONEOF2.fields_by_name['foo_string'])
+_TESTONEOF2.fields_by_name['foo_string'].containing_oneof = _TESTONEOF2.oneofs_by_name['foo']
+_TESTONEOF2.oneofs_by_name['foo'].fields.append(
+  _TESTONEOF2.fields_by_name['foo_cord'])
+_TESTONEOF2.fields_by_name['foo_cord'].containing_oneof = _TESTONEOF2.oneofs_by_name['foo']
+_TESTONEOF2.oneofs_by_name['foo'].fields.append(
+  _TESTONEOF2.fields_by_name['foo_string_piece'])
+_TESTONEOF2.fields_by_name['foo_string_piece'].containing_oneof = _TESTONEOF2.oneofs_by_name['foo']
+_TESTONEOF2.oneofs_by_name['foo'].fields.append(
+  _TESTONEOF2.fields_by_name['foo_bytes'])
+_TESTONEOF2.fields_by_name['foo_bytes'].containing_oneof = _TESTONEOF2.oneofs_by_name['foo']
+_TESTONEOF2.oneofs_by_name['foo'].fields.append(
+  _TESTONEOF2.fields_by_name['foo_enum'])
+_TESTONEOF2.fields_by_name['foo_enum'].containing_oneof = _TESTONEOF2.oneofs_by_name['foo']
+_TESTONEOF2.oneofs_by_name['foo'].fields.append(
+  _TESTONEOF2.fields_by_name['foo_message'])
+_TESTONEOF2.fields_by_name['foo_message'].containing_oneof = _TESTONEOF2.oneofs_by_name['foo']
+_TESTONEOF2.oneofs_by_name['foo'].fields.append(
+  _TESTONEOF2.fields_by_name['foogroup'])
+_TESTONEOF2.fields_by_name['foogroup'].containing_oneof = _TESTONEOF2.oneofs_by_name['foo']
+_TESTONEOF2.oneofs_by_name['foo'].fields.append(
+  _TESTONEOF2.fields_by_name['foo_lazy_message'])
+_TESTONEOF2.fields_by_name['foo_lazy_message'].containing_oneof = _TESTONEOF2.oneofs_by_name['foo']
+_TESTONEOF2.oneofs_by_name['bar'].fields.append(
+  _TESTONEOF2.fields_by_name['bar_int'])
+_TESTONEOF2.fields_by_name['bar_int'].containing_oneof = _TESTONEOF2.oneofs_by_name['bar']
+_TESTONEOF2.oneofs_by_name['bar'].fields.append(
+  _TESTONEOF2.fields_by_name['bar_string'])
+_TESTONEOF2.fields_by_name['bar_string'].containing_oneof = _TESTONEOF2.oneofs_by_name['bar']
+_TESTONEOF2.oneofs_by_name['bar'].fields.append(
+  _TESTONEOF2.fields_by_name['bar_cord'])
+_TESTONEOF2.fields_by_name['bar_cord'].containing_oneof = _TESTONEOF2.oneofs_by_name['bar']
+_TESTONEOF2.oneofs_by_name['bar'].fields.append(
+  _TESTONEOF2.fields_by_name['bar_string_piece'])
+_TESTONEOF2.fields_by_name['bar_string_piece'].containing_oneof = _TESTONEOF2.oneofs_by_name['bar']
+_TESTONEOF2.oneofs_by_name['bar'].fields.append(
+  _TESTONEOF2.fields_by_name['bar_bytes'])
+_TESTONEOF2.fields_by_name['bar_bytes'].containing_oneof = _TESTONEOF2.oneofs_by_name['bar']
+_TESTONEOF2.oneofs_by_name['bar'].fields.append(
+  _TESTONEOF2.fields_by_name['bar_enum'])
+_TESTONEOF2.fields_by_name['bar_enum'].containing_oneof = _TESTONEOF2.oneofs_by_name['bar']
+_TESTREQUIREDONEOF_NESTEDMESSAGE.containing_type = _TESTREQUIREDONEOF
+_TESTREQUIREDONEOF.fields_by_name['foo_message'].message_type = _TESTREQUIREDONEOF_NESTEDMESSAGE
+_TESTREQUIREDONEOF.oneofs_by_name['foo'].fields.append(
+  _TESTREQUIREDONEOF.fields_by_name['foo_int'])
+_TESTREQUIREDONEOF.fields_by_name['foo_int'].containing_oneof = _TESTREQUIREDONEOF.oneofs_by_name['foo']
+_TESTREQUIREDONEOF.oneofs_by_name['foo'].fields.append(
+  _TESTREQUIREDONEOF.fields_by_name['foo_string'])
+_TESTREQUIREDONEOF.fields_by_name['foo_string'].containing_oneof = _TESTREQUIREDONEOF.oneofs_by_name['foo']
+_TESTREQUIREDONEOF.oneofs_by_name['foo'].fields.append(
+  _TESTREQUIREDONEOF.fields_by_name['foo_message'])
+_TESTREQUIREDONEOF.fields_by_name['foo_message'].containing_oneof = _TESTREQUIREDONEOF.oneofs_by_name['foo']
+_TESTPACKEDTYPES.fields_by_name['packed_enum'].enum_type = _FOREIGNENUM
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_enum'].enum_type = _FOREIGNENUM
+_TESTDYNAMICEXTENSIONS_DYNAMICMESSAGETYPE.containing_type = _TESTDYNAMICEXTENSIONS
+_TESTDYNAMICEXTENSIONS.fields_by_name['enum_extension'].enum_type = _FOREIGNENUM
+_TESTDYNAMICEXTENSIONS.fields_by_name['dynamic_enum_extension'].enum_type = _TESTDYNAMICEXTENSIONS_DYNAMICENUMTYPE
+_TESTDYNAMICEXTENSIONS.fields_by_name['message_extension'].message_type = _FOREIGNMESSAGE
+_TESTDYNAMICEXTENSIONS.fields_by_name['dynamic_message_extension'].message_type = _TESTDYNAMICEXTENSIONS_DYNAMICMESSAGETYPE
+_TESTDYNAMICEXTENSIONS_DYNAMICENUMTYPE.containing_type = _TESTDYNAMICEXTENSIONS
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR_GROUP1.fields_by_name['field1'].message_type = _TESTALLTYPES
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR_GROUP1.containing_type = _TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR_GROUP2.fields_by_name['field1'].message_type = _TESTALLTYPES
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR_GROUP2.containing_type = _TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR.fields_by_name['field1'].message_type = _TESTALLTYPES
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR.fields_by_name['field2'].message_type = _TESTALLTYPES
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR.fields_by_name['field3'].message_type = _TESTALLTYPES
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR.fields_by_name['group1'].message_type = _TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR_GROUP1
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR.fields_by_name['group2'].message_type = _TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR_GROUP2
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR.fields_by_name['ext1'].message_type = _TESTALLTYPES
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR.fields_by_name['ext2'].message_type = _TESTALLTYPES
+_TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR.containing_type = _TESTPARSINGMERGE
+_TESTPARSINGMERGE_OPTIONALGROUP.fields_by_name['optional_group_all_types'].message_type = _TESTALLTYPES
+_TESTPARSINGMERGE_OPTIONALGROUP.containing_type = _TESTPARSINGMERGE
+_TESTPARSINGMERGE_REPEATEDGROUP.fields_by_name['repeated_group_all_types'].message_type = _TESTALLTYPES
+_TESTPARSINGMERGE_REPEATEDGROUP.containing_type = _TESTPARSINGMERGE
+_TESTPARSINGMERGE.fields_by_name['required_all_types'].message_type = _TESTALLTYPES
+_TESTPARSINGMERGE.fields_by_name['optional_all_types'].message_type = _TESTALLTYPES
+_TESTPARSINGMERGE.fields_by_name['repeated_all_types'].message_type = _TESTALLTYPES
+_TESTPARSINGMERGE.fields_by_name['optionalgroup'].message_type = _TESTPARSINGMERGE_OPTIONALGROUP
+_TESTPARSINGMERGE.fields_by_name['repeatedgroup'].message_type = _TESTPARSINGMERGE_REPEATEDGROUP
+DESCRIPTOR.message_types_by_name['TestAllTypes'] = _TESTALLTYPES
+DESCRIPTOR.message_types_by_name['NestedTestAllTypes'] = _NESTEDTESTALLTYPES
+DESCRIPTOR.message_types_by_name['TestDeprecatedFields'] = _TESTDEPRECATEDFIELDS
+DESCRIPTOR.message_types_by_name['ForeignMessage'] = _FOREIGNMESSAGE
+DESCRIPTOR.message_types_by_name['TestReservedFields'] = _TESTRESERVEDFIELDS
+DESCRIPTOR.message_types_by_name['TestAllExtensions'] = _TESTALLEXTENSIONS
+DESCRIPTOR.message_types_by_name['OptionalGroup_extension'] = _OPTIONALGROUP_EXTENSION
+DESCRIPTOR.message_types_by_name['RepeatedGroup_extension'] = _REPEATEDGROUP_EXTENSION
+DESCRIPTOR.message_types_by_name['TestNestedExtension'] = _TESTNESTEDEXTENSION
+DESCRIPTOR.message_types_by_name['TestRequired'] = _TESTREQUIRED
+DESCRIPTOR.message_types_by_name['TestRequiredForeign'] = _TESTREQUIREDFOREIGN
+DESCRIPTOR.message_types_by_name['TestForeignNested'] = _TESTFOREIGNNESTED
+DESCRIPTOR.message_types_by_name['TestEmptyMessage'] = _TESTEMPTYMESSAGE
+DESCRIPTOR.message_types_by_name['TestEmptyMessageWithExtensions'] = _TESTEMPTYMESSAGEWITHEXTENSIONS
+DESCRIPTOR.message_types_by_name['TestMultipleExtensionRanges'] = _TESTMULTIPLEEXTENSIONRANGES
+DESCRIPTOR.message_types_by_name['TestReallyLargeTagNumber'] = _TESTREALLYLARGETAGNUMBER
+DESCRIPTOR.message_types_by_name['TestRecursiveMessage'] = _TESTRECURSIVEMESSAGE
+DESCRIPTOR.message_types_by_name['TestMutualRecursionA'] = _TESTMUTUALRECURSIONA
+DESCRIPTOR.message_types_by_name['TestMutualRecursionB'] = _TESTMUTUALRECURSIONB
+DESCRIPTOR.message_types_by_name['TestDupFieldNumber'] = _TESTDUPFIELDNUMBER
+DESCRIPTOR.message_types_by_name['TestEagerMessage'] = _TESTEAGERMESSAGE
+DESCRIPTOR.message_types_by_name['TestLazyMessage'] = _TESTLAZYMESSAGE
+DESCRIPTOR.message_types_by_name['TestNestedMessageHasBits'] = _TESTNESTEDMESSAGEHASBITS
+DESCRIPTOR.message_types_by_name['TestCamelCaseFieldNames'] = _TESTCAMELCASEFIELDNAMES
+DESCRIPTOR.message_types_by_name['TestFieldOrderings'] = _TESTFIELDORDERINGS
+DESCRIPTOR.message_types_by_name['TestExtremeDefaultValues'] = _TESTEXTREMEDEFAULTVALUES
+DESCRIPTOR.message_types_by_name['SparseEnumMessage'] = _SPARSEENUMMESSAGE
+DESCRIPTOR.message_types_by_name['OneString'] = _ONESTRING
+DESCRIPTOR.message_types_by_name['MoreString'] = _MORESTRING
+DESCRIPTOR.message_types_by_name['OneBytes'] = _ONEBYTES
+DESCRIPTOR.message_types_by_name['MoreBytes'] = _MOREBYTES
+DESCRIPTOR.message_types_by_name['Int32Message'] = _INT32MESSAGE
+DESCRIPTOR.message_types_by_name['Uint32Message'] = _UINT32MESSAGE
+DESCRIPTOR.message_types_by_name['Int64Message'] = _INT64MESSAGE
+DESCRIPTOR.message_types_by_name['Uint64Message'] = _UINT64MESSAGE
+DESCRIPTOR.message_types_by_name['BoolMessage'] = _BOOLMESSAGE
+DESCRIPTOR.message_types_by_name['TestOneof'] = _TESTONEOF
+DESCRIPTOR.message_types_by_name['TestOneofBackwardsCompatible'] = _TESTONEOFBACKWARDSCOMPATIBLE
+DESCRIPTOR.message_types_by_name['TestOneof2'] = _TESTONEOF2
+DESCRIPTOR.message_types_by_name['TestRequiredOneof'] = _TESTREQUIREDONEOF
+DESCRIPTOR.message_types_by_name['TestPackedTypes'] = _TESTPACKEDTYPES
+DESCRIPTOR.message_types_by_name['TestUnpackedTypes'] = _TESTUNPACKEDTYPES
+DESCRIPTOR.message_types_by_name['TestPackedExtensions'] = _TESTPACKEDEXTENSIONS
+DESCRIPTOR.message_types_by_name['TestUnpackedExtensions'] = _TESTUNPACKEDEXTENSIONS
+DESCRIPTOR.message_types_by_name['TestDynamicExtensions'] = _TESTDYNAMICEXTENSIONS
+DESCRIPTOR.message_types_by_name['TestRepeatedScalarDifferentTagSizes'] = _TESTREPEATEDSCALARDIFFERENTTAGSIZES
+DESCRIPTOR.message_types_by_name['TestParsingMerge'] = _TESTPARSINGMERGE
+DESCRIPTOR.message_types_by_name['TestCommentInjectionMessage'] = _TESTCOMMENTINJECTIONMESSAGE
+DESCRIPTOR.message_types_by_name['FooRequest'] = _FOOREQUEST
+DESCRIPTOR.message_types_by_name['FooResponse'] = _FOORESPONSE
+DESCRIPTOR.message_types_by_name['FooClientMessage'] = _FOOCLIENTMESSAGE
+DESCRIPTOR.message_types_by_name['FooServerMessage'] = _FOOSERVERMESSAGE
+DESCRIPTOR.message_types_by_name['BarRequest'] = _BARREQUEST
+DESCRIPTOR.message_types_by_name['BarResponse'] = _BARRESPONSE
+DESCRIPTOR.enum_types_by_name['ForeignEnum'] = _FOREIGNENUM
+DESCRIPTOR.enum_types_by_name['TestEnumWithDupValue'] = _TESTENUMWITHDUPVALUE
+DESCRIPTOR.enum_types_by_name['TestSparseEnum'] = _TESTSPARSEENUM
+DESCRIPTOR.extensions_by_name['optional_int32_extension'] = optional_int32_extension
+DESCRIPTOR.extensions_by_name['optional_int64_extension'] = optional_int64_extension
+DESCRIPTOR.extensions_by_name['optional_uint32_extension'] = optional_uint32_extension
+DESCRIPTOR.extensions_by_name['optional_uint64_extension'] = optional_uint64_extension
+DESCRIPTOR.extensions_by_name['optional_sint32_extension'] = optional_sint32_extension
+DESCRIPTOR.extensions_by_name['optional_sint64_extension'] = optional_sint64_extension
+DESCRIPTOR.extensions_by_name['optional_fixed32_extension'] = optional_fixed32_extension
+DESCRIPTOR.extensions_by_name['optional_fixed64_extension'] = optional_fixed64_extension
+DESCRIPTOR.extensions_by_name['optional_sfixed32_extension'] = optional_sfixed32_extension
+DESCRIPTOR.extensions_by_name['optional_sfixed64_extension'] = optional_sfixed64_extension
+DESCRIPTOR.extensions_by_name['optional_float_extension'] = optional_float_extension
+DESCRIPTOR.extensions_by_name['optional_double_extension'] = optional_double_extension
+DESCRIPTOR.extensions_by_name['optional_bool_extension'] = optional_bool_extension
+DESCRIPTOR.extensions_by_name['optional_string_extension'] = optional_string_extension
+DESCRIPTOR.extensions_by_name['optional_bytes_extension'] = optional_bytes_extension
+DESCRIPTOR.extensions_by_name['optionalgroup_extension'] = optionalgroup_extension
+DESCRIPTOR.extensions_by_name['optional_nested_message_extension'] = optional_nested_message_extension
+DESCRIPTOR.extensions_by_name['optional_foreign_message_extension'] = optional_foreign_message_extension
+DESCRIPTOR.extensions_by_name['optional_import_message_extension'] = optional_import_message_extension
+DESCRIPTOR.extensions_by_name['optional_nested_enum_extension'] = optional_nested_enum_extension
+DESCRIPTOR.extensions_by_name['optional_foreign_enum_extension'] = optional_foreign_enum_extension
+DESCRIPTOR.extensions_by_name['optional_import_enum_extension'] = optional_import_enum_extension
+DESCRIPTOR.extensions_by_name['optional_string_piece_extension'] = optional_string_piece_extension
+DESCRIPTOR.extensions_by_name['optional_cord_extension'] = optional_cord_extension
+DESCRIPTOR.extensions_by_name['optional_public_import_message_extension'] = optional_public_import_message_extension
+DESCRIPTOR.extensions_by_name['optional_lazy_message_extension'] = optional_lazy_message_extension
+DESCRIPTOR.extensions_by_name['repeated_int32_extension'] = repeated_int32_extension
+DESCRIPTOR.extensions_by_name['repeated_int64_extension'] = repeated_int64_extension
+DESCRIPTOR.extensions_by_name['repeated_uint32_extension'] = repeated_uint32_extension
+DESCRIPTOR.extensions_by_name['repeated_uint64_extension'] = repeated_uint64_extension
+DESCRIPTOR.extensions_by_name['repeated_sint32_extension'] = repeated_sint32_extension
+DESCRIPTOR.extensions_by_name['repeated_sint64_extension'] = repeated_sint64_extension
+DESCRIPTOR.extensions_by_name['repeated_fixed32_extension'] = repeated_fixed32_extension
+DESCRIPTOR.extensions_by_name['repeated_fixed64_extension'] = repeated_fixed64_extension
+DESCRIPTOR.extensions_by_name['repeated_sfixed32_extension'] = repeated_sfixed32_extension
+DESCRIPTOR.extensions_by_name['repeated_sfixed64_extension'] = repeated_sfixed64_extension
+DESCRIPTOR.extensions_by_name['repeated_float_extension'] = repeated_float_extension
+DESCRIPTOR.extensions_by_name['repeated_double_extension'] = repeated_double_extension
+DESCRIPTOR.extensions_by_name['repeated_bool_extension'] = repeated_bool_extension
+DESCRIPTOR.extensions_by_name['repeated_string_extension'] = repeated_string_extension
+DESCRIPTOR.extensions_by_name['repeated_bytes_extension'] = repeated_bytes_extension
+DESCRIPTOR.extensions_by_name['repeatedgroup_extension'] = repeatedgroup_extension
+DESCRIPTOR.extensions_by_name['repeated_nested_message_extension'] = repeated_nested_message_extension
+DESCRIPTOR.extensions_by_name['repeated_foreign_message_extension'] = repeated_foreign_message_extension
+DESCRIPTOR.extensions_by_name['repeated_import_message_extension'] = repeated_import_message_extension
+DESCRIPTOR.extensions_by_name['repeated_nested_enum_extension'] = repeated_nested_enum_extension
+DESCRIPTOR.extensions_by_name['repeated_foreign_enum_extension'] = repeated_foreign_enum_extension
+DESCRIPTOR.extensions_by_name['repeated_import_enum_extension'] = repeated_import_enum_extension
+DESCRIPTOR.extensions_by_name['repeated_string_piece_extension'] = repeated_string_piece_extension
+DESCRIPTOR.extensions_by_name['repeated_cord_extension'] = repeated_cord_extension
+DESCRIPTOR.extensions_by_name['repeated_lazy_message_extension'] = repeated_lazy_message_extension
+DESCRIPTOR.extensions_by_name['default_int32_extension'] = default_int32_extension
+DESCRIPTOR.extensions_by_name['default_int64_extension'] = default_int64_extension
+DESCRIPTOR.extensions_by_name['default_uint32_extension'] = default_uint32_extension
+DESCRIPTOR.extensions_by_name['default_uint64_extension'] = default_uint64_extension
+DESCRIPTOR.extensions_by_name['default_sint32_extension'] = default_sint32_extension
+DESCRIPTOR.extensions_by_name['default_sint64_extension'] = default_sint64_extension
+DESCRIPTOR.extensions_by_name['default_fixed32_extension'] = default_fixed32_extension
+DESCRIPTOR.extensions_by_name['default_fixed64_extension'] = default_fixed64_extension
+DESCRIPTOR.extensions_by_name['default_sfixed32_extension'] = default_sfixed32_extension
+DESCRIPTOR.extensions_by_name['default_sfixed64_extension'] = default_sfixed64_extension
+DESCRIPTOR.extensions_by_name['default_float_extension'] = default_float_extension
+DESCRIPTOR.extensions_by_name['default_double_extension'] = default_double_extension
+DESCRIPTOR.extensions_by_name['default_bool_extension'] = default_bool_extension
+DESCRIPTOR.extensions_by_name['default_string_extension'] = default_string_extension
+DESCRIPTOR.extensions_by_name['default_bytes_extension'] = default_bytes_extension
+DESCRIPTOR.extensions_by_name['default_nested_enum_extension'] = default_nested_enum_extension
+DESCRIPTOR.extensions_by_name['default_foreign_enum_extension'] = default_foreign_enum_extension
+DESCRIPTOR.extensions_by_name['default_import_enum_extension'] = default_import_enum_extension
+DESCRIPTOR.extensions_by_name['default_string_piece_extension'] = default_string_piece_extension
+DESCRIPTOR.extensions_by_name['default_cord_extension'] = default_cord_extension
+DESCRIPTOR.extensions_by_name['oneof_uint32_extension'] = oneof_uint32_extension
+DESCRIPTOR.extensions_by_name['oneof_nested_message_extension'] = oneof_nested_message_extension
+DESCRIPTOR.extensions_by_name['oneof_string_extension'] = oneof_string_extension
+DESCRIPTOR.extensions_by_name['oneof_bytes_extension'] = oneof_bytes_extension
+DESCRIPTOR.extensions_by_name['my_extension_string'] = my_extension_string
+DESCRIPTOR.extensions_by_name['my_extension_int'] = my_extension_int
+DESCRIPTOR.extensions_by_name['packed_int32_extension'] = packed_int32_extension
+DESCRIPTOR.extensions_by_name['packed_int64_extension'] = packed_int64_extension
+DESCRIPTOR.extensions_by_name['packed_uint32_extension'] = packed_uint32_extension
+DESCRIPTOR.extensions_by_name['packed_uint64_extension'] = packed_uint64_extension
+DESCRIPTOR.extensions_by_name['packed_sint32_extension'] = packed_sint32_extension
+DESCRIPTOR.extensions_by_name['packed_sint64_extension'] = packed_sint64_extension
+DESCRIPTOR.extensions_by_name['packed_fixed32_extension'] = packed_fixed32_extension
+DESCRIPTOR.extensions_by_name['packed_fixed64_extension'] = packed_fixed64_extension
+DESCRIPTOR.extensions_by_name['packed_sfixed32_extension'] = packed_sfixed32_extension
+DESCRIPTOR.extensions_by_name['packed_sfixed64_extension'] = packed_sfixed64_extension
+DESCRIPTOR.extensions_by_name['packed_float_extension'] = packed_float_extension
+DESCRIPTOR.extensions_by_name['packed_double_extension'] = packed_double_extension
+DESCRIPTOR.extensions_by_name['packed_bool_extension'] = packed_bool_extension
+DESCRIPTOR.extensions_by_name['packed_enum_extension'] = packed_enum_extension
+DESCRIPTOR.extensions_by_name['unpacked_int32_extension'] = unpacked_int32_extension
+DESCRIPTOR.extensions_by_name['unpacked_int64_extension'] = unpacked_int64_extension
+DESCRIPTOR.extensions_by_name['unpacked_uint32_extension'] = unpacked_uint32_extension
+DESCRIPTOR.extensions_by_name['unpacked_uint64_extension'] = unpacked_uint64_extension
+DESCRIPTOR.extensions_by_name['unpacked_sint32_extension'] = unpacked_sint32_extension
+DESCRIPTOR.extensions_by_name['unpacked_sint64_extension'] = unpacked_sint64_extension
+DESCRIPTOR.extensions_by_name['unpacked_fixed32_extension'] = unpacked_fixed32_extension
+DESCRIPTOR.extensions_by_name['unpacked_fixed64_extension'] = unpacked_fixed64_extension
+DESCRIPTOR.extensions_by_name['unpacked_sfixed32_extension'] = unpacked_sfixed32_extension
+DESCRIPTOR.extensions_by_name['unpacked_sfixed64_extension'] = unpacked_sfixed64_extension
+DESCRIPTOR.extensions_by_name['unpacked_float_extension'] = unpacked_float_extension
+DESCRIPTOR.extensions_by_name['unpacked_double_extension'] = unpacked_double_extension
+DESCRIPTOR.extensions_by_name['unpacked_bool_extension'] = unpacked_bool_extension
+DESCRIPTOR.extensions_by_name['unpacked_enum_extension'] = unpacked_enum_extension
+
+TestAllTypes = _reflection.GeneratedProtocolMessageType('TestAllTypes', (_message.Message,), dict(
+
+  NestedMessage = _reflection.GeneratedProtocolMessageType('NestedMessage', (_message.Message,), dict(
+    DESCRIPTOR = _TESTALLTYPES_NESTEDMESSAGE,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllTypes.NestedMessage)
+    ))
+  ,
+
+  OptionalGroup = _reflection.GeneratedProtocolMessageType('OptionalGroup', (_message.Message,), dict(
+    DESCRIPTOR = _TESTALLTYPES_OPTIONALGROUP,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllTypes.OptionalGroup)
+    ))
+  ,
+
+  RepeatedGroup = _reflection.GeneratedProtocolMessageType('RepeatedGroup', (_message.Message,), dict(
+    DESCRIPTOR = _TESTALLTYPES_REPEATEDGROUP,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllTypes.RepeatedGroup)
+    ))
+  ,
+  DESCRIPTOR = _TESTALLTYPES,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllTypes)
+  ))
+_sym_db.RegisterMessage(TestAllTypes)
+_sym_db.RegisterMessage(TestAllTypes.NestedMessage)
+_sym_db.RegisterMessage(TestAllTypes.OptionalGroup)
+_sym_db.RegisterMessage(TestAllTypes.RepeatedGroup)
+
+NestedTestAllTypes = _reflection.GeneratedProtocolMessageType('NestedTestAllTypes', (_message.Message,), dict(
+  DESCRIPTOR = _NESTEDTESTALLTYPES,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.NestedTestAllTypes)
+  ))
+_sym_db.RegisterMessage(NestedTestAllTypes)
+
+TestDeprecatedFields = _reflection.GeneratedProtocolMessageType('TestDeprecatedFields', (_message.Message,), dict(
+  DESCRIPTOR = _TESTDEPRECATEDFIELDS,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestDeprecatedFields)
+  ))
+_sym_db.RegisterMessage(TestDeprecatedFields)
+
+ForeignMessage = _reflection.GeneratedProtocolMessageType('ForeignMessage', (_message.Message,), dict(
+  DESCRIPTOR = _FOREIGNMESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.ForeignMessage)
+  ))
+_sym_db.RegisterMessage(ForeignMessage)
+
+TestReservedFields = _reflection.GeneratedProtocolMessageType('TestReservedFields', (_message.Message,), dict(
+  DESCRIPTOR = _TESTRESERVEDFIELDS,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestReservedFields)
+  ))
+_sym_db.RegisterMessage(TestReservedFields)
+
+TestAllExtensions = _reflection.GeneratedProtocolMessageType('TestAllExtensions', (_message.Message,), dict(
+  DESCRIPTOR = _TESTALLEXTENSIONS,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestAllExtensions)
+  ))
+_sym_db.RegisterMessage(TestAllExtensions)
+
+OptionalGroup_extension = _reflection.GeneratedProtocolMessageType('OptionalGroup_extension', (_message.Message,), dict(
+  DESCRIPTOR = _OPTIONALGROUP_EXTENSION,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.OptionalGroup_extension)
+  ))
+_sym_db.RegisterMessage(OptionalGroup_extension)
+
+RepeatedGroup_extension = _reflection.GeneratedProtocolMessageType('RepeatedGroup_extension', (_message.Message,), dict(
+  DESCRIPTOR = _REPEATEDGROUP_EXTENSION,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.RepeatedGroup_extension)
+  ))
+_sym_db.RegisterMessage(RepeatedGroup_extension)
+
+TestNestedExtension = _reflection.GeneratedProtocolMessageType('TestNestedExtension', (_message.Message,), dict(
+  DESCRIPTOR = _TESTNESTEDEXTENSION,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestNestedExtension)
+  ))
+_sym_db.RegisterMessage(TestNestedExtension)
+
+TestRequired = _reflection.GeneratedProtocolMessageType('TestRequired', (_message.Message,), dict(
+  DESCRIPTOR = _TESTREQUIRED,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestRequired)
+  ))
+_sym_db.RegisterMessage(TestRequired)
+
+TestRequiredForeign = _reflection.GeneratedProtocolMessageType('TestRequiredForeign', (_message.Message,), dict(
+  DESCRIPTOR = _TESTREQUIREDFOREIGN,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestRequiredForeign)
+  ))
+_sym_db.RegisterMessage(TestRequiredForeign)
+
+TestForeignNested = _reflection.GeneratedProtocolMessageType('TestForeignNested', (_message.Message,), dict(
+  DESCRIPTOR = _TESTFOREIGNNESTED,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestForeignNested)
+  ))
+_sym_db.RegisterMessage(TestForeignNested)
+
+TestEmptyMessage = _reflection.GeneratedProtocolMessageType('TestEmptyMessage', (_message.Message,), dict(
+  DESCRIPTOR = _TESTEMPTYMESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestEmptyMessage)
+  ))
+_sym_db.RegisterMessage(TestEmptyMessage)
+
+TestEmptyMessageWithExtensions = _reflection.GeneratedProtocolMessageType('TestEmptyMessageWithExtensions', (_message.Message,), dict(
+  DESCRIPTOR = _TESTEMPTYMESSAGEWITHEXTENSIONS,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestEmptyMessageWithExtensions)
+  ))
+_sym_db.RegisterMessage(TestEmptyMessageWithExtensions)
+
+TestMultipleExtensionRanges = _reflection.GeneratedProtocolMessageType('TestMultipleExtensionRanges', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMULTIPLEEXTENSIONRANGES,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMultipleExtensionRanges)
+  ))
+_sym_db.RegisterMessage(TestMultipleExtensionRanges)
+
+TestReallyLargeTagNumber = _reflection.GeneratedProtocolMessageType('TestReallyLargeTagNumber', (_message.Message,), dict(
+  DESCRIPTOR = _TESTREALLYLARGETAGNUMBER,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestReallyLargeTagNumber)
+  ))
+_sym_db.RegisterMessage(TestReallyLargeTagNumber)
+
+TestRecursiveMessage = _reflection.GeneratedProtocolMessageType('TestRecursiveMessage', (_message.Message,), dict(
+  DESCRIPTOR = _TESTRECURSIVEMESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestRecursiveMessage)
+  ))
+_sym_db.RegisterMessage(TestRecursiveMessage)
+
+TestMutualRecursionA = _reflection.GeneratedProtocolMessageType('TestMutualRecursionA', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMUTUALRECURSIONA,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMutualRecursionA)
+  ))
+_sym_db.RegisterMessage(TestMutualRecursionA)
+
+TestMutualRecursionB = _reflection.GeneratedProtocolMessageType('TestMutualRecursionB', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMUTUALRECURSIONB,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestMutualRecursionB)
+  ))
+_sym_db.RegisterMessage(TestMutualRecursionB)
+
+TestDupFieldNumber = _reflection.GeneratedProtocolMessageType('TestDupFieldNumber', (_message.Message,), dict(
+
+  Foo = _reflection.GeneratedProtocolMessageType('Foo', (_message.Message,), dict(
+    DESCRIPTOR = _TESTDUPFIELDNUMBER_FOO,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestDupFieldNumber.Foo)
+    ))
+  ,
+
+  Bar = _reflection.GeneratedProtocolMessageType('Bar', (_message.Message,), dict(
+    DESCRIPTOR = _TESTDUPFIELDNUMBER_BAR,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestDupFieldNumber.Bar)
+    ))
+  ,
+  DESCRIPTOR = _TESTDUPFIELDNUMBER,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestDupFieldNumber)
+  ))
+_sym_db.RegisterMessage(TestDupFieldNumber)
+_sym_db.RegisterMessage(TestDupFieldNumber.Foo)
+_sym_db.RegisterMessage(TestDupFieldNumber.Bar)
+
+TestEagerMessage = _reflection.GeneratedProtocolMessageType('TestEagerMessage', (_message.Message,), dict(
+  DESCRIPTOR = _TESTEAGERMESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestEagerMessage)
+  ))
+_sym_db.RegisterMessage(TestEagerMessage)
+
+TestLazyMessage = _reflection.GeneratedProtocolMessageType('TestLazyMessage', (_message.Message,), dict(
+  DESCRIPTOR = _TESTLAZYMESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestLazyMessage)
+  ))
+_sym_db.RegisterMessage(TestLazyMessage)
+
+TestNestedMessageHasBits = _reflection.GeneratedProtocolMessageType('TestNestedMessageHasBits', (_message.Message,), dict(
+
+  NestedMessage = _reflection.GeneratedProtocolMessageType('NestedMessage', (_message.Message,), dict(
+    DESCRIPTOR = _TESTNESTEDMESSAGEHASBITS_NESTEDMESSAGE,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestNestedMessageHasBits.NestedMessage)
+    ))
+  ,
+  DESCRIPTOR = _TESTNESTEDMESSAGEHASBITS,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestNestedMessageHasBits)
+  ))
+_sym_db.RegisterMessage(TestNestedMessageHasBits)
+_sym_db.RegisterMessage(TestNestedMessageHasBits.NestedMessage)
+
+TestCamelCaseFieldNames = _reflection.GeneratedProtocolMessageType('TestCamelCaseFieldNames', (_message.Message,), dict(
+  DESCRIPTOR = _TESTCAMELCASEFIELDNAMES,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestCamelCaseFieldNames)
+  ))
+_sym_db.RegisterMessage(TestCamelCaseFieldNames)
+
+TestFieldOrderings = _reflection.GeneratedProtocolMessageType('TestFieldOrderings', (_message.Message,), dict(
+
+  NestedMessage = _reflection.GeneratedProtocolMessageType('NestedMessage', (_message.Message,), dict(
+    DESCRIPTOR = _TESTFIELDORDERINGS_NESTEDMESSAGE,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestFieldOrderings.NestedMessage)
+    ))
+  ,
+  DESCRIPTOR = _TESTFIELDORDERINGS,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestFieldOrderings)
+  ))
+_sym_db.RegisterMessage(TestFieldOrderings)
+_sym_db.RegisterMessage(TestFieldOrderings.NestedMessage)
+
+TestExtremeDefaultValues = _reflection.GeneratedProtocolMessageType('TestExtremeDefaultValues', (_message.Message,), dict(
+  DESCRIPTOR = _TESTEXTREMEDEFAULTVALUES,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestExtremeDefaultValues)
+  ))
+_sym_db.RegisterMessage(TestExtremeDefaultValues)
+
+SparseEnumMessage = _reflection.GeneratedProtocolMessageType('SparseEnumMessage', (_message.Message,), dict(
+  DESCRIPTOR = _SPARSEENUMMESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.SparseEnumMessage)
+  ))
+_sym_db.RegisterMessage(SparseEnumMessage)
+
+OneString = _reflection.GeneratedProtocolMessageType('OneString', (_message.Message,), dict(
+  DESCRIPTOR = _ONESTRING,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.OneString)
+  ))
+_sym_db.RegisterMessage(OneString)
+
+MoreString = _reflection.GeneratedProtocolMessageType('MoreString', (_message.Message,), dict(
+  DESCRIPTOR = _MORESTRING,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.MoreString)
+  ))
+_sym_db.RegisterMessage(MoreString)
+
+OneBytes = _reflection.GeneratedProtocolMessageType('OneBytes', (_message.Message,), dict(
+  DESCRIPTOR = _ONEBYTES,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.OneBytes)
+  ))
+_sym_db.RegisterMessage(OneBytes)
+
+MoreBytes = _reflection.GeneratedProtocolMessageType('MoreBytes', (_message.Message,), dict(
+  DESCRIPTOR = _MOREBYTES,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.MoreBytes)
+  ))
+_sym_db.RegisterMessage(MoreBytes)
+
+Int32Message = _reflection.GeneratedProtocolMessageType('Int32Message', (_message.Message,), dict(
+  DESCRIPTOR = _INT32MESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.Int32Message)
+  ))
+_sym_db.RegisterMessage(Int32Message)
+
+Uint32Message = _reflection.GeneratedProtocolMessageType('Uint32Message', (_message.Message,), dict(
+  DESCRIPTOR = _UINT32MESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.Uint32Message)
+  ))
+_sym_db.RegisterMessage(Uint32Message)
+
+Int64Message = _reflection.GeneratedProtocolMessageType('Int64Message', (_message.Message,), dict(
+  DESCRIPTOR = _INT64MESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.Int64Message)
+  ))
+_sym_db.RegisterMessage(Int64Message)
+
+Uint64Message = _reflection.GeneratedProtocolMessageType('Uint64Message', (_message.Message,), dict(
+  DESCRIPTOR = _UINT64MESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.Uint64Message)
+  ))
+_sym_db.RegisterMessage(Uint64Message)
+
+BoolMessage = _reflection.GeneratedProtocolMessageType('BoolMessage', (_message.Message,), dict(
+  DESCRIPTOR = _BOOLMESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.BoolMessage)
+  ))
+_sym_db.RegisterMessage(BoolMessage)
+
+TestOneof = _reflection.GeneratedProtocolMessageType('TestOneof', (_message.Message,), dict(
+
+  FooGroup = _reflection.GeneratedProtocolMessageType('FooGroup', (_message.Message,), dict(
+    DESCRIPTOR = _TESTONEOF_FOOGROUP,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneof.FooGroup)
+    ))
+  ,
+  DESCRIPTOR = _TESTONEOF,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneof)
+  ))
+_sym_db.RegisterMessage(TestOneof)
+_sym_db.RegisterMessage(TestOneof.FooGroup)
+
+TestOneofBackwardsCompatible = _reflection.GeneratedProtocolMessageType('TestOneofBackwardsCompatible', (_message.Message,), dict(
+
+  FooGroup = _reflection.GeneratedProtocolMessageType('FooGroup', (_message.Message,), dict(
+    DESCRIPTOR = _TESTONEOFBACKWARDSCOMPATIBLE_FOOGROUP,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneofBackwardsCompatible.FooGroup)
+    ))
+  ,
+  DESCRIPTOR = _TESTONEOFBACKWARDSCOMPATIBLE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneofBackwardsCompatible)
+  ))
+_sym_db.RegisterMessage(TestOneofBackwardsCompatible)
+_sym_db.RegisterMessage(TestOneofBackwardsCompatible.FooGroup)
+
+TestOneof2 = _reflection.GeneratedProtocolMessageType('TestOneof2', (_message.Message,), dict(
+
+  FooGroup = _reflection.GeneratedProtocolMessageType('FooGroup', (_message.Message,), dict(
+    DESCRIPTOR = _TESTONEOF2_FOOGROUP,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneof2.FooGroup)
+    ))
+  ,
+
+  NestedMessage = _reflection.GeneratedProtocolMessageType('NestedMessage', (_message.Message,), dict(
+    DESCRIPTOR = _TESTONEOF2_NESTEDMESSAGE,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneof2.NestedMessage)
+    ))
+  ,
+  DESCRIPTOR = _TESTONEOF2,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestOneof2)
+  ))
+_sym_db.RegisterMessage(TestOneof2)
+_sym_db.RegisterMessage(TestOneof2.FooGroup)
+_sym_db.RegisterMessage(TestOneof2.NestedMessage)
+
+TestRequiredOneof = _reflection.GeneratedProtocolMessageType('TestRequiredOneof', (_message.Message,), dict(
+
+  NestedMessage = _reflection.GeneratedProtocolMessageType('NestedMessage', (_message.Message,), dict(
+    DESCRIPTOR = _TESTREQUIREDONEOF_NESTEDMESSAGE,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestRequiredOneof.NestedMessage)
+    ))
+  ,
+  DESCRIPTOR = _TESTREQUIREDONEOF,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestRequiredOneof)
+  ))
+_sym_db.RegisterMessage(TestRequiredOneof)
+_sym_db.RegisterMessage(TestRequiredOneof.NestedMessage)
+
+TestPackedTypes = _reflection.GeneratedProtocolMessageType('TestPackedTypes', (_message.Message,), dict(
+  DESCRIPTOR = _TESTPACKEDTYPES,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestPackedTypes)
+  ))
+_sym_db.RegisterMessage(TestPackedTypes)
+
+TestUnpackedTypes = _reflection.GeneratedProtocolMessageType('TestUnpackedTypes', (_message.Message,), dict(
+  DESCRIPTOR = _TESTUNPACKEDTYPES,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestUnpackedTypes)
+  ))
+_sym_db.RegisterMessage(TestUnpackedTypes)
+
+TestPackedExtensions = _reflection.GeneratedProtocolMessageType('TestPackedExtensions', (_message.Message,), dict(
+  DESCRIPTOR = _TESTPACKEDEXTENSIONS,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestPackedExtensions)
+  ))
+_sym_db.RegisterMessage(TestPackedExtensions)
+
+TestUnpackedExtensions = _reflection.GeneratedProtocolMessageType('TestUnpackedExtensions', (_message.Message,), dict(
+  DESCRIPTOR = _TESTUNPACKEDEXTENSIONS,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestUnpackedExtensions)
+  ))
+_sym_db.RegisterMessage(TestUnpackedExtensions)
+
+TestDynamicExtensions = _reflection.GeneratedProtocolMessageType('TestDynamicExtensions', (_message.Message,), dict(
+
+  DynamicMessageType = _reflection.GeneratedProtocolMessageType('DynamicMessageType', (_message.Message,), dict(
+    DESCRIPTOR = _TESTDYNAMICEXTENSIONS_DYNAMICMESSAGETYPE,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestDynamicExtensions.DynamicMessageType)
+    ))
+  ,
+  DESCRIPTOR = _TESTDYNAMICEXTENSIONS,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestDynamicExtensions)
+  ))
+_sym_db.RegisterMessage(TestDynamicExtensions)
+_sym_db.RegisterMessage(TestDynamicExtensions.DynamicMessageType)
+
+TestRepeatedScalarDifferentTagSizes = _reflection.GeneratedProtocolMessageType('TestRepeatedScalarDifferentTagSizes', (_message.Message,), dict(
+  DESCRIPTOR = _TESTREPEATEDSCALARDIFFERENTTAGSIZES,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestRepeatedScalarDifferentTagSizes)
+  ))
+_sym_db.RegisterMessage(TestRepeatedScalarDifferentTagSizes)
+
+TestParsingMerge = _reflection.GeneratedProtocolMessageType('TestParsingMerge', (_message.Message,), dict(
+
+  RepeatedFieldsGenerator = _reflection.GeneratedProtocolMessageType('RepeatedFieldsGenerator', (_message.Message,), dict(
+
+    Group1 = _reflection.GeneratedProtocolMessageType('Group1', (_message.Message,), dict(
+      DESCRIPTOR = _TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR_GROUP1,
+      __module__ = 'google.protobuf.unittest_pb2'
+      # @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group1)
+      ))
+    ,
+
+    Group2 = _reflection.GeneratedProtocolMessageType('Group2', (_message.Message,), dict(
+      DESCRIPTOR = _TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR_GROUP2,
+      __module__ = 'google.protobuf.unittest_pb2'
+      # @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator.Group2)
+      ))
+    ,
+    DESCRIPTOR = _TESTPARSINGMERGE_REPEATEDFIELDSGENERATOR,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMerge.RepeatedFieldsGenerator)
+    ))
+  ,
+
+  OptionalGroup = _reflection.GeneratedProtocolMessageType('OptionalGroup', (_message.Message,), dict(
+    DESCRIPTOR = _TESTPARSINGMERGE_OPTIONALGROUP,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMerge.OptionalGroup)
+    ))
+  ,
+
+  RepeatedGroup = _reflection.GeneratedProtocolMessageType('RepeatedGroup', (_message.Message,), dict(
+    DESCRIPTOR = _TESTPARSINGMERGE_REPEATEDGROUP,
+    __module__ = 'google.protobuf.unittest_pb2'
+    # @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMerge.RepeatedGroup)
+    ))
+  ,
+  DESCRIPTOR = _TESTPARSINGMERGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestParsingMerge)
+  ))
+_sym_db.RegisterMessage(TestParsingMerge)
+_sym_db.RegisterMessage(TestParsingMerge.RepeatedFieldsGenerator)
+_sym_db.RegisterMessage(TestParsingMerge.RepeatedFieldsGenerator.Group1)
+_sym_db.RegisterMessage(TestParsingMerge.RepeatedFieldsGenerator.Group2)
+_sym_db.RegisterMessage(TestParsingMerge.OptionalGroup)
+_sym_db.RegisterMessage(TestParsingMerge.RepeatedGroup)
+
+TestCommentInjectionMessage = _reflection.GeneratedProtocolMessageType('TestCommentInjectionMessage', (_message.Message,), dict(
+  DESCRIPTOR = _TESTCOMMENTINJECTIONMESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.TestCommentInjectionMessage)
+  ))
+_sym_db.RegisterMessage(TestCommentInjectionMessage)
+
+FooRequest = _reflection.GeneratedProtocolMessageType('FooRequest', (_message.Message,), dict(
+  DESCRIPTOR = _FOOREQUEST,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.FooRequest)
+  ))
+_sym_db.RegisterMessage(FooRequest)
+
+FooResponse = _reflection.GeneratedProtocolMessageType('FooResponse', (_message.Message,), dict(
+  DESCRIPTOR = _FOORESPONSE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.FooResponse)
+  ))
+_sym_db.RegisterMessage(FooResponse)
+
+FooClientMessage = _reflection.GeneratedProtocolMessageType('FooClientMessage', (_message.Message,), dict(
+  DESCRIPTOR = _FOOCLIENTMESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.FooClientMessage)
+  ))
+_sym_db.RegisterMessage(FooClientMessage)
+
+FooServerMessage = _reflection.GeneratedProtocolMessageType('FooServerMessage', (_message.Message,), dict(
+  DESCRIPTOR = _FOOSERVERMESSAGE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.FooServerMessage)
+  ))
+_sym_db.RegisterMessage(FooServerMessage)
+
+BarRequest = _reflection.GeneratedProtocolMessageType('BarRequest', (_message.Message,), dict(
+  DESCRIPTOR = _BARREQUEST,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.BarRequest)
+  ))
+_sym_db.RegisterMessage(BarRequest)
+
+BarResponse = _reflection.GeneratedProtocolMessageType('BarResponse', (_message.Message,), dict(
+  DESCRIPTOR = _BARRESPONSE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  # @@protoc_insertion_point(class_scope:protobuf_unittest.BarResponse)
+  ))
+_sym_db.RegisterMessage(BarResponse)
+
+TestAllExtensions.RegisterExtension(optional_int32_extension)
+TestAllExtensions.RegisterExtension(optional_int64_extension)
+TestAllExtensions.RegisterExtension(optional_uint32_extension)
+TestAllExtensions.RegisterExtension(optional_uint64_extension)
+TestAllExtensions.RegisterExtension(optional_sint32_extension)
+TestAllExtensions.RegisterExtension(optional_sint64_extension)
+TestAllExtensions.RegisterExtension(optional_fixed32_extension)
+TestAllExtensions.RegisterExtension(optional_fixed64_extension)
+TestAllExtensions.RegisterExtension(optional_sfixed32_extension)
+TestAllExtensions.RegisterExtension(optional_sfixed64_extension)
+TestAllExtensions.RegisterExtension(optional_float_extension)
+TestAllExtensions.RegisterExtension(optional_double_extension)
+TestAllExtensions.RegisterExtension(optional_bool_extension)
+TestAllExtensions.RegisterExtension(optional_string_extension)
+TestAllExtensions.RegisterExtension(optional_bytes_extension)
+optionalgroup_extension.message_type = _OPTIONALGROUP_EXTENSION
+TestAllExtensions.RegisterExtension(optionalgroup_extension)
+optional_nested_message_extension.message_type = _TESTALLTYPES_NESTEDMESSAGE
+TestAllExtensions.RegisterExtension(optional_nested_message_extension)
+optional_foreign_message_extension.message_type = _FOREIGNMESSAGE
+TestAllExtensions.RegisterExtension(optional_foreign_message_extension)
+optional_import_message_extension.message_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTMESSAGE
+TestAllExtensions.RegisterExtension(optional_import_message_extension)
+optional_nested_enum_extension.enum_type = _TESTALLTYPES_NESTEDENUM
+TestAllExtensions.RegisterExtension(optional_nested_enum_extension)
+optional_foreign_enum_extension.enum_type = _FOREIGNENUM
+TestAllExtensions.RegisterExtension(optional_foreign_enum_extension)
+optional_import_enum_extension.enum_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTENUM
+TestAllExtensions.RegisterExtension(optional_import_enum_extension)
+TestAllExtensions.RegisterExtension(optional_string_piece_extension)
+TestAllExtensions.RegisterExtension(optional_cord_extension)
+optional_public_import_message_extension.message_type = google_dot_protobuf_dot_unittest__import__public__pb2._PUBLICIMPORTMESSAGE
+TestAllExtensions.RegisterExtension(optional_public_import_message_extension)
+optional_lazy_message_extension.message_type = _TESTALLTYPES_NESTEDMESSAGE
+TestAllExtensions.RegisterExtension(optional_lazy_message_extension)
+TestAllExtensions.RegisterExtension(repeated_int32_extension)
+TestAllExtensions.RegisterExtension(repeated_int64_extension)
+TestAllExtensions.RegisterExtension(repeated_uint32_extension)
+TestAllExtensions.RegisterExtension(repeated_uint64_extension)
+TestAllExtensions.RegisterExtension(repeated_sint32_extension)
+TestAllExtensions.RegisterExtension(repeated_sint64_extension)
+TestAllExtensions.RegisterExtension(repeated_fixed32_extension)
+TestAllExtensions.RegisterExtension(repeated_fixed64_extension)
+TestAllExtensions.RegisterExtension(repeated_sfixed32_extension)
+TestAllExtensions.RegisterExtension(repeated_sfixed64_extension)
+TestAllExtensions.RegisterExtension(repeated_float_extension)
+TestAllExtensions.RegisterExtension(repeated_double_extension)
+TestAllExtensions.RegisterExtension(repeated_bool_extension)
+TestAllExtensions.RegisterExtension(repeated_string_extension)
+TestAllExtensions.RegisterExtension(repeated_bytes_extension)
+repeatedgroup_extension.message_type = _REPEATEDGROUP_EXTENSION
+TestAllExtensions.RegisterExtension(repeatedgroup_extension)
+repeated_nested_message_extension.message_type = _TESTALLTYPES_NESTEDMESSAGE
+TestAllExtensions.RegisterExtension(repeated_nested_message_extension)
+repeated_foreign_message_extension.message_type = _FOREIGNMESSAGE
+TestAllExtensions.RegisterExtension(repeated_foreign_message_extension)
+repeated_import_message_extension.message_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTMESSAGE
+TestAllExtensions.RegisterExtension(repeated_import_message_extension)
+repeated_nested_enum_extension.enum_type = _TESTALLTYPES_NESTEDENUM
+TestAllExtensions.RegisterExtension(repeated_nested_enum_extension)
+repeated_foreign_enum_extension.enum_type = _FOREIGNENUM
+TestAllExtensions.RegisterExtension(repeated_foreign_enum_extension)
+repeated_import_enum_extension.enum_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTENUM
+TestAllExtensions.RegisterExtension(repeated_import_enum_extension)
+TestAllExtensions.RegisterExtension(repeated_string_piece_extension)
+TestAllExtensions.RegisterExtension(repeated_cord_extension)
+repeated_lazy_message_extension.message_type = _TESTALLTYPES_NESTEDMESSAGE
+TestAllExtensions.RegisterExtension(repeated_lazy_message_extension)
+TestAllExtensions.RegisterExtension(default_int32_extension)
+TestAllExtensions.RegisterExtension(default_int64_extension)
+TestAllExtensions.RegisterExtension(default_uint32_extension)
+TestAllExtensions.RegisterExtension(default_uint64_extension)
+TestAllExtensions.RegisterExtension(default_sint32_extension)
+TestAllExtensions.RegisterExtension(default_sint64_extension)
+TestAllExtensions.RegisterExtension(default_fixed32_extension)
+TestAllExtensions.RegisterExtension(default_fixed64_extension)
+TestAllExtensions.RegisterExtension(default_sfixed32_extension)
+TestAllExtensions.RegisterExtension(default_sfixed64_extension)
+TestAllExtensions.RegisterExtension(default_float_extension)
+TestAllExtensions.RegisterExtension(default_double_extension)
+TestAllExtensions.RegisterExtension(default_bool_extension)
+TestAllExtensions.RegisterExtension(default_string_extension)
+TestAllExtensions.RegisterExtension(default_bytes_extension)
+default_nested_enum_extension.enum_type = _TESTALLTYPES_NESTEDENUM
+TestAllExtensions.RegisterExtension(default_nested_enum_extension)
+default_foreign_enum_extension.enum_type = _FOREIGNENUM
+TestAllExtensions.RegisterExtension(default_foreign_enum_extension)
+default_import_enum_extension.enum_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTENUM
+TestAllExtensions.RegisterExtension(default_import_enum_extension)
+TestAllExtensions.RegisterExtension(default_string_piece_extension)
+TestAllExtensions.RegisterExtension(default_cord_extension)
+TestAllExtensions.RegisterExtension(oneof_uint32_extension)
+oneof_nested_message_extension.message_type = _TESTALLTYPES_NESTEDMESSAGE
+TestAllExtensions.RegisterExtension(oneof_nested_message_extension)
+TestAllExtensions.RegisterExtension(oneof_string_extension)
+TestAllExtensions.RegisterExtension(oneof_bytes_extension)
+TestFieldOrderings.RegisterExtension(my_extension_string)
+TestFieldOrderings.RegisterExtension(my_extension_int)
+TestPackedExtensions.RegisterExtension(packed_int32_extension)
+TestPackedExtensions.RegisterExtension(packed_int64_extension)
+TestPackedExtensions.RegisterExtension(packed_uint32_extension)
+TestPackedExtensions.RegisterExtension(packed_uint64_extension)
+TestPackedExtensions.RegisterExtension(packed_sint32_extension)
+TestPackedExtensions.RegisterExtension(packed_sint64_extension)
+TestPackedExtensions.RegisterExtension(packed_fixed32_extension)
+TestPackedExtensions.RegisterExtension(packed_fixed64_extension)
+TestPackedExtensions.RegisterExtension(packed_sfixed32_extension)
+TestPackedExtensions.RegisterExtension(packed_sfixed64_extension)
+TestPackedExtensions.RegisterExtension(packed_float_extension)
+TestPackedExtensions.RegisterExtension(packed_double_extension)
+TestPackedExtensions.RegisterExtension(packed_bool_extension)
+packed_enum_extension.enum_type = _FOREIGNENUM
+TestPackedExtensions.RegisterExtension(packed_enum_extension)
+TestUnpackedExtensions.RegisterExtension(unpacked_int32_extension)
+TestUnpackedExtensions.RegisterExtension(unpacked_int64_extension)
+TestUnpackedExtensions.RegisterExtension(unpacked_uint32_extension)
+TestUnpackedExtensions.RegisterExtension(unpacked_uint64_extension)
+TestUnpackedExtensions.RegisterExtension(unpacked_sint32_extension)
+TestUnpackedExtensions.RegisterExtension(unpacked_sint64_extension)
+TestUnpackedExtensions.RegisterExtension(unpacked_fixed32_extension)
+TestUnpackedExtensions.RegisterExtension(unpacked_fixed64_extension)
+TestUnpackedExtensions.RegisterExtension(unpacked_sfixed32_extension)
+TestUnpackedExtensions.RegisterExtension(unpacked_sfixed64_extension)
+TestUnpackedExtensions.RegisterExtension(unpacked_float_extension)
+TestUnpackedExtensions.RegisterExtension(unpacked_double_extension)
+TestUnpackedExtensions.RegisterExtension(unpacked_bool_extension)
+unpacked_enum_extension.enum_type = _FOREIGNENUM
+TestUnpackedExtensions.RegisterExtension(unpacked_enum_extension)
+TestAllExtensions.RegisterExtension(_TESTNESTEDEXTENSION.extensions_by_name['test'])
+TestAllExtensions.RegisterExtension(_TESTNESTEDEXTENSION.extensions_by_name['nested_string_extension'])
+_TESTREQUIRED.extensions_by_name['single'].message_type = _TESTREQUIRED
+TestAllExtensions.RegisterExtension(_TESTREQUIRED.extensions_by_name['single'])
+_TESTREQUIRED.extensions_by_name['multi'].message_type = _TESTREQUIRED
+TestAllExtensions.RegisterExtension(_TESTREQUIRED.extensions_by_name['multi'])
+_TESTPARSINGMERGE.extensions_by_name['optional_ext'].message_type = _TESTALLTYPES
+TestParsingMerge.RegisterExtension(_TESTPARSINGMERGE.extensions_by_name['optional_ext'])
+_TESTPARSINGMERGE.extensions_by_name['repeated_ext'].message_type = _TESTALLTYPES
+TestParsingMerge.RegisterExtension(_TESTPARSINGMERGE.extensions_by_name['repeated_ext'])
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('B\rUnittestProtoH\001\200\001\001\210\001\001\220\001\001\370\001\001'))
+_TESTENUMWITHDUPVALUE.has_options = True
+_TESTENUMWITHDUPVALUE._options = _descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\020\001'))
+optional_string_piece_extension.has_options = True
+optional_string_piece_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+optional_cord_extension.has_options = True
+optional_cord_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+optional_lazy_message_extension.has_options = True
+optional_lazy_message_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))
+repeated_string_piece_extension.has_options = True
+repeated_string_piece_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+repeated_cord_extension.has_options = True
+repeated_cord_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+repeated_lazy_message_extension.has_options = True
+repeated_lazy_message_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))
+default_string_piece_extension.has_options = True
+default_string_piece_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+default_cord_extension.has_options = True
+default_cord_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+packed_int32_extension.has_options = True
+packed_int32_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+packed_int64_extension.has_options = True
+packed_int64_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+packed_uint32_extension.has_options = True
+packed_uint32_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+packed_uint64_extension.has_options = True
+packed_uint64_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+packed_sint32_extension.has_options = True
+packed_sint32_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+packed_sint64_extension.has_options = True
+packed_sint64_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+packed_fixed32_extension.has_options = True
+packed_fixed32_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+packed_fixed64_extension.has_options = True
+packed_fixed64_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+packed_sfixed32_extension.has_options = True
+packed_sfixed32_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+packed_sfixed64_extension.has_options = True
+packed_sfixed64_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+packed_float_extension.has_options = True
+packed_float_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+packed_double_extension.has_options = True
+packed_double_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+packed_bool_extension.has_options = True
+packed_bool_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+packed_enum_extension.has_options = True
+packed_enum_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+unpacked_int32_extension.has_options = True
+unpacked_int32_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+unpacked_int64_extension.has_options = True
+unpacked_int64_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+unpacked_uint32_extension.has_options = True
+unpacked_uint32_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+unpacked_uint64_extension.has_options = True
+unpacked_uint64_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+unpacked_sint32_extension.has_options = True
+unpacked_sint32_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+unpacked_sint64_extension.has_options = True
+unpacked_sint64_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+unpacked_fixed32_extension.has_options = True
+unpacked_fixed32_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+unpacked_fixed64_extension.has_options = True
+unpacked_fixed64_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+unpacked_sfixed32_extension.has_options = True
+unpacked_sfixed32_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+unpacked_sfixed64_extension.has_options = True
+unpacked_sfixed64_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+unpacked_float_extension.has_options = True
+unpacked_float_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+unpacked_double_extension.has_options = True
+unpacked_double_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+unpacked_bool_extension.has_options = True
+unpacked_bool_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+unpacked_enum_extension.has_options = True
+unpacked_enum_extension._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTALLTYPES.fields_by_name['optional_string_piece'].has_options = True
+_TESTALLTYPES.fields_by_name['optional_string_piece']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+_TESTALLTYPES.fields_by_name['optional_cord'].has_options = True
+_TESTALLTYPES.fields_by_name['optional_cord']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+_TESTALLTYPES.fields_by_name['optional_lazy_message'].has_options = True
+_TESTALLTYPES.fields_by_name['optional_lazy_message']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))
+_TESTALLTYPES.fields_by_name['repeated_string_piece'].has_options = True
+_TESTALLTYPES.fields_by_name['repeated_string_piece']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+_TESTALLTYPES.fields_by_name['repeated_cord'].has_options = True
+_TESTALLTYPES.fields_by_name['repeated_cord']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+_TESTALLTYPES.fields_by_name['repeated_lazy_message'].has_options = True
+_TESTALLTYPES.fields_by_name['repeated_lazy_message']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))
+_TESTALLTYPES.fields_by_name['default_string_piece'].has_options = True
+_TESTALLTYPES.fields_by_name['default_string_piece']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+_TESTALLTYPES.fields_by_name['default_cord'].has_options = True
+_TESTALLTYPES.fields_by_name['default_cord']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+_TESTDEPRECATEDFIELDS.fields_by_name['deprecated_int32'].has_options = True
+_TESTDEPRECATEDFIELDS.fields_by_name['deprecated_int32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))
+_TESTEAGERMESSAGE.fields_by_name['sub_message'].has_options = True
+_TESTEAGERMESSAGE.fields_by_name['sub_message']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\000'))
+_TESTLAZYMESSAGE.fields_by_name['sub_message'].has_options = True
+_TESTLAZYMESSAGE.fields_by_name['sub_message']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))
+_TESTCAMELCASEFIELDNAMES.fields_by_name['StringPieceField'].has_options = True
+_TESTCAMELCASEFIELDNAMES.fields_by_name['StringPieceField']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+_TESTCAMELCASEFIELDNAMES.fields_by_name['CordField'].has_options = True
+_TESTCAMELCASEFIELDNAMES.fields_by_name['CordField']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+_TESTCAMELCASEFIELDNAMES.fields_by_name['RepeatedStringPieceField'].has_options = True
+_TESTCAMELCASEFIELDNAMES.fields_by_name['RepeatedStringPieceField']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+_TESTCAMELCASEFIELDNAMES.fields_by_name['RepeatedCordField'].has_options = True
+_TESTCAMELCASEFIELDNAMES.fields_by_name['RepeatedCordField']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+_TESTEXTREMEDEFAULTVALUES.fields_by_name['string_piece_with_zero'].has_options = True
+_TESTEXTREMEDEFAULTVALUES.fields_by_name['string_piece_with_zero']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+_TESTEXTREMEDEFAULTVALUES.fields_by_name['cord_with_zero'].has_options = True
+_TESTEXTREMEDEFAULTVALUES.fields_by_name['cord_with_zero']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+_TESTONEOF2.fields_by_name['foo_cord'].has_options = True
+_TESTONEOF2.fields_by_name['foo_cord']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+_TESTONEOF2.fields_by_name['foo_string_piece'].has_options = True
+_TESTONEOF2.fields_by_name['foo_string_piece']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+_TESTONEOF2.fields_by_name['foo_lazy_message'].has_options = True
+_TESTONEOF2.fields_by_name['foo_lazy_message']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))
+_TESTONEOF2.fields_by_name['bar_cord'].has_options = True
+_TESTONEOF2.fields_by_name['bar_cord']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+_TESTONEOF2.fields_by_name['bar_string_piece'].has_options = True
+_TESTONEOF2.fields_by_name['bar_string_piece']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+_TESTPACKEDTYPES.fields_by_name['packed_int32'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_int32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_int64'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_int64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_uint32'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_uint32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_uint64'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_uint64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_sint32'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_sint32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_sint64'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_sint64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_fixed32'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_fixed32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_fixed64'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_fixed64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_sfixed32'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_sfixed32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_sfixed64'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_sfixed64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_float'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_float']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_double'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_double']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_bool'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_bool']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_enum'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_enum']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_int32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_int32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_int64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_int64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_uint32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_uint32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_uint64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_uint64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_sint32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_sint32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_sint64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_sint64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_fixed32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_fixed32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_fixed64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_fixed64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_sfixed32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_sfixed32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_sfixed64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_sfixed64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_float'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_float']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_double'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_double']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_bool'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_bool']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_enum'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['unpacked_enum']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTDYNAMICEXTENSIONS.fields_by_name['packed_extension'].has_options = True
+_TESTDYNAMICEXTENSIONS.fields_by_name['packed_extension']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+
+_TESTSERVICE = _descriptor.ServiceDescriptor(
+  name='TestService',
+  full_name='protobuf_unittest.TestService',
+  file=DESCRIPTOR,
+  index=0,
+  options=None,
+  serialized_start=12729,
+  serialized_end=12882,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='Foo',
+    full_name='protobuf_unittest.TestService.Foo',
+    index=0,
+    containing_service=None,
+    input_type=_FOOREQUEST,
+    output_type=_FOORESPONSE,
+    options=None,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Bar',
+    full_name='protobuf_unittest.TestService.Bar',
+    index=1,
+    containing_service=None,
+    input_type=_BARREQUEST,
+    output_type=_BARRESPONSE,
+    options=None,
+  ),
+])
+
+TestService = service_reflection.GeneratedServiceType('TestService', (_service.Service,), dict(
+  DESCRIPTOR = _TESTSERVICE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  ))
+
+TestService_Stub = service_reflection.GeneratedServiceStubType('TestService_Stub', (TestService,), dict(
+  DESCRIPTOR = _TESTSERVICE,
+  __module__ = 'google.protobuf.unittest_pb2'
+  ))
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/unittest_proto3_arena_pb2.py b/generator/google/protobuf/unittest_proto3_arena_pb2.py
new file mode 100644
index 0000000..ba2c829
--- /dev/null
+++ b/generator/google/protobuf/unittest_proto3_arena_pb2.py
@@ -0,0 +1,1014 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/unittest_proto3_arena.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import unittest_import_pb2 as google_dot_protobuf_dot_unittest__import__pb2
+google_dot_protobuf_dot_unittest__import__public__pb2 = google_dot_protobuf_dot_unittest__import__pb2.google_dot_protobuf_dot_unittest__import__public__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/unittest_proto3_arena.proto',
+  package='proto3_arena_unittest',
+  syntax='proto3',
+  serialized_pb=_b('\n+google/protobuf/unittest_proto3_arena.proto\x12\x15proto3_arena_unittest\x1a%google/protobuf/unittest_import.proto\"\xf6\x10\n\x0cTestAllTypes\x12\x16\n\x0eoptional_int32\x18\x01 \x01(\x05\x12\x16\n\x0eoptional_int64\x18\x02 \x01(\x03\x12\x17\n\x0foptional_uint32\x18\x03 \x01(\r\x12\x17\n\x0foptional_uint64\x18\x04 \x01(\x04\x12\x17\n\x0foptional_sint32\x18\x05 \x01(\x11\x12\x17\n\x0foptional_sint64\x18\x06 \x01(\x12\x12\x18\n\x10optional_fixed32\x18\x07 \x01(\x07\x12\x18\n\x10optional_fixed64\x18\x08 \x01(\x06\x12\x19\n\x11optional_sfixed32\x18\t \x01(\x0f\x12\x19\n\x11optional_sfixed64\x18\n \x01(\x10\x12\x16\n\x0eoptional_float\x18\x0b \x01(\x02\x12\x17\n\x0foptional_double\x18\x0c \x01(\x01\x12\x15\n\roptional_bool\x18\r \x01(\x08\x12\x17\n\x0foptional_string\x18\x0e \x01(\t\x12\x16\n\x0eoptional_bytes\x18\x0f \x01(\x0c\x12R\n\x17optional_nested_message\x18\x12 \x01(\x0b\x32\x31.proto3_arena_unittest.TestAllTypes.NestedMessage\x12G\n\x18optional_foreign_message\x18\x13 \x01(\x0b\x32%.proto3_arena_unittest.ForeignMessage\x12H\n\x17optional_import_message\x18\x14 \x01(\x0b\x32\'.protobuf_unittest_import.ImportMessage\x12L\n\x14optional_nested_enum\x18\x15 \x01(\x0e\x32..proto3_arena_unittest.TestAllTypes.NestedEnum\x12\x41\n\x15optional_foreign_enum\x18\x16 \x01(\x0e\x32\".proto3_arena_unittest.ForeignEnum\x12!\n\x15optional_string_piece\x18\x18 \x01(\tB\x02\x08\x02\x12\x19\n\roptional_cord\x18\x19 \x01(\tB\x02\x08\x01\x12U\n\x1eoptional_public_import_message\x18\x1a \x01(\x0b\x32-.protobuf_unittest_import.PublicImportMessage\x12T\n\x15optional_lazy_message\x18\x1b \x01(\x0b\x32\x31.proto3_arena_unittest.TestAllTypes.NestedMessageB\x02(\x01\x12\x16\n\x0erepeated_int32\x18\x1f \x03(\x05\x12\x16\n\x0erepeated_int64\x18  \x03(\x03\x12\x17\n\x0frepeated_uint32\x18! \x03(\r\x12\x17\n\x0frepeated_uint64\x18\" \x03(\x04\x12\x17\n\x0frepeated_sint32\x18# \x03(\x11\x12\x17\n\x0frepeated_sint64\x18$ \x03(\x12\x12\x18\n\x10repeated_fixed32\x18% \x03(\x07\x12\x18\n\x10repeated_fixed64\x18& \x03(\x06\x12\x19\n\x11repeated_sfixed32\x18\' \x03(\x0f\x12\x19\n\x11repeated_sfixed64\x18( \x03(\x10\x12\x16\n\x0erepeated_float\x18) \x03(\x02\x12\x17\n\x0frepeated_double\x18* \x03(\x01\x12\x15\n\rrepeated_bool\x18+ \x03(\x08\x12\x17\n\x0frepeated_string\x18, \x03(\t\x12\x16\n\x0erepeated_bytes\x18- \x03(\x0c\x12R\n\x17repeated_nested_message\x18\x30 \x03(\x0b\x32\x31.proto3_arena_unittest.TestAllTypes.NestedMessage\x12G\n\x18repeated_foreign_message\x18\x31 \x03(\x0b\x32%.proto3_arena_unittest.ForeignMessage\x12H\n\x17repeated_import_message\x18\x32 \x03(\x0b\x32\'.protobuf_unittest_import.ImportMessage\x12L\n\x14repeated_nested_enum\x18\x33 \x03(\x0e\x32..proto3_arena_unittest.TestAllTypes.NestedEnum\x12\x41\n\x15repeated_foreign_enum\x18\x34 \x03(\x0e\x32\".proto3_arena_unittest.ForeignEnum\x12!\n\x15repeated_string_piece\x18\x36 \x03(\tB\x02\x08\x02\x12\x19\n\rrepeated_cord\x18\x37 \x03(\tB\x02\x08\x01\x12T\n\x15repeated_lazy_message\x18\x39 \x03(\x0b\x32\x31.proto3_arena_unittest.TestAllTypes.NestedMessageB\x02(\x01\x12\x16\n\x0coneof_uint32\x18o \x01(\rH\x00\x12Q\n\x14oneof_nested_message\x18p \x01(\x0b\x32\x31.proto3_arena_unittest.TestAllTypes.NestedMessageH\x00\x12\x16\n\x0coneof_string\x18q \x01(\tH\x00\x12\x15\n\x0boneof_bytes\x18r \x01(\x0cH\x00\x1a\x1b\n\rNestedMessage\x12\n\n\x02\x62\x62\x18\x01 \x01(\x05\"C\n\nNestedEnum\x12\x08\n\x04ZERO\x10\x00\x12\x07\n\x03\x46OO\x10\x01\x12\x07\n\x03\x42\x41R\x10\x02\x12\x07\n\x03\x42\x41Z\x10\x03\x12\x10\n\x03NEG\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x42\r\n\x0boneof_field\"\xae\x03\n\x0fTestPackedTypes\x12\x18\n\x0cpacked_int32\x18Z \x03(\x05\x42\x02\x10\x01\x12\x18\n\x0cpacked_int64\x18[ \x03(\x03\x42\x02\x10\x01\x12\x19\n\rpacked_uint32\x18\\ \x03(\rB\x02\x10\x01\x12\x19\n\rpacked_uint64\x18] \x03(\x04\x42\x02\x10\x01\x12\x19\n\rpacked_sint32\x18^ \x03(\x11\x42\x02\x10\x01\x12\x19\n\rpacked_sint64\x18_ \x03(\x12\x42\x02\x10\x01\x12\x1a\n\x0epacked_fixed32\x18` \x03(\x07\x42\x02\x10\x01\x12\x1a\n\x0epacked_fixed64\x18\x61 \x03(\x06\x42\x02\x10\x01\x12\x1b\n\x0fpacked_sfixed32\x18\x62 \x03(\x0f\x42\x02\x10\x01\x12\x1b\n\x0fpacked_sfixed64\x18\x63 \x03(\x10\x42\x02\x10\x01\x12\x18\n\x0cpacked_float\x18\x64 \x03(\x02\x42\x02\x10\x01\x12\x19\n\rpacked_double\x18\x65 \x03(\x01\x42\x02\x10\x01\x12\x17\n\x0bpacked_bool\x18\x66 \x03(\x08\x42\x02\x10\x01\x12;\n\x0bpacked_enum\x18g \x03(\x0e\x32\".proto3_arena_unittest.ForeignEnumB\x02\x10\x01\"\xdf\x03\n\x11TestUnpackedTypes\x12\x1a\n\x0erepeated_int32\x18\x01 \x03(\x05\x42\x02\x10\x00\x12\x1a\n\x0erepeated_int64\x18\x02 \x03(\x03\x42\x02\x10\x00\x12\x1b\n\x0frepeated_uint32\x18\x03 \x03(\rB\x02\x10\x00\x12\x1b\n\x0frepeated_uint64\x18\x04 \x03(\x04\x42\x02\x10\x00\x12\x1b\n\x0frepeated_sint32\x18\x05 \x03(\x11\x42\x02\x10\x00\x12\x1b\n\x0frepeated_sint64\x18\x06 \x03(\x12\x42\x02\x10\x00\x12\x1c\n\x10repeated_fixed32\x18\x07 \x03(\x07\x42\x02\x10\x00\x12\x1c\n\x10repeated_fixed64\x18\x08 \x03(\x06\x42\x02\x10\x00\x12\x1d\n\x11repeated_sfixed32\x18\t \x03(\x0f\x42\x02\x10\x00\x12\x1d\n\x11repeated_sfixed64\x18\n \x03(\x10\x42\x02\x10\x00\x12\x1a\n\x0erepeated_float\x18\x0b \x03(\x02\x42\x02\x10\x00\x12\x1b\n\x0frepeated_double\x18\x0c \x03(\x01\x42\x02\x10\x00\x12\x19\n\rrepeated_bool\x18\r \x03(\x08\x42\x02\x10\x00\x12P\n\x14repeated_nested_enum\x18\x0e \x03(\x0e\x32..proto3_arena_unittest.TestAllTypes.NestedEnumB\x02\x10\x00\"\x84\x01\n\x12NestedTestAllTypes\x12\x38\n\x05\x63hild\x18\x01 \x01(\x0b\x32).proto3_arena_unittest.NestedTestAllTypes\x12\x34\n\x07payload\x18\x02 \x01(\x0b\x32#.proto3_arena_unittest.TestAllTypes\"\x1b\n\x0e\x46oreignMessage\x12\t\n\x01\x63\x18\x01 \x01(\x05\"\x12\n\x10TestEmptyMessage*R\n\x0b\x46oreignEnum\x12\x10\n\x0c\x46OREIGN_ZERO\x10\x00\x12\x0f\n\x0b\x46OREIGN_FOO\x10\x04\x12\x0f\n\x0b\x46OREIGN_BAR\x10\x05\x12\x0f\n\x0b\x46OREIGN_BAZ\x10\x06\x42\x03\xf8\x01\x01\x62\x06proto3')
+  ,
+  dependencies=[google_dot_protobuf_dot_unittest__import__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+_FOREIGNENUM = _descriptor.EnumDescriptor(
+  name='ForeignEnum',
+  full_name='proto3_arena_unittest.ForeignEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='FOREIGN_ZERO', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FOREIGN_FOO', index=1, number=4,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FOREIGN_BAR', index=2, number=5,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FOREIGN_BAZ', index=3, number=6,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=3377,
+  serialized_end=3459,
+)
+_sym_db.RegisterEnumDescriptor(_FOREIGNENUM)
+
+ForeignEnum = enum_type_wrapper.EnumTypeWrapper(_FOREIGNENUM)
+FOREIGN_ZERO = 0
+FOREIGN_FOO = 4
+FOREIGN_BAR = 5
+FOREIGN_BAZ = 6
+
+
+_TESTALLTYPES_NESTEDENUM = _descriptor.EnumDescriptor(
+  name='NestedEnum',
+  full_name='proto3_arena_unittest.TestAllTypes.NestedEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='ZERO', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FOO', index=1, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAR', index=2, number=2,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAZ', index=3, number=3,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='NEG', index=4, number=-1,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=2194,
+  serialized_end=2261,
+)
+_sym_db.RegisterEnumDescriptor(_TESTALLTYPES_NESTEDENUM)
+
+
+_TESTALLTYPES_NESTEDMESSAGE = _descriptor.Descriptor(
+  name='NestedMessage',
+  full_name='proto3_arena_unittest.TestAllTypes.NestedMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='bb', full_name='proto3_arena_unittest.TestAllTypes.NestedMessage.bb', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2165,
+  serialized_end=2192,
+)
+
+_TESTALLTYPES = _descriptor.Descriptor(
+  name='TestAllTypes',
+  full_name='proto3_arena_unittest.TestAllTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='optional_int32', full_name='proto3_arena_unittest.TestAllTypes.optional_int32', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_int64', full_name='proto3_arena_unittest.TestAllTypes.optional_int64', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_uint32', full_name='proto3_arena_unittest.TestAllTypes.optional_uint32', index=2,
+      number=3, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_uint64', full_name='proto3_arena_unittest.TestAllTypes.optional_uint64', index=3,
+      number=4, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_sint32', full_name='proto3_arena_unittest.TestAllTypes.optional_sint32', index=4,
+      number=5, type=17, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_sint64', full_name='proto3_arena_unittest.TestAllTypes.optional_sint64', index=5,
+      number=6, type=18, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_fixed32', full_name='proto3_arena_unittest.TestAllTypes.optional_fixed32', index=6,
+      number=7, type=7, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_fixed64', full_name='proto3_arena_unittest.TestAllTypes.optional_fixed64', index=7,
+      number=8, type=6, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_sfixed32', full_name='proto3_arena_unittest.TestAllTypes.optional_sfixed32', index=8,
+      number=9, type=15, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_sfixed64', full_name='proto3_arena_unittest.TestAllTypes.optional_sfixed64', index=9,
+      number=10, type=16, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_float', full_name='proto3_arena_unittest.TestAllTypes.optional_float', index=10,
+      number=11, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_double', full_name='proto3_arena_unittest.TestAllTypes.optional_double', index=11,
+      number=12, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_bool', full_name='proto3_arena_unittest.TestAllTypes.optional_bool', index=12,
+      number=13, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_string', full_name='proto3_arena_unittest.TestAllTypes.optional_string', index=13,
+      number=14, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_bytes', full_name='proto3_arena_unittest.TestAllTypes.optional_bytes', index=14,
+      number=15, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_nested_message', full_name='proto3_arena_unittest.TestAllTypes.optional_nested_message', index=15,
+      number=18, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_foreign_message', full_name='proto3_arena_unittest.TestAllTypes.optional_foreign_message', index=16,
+      number=19, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_import_message', full_name='proto3_arena_unittest.TestAllTypes.optional_import_message', index=17,
+      number=20, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_nested_enum', full_name='proto3_arena_unittest.TestAllTypes.optional_nested_enum', index=18,
+      number=21, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_foreign_enum', full_name='proto3_arena_unittest.TestAllTypes.optional_foreign_enum', index=19,
+      number=22, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_string_piece', full_name='proto3_arena_unittest.TestAllTypes.optional_string_piece', index=20,
+      number=24, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))),
+    _descriptor.FieldDescriptor(
+      name='optional_cord', full_name='proto3_arena_unittest.TestAllTypes.optional_cord', index=21,
+      number=25, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))),
+    _descriptor.FieldDescriptor(
+      name='optional_public_import_message', full_name='proto3_arena_unittest.TestAllTypes.optional_public_import_message', index=22,
+      number=26, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='optional_lazy_message', full_name='proto3_arena_unittest.TestAllTypes.optional_lazy_message', index=23,
+      number=27, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_int32', full_name='proto3_arena_unittest.TestAllTypes.repeated_int32', index=24,
+      number=31, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_int64', full_name='proto3_arena_unittest.TestAllTypes.repeated_int64', index=25,
+      number=32, type=3, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint32', full_name='proto3_arena_unittest.TestAllTypes.repeated_uint32', index=26,
+      number=33, type=13, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint64', full_name='proto3_arena_unittest.TestAllTypes.repeated_uint64', index=27,
+      number=34, type=4, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sint32', full_name='proto3_arena_unittest.TestAllTypes.repeated_sint32', index=28,
+      number=35, type=17, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sint64', full_name='proto3_arena_unittest.TestAllTypes.repeated_sint64', index=29,
+      number=36, type=18, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed32', full_name='proto3_arena_unittest.TestAllTypes.repeated_fixed32', index=30,
+      number=37, type=7, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed64', full_name='proto3_arena_unittest.TestAllTypes.repeated_fixed64', index=31,
+      number=38, type=6, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sfixed32', full_name='proto3_arena_unittest.TestAllTypes.repeated_sfixed32', index=32,
+      number=39, type=15, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_sfixed64', full_name='proto3_arena_unittest.TestAllTypes.repeated_sfixed64', index=33,
+      number=40, type=16, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_float', full_name='proto3_arena_unittest.TestAllTypes.repeated_float', index=34,
+      number=41, type=2, cpp_type=6, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_double', full_name='proto3_arena_unittest.TestAllTypes.repeated_double', index=35,
+      number=42, type=1, cpp_type=5, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_bool', full_name='proto3_arena_unittest.TestAllTypes.repeated_bool', index=36,
+      number=43, type=8, cpp_type=7, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_string', full_name='proto3_arena_unittest.TestAllTypes.repeated_string', index=37,
+      number=44, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_bytes', full_name='proto3_arena_unittest.TestAllTypes.repeated_bytes', index=38,
+      number=45, type=12, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_nested_message', full_name='proto3_arena_unittest.TestAllTypes.repeated_nested_message', index=39,
+      number=48, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_foreign_message', full_name='proto3_arena_unittest.TestAllTypes.repeated_foreign_message', index=40,
+      number=49, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_import_message', full_name='proto3_arena_unittest.TestAllTypes.repeated_import_message', index=41,
+      number=50, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_nested_enum', full_name='proto3_arena_unittest.TestAllTypes.repeated_nested_enum', index=42,
+      number=51, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_foreign_enum', full_name='proto3_arena_unittest.TestAllTypes.repeated_foreign_enum', index=43,
+      number=52, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_string_piece', full_name='proto3_arena_unittest.TestAllTypes.repeated_string_piece', index=44,
+      number=54, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_cord', full_name='proto3_arena_unittest.TestAllTypes.repeated_cord', index=45,
+      number=55, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_lazy_message', full_name='proto3_arena_unittest.TestAllTypes.repeated_lazy_message', index=46,
+      number=57, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))),
+    _descriptor.FieldDescriptor(
+      name='oneof_uint32', full_name='proto3_arena_unittest.TestAllTypes.oneof_uint32', index=47,
+      number=111, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_nested_message', full_name='proto3_arena_unittest.TestAllTypes.oneof_nested_message', index=48,
+      number=112, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_string', full_name='proto3_arena_unittest.TestAllTypes.oneof_string', index=49,
+      number=113, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_bytes', full_name='proto3_arena_unittest.TestAllTypes.oneof_bytes', index=50,
+      number=114, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTALLTYPES_NESTEDMESSAGE, ],
+  enum_types=[
+    _TESTALLTYPES_NESTEDENUM,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='oneof_field', full_name='proto3_arena_unittest.TestAllTypes.oneof_field',
+      index=0, containing_type=None, fields=[]),
+  ],
+  serialized_start=110,
+  serialized_end=2276,
+)
+
+
+_TESTPACKEDTYPES = _descriptor.Descriptor(
+  name='TestPackedTypes',
+  full_name='proto3_arena_unittest.TestPackedTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='packed_int32', full_name='proto3_arena_unittest.TestPackedTypes.packed_int32', index=0,
+      number=90, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_int64', full_name='proto3_arena_unittest.TestPackedTypes.packed_int64', index=1,
+      number=91, type=3, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_uint32', full_name='proto3_arena_unittest.TestPackedTypes.packed_uint32', index=2,
+      number=92, type=13, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_uint64', full_name='proto3_arena_unittest.TestPackedTypes.packed_uint64', index=3,
+      number=93, type=4, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_sint32', full_name='proto3_arena_unittest.TestPackedTypes.packed_sint32', index=4,
+      number=94, type=17, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_sint64', full_name='proto3_arena_unittest.TestPackedTypes.packed_sint64', index=5,
+      number=95, type=18, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_fixed32', full_name='proto3_arena_unittest.TestPackedTypes.packed_fixed32', index=6,
+      number=96, type=7, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_fixed64', full_name='proto3_arena_unittest.TestPackedTypes.packed_fixed64', index=7,
+      number=97, type=6, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_sfixed32', full_name='proto3_arena_unittest.TestPackedTypes.packed_sfixed32', index=8,
+      number=98, type=15, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_sfixed64', full_name='proto3_arena_unittest.TestPackedTypes.packed_sfixed64', index=9,
+      number=99, type=16, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_float', full_name='proto3_arena_unittest.TestPackedTypes.packed_float', index=10,
+      number=100, type=2, cpp_type=6, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_double', full_name='proto3_arena_unittest.TestPackedTypes.packed_double', index=11,
+      number=101, type=1, cpp_type=5, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_bool', full_name='proto3_arena_unittest.TestPackedTypes.packed_bool', index=12,
+      number=102, type=8, cpp_type=7, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+    _descriptor.FieldDescriptor(
+      name='packed_enum', full_name='proto3_arena_unittest.TestPackedTypes.packed_enum', index=13,
+      number=103, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2279,
+  serialized_end=2709,
+)
+
+
+_TESTUNPACKEDTYPES = _descriptor.Descriptor(
+  name='TestUnpackedTypes',
+  full_name='proto3_arena_unittest.TestUnpackedTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='repeated_int32', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_int32', index=0,
+      number=1, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_int64', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_int64', index=1,
+      number=2, type=3, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint32', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_uint32', index=2,
+      number=3, type=13, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint64', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_uint64', index=3,
+      number=4, type=4, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_sint32', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_sint32', index=4,
+      number=5, type=17, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_sint64', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_sint64', index=5,
+      number=6, type=18, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed32', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_fixed32', index=6,
+      number=7, type=7, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_fixed64', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_fixed64', index=7,
+      number=8, type=6, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_sfixed32', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_sfixed32', index=8,
+      number=9, type=15, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_sfixed64', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_sfixed64', index=9,
+      number=10, type=16, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_float', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_float', index=10,
+      number=11, type=2, cpp_type=6, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_double', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_double', index=11,
+      number=12, type=1, cpp_type=5, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_bool', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_bool', index=12,
+      number=13, type=8, cpp_type=7, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+    _descriptor.FieldDescriptor(
+      name='repeated_nested_enum', full_name='proto3_arena_unittest.TestUnpackedTypes.repeated_nested_enum', index=13,
+      number=14, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2712,
+  serialized_end=3191,
+)
+
+
+_NESTEDTESTALLTYPES = _descriptor.Descriptor(
+  name='NestedTestAllTypes',
+  full_name='proto3_arena_unittest.NestedTestAllTypes',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='child', full_name='proto3_arena_unittest.NestedTestAllTypes.child', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='payload', full_name='proto3_arena_unittest.NestedTestAllTypes.payload', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3194,
+  serialized_end=3326,
+)
+
+
+_FOREIGNMESSAGE = _descriptor.Descriptor(
+  name='ForeignMessage',
+  full_name='proto3_arena_unittest.ForeignMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='c', full_name='proto3_arena_unittest.ForeignMessage.c', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3328,
+  serialized_end=3355,
+)
+
+
+_TESTEMPTYMESSAGE = _descriptor.Descriptor(
+  name='TestEmptyMessage',
+  full_name='proto3_arena_unittest.TestEmptyMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3357,
+  serialized_end=3375,
+)
+
+_TESTALLTYPES_NESTEDMESSAGE.containing_type = _TESTALLTYPES
+_TESTALLTYPES.fields_by_name['optional_nested_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['optional_foreign_message'].message_type = _FOREIGNMESSAGE
+_TESTALLTYPES.fields_by_name['optional_import_message'].message_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTMESSAGE
+_TESTALLTYPES.fields_by_name['optional_nested_enum'].enum_type = _TESTALLTYPES_NESTEDENUM
+_TESTALLTYPES.fields_by_name['optional_foreign_enum'].enum_type = _FOREIGNENUM
+_TESTALLTYPES.fields_by_name['optional_public_import_message'].message_type = google_dot_protobuf_dot_unittest__import__public__pb2._PUBLICIMPORTMESSAGE
+_TESTALLTYPES.fields_by_name['optional_lazy_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['repeated_nested_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['repeated_foreign_message'].message_type = _FOREIGNMESSAGE
+_TESTALLTYPES.fields_by_name['repeated_import_message'].message_type = google_dot_protobuf_dot_unittest__import__pb2._IMPORTMESSAGE
+_TESTALLTYPES.fields_by_name['repeated_nested_enum'].enum_type = _TESTALLTYPES_NESTEDENUM
+_TESTALLTYPES.fields_by_name['repeated_foreign_enum'].enum_type = _FOREIGNENUM
+_TESTALLTYPES.fields_by_name['repeated_lazy_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES.fields_by_name['oneof_nested_message'].message_type = _TESTALLTYPES_NESTEDMESSAGE
+_TESTALLTYPES_NESTEDENUM.containing_type = _TESTALLTYPES
+_TESTALLTYPES.oneofs_by_name['oneof_field'].fields.append(
+  _TESTALLTYPES.fields_by_name['oneof_uint32'])
+_TESTALLTYPES.fields_by_name['oneof_uint32'].containing_oneof = _TESTALLTYPES.oneofs_by_name['oneof_field']
+_TESTALLTYPES.oneofs_by_name['oneof_field'].fields.append(
+  _TESTALLTYPES.fields_by_name['oneof_nested_message'])
+_TESTALLTYPES.fields_by_name['oneof_nested_message'].containing_oneof = _TESTALLTYPES.oneofs_by_name['oneof_field']
+_TESTALLTYPES.oneofs_by_name['oneof_field'].fields.append(
+  _TESTALLTYPES.fields_by_name['oneof_string'])
+_TESTALLTYPES.fields_by_name['oneof_string'].containing_oneof = _TESTALLTYPES.oneofs_by_name['oneof_field']
+_TESTALLTYPES.oneofs_by_name['oneof_field'].fields.append(
+  _TESTALLTYPES.fields_by_name['oneof_bytes'])
+_TESTALLTYPES.fields_by_name['oneof_bytes'].containing_oneof = _TESTALLTYPES.oneofs_by_name['oneof_field']
+_TESTPACKEDTYPES.fields_by_name['packed_enum'].enum_type = _FOREIGNENUM
+_TESTUNPACKEDTYPES.fields_by_name['repeated_nested_enum'].enum_type = _TESTALLTYPES_NESTEDENUM
+_NESTEDTESTALLTYPES.fields_by_name['child'].message_type = _NESTEDTESTALLTYPES
+_NESTEDTESTALLTYPES.fields_by_name['payload'].message_type = _TESTALLTYPES
+DESCRIPTOR.message_types_by_name['TestAllTypes'] = _TESTALLTYPES
+DESCRIPTOR.message_types_by_name['TestPackedTypes'] = _TESTPACKEDTYPES
+DESCRIPTOR.message_types_by_name['TestUnpackedTypes'] = _TESTUNPACKEDTYPES
+DESCRIPTOR.message_types_by_name['NestedTestAllTypes'] = _NESTEDTESTALLTYPES
+DESCRIPTOR.message_types_by_name['ForeignMessage'] = _FOREIGNMESSAGE
+DESCRIPTOR.message_types_by_name['TestEmptyMessage'] = _TESTEMPTYMESSAGE
+DESCRIPTOR.enum_types_by_name['ForeignEnum'] = _FOREIGNENUM
+
+TestAllTypes = _reflection.GeneratedProtocolMessageType('TestAllTypes', (_message.Message,), dict(
+
+  NestedMessage = _reflection.GeneratedProtocolMessageType('NestedMessage', (_message.Message,), dict(
+    DESCRIPTOR = _TESTALLTYPES_NESTEDMESSAGE,
+    __module__ = 'google.protobuf.unittest_proto3_arena_pb2'
+    # @@protoc_insertion_point(class_scope:proto3_arena_unittest.TestAllTypes.NestedMessage)
+    ))
+  ,
+  DESCRIPTOR = _TESTALLTYPES,
+  __module__ = 'google.protobuf.unittest_proto3_arena_pb2'
+  # @@protoc_insertion_point(class_scope:proto3_arena_unittest.TestAllTypes)
+  ))
+_sym_db.RegisterMessage(TestAllTypes)
+_sym_db.RegisterMessage(TestAllTypes.NestedMessage)
+
+TestPackedTypes = _reflection.GeneratedProtocolMessageType('TestPackedTypes', (_message.Message,), dict(
+  DESCRIPTOR = _TESTPACKEDTYPES,
+  __module__ = 'google.protobuf.unittest_proto3_arena_pb2'
+  # @@protoc_insertion_point(class_scope:proto3_arena_unittest.TestPackedTypes)
+  ))
+_sym_db.RegisterMessage(TestPackedTypes)
+
+TestUnpackedTypes = _reflection.GeneratedProtocolMessageType('TestUnpackedTypes', (_message.Message,), dict(
+  DESCRIPTOR = _TESTUNPACKEDTYPES,
+  __module__ = 'google.protobuf.unittest_proto3_arena_pb2'
+  # @@protoc_insertion_point(class_scope:proto3_arena_unittest.TestUnpackedTypes)
+  ))
+_sym_db.RegisterMessage(TestUnpackedTypes)
+
+NestedTestAllTypes = _reflection.GeneratedProtocolMessageType('NestedTestAllTypes', (_message.Message,), dict(
+  DESCRIPTOR = _NESTEDTESTALLTYPES,
+  __module__ = 'google.protobuf.unittest_proto3_arena_pb2'
+  # @@protoc_insertion_point(class_scope:proto3_arena_unittest.NestedTestAllTypes)
+  ))
+_sym_db.RegisterMessage(NestedTestAllTypes)
+
+ForeignMessage = _reflection.GeneratedProtocolMessageType('ForeignMessage', (_message.Message,), dict(
+  DESCRIPTOR = _FOREIGNMESSAGE,
+  __module__ = 'google.protobuf.unittest_proto3_arena_pb2'
+  # @@protoc_insertion_point(class_scope:proto3_arena_unittest.ForeignMessage)
+  ))
+_sym_db.RegisterMessage(ForeignMessage)
+
+TestEmptyMessage = _reflection.GeneratedProtocolMessageType('TestEmptyMessage', (_message.Message,), dict(
+  DESCRIPTOR = _TESTEMPTYMESSAGE,
+  __module__ = 'google.protobuf.unittest_proto3_arena_pb2'
+  # @@protoc_insertion_point(class_scope:proto3_arena_unittest.TestEmptyMessage)
+  ))
+_sym_db.RegisterMessage(TestEmptyMessage)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\370\001\001'))
+_TESTALLTYPES.fields_by_name['optional_string_piece'].has_options = True
+_TESTALLTYPES.fields_by_name['optional_string_piece']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+_TESTALLTYPES.fields_by_name['optional_cord'].has_options = True
+_TESTALLTYPES.fields_by_name['optional_cord']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+_TESTALLTYPES.fields_by_name['optional_lazy_message'].has_options = True
+_TESTALLTYPES.fields_by_name['optional_lazy_message']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))
+_TESTALLTYPES.fields_by_name['repeated_string_piece'].has_options = True
+_TESTALLTYPES.fields_by_name['repeated_string_piece']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\002'))
+_TESTALLTYPES.fields_by_name['repeated_cord'].has_options = True
+_TESTALLTYPES.fields_by_name['repeated_cord']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\010\001'))
+_TESTALLTYPES.fields_by_name['repeated_lazy_message'].has_options = True
+_TESTALLTYPES.fields_by_name['repeated_lazy_message']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('(\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_int32'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_int32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_int64'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_int64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_uint32'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_uint32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_uint64'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_uint64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_sint32'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_sint32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_sint64'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_sint64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_fixed32'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_fixed32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_fixed64'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_fixed64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_sfixed32'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_sfixed32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_sfixed64'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_sfixed64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_float'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_float']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_double'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_double']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_bool'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_bool']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTPACKEDTYPES.fields_by_name['packed_enum'].has_options = True
+_TESTPACKEDTYPES.fields_by_name['packed_enum']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\001'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_int32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_int32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_int64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_int64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_uint32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_uint32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_uint64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_uint64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sint32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sint32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sint64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sint64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_fixed32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_fixed32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_fixed64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_fixed64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sfixed32'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sfixed32']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sfixed64'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_sfixed64']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_float'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_float']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_double'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_double']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_bool'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_bool']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+_TESTUNPACKEDTYPES.fields_by_name['repeated_nested_enum'].has_options = True
+_TESTUNPACKEDTYPES.fields_by_name['repeated_nested_enum']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\020\000'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/util/__init__.py b/generator/google/protobuf/util/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/generator/google/protobuf/util/__init__.py
diff --git a/generator/google/protobuf/util/json_format_proto3_pb2.py b/generator/google/protobuf/util/json_format_proto3_pb2.py
new file mode 100644
index 0000000..d7aaf29
--- /dev/null
+++ b/generator/google/protobuf/util/json_format_proto3_pb2.py
@@ -0,0 +1,1852 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/util/json_format_proto3.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2
+from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
+from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2
+from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
+from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
+from google.protobuf import field_mask_pb2 as google_dot_protobuf_dot_field__mask__pb2
+from google.protobuf import unittest_pb2 as google_dot_protobuf_dot_unittest__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/util/json_format_proto3.proto',
+  package='proto3',
+  syntax='proto3',
+  serialized_pb=_b('\n-google/protobuf/util/json_format_proto3.proto\x12\x06proto3\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x19google/protobuf/any.proto\x1a google/protobuf/field_mask.proto\x1a\x1egoogle/protobuf/unittest.proto\"\x1c\n\x0bMessageType\x12\r\n\x05value\x18\x01 \x01(\x05\"\x94\x05\n\x0bTestMessage\x12\x12\n\nbool_value\x18\x01 \x01(\x08\x12\x13\n\x0bint32_value\x18\x02 \x01(\x05\x12\x13\n\x0bint64_value\x18\x03 \x01(\x03\x12\x14\n\x0cuint32_value\x18\x04 \x01(\r\x12\x14\n\x0cuint64_value\x18\x05 \x01(\x04\x12\x13\n\x0b\x66loat_value\x18\x06 \x01(\x02\x12\x14\n\x0c\x64ouble_value\x18\x07 \x01(\x01\x12\x14\n\x0cstring_value\x18\x08 \x01(\t\x12\x13\n\x0b\x62ytes_value\x18\t \x01(\x0c\x12$\n\nenum_value\x18\n \x01(\x0e\x32\x10.proto3.EnumType\x12*\n\rmessage_value\x18\x0b \x01(\x0b\x32\x13.proto3.MessageType\x12\x1b\n\x13repeated_bool_value\x18\x15 \x03(\x08\x12\x1c\n\x14repeated_int32_value\x18\x16 \x03(\x05\x12\x1c\n\x14repeated_int64_value\x18\x17 \x03(\x03\x12\x1d\n\x15repeated_uint32_value\x18\x18 \x03(\r\x12\x1d\n\x15repeated_uint64_value\x18\x19 \x03(\x04\x12\x1c\n\x14repeated_float_value\x18\x1a \x03(\x02\x12\x1d\n\x15repeated_double_value\x18\x1b \x03(\x01\x12\x1d\n\x15repeated_string_value\x18\x1c \x03(\t\x12\x1c\n\x14repeated_bytes_value\x18\x1d \x03(\x0c\x12-\n\x13repeated_enum_value\x18\x1e \x03(\x0e\x32\x10.proto3.EnumType\x12\x33\n\x16repeated_message_value\x18\x1f \x03(\x0b\x32\x13.proto3.MessageType\"\xd4\x01\n\tTestOneof\x12\x1b\n\x11oneof_int32_value\x18\x01 \x01(\x05H\x00\x12\x1c\n\x12oneof_string_value\x18\x02 \x01(\tH\x00\x12\x1b\n\x11oneof_bytes_value\x18\x03 \x01(\x0cH\x00\x12,\n\x10oneof_enum_value\x18\x04 \x01(\x0e\x32\x10.proto3.EnumTypeH\x00\x12\x32\n\x13oneof_message_value\x18\x05 \x01(\x0b\x32\x13.proto3.MessageTypeH\x00\x42\r\n\x0boneof_value\"\xe1\x04\n\x07TestMap\x12.\n\x08\x62ool_map\x18\x01 \x03(\x0b\x32\x1c.proto3.TestMap.BoolMapEntry\x12\x30\n\tint32_map\x18\x02 \x03(\x0b\x32\x1d.proto3.TestMap.Int32MapEntry\x12\x30\n\tint64_map\x18\x03 \x03(\x0b\x32\x1d.proto3.TestMap.Int64MapEntry\x12\x32\n\nuint32_map\x18\x04 \x03(\x0b\x32\x1e.proto3.TestMap.Uint32MapEntry\x12\x32\n\nuint64_map\x18\x05 \x03(\x0b\x32\x1e.proto3.TestMap.Uint64MapEntry\x12\x32\n\nstring_map\x18\x06 \x03(\x0b\x32\x1e.proto3.TestMap.StringMapEntry\x1a.\n\x0c\x42oolMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a/\n\rInt32MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a/\n\rInt64MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x03\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eUint32MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eUint64MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eStringMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"\x85\x06\n\rTestNestedMap\x12\x34\n\x08\x62ool_map\x18\x01 \x03(\x0b\x32\".proto3.TestNestedMap.BoolMapEntry\x12\x36\n\tint32_map\x18\x02 \x03(\x0b\x32#.proto3.TestNestedMap.Int32MapEntry\x12\x36\n\tint64_map\x18\x03 \x03(\x0b\x32#.proto3.TestNestedMap.Int64MapEntry\x12\x38\n\nuint32_map\x18\x04 \x03(\x0b\x32$.proto3.TestNestedMap.Uint32MapEntry\x12\x38\n\nuint64_map\x18\x05 \x03(\x0b\x32$.proto3.TestNestedMap.Uint64MapEntry\x12\x38\n\nstring_map\x18\x06 \x03(\x0b\x32$.proto3.TestNestedMap.StringMapEntry\x12\x32\n\x07map_map\x18\x07 \x03(\x0b\x32!.proto3.TestNestedMap.MapMapEntry\x1a.\n\x0c\x42oolMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a/\n\rInt32MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a/\n\rInt64MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x03\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eUint32MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eUint64MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eStringMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x44\n\x0bMapMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.proto3.TestNestedMap:\x02\x38\x01\"\xee\x07\n\x0bTestWrapper\x12.\n\nbool_value\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x30\n\x0bint32_value\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x30\n\x0bint64_value\x18\x03 \x01(\x0b\x32\x1b.google.protobuf.Int64Value\x12\x32\n\x0cuint32_value\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.UInt32Value\x12\x32\n\x0cuint64_value\x18\x05 \x01(\x0b\x32\x1c.google.protobuf.UInt64Value\x12\x30\n\x0b\x66loat_value\x18\x06 \x01(\x0b\x32\x1b.google.protobuf.FloatValue\x12\x32\n\x0c\x64ouble_value\x18\x07 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12\x32\n\x0cstring_value\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\x0b\x62ytes_value\x18\t \x01(\x0b\x32\x1b.google.protobuf.BytesValue\x12\x37\n\x13repeated_bool_value\x18\x0b \x03(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x39\n\x14repeated_int32_value\x18\x0c \x03(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x39\n\x14repeated_int64_value\x18\r \x03(\x0b\x32\x1b.google.protobuf.Int64Value\x12;\n\x15repeated_uint32_value\x18\x0e \x03(\x0b\x32\x1c.google.protobuf.UInt32Value\x12;\n\x15repeated_uint64_value\x18\x0f \x03(\x0b\x32\x1c.google.protobuf.UInt64Value\x12\x39\n\x14repeated_float_value\x18\x10 \x03(\x0b\x32\x1b.google.protobuf.FloatValue\x12;\n\x15repeated_double_value\x18\x11 \x03(\x0b\x32\x1c.google.protobuf.DoubleValue\x12;\n\x15repeated_string_value\x18\x12 \x03(\x0b\x32\x1c.google.protobuf.StringValue\x12\x39\n\x14repeated_bytes_value\x18\x13 \x03(\x0b\x32\x1b.google.protobuf.BytesValue\"n\n\rTestTimestamp\x12)\n\x05value\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.Timestamp\"k\n\x0cTestDuration\x12(\n\x05value\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x31\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x19.google.protobuf.Duration\":\n\rTestFieldMask\x12)\n\x05value\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.FieldMask\"e\n\nTestStruct\x12&\n\x05value\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\x12/\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x17.google.protobuf.Struct\"\\\n\x07TestAny\x12#\n\x05value\x18\x01 \x01(\x0b\x32\x14.google.protobuf.Any\x12,\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x14.google.protobuf.Any\"b\n\tTestValue\x12%\n\x05value\x18\x01 \x01(\x0b\x32\x16.google.protobuf.Value\x12.\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x16.google.protobuf.Value\"n\n\rTestListValue\x12)\n\x05value\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.ListValue\x12\x32\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.ListValue\"\x89\x01\n\rTestBoolValue\x12\x12\n\nbool_value\x18\x01 \x01(\x08\x12\x34\n\x08\x62ool_map\x18\x02 \x03(\x0b\x32\".proto3.TestBoolValue.BoolMapEntry\x1a.\n\x0c\x42oolMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"+\n\x12TestCustomJsonName\x12\x15\n\x05value\x18\x01 \x01(\x05R\x06@value\"J\n\x0eTestExtensions\x12\x38\n\nextensions\x18\x01 \x01(\x0b\x32$.protobuf_unittest.TestAllExtensions*\x1c\n\x08\x45numType\x12\x07\n\x03\x46OO\x10\x00\x12\x07\n\x03\x42\x41R\x10\x01\x62\x06proto3')
+  ,
+  dependencies=[google_dot_protobuf_dot_duration__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,google_dot_protobuf_dot_wrappers__pb2.DESCRIPTOR,google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,google_dot_protobuf_dot_any__pb2.DESCRIPTOR,google_dot_protobuf_dot_field__mask__pb2.DESCRIPTOR,google_dot_protobuf_dot_unittest__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+_ENUMTYPE = _descriptor.EnumDescriptor(
+  name='EnumType',
+  full_name='proto3.EnumType',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='FOO', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BAR', index=1, number=1,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=4533,
+  serialized_end=4561,
+)
+_sym_db.RegisterEnumDescriptor(_ENUMTYPE)
+
+EnumType = enum_type_wrapper.EnumTypeWrapper(_ENUMTYPE)
+FOO = 0
+BAR = 1
+
+
+
+_MESSAGETYPE = _descriptor.Descriptor(
+  name='MessageType',
+  full_name='proto3.MessageType',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.MessageType.value', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=277,
+  serialized_end=305,
+)
+
+
+_TESTMESSAGE = _descriptor.Descriptor(
+  name='TestMessage',
+  full_name='proto3.TestMessage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='bool_value', full_name='proto3.TestMessage.bool_value', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='int32_value', full_name='proto3.TestMessage.int32_value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='int64_value', full_name='proto3.TestMessage.int64_value', index=2,
+      number=3, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uint32_value', full_name='proto3.TestMessage.uint32_value', index=3,
+      number=4, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uint64_value', full_name='proto3.TestMessage.uint64_value', index=4,
+      number=5, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='float_value', full_name='proto3.TestMessage.float_value', index=5,
+      number=6, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='double_value', full_name='proto3.TestMessage.double_value', index=6,
+      number=7, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='string_value', full_name='proto3.TestMessage.string_value', index=7,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bytes_value', full_name='proto3.TestMessage.bytes_value', index=8,
+      number=9, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='enum_value', full_name='proto3.TestMessage.enum_value', index=9,
+      number=10, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='message_value', full_name='proto3.TestMessage.message_value', index=10,
+      number=11, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_bool_value', full_name='proto3.TestMessage.repeated_bool_value', index=11,
+      number=21, type=8, cpp_type=7, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_int32_value', full_name='proto3.TestMessage.repeated_int32_value', index=12,
+      number=22, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_int64_value', full_name='proto3.TestMessage.repeated_int64_value', index=13,
+      number=23, type=3, cpp_type=2, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint32_value', full_name='proto3.TestMessage.repeated_uint32_value', index=14,
+      number=24, type=13, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint64_value', full_name='proto3.TestMessage.repeated_uint64_value', index=15,
+      number=25, type=4, cpp_type=4, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_float_value', full_name='proto3.TestMessage.repeated_float_value', index=16,
+      number=26, type=2, cpp_type=6, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_double_value', full_name='proto3.TestMessage.repeated_double_value', index=17,
+      number=27, type=1, cpp_type=5, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_string_value', full_name='proto3.TestMessage.repeated_string_value', index=18,
+      number=28, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_bytes_value', full_name='proto3.TestMessage.repeated_bytes_value', index=19,
+      number=29, type=12, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_enum_value', full_name='proto3.TestMessage.repeated_enum_value', index=20,
+      number=30, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_message_value', full_name='proto3.TestMessage.repeated_message_value', index=21,
+      number=31, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=308,
+  serialized_end=968,
+)
+
+
+_TESTONEOF = _descriptor.Descriptor(
+  name='TestOneof',
+  full_name='proto3.TestOneof',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='oneof_int32_value', full_name='proto3.TestOneof.oneof_int32_value', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_string_value', full_name='proto3.TestOneof.oneof_string_value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_bytes_value', full_name='proto3.TestOneof.oneof_bytes_value', index=2,
+      number=3, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_enum_value', full_name='proto3.TestOneof.oneof_enum_value', index=3,
+      number=4, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='oneof_message_value', full_name='proto3.TestOneof.oneof_message_value', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='oneof_value', full_name='proto3.TestOneof.oneof_value',
+      index=0, containing_type=None, fields=[]),
+  ],
+  serialized_start=971,
+  serialized_end=1183,
+)
+
+
+_TESTMAP_BOOLMAPENTRY = _descriptor.Descriptor(
+  name='BoolMapEntry',
+  full_name='proto3.TestMap.BoolMapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestMap.BoolMapEntry.key', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestMap.BoolMapEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1501,
+  serialized_end=1547,
+)
+
+_TESTMAP_INT32MAPENTRY = _descriptor.Descriptor(
+  name='Int32MapEntry',
+  full_name='proto3.TestMap.Int32MapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestMap.Int32MapEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestMap.Int32MapEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1549,
+  serialized_end=1596,
+)
+
+_TESTMAP_INT64MAPENTRY = _descriptor.Descriptor(
+  name='Int64MapEntry',
+  full_name='proto3.TestMap.Int64MapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestMap.Int64MapEntry.key', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestMap.Int64MapEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1598,
+  serialized_end=1645,
+)
+
+_TESTMAP_UINT32MAPENTRY = _descriptor.Descriptor(
+  name='Uint32MapEntry',
+  full_name='proto3.TestMap.Uint32MapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestMap.Uint32MapEntry.key', index=0,
+      number=1, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestMap.Uint32MapEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1647,
+  serialized_end=1695,
+)
+
+_TESTMAP_UINT64MAPENTRY = _descriptor.Descriptor(
+  name='Uint64MapEntry',
+  full_name='proto3.TestMap.Uint64MapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestMap.Uint64MapEntry.key', index=0,
+      number=1, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestMap.Uint64MapEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1697,
+  serialized_end=1745,
+)
+
+_TESTMAP_STRINGMAPENTRY = _descriptor.Descriptor(
+  name='StringMapEntry',
+  full_name='proto3.TestMap.StringMapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestMap.StringMapEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestMap.StringMapEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1747,
+  serialized_end=1795,
+)
+
+_TESTMAP = _descriptor.Descriptor(
+  name='TestMap',
+  full_name='proto3.TestMap',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='bool_map', full_name='proto3.TestMap.bool_map', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='int32_map', full_name='proto3.TestMap.int32_map', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='int64_map', full_name='proto3.TestMap.int64_map', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uint32_map', full_name='proto3.TestMap.uint32_map', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uint64_map', full_name='proto3.TestMap.uint64_map', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='string_map', full_name='proto3.TestMap.string_map', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTMAP_BOOLMAPENTRY, _TESTMAP_INT32MAPENTRY, _TESTMAP_INT64MAPENTRY, _TESTMAP_UINT32MAPENTRY, _TESTMAP_UINT64MAPENTRY, _TESTMAP_STRINGMAPENTRY, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1186,
+  serialized_end=1795,
+)
+
+
+_TESTNESTEDMAP_BOOLMAPENTRY = _descriptor.Descriptor(
+  name='BoolMapEntry',
+  full_name='proto3.TestNestedMap.BoolMapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestNestedMap.BoolMapEntry.key', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestNestedMap.BoolMapEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1501,
+  serialized_end=1547,
+)
+
+_TESTNESTEDMAP_INT32MAPENTRY = _descriptor.Descriptor(
+  name='Int32MapEntry',
+  full_name='proto3.TestNestedMap.Int32MapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestNestedMap.Int32MapEntry.key', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestNestedMap.Int32MapEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1549,
+  serialized_end=1596,
+)
+
+_TESTNESTEDMAP_INT64MAPENTRY = _descriptor.Descriptor(
+  name='Int64MapEntry',
+  full_name='proto3.TestNestedMap.Int64MapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestNestedMap.Int64MapEntry.key', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestNestedMap.Int64MapEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1598,
+  serialized_end=1645,
+)
+
+_TESTNESTEDMAP_UINT32MAPENTRY = _descriptor.Descriptor(
+  name='Uint32MapEntry',
+  full_name='proto3.TestNestedMap.Uint32MapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestNestedMap.Uint32MapEntry.key', index=0,
+      number=1, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestNestedMap.Uint32MapEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1647,
+  serialized_end=1695,
+)
+
+_TESTNESTEDMAP_UINT64MAPENTRY = _descriptor.Descriptor(
+  name='Uint64MapEntry',
+  full_name='proto3.TestNestedMap.Uint64MapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestNestedMap.Uint64MapEntry.key', index=0,
+      number=1, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestNestedMap.Uint64MapEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1697,
+  serialized_end=1745,
+)
+
+_TESTNESTEDMAP_STRINGMAPENTRY = _descriptor.Descriptor(
+  name='StringMapEntry',
+  full_name='proto3.TestNestedMap.StringMapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestNestedMap.StringMapEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestNestedMap.StringMapEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1747,
+  serialized_end=1795,
+)
+
+_TESTNESTEDMAP_MAPMAPENTRY = _descriptor.Descriptor(
+  name='MapMapEntry',
+  full_name='proto3.TestNestedMap.MapMapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestNestedMap.MapMapEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestNestedMap.MapMapEntry.value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2503,
+  serialized_end=2571,
+)
+
+_TESTNESTEDMAP = _descriptor.Descriptor(
+  name='TestNestedMap',
+  full_name='proto3.TestNestedMap',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='bool_map', full_name='proto3.TestNestedMap.bool_map', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='int32_map', full_name='proto3.TestNestedMap.int32_map', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='int64_map', full_name='proto3.TestNestedMap.int64_map', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uint32_map', full_name='proto3.TestNestedMap.uint32_map', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uint64_map', full_name='proto3.TestNestedMap.uint64_map', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='string_map', full_name='proto3.TestNestedMap.string_map', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='map_map', full_name='proto3.TestNestedMap.map_map', index=6,
+      number=7, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTNESTEDMAP_BOOLMAPENTRY, _TESTNESTEDMAP_INT32MAPENTRY, _TESTNESTEDMAP_INT64MAPENTRY, _TESTNESTEDMAP_UINT32MAPENTRY, _TESTNESTEDMAP_UINT64MAPENTRY, _TESTNESTEDMAP_STRINGMAPENTRY, _TESTNESTEDMAP_MAPMAPENTRY, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1798,
+  serialized_end=2571,
+)
+
+
+_TESTWRAPPER = _descriptor.Descriptor(
+  name='TestWrapper',
+  full_name='proto3.TestWrapper',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='bool_value', full_name='proto3.TestWrapper.bool_value', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='int32_value', full_name='proto3.TestWrapper.int32_value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='int64_value', full_name='proto3.TestWrapper.int64_value', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uint32_value', full_name='proto3.TestWrapper.uint32_value', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uint64_value', full_name='proto3.TestWrapper.uint64_value', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='float_value', full_name='proto3.TestWrapper.float_value', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='double_value', full_name='proto3.TestWrapper.double_value', index=6,
+      number=7, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='string_value', full_name='proto3.TestWrapper.string_value', index=7,
+      number=8, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bytes_value', full_name='proto3.TestWrapper.bytes_value', index=8,
+      number=9, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_bool_value', full_name='proto3.TestWrapper.repeated_bool_value', index=9,
+      number=11, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_int32_value', full_name='proto3.TestWrapper.repeated_int32_value', index=10,
+      number=12, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_int64_value', full_name='proto3.TestWrapper.repeated_int64_value', index=11,
+      number=13, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint32_value', full_name='proto3.TestWrapper.repeated_uint32_value', index=12,
+      number=14, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_uint64_value', full_name='proto3.TestWrapper.repeated_uint64_value', index=13,
+      number=15, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_float_value', full_name='proto3.TestWrapper.repeated_float_value', index=14,
+      number=16, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_double_value', full_name='proto3.TestWrapper.repeated_double_value', index=15,
+      number=17, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_string_value', full_name='proto3.TestWrapper.repeated_string_value', index=16,
+      number=18, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_bytes_value', full_name='proto3.TestWrapper.repeated_bytes_value', index=17,
+      number=19, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2574,
+  serialized_end=3580,
+)
+
+
+_TESTTIMESTAMP = _descriptor.Descriptor(
+  name='TestTimestamp',
+  full_name='proto3.TestTimestamp',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestTimestamp.value', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_value', full_name='proto3.TestTimestamp.repeated_value', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3582,
+  serialized_end=3692,
+)
+
+
+_TESTDURATION = _descriptor.Descriptor(
+  name='TestDuration',
+  full_name='proto3.TestDuration',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestDuration.value', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_value', full_name='proto3.TestDuration.repeated_value', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3694,
+  serialized_end=3801,
+)
+
+
+_TESTFIELDMASK = _descriptor.Descriptor(
+  name='TestFieldMask',
+  full_name='proto3.TestFieldMask',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestFieldMask.value', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3803,
+  serialized_end=3861,
+)
+
+
+_TESTSTRUCT = _descriptor.Descriptor(
+  name='TestStruct',
+  full_name='proto3.TestStruct',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestStruct.value', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_value', full_name='proto3.TestStruct.repeated_value', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3863,
+  serialized_end=3964,
+)
+
+
+_TESTANY = _descriptor.Descriptor(
+  name='TestAny',
+  full_name='proto3.TestAny',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestAny.value', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_value', full_name='proto3.TestAny.repeated_value', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3966,
+  serialized_end=4058,
+)
+
+
+_TESTVALUE = _descriptor.Descriptor(
+  name='TestValue',
+  full_name='proto3.TestValue',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestValue.value', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_value', full_name='proto3.TestValue.repeated_value', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4060,
+  serialized_end=4158,
+)
+
+
+_TESTLISTVALUE = _descriptor.Descriptor(
+  name='TestListValue',
+  full_name='proto3.TestListValue',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestListValue.value', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='repeated_value', full_name='proto3.TestListValue.repeated_value', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4160,
+  serialized_end=4270,
+)
+
+
+_TESTBOOLVALUE_BOOLMAPENTRY = _descriptor.Descriptor(
+  name='BoolMapEntry',
+  full_name='proto3.TestBoolValue.BoolMapEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='proto3.TestBoolValue.BoolMapEntry.key', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestBoolValue.BoolMapEntry.value', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1501,
+  serialized_end=1547,
+)
+
+_TESTBOOLVALUE = _descriptor.Descriptor(
+  name='TestBoolValue',
+  full_name='proto3.TestBoolValue',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='bool_value', full_name='proto3.TestBoolValue.bool_value', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bool_map', full_name='proto3.TestBoolValue.bool_map', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTBOOLVALUE_BOOLMAPENTRY, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4273,
+  serialized_end=4410,
+)
+
+
+_TESTCUSTOMJSONNAME = _descriptor.Descriptor(
+  name='TestCustomJsonName',
+  full_name='proto3.TestCustomJsonName',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='proto3.TestCustomJsonName.value', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4412,
+  serialized_end=4455,
+)
+
+
+_TESTEXTENSIONS = _descriptor.Descriptor(
+  name='TestExtensions',
+  full_name='proto3.TestExtensions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='extensions', full_name='proto3.TestExtensions.extensions', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4457,
+  serialized_end=4531,
+)
+
+_TESTMESSAGE.fields_by_name['enum_value'].enum_type = _ENUMTYPE
+_TESTMESSAGE.fields_by_name['message_value'].message_type = _MESSAGETYPE
+_TESTMESSAGE.fields_by_name['repeated_enum_value'].enum_type = _ENUMTYPE
+_TESTMESSAGE.fields_by_name['repeated_message_value'].message_type = _MESSAGETYPE
+_TESTONEOF.fields_by_name['oneof_enum_value'].enum_type = _ENUMTYPE
+_TESTONEOF.fields_by_name['oneof_message_value'].message_type = _MESSAGETYPE
+_TESTONEOF.oneofs_by_name['oneof_value'].fields.append(
+  _TESTONEOF.fields_by_name['oneof_int32_value'])
+_TESTONEOF.fields_by_name['oneof_int32_value'].containing_oneof = _TESTONEOF.oneofs_by_name['oneof_value']
+_TESTONEOF.oneofs_by_name['oneof_value'].fields.append(
+  _TESTONEOF.fields_by_name['oneof_string_value'])
+_TESTONEOF.fields_by_name['oneof_string_value'].containing_oneof = _TESTONEOF.oneofs_by_name['oneof_value']
+_TESTONEOF.oneofs_by_name['oneof_value'].fields.append(
+  _TESTONEOF.fields_by_name['oneof_bytes_value'])
+_TESTONEOF.fields_by_name['oneof_bytes_value'].containing_oneof = _TESTONEOF.oneofs_by_name['oneof_value']
+_TESTONEOF.oneofs_by_name['oneof_value'].fields.append(
+  _TESTONEOF.fields_by_name['oneof_enum_value'])
+_TESTONEOF.fields_by_name['oneof_enum_value'].containing_oneof = _TESTONEOF.oneofs_by_name['oneof_value']
+_TESTONEOF.oneofs_by_name['oneof_value'].fields.append(
+  _TESTONEOF.fields_by_name['oneof_message_value'])
+_TESTONEOF.fields_by_name['oneof_message_value'].containing_oneof = _TESTONEOF.oneofs_by_name['oneof_value']
+_TESTMAP_BOOLMAPENTRY.containing_type = _TESTMAP
+_TESTMAP_INT32MAPENTRY.containing_type = _TESTMAP
+_TESTMAP_INT64MAPENTRY.containing_type = _TESTMAP
+_TESTMAP_UINT32MAPENTRY.containing_type = _TESTMAP
+_TESTMAP_UINT64MAPENTRY.containing_type = _TESTMAP
+_TESTMAP_STRINGMAPENTRY.containing_type = _TESTMAP
+_TESTMAP.fields_by_name['bool_map'].message_type = _TESTMAP_BOOLMAPENTRY
+_TESTMAP.fields_by_name['int32_map'].message_type = _TESTMAP_INT32MAPENTRY
+_TESTMAP.fields_by_name['int64_map'].message_type = _TESTMAP_INT64MAPENTRY
+_TESTMAP.fields_by_name['uint32_map'].message_type = _TESTMAP_UINT32MAPENTRY
+_TESTMAP.fields_by_name['uint64_map'].message_type = _TESTMAP_UINT64MAPENTRY
+_TESTMAP.fields_by_name['string_map'].message_type = _TESTMAP_STRINGMAPENTRY
+_TESTNESTEDMAP_BOOLMAPENTRY.containing_type = _TESTNESTEDMAP
+_TESTNESTEDMAP_INT32MAPENTRY.containing_type = _TESTNESTEDMAP
+_TESTNESTEDMAP_INT64MAPENTRY.containing_type = _TESTNESTEDMAP
+_TESTNESTEDMAP_UINT32MAPENTRY.containing_type = _TESTNESTEDMAP
+_TESTNESTEDMAP_UINT64MAPENTRY.containing_type = _TESTNESTEDMAP
+_TESTNESTEDMAP_STRINGMAPENTRY.containing_type = _TESTNESTEDMAP
+_TESTNESTEDMAP_MAPMAPENTRY.fields_by_name['value'].message_type = _TESTNESTEDMAP
+_TESTNESTEDMAP_MAPMAPENTRY.containing_type = _TESTNESTEDMAP
+_TESTNESTEDMAP.fields_by_name['bool_map'].message_type = _TESTNESTEDMAP_BOOLMAPENTRY
+_TESTNESTEDMAP.fields_by_name['int32_map'].message_type = _TESTNESTEDMAP_INT32MAPENTRY
+_TESTNESTEDMAP.fields_by_name['int64_map'].message_type = _TESTNESTEDMAP_INT64MAPENTRY
+_TESTNESTEDMAP.fields_by_name['uint32_map'].message_type = _TESTNESTEDMAP_UINT32MAPENTRY
+_TESTNESTEDMAP.fields_by_name['uint64_map'].message_type = _TESTNESTEDMAP_UINT64MAPENTRY
+_TESTNESTEDMAP.fields_by_name['string_map'].message_type = _TESTNESTEDMAP_STRINGMAPENTRY
+_TESTNESTEDMAP.fields_by_name['map_map'].message_type = _TESTNESTEDMAP_MAPMAPENTRY
+_TESTWRAPPER.fields_by_name['bool_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._BOOLVALUE
+_TESTWRAPPER.fields_by_name['int32_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._INT32VALUE
+_TESTWRAPPER.fields_by_name['int64_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._INT64VALUE
+_TESTWRAPPER.fields_by_name['uint32_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._UINT32VALUE
+_TESTWRAPPER.fields_by_name['uint64_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._UINT64VALUE
+_TESTWRAPPER.fields_by_name['float_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._FLOATVALUE
+_TESTWRAPPER.fields_by_name['double_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._DOUBLEVALUE
+_TESTWRAPPER.fields_by_name['string_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._STRINGVALUE
+_TESTWRAPPER.fields_by_name['bytes_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._BYTESVALUE
+_TESTWRAPPER.fields_by_name['repeated_bool_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._BOOLVALUE
+_TESTWRAPPER.fields_by_name['repeated_int32_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._INT32VALUE
+_TESTWRAPPER.fields_by_name['repeated_int64_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._INT64VALUE
+_TESTWRAPPER.fields_by_name['repeated_uint32_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._UINT32VALUE
+_TESTWRAPPER.fields_by_name['repeated_uint64_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._UINT64VALUE
+_TESTWRAPPER.fields_by_name['repeated_float_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._FLOATVALUE
+_TESTWRAPPER.fields_by_name['repeated_double_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._DOUBLEVALUE
+_TESTWRAPPER.fields_by_name['repeated_string_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._STRINGVALUE
+_TESTWRAPPER.fields_by_name['repeated_bytes_value'].message_type = google_dot_protobuf_dot_wrappers__pb2._BYTESVALUE
+_TESTTIMESTAMP.fields_by_name['value'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_TESTTIMESTAMP.fields_by_name['repeated_value'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_TESTDURATION.fields_by_name['value'].message_type = google_dot_protobuf_dot_duration__pb2._DURATION
+_TESTDURATION.fields_by_name['repeated_value'].message_type = google_dot_protobuf_dot_duration__pb2._DURATION
+_TESTFIELDMASK.fields_by_name['value'].message_type = google_dot_protobuf_dot_field__mask__pb2._FIELDMASK
+_TESTSTRUCT.fields_by_name['value'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT
+_TESTSTRUCT.fields_by_name['repeated_value'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT
+_TESTANY.fields_by_name['value'].message_type = google_dot_protobuf_dot_any__pb2._ANY
+_TESTANY.fields_by_name['repeated_value'].message_type = google_dot_protobuf_dot_any__pb2._ANY
+_TESTVALUE.fields_by_name['value'].message_type = google_dot_protobuf_dot_struct__pb2._VALUE
+_TESTVALUE.fields_by_name['repeated_value'].message_type = google_dot_protobuf_dot_struct__pb2._VALUE
+_TESTLISTVALUE.fields_by_name['value'].message_type = google_dot_protobuf_dot_struct__pb2._LISTVALUE
+_TESTLISTVALUE.fields_by_name['repeated_value'].message_type = google_dot_protobuf_dot_struct__pb2._LISTVALUE
+_TESTBOOLVALUE_BOOLMAPENTRY.containing_type = _TESTBOOLVALUE
+_TESTBOOLVALUE.fields_by_name['bool_map'].message_type = _TESTBOOLVALUE_BOOLMAPENTRY
+_TESTEXTENSIONS.fields_by_name['extensions'].message_type = google_dot_protobuf_dot_unittest__pb2._TESTALLEXTENSIONS
+DESCRIPTOR.message_types_by_name['MessageType'] = _MESSAGETYPE
+DESCRIPTOR.message_types_by_name['TestMessage'] = _TESTMESSAGE
+DESCRIPTOR.message_types_by_name['TestOneof'] = _TESTONEOF
+DESCRIPTOR.message_types_by_name['TestMap'] = _TESTMAP
+DESCRIPTOR.message_types_by_name['TestNestedMap'] = _TESTNESTEDMAP
+DESCRIPTOR.message_types_by_name['TestWrapper'] = _TESTWRAPPER
+DESCRIPTOR.message_types_by_name['TestTimestamp'] = _TESTTIMESTAMP
+DESCRIPTOR.message_types_by_name['TestDuration'] = _TESTDURATION
+DESCRIPTOR.message_types_by_name['TestFieldMask'] = _TESTFIELDMASK
+DESCRIPTOR.message_types_by_name['TestStruct'] = _TESTSTRUCT
+DESCRIPTOR.message_types_by_name['TestAny'] = _TESTANY
+DESCRIPTOR.message_types_by_name['TestValue'] = _TESTVALUE
+DESCRIPTOR.message_types_by_name['TestListValue'] = _TESTLISTVALUE
+DESCRIPTOR.message_types_by_name['TestBoolValue'] = _TESTBOOLVALUE
+DESCRIPTOR.message_types_by_name['TestCustomJsonName'] = _TESTCUSTOMJSONNAME
+DESCRIPTOR.message_types_by_name['TestExtensions'] = _TESTEXTENSIONS
+DESCRIPTOR.enum_types_by_name['EnumType'] = _ENUMTYPE
+
+MessageType = _reflection.GeneratedProtocolMessageType('MessageType', (_message.Message,), dict(
+  DESCRIPTOR = _MESSAGETYPE,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.MessageType)
+  ))
+_sym_db.RegisterMessage(MessageType)
+
+TestMessage = _reflection.GeneratedProtocolMessageType('TestMessage', (_message.Message,), dict(
+  DESCRIPTOR = _TESTMESSAGE,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestMessage)
+  ))
+_sym_db.RegisterMessage(TestMessage)
+
+TestOneof = _reflection.GeneratedProtocolMessageType('TestOneof', (_message.Message,), dict(
+  DESCRIPTOR = _TESTONEOF,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestOneof)
+  ))
+_sym_db.RegisterMessage(TestOneof)
+
+TestMap = _reflection.GeneratedProtocolMessageType('TestMap', (_message.Message,), dict(
+
+  BoolMapEntry = _reflection.GeneratedProtocolMessageType('BoolMapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_BOOLMAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestMap.BoolMapEntry)
+    ))
+  ,
+
+  Int32MapEntry = _reflection.GeneratedProtocolMessageType('Int32MapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_INT32MAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestMap.Int32MapEntry)
+    ))
+  ,
+
+  Int64MapEntry = _reflection.GeneratedProtocolMessageType('Int64MapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_INT64MAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestMap.Int64MapEntry)
+    ))
+  ,
+
+  Uint32MapEntry = _reflection.GeneratedProtocolMessageType('Uint32MapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_UINT32MAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestMap.Uint32MapEntry)
+    ))
+  ,
+
+  Uint64MapEntry = _reflection.GeneratedProtocolMessageType('Uint64MapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_UINT64MAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestMap.Uint64MapEntry)
+    ))
+  ,
+
+  StringMapEntry = _reflection.GeneratedProtocolMessageType('StringMapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTMAP_STRINGMAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestMap.StringMapEntry)
+    ))
+  ,
+  DESCRIPTOR = _TESTMAP,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestMap)
+  ))
+_sym_db.RegisterMessage(TestMap)
+_sym_db.RegisterMessage(TestMap.BoolMapEntry)
+_sym_db.RegisterMessage(TestMap.Int32MapEntry)
+_sym_db.RegisterMessage(TestMap.Int64MapEntry)
+_sym_db.RegisterMessage(TestMap.Uint32MapEntry)
+_sym_db.RegisterMessage(TestMap.Uint64MapEntry)
+_sym_db.RegisterMessage(TestMap.StringMapEntry)
+
+TestNestedMap = _reflection.GeneratedProtocolMessageType('TestNestedMap', (_message.Message,), dict(
+
+  BoolMapEntry = _reflection.GeneratedProtocolMessageType('BoolMapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTNESTEDMAP_BOOLMAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestNestedMap.BoolMapEntry)
+    ))
+  ,
+
+  Int32MapEntry = _reflection.GeneratedProtocolMessageType('Int32MapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTNESTEDMAP_INT32MAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestNestedMap.Int32MapEntry)
+    ))
+  ,
+
+  Int64MapEntry = _reflection.GeneratedProtocolMessageType('Int64MapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTNESTEDMAP_INT64MAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestNestedMap.Int64MapEntry)
+    ))
+  ,
+
+  Uint32MapEntry = _reflection.GeneratedProtocolMessageType('Uint32MapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTNESTEDMAP_UINT32MAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestNestedMap.Uint32MapEntry)
+    ))
+  ,
+
+  Uint64MapEntry = _reflection.GeneratedProtocolMessageType('Uint64MapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTNESTEDMAP_UINT64MAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestNestedMap.Uint64MapEntry)
+    ))
+  ,
+
+  StringMapEntry = _reflection.GeneratedProtocolMessageType('StringMapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTNESTEDMAP_STRINGMAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestNestedMap.StringMapEntry)
+    ))
+  ,
+
+  MapMapEntry = _reflection.GeneratedProtocolMessageType('MapMapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTNESTEDMAP_MAPMAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestNestedMap.MapMapEntry)
+    ))
+  ,
+  DESCRIPTOR = _TESTNESTEDMAP,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestNestedMap)
+  ))
+_sym_db.RegisterMessage(TestNestedMap)
+_sym_db.RegisterMessage(TestNestedMap.BoolMapEntry)
+_sym_db.RegisterMessage(TestNestedMap.Int32MapEntry)
+_sym_db.RegisterMessage(TestNestedMap.Int64MapEntry)
+_sym_db.RegisterMessage(TestNestedMap.Uint32MapEntry)
+_sym_db.RegisterMessage(TestNestedMap.Uint64MapEntry)
+_sym_db.RegisterMessage(TestNestedMap.StringMapEntry)
+_sym_db.RegisterMessage(TestNestedMap.MapMapEntry)
+
+TestWrapper = _reflection.GeneratedProtocolMessageType('TestWrapper', (_message.Message,), dict(
+  DESCRIPTOR = _TESTWRAPPER,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestWrapper)
+  ))
+_sym_db.RegisterMessage(TestWrapper)
+
+TestTimestamp = _reflection.GeneratedProtocolMessageType('TestTimestamp', (_message.Message,), dict(
+  DESCRIPTOR = _TESTTIMESTAMP,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestTimestamp)
+  ))
+_sym_db.RegisterMessage(TestTimestamp)
+
+TestDuration = _reflection.GeneratedProtocolMessageType('TestDuration', (_message.Message,), dict(
+  DESCRIPTOR = _TESTDURATION,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestDuration)
+  ))
+_sym_db.RegisterMessage(TestDuration)
+
+TestFieldMask = _reflection.GeneratedProtocolMessageType('TestFieldMask', (_message.Message,), dict(
+  DESCRIPTOR = _TESTFIELDMASK,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestFieldMask)
+  ))
+_sym_db.RegisterMessage(TestFieldMask)
+
+TestStruct = _reflection.GeneratedProtocolMessageType('TestStruct', (_message.Message,), dict(
+  DESCRIPTOR = _TESTSTRUCT,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestStruct)
+  ))
+_sym_db.RegisterMessage(TestStruct)
+
+TestAny = _reflection.GeneratedProtocolMessageType('TestAny', (_message.Message,), dict(
+  DESCRIPTOR = _TESTANY,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestAny)
+  ))
+_sym_db.RegisterMessage(TestAny)
+
+TestValue = _reflection.GeneratedProtocolMessageType('TestValue', (_message.Message,), dict(
+  DESCRIPTOR = _TESTVALUE,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestValue)
+  ))
+_sym_db.RegisterMessage(TestValue)
+
+TestListValue = _reflection.GeneratedProtocolMessageType('TestListValue', (_message.Message,), dict(
+  DESCRIPTOR = _TESTLISTVALUE,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestListValue)
+  ))
+_sym_db.RegisterMessage(TestListValue)
+
+TestBoolValue = _reflection.GeneratedProtocolMessageType('TestBoolValue', (_message.Message,), dict(
+
+  BoolMapEntry = _reflection.GeneratedProtocolMessageType('BoolMapEntry', (_message.Message,), dict(
+    DESCRIPTOR = _TESTBOOLVALUE_BOOLMAPENTRY,
+    __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+    # @@protoc_insertion_point(class_scope:proto3.TestBoolValue.BoolMapEntry)
+    ))
+  ,
+  DESCRIPTOR = _TESTBOOLVALUE,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestBoolValue)
+  ))
+_sym_db.RegisterMessage(TestBoolValue)
+_sym_db.RegisterMessage(TestBoolValue.BoolMapEntry)
+
+TestCustomJsonName = _reflection.GeneratedProtocolMessageType('TestCustomJsonName', (_message.Message,), dict(
+  DESCRIPTOR = _TESTCUSTOMJSONNAME,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestCustomJsonName)
+  ))
+_sym_db.RegisterMessage(TestCustomJsonName)
+
+TestExtensions = _reflection.GeneratedProtocolMessageType('TestExtensions', (_message.Message,), dict(
+  DESCRIPTOR = _TESTEXTENSIONS,
+  __module__ = 'google.protobuf.util.json_format_proto3_pb2'
+  # @@protoc_insertion_point(class_scope:proto3.TestExtensions)
+  ))
+_sym_db.RegisterMessage(TestExtensions)
+
+
+_TESTMAP_BOOLMAPENTRY.has_options = True
+_TESTMAP_BOOLMAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_INT32MAPENTRY.has_options = True
+_TESTMAP_INT32MAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_INT64MAPENTRY.has_options = True
+_TESTMAP_INT64MAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_UINT32MAPENTRY.has_options = True
+_TESTMAP_UINT32MAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_UINT64MAPENTRY.has_options = True
+_TESTMAP_UINT64MAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTMAP_STRINGMAPENTRY.has_options = True
+_TESTMAP_STRINGMAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTNESTEDMAP_BOOLMAPENTRY.has_options = True
+_TESTNESTEDMAP_BOOLMAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTNESTEDMAP_INT32MAPENTRY.has_options = True
+_TESTNESTEDMAP_INT32MAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTNESTEDMAP_INT64MAPENTRY.has_options = True
+_TESTNESTEDMAP_INT64MAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTNESTEDMAP_UINT32MAPENTRY.has_options = True
+_TESTNESTEDMAP_UINT32MAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTNESTEDMAP_UINT64MAPENTRY.has_options = True
+_TESTNESTEDMAP_UINT64MAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTNESTEDMAP_STRINGMAPENTRY.has_options = True
+_TESTNESTEDMAP_STRINGMAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTNESTEDMAP_MAPMAPENTRY.has_options = True
+_TESTNESTEDMAP_MAPMAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_TESTBOOLVALUE_BOOLMAPENTRY.has_options = True
+_TESTBOOLVALUE_BOOLMAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/google/protobuf/wrappers_pb2.py b/generator/google/protobuf/wrappers_pb2.py
new file mode 100644
index 0000000..03de834
--- /dev/null
+++ b/generator/google/protobuf/wrappers_pb2.py
@@ -0,0 +1,383 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: google/protobuf/wrappers.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='google/protobuf/wrappers.proto',
+  package='google.protobuf',
+  syntax='proto3',
+  serialized_pb=_b('\n\x1egoogle/protobuf/wrappers.proto\x12\x0fgoogle.protobuf\"\x1c\n\x0b\x44oubleValue\x12\r\n\x05value\x18\x01 \x01(\x01\"\x1b\n\nFloatValue\x12\r\n\x05value\x18\x01 \x01(\x02\"\x1b\n\nInt64Value\x12\r\n\x05value\x18\x01 \x01(\x03\"\x1c\n\x0bUInt64Value\x12\r\n\x05value\x18\x01 \x01(\x04\"\x1b\n\nInt32Value\x12\r\n\x05value\x18\x01 \x01(\x05\"\x1c\n\x0bUInt32Value\x12\r\n\x05value\x18\x01 \x01(\r\"\x1a\n\tBoolValue\x12\r\n\x05value\x18\x01 \x01(\x08\"\x1c\n\x0bStringValue\x12\r\n\x05value\x18\x01 \x01(\t\"\x1b\n\nBytesValue\x12\r\n\x05value\x18\x01 \x01(\x0c\x42\x7f\n\x13\x63om.google.protobufB\rWrappersProtoP\x01Z*github.com/golang/protobuf/ptypes/wrappers\xa0\x01\x01\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_DOUBLEVALUE = _descriptor.Descriptor(
+  name='DoubleValue',
+  full_name='google.protobuf.DoubleValue',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.DoubleValue.value', index=0,
+      number=1, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=51,
+  serialized_end=79,
+)
+
+
+_FLOATVALUE = _descriptor.Descriptor(
+  name='FloatValue',
+  full_name='google.protobuf.FloatValue',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.FloatValue.value', index=0,
+      number=1, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=81,
+  serialized_end=108,
+)
+
+
+_INT64VALUE = _descriptor.Descriptor(
+  name='Int64Value',
+  full_name='google.protobuf.Int64Value',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.Int64Value.value', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=110,
+  serialized_end=137,
+)
+
+
+_UINT64VALUE = _descriptor.Descriptor(
+  name='UInt64Value',
+  full_name='google.protobuf.UInt64Value',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.UInt64Value.value', index=0,
+      number=1, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=139,
+  serialized_end=167,
+)
+
+
+_INT32VALUE = _descriptor.Descriptor(
+  name='Int32Value',
+  full_name='google.protobuf.Int32Value',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.Int32Value.value', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=169,
+  serialized_end=196,
+)
+
+
+_UINT32VALUE = _descriptor.Descriptor(
+  name='UInt32Value',
+  full_name='google.protobuf.UInt32Value',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.UInt32Value.value', index=0,
+      number=1, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=198,
+  serialized_end=226,
+)
+
+
+_BOOLVALUE = _descriptor.Descriptor(
+  name='BoolValue',
+  full_name='google.protobuf.BoolValue',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.BoolValue.value', index=0,
+      number=1, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=228,
+  serialized_end=254,
+)
+
+
+_STRINGVALUE = _descriptor.Descriptor(
+  name='StringValue',
+  full_name='google.protobuf.StringValue',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.StringValue.value', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=256,
+  serialized_end=284,
+)
+
+
+_BYTESVALUE = _descriptor.Descriptor(
+  name='BytesValue',
+  full_name='google.protobuf.BytesValue',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='google.protobuf.BytesValue.value', index=0,
+      number=1, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=286,
+  serialized_end=313,
+)
+
+DESCRIPTOR.message_types_by_name['DoubleValue'] = _DOUBLEVALUE
+DESCRIPTOR.message_types_by_name['FloatValue'] = _FLOATVALUE
+DESCRIPTOR.message_types_by_name['Int64Value'] = _INT64VALUE
+DESCRIPTOR.message_types_by_name['UInt64Value'] = _UINT64VALUE
+DESCRIPTOR.message_types_by_name['Int32Value'] = _INT32VALUE
+DESCRIPTOR.message_types_by_name['UInt32Value'] = _UINT32VALUE
+DESCRIPTOR.message_types_by_name['BoolValue'] = _BOOLVALUE
+DESCRIPTOR.message_types_by_name['StringValue'] = _STRINGVALUE
+DESCRIPTOR.message_types_by_name['BytesValue'] = _BYTESVALUE
+
+DoubleValue = _reflection.GeneratedProtocolMessageType('DoubleValue', (_message.Message,), dict(
+  DESCRIPTOR = _DOUBLEVALUE,
+  __module__ = 'google.protobuf.wrappers_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.DoubleValue)
+  ))
+_sym_db.RegisterMessage(DoubleValue)
+
+FloatValue = _reflection.GeneratedProtocolMessageType('FloatValue', (_message.Message,), dict(
+  DESCRIPTOR = _FLOATVALUE,
+  __module__ = 'google.protobuf.wrappers_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.FloatValue)
+  ))
+_sym_db.RegisterMessage(FloatValue)
+
+Int64Value = _reflection.GeneratedProtocolMessageType('Int64Value', (_message.Message,), dict(
+  DESCRIPTOR = _INT64VALUE,
+  __module__ = 'google.protobuf.wrappers_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Int64Value)
+  ))
+_sym_db.RegisterMessage(Int64Value)
+
+UInt64Value = _reflection.GeneratedProtocolMessageType('UInt64Value', (_message.Message,), dict(
+  DESCRIPTOR = _UINT64VALUE,
+  __module__ = 'google.protobuf.wrappers_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.UInt64Value)
+  ))
+_sym_db.RegisterMessage(UInt64Value)
+
+Int32Value = _reflection.GeneratedProtocolMessageType('Int32Value', (_message.Message,), dict(
+  DESCRIPTOR = _INT32VALUE,
+  __module__ = 'google.protobuf.wrappers_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.Int32Value)
+  ))
+_sym_db.RegisterMessage(Int32Value)
+
+UInt32Value = _reflection.GeneratedProtocolMessageType('UInt32Value', (_message.Message,), dict(
+  DESCRIPTOR = _UINT32VALUE,
+  __module__ = 'google.protobuf.wrappers_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.UInt32Value)
+  ))
+_sym_db.RegisterMessage(UInt32Value)
+
+BoolValue = _reflection.GeneratedProtocolMessageType('BoolValue', (_message.Message,), dict(
+  DESCRIPTOR = _BOOLVALUE,
+  __module__ = 'google.protobuf.wrappers_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.BoolValue)
+  ))
+_sym_db.RegisterMessage(BoolValue)
+
+StringValue = _reflection.GeneratedProtocolMessageType('StringValue', (_message.Message,), dict(
+  DESCRIPTOR = _STRINGVALUE,
+  __module__ = 'google.protobuf.wrappers_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.StringValue)
+  ))
+_sym_db.RegisterMessage(StringValue)
+
+BytesValue = _reflection.GeneratedProtocolMessageType('BytesValue', (_message.Message,), dict(
+  DESCRIPTOR = _BYTESVALUE,
+  __module__ = 'google.protobuf.wrappers_pb2'
+  # @@protoc_insertion_point(class_scope:google.protobuf.BytesValue)
+  ))
+_sym_db.RegisterMessage(BytesValue)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\023com.google.protobufB\rWrappersProtoP\001Z*github.com/golang/protobuf/ptypes/wrappers\240\001\001\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes'))
+# @@protoc_insertion_point(module_scope)
diff --git a/generator/nanopb/options.proto b/generator/nanopb/options.proto
new file mode 100644
index 0000000..b94dca2
--- /dev/null
+++ b/generator/nanopb/options.proto
@@ -0,0 +1,123 @@
+// This is a transitional file, to provide parallel support between the old
+// nanopb.proto and new options.proto files. Eventually nanopb.proto will
+// be left only for legacy code, but for now the generator is still also
+// using it. However, your new code can start using this file already now.
+// See pull request #241 for details:
+// https://github.com/nanopb/nanopb/pull/241
+
+// Custom options for defining:
+// - Maximum size of string/bytes
+// - Maximum number of elements in array
+//
+// These are used by nanopb to generate statically allocable structures
+// for memory-limited environments.
+
+syntax = "proto2";
+import "google/protobuf/descriptor.proto";
+
+package nanopb;
+option java_package = "fi.kapsi.koti.jpa.nanopb";
+
+enum FieldType {
+    FT_DEFAULT = 0; // Automatically decide field type, generate static field if possible.
+    FT_CALLBACK = 1; // Always generate a callback field.
+    FT_POINTER = 4; // Always generate a dynamically allocated field.
+    FT_STATIC = 2; // Generate a static field or raise an exception if not possible.
+    FT_IGNORE = 3; // Ignore the field completely.
+    FT_INLINE = 5; // Legacy option, use the separate 'fixed_length' option instead
+}
+
+enum IntSize {
+    IS_DEFAULT = 0; // Default, 32/64bit based on type in .proto
+    IS_8 = 8;
+    IS_16 = 16;
+    IS_32 = 32;
+    IS_64 = 64;
+}
+
+// This is the inner options message, which basically defines options for
+// a field. When it is used in message or file scope, it applies to all
+// fields.
+message Options {
+  // Allocated size for 'bytes' and 'string' fields.
+  // For string fields, this should include the space for null terminator.
+  optional int32 max_size = 1;
+
+  // Maximum length for 'string' fields. Setting this is equivalent
+  // to setting max_size to a value of length+1.
+  optional int32 max_length = 14;
+
+  // Allocated number of entries in arrays ('repeated' fields)
+  optional int32 max_count = 2;
+
+  // Size of integer fields. Can save some memory if you don't need
+  // full 32 bits for the value.
+  optional IntSize int_size = 7 [default = IS_DEFAULT];
+
+  // Force type of field (callback or static allocation)
+  optional FieldType type = 3 [default = FT_DEFAULT];
+
+  // Use long names for enums, i.e. EnumName_EnumValue.
+  optional bool long_names = 4 [default = true];
+
+  // Add 'packed' attribute to generated structs.
+  // Note: this cannot be used on CPUs that break on unaligned
+  // accesses to variables.
+  optional bool packed_struct = 5 [default = false];
+
+  // Add 'packed' attribute to generated enums.
+  optional bool packed_enum = 10 [default = false];
+
+  // Skip this message
+  optional bool skip_message = 6 [default = false];
+
+  // Generate oneof fields as normal optional fields instead of union.
+  optional bool no_unions = 8 [default = false];
+
+  // integer type tag for a message
+  optional uint32 msgid = 9;
+
+  // decode oneof as anonymous union
+  optional bool anonymous_oneof = 11 [default = false];
+
+  // Proto3 singular field does not generate a "has_" flag
+  optional bool proto3 = 12 [default = false];
+
+  // Generate an enum->string mapping function (can take up lots of space).
+  optional bool enum_to_string = 13 [default = false];
+
+  // Generate bytes arrays with fixed length
+  optional bool fixed_length = 15 [default = false];
+
+  // Generate repeated field with fixed count
+  optional bool fixed_count = 16 [default = false];
+}
+
+// Extensions to protoc 'Descriptor' type in order to define options
+// inside a .proto file.
+//
+// Protocol Buffers extension number registry
+// --------------------------------
+// Project:  Nanopb
+// Contact:  Petteri Aimonen <jpa@kapsi.fi>
+// Web site: http://kapsi.fi/~jpa/nanopb
+// Extensions: 1010 (all types)
+// --------------------------------
+
+extend google.protobuf.FileOptions {
+    optional Options fileopt = 1010;
+}
+
+extend google.protobuf.MessageOptions {
+    optional Options msgopt = 1010;
+}
+
+extend google.protobuf.EnumOptions {
+    optional Options enumopt = 1010;
+}
+
+extend google.protobuf.FieldOptions {
+    optional Options fieldopt = 1010;
+}
+
+
diff --git a/generator/nanopb_generator.py b/generator/nanopb_generator.py
index 4d8d733..5b74ca1 100755
--- a/generator/nanopb_generator.py
+++ b/generator/nanopb_generator.py
@@ -1,9 +1,14 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+
+from __future__ import unicode_literals
 
 '''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.'''
-nanopb_version = "nanopb-0.2.8-dev"
+nanopb_version = "nanopb-0.3.9.1"
 
 import sys
+import re
+import codecs
+from functools import reduce
 
 try:
     # Add some dummy imports to keep packaging tools happy.
@@ -28,6 +33,20 @@
 try:
     import proto.nanopb_pb2 as nanopb_pb2
     import proto.plugin_pb2 as plugin_pb2
+except TypeError:
+    sys.stderr.write('''
+         ****************************************************************************
+         *** Got TypeError when importing the protocol definitions for generator. ***
+         *** This usually means that the protoc in your path doesn't match the    ***
+         *** Python protobuf library version.                                     ***
+         ***                                                                      ***
+         *** Please check the output of the following commands:                   ***
+         *** which protoc                                                         ***
+         *** protoc --version                                                     ***
+         *** python -c 'import google.protobuf; print(google.protobuf.__file__)'  ***
+         ****************************************************************************
+    ''' + '\n')
+    raise
 except:
     sys.stderr.write('''
          ********************************************************************
@@ -44,45 +63,59 @@
 import time
 import os.path
 
-# Values are tuple (c type, pb type, encoded size)
+# Values are tuple (c type, pb type, encoded size, int_size_allowed)
 FieldD = descriptor.FieldDescriptorProto
 datatypes = {
-    FieldD.TYPE_BOOL:       ('bool',     'BOOL',        1),
-    FieldD.TYPE_DOUBLE:     ('double',   'DOUBLE',      8),
-    FieldD.TYPE_FIXED32:    ('uint32_t', 'FIXED32',     4),
-    FieldD.TYPE_FIXED64:    ('uint64_t', 'FIXED64',     8),
-    FieldD.TYPE_FLOAT:      ('float',    'FLOAT',       4),
-    FieldD.TYPE_INT32:      ('int32_t',  'INT32',      10),
-    FieldD.TYPE_INT64:      ('int64_t',  'INT64',      10),
-    FieldD.TYPE_SFIXED32:   ('int32_t',  'SFIXED32',    4),
-    FieldD.TYPE_SFIXED64:   ('int64_t',  'SFIXED64',    8),
-    FieldD.TYPE_SINT32:     ('int32_t',  'SINT32',      5),
-    FieldD.TYPE_SINT64:     ('int64_t',  'SINT64',     10),
-    FieldD.TYPE_UINT32:     ('uint32_t', 'UINT32',      5),
-    FieldD.TYPE_UINT64:     ('uint64_t', 'UINT64',     10)
+    FieldD.TYPE_BOOL:       ('bool',     'BOOL',        1,  False),
+    FieldD.TYPE_DOUBLE:     ('double',   'DOUBLE',      8,  False),
+    FieldD.TYPE_FIXED32:    ('uint32_t', 'FIXED32',     4,  False),
+    FieldD.TYPE_FIXED64:    ('uint64_t', 'FIXED64',     8,  False),
+    FieldD.TYPE_FLOAT:      ('float',    'FLOAT',       4,  False),
+    FieldD.TYPE_INT32:      ('int32_t',  'INT32',      10,  True),
+    FieldD.TYPE_INT64:      ('int64_t',  'INT64',      10,  True),
+    FieldD.TYPE_SFIXED32:   ('int32_t',  'SFIXED32',    4,  False),
+    FieldD.TYPE_SFIXED64:   ('int64_t',  'SFIXED64',    8,  False),
+    FieldD.TYPE_SINT32:     ('int32_t',  'SINT32',      5,  True),
+    FieldD.TYPE_SINT64:     ('int64_t',  'SINT64',     10,  True),
+    FieldD.TYPE_UINT32:     ('uint32_t', 'UINT32',      5,  True),
+    FieldD.TYPE_UINT64:     ('uint64_t', 'UINT64',     10,  True)
 }
 
+# Integer size overrides (from .proto settings)
+intsizes = {
+    nanopb_pb2.IS_8:     'int8_t',
+    nanopb_pb2.IS_16:    'int16_t',
+    nanopb_pb2.IS_32:    'int32_t',
+    nanopb_pb2.IS_64:    'int64_t',
+}
+
+# String types (for python 2 / python 3 compatibility)
+try:
+    strtypes = (unicode, str)
+except NameError:
+    strtypes = (str, )
+
 class Names:
     '''Keeps a set of nested names and formats them to C identifier.'''
     def __init__(self, parts = ()):
         if isinstance(parts, Names):
             parts = parts.parts
         self.parts = tuple(parts)
-    
+
     def __str__(self):
         return '_'.join(self.parts)
 
     def __add__(self, other):
-        if isinstance(other, (str, unicode)):
+        if isinstance(other, strtypes):
             return Names(self.parts + (other,))
         elif isinstance(other, tuple):
             return Names(self.parts + other)
         else:
             raise ValueError("Name parts should be of type str")
-    
+
     def __eq__(self, other):
         return isinstance(other, Names) and self.parts == other.parts
-    
+
 def names_from_type_name(type_name):
     '''Parse Names() from FieldDescriptorProto type_name'''
     if type_name[0] != '.':
@@ -91,11 +124,14 @@
 
 def varint_max_size(max_value):
     '''Returns the maximum number of bytes a varint can take when encoded.'''
+    if max_value < 0:
+        max_value = 2**64 - max_value
     for i in range(1, 11):
         if (max_value >> (i * 7)) == 0:
             return i
     raise ValueError("Value too large for varint: " + str(max_value))
 
+assert varint_max_size(-1) == 10
 assert varint_max_size(0) == 1
 assert varint_max_size(127) == 1
 assert varint_max_size(128) == 2
@@ -104,16 +140,20 @@
     '''Class used to represent the encoded size of a field or a message.
     Consists of a combination of symbolic sizes and integer sizes.'''
     def __init__(self, value = 0, symbols = []):
-        if isinstance(value, (str, Names)):
-            symbols = [str(value)]
-            value = 0
-        self.value = value
-        self.symbols = symbols
-    
+        if isinstance(value, EncodedSize):
+            self.value = value.value
+            self.symbols = value.symbols
+        elif isinstance(value, strtypes + (Names,)):
+            self.symbols = [str(value)]
+            self.value = 0
+        else:
+            self.value = value
+            self.symbols = symbols
+
     def __add__(self, other):
-        if isinstance(other, (int, long)):
+        if isinstance(other, int):
             return EncodedSize(self.value + other, self.symbols)
-        elif isinstance(other, (str, Names)):
+        elif isinstance(other, strtypes + (Names,)):
             return EncodedSize(self.value, self.symbols + [str(other)])
         elif isinstance(other, EncodedSize):
             return EncodedSize(self.value + other.value, self.symbols + other.symbols)
@@ -121,7 +161,7 @@
             raise ValueError("Cannot add size: " + repr(other))
 
     def __mul__(self, other):
-        if isinstance(other, (int, long)):
+        if isinstance(other, int):
             return EncodedSize(self.value * other, [str(other) + '*' + s for s in self.symbols])
         else:
             raise ValueError("Cannot multiply size: " + repr(other))
@@ -141,28 +181,94 @@
 class Enum:
     def __init__(self, names, desc, enum_options):
         '''desc is EnumDescriptorProto'''
-        
+
         self.options = enum_options
         self.names = names + desc.name
-        
+
         if enum_options.long_names:
-            self.values = [(self.names + x.name, x.number) for x in desc.value]            
+            self.values = [(self.names + x.name, x.number) for x in desc.value]
         else:
-            self.values = [(names + x.name, x.number) for x in desc.value] 
-        
+            self.values = [(names + x.name, x.number) for x in desc.value]
+
         self.value_longnames = [self.names + x.name for x in desc.value]
-    
+        self.packed = enum_options.packed_enum
+
+    def has_negative(self):
+        for n, v in self.values:
+            if v < 0:
+                return True
+        return False
+
+    def encoded_size(self):
+        return max([varint_max_size(v) for n,v in self.values])
+
     def __str__(self):
         result = 'typedef enum _%s {\n' % self.names
         result += ',\n'.join(["    %s = %d" % x for x in self.values])
-        result += '\n} %s;' % self.names
+        result += '\n}'
+
+        if self.packed:
+            result += ' pb_packed'
+
+        result += ' %s;' % self.names
+
+        result += '\n#define _%s_MIN %s' % (self.names, self.values[0][0])
+        result += '\n#define _%s_MAX %s' % (self.names, self.values[-1][0])
+        result += '\n#define _%s_ARRAYSIZE ((%s)(%s+1))' % (self.names, self.names, self.values[-1][0])
+
+        if not self.options.long_names:
+            # Define the long names always so that enum value references
+            # from other files work properly.
+            for i, x in enumerate(self.values):
+                result += '\n#define %s %s' % (self.value_longnames[i], x[0])
+
+        if self.options.enum_to_string:
+            result += '\nconst char *%s_name(%s v);\n' % (self.names, self.names)
+
         return result
 
+    def enum_to_string_definition(self):
+        if not self.options.enum_to_string:
+            return ""
+
+        result = 'const char *%s_name(%s v) {\n' % (self.names, self.names)
+        result += '    switch (v) {\n'
+
+        for ((enumname, _), strname) in zip(self.values, self.value_longnames):
+            # Strip off the leading type name from the string value.
+            strval = str(strname)[len(str(self.names)) + 1:]
+            result += '        case %s: return "%s";\n' % (enumname, strval)
+
+        result += '    }\n'
+        result += '    return "unknown";\n'
+        result += '}\n'
+
+        return result
+
+class FieldMaxSize:
+    def __init__(self, worst = 0, checks = [], field_name = 'undefined'):
+        if isinstance(worst, list):
+            self.worst = max(i for i in worst if i is not None)
+        else:
+            self.worst = worst
+
+        self.worst_field = field_name
+        self.checks = list(checks)
+
+    def extend(self, extend, field_name = None):
+        self.worst = max(self.worst, extend.worst)
+
+        if self.worst == extend.worst:
+            self.worst_field = extend.worst_field
+
+        self.checks.extend(extend.checks)
+
 class Field:
     def __init__(self, struct_name, desc, field_options):
         '''desc is FieldDescriptorProto'''
         self.tag = desc.number
         self.struct_name = struct_name
+        self.union_name = None
         self.name = desc.name
         self.default = None
         self.max_size = None
@@ -170,51 +276,71 @@
         self.array_decl = ""
         self.enc_size = None
         self.ctype = None
-        
+        self.fixed_count = False
+
+        if field_options.type == nanopb_pb2.FT_INLINE:
+            # Before nanopb-0.3.8, fixed length bytes arrays were specified
+            # by setting type to FT_INLINE. But to handle pointer typed fields,
+            # it makes sense to have it as a separate option.
+            field_options.type = nanopb_pb2.FT_STATIC
+            field_options.fixed_length = True
+
         # Parse field options
         if field_options.HasField("max_size"):
             self.max_size = field_options.max_size
-        
+
+        if desc.type == FieldD.TYPE_STRING and field_options.HasField("max_length"):
+            # max_length overrides max_size for strings
+            self.max_size = field_options.max_length + 1
+
         if field_options.HasField("max_count"):
             self.max_count = field_options.max_count
-        
+
         if desc.HasField('default_value'):
             self.default = desc.default_value
-           
+
         # Check field rules, i.e. required/optional/repeated.
         can_be_static = True
-        if desc.label == FieldD.LABEL_REQUIRED:
-            self.rules = 'REQUIRED'
-        elif desc.label == FieldD.LABEL_OPTIONAL:
-            self.rules = 'OPTIONAL'
-        elif desc.label == FieldD.LABEL_REPEATED:
+        if desc.label == FieldD.LABEL_REPEATED:
             self.rules = 'REPEATED'
             if self.max_count is None:
                 can_be_static = False
             else:
                 self.array_decl = '[%d]' % self.max_count
+                self.fixed_count = field_options.fixed_count
+
+        elif field_options.proto3:
+            self.rules = 'SINGULAR'
+        elif desc.label == FieldD.LABEL_REQUIRED:
+            self.rules = 'REQUIRED'
+        elif desc.label == FieldD.LABEL_OPTIONAL:
+            self.rules = 'OPTIONAL'
         else:
             raise NotImplementedError(desc.label)
-        
+
         # Check if the field can be implemented with static allocation
         # i.e. whether the data size is known.
         if desc.type == FieldD.TYPE_STRING and self.max_size is None:
             can_be_static = False
-        
+
         if desc.type == FieldD.TYPE_BYTES and self.max_size is None:
             can_be_static = False
-        
+
         # Decide how the field data will be allocated
         if field_options.type == nanopb_pb2.FT_DEFAULT:
             if can_be_static:
                 field_options.type = nanopb_pb2.FT_STATIC
             else:
                 field_options.type = nanopb_pb2.FT_CALLBACK
-        
+
         if field_options.type == nanopb_pb2.FT_STATIC and not can_be_static:
-            raise Exception("Field %s is defined as static, but max_size or "
+            raise Exception("Field '%s' is defined as static, but max_size or "
                             "max_count is not given." % self.name)
         
+        if field_options.fixed_count and self.max_count is None:
+            raise Exception("Field '%s' is defined as fixed count, "
+                            "but max_count is not given." % self.name)
+
         if field_options.type == nanopb_pb2.FT_STATIC:
             self.allocation = 'STATIC'
         elif field_options.type == nanopb_pb2.FT_POINTER:
@@ -223,16 +349,22 @@
             self.allocation = 'CALLBACK'
         else:
             raise NotImplementedError(field_options.type)
-        
+
         # Decide the C data type to use in the struct.
-        if datatypes.has_key(desc.type):
-            self.ctype, self.pbtype, self.enc_size = datatypes[desc.type]
+        if desc.type in datatypes:
+            self.ctype, self.pbtype, self.enc_size, isa = datatypes[desc.type]
+
+            # Override the field size if user wants to use smaller integers
+            if isa and field_options.int_size != nanopb_pb2.IS_DEFAULT:
+                self.ctype = intsizes[field_options.int_size]
+                if desc.type == FieldD.TYPE_UINT32 or desc.type == FieldD.TYPE_UINT64:
+                    self.ctype = 'u' + self.ctype;
         elif desc.type == FieldD.TYPE_ENUM:
             self.pbtype = 'ENUM'
             self.ctype = names_from_type_name(desc.type_name)
             if self.default is not None:
                 self.default = self.ctype + self.default
-            self.enc_size = 5 # protoc rejects enum values > 32 bits
+            self.enc_size = None # Needs to be filled in when enum values are known
         elif desc.type == FieldD.TYPE_STRING:
             self.pbtype = 'STRING'
             self.ctype = 'char'
@@ -241,31 +373,44 @@
                 self.array_decl += '[%d]' % self.max_size
                 self.enc_size = varint_max_size(self.max_size) + self.max_size
         elif desc.type == FieldD.TYPE_BYTES:
-            self.pbtype = 'BYTES'
-            if self.allocation == 'STATIC':
-                self.ctype = self.struct_name + self.name + 't'
+            if field_options.fixed_length:
+                self.pbtype = 'FIXED_LENGTH_BYTES'
+
+                if self.max_size is None:
+                    raise Exception("Field '%s' is defined as fixed length, "
+                                    "but max_size is not given." % self.name)
+
                 self.enc_size = varint_max_size(self.max_size) + self.max_size
-            elif self.allocation == 'POINTER':
+                self.ctype = 'pb_byte_t'
+                self.array_decl += '[%d]' % self.max_size
+            else:
+                self.pbtype = 'BYTES'
                 self.ctype = 'pb_bytes_array_t'
+                if self.allocation == 'STATIC':
+                    self.ctype = self.struct_name + self.name + 't'
+                    self.enc_size = varint_max_size(self.max_size) + self.max_size
         elif desc.type == FieldD.TYPE_MESSAGE:
             self.pbtype = 'MESSAGE'
             self.ctype = self.submsgname = names_from_type_name(desc.type_name)
             self.enc_size = None # Needs to be filled in after the message type is available
         else:
             raise NotImplementedError(desc.type)
-        
-    def __cmp__(self, other):
-        return cmp(self.tag, other.tag)
-    
+
+    def __lt__(self, other):
+        return self.tag < other.tag
+
     def __str__(self):
         result = ''
         if self.allocation == 'POINTER':
             if self.rules == 'REPEATED':
-                result += '    size_t ' + self.name + '_count;\n'
-            
+                result += '    pb_size_t ' + self.name + '_count;\n'
+
             if self.pbtype == 'MESSAGE':
                 # Use struct definition, so recursive submessages are possible
                 result += '    struct _%s *%s;' % (self.ctype, self.name)
+            elif self.pbtype == 'FIXED_LENGTH_BYTES':
+                # Pointer to fixed size array
+                result += '    %s (*%s)%s;' % (self.ctype, self.name, self.array_decl)
             elif self.rules == 'REPEATED' and self.pbtype in ['STRING', 'BYTES']:
                 # String/bytes arrays need to be defined as pointers to pointers
                 result += '    %s **%s;' % (self.ctype, self.name)
@@ -276,120 +421,230 @@
         else:
             if self.rules == 'OPTIONAL' and self.allocation == 'STATIC':
                 result += '    bool has_' + self.name + ';\n'
-            elif self.rules == 'REPEATED' and self.allocation == 'STATIC':
-                result += '    size_t ' + self.name + '_count;\n'
+            elif (self.rules == 'REPEATED' and
+                  self.allocation == 'STATIC' and
+                  not self.fixed_count):
+                result += '    pb_size_t ' + self.name + '_count;\n'
             result += '    %s %s%s;' % (self.ctype, self.name, self.array_decl)
         return result
-    
+
     def types(self):
         '''Return definitions for any special types this field might need.'''
         if self.pbtype == 'BYTES' and self.allocation == 'STATIC':
-            result = 'typedef struct {\n'
-            result += '    size_t size;\n'
-            result += '    uint8_t bytes[%d];\n' % self.max_size
-            result += '} %s;\n' % self.ctype
+            result = 'typedef PB_BYTES_ARRAY_T(%d) %s;\n' % (self.max_size, self.ctype)
         else:
-            result = None
+            result = ''
         return result
-    
+
+    def get_dependencies(self):
+        '''Get list of type names used by this field.'''
+        if self.allocation == 'STATIC':
+            return [str(self.ctype)]
+        else:
+            return []
+
+    def get_initializer(self, null_init, inner_init_only = False):
+        '''Return literal expression for this field's default value.
+        null_init: If True, initialize to a 0 value instead of default from .proto
+        inner_init_only: If True, exclude initialization for any count/has fields
+        '''
+
+        inner_init = None
+        if self.pbtype == 'MESSAGE':
+            if null_init:
+                inner_init = '%s_init_zero' % self.ctype
+            else:
+                inner_init = '%s_init_default' % self.ctype
+        elif self.default is None or null_init:
+            if self.pbtype == 'STRING':
+                inner_init = '""'
+            elif self.pbtype == 'BYTES':
+                inner_init = '{0, {0}}'
+            elif self.pbtype == 'FIXED_LENGTH_BYTES':
+                inner_init = '{0}'
+            elif self.pbtype in ('ENUM', 'UENUM'):
+                inner_init = '_%s_MIN' % self.ctype
+            else:
+                inner_init = '0'
+        else:
+            if self.pbtype == 'STRING':
+                data = codecs.escape_encode(self.default.encode('utf-8'))[0]
+                inner_init = '"' + data.decode('ascii') + '"'
+            elif self.pbtype == 'BYTES':
+                data = codecs.escape_decode(self.default)[0]
+                data = ["0x%02x" % c for c in bytearray(data)]
+                if len(data) == 0:
+                    inner_init = '{0, {0}}'
+                else:
+                    inner_init = '{%d, {%s}}' % (len(data), ','.join(data))
+            elif self.pbtype == 'FIXED_LENGTH_BYTES':
+                data = codecs.escape_decode(self.default)[0]
+                data = ["0x%02x" % c for c in bytearray(data)]
+                if len(data) == 0:
+                    inner_init = '{0}'
+                else:
+                    inner_init = '{%s}' % ','.join(data)
+            elif self.pbtype in ['FIXED32', 'UINT32']:
+                inner_init = str(self.default) + 'u'
+            elif self.pbtype in ['FIXED64', 'UINT64']:
+                inner_init = str(self.default) + 'ull'
+            elif self.pbtype in ['SFIXED64', 'INT64']:
+                inner_init = str(self.default) + 'll'
+            else:
+                inner_init = str(self.default)
+
+        if inner_init_only:
+            return inner_init
+
+        outer_init = None
+        if self.allocation == 'STATIC':
+            if self.rules == 'REPEATED':
+                outer_init = ''
+                if not self.fixed_count:
+                    outer_init += '0, '
+                outer_init += '{'
+                outer_init += ', '.join([inner_init] * self.max_count)
+                outer_init += '}'
+            elif self.rules == 'OPTIONAL':
+                outer_init = 'false, ' + inner_init
+            else:
+                outer_init = inner_init
+        elif self.allocation == 'POINTER':
+            if self.rules == 'REPEATED':
+                outer_init = '0, NULL'
+            else:
+                outer_init = 'NULL'
+        elif self.allocation == 'CALLBACK':
+            if self.pbtype == 'EXTENSION':
+                outer_init = 'NULL'
+            else:
+                outer_init = '{{NULL}, NULL}'
+
+        return outer_init
+
     def default_decl(self, declaration_only = False):
         '''Return definition for this field's default value.'''
         if self.default is None:
             return None
 
-        ctype, default = self.ctype, self.default
+        ctype = self.ctype
+        default = self.get_initializer(False, True)
         array_decl = ''
-        
+
         if self.pbtype == 'STRING':
             if self.allocation != 'STATIC':
                 return None # Not implemented
-        
             array_decl = '[%d]' % self.max_size
-            default = str(self.default).encode('string_escape')
-            default = default.replace('"', '\\"')
-            default = '"' + default + '"'
         elif self.pbtype == 'BYTES':
             if self.allocation != 'STATIC':
                 return None # Not implemented
+        elif self.pbtype == 'FIXED_LENGTH_BYTES':
+            if self.allocation != 'STATIC':
+                return None # Not implemented
+            array_decl = '[%d]' % self.max_size
 
-            data = self.default.decode('string_escape')
-            data = ['0x%02x' % ord(c) for c in data]
-            default = '{%d, {%s}}' % (len(data), ','.join(data))
-        elif self.pbtype in ['FIXED32', 'UINT32']:
-            default += 'u'
-        elif self.pbtype in ['FIXED64', 'UINT64']:
-            default += 'ull'
-        elif self.pbtype in ['SFIXED64', 'INT64']:
-            default += 'll'
-        
         if declaration_only:
             return 'extern const %s %s_default%s;' % (ctype, self.struct_name + self.name, array_decl)
         else:
             return 'const %s %s_default%s = %s;' % (ctype, self.struct_name + self.name, array_decl, default)
-    
+
     def tags(self):
         '''Return the #define for the tag number of this field.'''
         identifier = '%s_%s_tag' % (self.struct_name, self.name)
         return '#define %-40s %d\n' % (identifier, self.tag)
-    
-    def pb_field_t(self, prev_field_name):
+
+    def pb_field_t(self, prev_field_name, union_index = None):
         '''Return the pb_field_t initializer to use in the constant array.
-        prev_field_name is the name of the previous field or None.
+        prev_field_name is the name of the previous field or None. For OneOf
+        unions, union_index is the index of this field inside the OneOf.
         '''
-        result  = '    PB_FIELD2(%3d, ' % self.tag
+
+        if self.rules == 'ONEOF':
+            if self.anonymous:
+                result = '    PB_ANONYMOUS_ONEOF_FIELD(%s, ' % self.union_name
+            else:
+                result = '    PB_ONEOF_FIELD(%s, ' % self.union_name
+        elif self.fixed_count:
+            result = '    PB_REPEATED_FIXED_COUNT('
+        else:
+            result = '    PB_FIELD('
+
+        result += '%3d, ' % self.tag
         result += '%-8s, ' % self.pbtype
-        result += '%s, ' % self.rules
-        result += '%-8s, ' % self.allocation
-        result += '%s, ' % ("FIRST" if not prev_field_name else "OTHER")
+        if not self.fixed_count:
+            result += '%s, ' % self.rules
+            result += '%-8s, ' % self.allocation
+
+        if union_index is not None and union_index > 0:
+            result += 'UNION, '
+        elif prev_field_name is None:
+            result += 'FIRST, '
+        else:
+            result += 'OTHER, '
+
         result += '%s, ' % self.struct_name
         result += '%s, ' % self.name
         result += '%s, ' % (prev_field_name or self.name)
-        
+
         if self.pbtype == 'MESSAGE':
             result += '&%s_fields)' % self.submsgname
         elif self.default is None:
             result += '0)'
-        elif self.pbtype in ['BYTES', 'STRING'] and self.allocation != 'STATIC':
+        elif self.pbtype in ['BYTES', 'STRING', 'FIXED_LENGTH_BYTES'] and self.allocation != 'STATIC':
             result += '0)' # Arbitrary size default values not implemented
         elif self.rules == 'OPTEXT':
             result += '0)' # Default value for extensions is not implemented
         else:
             result += '&%s_default)' % (self.struct_name + self.name)
-        
+
         return result
-    
+
+    def get_last_field_name(self):
+        return self.name
+
     def largest_field_value(self):
         '''Determine if this field needs 16bit or 32bit pb_field_t structure to compile properly.
         Returns numeric value or a C-expression for assert.'''
-        if self.pbtype == 'MESSAGE':
-            if self.rules == 'REPEATED' and self.allocation == 'STATIC':
-                return 'pb_membersize(%s, %s[0])' % (self.struct_name, self.name)
+        check = []
+        if self.pbtype == 'MESSAGE' and self.allocation == 'STATIC':
+            if self.rules == 'REPEATED':
+                check.append('pb_membersize(%s, %s[0])' % (self.struct_name, self.name))
+            elif self.rules == 'ONEOF':
+                if self.anonymous:
+                    check.append('pb_membersize(%s, %s)' % (self.struct_name, self.name))
+                else:
+                    check.append('pb_membersize(%s, %s.%s)' % (self.struct_name, self.union_name, self.name))
             else:
-                return 'pb_membersize(%s, %s)' % (self.struct_name, self.name)
+                check.append('pb_membersize(%s, %s)' % (self.struct_name, self.name))
+        elif self.pbtype == 'BYTES' and self.allocation == 'STATIC':
+            if self.max_size > 251:
+                check.append('pb_membersize(%s, %s)' % (self.struct_name, self.name))
 
-        return max(self.tag, self.max_size, self.max_count)        
+        return FieldMaxSize([self.tag, self.max_size, self.max_count],
+                            check,
+                            ('%s.%s' % (self.struct_name, self.name)))
 
-    def encoded_size(self, allmsgs):
+    def encoded_size(self, dependencies):
         '''Return the maximum size that this field can take when encoded,
         including the field tag. If the size cannot be determined, returns
         None.'''
-        
+
         if self.allocation != 'STATIC':
             return None
-        
+
         if self.pbtype == 'MESSAGE':
-            for msg in allmsgs:
-                if msg.name == self.submsgname:
-                    encsize = msg.encoded_size(allmsgs)
-                    if encsize is None:
-                        return None # Submessage size is indeterminate
-                        
+            encsize = None
+            if str(self.submsgname) in dependencies:
+                submsg = dependencies[str(self.submsgname)]
+                encsize = submsg.encoded_size(dependencies)
+                if encsize is not None:
                     # Include submessage length prefix
                     encsize += varint_max_size(encsize.upperlimit())
-                    break
-            else:
-                # Submessage cannot be found, this currently occurs when
-                # the submessage type is defined in a different file.
+
+            if encsize is None:
+                # Submessage or its size cannot be found.
+                # This can occur if submessage is defined in different
+                # file, and it or its .options could not be found.
                 # Instead of direct numeric value, reference the size that
                 # has been #defined in the other file.
                 encsize = EncodedSize(self.submsgname + 'size')
@@ -398,20 +653,33 @@
                 # prefix size, though.
                 encsize += 5
 
+        elif self.pbtype in ['ENUM', 'UENUM']:
+            if str(self.ctype) in dependencies:
+                enumtype = dependencies[str(self.ctype)]
+                encsize = enumtype.encoded_size()
+            else:
+                # Conservative assumption
+                encsize = 10
+
         elif self.enc_size is None:
             raise RuntimeError("Could not determine encoded size for %s.%s"
                                % (self.struct_name, self.name))
         else:
             encsize = EncodedSize(self.enc_size)
-        
+
         encsize += varint_max_size(self.tag << 3) # Tag + wire type
 
         if self.rules == 'REPEATED':
             # Decoders must be always able to handle unpacked arrays.
             # Therefore we have to reserve space for it, even though
-            # we emit packed arrays ourselves.
+            # we emit packed arrays ourselves. For length of 1, packed
+            # arrays are larger however so we need to add allowance
+            # for the length byte.
             encsize *= self.max_count
-        
+
+            if self.max_count == 1:
+                encsize += 1
+
         return encsize
 
 
@@ -433,17 +701,18 @@
         self.default = None
         self.max_size = 0
         self.max_count = 0
-        
+        self.fixed_count = False
+
     def __str__(self):
         return '    pb_extension_t *extensions;'
-    
+
     def types(self):
-        return None
-    
+        return ''
+
     def tags(self):
         return ''
-        
-    def encoded_size(self, allmsgs):
+
+    def encoded_size(self, dependencies):
         # We exclude extensions from the count, because they cannot be known
         # until runtime. Other option would be to return None here, but this
         # way the value remains useful if extensions are not used.
@@ -454,7 +723,7 @@
         self.fullname = struct_name + desc.name
         self.extendee_name = names_from_type_name(desc.extendee)
         Field.__init__(self, self.fullname + 'struct', desc, field_options)
-        
+
         if self.rules != 'OPTIONAL':
             self.skip = True
         else:
@@ -472,8 +741,9 @@
             msg = '/* Extension field %s was skipped because only "optional"\n' % self.fullname
             msg +='   type of extension fields is currently supported. */\n'
             return msg
-        
-        return 'extern const pb_extension_type_t %s;\n' % self.fullname
+
+        return ('extern const pb_extension_type_t %s; /* field type: %s */\n' %
+            (self.fullname, str(self).strip()))
 
     def extension_def(self):
         '''Definition of the extension type in the .pb.c file'''
@@ -495,6 +765,106 @@
 
 
 # ---------------------------------------------------------------------------
+#                   Generation of oneofs (unions)
+# ---------------------------------------------------------------------------
+
+class OneOf(Field):
+    def __init__(self, struct_name, oneof_desc):
+        self.struct_name = struct_name
+        self.name = oneof_desc.name
+        self.ctype = 'union'
+        self.pbtype = 'oneof'
+        self.fields = []
+        self.allocation = 'ONEOF'
+        self.default = None
+        self.rules = 'ONEOF'
+        self.anonymous = False
+
+    def add_field(self, field):
+        if field.allocation == 'CALLBACK':
+            raise Exception("Callback fields inside of oneof are not supported"
+                            + " (field %s)" % field.name)
+
+        field.union_name = self.name
+        field.rules = 'ONEOF'
+        field.anonymous = self.anonymous
+        self.fields.append(field)
+        self.fields.sort(key = lambda f: f.tag)
+
+        # Sort by the lowest tag number inside union
+        self.tag = min([f.tag for f in self.fields])
+
+    def __str__(self):
+        result = ''
+        if self.fields:
+            result += '    pb_size_t which_' + self.name + ";\n"
+            result += '    union {\n'
+            for f in self.fields:
+                result += '    ' + str(f).replace('\n', '\n    ') + '\n'
+            if self.anonymous:
+                result += '    };'
+            else:
+                result += '    } ' + self.name + ';'
+        return result
+
+    def types(self):
+        return ''.join([f.types() for f in self.fields])
+
+    def get_dependencies(self):
+        deps = []
+        for f in self.fields:
+            deps += f.get_dependencies()
+        return deps
+
+    def get_initializer(self, null_init):
+        return '0, {' + self.fields[0].get_initializer(null_init) + '}'
+
+    def default_decl(self, declaration_only = False):
+        return None
+
+    def tags(self):
+        return ''.join([f.tags() for f in self.fields])
+
+    def pb_field_t(self, prev_field_name):
+        parts = []
+        for union_index, field in enumerate(self.fields):
+            parts.append(field.pb_field_t(prev_field_name, union_index))
+        return ',\n'.join(parts)
+
+    def get_last_field_name(self):
+        if self.anonymous:
+            return self.fields[-1].name
+        else:
+            return self.name + '.' + self.fields[-1].name
+
+    def largest_field_value(self):
+        largest = FieldMaxSize()
+        for f in self.fields:
+            largest.extend(f.largest_field_value())
+        return largest
+
+    def encoded_size(self, dependencies):
+        '''Returns the size of the largest oneof field.'''
+        largest = EncodedSize(0)
+        symbols = set()
+        for f in self.fields:
+            size = EncodedSize(f.encoded_size(dependencies))
+            if size.value is None:
+                return None
+            elif size.symbols:
+                symbols.add(EncodedSize(f.submsgname + 'size').symbols[0])
+            elif size.value > largest.value:
+                largest = size
+
+        if not symbols:
+            return largest
+
+        symbols = list(symbols)
+        symbols.append(str(largest))
+        max_size = lambda x, y: '({0} > {1} ? {0} : {1})'.format(x, y)
+        return reduce(max_size, symbols)
+
+# ---------------------------------------------------------------------------
 #                   Generation of messages (structures)
 # ---------------------------------------------------------------------------
 
@@ -503,56 +873,94 @@
     def __init__(self, names, desc, message_options):
         self.name = names
         self.fields = []
-        
+        self.oneofs = {}
+        no_unions = []
+
+        if message_options.msgid:
+            self.msgid = message_options.msgid
+
+        if hasattr(desc, 'oneof_decl'):
+            for i, f in enumerate(desc.oneof_decl):
+                oneof_options = get_nanopb_suboptions(desc, message_options, self.name + f.name)
+                if oneof_options.no_unions:
+                    no_unions.append(i) # No union, but add fields normally
+                elif oneof_options.type == nanopb_pb2.FT_IGNORE:
+                    pass # No union and skip fields also
+                else:
+                    oneof = OneOf(self.name, f)
+                    if oneof_options.anonymous_oneof:
+                        oneof.anonymous = True
+                    self.oneofs[i] = oneof
+                    self.fields.append(oneof)
+        else:
+            sys.stderr.write('Note: This Python protobuf library has no OneOf support\n')
+
         for f in desc.field:
             field_options = get_nanopb_suboptions(f, message_options, self.name + f.name)
-            if field_options.type != nanopb_pb2.FT_IGNORE:
-                self.fields.append(Field(self.name, f, field_options))
-        
+            if field_options.type == nanopb_pb2.FT_IGNORE:
+                continue
+
+            field = Field(self.name, f, field_options)
+            if (hasattr(f, 'oneof_index') and
+                f.HasField('oneof_index') and
+                f.oneof_index not in no_unions):
+                if f.oneof_index in self.oneofs:
+                    self.oneofs[f.oneof_index].add_field(field)
+            else:
+                self.fields.append(field)
+
         if len(desc.extension_range) > 0:
             field_options = get_nanopb_suboptions(desc, message_options, self.name + 'extensions')
             range_start = min([r.start for r in desc.extension_range])
             if field_options.type != nanopb_pb2.FT_IGNORE:
                 self.fields.append(ExtensionRange(self.name, range_start, field_options))
-        
+
         self.packed = message_options.packed_struct
         self.ordered_fields = self.fields[:]
         self.ordered_fields.sort()
 
     def get_dependencies(self):
         '''Get list of type names that this structure refers to.'''
-        return [str(field.ctype) for field in self.fields]
-    
+        deps = []
+        for f in self.fields:
+            deps += f.get_dependencies()
+        return deps
+
     def __str__(self):
         result = 'typedef struct _%s {\n' % self.name
 
         if not self.ordered_fields:
             # Empty structs are not allowed in C standard.
             # Therefore add a dummy field if an empty message occurs.
-            result += '    uint8_t dummy_field;'
+            result += '    char dummy_field;'
 
         result += '\n'.join([str(f) for f in self.ordered_fields])
+        result += '\n/* @@protoc_insertion_point(struct:%s) */' % self.name
         result += '\n}'
-        
+
         if self.packed:
             result += ' pb_packed'
-        
+
         result += ' %s;' % self.name
-        
+
         if self.packed:
             result = 'PB_PACKED_STRUCT_START\n' + result
             result += '\nPB_PACKED_STRUCT_END'
-        
+
         return result
-    
+
     def types(self):
-        result = ""
-        for field in self.fields:
-            types = field.types()
-            if types is not None:
-                result += types + '\n'
-        return result
-    
+        return ''.join([f.types() for f in self.fields])
+
+    def get_initializer(self, null_init):
+        if not self.ordered_fields:
+            return '{0}'
+
+        parts = []
+        for field in self.ordered_fields:
+            parts.append(field.get_initializer(null_init))
+        return '{' + ', '.join(parts) + '}'
+
     def default_decl(self, declaration_only = False):
         result = ""
         for field in self.fields:
@@ -561,33 +969,51 @@
                 result += default + '\n'
         return result
 
+    def count_required_fields(self):
+        '''Returns number of required fields inside this message'''
+        count = 0
+        for f in self.fields:
+            if not isinstance(f, OneOf):
+                if f.rules == 'REQUIRED':
+                    count += 1
+        return count
+
+    def count_all_fields(self):
+        count = 0
+        for f in self.fields:
+            if isinstance(f, OneOf):
+                count += len(f.fields)
+            else:
+                count += 1
+        return count
+
     def fields_declaration(self):
-        result = 'extern const pb_field_t %s_fields[%d];' % (self.name, len(self.fields) + 1)
+        result = 'extern const pb_field_t %s_fields[%d];' % (self.name, self.count_all_fields() + 1)
         return result
 
     def fields_definition(self):
-        result = 'const pb_field_t %s_fields[%d] = {\n' % (self.name, len(self.fields) + 1)
-        
+        result = 'const pb_field_t %s_fields[%d] = {\n' % (self.name, self.count_all_fields() + 1)
+
         prev = None
         for field in self.ordered_fields:
             result += field.pb_field_t(prev)
             result += ',\n'
-            prev = field.name
-        
+            prev = field.get_last_field_name()
+
         result += '    PB_LAST_FIELD\n};'
         return result
 
-    def encoded_size(self, allmsgs):
+    def encoded_size(self, dependencies):
         '''Return the maximum size that this message can take when encoded.
         If the size cannot be determined, returns None.
         '''
         size = EncodedSize(0)
         for field in self.fields:
-            fsize = field.encoded_size(allmsgs)
+            fsize = field.encoded_size(dependencies)
             if fsize is None:
                 return None
             size += fsize
-        
+
         return size
 
 
@@ -595,18 +1021,17 @@
 #                    Processing of entire .proto files
 # ---------------------------------------------------------------------------
 
-
 def iterate_messages(desc, names = Names()):
     '''Recursively find all messages. For each, yield name, DescriptorProto.'''
     if hasattr(desc, 'message_type'):
         submsgs = desc.message_type
     else:
         submsgs = desc.nested_type
-    
+
     for submsg in submsgs:
         sub_names = names + submsg.name
         yield sub_names, submsg
-        
+
         for x in iterate_messages(submsg, sub_names):
             yield x
 
@@ -621,61 +1046,22 @@
         for extension in subdesc.extension:
             yield subname, extension
 
-def parse_file(fdesc, file_options):
-    '''Takes a FileDescriptorProto and returns tuple (enums, messages, extensions).'''
-    
-    enums = []
-    messages = []
-    extensions = []
-    
-    if fdesc.package:
-        base_name = Names(fdesc.package.split('.'))
-    else:
-        base_name = Names()
-    
-    for enum in fdesc.enum_type:
-        enum_options = get_nanopb_suboptions(enum, file_options, base_name + enum.name)
-        enums.append(Enum(base_name, enum, enum_options))
-    
-    for names, message in iterate_messages(fdesc, base_name):
-        message_options = get_nanopb_suboptions(message, file_options, names)
-        messages.append(Message(names, message, message_options))
-        for enum in message.enum_type:
-            enum_options = get_nanopb_suboptions(enum, message_options, names + enum.name)
-            enums.append(Enum(names, enum, enum_options))
-    
-    for names, extension in iterate_extensions(fdesc, base_name):
-        field_options = get_nanopb_suboptions(extension, file_options, names)
-        if field_options.type != nanopb_pb2.FT_IGNORE:
-            extensions.append(ExtensionField(names, extension, field_options))
-    
-    # Fix field default values where enum short names are used.
-    for enum in enums:
-        if not enum.options.long_names:
-            for message in messages:
-                for field in message.fields:
-                    if field.default in enum.value_longnames:
-                        idx = enum.value_longnames.index(field.default)
-                        field.default = enum.values[idx][0]
-    
-    return enums, messages, extensions
-
 def toposort2(data):
     '''Topological sort.
     From http://code.activestate.com/recipes/577413-topological-sort/
     This function is under the MIT license.
     '''
-    for k, v in data.items():
+    for k, v in list(data.items()):
         v.discard(k) # Ignore self dependencies
-    extra_items_in_deps = reduce(set.union, data.values(), set()) - set(data.keys())
+    extra_items_in_deps = reduce(set.union, list(data.values()), set()) - set(data.keys())
     data.update(dict([(item, set()) for item in extra_items_in_deps]))
     while True:
-        ordered = set(item for item,dep in data.items() if not dep)
+        ordered = set(item for item,dep in list(data.items()) if not dep)
         if not ordered:
             break
         for item in sorted(ordered):
             yield item
-        data = dict([(item, (dep - ordered)) for item,dep in data.items()
+        data = dict([(item, (dep - ordered)) for item,dep in list(data.items())
                 if item not in ordered])
     assert not data, "A cyclic dependency exists amongst %r" % data
 
@@ -686,7 +1072,7 @@
     for message in messages:
         dependencies[str(message.name)] = set(message.get_dependencies())
         message_by_name[str(message.name)] = message
-    
+
     for msgname in toposort2(dependencies):
         if msgname in message_by_name:
             yield message_by_name[msgname]
@@ -701,185 +1087,311 @@
             result += '_'
     return result
 
-def generate_header(dependencies, headername, enums, messages, extensions, options):
-    '''Generate content for a header file.
-    Generates strings, which should be concatenated and stored to file.
-    '''
-    
-    yield '/* Automatically generated nanopb header */\n'
-    if options.notimestamp:
-        yield '/* Generated by %s */\n\n' % (nanopb_version)
-    else:
-        yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime())
-    
-    symbol = make_identifier(headername)
-    yield '#ifndef _PB_%s_\n' % symbol
-    yield '#define _PB_%s_\n' % symbol
-    try:
-        yield options.libformat % ('pb.h')
-    except TypeError:
-        # no %s specified - use whatever was passed in as options.libformat
-        yield options.libformat
-    yield '\n'
-    
-    for dependency in dependencies:
-        noext = os.path.splitext(dependency)[0]
-        yield options.genformat % (noext + '.' + options.extension + '.h')
+class ProtoFile:
+    def __init__(self, fdesc, file_options):
+        '''Takes a FileDescriptorProto and parses it.'''
+        self.fdesc = fdesc
+        self.file_options = file_options
+        self.dependencies = {}
+        self.parse()
+
+        # Some of types used in this file probably come from the file itself.
+        # Thus it has implicit dependency on itself.
+        self.add_dependency(self)
+
+    def parse(self):
+        self.enums = []
+        self.messages = []
+        self.extensions = []
+
+        if self.fdesc.package:
+            base_name = Names(self.fdesc.package.split('.'))
+        else:
+            base_name = Names()
+
+        for enum in self.fdesc.enum_type:
+            enum_options = get_nanopb_suboptions(enum, self.file_options, base_name + enum.name)
+            self.enums.append(Enum(base_name, enum, enum_options))
+
+        for names, message in iterate_messages(self.fdesc, base_name):
+            message_options = get_nanopb_suboptions(message, self.file_options, names)
+
+            if message_options.skip_message:
+                continue
+
+            self.messages.append(Message(names, message, message_options))
+            for enum in message.enum_type:
+                enum_options = get_nanopb_suboptions(enum, message_options, names + enum.name)
+                self.enums.append(Enum(names, enum, enum_options))
+
+        for names, extension in iterate_extensions(self.fdesc, base_name):
+            field_options = get_nanopb_suboptions(extension, self.file_options, names + extension.name)
+            if field_options.type != nanopb_pb2.FT_IGNORE:
+                self.extensions.append(ExtensionField(names, extension, field_options))
+
+    def add_dependency(self, other):
+        for enum in other.enums:
+            self.dependencies[str(enum.names)] = enum
+
+        for msg in other.messages:
+            self.dependencies[str(msg.name)] = msg
+
+        # Fix field default values where enum short names are used.
+        for enum in other.enums:
+            if not enum.options.long_names:
+                for message in self.messages:
+                    for field in message.fields:
+                        if field.default in enum.value_longnames:
+                            idx = enum.value_longnames.index(field.default)
+                            field.default = enum.values[idx][0]
+
+        # Fix field data types where enums have negative values.
+        for enum in other.enums:
+            if not enum.has_negative():
+                for message in self.messages:
+                    for field in message.fields:
+                        if field.pbtype == 'ENUM' and field.ctype == enum.names:
+                            field.pbtype = 'UENUM'
+
+    def generate_header(self, includes, headername, options):
+        '''Generate content for a header file.
+        Generates strings, which should be concatenated and stored to file.
+        '''
+
+        yield '/* Automatically generated nanopb header */\n'
+        if options.notimestamp:
+            yield '/* Generated by %s */\n\n' % (nanopb_version)
+        else:
+            yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime())
+
+        if self.fdesc.package:
+            symbol = make_identifier(self.fdesc.package + '_' + headername)
+        else:
+            symbol = make_identifier(headername)
+        yield '#ifndef PB_%s_INCLUDED\n' % symbol
+        yield '#define PB_%s_INCLUDED\n' % symbol
+        try:
+            yield options.libformat % ('pb.h')
+        except TypeError:
+            # no %s specified - use whatever was passed in as options.libformat
+            yield options.libformat
         yield '\n'
 
-    yield '#ifdef __cplusplus\n'
-    yield 'extern "C" {\n'
-    yield '#endif\n\n'
-    
-    yield '/* Enum definitions */\n'
-    for enum in enums:
-        yield str(enum) + '\n\n'
-    
-    yield '/* Struct definitions */\n'
-    for msg in sort_dependencies(messages):
-        yield msg.types()
-        yield str(msg) + '\n\n'
-    
-    if extensions:
-        yield '/* Extensions */\n'
-        for extension in extensions:
-            yield extension.extension_decl()
+        for incfile in includes:
+            noext = os.path.splitext(incfile)[0]
+            yield options.genformat % (noext + options.extension + options.header_extension)
+            yield '\n'
+
+        yield '/* @@protoc_insertion_point(includes) */\n'
+
+        yield '#if PB_PROTO_HEADER_VERSION != 30\n'
+        yield '#error Regenerate this file with the current version of nanopb generator.\n'
+        yield '#endif\n'
         yield '\n'
-        
-    yield '/* Default values for struct fields */\n'
-    for msg in messages:
-        yield msg.default_decl(True)
-    yield '\n'
-    
-    yield '/* Field tags (for use in manual encoding/decoding) */\n'
-    for msg in sort_dependencies(messages):
-        for field in msg.fields:
-            yield field.tags()
-    for extension in extensions:
-        yield extension.tags()
-    yield '\n'
-    
-    yield '/* Struct field encoding specification for nanopb */\n'
-    for msg in messages:
-        yield msg.fields_declaration() + '\n'
-    yield '\n'
-    
-    yield '/* Maximum encoded size of messages (where known) */\n'
-    for msg in messages:
-        msize = msg.encoded_size(messages)
-        if msize is not None:
-            identifier = '%s_size' % msg.name
-            yield '#define %-40s %s\n' % (identifier, msize)
-    yield '\n'
-    
-    yield '#ifdef __cplusplus\n'
-    yield '} /* extern "C" */\n'
-    yield '#endif\n'
-    
-    # End of header
-    yield '\n#endif\n'
 
-def generate_source(headername, enums, messages, extensions, options):
-    '''Generate content for a source file.'''
-    
-    yield '/* Automatically generated nanopb constant definitions */\n'
-    if options.notimestamp:
-        yield '/* Generated by %s */\n\n' % (nanopb_version)
-    else:
-        yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime())
-    yield options.genformat % (headername)
-    yield '\n'
-    
-    for msg in messages:
-        yield msg.default_decl(False)
-    
-    yield '\n\n'
-    
-    for msg in messages:
-        yield msg.fields_definition() + '\n\n'
-    
-    for ext in extensions:
-        yield ext.extension_def() + '\n'
-        
-    # Add checks for numeric limits
-    if messages:
-        count_required_fields = lambda m: len([f for f in msg.fields if f.rules == 'REQUIRED'])
-        largest_msg = max(messages, key = count_required_fields)
-        largest_count = count_required_fields(largest_msg)
-        if largest_count > 64:
-            yield '\n/* Check that missing required fields will be properly detected */\n'
-            yield '#if PB_MAX_REQUIRED_FIELDS < %d\n' % largest_count
-            yield '#error Properly detecting missing required fields in %s requires \\\n' % largest_msg.name
-            yield '       setting PB_MAX_REQUIRED_FIELDS to %d or more.\n' % largest_count
-            yield '#endif\n'
-    
-    worst = 0
-    worst_field = ''
-    checks = []
-    checks_msgnames = []
-    for msg in messages:
-        checks_msgnames.append(msg.name)
-        for field in msg.fields:
-            status = field.largest_field_value()
-            if isinstance(status, (str, unicode)):
-                checks.append(status)
-            elif status > worst:
-                worst = status
-                worst_field = str(field.struct_name) + '.' + str(field.name)
+        yield '#ifdef __cplusplus\n'
+        yield 'extern "C" {\n'
+        yield '#endif\n\n'
 
-    if worst > 255 or checks:
-        yield '\n/* Check that field information fits in pb_field_t */\n'
-        
-        if worst > 65535 or checks:
-            yield '#if !defined(PB_FIELD_32BIT)\n'
-            if worst > 65535:
-                yield '#error Field descriptor for %s is too large. Define PB_FIELD_32BIT to fix this.\n' % worst_field
-            else:
-                assertion = ' && '.join(str(c) + ' < 65536' for c in checks)
-                msgs = '_'.join(str(n) for n in checks_msgnames)
-                yield '/* If you get an error here, it means that you need to define PB_FIELD_32BIT\n'
-                yield ' * compile-time option. You can do that in pb.h or on compiler command line.\n'
-                yield ' * \n'
-                yield ' * The reason you need to do this is that some of your messages contain tag\n'
-                yield ' * numbers or field sizes that are larger than what can fit in 8 or 16 bit\n'
-                yield ' * field descriptors.\n'
-                yield ' */\n'
-                yield 'STATIC_ASSERT((%s), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_%s)\n'%(assertion,msgs)
+        if self.enums:
+            yield '/* Enum definitions */\n'
+            for enum in self.enums:
+                yield str(enum) + '\n\n'
+
+        if self.messages:
+            yield '/* Struct definitions */\n'
+            for msg in sort_dependencies(self.messages):
+                yield msg.types()
+                yield str(msg) + '\n\n'
+
+        if self.extensions:
+            yield '/* Extensions */\n'
+            for extension in self.extensions:
+                yield extension.extension_decl()
+            yield '\n'
+
+        if self.messages:
+            yield '/* Default values for struct fields */\n'
+            for msg in self.messages:
+                yield msg.default_decl(True)
+            yield '\n'
+
+            yield '/* Initializer values for message structs */\n'
+            for msg in self.messages:
+                identifier = '%s_init_default' % msg.name
+                yield '#define %-40s %s\n' % (identifier, msg.get_initializer(False))
+            for msg in self.messages:
+                identifier = '%s_init_zero' % msg.name
+                yield '#define %-40s %s\n' % (identifier, msg.get_initializer(True))
+            yield '\n'
+
+            yield '/* Field tags (for use in manual encoding/decoding) */\n'
+            for msg in sort_dependencies(self.messages):
+                for field in msg.fields:
+                    yield field.tags()
+            for extension in self.extensions:
+                yield extension.tags()
+            yield '\n'
+
+            yield '/* Struct field encoding specification for nanopb */\n'
+            for msg in self.messages:
+                yield msg.fields_declaration() + '\n'
+            yield '\n'
+
+            yield '/* Maximum encoded size of messages (where known) */\n'
+            for msg in self.messages:
+                msize = msg.encoded_size(self.dependencies)
+                identifier = '%s_size' % msg.name
+                if msize is not None:
+                    yield '#define %-40s %s\n' % (identifier, msize)
+                else:
+                    yield '/* %s depends on runtime parameters */\n' % identifier
+            yield '\n'
+
+            yield '/* Message IDs (where set with "msgid" option) */\n'
+
+            yield '#ifdef PB_MSGID\n'
+            for msg in self.messages:
+                if hasattr(msg,'msgid'):
+                    yield '#define PB_MSG_%d %s\n' % (msg.msgid, msg.name)
+            yield '\n'
+
+            symbol = make_identifier(headername.split('.')[0])
+            yield '#define %s_MESSAGES \\\n' % symbol
+
+            for msg in self.messages:
+                m = "-1"
+                msize = msg.encoded_size(self.dependencies)
+                if msize is not None:
+                    m = msize
+                if hasattr(msg,'msgid'):
+                    yield '\tPB_MSG(%d,%s,%s) \\\n' % (msg.msgid, m, msg.name)
+            yield '\n'
+
+            for msg in self.messages:
+                if hasattr(msg,'msgid'):
+                    yield '#define %s_msgid %d\n' % (msg.name, msg.msgid)
+            yield '\n'
+
             yield '#endif\n\n'
-        
-        if worst < 65536:
-            yield '#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)\n'
-            if worst > 255:
-                yield '#error Field descriptor for %s is too large. Define PB_FIELD_16BIT to fix this.\n' % worst_field
-            else:
-                assertion = ' && '.join(str(c) + ' < 256' for c in checks)
-                msgs = '_'.join(str(n) for n in checks_msgnames)
-                yield '/* If you get an error here, it means that you need to define PB_FIELD_16BIT\n'
-                yield ' * compile-time option. You can do that in pb.h or on compiler command line.\n'
-                yield ' * \n'
-                yield ' * The reason you need to do this is that some of your messages contain tag\n'
-                yield ' * numbers or field sizes that are larger than what can fit in the default\n'
-                yield ' * 8 bit descriptors.\n'
-                yield ' */\n'
-                yield 'STATIC_ASSERT((%s), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_%s)\n'%(assertion,msgs)
-            yield '#endif\n\n'
-    
-    # Add check for sizeof(double)
-    has_double = False
-    for msg in messages:
-        for field in msg.fields:
-            if field.ctype == 'double':
-                has_double = True
-    
-    if has_double:
+
+        yield '#ifdef __cplusplus\n'
+        yield '} /* extern "C" */\n'
+        yield '#endif\n'
+
+        # End of header
+        yield '/* @@protoc_insertion_point(eof) */\n'
+        yield '\n#endif\n'
+
+    def generate_source(self, headername, options):
+        '''Generate content for a source file.'''
+
+        yield '/* Automatically generated nanopb constant definitions */\n'
+        if options.notimestamp:
+            yield '/* Generated by %s */\n\n' % (nanopb_version)
+        else:
+            yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime())
+        yield options.genformat % (headername)
         yield '\n'
-        yield '/* On some platforms (such as AVR), double is really float.\n'
-        yield ' * These are not directly supported by nanopb, but see example_avr_double.\n'
-        yield ' * To get rid of this error, remove any double fields from your .proto.\n'
-        yield ' */\n'
-        yield 'STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES)\n'
-    
-    yield '\n'
+        yield '/* @@protoc_insertion_point(includes) */\n'
+
+        yield '#if PB_PROTO_HEADER_VERSION != 30\n'
+        yield '#error Regenerate this file with the current version of nanopb generator.\n'
+        yield '#endif\n'
+        yield '\n'
+
+        for msg in self.messages:
+            yield msg.default_decl(False)
+
+        yield '\n\n'
+
+        for msg in self.messages:
+            yield msg.fields_definition() + '\n\n'
+
+        for ext in self.extensions:
+            yield ext.extension_def() + '\n'
+
+        for enum in self.enums:
+            yield enum.enum_to_string_definition() + '\n'
+
+        # Add checks for numeric limits
+        if self.messages:
+            largest_msg = max(self.messages, key = lambda m: m.count_required_fields())
+            largest_count = largest_msg.count_required_fields()
+            if largest_count > 64:
+                yield '\n/* Check that missing required fields will be properly detected */\n'
+                yield '#if PB_MAX_REQUIRED_FIELDS < %d\n' % largest_count
+                yield '#error Properly detecting missing required fields in %s requires \\\n' % largest_msg.name
+                yield '       setting PB_MAX_REQUIRED_FIELDS to %d or more.\n' % largest_count
+                yield '#endif\n'
+
+        max_field = FieldMaxSize()
+        checks_msgnames = []
+        for msg in self.messages:
+            checks_msgnames.append(msg.name)
+            for field in msg.fields:
+                max_field.extend(field.largest_field_value())
+        for field in self.extensions:
+            max_field.extend(field.largest_field_value())
+
+        worst = max_field.worst
+        worst_field = max_field.worst_field
+        checks = max_field.checks
+
+        if worst > 255 or checks:
+            yield '\n/* Check that field information fits in pb_field_t */\n'
+
+            if worst > 65535 or checks:
+                yield '#if !defined(PB_FIELD_32BIT)\n'
+                if worst > 65535:
+                    yield '#error Field descriptor for %s is too large. Define PB_FIELD_32BIT to fix this.\n' % worst_field
+                else:
+                    assertion = ' && '.join(str(c) + ' < 65536' for c in checks)
+                    msgs = '_'.join(str(n) for n in checks_msgnames)
+                    yield '/* If you get an error here, it means that you need to define PB_FIELD_32BIT\n'
+                    yield ' * compile-time option. You can do that in pb.h or on compiler command line.\n'
+                    yield ' * \n'
+                    yield ' * The reason you need to do this is that some of your messages contain tag\n'
+                    yield ' * numbers or field sizes that are larger than what can fit in 8 or 16 bit\n'
+                    yield ' * field descriptors.\n'
+                    yield ' */\n'
+                    yield 'PB_STATIC_ASSERT((%s), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_%s)\n'%(assertion,msgs)
+                yield '#endif\n\n'
+
+            if worst < 65536:
+                yield '#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)\n'
+                if worst > 255:
+                    yield '#error Field descriptor for %s is too large. Define PB_FIELD_16BIT to fix this.\n' % worst_field
+                else:
+                    assertion = ' && '.join(str(c) + ' < 256' for c in checks)
+                    msgs = '_'.join(str(n) for n in checks_msgnames)
+                    yield '/* If you get an error here, it means that you need to define PB_FIELD_16BIT\n'
+                    yield ' * compile-time option. You can do that in pb.h or on compiler command line.\n'
+                    yield ' * \n'
+                    yield ' * The reason you need to do this is that some of your messages contain tag\n'
+                    yield ' * numbers or field sizes that are larger than what can fit in the default\n'
+                    yield ' * 8 bit descriptors.\n'
+                    yield ' */\n'
+                    yield 'PB_STATIC_ASSERT((%s), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_%s)\n'%(assertion,msgs)
+                yield '#endif\n\n'
+
+        # Add check for sizeof(double)
+        has_double = False
+        for msg in self.messages:
+            for field in msg.fields:
+                if field.ctype == 'double':
+                    has_double = True
+
+        if has_double:
+            yield '\n'
+            yield '/* On some platforms (such as AVR), double is really float.\n'
+            yield ' * These are not directly supported by nanopb, but see example_avr_double.\n'
+            yield ' * To get rid of this error, remove any double fields from your .proto.\n'
+            yield ' */\n'
+            yield 'PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES)\n'
+
+        yield '\n'
+        yield '/* @@protoc_insertion_point(eof) */\n'
 
 # ---------------------------------------------------------------------------
 #                    Options parsing for the .proto files
@@ -892,14 +1404,32 @@
         [(namemask, options), ...]
     '''
     results = []
-    for line in infile:
+    data = infile.read()
+    data = re.sub('/\*.*?\*/', '', data, flags = re.MULTILINE)
+    data = re.sub('//.*?$', '', data, flags = re.MULTILINE)
+    data = re.sub('#.*?$', '', data, flags = re.MULTILINE)
+    for i, line in enumerate(data.split('\n')):
         line = line.strip()
-        if not line or line.startswith('//') or line.startswith('#'):
+        if not line:
             continue
-        
+
         parts = line.split(None, 1)
+
+        if len(parts) < 2:
+            sys.stderr.write("%s:%d: " % (infile.name, i + 1) +
+                             "Option lines should have space between field name and options. " +
+                             "Skipping line: '%s'\n" % line)
+            continue
+
         opts = nanopb_pb2.NanoPBOptions()
-        text_format.Merge(parts[1], opts)
+
+        try:
+            text_format.Merge(parts[1], opts)
+        except Exception as e:
+            sys.stderr.write("%s:%d: " % (infile.name, i + 1) +
+                             "Unparseable option line: '%s'. " % line +
+                             "Error: %s\n" % str(e))
+            continue
         results.append((parts[0], opts))
 
     return results
@@ -914,14 +1444,17 @@
     '''Get copy of options, and merge information from subdesc.'''
     new_options = nanopb_pb2.NanoPBOptions()
     new_options.CopyFrom(options)
-    
+
+    if hasattr(subdesc, 'syntax') and subdesc.syntax == "proto3":
+        new_options.proto3 = True
+
     # Handle options defined in a separate file
     dotname = '.'.join(name.parts)
     for namemask, options in Globals.separate_options:
         if fnmatch(dotname, namemask):
             Globals.matched_namemasks.add(namemask)
             new_options.MergeFrom(options)
-    
+
     # Handle options defined in .proto
     if isinstance(subdesc.options, descriptor.FieldOptions):
         ext_type = nanopb_pb2.nanopb
@@ -933,15 +1466,15 @@
         ext_type = nanopb_pb2.nanopb_enumopt
     else:
         raise Exception("Unknown options type")
-    
+
     if subdesc.options.HasExtension(ext_type):
         ext = subdesc.options.Extensions[ext_type]
         new_options.MergeFrom(ext)
-    
+
     if Globals.verbose_options:
         sys.stderr.write("Options for " + dotname + ": ")
         sys.stderr.write(text_format.MessageToString(new_options) + "\n")
-    
+
     return new_options
 
 
@@ -950,7 +1483,7 @@
 # ---------------------------------------------------------------------------
 
 import sys
-import os.path    
+import os.path
 from optparse import OptionParser
 
 optparser = OptionParser(
@@ -959,10 +1492,20 @@
              "Output will be written to file.pb.h and file.pb.c.")
 optparser.add_option("-x", dest="exclude", metavar="FILE", action="append", default=[],
     help="Exclude file from generated #include list.")
-optparser.add_option("-e", "--extension", dest="extension", metavar="EXTENSION", default="pb",
-    help="Set extension to use instead of 'pb' for generated files. [default: %default]")
+optparser.add_option("-e", "--extension", dest="extension", metavar="EXTENSION", default=".pb",
+    help="Set extension to use instead of '.pb' for generated files. [default: %default]")
+optparser.add_option("-H", "--header-extension", dest="header_extension", metavar="EXTENSION", default=".h",
+    help="Set extension to use for generated header files. [default: %default]")
+optparser.add_option("-S", "--source-extension", dest="source_extension", metavar="EXTENSION", default=".c",
+    help="Set extension to use for generated source files. [default: %default]")
 optparser.add_option("-f", "--options-file", dest="options_file", metavar="FILE", default="%s.options",
     help="Set name of a separate generator options file.")
+optparser.add_option("-I", "--options-path", dest="options_path", metavar="DIR",
+    action="append", default = [],
+    help="Search for .options files additionally in this path")
+optparser.add_option("-D", "--output-dir", dest="output_dir",
+                     metavar="OUTPUTDIR", default=None,
+                     help="Output directory of .pb.h and .pb.c files")
 optparser.add_option("-Q", "--generated-include-format", dest="genformat",
     metavar="FORMAT", default='#include "%s"\n',
     help="Set format string to use for including other .pb.h files. [default: %default]")
@@ -978,12 +1521,56 @@
 optparser.add_option("-s", dest="settings", metavar="OPTION:VALUE", action="append", default=[],
     help="Set generator option (max_size, max_count etc.).")
 
-def process_file(filename, fdesc, options):
+def parse_file(filename, fdesc, options):
+    '''Parse a single file. Returns a ProtoFile instance.'''
+    toplevel_options = nanopb_pb2.NanoPBOptions()
+    for s in options.settings:
+        text_format.Merge(s, toplevel_options)
+
+    if not fdesc:
+        data = open(filename, 'rb').read()
+        fdesc = descriptor.FileDescriptorSet.FromString(data).file[0]
+
+    # Check if there is a separate .options file
+    had_abspath = False
+    try:
+        optfilename = options.options_file % os.path.splitext(filename)[0]
+    except TypeError:
+        # No %s specified, use the filename as-is
+        optfilename = options.options_file
+        had_abspath = True
+
+    paths = ['.'] + options.options_path
+    for p in paths:
+        if os.path.isfile(os.path.join(p, optfilename)):
+            optfilename = os.path.join(p, optfilename)
+            if options.verbose:
+                sys.stderr.write('Reading options from ' + optfilename + '\n')
+            Globals.separate_options = read_options_file(open(optfilename, "rU"))
+            break
+    else:
+        # If we are given a full filename and it does not exist, give an error.
+        # However, don't give error when we automatically look for .options file
+        # with the same name as .proto.
+        if options.verbose or had_abspath:
+            sys.stderr.write('Options file not found: ' + optfilename + '\n')
+        Globals.separate_options = []
+
+    Globals.matched_namemasks = set()
+
+    # Parse the file
+    file_options = get_nanopb_suboptions(fdesc, toplevel_options, Names([filename]))
+    f = ProtoFile(fdesc, file_options)
+    f.optfilename = optfilename
+
+    return f
+
+def process_file(filename, fdesc, options, other_files = {}):
     '''Process a single file.
     filename: The full path to the .proto or .pb source file, as string.
     fdesc: The loaded FileDescriptorSet, or None to read from the input file.
     options: Command line options as they come from OptionsParser.
-    
+
     Returns a dict:
         {'headername': Name of header file,
          'headerdata': Data for the .h header file,
@@ -991,121 +1578,136 @@
          'sourcedata': Data for the .c source code file
         }
     '''
-    toplevel_options = nanopb_pb2.NanoPBOptions()
-    for s in options.settings:
-        text_format.Merge(s, toplevel_options)
-    
-    if not fdesc:
-        data = open(filename, 'rb').read()
-        fdesc = descriptor.FileDescriptorSet.FromString(data).file[0]
-    
-    # Check if there is a separate .options file
-    try:
-        optfilename = options.options_file % os.path.splitext(filename)[0]
-    except TypeError:
-        # No %s specified, use the filename as-is
-        optfilename = options.options_file
-    
-    if os.path.isfile(optfilename):
-        if options.verbose:
-            sys.stderr.write('Reading options from ' + optfilename + '\n')
+    f = parse_file(filename, fdesc, options)
 
-        Globals.separate_options = read_options_file(open(optfilename, "rU"))
-    else:
-        Globals.separate_options = []
-    Globals.matched_namemasks = set()
-    
-    # Parse the file
-    file_options = get_nanopb_suboptions(fdesc, toplevel_options, Names([filename]))
-    enums, messages, extensions = parse_file(fdesc, file_options)
-    
+    # Provide dependencies if available
+    for dep in f.fdesc.dependency:
+        if dep in other_files:
+            f.add_dependency(other_files[dep])
+
     # Decide the file names
     noext = os.path.splitext(filename)[0]
-    headername = noext + '.' + options.extension + '.h'
-    sourcename = noext + '.' + options.extension + '.c'
+    headername = noext + options.extension + options.header_extension
+    sourcename = noext + options.extension + options.source_extension
     headerbasename = os.path.basename(headername)
-    
+
     # List of .proto files that should not be included in the C header file
     # even if they are mentioned in the source .proto.
     excludes = ['nanopb.proto', 'google/protobuf/descriptor.proto'] + options.exclude
-    dependencies = [d for d in fdesc.dependency if d not in excludes]
-    
-    headerdata = ''.join(generate_header(dependencies, headerbasename, enums,
-                                         messages, extensions, options))
+    includes = [d for d in f.fdesc.dependency if d not in excludes]
 
-    sourcedata = ''.join(generate_source(headerbasename, enums,
-                                         messages, extensions, options))
+    headerdata = ''.join(f.generate_header(includes, headerbasename, options))
+    sourcedata = ''.join(f.generate_source(headerbasename, options))
 
     # Check if there were any lines in .options that did not match a member
     unmatched = [n for n,o in Globals.separate_options if n not in Globals.matched_namemasks]
     if unmatched and not options.quiet:
-        sys.stderr.write("Following patterns in " + optfilename + " did not match any fields: "
+        sys.stderr.write("Following patterns in " + f.optfilename + " did not match any fields: "
                          + ', '.join(unmatched) + "\n")
         if not Globals.verbose_options:
             sys.stderr.write("Use  protoc --nanopb-out=-v:.   to see a list of the field names.\n")
 
     return {'headername': headername, 'headerdata': headerdata,
             'sourcename': sourcename, 'sourcedata': sourcedata}
-    
+
 def main_cli():
     '''Main function when invoked directly from the command line.'''
-    
+
     options, filenames = optparser.parse_args()
-    
+
     if not filenames:
         optparser.print_help()
         sys.exit(1)
-    
+
     if options.quiet:
         options.verbose = False
 
+    if options.output_dir and not os.path.exists(options.output_dir):
+        optparser.print_help()
+        sys.stderr.write("\noutput_dir does not exist: %s\n" % options.output_dir)
+        sys.exit(1)
+
+    if options.verbose:
+        sys.stderr.write('Google Python protobuf library imported from %s, version %s\n'
+                         % (google.protobuf.__file__, google.protobuf.__version__))
+
     Globals.verbose_options = options.verbose
-    
     for filename in filenames:
         results = process_file(filename, None, options)
-        
+
+        base_dir = options.output_dir or ''
+        to_write = [
+            (os.path.join(base_dir, results['headername']), results['headerdata']),
+            (os.path.join(base_dir, results['sourcename']), results['sourcedata']),
+        ]
+
         if not options.quiet:
-            sys.stderr.write("Writing to " + results['headername'] + " and "
-                             + results['sourcename'] + "\n")
-    
-        open(results['headername'], 'w').write(results['headerdata'])
-        open(results['sourcename'], 'w').write(results['sourcedata'])        
+            paths = " and ".join([x[0] for x in to_write])
+            sys.stderr.write("Writing to %s\n" % paths)
+
+        for path, data in to_write:
+            with open(path, 'w') as f:
+                f.write(data)
 
 def main_plugin():
     '''Main function when invoked as a protoc plugin.'''
 
-    import sys
+    import io, sys
     if sys.platform == "win32":
         import os, msvcrt
         # Set stdin and stdout to binary mode
         msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
         msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
-    
-    data = sys.stdin.read()
+
+    data = io.open(sys.stdin.fileno(), "rb").read()
+
     request = plugin_pb2.CodeGeneratorRequest.FromString(data)
-    
+
+    try:
+        # Versions of Python prior to 2.7.3 do not support unicode
+        # input to shlex.split(). Try to convert to str if possible.
+        params = str(request.parameter)
+    except UnicodeEncodeError:
+        params = request.parameter
+
     import shlex
-    args = shlex.split(request.parameter)
+    args = shlex.split(params)
     options, dummy = optparser.parse_args(args)
-    
+
     Globals.verbose_options = options.verbose
-    
+
+    if options.verbose:
+        sys.stderr.write('Google Python protobuf library imported from %s, version %s\n'
+                         % (google.protobuf.__file__, google.protobuf.__version__))
+
     response = plugin_pb2.CodeGeneratorResponse()
-    
+
+    # Google's protoc does not currently indicate the full path of proto files.
+    # Instead always add the main file path to the search dirs, that works for
+    # the common case.
+    import os.path
+    options.options_path.append(os.path.dirname(request.file_to_generate[0]))
+
+    # Process any include files first, in order to have them
+    # available as dependencies
+    other_files = {}
+    for fdesc in request.proto_file:
+        other_files[fdesc.name] = parse_file(fdesc.name, fdesc, options)
+
     for filename in request.file_to_generate:
         for fdesc in request.proto_file:
             if fdesc.name == filename:
-                results = process_file(filename, fdesc, options)
-                
+                results = process_file(filename, fdesc, options, other_files)
+
                 f = response.file.add()
                 f.name = results['headername']
                 f.content = results['headerdata']
 
                 f = response.file.add()
                 f.name = results['sourcename']
-                f.content = results['sourcedata']    
-    
-    sys.stdout.write(response.SerializeToString())
+                f.content = results['sourcedata']
+
+    io.open(sys.stdout.fileno(), "wb").write(response.SerializeToString())
 
 if __name__ == '__main__':
     # Check if we are running as a plugin under protoc
@@ -1113,4 +1715,3 @@
         main_plugin()
     else:
         main_cli()
-
diff --git a/generator/proto/Makefile b/generator/proto/Makefile
index 032392c..89bfe52 100644
--- a/generator/proto/Makefile
+++ b/generator/proto/Makefile
@@ -1,4 +1,4 @@
 all: nanopb_pb2.py plugin_pb2.py
 
 %_pb2.py: %.proto
-	aprotoc --python_out=. $<
+	protoc --python_out=. $<
diff --git a/generator/proto/google/protobuf/descriptor.proto b/generator/proto/google/protobuf/descriptor.proto
index a785f79..8697a50 100644
--- a/generator/proto/google/protobuf/descriptor.proto
+++ b/generator/proto/google/protobuf/descriptor.proto
@@ -1,6 +1,6 @@
 // Protocol Buffers - Google's data interchange format
 // Copyright 2008 Google Inc.  All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -37,10 +37,15 @@
 // without any other information (e.g. without reading its imports).
 
 
+syntax = "proto2";
 
 package google.protobuf;
+option go_package = "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor";
 option java_package = "com.google.protobuf";
 option java_outer_classname = "DescriptorProtos";
+option csharp_namespace = "Google.Protobuf.Reflection";
+option objc_class_prefix = "GPB";
+option cc_enable_arenas = true;
 
 // descriptor.proto must be optimized for speed because reflection-based
 // algorithms don't work during bootstrapping.
@@ -74,10 +79,14 @@
   optional FileOptions options = 8;
 
   // This field contains optional information about the original source code.
-  // You may safely remove this entire field whithout harming runtime
+  // You may safely remove this entire field without harming runtime
   // functionality of the descriptors -- the information is needed only by
   // development tools.
   optional SourceCodeInfo source_code_info = 9;
+
+  // The syntax of the proto file.
+  // The supported values are "proto2" and "proto3".
+  optional string syntax = 12;
 }
 
 // Describes a message type.
@@ -93,10 +102,34 @@
   message ExtensionRange {
     optional int32 start = 1;
     optional int32 end = 2;
+
+    optional ExtensionRangeOptions options = 3;
   }
   repeated ExtensionRange extension_range = 5;
 
+  repeated OneofDescriptorProto oneof_decl = 8;
+
   optional MessageOptions options = 7;
+
+  // Range of reserved tag numbers. Reserved tag numbers may not be used by
+  // fields or extension ranges in the same message. Reserved ranges may
+  // not overlap.
+  message ReservedRange {
+    optional int32 start = 1; // Inclusive.
+    optional int32 end = 2;   // Exclusive.
+  }
+  repeated ReservedRange reserved_range = 9;
+  // Reserved field names, which may not be used by fields in the same message.
+  // A given name may only be reserved once.
+  repeated string reserved_name = 10;
+}
+
+message ExtensionRangeOptions {
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
 }
 
 // Describes a field within a message.
@@ -117,7 +150,11 @@
     TYPE_FIXED32        = 7;
     TYPE_BOOL           = 8;
     TYPE_STRING         = 9;
-    TYPE_GROUP          = 10;  // Tag-delimited aggregate.
+    // Tag-delimited aggregate.
+    // Group type is deprecated and not supported in proto3. However, Proto3
+    // implementations should still be able to parse the group wire format and
+    // treat group fields as unknown fields.
+    TYPE_GROUP          = 10;
     TYPE_MESSAGE        = 11;  // Length-delimited aggregate.
 
     // New in version 2.
@@ -135,7 +172,6 @@
     LABEL_OPTIONAL      = 1;
     LABEL_REQUIRED      = 2;
     LABEL_REPEATED      = 3;
-    // TODO(sanjay): Should we add LABEL_MAP?
   };
 
   optional string name = 1;
@@ -143,7 +179,7 @@
   optional Label label = 4;
 
   // If type_name is set, this need not be set.  If both this and type_name
-  // are set, this must be either TYPE_ENUM or TYPE_MESSAGE.
+  // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
   optional Type type = 5;
 
   // For message and enum types, this is the name of the type.  If the name
@@ -164,9 +200,25 @@
   // TODO(kenton):  Base-64 encode?
   optional string default_value = 7;
 
+  // If set, gives the index of a oneof in the containing type's oneof_decl
+  // list.  This field is a member of that oneof.
+  optional int32 oneof_index = 9;
+
+  // JSON name of this field. The value is set by protocol compiler. If the
+  // user has set a "json_name" option on this field, that option's value
+  // will be used. Otherwise, it's deduced from the field's name by converting
+  // it to camelCase.
+  optional string json_name = 10;
+
   optional FieldOptions options = 8;
 }
 
+// Describes a oneof.
+message OneofDescriptorProto {
+  optional string name = 1;
+  optional OneofOptions options = 2;
+}
+
 // Describes an enum type.
 message EnumDescriptorProto {
   optional string name = 1;
@@ -174,6 +226,26 @@
   repeated EnumValueDescriptorProto value = 2;
 
   optional EnumOptions options = 3;
+
+  // Range of reserved numeric values. Reserved values may not be used by
+  // entries in the same enum. Reserved ranges may not overlap.
+  //
+  // Note that this is distinct from DescriptorProto.ReservedRange in that it
+  // is inclusive such that it can appropriately represent the entire int32
+  // domain.
+  message EnumReservedRange {
+    optional int32 start = 1; // Inclusive.
+    optional int32 end = 2;   // Inclusive.
+  }
+
+  // Range of reserved numeric values. Reserved numeric values may not be used
+  // by enum values in the same enum declaration. Reserved ranges may not
+  // overlap.
+  repeated EnumReservedRange reserved_range = 4;
+
+  // Reserved enum value names, which may not be reused. A given name may only
+  // be reserved once.
+  repeated string reserved_name = 5;
 }
 
 // Describes a value within an enum.
@@ -202,6 +274,11 @@
   optional string output_type = 3;
 
   optional MethodOptions options = 4;
+
+  // Identifies if client streams multiple client messages
+  optional bool client_streaming = 5 [default=false];
+  // Identifies if server streams multiple server messages
+  optional bool server_streaming = 6 [default=false];
 }
 
 
@@ -228,12 +305,12 @@
 // * For options which will be published and used publicly by multiple
 //   independent entities, e-mail protobuf-global-extension-registry@google.com
 //   to reserve extension numbers. Simply provide your project name (e.g.
-//   Object-C plugin) and your porject website (if available) -- there's no need
-//   to explain how you intend to use them. Usually you only need one extension
-//   number. You can declare multiple options with only one extension number by
-//   putting them in a sub-message. See the Custom Options section of the docs
-//   for examples:
-//   http://code.google.com/apis/protocolbuffers/docs/proto.html#options
+//   Objective-C plugin) and your project website (if available) -- there's no
+//   need to explain how you intend to use them. Usually you only need one
+//   extension number. You can declare multiple options with only one extension
+//   number by putting them in a sub-message. See the Custom Options section of
+//   the docs for examples:
+//   https://developers.google.com/protocol-buffers/docs/proto#options
 //   If this turns out to be popular, a web service will be set up
 //   to automatically assign option numbers.
 
@@ -262,11 +339,17 @@
   // top-level extensions defined in the file.
   optional bool java_multiple_files = 10 [default=false];
 
-  // If set true, then the Java code generator will generate equals() and
-  // hashCode() methods for all messages defined in the .proto file. This is
-  // purely a speed optimization, as the AbstractMessage base class includes
-  // reflection-based implementations of these methods.
-  optional bool java_generate_equals_and_hash = 20 [default=false];
+  // This option does nothing.
+  optional bool java_generate_equals_and_hash = 20 [deprecated=true];
+
+  // If set true, then the Java2 code generator will generate code that
+  // throws an exception whenever an attempt is made to assign a non-UTF-8
+  // byte sequence to a string field.
+  // Message reflection will do the same.
+  // However, an extension field still accepts non-UTF-8 byte sequences.
+  // This option has no effect on when used with the lite runtime.
+  optional bool java_string_check_utf8 = 27 [default=false];
+
 
   // Generated classes can be optimized for speed or code size.
   enum OptimizeMode {
@@ -278,7 +361,10 @@
   optional OptimizeMode optimize_for = 9 [default=SPEED];
 
   // Sets the Go package where structs generated from this .proto will be
-  // placed.  There is no default.
+  // placed. If omitted, the Go package will be derived from the following:
+  //   - The basename of the package import path, if provided.
+  //   - Otherwise, the package statement in the .proto file, if present.
+  //   - Otherwise, the basename of the .proto file, without extension.
   optional string go_package = 11;
 
 
@@ -287,7 +373,7 @@
   // are not specific to any particular RPC system.  They are generated by the
   // main code generators in each language (without additional plugins).
   // Generic services were the only kind of service generation supported by
-  // early versions of proto2.
+  // early versions of google.protobuf.
   //
   // Generic services are now considered deprecated in favor of using plugins
   // that generate code specific to your particular RPC system.  Therefore,
@@ -296,12 +382,50 @@
   optional bool cc_generic_services = 16 [default=false];
   optional bool java_generic_services = 17 [default=false];
   optional bool py_generic_services = 18 [default=false];
+  optional bool php_generic_services = 42 [default=false];
 
-  // The parser stores options it doesn't recognize here. See above.
+  // Is this file deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for everything in the file, or it will be completely ignored; in the very
+  // least, this is a formalization for deprecating files.
+  optional bool deprecated = 23 [default=false];
+
+  // Enables the use of arenas for the proto messages in this file. This applies
+  // only to generated classes for C++.
+  optional bool cc_enable_arenas = 31 [default=false];
+
+
+  // Sets the objective c class prefix which is prepended to all objective c
+  // generated classes from this .proto. There is no default.
+  optional string objc_class_prefix = 36;
+
+  // Namespace for generated classes; defaults to the package.
+  optional string csharp_namespace = 37;
+
+  // By default Swift generators will take the proto package and CamelCase it
+  // replacing '.' with underscore and use that to prefix the types/symbols
+  // defined. When this options is provided, they will use this value instead
+  // to prefix the types/symbols defined.
+  optional string swift_prefix = 39;
+
+  // Sets the php class prefix which is prepended to all php generated classes
+  // from this .proto. Default is empty.
+  optional string php_class_prefix = 40;
+
+  // Use this option to change the namespace of php generated classes. Default
+  // is empty. When this option is empty, the package name will be used for
+  // determining the namespace.
+  optional string php_namespace = 41;
+
+  // The parser stores options it doesn't recognize here.
+  // See the documentation for the "Options" section above.
   repeated UninterpretedOption uninterpreted_option = 999;
 
-  // Clients can define custom options in extensions of this message. See above.
+  // Clients can define custom options in extensions of this message.
+  // See the documentation for the "Options" section above.
   extensions 1000 to max;
+
+  reserved 38;
 }
 
 message MessageOptions {
@@ -330,6 +454,38 @@
   // from proto1 easier; new code should avoid fields named "descriptor".
   optional bool no_standard_descriptor_accessor = 2 [default=false];
 
+  // Is this message deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the message, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating messages.
+  optional bool deprecated = 3 [default=false];
+
+  // Whether the message is an automatically generated map entry type for the
+  // maps field.
+  //
+  // For maps fields:
+  //     map<KeyType, ValueType> map_field = 1;
+  // The parsed descriptor looks like:
+  //     message MapFieldEntry {
+  //         option map_entry = true;
+  //         optional KeyType key = 1;
+  //         optional ValueType value = 2;
+  //     }
+  //     repeated MapFieldEntry map_field = 1;
+  //
+  // Implementations may choose not to generate the map_entry=true message, but
+  // use a native map in the target language to hold the keys and values.
+  // The reflection APIs in such implementions still need to work as
+  // if the field is a repeated message field.
+  //
+  // NOTE: Do not set the option in .proto files. Always use the maps syntax
+  // instead. The option should only be implicitly set by the proto compiler
+  // parser.
+  optional bool map_entry = 7;
+
+  reserved 8;  // javalite_serializable
+  reserved 9;  // javanano_as_lite
+
   // The parser stores options it doesn't recognize here. See above.
   repeated UninterpretedOption uninterpreted_option = 999;
 
@@ -354,10 +510,32 @@
   // The packed option can be enabled for repeated primitive fields to enable
   // a more efficient representation on the wire. Rather than repeatedly
   // writing the tag and type for each element, the entire array is encoded as
-  // a single length-delimited blob.
+  // a single length-delimited blob. In proto3, only explicit setting it to
+  // false will avoid using packed encoding.
   optional bool packed = 2;
 
+  // The jstype option determines the JavaScript type used for values of the
+  // field.  The option is permitted only for 64 bit integral and fixed types
+  // (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
+  // is represented as JavaScript string, which avoids loss of precision that
+  // can happen when a large value is converted to a floating point JavaScript.
+  // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
+  // use the JavaScript "number" type.  The behavior of the default option
+  // JS_NORMAL is implementation dependent.
+  //
+  // This option is an enum to permit additional types to be added, e.g.
+  // goog.math.Integer.
+  optional JSType jstype = 6 [default = JS_NORMAL];
+  enum JSType {
+    // Use the default type.
+    JS_NORMAL = 0;
 
+    // Use JavaScript strings.
+    JS_STRING = 1;
+
+    // Use JavaScript numbers.
+    JS_NUMBER = 2;
+  }
 
   // Should this field be parsed lazily?  Lazy applies only to message-type
   // fields.  It means that when the outer message is initially parsed, the
@@ -378,7 +556,7 @@
   //
   //
   // Note that implementations may choose not to check required fields within
-  // a lazy sub-message.  That is, calling IsInitialized() on the outher message
+  // a lazy sub-message.  That is, calling IsInitialized() on the outer message
   // may return true even if the inner message has missing required fields.
   // This is necessary because otherwise the inner message would have to be
   // parsed in order to perform the check, defeating the purpose of lazy
@@ -395,23 +573,20 @@
   // is a formalization for deprecating fields.
   optional bool deprecated = 3 [default=false];
 
-  // EXPERIMENTAL.  DO NOT USE.
-  // For "map" fields, the name of the field in the enclosed type that
-  // is the key for this map.  For example, suppose we have:
-  //   message Item {
-  //     required string name = 1;
-  //     required string value = 2;
-  //   }
-  //   message Config {
-  //     repeated Item items = 1 [experimental_map_key="name"];
-  //   }
-  // In this situation, the map key for Item will be set to "name".
-  // TODO: Fully-implement this, then remove the "experimental_" prefix.
-  optional string experimental_map_key = 9;
-
   // For Google-internal migration only. Do not use.
   optional bool weak = 10 [default=false];
 
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+
+  reserved 4;  // removed jtype
+}
+
+message OneofOptions {
   // The parser stores options it doesn't recognize here. See above.
   repeated UninterpretedOption uninterpreted_option = 999;
 
@@ -421,9 +596,17 @@
 
 message EnumOptions {
 
-  // Set this option to false to disallow mapping different tag names to a same
+  // Set this option to true to allow mapping different tag names to the same
   // value.
-  optional bool allow_alias = 2 [default=true];
+  optional bool allow_alias = 2;
+
+  // Is this enum deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the enum, or it will be completely ignored; in the very least, this
+  // is a formalization for deprecating enums.
+  optional bool deprecated = 3 [default=false];
+
+  reserved 5;  // javanano_as_lite
 
   // The parser stores options it doesn't recognize here. See above.
   repeated UninterpretedOption uninterpreted_option = 999;
@@ -433,6 +616,12 @@
 }
 
 message EnumValueOptions {
+  // Is this enum value deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the enum value, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating enum values.
+  optional bool deprecated = 1 [default=false];
+
   // The parser stores options it doesn't recognize here. See above.
   repeated UninterpretedOption uninterpreted_option = 999;
 
@@ -447,6 +636,12 @@
   //   we were already using them long before we decided to release Protocol
   //   Buffers.
 
+  // Is this service deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the service, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating services.
+  optional bool deprecated = 33 [default=false];
+
   // The parser stores options it doesn't recognize here. See above.
   repeated UninterpretedOption uninterpreted_option = 999;
 
@@ -461,6 +656,23 @@
   //   we were already using them long before we decided to release Protocol
   //   Buffers.
 
+  // Is this method deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the method, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating methods.
+  optional bool deprecated = 33 [default=false];
+
+  // Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
+  // or neither? HTTP based RPC implementation may choose GET verb for safe
+  // methods, and PUT verb for idempotent methods instead of the default POST.
+  enum IdempotencyLevel {
+    IDEMPOTENCY_UNKNOWN = 0;
+    NO_SIDE_EFFECTS     = 1; // implies idempotent
+    IDEMPOTENT          = 2; // idempotent, but may have side effects
+  }
+  optional IdempotencyLevel idempotency_level =
+      34 [default=IDEMPOTENCY_UNKNOWN];
+
   // The parser stores options it doesn't recognize here. See above.
   repeated UninterpretedOption uninterpreted_option = 999;
 
@@ -587,6 +799,11 @@
     // A series of line comments appearing on consecutive lines, with no other
     // tokens appearing on those lines, will be treated as a single comment.
     //
+    // leading_detached_comments will keep paragraphs of comments that appear
+    // before (but not connected to) the current element. Each paragraph,
+    // separated by empty lines, will be one comment element in the repeated
+    // field.
+    //
     // Only the comment content is provided; comment markers (e.g. //) are
     // stripped out.  For block comments, leading whitespace and an asterisk
     // will be stripped from the beginning of each line other than the first.
@@ -607,6 +824,12 @@
     //   // Another line attached to qux.
     //   optional double qux = 4;
     //
+    //   // Detached comment for corge. This is not leading or trailing comments
+    //   // to qux or corge because there are blank lines separating it from
+    //   // both.
+    //
+    //   // Detached comment for corge paragraph 2.
+    //
     //   optional string corge = 5;
     //   /* Block comment attached
     //    * to corge.  Leading asterisks
@@ -614,7 +837,36 @@
     //   /* Block comment attached to
     //    * grault. */
     //   optional int32 grault = 6;
+    //
+    //   // ignored detached comments.
     optional string leading_comments = 3;
     optional string trailing_comments = 4;
+    repeated string leading_detached_comments = 6;
+  }
+}
+
+// Describes the relationship between generated code and its original source
+// file. A GeneratedCodeInfo message is associated with only one generated
+// source file, but may contain references to different source .proto files.
+message GeneratedCodeInfo {
+  // An Annotation connects some span of text in generated code to an element
+  // of its generating .proto file.
+  repeated Annotation annotation = 1;
+  message Annotation {
+    // Identifies the element in the original source .proto file. This field
+    // is formatted the same as SourceCodeInfo.Location.path.
+    repeated int32 path = 1 [packed=true];
+
+    // Identifies the filesystem path to the original source .proto.
+    optional string source_file = 2;
+
+    // Identifies the starting offset in bytes in the generated code
+    // that relates to the identified object.
+    optional int32 begin = 3;
+
+    // Identifies the ending offset in bytes in the generated code that
+    // relates to the identified offset. The end offset should be one past
+    // the last relevant byte (so the length of the text = end - begin).
+    optional int32 end = 4;
   }
 }
diff --git a/generator/proto/nanopb.proto b/generator/proto/nanopb.proto
index 2be2f80..0c05a2b 100644
--- a/generator/proto/nanopb.proto
+++ b/generator/proto/nanopb.proto
@@ -5,6 +5,7 @@
 // These are used by nanopb to generate statically allocable structures
 // for memory-limited environments.
 
+syntax = "proto2";
 import "google/protobuf/descriptor.proto";
 
 option java_package = "fi.kapsi.koti.jpa.nanopb";
@@ -15,6 +16,15 @@
     FT_POINTER = 4; // Always generate a dynamically allocated field.
     FT_STATIC = 2; // Generate a static field or raise an exception if not possible.
     FT_IGNORE = 3; // Ignore the field completely.
+    FT_INLINE = 5; // Legacy option, use the separate 'fixed_length' option instead
+}
+
+enum IntSize {
+    IS_DEFAULT = 0; // Default, 32/64bit based on type in .proto
+    IS_8 = 8;
+    IS_16 = 16;
+    IS_32 = 32;
+    IS_64 = 64;
 }
 
 // This is the inner options message, which basically defines options for
@@ -22,11 +32,20 @@
 // fields.
 message NanoPBOptions {
   // Allocated size for 'bytes' and 'string' fields.
+  // For string fields, this should include the space for null terminator.
   optional int32 max_size = 1;
   
+  // Maximum length for 'string' fields. Setting this is equivalent
+  // to setting max_size to a value of length+1.
+  optional int32 max_length = 14;
+  
   // Allocated number of entries in arrays ('repeated' fields)
   optional int32 max_count = 2;
   
+  // Size of integer fields. Can save some memory if you don't need
+  // full 32 bits for the value.
+  optional IntSize int_size = 7 [default = IS_DEFAULT];
+
   // Force type of field (callback or static allocation)
   optional FieldType type = 3 [default = FT_DEFAULT];
   
@@ -37,6 +56,33 @@
   // Note: this cannot be used on CPUs that break on unaligned
   // accesses to variables.
   optional bool packed_struct = 5 [default = false];
+  
+  // Add 'packed' attribute to generated enums.
+  optional bool packed_enum = 10 [default = false];
+  
+  // Skip this message
+  optional bool skip_message = 6 [default = false];
+
+  // Generate oneof fields as normal optional fields instead of union.
+  optional bool no_unions = 8 [default = false];
+
+  // integer type tag for a message
+  optional uint32 msgid = 9;
+
+  // decode oneof as anonymous union
+  optional bool anonymous_oneof = 11 [default = false];
+
+  // Proto3 singular field does not generate a "has_" flag
+  optional bool proto3 = 12 [default = false];
+
+  // Generate an enum->string mapping function (can take up lots of space).
+  optional bool enum_to_string = 13 [default = false];
+
+  // Generate bytes arrays with fixed length
+  optional bool fixed_length = 15 [default = false];
+
+  // Generate repeated field with fixed count
+  optional bool fixed_count = 16 [default = false];
 }
 
 // Extensions to protoc 'Descriptor' type in order to define options
diff --git a/generator/proto/nanopb_pb2.py b/generator/proto/nanopb_pb2.py
index 7291eae..24215eb 100644
--- a/generator/proto/nanopb_pb2.py
+++ b/generator/proto/nanopb_pb2.py
@@ -1,59 +1,119 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: nanopb.proto
 
-from google.protobuf import descriptor
-from google.protobuf import message
-from google.protobuf import reflection
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
 from google.protobuf import descriptor_pb2
 # @@protoc_insertion_point(imports)
 
+_sym_db = _symbol_database.Default()
 
-DESCRIPTOR = descriptor.FileDescriptor(
+
+from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
   name='nanopb.proto',
   package='',
-  serialized_pb='\n\x0cnanopb.proto\x1a google/protobuf/descriptor.proto\"\x92\x01\n\rNanoPBOptions\x12\x10\n\x08max_size\x18\x01 \x01(\x05\x12\x11\n\tmax_count\x18\x02 \x01(\x05\x12$\n\x04type\x18\x03 \x01(\x0e\x32\n.FieldType:\nFT_DEFAULT\x12\x18\n\nlong_names\x18\x04 \x01(\x08:\x04true\x12\x1c\n\rpacked_struct\x18\x05 \x01(\x08:\x05\x66\x61lse*Z\n\tFieldType\x12\x0e\n\nFT_DEFAULT\x10\x00\x12\x0f\n\x0b\x46T_CALLBACK\x10\x01\x12\x0e\n\nFT_POINTER\x10\x04\x12\r\n\tFT_STATIC\x10\x02\x12\r\n\tFT_IGNORE\x10\x03:E\n\x0enanopb_fileopt\x12\x1c.google.protobuf.FileOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:G\n\rnanopb_msgopt\x12\x1f.google.protobuf.MessageOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:E\n\x0enanopb_enumopt\x12\x1c.google.protobuf.EnumOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:>\n\x06nanopb\x12\x1d.google.protobuf.FieldOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptionsB\x1a\n\x18\x66i.kapsi.koti.jpa.nanopb')
+  syntax='proto2',
+  serialized_pb=_b('\n\x0cnanopb.proto\x1a google/protobuf/descriptor.proto\"\xbf\x03\n\rNanoPBOptions\x12\x10\n\x08max_size\x18\x01 \x01(\x05\x12\x12\n\nmax_length\x18\x0e \x01(\x05\x12\x11\n\tmax_count\x18\x02 \x01(\x05\x12&\n\x08int_size\x18\x07 \x01(\x0e\x32\x08.IntSize:\nIS_DEFAULT\x12$\n\x04type\x18\x03 \x01(\x0e\x32\n.FieldType:\nFT_DEFAULT\x12\x18\n\nlong_names\x18\x04 \x01(\x08:\x04true\x12\x1c\n\rpacked_struct\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0bpacked_enum\x18\n \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0cskip_message\x18\x06 \x01(\x08:\x05\x66\x61lse\x12\x18\n\tno_unions\x18\x08 \x01(\x08:\x05\x66\x61lse\x12\r\n\x05msgid\x18\t \x01(\r\x12\x1e\n\x0f\x61nonymous_oneof\x18\x0b \x01(\x08:\x05\x66\x61lse\x12\x15\n\x06proto3\x18\x0c \x01(\x08:\x05\x66\x61lse\x12\x1d\n\x0e\x65num_to_string\x18\r \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0c\x66ixed_length\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0b\x66ixed_count\x18\x10 \x01(\x08:\x05\x66\x61lse*i\n\tFieldType\x12\x0e\n\nFT_DEFAULT\x10\x00\x12\x0f\n\x0b\x46T_CALLBACK\x10\x01\x12\x0e\n\nFT_POINTER\x10\x04\x12\r\n\tFT_STATIC\x10\x02\x12\r\n\tFT_IGNORE\x10\x03\x12\r\n\tFT_INLINE\x10\x05*D\n\x07IntSize\x12\x0e\n\nIS_DEFAULT\x10\x00\x12\x08\n\x04IS_8\x10\x08\x12\t\n\x05IS_16\x10\x10\x12\t\n\x05IS_32\x10 \x12\t\n\x05IS_64\x10@:E\n\x0enanopb_fileopt\x12\x1c.google.protobuf.FileOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:G\n\rnanopb_msgopt\x12\x1f.google.protobuf.MessageOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:E\n\x0enanopb_enumopt\x12\x1c.google.protobuf.EnumOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:>\n\x06nanopb\x12\x1d.google.protobuf.FieldOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptionsB\x1a\n\x18\x66i.kapsi.koti.jpa.nanopb')
+  ,
+  dependencies=[google_dot_protobuf_dot_descriptor__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
-_FIELDTYPE = descriptor.EnumDescriptor(
+_FIELDTYPE = _descriptor.EnumDescriptor(
   name='FieldType',
   full_name='FieldType',
   filename=None,
   file=DESCRIPTOR,
   values=[
-    descriptor.EnumValueDescriptor(
+    _descriptor.EnumValueDescriptor(
       name='FT_DEFAULT', index=0, number=0,
       options=None,
       type=None),
-    descriptor.EnumValueDescriptor(
+    _descriptor.EnumValueDescriptor(
       name='FT_CALLBACK', index=1, number=1,
       options=None,
       type=None),
-    descriptor.EnumValueDescriptor(
+    _descriptor.EnumValueDescriptor(
       name='FT_POINTER', index=2, number=4,
       options=None,
       type=None),
-    descriptor.EnumValueDescriptor(
+    _descriptor.EnumValueDescriptor(
       name='FT_STATIC', index=3, number=2,
       options=None,
       type=None),
-    descriptor.EnumValueDescriptor(
+    _descriptor.EnumValueDescriptor(
       name='FT_IGNORE', index=4, number=3,
       options=None,
       type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FT_INLINE', index=5, number=5,
+      options=None,
+      type=None),
   ],
   containing_type=None,
   options=None,
-  serialized_start=199,
-  serialized_end=289,
+  serialized_start=500,
+  serialized_end=605,
 )
+_sym_db.RegisterEnumDescriptor(_FIELDTYPE)
 
+FieldType = enum_type_wrapper.EnumTypeWrapper(_FIELDTYPE)
+_INTSIZE = _descriptor.EnumDescriptor(
+  name='IntSize',
+  full_name='IntSize',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='IS_DEFAULT', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='IS_8', index=1, number=8,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='IS_16', index=2, number=16,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='IS_32', index=3, number=32,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='IS_64', index=4, number=64,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=607,
+  serialized_end=675,
+)
+_sym_db.RegisterEnumDescriptor(_INTSIZE)
 
+IntSize = enum_type_wrapper.EnumTypeWrapper(_INTSIZE)
 FT_DEFAULT = 0
 FT_CALLBACK = 1
 FT_POINTER = 4
 FT_STATIC = 2
 FT_IGNORE = 3
+FT_INLINE = 5
+IS_DEFAULT = 0
+IS_8 = 8
+IS_16 = 16
+IS_32 = 32
+IS_64 = 64
 
 NANOPB_FILEOPT_FIELD_NUMBER = 1010
-nanopb_fileopt = descriptor.FieldDescriptor(
+nanopb_fileopt = _descriptor.FieldDescriptor(
   name='nanopb_fileopt', full_name='nanopb_fileopt', index=0,
   number=1010, type=11, cpp_type=10, label=1,
   has_default_value=False, default_value=None,
@@ -61,7 +121,7 @@
   is_extension=True, extension_scope=None,
   options=None)
 NANOPB_MSGOPT_FIELD_NUMBER = 1010
-nanopb_msgopt = descriptor.FieldDescriptor(
+nanopb_msgopt = _descriptor.FieldDescriptor(
   name='nanopb_msgopt', full_name='nanopb_msgopt', index=1,
   number=1010, type=11, cpp_type=10, label=1,
   has_default_value=False, default_value=None,
@@ -69,7 +129,7 @@
   is_extension=True, extension_scope=None,
   options=None)
 NANOPB_ENUMOPT_FIELD_NUMBER = 1010
-nanopb_enumopt = descriptor.FieldDescriptor(
+nanopb_enumopt = _descriptor.FieldDescriptor(
   name='nanopb_enumopt', full_name='nanopb_enumopt', index=2,
   number=1010, type=11, cpp_type=10, label=1,
   has_default_value=False, default_value=None,
@@ -77,7 +137,7 @@
   is_extension=True, extension_scope=None,
   options=None)
 NANOPB_FIELD_NUMBER = 1010
-nanopb = descriptor.FieldDescriptor(
+nanopb = _descriptor.FieldDescriptor(
   name='nanopb', full_name='nanopb', index=3,
   number=1010, type=11, cpp_type=10, label=1,
   has_default_value=False, default_value=None,
@@ -86,48 +146,125 @@
   options=None)
 
 
-_NANOPBOPTIONS = descriptor.Descriptor(
+_NANOPBOPTIONS = _descriptor.Descriptor(
   name='NanoPBOptions',
   full_name='NanoPBOptions',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   fields=[
-    descriptor.FieldDescriptor(
+    _descriptor.FieldDescriptor(
       name='max_size', full_name='NanoPBOptions.max_size', index=0,
       number=1, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
-    descriptor.FieldDescriptor(
-      name='max_count', full_name='NanoPBOptions.max_count', index=1,
+    _descriptor.FieldDescriptor(
+      name='max_length', full_name='NanoPBOptions.max_length', index=1,
+      number=14, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='max_count', full_name='NanoPBOptions.max_count', index=2,
       number=2, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
-    descriptor.FieldDescriptor(
-      name='type', full_name='NanoPBOptions.type', index=2,
+    _descriptor.FieldDescriptor(
+      name='int_size', full_name='NanoPBOptions.int_size', index=3,
+      number=7, type=14, cpp_type=8, label=1,
+      has_default_value=True, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='type', full_name='NanoPBOptions.type', index=4,
       number=3, type=14, cpp_type=8, label=1,
       has_default_value=True, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
-    descriptor.FieldDescriptor(
-      name='long_names', full_name='NanoPBOptions.long_names', index=3,
+    _descriptor.FieldDescriptor(
+      name='long_names', full_name='NanoPBOptions.long_names', index=5,
       number=4, type=8, cpp_type=7, label=1,
       has_default_value=True, default_value=True,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
-    descriptor.FieldDescriptor(
-      name='packed_struct', full_name='NanoPBOptions.packed_struct', index=4,
+    _descriptor.FieldDescriptor(
+      name='packed_struct', full_name='NanoPBOptions.packed_struct', index=6,
       number=5, type=8, cpp_type=7, label=1,
       has_default_value=True, default_value=False,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
+    _descriptor.FieldDescriptor(
+      name='packed_enum', full_name='NanoPBOptions.packed_enum', index=7,
+      number=10, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='skip_message', full_name='NanoPBOptions.skip_message', index=8,
+      number=6, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='no_unions', full_name='NanoPBOptions.no_unions', index=9,
+      number=8, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='msgid', full_name='NanoPBOptions.msgid', index=10,
+      number=9, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='anonymous_oneof', full_name='NanoPBOptions.anonymous_oneof', index=11,
+      number=11, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='proto3', full_name='NanoPBOptions.proto3', index=12,
+      number=12, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='enum_to_string', full_name='NanoPBOptions.enum_to_string', index=13,
+      number=13, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='fixed_length', full_name='NanoPBOptions.fixed_length', index=14,
+      number=15, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='fixed_count', full_name='NanoPBOptions.fixed_count', index=15,
+      number=16, type=8, cpp_type=7, label=1,
+      has_default_value=True, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
   ],
   extensions=[
   ],
@@ -136,27 +273,40 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
+  oneofs=[
+  ],
   serialized_start=51,
-  serialized_end=197,
+  serialized_end=498,
 )
 
-import google.protobuf.descriptor_pb2
-
+_NANOPBOPTIONS.fields_by_name['int_size'].enum_type = _INTSIZE
 _NANOPBOPTIONS.fields_by_name['type'].enum_type = _FIELDTYPE
+DESCRIPTOR.message_types_by_name['NanoPBOptions'] = _NANOPBOPTIONS
+DESCRIPTOR.enum_types_by_name['FieldType'] = _FIELDTYPE
+DESCRIPTOR.enum_types_by_name['IntSize'] = _INTSIZE
+DESCRIPTOR.extensions_by_name['nanopb_fileopt'] = nanopb_fileopt
+DESCRIPTOR.extensions_by_name['nanopb_msgopt'] = nanopb_msgopt
+DESCRIPTOR.extensions_by_name['nanopb_enumopt'] = nanopb_enumopt
+DESCRIPTOR.extensions_by_name['nanopb'] = nanopb
 
-class NanoPBOptions(message.Message):
-  __metaclass__ = reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _NANOPBOPTIONS
-  
+NanoPBOptions = _reflection.GeneratedProtocolMessageType('NanoPBOptions', (_message.Message,), dict(
+  DESCRIPTOR = _NANOPBOPTIONS,
+  __module__ = 'nanopb_pb2'
   # @@protoc_insertion_point(class_scope:NanoPBOptions)
+  ))
+_sym_db.RegisterMessage(NanoPBOptions)
 
 nanopb_fileopt.message_type = _NANOPBOPTIONS
-google.protobuf.descriptor_pb2.FileOptions.RegisterExtension(nanopb_fileopt)
+google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(nanopb_fileopt)
 nanopb_msgopt.message_type = _NANOPBOPTIONS
-google.protobuf.descriptor_pb2.MessageOptions.RegisterExtension(nanopb_msgopt)
+google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(nanopb_msgopt)
 nanopb_enumopt.message_type = _NANOPBOPTIONS
-google.protobuf.descriptor_pb2.EnumOptions.RegisterExtension(nanopb_enumopt)
+google_dot_protobuf_dot_descriptor__pb2.EnumOptions.RegisterExtension(nanopb_enumopt)
 nanopb.message_type = _NANOPBOPTIONS
-google.protobuf.descriptor_pb2.FieldOptions.RegisterExtension(nanopb)
+google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(nanopb)
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\030fi.kapsi.koti.jpa.nanopb'))
 # @@protoc_insertion_point(module_scope)
diff --git a/generator/proto/plugin.proto b/generator/proto/plugin.proto
index 651ed10..e627289 100644
--- a/generator/proto/plugin.proto
+++ b/generator/proto/plugin.proto
@@ -1,6 +1,6 @@
 // Protocol Buffers - Google's data interchange format
 // Copyright 2008 Google Inc.  All rights reserved.
-// http://code.google.com/p/protobuf/
+// 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
@@ -44,7 +44,10 @@
 // plugin should be named "protoc-gen-$NAME", and will then be used when the
 // flag "--${NAME}_out" is passed to protoc.
 
+syntax = "proto2";
 package google.protobuf.compiler;
+option java_package = "com.google.protobuf.compiler";
+option java_outer_classname = "PluginProtos";
 
 import "google/protobuf/descriptor.proto";
 
diff --git a/generator/proto/plugin_pb2.py b/generator/proto/plugin_pb2.py
index a0a6bb7..b046775 100644
--- a/generator/proto/plugin_pb2.py
+++ b/generator/proto/plugin_pb2.py
@@ -1,42 +1,55 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: plugin.proto
 
-from google.protobuf import descriptor
-from google.protobuf import message
-from google.protobuf import reflection
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
 from google.protobuf import descriptor_pb2
 # @@protoc_insertion_point(imports)
 
+_sym_db = _symbol_database.Default()
 
-DESCRIPTOR = descriptor.FileDescriptor(
+
+from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
   name='plugin.proto',
   package='google.protobuf.compiler',
-  serialized_pb='\n\x0cplugin.proto\x12\x18google.protobuf.compiler\x1a google/protobuf/descriptor.proto\"}\n\x14\x43odeGeneratorRequest\x12\x18\n\x10\x66ile_to_generate\x18\x01 \x03(\t\x12\x11\n\tparameter\x18\x02 \x01(\t\x12\x38\n\nproto_file\x18\x0f \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xaa\x01\n\x15\x43odeGeneratorResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x12\x42\n\x04\x66ile\x18\x0f \x03(\x0b\x32\x34.google.protobuf.compiler.CodeGeneratorResponse.File\x1a>\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0finsertion_point\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x0f \x01(\t')
+  syntax='proto2',
+  serialized_pb=_b('\n\x0cplugin.proto\x12\x18google.protobuf.compiler\x1a google/protobuf/descriptor.proto\"}\n\x14\x43odeGeneratorRequest\x12\x18\n\x10\x66ile_to_generate\x18\x01 \x03(\t\x12\x11\n\tparameter\x18\x02 \x01(\t\x12\x38\n\nproto_file\x18\x0f \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xaa\x01\n\x15\x43odeGeneratorResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x12\x42\n\x04\x66ile\x18\x0f \x03(\x0b\x32\x34.google.protobuf.compiler.CodeGeneratorResponse.File\x1a>\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0finsertion_point\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x0f \x01(\tB,\n\x1c\x63om.google.protobuf.compilerB\x0cPluginProtos')
+  ,
+  dependencies=[google_dot_protobuf_dot_descriptor__pb2.DESCRIPTOR,])
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
 
 
 
-_CODEGENERATORREQUEST = descriptor.Descriptor(
+_CODEGENERATORREQUEST = _descriptor.Descriptor(
   name='CodeGeneratorRequest',
   full_name='google.protobuf.compiler.CodeGeneratorRequest',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   fields=[
-    descriptor.FieldDescriptor(
+    _descriptor.FieldDescriptor(
       name='file_to_generate', full_name='google.protobuf.compiler.CodeGeneratorRequest.file_to_generate', index=0,
       number=1, type=9, cpp_type=9, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
-    descriptor.FieldDescriptor(
+    _descriptor.FieldDescriptor(
       name='parameter', full_name='google.protobuf.compiler.CodeGeneratorRequest.parameter', index=1,
       number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
-    descriptor.FieldDescriptor(
+    _descriptor.FieldDescriptor(
       name='proto_file', full_name='google.protobuf.compiler.CodeGeneratorRequest.proto_file', index=2,
       number=15, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
@@ -51,37 +64,40 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
+  oneofs=[
+  ],
   serialized_start=76,
   serialized_end=201,
 )
 
 
-_CODEGENERATORRESPONSE_FILE = descriptor.Descriptor(
+_CODEGENERATORRESPONSE_FILE = _descriptor.Descriptor(
   name='File',
   full_name='google.protobuf.compiler.CodeGeneratorResponse.File',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   fields=[
-    descriptor.FieldDescriptor(
+    _descriptor.FieldDescriptor(
       name='name', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.name', index=0,
       number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
-    descriptor.FieldDescriptor(
+    _descriptor.FieldDescriptor(
       name='insertion_point', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point', index=1,
       number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
-    descriptor.FieldDescriptor(
+    _descriptor.FieldDescriptor(
       name='content', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.content', index=2,
       number=15, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -93,26 +109,29 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
+  oneofs=[
+  ],
   serialized_start=312,
   serialized_end=374,
 )
 
-_CODEGENERATORRESPONSE = descriptor.Descriptor(
+_CODEGENERATORRESPONSE = _descriptor.Descriptor(
   name='CodeGeneratorResponse',
   full_name='google.protobuf.compiler.CodeGeneratorResponse',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   fields=[
-    descriptor.FieldDescriptor(
+    _descriptor.FieldDescriptor(
       name='error', full_name='google.protobuf.compiler.CodeGeneratorResponse.error', index=0,
       number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=unicode("", "utf-8"),
+      has_default_value=False, default_value=_b("").decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
-    descriptor.FieldDescriptor(
+    _descriptor.FieldDescriptor(
       name='file', full_name='google.protobuf.compiler.CodeGeneratorResponse.file', index=1,
       number=15, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
@@ -127,33 +146,43 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto2',
   extension_ranges=[],
+  oneofs=[
+  ],
   serialized_start=204,
   serialized_end=374,
 )
 
-import google.protobuf.descriptor_pb2
-
-_CODEGENERATORREQUEST.fields_by_name['proto_file'].message_type = google.protobuf.descriptor_pb2._FILEDESCRIPTORPROTO
-_CODEGENERATORRESPONSE_FILE.containing_type = _CODEGENERATORRESPONSE;
+_CODEGENERATORREQUEST.fields_by_name['proto_file'].message_type = google_dot_protobuf_dot_descriptor__pb2._FILEDESCRIPTORPROTO
+_CODEGENERATORRESPONSE_FILE.containing_type = _CODEGENERATORRESPONSE
 _CODEGENERATORRESPONSE.fields_by_name['file'].message_type = _CODEGENERATORRESPONSE_FILE
+DESCRIPTOR.message_types_by_name['CodeGeneratorRequest'] = _CODEGENERATORREQUEST
+DESCRIPTOR.message_types_by_name['CodeGeneratorResponse'] = _CODEGENERATORRESPONSE
 
-class CodeGeneratorRequest(message.Message):
-  __metaclass__ = reflection.GeneratedProtocolMessageType
-  DESCRIPTOR = _CODEGENERATORREQUEST
-  
+CodeGeneratorRequest = _reflection.GeneratedProtocolMessageType('CodeGeneratorRequest', (_message.Message,), dict(
+  DESCRIPTOR = _CODEGENERATORREQUEST,
+  __module__ = 'plugin_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
+  ))
+_sym_db.RegisterMessage(CodeGeneratorRequest)
 
-class CodeGeneratorResponse(message.Message):
-  __metaclass__ = reflection.GeneratedProtocolMessageType
-  
-  class File(message.Message):
-    __metaclass__ = reflection.GeneratedProtocolMessageType
-    DESCRIPTOR = _CODEGENERATORRESPONSE_FILE
-    
+CodeGeneratorResponse = _reflection.GeneratedProtocolMessageType('CodeGeneratorResponse', (_message.Message,), dict(
+
+  File = _reflection.GeneratedProtocolMessageType('File', (_message.Message,), dict(
+    DESCRIPTOR = _CODEGENERATORRESPONSE_FILE,
+    __module__ = 'plugin_pb2'
     # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
-  DESCRIPTOR = _CODEGENERATORRESPONSE
-  
+    ))
+  ,
+  DESCRIPTOR = _CODEGENERATORRESPONSE,
+  __module__ = 'plugin_pb2'
   # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
+  ))
+_sym_db.RegisterMessage(CodeGeneratorResponse)
+_sym_db.RegisterMessage(CodeGeneratorResponse.File)
 
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\034com.google.protobuf.compilerB\014PluginProtos'))
 # @@protoc_insertion_point(module_scope)
diff --git a/generator/protoc-gen-nanopb b/generator/protoc-gen-nanopb
index 2de5621..471a620 100755
--- a/generator/protoc-gen-nanopb
+++ b/generator/protoc-gen-nanopb
@@ -3,11 +3,11 @@
 # This file is used to invoke nanopb_generator.py as a plugin
 # to protoc on Linux and other *nix-style systems.
 # Use it like this:
-# protoc --plugin=nanopb=..../protoc-gen-nanopb --nanopb_out=dir foo.proto
+# protoc --plugin=protoc-gen-nanopb=..../protoc-gen-nanopb --nanopb_out=dir foo.proto
 #
 # Note that if you use the binary package of nanopb, the protoc
 # path is already set up properly and there is no need to give
 # --plugin= on the command line.
 
 MYPATH=$(dirname "$0")
-exec python "$MYPATH/nanopb_generator.py" --protoc-plugin
+exec "$MYPATH/nanopb_generator.py" --protoc-plugin
diff --git a/generator/protoc-gen-nanopb.bat b/generator/protoc-gen-nanopb.bat
index 7624984..e6cf187 100644
--- a/generator/protoc-gen-nanopb.bat
+++ b/generator/protoc-gen-nanopb.bat
@@ -2,7 +2,7 @@
 :: This file is used to invoke nanopb_generator.py as a plugin
 :: to protoc on Windows.
 :: Use it like this:
-:: protoc --plugin=nanopb=..../protoc-gen-nanopb.bat --nanopb_out=dir foo.proto
+:: protoc --plugin=protoc-gen-nanopb=..../protoc-gen-nanopb.bat --nanopb_out=dir foo.proto
 ::
 :: Note that if you use the binary package of nanopb, the protoc
 :: path is already set up properly and there is no need to give
diff --git a/library.json b/library.json
new file mode 100644
index 0000000..b070e54
--- /dev/null
+++ b/library.json
@@ -0,0 +1,26 @@
+{
+  "name": "Nanopb",
+  "version": "0.3.9.1",
+  "keywords": "protocol buffers, protobuf, google",
+  "description": "Nanopb is a plain-C implementation of Google's Protocol Buffers data format. It is targeted at 32 bit microcontrollers, but is also fit for other embedded systems with tight (2-10 kB ROM, <1 kB RAM) memory constraints.",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/nanopb/nanopb.git"
+  },
+  "authors": [{
+    "name": "Petteri Aimonen",
+    "email": "jpa@nanopb.mail.kapsi.fi",
+    "url": "http://koti.kapsi.fi/jpa/nanopb/"
+  }],
+  "export": {
+    "include": [
+      "*.c",
+      "*.cpp",
+      "*.h",
+      "examples"
+    ]
+  },
+  "examples": "examples/*/*.c",
+  "frameworks": "*",
+  "platforms": "*"
+}
diff --git a/pb.h b/pb.h
index fe6fb5b..174a84b 100644
--- a/pb.h
+++ b/pb.h
@@ -2,8 +2,8 @@
  * stuff. For the high-level interface, see pb_encode.h and pb_decode.h.
  */
 
-#ifndef _PB_H_
-#define _PB_H_
+#ifndef PB_H_INCLUDED
+#define PB_H_INCLUDED
 
 /*****************************************************************
  * Nanopb compilation time options. You can change these here by *
@@ -13,9 +13,9 @@
 /* Enable support for dynamically allocated fields */
 /* #define PB_ENABLE_MALLOC 1 */
 
-/* Define this if your CPU architecture is big endian, i.e. it
- * stores the most-significant byte first. */
-/* #define __BIG_ENDIAN__ 1 */
+/* Define this if your CPU / compiler combination does not support
+ * unaligned memory access to packed structures. */
+/* #define PB_NO_PACKED_STRUCTS 1 */
 
 /* Increase the number of required fields that are tracked.
  * A compiler warning will tell if you need this. */
@@ -46,12 +46,12 @@
 
 /* Version of the nanopb library. Just in case you want to check it in
  * your own program. */
-#define NANOPB_VERSION nanopb-0.2.8-dev
+#define NANOPB_VERSION nanopb-0.3.9.1
 
 /* Include all the system headers needed by nanopb. You will need the
  * definitions of the following:
  * - strlen, memcpy, memset functions
- * - [u]int8_t, [u]int16_t, [u]int32_t, [u]int64_t
+ * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t
  * - size_t
  * - bool
  *
@@ -75,13 +75,18 @@
 /* Macro for defining packed structures (compiler dependent).
  * This just reduces memory requirements, but is not required.
  */
-#if defined(__GNUC__) || defined(__clang__)
+#if defined(PB_NO_PACKED_STRUCTS)
+    /* Disable struct packing */
+#   define PB_PACKED_STRUCT_START
+#   define PB_PACKED_STRUCT_END
+#   define pb_packed
+#elif defined(__GNUC__) || defined(__clang__)
     /* For GCC and clang */
 #   define PB_PACKED_STRUCT_START
 #   define PB_PACKED_STRUCT_END
 #   define pb_packed __attribute__((packed))
-#elif defined(__ICCARM__)
-    /* For IAR ARM compiler */
+#elif defined(__ICCARM__) || defined(__CC_ARM)
+    /* For IAR ARM and Keil MDK-ARM compilers */
 #   define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)")
 #   define PB_PACKED_STRUCT_END _Pragma("pack(pop)")
 #   define pb_packed
@@ -98,23 +103,27 @@
 #endif
 
 /* Handly macro for suppressing unreferenced-parameter compiler warnings. */
-#ifndef UNUSED
-#define UNUSED(x) (void)(x)
+#ifndef PB_UNUSED
+#define PB_UNUSED(x) (void)(x)
 #endif
 
 /* Compile-time assertion, used for checking compatible compilation options.
- * If this does not work properly on your compiler, use #define STATIC_ASSERT
- * to disable it.
+ * If this does not work properly on your compiler, use
+ * #define PB_NO_STATIC_ASSERT to disable it.
  *
  * But before doing that, check carefully the error message / place where it
  * comes from to see if the error has a real cause. Unfortunately the error
  * message is not always very clear to read, but you can see the reason better
- * in the place where the STATIC_ASSERT macro was called.
+ * in the place where the PB_STATIC_ASSERT macro was called.
  */
-#ifndef STATIC_ASSERT
-#define STATIC_ASSERT(COND,MSG) typedef char STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1];
-#define STATIC_ASSERT_MSG(MSG, LINE, COUNTER) STATIC_ASSERT_MSG_(MSG, LINE, COUNTER)
-#define STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) static_assertion_##MSG##LINE##COUNTER
+#ifndef PB_NO_STATIC_ASSERT
+#ifndef PB_STATIC_ASSERT
+#define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1];
+#define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER)
+#define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##LINE##COUNTER
+#endif
+#else
+#define PB_STATIC_ASSERT(COND,MSG)
 #endif
 
 /* Number of required fields to keep track of. */
@@ -131,7 +140,7 @@
  * Most-significant 4 bits specify repeated/required/packed etc.
  */
 
-typedef uint8_t pb_type_t;
+typedef uint_least8_t pb_type_t;
 
 /**** Field data types ****/
 
@@ -161,8 +170,14 @@
  * The field contains a pointer to pb_extension_t */
 #define PB_LTYPE_EXTENSION 0x08
 
+/* Byte array with inline, pre-allocated byffer.
+ * data_size is the length of the inline, allocated buffer.
+ * This differs from PB_LTYPE_BYTES by defining the element as
+ * pb_byte_t[data_size] rather than pb_bytes_array_t. */
+#define PB_LTYPE_FIXED_LENGTH_BYTES 0x09
+
 /* Number of declared LTYPES */
-#define PB_LTYPES_COUNT 9
+#define PB_LTYPES_COUNT 0x0A
 #define PB_LTYPE_MASK 0x0F
 
 /**** Field repetition rules ****/
@@ -170,6 +185,7 @@
 #define PB_HTYPE_REQUIRED 0x00
 #define PB_HTYPE_OPTIONAL 0x10
 #define PB_HTYPE_REPEATED 0x20
+#define PB_HTYPE_ONEOF    0x30
 #define PB_HTYPE_MASK     0x30
 
 /**** Field allocation types ****/
@@ -190,12 +206,19 @@
     typedef uint32_t pb_size_t;
     typedef int32_t pb_ssize_t;
 #elif defined(PB_FIELD_16BIT)
-    typedef uint16_t pb_size_t;
-    typedef int16_t pb_ssize_t;
+    typedef uint_least16_t pb_size_t;
+    typedef int_least16_t pb_ssize_t;
 #else
-    typedef uint8_t pb_size_t;
-    typedef int8_t pb_ssize_t;
+    typedef uint_least8_t pb_size_t;
+    typedef int_least8_t pb_ssize_t;
 #endif
+#define PB_SIZE_MAX ((pb_size_t)-1)
+
+/* Data type for storing encoded data and other byte streams.
+ * This typedef exists to support platforms where uint8_t does not exist.
+ * You can regard it as equivalent on uint8_t on other platforms.
+ */
+typedef uint_least8_t pb_byte_t;
 
 /* This structure is used in auto-generated constants
  * to specify struct fields.
@@ -206,8 +229,8 @@
  * PB_FIELD_32BIT.
  */
 PB_PACKED_STRUCT_START
-typedef struct _pb_field_t pb_field_t;
-struct _pb_field_t {
+typedef struct pb_field_s pb_field_t;
+struct pb_field_s {
     pb_size_t tag;
     pb_type_t type;
     pb_size_t data_offset; /* Offset of field data, relative to previous field. */
@@ -223,32 +246,28 @@
 PB_PACKED_STRUCT_END
 
 /* Make sure that the standard integer types are of the expected sizes.
- * All kinds of things may break otherwise.. atleast all fixed* types.
+ * Otherwise fixed32/fixed64 fields can break.
  *
  * If you get errors here, it probably means that your stdint.h is not
  * correct for your platform.
  */
-STATIC_ASSERT(sizeof(int8_t) == 1, INT8_T_WRONG_SIZE)
-STATIC_ASSERT(sizeof(uint8_t) == 1, UINT8_T_WRONG_SIZE)
-STATIC_ASSERT(sizeof(int16_t) == 2, INT16_T_WRONG_SIZE)
-STATIC_ASSERT(sizeof(uint16_t) == 2, UINT16_T_WRONG_SIZE)
-STATIC_ASSERT(sizeof(int32_t) == 4, INT32_T_WRONG_SIZE)
-STATIC_ASSERT(sizeof(uint32_t) == 4, UINT32_T_WRONG_SIZE)
-STATIC_ASSERT(sizeof(int64_t) == 8, INT64_T_WRONG_SIZE)
-STATIC_ASSERT(sizeof(uint64_t) == 8, UINT64_T_WRONG_SIZE)
+#ifndef PB_WITHOUT_64BIT
+PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE)
+PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE)
+#endif
 
 /* This structure is used for 'bytes' arrays.
  * It has the number of bytes in the beginning, and after that an array.
  * Note that actual structs used will have a different length of bytes array.
  */
-#define PB_BYTES_ARRAY_T(n) struct { size_t size; uint8_t bytes[n]; }
+#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; }
 #define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes))
 
-struct _pb_bytes_array_t {
-    size_t size;
-    uint8_t bytes[1];
+struct pb_bytes_array_s {
+    pb_size_t size;
+    pb_byte_t bytes[1];
 };
-typedef struct _pb_bytes_array_t pb_bytes_array_t;
+typedef struct pb_bytes_array_s pb_bytes_array_t;
 
 /* This structure is used for giving the callback function.
  * It is stored in the message structure and filled in by the method that
@@ -268,10 +287,10 @@
  *
  * The callback can be null if you want to skip a field.
  */
-typedef struct _pb_istream_t pb_istream_t;
-typedef struct _pb_ostream_t pb_ostream_t;
-typedef struct _pb_callback_t pb_callback_t;
-struct _pb_callback_t {
+typedef struct pb_istream_s pb_istream_t;
+typedef struct pb_ostream_s pb_ostream_t;
+typedef struct pb_callback_s pb_callback_t;
+struct pb_callback_s {
 #ifdef PB_OLD_CALLBACK_STYLE
     /* Deprecated since nanopb-0.2.1 */
     union {
@@ -304,9 +323,9 @@
  * if you want to catch all unknown fields, you can also create a custom
  * pb_extension_type_t with your own callback.
  */
-typedef struct _pb_extension_type_t pb_extension_type_t;
-typedef struct _pb_extension_t pb_extension_t;
-struct _pb_extension_type_t {
+typedef struct pb_extension_type_s pb_extension_type_t;
+typedef struct pb_extension_s pb_extension_t;
+struct pb_extension_type_s {
     /* Called for each unknown field in the message.
      * If you handle the field, read off all of its data and return true.
      * If you do not handle the field, do not read anything and return true.
@@ -328,7 +347,7 @@
     const void *arg;
 };
 
-struct _pb_extension_t {
+struct pb_extension_s {
     /* Type describing the extension field. Usually you'll initialize
      * this to a pointer to the automatically generated structure. */
     const pb_extension_type_t *type;
@@ -358,6 +377,9 @@
 #   endif
 #endif
 
+/* This is used to inform about need to regenerate .pb.h/.pb.c files. */
+#define PB_PROTO_HEADER_VERSION 30
+
 /* These macros are used to declare pb_field_t's in the constant array. */
 /* Size of a structure member, in bytes. */
 #define pb_membersize(st, m) (sizeof ((st*)0)->m)
@@ -373,6 +395,8 @@
 #define PB_DATAOFFSET_FIRST(st, m1, m2) (offsetof(st, m1))
 /* data_offset for subsequent fields */
 #define PB_DATAOFFSET_OTHER(st, m1, m2) (offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2))
+/* data offset for subsequent fields inside an union (oneof) */
+#define PB_DATAOFFSET_UNION(st, m1, m2) (PB_SIZE_MAX)
 /* Choose first/other based on m1 == m2 (deprecated, remains for backwards compatibility) */
 #define PB_DATAOFFSET_CHOOSE(st, m1, m2) (int)(offsetof(st, m1) == offsetof(st, m2) \
                                   ? PB_DATAOFFSET_FIRST(st, m1, m2) \
@@ -393,6 +417,10 @@
     pb_delta(st, has_ ## m, m), \
     pb_membersize(st, m), 0, ptr}
 
+#define PB_SINGULAR_STATIC(tag, st, m, fd, ltype, ptr) \
+    {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \
+    fd, 0, pb_membersize(st, m), 0, ptr}
+
 /* Repeated fields have a _count field and also the maximum number of entries. */
 #define PB_REPEATED_STATIC(tag, st, m, fd, ltype, ptr) \
     {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | ltype, \
@@ -411,6 +439,11 @@
     {tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \
     fd, 0, pb_membersize(st, m[0]), 0, ptr}
 
+/* Same as optional fields*/
+#define PB_SINGULAR_POINTER(tag, st, m, fd, ltype, ptr) \
+    {tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \
+    fd, 0, pb_membersize(st, m[0]), 0, ptr}
+
 /* Repeated fields have a _count field and a pointer to array of pointers */
 #define PB_REPEATED_POINTER(tag, st, m, fd, ltype, ptr) \
     {tag, PB_ATYPE_POINTER | PB_HTYPE_REPEATED | ltype, \
@@ -425,95 +458,136 @@
 #define PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) \
     {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \
     fd, 0, pb_membersize(st, m), 0, ptr}
+
+#define PB_SINGULAR_CALLBACK(tag, st, m, fd, ltype, ptr) \
+    {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \
+    fd, 0, pb_membersize(st, m), 0, ptr}
     
 #define PB_REPEATED_CALLBACK(tag, st, m, fd, ltype, ptr) \
     {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REPEATED | ltype, \
     fd, 0, pb_membersize(st, m), 0, ptr}
 
-/* Optional extensions don't have the has_ field, as that would be redundant. */
+/* Optional extensions don't have the has_ field, as that would be redundant.
+ * Furthermore, the combination of OPTIONAL without has_ field is used
+ * for indicating proto3 style fields. Extensions exist in proto2 mode only,
+ * so they should be encoded according to proto2 rules. To avoid the conflict,
+ * extensions are marked as REQUIRED instead.
+ */
 #define PB_OPTEXT_STATIC(tag, st, m, fd, ltype, ptr) \
-    {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \
+    {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \
     0, \
     0, \
     pb_membersize(st, m), 0, ptr}
 
+#define PB_OPTEXT_POINTER(tag, st, m, fd, ltype, ptr) \
+    PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr)
+
 #define PB_OPTEXT_CALLBACK(tag, st, m, fd, ltype, ptr) \
-    {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \
-    0, 0, pb_membersize(st, m), 0, ptr}
+    PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr)
 
 /* The mapping from protobuf types to LTYPEs is done using these macros. */
-#define PB_LTYPE_MAP_BOOL       PB_LTYPE_VARINT
-#define PB_LTYPE_MAP_BYTES      PB_LTYPE_BYTES
-#define PB_LTYPE_MAP_DOUBLE     PB_LTYPE_FIXED64
-#define PB_LTYPE_MAP_ENUM       PB_LTYPE_VARINT
-#define PB_LTYPE_MAP_FIXED32    PB_LTYPE_FIXED32
-#define PB_LTYPE_MAP_FIXED64    PB_LTYPE_FIXED64
-#define PB_LTYPE_MAP_FLOAT      PB_LTYPE_FIXED32
-#define PB_LTYPE_MAP_INT32      PB_LTYPE_VARINT
-#define PB_LTYPE_MAP_INT64      PB_LTYPE_VARINT
-#define PB_LTYPE_MAP_MESSAGE    PB_LTYPE_SUBMESSAGE
-#define PB_LTYPE_MAP_SFIXED32   PB_LTYPE_FIXED32
-#define PB_LTYPE_MAP_SFIXED64   PB_LTYPE_FIXED64
-#define PB_LTYPE_MAP_SINT32     PB_LTYPE_SVARINT
-#define PB_LTYPE_MAP_SINT64     PB_LTYPE_SVARINT
-#define PB_LTYPE_MAP_STRING     PB_LTYPE_STRING
-#define PB_LTYPE_MAP_UINT32     PB_LTYPE_UVARINT
-#define PB_LTYPE_MAP_UINT64     PB_LTYPE_UVARINT
-#define PB_LTYPE_MAP_EXTENSION  PB_LTYPE_EXTENSION
+#define PB_LTYPE_MAP_BOOL               PB_LTYPE_VARINT
+#define PB_LTYPE_MAP_BYTES              PB_LTYPE_BYTES
+#define PB_LTYPE_MAP_DOUBLE             PB_LTYPE_FIXED64
+#define PB_LTYPE_MAP_ENUM               PB_LTYPE_VARINT
+#define PB_LTYPE_MAP_UENUM              PB_LTYPE_UVARINT
+#define PB_LTYPE_MAP_FIXED32            PB_LTYPE_FIXED32
+#define PB_LTYPE_MAP_FIXED64            PB_LTYPE_FIXED64
+#define PB_LTYPE_MAP_FLOAT              PB_LTYPE_FIXED32
+#define PB_LTYPE_MAP_INT32              PB_LTYPE_VARINT
+#define PB_LTYPE_MAP_INT64              PB_LTYPE_VARINT
+#define PB_LTYPE_MAP_MESSAGE            PB_LTYPE_SUBMESSAGE
+#define PB_LTYPE_MAP_SFIXED32           PB_LTYPE_FIXED32
+#define PB_LTYPE_MAP_SFIXED64           PB_LTYPE_FIXED64
+#define PB_LTYPE_MAP_SINT32             PB_LTYPE_SVARINT
+#define PB_LTYPE_MAP_SINT64             PB_LTYPE_SVARINT
+#define PB_LTYPE_MAP_STRING             PB_LTYPE_STRING
+#define PB_LTYPE_MAP_UINT32             PB_LTYPE_UVARINT
+#define PB_LTYPE_MAP_UINT64             PB_LTYPE_UVARINT
+#define PB_LTYPE_MAP_EXTENSION          PB_LTYPE_EXTENSION
+#define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES
 
 /* This is the actual macro used in field descriptions.
  * It takes these arguments:
  * - Field tag number
- * - Field type:   BOOL, BYTES, DOUBLE, ENUM, FIXED32, FIXED64,
+ * - Field type:   BOOL, BYTES, DOUBLE, ENUM, UENUM, FIXED32, FIXED64,
  *                 FLOAT, INT32, INT64, MESSAGE, SFIXED32, SFIXED64
  *                 SINT32, SINT64, STRING, UINT32, UINT64 or EXTENSION
  * - Field rules:  REQUIRED, OPTIONAL or REPEATED
- * - Allocation:   STATIC or CALLBACK
+ * - Allocation:   STATIC, CALLBACK or POINTER
+ * - Placement: FIRST or OTHER, depending on if this is the first field in structure.
  * - Message name
  * - Field name
  * - Previous field name (or field name again for first field)
  * - Pointer to default value or submsg fields.
  */
 
-#define PB_FIELD(tag, type, rules, allocation, message, field, prevfield, ptr) \
-    PB_ ## rules ## _ ## allocation(tag, message, field, \
-        PB_DATAOFFSET_CHOOSE(message, field, prevfield), \
-        PB_LTYPE_MAP_ ## type, ptr)
-
-/* This is a new version of the macro used by nanopb generator from
- * version 0.2.3 onwards. It avoids the use of a ternary expression in
- * the initialization, which confused some compilers.
- *
- * - Placement: FIRST or OTHER, depending on if this is the first field in structure.
- *
- */
-#define PB_FIELD2(tag, type, rules, allocation, placement, message, field, prevfield, ptr) \
-    PB_ ## rules ## _ ## allocation(tag, message, field, \
+#define PB_FIELD(tag, type, rules, allocation, placement, message, field, prevfield, ptr) \
+        PB_ ## rules ## _ ## allocation(tag, message, field, \
         PB_DATAOFFSET_ ## placement(message, field, prevfield), \
         PB_LTYPE_MAP_ ## type, ptr)
 
+/* Field description for repeated static fixed count fields.*/
+#define PB_REPEATED_FIXED_COUNT(tag, type, placement, message, field, prevfield, ptr) \
+    {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | PB_LTYPE_MAP_ ## type, \
+    PB_DATAOFFSET_ ## placement(message, field, prevfield), \
+    0, \
+    pb_membersize(message, field[0]), \
+    pb_arraysize(message, field), ptr}
+
+/* Field description for oneof fields. This requires taking into account the
+ * union name also, that's why a separate set of macros is needed.
+ */
+#define PB_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \
+    {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \
+    fd, pb_delta(st, which_ ## u, u.m), \
+    pb_membersize(st, u.m), 0, ptr}
+
+#define PB_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \
+    {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \
+    fd, pb_delta(st, which_ ## u, u.m), \
+    pb_membersize(st, u.m[0]), 0, ptr}
+
+#define PB_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \
+        PB_ONEOF_ ## allocation(union_name, tag, message, field, \
+        PB_DATAOFFSET_ ## placement(message, union_name.field, prevfield), \
+        PB_LTYPE_MAP_ ## type, ptr)
+
+#define PB_ANONYMOUS_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \
+    {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \
+    fd, pb_delta(st, which_ ## u, m), \
+    pb_membersize(st, m), 0, ptr}
+
+#define PB_ANONYMOUS_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \
+    {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \
+    fd, pb_delta(st, which_ ## u, m), \
+    pb_membersize(st, m[0]), 0, ptr}
+
+#define PB_ANONYMOUS_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \
+        PB_ANONYMOUS_ONEOF_ ## allocation(union_name, tag, message, field, \
+        PB_DATAOFFSET_ ## placement(message, field, prevfield), \
+        PB_LTYPE_MAP_ ## type, ptr)
 
 /* These macros are used for giving out error messages.
  * They are mostly a debugging aid; the main error information
  * is the true/false return value from functions.
  * Some code space can be saved by disabling the error
  * messages if not used.
+ *
+ * PB_SET_ERROR() sets the error message if none has been set yet.
+ *                msg must be a constant string literal.
+ * PB_GET_ERROR() always returns a pointer to a string.
+ * PB_RETURN_ERROR() sets the error and returns false from current
+ *                   function.
  */
 #ifdef PB_NO_ERRMSG
-#define PB_RETURN_ERROR(stream,msg) \
-    do {\
-        UNUSED(stream); \
-        return false; \
-    } while(0)
+#define PB_SET_ERROR(stream, msg) PB_UNUSED(stream)
 #define PB_GET_ERROR(stream) "(errmsg disabled)"
 #else
-#define PB_RETURN_ERROR(stream,msg) \
-    do {\
-        if ((stream)->errmsg == NULL) \
-            (stream)->errmsg = (msg); \
-        return false; \
-    } while(0)
+#define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg))
 #define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)")
 #endif
 
+#define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false
+
 #endif
diff --git a/pb_common.c b/pb_common.c
new file mode 100644
index 0000000..4fb7186
--- /dev/null
+++ b/pb_common.c
@@ -0,0 +1,97 @@
+/* pb_common.c: Common support functions for pb_encode.c and pb_decode.c.
+ *
+ * 2014 Petteri Aimonen <jpa@kapsi.fi>
+ */
+
+#include "pb_common.h"
+
+bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct)
+{
+    iter->start = fields;
+    iter->pos = fields;
+    iter->required_field_index = 0;
+    iter->dest_struct = dest_struct;
+    iter->pData = (char*)dest_struct + iter->pos->data_offset;
+    iter->pSize = (char*)iter->pData + iter->pos->size_offset;
+    
+    return (iter->pos->tag != 0);
+}
+
+bool pb_field_iter_next(pb_field_iter_t *iter)
+{
+    const pb_field_t *prev_field = iter->pos;
+
+    if (prev_field->tag == 0)
+    {
+        /* Handle empty message types, where the first field is already the terminator.
+         * In other cases, the iter->pos never points to the terminator. */
+        return false;
+    }
+    
+    iter->pos++;
+    
+    if (iter->pos->tag == 0)
+    {
+        /* Wrapped back to beginning, reinitialize */
+        (void)pb_field_iter_begin(iter, iter->start, iter->dest_struct);
+        return false;
+    }
+    else
+    {
+        /* Increment the pointers based on previous field size */
+        size_t prev_size = prev_field->data_size;
+    
+        if (PB_HTYPE(prev_field->type) == PB_HTYPE_ONEOF &&
+            PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF &&
+            iter->pos->data_offset == PB_SIZE_MAX)
+        {
+            /* Don't advance pointers inside unions */
+            return true;
+        }
+        else if (PB_ATYPE(prev_field->type) == PB_ATYPE_STATIC &&
+                 PB_HTYPE(prev_field->type) == PB_HTYPE_REPEATED)
+        {
+            /* In static arrays, the data_size tells the size of a single entry and
+             * array_size is the number of entries */
+            prev_size *= prev_field->array_size;
+        }
+        else if (PB_ATYPE(prev_field->type) == PB_ATYPE_POINTER)
+        {
+            /* Pointer fields always have a constant size in the main structure.
+             * The data_size only applies to the dynamically allocated area. */
+            prev_size = sizeof(void*);
+        }
+
+        if (PB_HTYPE(prev_field->type) == PB_HTYPE_REQUIRED)
+        {
+            /* Count the required fields, in order to check their presence in the
+             * decoder. */
+            iter->required_field_index++;
+        }
+    
+        iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset;
+        iter->pSize = (char*)iter->pData + iter->pos->size_offset;
+        return true;
+    }
+}
+
+bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag)
+{
+    const pb_field_t *start = iter->pos;
+    
+    do {
+        if (iter->pos->tag == tag &&
+            PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION)
+        {
+            /* Found the wanted field */
+            return true;
+        }
+        
+        (void)pb_field_iter_next(iter);
+    } while (iter->pos != start);
+    
+    /* Searched all the way back to start, and found nothing. */
+    return false;
+}
+
+
diff --git a/pb_common.h b/pb_common.h
new file mode 100644
index 0000000..60b3d37
--- /dev/null
+++ b/pb_common.h
@@ -0,0 +1,42 @@
+/* pb_common.h: Common support functions for pb_encode.c and pb_decode.c.
+ * These functions are rarely needed by applications directly.
+ */
+
+#ifndef PB_COMMON_H_INCLUDED
+#define PB_COMMON_H_INCLUDED
+
+#include "pb.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Iterator for pb_field_t list */
+struct pb_field_iter_s {
+    const pb_field_t *start;       /* Start of the pb_field_t array */
+    const pb_field_t *pos;         /* Current position of the iterator */
+    unsigned required_field_index; /* Zero-based index that counts only the required fields */
+    void *dest_struct;             /* Pointer to start of the structure */
+    void *pData;                   /* Pointer to current field value */
+    void *pSize;                   /* Pointer to count/has field */
+};
+typedef struct pb_field_iter_s pb_field_iter_t;
+
+/* Initialize the field iterator structure to beginning.
+ * Returns false if the message type is empty. */
+bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct);
+
+/* Advance the iterator to the next field.
+ * Returns false when the iterator wraps back to the first field. */
+bool pb_field_iter_next(pb_field_iter_t *iter);
+
+/* Advance the iterator until it points at a field with the given tag.
+ * Returns false if no such field exists. */
+bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
+
diff --git a/pb_decode.c b/pb_decode.c
index 9a48c60..4b80e81 100644
--- a/pb_decode.c
+++ b/pb_decode.c
@@ -15,38 +15,27 @@
 
 #include "pb.h"
 #include "pb_decode.h"
+#include "pb_common.h"
 
 /**************************************
  * Declarations internal to this file *
  **************************************/
 
-/* Iterator for pb_field_t list */
-typedef struct {
-    const pb_field_t *start; /* Start of the pb_field_t array */
-    const pb_field_t *pos; /* Current position of the iterator */
-    unsigned field_index; /* Zero-based index of the field. */
-    unsigned required_field_index; /* Zero-based index that counts only the required fields */
-    void *dest_struct; /* Pointer to the destination structure to decode to */
-    void *pData; /* Pointer where to store current field value */
-    void *pSize; /* Pointer where to store the size of current array field */
-} pb_field_iterator_t;
-
 typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn;
 
-static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count);
-static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest);
-static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size);
-static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct);
-static bool pb_field_next(pb_field_iterator_t *iter);
-static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag);
-static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
-static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
-static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
+static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count);
+static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size);
+static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter);
+static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter);
+static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter);
+static void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension);
 static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type);
-static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
-static bool checkreturn find_extension_field(pb_field_iterator_t *iter);
+static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter);
+static bool checkreturn find_extension_field(pb_field_iter_t *iter);
+static void pb_field_set_to_default(pb_field_iter_t *iter);
 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct);
 static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest);
+static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof);
 static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest);
 static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest);
 static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest);
@@ -54,9 +43,24 @@
 static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest);
 static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest);
 static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest);
+static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest);
 static bool checkreturn pb_skip_varint(pb_istream_t *stream);
 static bool checkreturn pb_skip_string(pb_istream_t *stream);
 
+#ifdef PB_ENABLE_MALLOC
+static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size);
+static bool checkreturn pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter);
+static void pb_release_single_field(const pb_field_iter_t *iter);
+#endif
+
+#ifdef PB_WITHOUT_64BIT
+#define pb_int64_t int32_t
+#define pb_uint64_t uint32_t
+#else
+#define pb_int64_t int64_t
+#define pb_uint64_t uint64_t
+#endif
+
 /* --- Function pointers to field decoders ---
  * Order in the array must match pb_action_t LTYPE numbering.
  */
@@ -70,34 +74,36 @@
     &pb_dec_bytes,
     &pb_dec_string,
     &pb_dec_submessage,
-    NULL /* extensions */
+    NULL, /* extensions */
+    &pb_dec_fixed_length_bytes
 };
 
 /*******************************
  * pb_istream_t implementation *
  *******************************/
 
-static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count)
+static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count)
 {
-    uint8_t *source = (uint8_t*)stream->state;
-    stream->state = source + count;
+    size_t i;
+    const pb_byte_t *source = (const pb_byte_t*)stream->state;
+    stream->state = (pb_byte_t*)stream->state + count;
     
     if (buf != NULL)
     {
-        while (count--)
-            *buf++ = *source++;
+        for (i = 0; i < count; i++)
+            buf[i] = source[i];
     }
     
     return true;
 }
 
-bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count)
+bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count)
 {
 #ifndef PB_BUFFER_ONLY
 	if (buf == NULL && stream->callback != buf_read)
 	{
 		/* Skip input bytes */
-		uint8_t tmp[16];
+		pb_byte_t tmp[16];
 		while (count > 16)
 		{
 			if (!pb_read(stream, tmp, 16))
@@ -127,7 +133,7 @@
 
 /* Read a single byte from input stream. buf may not be NULL.
  * This is an optimization for the varint decoding. */
-static bool checkreturn pb_readbyte(pb_istream_t *stream, uint8_t *buf)
+static bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf)
 {
     if (stream->bytes_left == 0)
         PB_RETURN_ERROR(stream, "end-of-stream");
@@ -136,8 +142,8 @@
     if (!stream->callback(stream, buf, 1))
         PB_RETURN_ERROR(stream, "io error");
 #else
-    *buf = *(uint8_t*)stream->state;
-    stream->state = (uint8_t*)stream->state + 1;
+    *buf = *(const pb_byte_t*)stream->state;
+    stream->state = (pb_byte_t*)stream->state + 1;
 #endif
 
     stream->bytes_left--;
@@ -145,15 +151,23 @@
     return true;    
 }
 
-pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize)
+pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize)
 {
     pb_istream_t stream;
+    /* Cast away the const from buf without a compiler error.  We are
+     * careful to use it only in a const manner in the callbacks.
+     */
+    union {
+        void *state;
+        const void *c_state;
+    } state;
 #ifdef PB_BUFFER_ONLY
     stream.callback = NULL;
 #else
     stream.callback = &buf_read;
 #endif
-    stream.state = buf;
+    state.c_state = buf;
+    stream.state = state.state;
     stream.bytes_left = bufsize;
 #ifndef PB_NO_ERRMSG
     stream.errmsg = NULL;
@@ -165,13 +179,23 @@
  * Helper functions *
  ********************/
 
-static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
+static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof)
 {
-    uint8_t byte;
+    pb_byte_t byte;
     uint32_t result;
     
     if (!pb_readbyte(stream, &byte))
+    {
+        if (stream->bytes_left == 0)
+        {
+            if (eof)
+            {
+                *eof = true;
+            }
+        }
+
         return false;
+    }
     
     if ((byte & 0x80) == 0)
     {
@@ -181,30 +205,52 @@
     else
     {
         /* Multibyte case */
-        uint8_t bitpos = 7;
+        uint_fast8_t bitpos = 7;
         result = byte & 0x7F;
         
         do
         {
-            if (bitpos >= 32)
-                PB_RETURN_ERROR(stream, "varint overflow");
-            
             if (!pb_readbyte(stream, &byte))
                 return false;
             
-            result |= (uint32_t)(byte & 0x7F) << bitpos;
-            bitpos = (uint8_t)(bitpos + 7);
+            if (bitpos >= 32)
+            {
+                /* Note: The varint could have trailing 0x80 bytes, or 0xFF for negative. */
+                uint8_t sign_extension = (bitpos < 63) ? 0xFF : 0x01;
+                
+                if ((byte & 0x7F) != 0x00 && ((result >> 31) == 0 || byte != sign_extension))
+                {
+                    PB_RETURN_ERROR(stream, "varint overflow");
+                }
+            }
+            else
+            {
+                result |= (uint32_t)(byte & 0x7F) << bitpos;
+            }
+            bitpos = (uint_fast8_t)(bitpos + 7);
         } while (byte & 0x80);
+        
+        if (bitpos == 35 && (byte & 0x70) != 0)
+        {
+            /* The last byte was at bitpos=28, so only bottom 4 bits fit. */
+            PB_RETURN_ERROR(stream, "varint overflow");
+        }
    }
    
    *dest = result;
    return true;
 }
 
+bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
+{
+    return pb_decode_varint32_eof(stream, dest, NULL);
+}
+
+#ifndef PB_WITHOUT_64BIT
 bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
 {
-    uint8_t byte;
-    uint8_t bitpos = 0;
+    pb_byte_t byte;
+    uint_fast8_t bitpos = 0;
     uint64_t result = 0;
     
     do
@@ -216,16 +262,17 @@
             return false;
 
         result |= (uint64_t)(byte & 0x7F) << bitpos;
-        bitpos = (uint8_t)(bitpos + 7);
+        bitpos = (uint_fast8_t)(bitpos + 7);
     } while (byte & 0x80);
     
     *dest = result;
     return true;
 }
+#endif
 
 bool checkreturn pb_skip_varint(pb_istream_t *stream)
 {
-    uint8_t byte;
+    pb_byte_t byte;
     do
     {
         if (!pb_read(stream, &byte, 1))
@@ -250,11 +297,8 @@
     *wire_type = (pb_wire_type_t) 0;
     *tag = 0;
     
-    if (!pb_decode_varint32(stream, &temp))
+    if (!pb_decode_varint32_eof(stream, &temp, eof))
     {
-        if (stream->bytes_left == 0)
-            *eof = true;
-
         return false;
     }
     
@@ -284,7 +328,7 @@
 /* Read a raw value to buffer, for the purpose of passing it to callback as
  * a substream. Size is maximum size on call, and actual size on return.
  */
-static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size)
+static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size)
 {
     size_t max_size = *size;
     switch (wire_type)
@@ -307,6 +351,12 @@
             *size = 4;
             return pb_read(stream, buf, 4);
         
+        case PB_WT_STRING:
+            /* Calling read_raw_value with a PB_WT_STRING is an error.
+             * Explicitly handle this case and fallthrough to default to avoid
+             * compiler warnings.
+             */
+
         default: PB_RETURN_ERROR(stream, "invalid wire_type");
     }
 }
@@ -329,84 +379,26 @@
     return true;
 }
 
-void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream)
+bool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream)
 {
+    if (substream->bytes_left) {
+        if (!pb_read(substream, NULL, substream->bytes_left))
+            return false;
+    }
+
     stream->state = substream->state;
 
 #ifndef PB_NO_ERRMSG
     stream->errmsg = substream->errmsg;
 #endif
-}
-
-static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct)
-{
-    iter->start = iter->pos = fields;
-    iter->field_index = 0;
-    iter->required_field_index = 0;
-    iter->pData = (char*)dest_struct + iter->pos->data_offset;
-    iter->pSize = (char*)iter->pData + iter->pos->size_offset;
-    iter->dest_struct = dest_struct;
-}
-
-static bool pb_field_next(pb_field_iterator_t *iter)
-{
-    bool notwrapped = true;
-    size_t prev_size = iter->pos->data_size;
-    
-    if (PB_ATYPE(iter->pos->type) == PB_ATYPE_STATIC &&
-        PB_HTYPE(iter->pos->type) == PB_HTYPE_REPEATED)
-    {
-        prev_size *= iter->pos->array_size;
-    }
-    else if (PB_ATYPE(iter->pos->type) == PB_ATYPE_POINTER)
-    {
-        prev_size = sizeof(void*);
-    }
-    
-    if (iter->pos->tag == 0)
-        return false; /* Only happens with empty message types */
-    
-    if (PB_HTYPE(iter->pos->type) == PB_HTYPE_REQUIRED)
-        iter->required_field_index++;
-    
-    iter->pos++;
-    iter->field_index++;
-    if (iter->pos->tag == 0)
-    {
-        iter->pos = iter->start;
-        iter->field_index = 0;
-        iter->required_field_index = 0;
-        iter->pData = iter->dest_struct;
-        prev_size = 0;
-        notwrapped = false;
-    }
-    
-    iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset;
-    iter->pSize = (char*)iter->pData + iter->pos->size_offset;
-    return notwrapped;
-}
-
-static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag)
-{
-    unsigned start = iter->field_index;
-    
-    do {
-        if (iter->pos->tag == tag &&
-            PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION)
-        {
-            return true;
-        }
-        (void)pb_field_next(iter);
-    } while (iter->field_index != start);
-    
-    return false;
+    return true;
 }
 
 /*************************
  * Decode a single field *
  *************************/
 
-static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
+static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter)
 {
     pb_type_t type;
     pb_decoder_t func;
@@ -420,7 +412,8 @@
             return func(stream, iter->pos, iter->pData);
             
         case PB_HTYPE_OPTIONAL:
-            *(bool*)iter->pSize = true;
+            if (iter->pSize != iter->pData)
+                *(bool*)iter->pSize = true;
             return func(stream, iter->pos, iter->pData);
     
         case PB_HTYPE_REPEATED:
@@ -429,14 +422,15 @@
             {
                 /* Packed array */
                 bool status = true;
-                size_t *size = (size_t*)iter->pSize;
+                pb_size_t *size = (pb_size_t*)iter->pSize;
+
                 pb_istream_t substream;
                 if (!pb_make_string_substream(stream, &substream))
                     return false;
-                
+
                 while (substream.bytes_left > 0 && *size < iter->pos->array_size)
                 {
-                    void *pItem = (uint8_t*)iter->pData + iter->pos->data_size * (*size);
+                    void *pItem = (char*)iter->pData + iter->pos->data_size * (*size);
                     if (!func(&substream, iter->pos, pItem))
                     {
                         status = false;
@@ -444,25 +438,37 @@
                     }
                     (*size)++;
                 }
-                pb_close_string_substream(stream, &substream);
-                
+
                 if (substream.bytes_left != 0)
                     PB_RETURN_ERROR(stream, "array overflow");
-                
+                if (!pb_close_string_substream(stream, &substream))
+                    return false;
+
                 return status;
             }
             else
             {
                 /* Repeated field */
-                size_t *size = (size_t*)iter->pSize;
-                void *pItem = (uint8_t*)iter->pData + iter->pos->data_size * (*size);
-                if (*size >= iter->pos->array_size)
+                pb_size_t *size = (pb_size_t*)iter->pSize;
+                char *pItem = (char*)iter->pData + iter->pos->data_size * (*size);
+
+                if ((*size)++ >= iter->pos->array_size)
                     PB_RETURN_ERROR(stream, "array overflow");
-                
-                (*size)++;
+
                 return func(stream, iter->pos, pItem);
             }
 
+        case PB_HTYPE_ONEOF:
+            *(pb_size_t*)iter->pSize = iter->pos->tag;
+            if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE)
+            {
+                /* We memset to zero so that any callbacks are set to NULL.
+                 * Then set any default values. */
+                memset(iter->pData, 0, iter->pos->data_size);
+                pb_message_set_to_defaults((const pb_field_t*)iter->pos->ptr, iter->pData);
+            }
+            return func(stream, iter->pos, iter->pData);
+
         default:
             PB_RETURN_ERROR(stream, "invalid field type");
     }
@@ -470,16 +476,37 @@
 
 #ifdef PB_ENABLE_MALLOC
 /* Allocate storage for the field and store the pointer at iter->pData.
- * array_size is the number of entries to reserve in an array. */
+ * array_size is the number of entries to reserve in an array.
+ * Zero size is not allowed, use pb_free() for releasing.
+ */
 static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size)
 {    
     void *ptr = *(void**)pData;
-    size_t size = array_size * data_size;
+    
+    if (data_size == 0 || array_size == 0)
+        PB_RETURN_ERROR(stream, "invalid size");
+    
+    /* Check for multiplication overflows.
+     * This code avoids the costly division if the sizes are small enough.
+     * Multiplication is safe as long as only half of bits are set
+     * in either multiplicand.
+     */
+    {
+        const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4);
+        if (data_size >= check_limit || array_size >= check_limit)
+        {
+            const size_t size_max = (size_t)-1;
+            if (size_max / array_size < data_size)
+            {
+                PB_RETURN_ERROR(stream, "size too large");
+            }
+        }
+    }
     
     /* Allocate new or expand previous allocation */
     /* Note: on failure the old pointer will remain in the structure,
      * the message must be freed by caller also on error return. */
-    ptr = pb_realloc(ptr, size);
+    ptr = pb_realloc(ptr, array_size * data_size);
     if (ptr == NULL)
         PB_RETURN_ERROR(stream, "realloc failed");
     
@@ -488,7 +515,7 @@
 }
 
 /* Clear a newly allocated item in case it contains a pointer, or is a submessage. */
-static void initialize_pointer_field(void *pItem, pb_field_iterator_t *iter)
+static void initialize_pointer_field(void *pItem, pb_field_iter_t *iter)
 {
     if (PB_LTYPE(iter->pos->type) == PB_LTYPE_STRING ||
         PB_LTYPE(iter->pos->type) == PB_LTYPE_BYTES)
@@ -497,16 +524,19 @@
     }
     else if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE)
     {
+        /* We memset to zero so that any callbacks are set to NULL.
+         * Then set any default values. */
+        memset(pItem, 0, iter->pos->data_size);
         pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, pItem);
     }
 }
 #endif
 
-static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
+static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter)
 {
 #ifndef PB_ENABLE_MALLOC
-    UNUSED(wire_type);
-    UNUSED(iter);
+    PB_UNUSED(wire_type);
+    PB_UNUSED(iter);
     PB_RETURN_ERROR(stream, "no malloc support");
 #else
     pb_type_t type;
@@ -519,6 +549,19 @@
     {
         case PB_HTYPE_REQUIRED:
         case PB_HTYPE_OPTIONAL:
+        case PB_HTYPE_ONEOF:
+            if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE &&
+                *(void**)iter->pData != NULL)
+            {
+                /* Duplicate field, have to release the old allocation first. */
+                pb_release_single_field(iter);
+            }
+        
+            if (PB_HTYPE(type) == PB_HTYPE_ONEOF)
+            {
+                *(pb_size_t*)iter->pSize = iter->pos->tag;
+            }
+
             if (PB_LTYPE(type) == PB_LTYPE_STRING ||
                 PB_LTYPE(type) == PB_LTYPE_BYTES)
             {
@@ -539,7 +582,7 @@
             {
                 /* Packed array, multiple items come in at once. */
                 bool status = true;
-                size_t *size = (size_t*)iter->pSize;
+                pb_size_t *size = (pb_size_t*)iter->pSize;
                 size_t allocated_size = *size;
                 void *pItem;
                 pb_istream_t substream;
@@ -549,7 +592,7 @@
                 
                 while (substream.bytes_left)
                 {
-                    if (*size + 1 > allocated_size)
+                    if ((size_t)*size + 1 > allocated_size)
                     {
                         /* Allocate more storage. This tries to guess the
                          * number of remaining entries. Round the division
@@ -564,41 +607,55 @@
                     }
 
                     /* Decode the array entry */
-                    pItem = *(uint8_t**)iter->pData + iter->pos->data_size * (*size);
+                    pItem = *(char**)iter->pData + iter->pos->data_size * (*size);
                     initialize_pointer_field(pItem, iter);
                     if (!func(&substream, iter->pos, pItem))
                     {
                         status = false;
                         break;
                     }
+                    
+                    if (*size == PB_SIZE_MAX)
+                    {
+#ifndef PB_NO_ERRMSG
+                        stream->errmsg = "too many array entries";
+#endif
+                        status = false;
+                        break;
+                    }
+                    
                     (*size)++;
                 }
-                pb_close_string_substream(stream, &substream);
+                if (!pb_close_string_substream(stream, &substream))
+                    return false;
                 
                 return status;
             }
             else
             {
                 /* Normal repeated field, i.e. only one item at a time. */
-                size_t *size = (size_t*)iter->pSize;
+                pb_size_t *size = (pb_size_t*)iter->pSize;
                 void *pItem;
                 
+                if (*size == PB_SIZE_MAX)
+                    PB_RETURN_ERROR(stream, "too many array entries");
+                
                 (*size)++;
                 if (!allocate_field(stream, iter->pData, iter->pos->data_size, *size))
                     return false;
             
-                pItem = *(uint8_t**)iter->pData + iter->pos->data_size * (*size - 1);
+                pItem = *(char**)iter->pData + iter->pos->data_size * (*size - 1);
                 initialize_pointer_field(pItem, iter);
                 return func(stream, iter->pos, pItem);
             }
-            
+
         default:
             PB_RETURN_ERROR(stream, "invalid field type");
     }
 #endif
 }
 
-static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
+static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter)
 {
     pb_callback_t *pCallback = (pb_callback_t*)iter->pData;
     
@@ -608,7 +665,7 @@
     void **arg = &(pCallback->arg);
 #endif
     
-    if (pCallback->funcs.decode == NULL)
+    if (pCallback == NULL || pCallback->funcs.decode == NULL)
         return pb_skip_field(stream, wire_type);
     
     if (wire_type == PB_WT_STRING)
@@ -624,7 +681,9 @@
                 PB_RETURN_ERROR(stream, "callback failed");
         } while (substream.bytes_left);
         
-        pb_close_string_substream(stream, &substream);
+        if (!pb_close_string_substream(stream, &substream))
+            return false;
+
         return true;
     }
     else
@@ -634,7 +693,7 @@
          * which in turn allows to use same callback for packed and
          * not-packed fields. */
         pb_istream_t substream;
-        uint8_t buffer[10];
+        pb_byte_t buffer[10];
         size_t size = sizeof(buffer);
         
         if (!read_raw_value(stream, wire_type, buffer, &size))
@@ -645,8 +704,18 @@
     }
 }
 
-static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
+static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter)
 {
+#ifdef PB_ENABLE_MALLOC
+    /* When decoding an oneof field, check if there is old data that must be
+     * released first. */
+    if (PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF)
+    {
+        if (!pb_release_union_field(stream, iter))
+            return false;
+    }
+#endif
+
     switch (PB_ATYPE(iter->pos->type))
     {
         case PB_ATYPE_STATIC:
@@ -663,32 +732,45 @@
     }
 }
 
+static void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension)
+{
+    /* Fake a field iterator for the extension field.
+     * It is not actually safe to advance this iterator, but decode_field
+     * will not even try to. */
+    const pb_field_t *field = (const pb_field_t*)extension->type->arg;
+    (void)pb_field_iter_begin(iter, field, extension->dest);
+    iter->pData = extension->dest;
+    iter->pSize = &extension->found;
+    
+    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
+    {
+        /* For pointer extensions, the pointer is stored directly
+         * in the extension structure. This avoids having an extra
+         * indirection. */
+        iter->pData = &extension->dest;
+    }
+}
+
 /* Default handler for extension fields. Expects a pb_field_t structure
  * in extension->type->arg. */
 static bool checkreturn default_extension_decoder(pb_istream_t *stream,
     pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type)
 {
     const pb_field_t *field = (const pb_field_t*)extension->type->arg;
-    pb_field_iterator_t iter;
+    pb_field_iter_t iter;
     
     if (field->tag != tag)
         return true;
     
-    iter.start = field;
-    iter.pos = field;
-    iter.field_index = 0;
-    iter.required_field_index = 0;
-    iter.dest_struct = extension->dest;
-    iter.pData = extension->dest;
-    iter.pSize = &extension->found;
-    
+    iter_from_extension(&iter, extension);
+    extension->found = true;
     return decode_field(stream, wire_type, &iter);
 }
 
 /* Try to decode an unknown field as an extension field. Tries each extension
  * decoder in turn, until one of them handles the field or loop ends. */
 static bool checkreturn decode_extension(pb_istream_t *stream,
-    uint32_t tag, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
+    uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter)
 {
     pb_extension_t *extension = *(pb_extension_t* const *)iter->pData;
     size_t pos = stream->bytes_left;
@@ -713,81 +795,103 @@
 /* Step through the iterator until an extension field is found or until all
  * entries have been checked. There can be only one extension field per
  * message. Returns false if no extension field is found. */
-static bool checkreturn find_extension_field(pb_field_iterator_t *iter)
+static bool checkreturn find_extension_field(pb_field_iter_t *iter)
 {
-    unsigned start = iter->field_index;
+    const pb_field_t *start = iter->pos;
     
     do {
         if (PB_LTYPE(iter->pos->type) == PB_LTYPE_EXTENSION)
             return true;
-        (void)pb_field_next(iter);
-    } while (iter->field_index != start);
+        (void)pb_field_iter_next(iter);
+    } while (iter->pos != start);
     
     return false;
 }
 
 /* Initialize message fields to default values, recursively */
-static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct)
+static void pb_field_set_to_default(pb_field_iter_t *iter)
 {
-    pb_field_iterator_t iter;
-    pb_field_init(&iter, fields, dest_struct);
+    pb_type_t type;
+    type = iter->pos->type;
     
-    do
+    if (PB_LTYPE(type) == PB_LTYPE_EXTENSION)
     {
-        pb_type_t type;
-        type = iter.pos->type;
-    
-        /* Avoid crash on empty message types (zero fields) */
-        if (iter.pos->tag == 0)
-            continue;
-        
-        if (PB_ATYPE(type) == PB_ATYPE_STATIC)
+        pb_extension_t *ext = *(pb_extension_t* const *)iter->pData;
+        while (ext != NULL)
         {
-            if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL)
-            {
-                /* Set has_field to false. Still initialize the optional field
-                 * itself also. */
-                *(bool*)iter.pSize = false;
-            }
-            else if (PB_HTYPE(type) == PB_HTYPE_REPEATED)
-            {
-                /* Set array count to 0, no need to initialize contents. */
-                *(size_t*)iter.pSize = 0;
-                continue;
-            }
-            
-            if (PB_LTYPE(iter.pos->type) == PB_LTYPE_SUBMESSAGE)
+            pb_field_iter_t ext_iter;
+            ext->found = false;
+            iter_from_extension(&ext_iter, ext);
+            pb_field_set_to_default(&ext_iter);
+            ext = ext->next;
+        }
+    }
+    else if (PB_ATYPE(type) == PB_ATYPE_STATIC)
+    {
+        bool init_data = true;
+        if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && iter->pSize != iter->pData)
+        {
+            /* Set has_field to false. Still initialize the optional field
+             * itself also. */
+            *(bool*)iter->pSize = false;
+        }
+        else if (PB_HTYPE(type) == PB_HTYPE_REPEATED ||
+                 PB_HTYPE(type) == PB_HTYPE_ONEOF)
+        {
+            /* REPEATED: Set array count to 0, no need to initialize contents.
+               ONEOF: Set which_field to 0. */
+            *(pb_size_t*)iter->pSize = 0;
+            init_data = false;
+        }
+
+        if (init_data)
+        {
+            if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE)
             {
                 /* Initialize submessage to defaults */
-                pb_message_set_to_defaults((const pb_field_t *) iter.pos->ptr, iter.pData);
+                pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, iter->pData);
             }
-            else if (iter.pos->ptr != NULL)
+            else if (iter->pos->ptr != NULL)
             {
                 /* Initialize to default value */
-                memcpy(iter.pData, iter.pos->ptr, iter.pos->data_size);
+                memcpy(iter->pData, iter->pos->ptr, iter->pos->data_size);
             }
             else
             {
                 /* Initialize to zeros */
-                memset(iter.pData, 0, iter.pos->data_size);
+                memset(iter->pData, 0, iter->pos->data_size);
             }
         }
-        else if (PB_ATYPE(type) == PB_ATYPE_POINTER)
+    }
+    else if (PB_ATYPE(type) == PB_ATYPE_POINTER)
+    {
+        /* Initialize the pointer to NULL. */
+        *(void**)iter->pData = NULL;
+        
+        /* Initialize array count to 0. */
+        if (PB_HTYPE(type) == PB_HTYPE_REPEATED ||
+            PB_HTYPE(type) == PB_HTYPE_ONEOF)
         {
-            /* Initialize the pointer to NULL. */
-            *(void**)iter.pData = NULL;
-            
-            /* Initialize array count to 0. */
-            if (PB_HTYPE(type) == PB_HTYPE_REPEATED)
-            {
-                *(size_t*)iter.pSize = 0;
-            }
+            *(pb_size_t*)iter->pSize = 0;
         }
-        else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK)
-        {
-            /* Don't overwrite callback */
-        }
-    } while (pb_field_next(&iter));
+    }
+    else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK)
+    {
+        /* Don't overwrite callback */
+    }
+}
+
+static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct)
+{
+    pb_field_iter_t iter;
+
+    if (!pb_field_iter_begin(&iter, fields, dest_struct))
+        return; /* Empty message type */
+    
+    do
+    {
+        pb_field_set_to_default(&iter);
+    } while (pb_field_iter_next(&iter));
 }
 
 /*********************
@@ -796,18 +900,28 @@
 
 bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
 {
-    uint8_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 7) / 8] = {0, 0, 0, 0, 0, 0, 0, 0};
+    uint32_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 31) / 32] = {0, 0};
+    const uint32_t allbits = ~(uint32_t)0;
     uint32_t extension_range_start = 0;
-    pb_field_iterator_t iter;
-    
-    pb_field_init(&iter, fields, dest_struct);
-    
+    pb_field_iter_t iter;
+
+    /* 'fixed_count_field' and 'fixed_count_size' track position of a repeated fixed
+     * count field. This can only handle _one_ repeated fixed count field that
+     * is unpacked and unordered among other (non repeated fixed count) fields.
+     */
+    const pb_field_t *fixed_count_field = NULL;
+    pb_size_t fixed_count_size = 0;
+
+    /* Return value ignored, as empty message types will be correctly handled by
+     * pb_field_iter_find() anyway. */
+    (void)pb_field_iter_begin(&iter, fields, dest_struct);
+
     while (stream->bytes_left)
     {
         uint32_t tag;
         pb_wire_type_t wire_type;
         bool eof;
-        
+
         if (!pb_decode_tag(stream, &wire_type, &tag, &eof))
         {
             if (eof)
@@ -815,8 +929,8 @@
             else
                 return false;
         }
-        
-        if (!pb_field_find(&iter, tag))
+
+        if (!pb_field_iter_find(&iter, tag))
         {
             /* No match found, check if it matches an extension. */
             if (tag >= extension_range_start)
@@ -825,38 +939,70 @@
                     extension_range_start = (uint32_t)-1;
                 else
                     extension_range_start = iter.pos->tag;
-                
+
                 if (tag >= extension_range_start)
                 {
                     size_t pos = stream->bytes_left;
-                
+
                     if (!decode_extension(stream, tag, wire_type, &iter))
                         return false;
-                    
+
                     if (pos != stream->bytes_left)
                     {
                         /* The field was handled */
-                        continue;                    
+                        continue;
                     }
                 }
             }
-        
+
             /* No match found, skip data */
             if (!pb_skip_field(stream, wire_type))
                 return false;
             continue;
         }
-        
+
+        /* If a repeated fixed count field was found, get size from
+         * 'fixed_count_field' as there is no counter contained in the struct.
+         */
+        if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REPEATED
+            && iter.pSize == iter.pData)
+        {
+            if (fixed_count_field != iter.pos) {
+                /* If the new fixed count field does not match the previous one,
+                 * check that the previous one is NULL or that it finished
+                 * receiving all the expected data.
+                 */
+                if (fixed_count_field != NULL &&
+                    fixed_count_size != fixed_count_field->array_size)
+                {
+                    PB_RETURN_ERROR(stream, "wrong size for fixed count field");
+                }
+
+                fixed_count_field = iter.pos;
+                fixed_count_size = 0;
+            }
+
+            iter.pSize = &fixed_count_size;
+        }
+
         if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REQUIRED
             && iter.required_field_index < PB_MAX_REQUIRED_FIELDS)
         {
-            fields_seen[iter.required_field_index >> 3] |= (uint8_t)(1 << (iter.required_field_index & 7));
+            uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31));
+            fields_seen[iter.required_field_index >> 5] |= tmp;
         }
-            
+
         if (!decode_field(stream, wire_type, &iter))
             return false;
     }
-    
+
+    /* Check that all elements of the last decoded fixed count field were present. */
+    if (fixed_count_field != NULL &&
+        fixed_count_size != fixed_count_field->array_size)
+    {
+        PB_RETURN_ERROR(stream, "wrong size for fixed count field");
+    }
+
     /* Check that all required fields were present. */
     {
         /* First figure out the number of required fields by
@@ -869,22 +1015,34 @@
         do {
             req_field_count = iter.required_field_index;
             last_type = iter.pos->type;
-        } while (pb_field_next(&iter));
+        } while (pb_field_iter_next(&iter));
         
         /* Fixup if last field was also required. */
         if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED && iter.pos->tag != 0)
             req_field_count++;
         
-        /* Check the whole bytes */
-        for (i = 0; i < (req_field_count >> 3); i++)
+        if (req_field_count > PB_MAX_REQUIRED_FIELDS)
+            req_field_count = PB_MAX_REQUIRED_FIELDS;
+
+        if (req_field_count > 0)
         {
-            if (fields_seen[i] != 0xFF)
-                PB_RETURN_ERROR(stream, "missing required field");
+            /* Check the whole words */
+            for (i = 0; i < (req_field_count >> 5); i++)
+            {
+                if (fields_seen[i] != allbits)
+                    PB_RETURN_ERROR(stream, "missing required field");
+            }
+            
+            /* Check the remaining bits (if any) */
+            if ((req_field_count & 31) != 0)
+            {
+                if (fields_seen[req_field_count >> 5] !=
+                    (allbits >> (32 - (req_field_count & 31))))
+                {
+                    PB_RETURN_ERROR(stream, "missing required field");
+                }
+            }
         }
-        
-        /* Check the remaining bits */
-        if (fields_seen[req_field_count >> 3] != (0xFF >> (8 - (req_field_count & 7))))
-            PB_RETURN_ERROR(stream, "missing required field");
     }
     
     return true;
@@ -904,6 +1062,21 @@
     return status;
 }
 
+bool pb_decode_delimited_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
+{
+    pb_istream_t substream;
+    bool status;
+
+    if (!pb_make_string_substream(stream, &substream))
+        return false;
+
+    status = pb_decode_noinit(&substream, fields, dest_struct);
+
+    if (!pb_close_string_substream(stream, &substream))
+        return false;
+    return status;
+}
+
 bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
 {
     pb_istream_t substream;
@@ -913,212 +1086,342 @@
         return false;
     
     status = pb_decode(&substream, fields, dest_struct);
-    pb_close_string_substream(stream, &substream);
+
+    if (!pb_close_string_substream(stream, &substream))
+        return false;
     return status;
 }
 
-#ifdef PB_ENABLE_MALLOC
-void pb_release(const pb_field_t fields[], void *dest_struct)
+bool pb_decode_nullterminated(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
 {
-    pb_field_iterator_t iter;
-    pb_field_init(&iter, fields, dest_struct);
+    /* This behaviour will be separated in nanopb-0.4.0, see issue #278. */
+    return pb_decode(stream, fields, dest_struct);
+}
+
+#ifdef PB_ENABLE_MALLOC
+/* Given an oneof field, if there has already been a field inside this oneof,
+ * release it before overwriting with a different one. */
+static bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter)
+{
+    pb_size_t old_tag = *(pb_size_t*)iter->pSize; /* Previous which_ value */
+    pb_size_t new_tag = iter->pos->tag; /* New which_ value */
+
+    if (old_tag == 0)
+        return true; /* Ok, no old data in union */
+
+    if (old_tag == new_tag)
+        return true; /* Ok, old data is of same type => merge */
+
+    /* Release old data. The find can fail if the message struct contains
+     * invalid data. */
+    if (!pb_field_iter_find(iter, old_tag))
+        PB_RETURN_ERROR(stream, "invalid union tag");
+
+    pb_release_single_field(iter);
+
+    /* Restore iterator to where it should be.
+     * This shouldn't fail unless the pb_field_t structure is corrupted. */
+    if (!pb_field_iter_find(iter, new_tag))
+        PB_RETURN_ERROR(stream, "iterator error");
     
-    do
+    return true;
+}
+
+static void pb_release_single_field(const pb_field_iter_t *iter)
+{
+    pb_type_t type;
+    type = iter->pos->type;
+
+    if (PB_HTYPE(type) == PB_HTYPE_ONEOF)
     {
-        pb_type_t type;
-        type = iter.pos->type;
-    
-        /* Avoid crash on empty message types (zero fields) */
-        if (iter.pos->tag == 0)
-            continue;
+        if (*(pb_size_t*)iter->pSize != iter->pos->tag)
+            return; /* This is not the current field in the union */
+    }
+
+    /* Release anything contained inside an extension or submsg.
+     * This has to be done even if the submsg itself is statically
+     * allocated. */
+    if (PB_LTYPE(type) == PB_LTYPE_EXTENSION)
+    {
+        /* Release fields from all extensions in the linked list */
+        pb_extension_t *ext = *(pb_extension_t**)iter->pData;
+        while (ext != NULL)
+        {
+            pb_field_iter_t ext_iter;
+            iter_from_extension(&ext_iter, ext);
+            pb_release_single_field(&ext_iter);
+            ext = ext->next;
+        }
+    }
+    else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE)
+    {
+        /* Release fields in submessage or submsg array */
+        void *pItem = iter->pData;
+        pb_size_t count = 1;
         
         if (PB_ATYPE(type) == PB_ATYPE_POINTER)
         {
-            if (PB_HTYPE(type) == PB_HTYPE_REPEATED &&
-                (PB_LTYPE(type) == PB_LTYPE_STRING ||
-                 PB_LTYPE(type) == PB_LTYPE_BYTES))
-            {
-                /* Release entries in repeated string or bytes array */
-                void **pItem = *(void***)iter.pData;
-                size_t count = *(size_t*)iter.pSize;
-                while (count--)
-                {
-                    pb_free(*pItem);
-                    *pItem++ = NULL;
-                }
-            }
-            else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE)
-            {
-                /* Release fields in submessages */
-                void *pItem = *(void**)iter.pData;
-                size_t count = (pItem ? 1 : 0);
-                
-                if (PB_HTYPE(type) == PB_HTYPE_REPEATED)
-                {
-                    count = *(size_t*)iter.pSize;   
-                }
-                
-                while (count--)
-                {
-                    pb_release((const pb_field_t*)iter.pos->ptr, pItem);
-                    pItem = (uint8_t*)pItem + iter.pos->data_size;
-                }
-            }
-            
-            /* Release main item */
-            pb_free(*(void**)iter.pData);
-            *(void**)iter.pData = NULL;
+            pItem = *(void**)iter->pData;
         }
-    } while (pb_field_next(&iter));
+        
+        if (PB_HTYPE(type) == PB_HTYPE_REPEATED)
+        {
+            if (PB_ATYPE(type) == PB_ATYPE_STATIC && iter->pSize == iter->pData) {
+                /* No _count field so use size of the array */
+                count = iter->pos->array_size;
+            } else {
+                count = *(pb_size_t*)iter->pSize;
+            }
+
+            if (PB_ATYPE(type) == PB_ATYPE_STATIC && count > iter->pos->array_size)
+            {
+                /* Protect against corrupted _count fields */
+                count = iter->pos->array_size;
+            }
+        }
+        
+        if (pItem)
+        {
+            while (count--)
+            {
+                pb_release((const pb_field_t*)iter->pos->ptr, pItem);
+                pItem = (char*)pItem + iter->pos->data_size;
+            }
+        }
+    }
+    
+    if (PB_ATYPE(type) == PB_ATYPE_POINTER)
+    {
+        if (PB_HTYPE(type) == PB_HTYPE_REPEATED &&
+            (PB_LTYPE(type) == PB_LTYPE_STRING ||
+             PB_LTYPE(type) == PB_LTYPE_BYTES))
+        {
+            /* Release entries in repeated string or bytes array */
+            void **pItem = *(void***)iter->pData;
+            pb_size_t count = *(pb_size_t*)iter->pSize;
+            while (count--)
+            {
+                pb_free(*pItem);
+                *pItem++ = NULL;
+            }
+        }
+        
+        if (PB_HTYPE(type) == PB_HTYPE_REPEATED)
+        {
+            /* We are going to release the array, so set the size to 0 */
+            *(pb_size_t*)iter->pSize = 0;
+        }
+        
+        /* Release main item */
+        pb_free(*(void**)iter->pData);
+        *(void**)iter->pData = NULL;
+    }
+}
+
+void pb_release(const pb_field_t fields[], void *dest_struct)
+{
+    pb_field_iter_t iter;
+    
+    if (!dest_struct)
+        return; /* Ignore NULL pointers, similar to free() */
+
+    if (!pb_field_iter_begin(&iter, fields, dest_struct))
+        return; /* Empty message type */
+    
+    do
+    {
+        pb_release_single_field(&iter);
+    } while (pb_field_iter_next(&iter));
 }
 #endif
 
 /* Field decoders */
 
-bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest)
+bool pb_decode_svarint(pb_istream_t *stream, pb_int64_t *dest)
 {
-    uint64_t value;
+    pb_uint64_t value;
     if (!pb_decode_varint(stream, &value))
         return false;
     
     if (value & 1)
-        *dest = (int64_t)(~(value >> 1));
+        *dest = (pb_int64_t)(~(value >> 1));
     else
-        *dest = (int64_t)(value >> 1);
+        *dest = (pb_int64_t)(value >> 1);
     
     return true;
 }
 
 bool pb_decode_fixed32(pb_istream_t *stream, void *dest)
 {
-    #ifdef __BIG_ENDIAN__
-    uint8_t *bytes = (uint8_t*)dest;
-    uint8_t lebytes[4];
-    
-    if (!pb_read(stream, lebytes, 4))
+    pb_byte_t bytes[4];
+
+    if (!pb_read(stream, bytes, 4))
         return false;
     
-    bytes[0] = lebytes[3];
-    bytes[1] = lebytes[2];
-    bytes[2] = lebytes[1];
-    bytes[3] = lebytes[0];
+    *(uint32_t*)dest = ((uint32_t)bytes[0] << 0) |
+                       ((uint32_t)bytes[1] << 8) |
+                       ((uint32_t)bytes[2] << 16) |
+                       ((uint32_t)bytes[3] << 24);
     return true;
-    #else
-    return pb_read(stream, (uint8_t*)dest, 4);
-    #endif   
 }
 
+#ifndef PB_WITHOUT_64BIT
 bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
 {
-    #ifdef __BIG_ENDIAN__
-    uint8_t *bytes = (uint8_t*)dest;
-    uint8_t lebytes[8];
-    
-    if (!pb_read(stream, lebytes, 8))
+    pb_byte_t bytes[8];
+
+    if (!pb_read(stream, bytes, 8))
         return false;
     
-    bytes[0] = lebytes[7];
-    bytes[1] = lebytes[6];
-    bytes[2] = lebytes[5];
-    bytes[3] = lebytes[4];
-    bytes[4] = lebytes[3];
-    bytes[5] = lebytes[2];
-    bytes[6] = lebytes[1];
-    bytes[7] = lebytes[0];
+    *(uint64_t*)dest = ((uint64_t)bytes[0] << 0) |
+                       ((uint64_t)bytes[1] << 8) |
+                       ((uint64_t)bytes[2] << 16) |
+                       ((uint64_t)bytes[3] << 24) |
+                       ((uint64_t)bytes[4] << 32) |
+                       ((uint64_t)bytes[5] << 40) |
+                       ((uint64_t)bytes[6] << 48) |
+                       ((uint64_t)bytes[7] << 56);
+    
     return true;
-    #else
-    return pb_read(stream, (uint8_t*)dest, 8);
-    #endif   
 }
+#endif
 
 static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest)
 {
-    uint64_t value;
+    pb_uint64_t value;
+    pb_int64_t svalue;
+    pb_int64_t clamped;
     if (!pb_decode_varint(stream, &value))
         return false;
     
-    switch (field->data_size)
-    {
-        case 1: *(int8_t*)dest = (int8_t)value; break;
-        case 2: *(int16_t*)dest = (int16_t)value; break;
-        case 4: *(int32_t*)dest = (int32_t)value; break;
-        case 8: *(int64_t*)dest = (int64_t)value; break;
-        default: PB_RETURN_ERROR(stream, "invalid data_size");
-    }
+    /* See issue 97: Google's C++ protobuf allows negative varint values to
+     * be cast as int32_t, instead of the int64_t that should be used when
+     * encoding. Previous nanopb versions had a bug in encoding. In order to
+     * not break decoding of such messages, we cast <=32 bit fields to
+     * int32_t first to get the sign correct.
+     */
+    if (field->data_size == sizeof(pb_int64_t))
+        svalue = (pb_int64_t)value;
+    else
+        svalue = (int32_t)value;
+
+    /* Cast to the proper field size, while checking for overflows */
+    if (field->data_size == sizeof(pb_int64_t))
+        clamped = *(pb_int64_t*)dest = svalue;
+    else if (field->data_size == sizeof(int32_t))
+        clamped = *(int32_t*)dest = (int32_t)svalue;
+    else if (field->data_size == sizeof(int_least16_t))
+        clamped = *(int_least16_t*)dest = (int_least16_t)svalue;
+    else if (field->data_size == sizeof(int_least8_t))
+        clamped = *(int_least8_t*)dest = (int_least8_t)svalue;
+    else
+        PB_RETURN_ERROR(stream, "invalid data_size");
+
+    if (clamped != svalue)
+        PB_RETURN_ERROR(stream, "integer too large");
     
     return true;
 }
 
 static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
 {
-    uint64_t value;
+    pb_uint64_t value, clamped;
     if (!pb_decode_varint(stream, &value))
         return false;
     
-    switch (field->data_size)
-    {
-        case 4: *(uint32_t*)dest = (uint32_t)value; break;
-        case 8: *(uint64_t*)dest = value; break;
-        default: PB_RETURN_ERROR(stream, "invalid data_size");
-    }
+    /* Cast to the proper field size, while checking for overflows */
+    if (field->data_size == sizeof(pb_uint64_t))
+        clamped = *(pb_uint64_t*)dest = value;
+    else if (field->data_size == sizeof(uint32_t))
+        clamped = *(uint32_t*)dest = (uint32_t)value;
+    else if (field->data_size == sizeof(uint_least16_t))
+        clamped = *(uint_least16_t*)dest = (uint_least16_t)value;
+    else if (field->data_size == sizeof(uint_least8_t))
+        clamped = *(uint_least8_t*)dest = (uint_least8_t)value;
+    else
+        PB_RETURN_ERROR(stream, "invalid data_size");
     
+    if (clamped != value)
+        PB_RETURN_ERROR(stream, "integer too large");
+
     return true;
 }
 
 static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
 {
-    int64_t value;
+    pb_int64_t value, clamped;
     if (!pb_decode_svarint(stream, &value))
         return false;
     
-    switch (field->data_size)
-    {
-        case 4: *(int32_t*)dest = (int32_t)value; break;
-        case 8: *(int64_t*)dest = value; break;
-        default: PB_RETURN_ERROR(stream, "invalid data_size");
-    }
+    /* Cast to the proper field size, while checking for overflows */
+    if (field->data_size == sizeof(pb_int64_t))
+        clamped = *(pb_int64_t*)dest = value;
+    else if (field->data_size == sizeof(int32_t))
+        clamped = *(int32_t*)dest = (int32_t)value;
+    else if (field->data_size == sizeof(int_least16_t))
+        clamped = *(int_least16_t*)dest = (int_least16_t)value;
+    else if (field->data_size == sizeof(int_least8_t))
+        clamped = *(int_least8_t*)dest = (int_least8_t)value;
+    else
+        PB_RETURN_ERROR(stream, "invalid data_size");
+
+    if (clamped != value)
+        PB_RETURN_ERROR(stream, "integer too large");
     
     return true;
 }
 
 static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest)
 {
-    UNUSED(field);
+    PB_UNUSED(field);
     return pb_decode_fixed32(stream, dest);
 }
 
 static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest)
 {
-    UNUSED(field);
+    PB_UNUSED(field);
+#ifndef PB_WITHOUT_64BIT
     return pb_decode_fixed64(stream, dest);
+#else
+    PB_UNUSED(dest);
+    PB_RETURN_ERROR(stream, "no 64bit support");
+#endif
 }
 
 static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest)
 {
     uint32_t size;
+    size_t alloc_size;
     pb_bytes_array_t *bdest;
     
     if (!pb_decode_varint32(stream, &size))
         return false;
     
+    if (size > PB_SIZE_MAX)
+        PB_RETURN_ERROR(stream, "bytes overflow");
+    
+    alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size);
+    if (size > alloc_size)
+        PB_RETURN_ERROR(stream, "size too large");
+    
     if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
     {
 #ifndef PB_ENABLE_MALLOC
         PB_RETURN_ERROR(stream, "no malloc support");
 #else
-        if (!allocate_field(stream, dest, PB_BYTES_ARRAY_T_ALLOCSIZE(size), 1))
+        if (!allocate_field(stream, dest, alloc_size, 1))
             return false;
         bdest = *(pb_bytes_array_t**)dest;
 #endif
     }
     else
     {
-        if (PB_BYTES_ARRAY_T_ALLOCSIZE(size) > field->data_size)
+        if (alloc_size > field->data_size)
             PB_RETURN_ERROR(stream, "bytes overflow");
         bdest = (pb_bytes_array_t*)dest;
     }
-    
-    bdest->size = size;
+
+    bdest->size = (pb_size_t)size;
     return pb_read(stream, bdest->bytes, size);
 }
 
@@ -1133,6 +1436,9 @@
     /* Space for null terminator */
     alloc_size = size + 1;
     
+    if (alloc_size < size)
+        PB_RETURN_ERROR(stream, "size too large");
+    
     if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
     {
 #ifndef PB_ENABLE_MALLOC
@@ -1149,8 +1455,8 @@
             PB_RETURN_ERROR(stream, "string overflow");
     }
     
-    status = pb_read(stream, (uint8_t*)dest, size);
-    *((uint8_t*)dest + size) = 0;
+    status = pb_read(stream, (pb_byte_t*)dest, size);
+    *((pb_byte_t*)dest + size) = 0;
     return status;
 }
 
@@ -1173,6 +1479,30 @@
     else
         status = pb_decode_noinit(&substream, submsg_fields, dest);
     
-    pb_close_string_substream(stream, &substream);
+    if (!pb_close_string_substream(stream, &substream))
+        return false;
     return status;
 }
+
+static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest)
+{
+    uint32_t size;
+
+    if (!pb_decode_varint32(stream, &size))
+        return false;
+
+    if (size > PB_SIZE_MAX)
+        PB_RETURN_ERROR(stream, "bytes overflow");
+
+    if (size == 0)
+    {
+        /* As a special case, treat empty bytes string as all zeros for fixed_length_bytes. */
+        memset(dest, 0, field->data_size);
+        return true;
+    }
+
+    if (size != field->data_size)
+        PB_RETURN_ERROR(stream, "incorrect fixed length bytes size");
+
+    return pb_read(stream, (pb_byte_t*)dest, field->data_size);
+}
diff --git a/pb_decode.h b/pb_decode.h
index 8dc6740..398b24a 100644
--- a/pb_decode.h
+++ b/pb_decode.h
@@ -3,8 +3,8 @@
  * field descriptions created by nanopb_generator.py.
  */
 
-#ifndef _PB_DECODE_H_
-#define _PB_DECODE_H_
+#ifndef PB_DECODE_H_INCLUDED
+#define PB_DECODE_H_INCLUDED
 
 #include "pb.h"
 
@@ -25,7 +25,7 @@
  *    is different than from the main stream. Don't use bytes_left to compute
  *    any pointers.
  */
-struct _pb_istream_t
+struct pb_istream_s
 {
 #ifdef PB_BUFFER_ONLY
     /* Callback pointer is not used in buffer-only configuration.
@@ -34,7 +34,7 @@
      */
     int *callback;
 #else
-    bool (*callback)(pb_istream_t *stream, uint8_t *buf, size_t count);
+    bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count);
 #endif
 
     void *state; /* Free field for use by callback implementation */
@@ -85,6 +85,18 @@
  */
 bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);
 
+/* Same as pb_decode_delimited, except that it does not initialize the destination structure.
+ * See pb_decode_noinit
+ */
+bool pb_decode_delimited_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);
+
+/* Same as pb_decode, except allows the message to be terminated with a null byte.
+ * NOTE: Until nanopb-0.4.0, pb_decode() also allows null-termination. This behaviour
+ * is not supported in most other protobuf implementations, so pb_decode_delimited()
+ * is a better option for compatibility.
+ */
+bool pb_decode_nullterminated(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct);
+
 #ifdef PB_ENABLE_MALLOC
 /* Release any allocated pointer fields. If you use dynamic allocation, you should
  * call this for any successfully decoded message when you are done with it. If
@@ -103,12 +115,12 @@
  * Alternatively, you can use a custom stream that reads directly from e.g.
  * a file or a network socket.
  */
-pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize);
+pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize);
 
 /* Function to read from a pb_istream_t. You can use this if you need to
  * read some custom header data, or to read data in field callbacks.
  */
-bool pb_read(pb_istream_t *stream, uint8_t *buf, size_t count);
+bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count);
 
 
 /************************************************
@@ -124,23 +136,37 @@
 
 /* Decode an integer in the varint format. This works for bool, enum, int32,
  * int64, uint32 and uint64 field types. */
+#ifndef PB_WITHOUT_64BIT
 bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest);
+#else
+#define pb_decode_varint pb_decode_varint32
+#endif
+
+/* Decode an integer in the varint format. This works for bool, enum, int32,
+ * and uint32 field types. */
+bool pb_decode_varint32(pb_istream_t *stream, uint32_t *dest);
 
 /* Decode an integer in the zig-zagged svarint format. This works for sint32
  * and sint64. */
+#ifndef PB_WITHOUT_64BIT
 bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest);
+#else
+bool pb_decode_svarint(pb_istream_t *stream, int32_t *dest);
+#endif
 
 /* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to
  * a 4-byte wide C variable. */
 bool pb_decode_fixed32(pb_istream_t *stream, void *dest);
 
+#ifndef PB_WITHOUT_64BIT
 /* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to
  * a 8-byte wide C variable. */
 bool pb_decode_fixed64(pb_istream_t *stream, void *dest);
+#endif
 
 /* Make a limited-length substream for reading a PB_WT_STRING field. */
 bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream);
-void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream);
+bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream);
 
 #ifdef __cplusplus
 } /* extern "C" */
diff --git a/pb_encode.c b/pb_encode.c
index dc5a273..089172c 100644
--- a/pb_encode.c
+++ b/pb_encode.c
@@ -5,6 +5,7 @@
 
 #include "pb.h"
 #include "pb_encode.h"
+#include "pb_common.h"
 
 /* Use the GCC warn_unused_result attribute to check that all return values
  * are propagated correctly. On other compilers and gcc before 3.4.0 just
@@ -21,11 +22,12 @@
  **************************************/
 typedef bool (*pb_encoder_t)(pb_ostream_t *stream, const pb_field_t *field, const void *src) checkreturn;
 
-static bool checkreturn buf_write(pb_ostream_t *stream, const uint8_t *buf, size_t count);
+static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count);
 static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, const void *pData, size_t count, pb_encoder_t func);
 static bool checkreturn encode_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData);
 static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension);
 static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData);
+static void *pb_const_cast(const void *p);
 static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
 static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
 static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
@@ -34,6 +36,17 @@
 static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src);
 static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src);
 static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src);
+static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src);
+
+#ifdef PB_WITHOUT_64BIT
+#define pb_int64_t int32_t
+#define pb_uint64_t uint32_t
+
+static bool checkreturn pb_encode_negative_varint(pb_ostream_t *stream, pb_uint64_t value);
+#else
+#define pb_int64_t int64_t
+#define pb_uint64_t uint64_t
+#endif
 
 /* --- Function pointers to field encoders ---
  * Order in the array must match pb_action_t LTYPE numbering.
@@ -48,25 +61,27 @@
     &pb_enc_bytes,
     &pb_enc_string,
     &pb_enc_submessage,
-    NULL /* extensions */
+    NULL, /* extensions */
+    &pb_enc_fixed_length_bytes
 };
 
 /*******************************
  * pb_ostream_t implementation *
  *******************************/
 
-static bool checkreturn buf_write(pb_ostream_t *stream, const uint8_t *buf, size_t count)
+static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)
 {
-    uint8_t *dest = (uint8_t*)stream->state;
+    size_t i;
+    pb_byte_t *dest = (pb_byte_t*)stream->state;
     stream->state = dest + count;
     
-    while (count--)
-        *dest++ = *buf++;
+    for (i = 0; i < count; i++)
+        dest[i] = buf[i];
     
     return true;
 }
 
-pb_ostream_t pb_ostream_from_buffer(uint8_t *buf, size_t bufsize)
+pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize)
 {
     pb_ostream_t stream;
 #ifdef PB_BUFFER_ONLY
@@ -83,7 +98,7 @@
     return stream;
 }
 
-bool checkreturn pb_write(pb_ostream_t *stream, const uint8_t *buf, size_t count)
+bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)
 {
     if (stream->callback != NULL)
     {
@@ -149,7 +164,7 @@
             size = sizestream.bytes_written;
         }
         
-        if (!pb_encode_varint(stream, (uint64_t)size))
+        if (!pb_encode_varint(stream, (pb_uint64_t)size))
             return false;
         
         if (stream->callback == NULL)
@@ -181,7 +196,7 @@
                  PB_LTYPE(field->type) == PB_LTYPE_BYTES))
             {
                 if (!func(stream, field, *(const void* const*)p))
-                    return false;      
+                    return false;
             }
             else
             {
@@ -195,21 +210,124 @@
     return true;
 }
 
+/* In proto3, all fields are optional and are only encoded if their value is "non-zero".
+ * This function implements the check for the zero value. */
+static bool pb_check_proto3_default_value(const pb_field_t *field, const void *pData)
+{
+    pb_type_t type = field->type;
+    const void *pSize = (const char*)pData + field->size_offset;
+
+    if (PB_HTYPE(type) == PB_HTYPE_REQUIRED)
+    {
+        /* Required proto2 fields inside proto3 submessage, pretty rare case */
+        return false;
+    }
+    else if (PB_HTYPE(type) == PB_HTYPE_REPEATED)
+    {
+        /* Repeated fields inside proto3 submessage: present if count != 0 */
+        return *(const pb_size_t*)pSize == 0;
+    }
+    else if (PB_HTYPE(type) == PB_HTYPE_ONEOF)
+    {
+        /* Oneof fields */
+        return *(const pb_size_t*)pSize == 0;
+    }
+    else if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->size_offset)
+    {
+        /* Proto2 optional fields inside proto3 submessage */
+        return *(const bool*)pSize == false;
+    }
+
+    /* Rest is proto3 singular fields */
+
+    if (PB_ATYPE(type) == PB_ATYPE_STATIC)
+    {
+        if (PB_LTYPE(type) == PB_LTYPE_BYTES)
+        {
+            const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)pData;
+            return bytes->size == 0;
+        }
+        else if (PB_LTYPE(type) == PB_LTYPE_STRING)
+        {
+            return *(const char*)pData == '\0';
+        }
+        else if (PB_LTYPE(type) == PB_LTYPE_FIXED_LENGTH_BYTES)
+        {
+            /* Fixed length bytes is only empty if its length is fixed
+             * as 0. Which would be pretty strange, but we can check
+             * it anyway. */
+            return field->data_size == 0;
+        }
+        else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE)
+        {
+            /* Check all fields in the submessage to find if any of them
+             * are non-zero. The comparison cannot be done byte-per-byte
+             * because the C struct may contain padding bytes that must
+             * be skipped.
+             */
+            pb_field_iter_t iter;
+            if (pb_field_iter_begin(&iter, (const pb_field_t*)field->ptr, pb_const_cast(pData)))
+            {
+                do
+                {
+                    if (!pb_check_proto3_default_value(iter.pos, iter.pData))
+                    {
+                        return false;
+                    }
+                } while (pb_field_iter_next(&iter));
+            }
+            return true;
+        }
+    }
+    
+	{
+	    /* Catch-all branch that does byte-per-byte comparison for zero value.
+	     *
+	     * This is for all pointer fields, and for static PB_LTYPE_VARINT,
+	     * UVARINT, SVARINT, FIXED32, FIXED64, EXTENSION fields, and also
+	     * callback fields. These all have integer or pointer value which
+	     * can be compared with 0.
+	     */
+	    pb_size_t i;
+	    const char *p = (const char*)pData;
+	    for (i = 0; i < field->data_size; i++)
+	    {
+	        if (p[i] != 0)
+	        {
+	            return false;
+	        }
+	    }
+
+	    return true;
+	}
+}
+
 /* Encode a field with static or pointer allocation, i.e. one whose data
  * is available to the encoder directly. */
 static bool checkreturn encode_basic_field(pb_ostream_t *stream,
     const pb_field_t *field, const void *pData)
 {
     pb_encoder_t func;
-    const void *pSize;
-    bool implicit_has = true;
+    bool implicit_has;
+    const void *pSize = &implicit_has;
     
     func = PB_ENCODERS[PB_LTYPE(field->type)];
     
     if (field->size_offset)
+    {
+        /* Static optional, repeated or oneof field */
         pSize = (const char*)pData + field->size_offset;
+    }
+    else if (PB_HTYPE(field->type) == PB_HTYPE_OPTIONAL)
+    {
+        /* Proto3 style field, optional but without explicit has_ field. */
+        implicit_has = !pb_check_proto3_default_value(field, pData);
+    }
     else
-        pSize = &implicit_has;
+    {
+        /* Required field, always present */
+        implicit_has = true;
+    }
 
     if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
     {
@@ -217,7 +335,6 @@
          * the data. If the 2nd pointer is NULL, it is interpreted as if
          * the has_field was false.
          */
-        
         pData = *(const void* const*)pData;
         implicit_has = (pData != NULL);
     }
@@ -244,11 +361,29 @@
             }
             break;
         
-        case PB_HTYPE_REPEATED:
-            if (!encode_array(stream, field, pData, *(const size_t*)pSize, func))
+        case PB_HTYPE_REPEATED: {
+            pb_size_t count;
+            if (field->size_offset != 0) {
+                count = *(const pb_size_t*)pSize;
+            } else {
+                count = field->array_size;
+            }
+            if (!encode_array(stream, field, pData, count, func))
                 return false;
             break;
+        }
         
+        case PB_HTYPE_ONEOF:
+            if (*(const pb_size_t*)pSize == field->tag)
+            {
+                if (!pb_encode_tag_for_field(stream, field))
+                    return false;
+
+                if (!func(stream, field, pData))
+                    return false;
+            }
+            break;
+            
         default:
             PB_RETURN_ERROR(stream, "invalid field type");
     }
@@ -301,7 +436,18 @@
     const pb_extension_t *extension)
 {
     const pb_field_t *field = (const pb_field_t*)extension->type->arg;
-    return encode_field(stream, field, extension->dest);
+    
+    if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
+    {
+        /* For pointer extensions, the pointer is stored directly
+         * in the extension structure. This avoids having an extra
+         * indirection. */
+        return encode_field(stream, field, &extension->dest);
+    }
+    else
+    {
+        return encode_field(stream, field, extension->dest);
+    }
 }
 
 /* Walk through all the registered extensions and give them a chance
@@ -310,7 +456,7 @@
     const pb_field_t *field, const void *pData)
 {
     const pb_extension_t *extension = *(const pb_extension_t* const *)pData;
-    UNUSED(field);
+    PB_UNUSED(field);
     
     while (extension)
     {
@@ -333,42 +479,38 @@
  * Encode all fields *
  *********************/
 
+static void *pb_const_cast(const void *p)
+{
+    /* Note: this casts away const, in order to use the common field iterator
+     * logic for both encoding and decoding. */
+    union {
+        void *p1;
+        const void *p2;
+    } t;
+    t.p2 = p;
+    return t.p1;
+}
+
 bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
 {
-    const pb_field_t *field = fields;
-    const void *pData = src_struct;
-    size_t prev_size = 0;
+    pb_field_iter_t iter;
+    if (!pb_field_iter_begin(&iter, fields, pb_const_cast(src_struct)))
+        return true; /* Empty message type */
     
-    while (field->tag != 0)
-    {
-        pData = (const char*)pData + prev_size + field->data_offset;
-        if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
-            prev_size = sizeof(const void*);
-        else
-            prev_size = field->data_size;
-        
-        /* Special case for static arrays */
-        if (PB_ATYPE(field->type) == PB_ATYPE_STATIC &&
-            PB_HTYPE(field->type) == PB_HTYPE_REPEATED)
-        {
-            prev_size *= field->array_size;
-        }
-        
-        if (PB_LTYPE(field->type) == PB_LTYPE_EXTENSION)
+    do {
+        if (PB_LTYPE(iter.pos->type) == PB_LTYPE_EXTENSION)
         {
             /* Special case for the extension field placeholder */
-            if (!encode_extension_field(stream, field, pData))
+            if (!encode_extension_field(stream, iter.pos, iter.pData))
                 return false;
         }
         else
         {
             /* Regular field */
-            if (!encode_field(stream, field, pData))
+            if (!encode_field(stream, iter.pos, iter.pData))
                 return false;
         }
-    
-        field++;
-    }
+    } while (pb_field_iter_next(&iter));
     
     return true;
 }
@@ -378,6 +520,16 @@
     return pb_encode_submessage(stream, fields, src_struct);
 }
 
+bool pb_encode_nullterminated(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct)
+{
+    const pb_byte_t zero = 0;
+
+    if (!pb_encode(stream, fields, src_struct))
+        return false;
+
+    return pb_write(stream, &zero, 1);
+}
+
 bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct)
 {
     pb_ostream_t stream = PB_OSTREAM_SIZING;
@@ -392,17 +544,47 @@
 /********************
  * Helper functions *
  ********************/
-bool checkreturn pb_encode_varint(pb_ostream_t *stream, uint64_t value)
+
+#ifdef PB_WITHOUT_64BIT
+bool checkreturn pb_encode_negative_varint(pb_ostream_t *stream, pb_uint64_t value)
 {
-    uint8_t buffer[10];
+  pb_byte_t buffer[10];
+  size_t i = 0;
+  size_t compensation = 32;/* we need to compensate 32 bits all set to 1 */
+
+  while (value)
+  {
+    buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80);
+    value >>= 7;
+    if (compensation)
+    {
+      /* re-set all the compensation bits we can or need */
+      size_t bits = compensation > 7 ? 7 : compensation;
+      value ^= (pb_uint64_t)((0xFFu >> (8 - bits)) << 25); /* set the number of bits needed on the lowest of the most significant 7 bits */
+      compensation -= bits;
+    }
+    i++;
+  }
+  buffer[i - 1] &= 0x7F; /* Unset top bit on last byte */
+
+  return pb_write(stream, buffer, i);
+}
+#endif
+
+bool checkreturn pb_encode_varint(pb_ostream_t *stream, pb_uint64_t value)
+{
+    pb_byte_t buffer[10];
     size_t i = 0;
     
-    if (value == 0)
-        return pb_write(stream, (uint8_t*)&value, 1);
+    if (value <= 0x7F)
+    {
+        pb_byte_t v = (pb_byte_t)value;
+        return pb_write(stream, &v, 1);
+    }
     
     while (value)
     {
-        buffer[i] = (uint8_t)((value & 0x7F) | 0x80);
+        buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80);
         value >>= 7;
         i++;
     }
@@ -411,54 +593,48 @@
     return pb_write(stream, buffer, i);
 }
 
-bool checkreturn pb_encode_svarint(pb_ostream_t *stream, int64_t value)
+bool checkreturn pb_encode_svarint(pb_ostream_t *stream, pb_int64_t value)
 {
-    uint64_t zigzagged;
+    pb_uint64_t zigzagged;
     if (value < 0)
-        zigzagged = ~((uint64_t)value << 1);
+        zigzagged = ~((pb_uint64_t)value << 1);
     else
-        zigzagged = (uint64_t)value << 1;
+        zigzagged = (pb_uint64_t)value << 1;
     
     return pb_encode_varint(stream, zigzagged);
 }
 
 bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value)
 {
-    #ifdef __BIG_ENDIAN__
-    const uint8_t *bytes = value;
-    uint8_t lebytes[4];
-    lebytes[0] = bytes[3];
-    lebytes[1] = bytes[2];
-    lebytes[2] = bytes[1];
-    lebytes[3] = bytes[0];
-    return pb_write(stream, lebytes, 4);
-    #else
-    return pb_write(stream, (const uint8_t*)value, 4);
-    #endif
+    uint32_t val = *(const uint32_t*)value;
+    pb_byte_t bytes[4];
+    bytes[0] = (pb_byte_t)(val & 0xFF);
+    bytes[1] = (pb_byte_t)((val >> 8) & 0xFF);
+    bytes[2] = (pb_byte_t)((val >> 16) & 0xFF);
+    bytes[3] = (pb_byte_t)((val >> 24) & 0xFF);
+    return pb_write(stream, bytes, 4);
 }
 
+#ifndef PB_WITHOUT_64BIT
 bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value)
 {
-    #ifdef __BIG_ENDIAN__
-    const uint8_t *bytes = value;
-    uint8_t lebytes[8];
-    lebytes[0] = bytes[7];
-    lebytes[1] = bytes[6];
-    lebytes[2] = bytes[5];
-    lebytes[3] = bytes[4];
-    lebytes[4] = bytes[3];
-    lebytes[5] = bytes[2];
-    lebytes[6] = bytes[1];
-    lebytes[7] = bytes[0];
-    return pb_write(stream, lebytes, 8);
-    #else
-    return pb_write(stream, (const uint8_t*)value, 8);
-    #endif
+    uint64_t val = *(const uint64_t*)value;
+    pb_byte_t bytes[8];
+    bytes[0] = (pb_byte_t)(val & 0xFF);
+    bytes[1] = (pb_byte_t)((val >> 8) & 0xFF);
+    bytes[2] = (pb_byte_t)((val >> 16) & 0xFF);
+    bytes[3] = (pb_byte_t)((val >> 24) & 0xFF);
+    bytes[4] = (pb_byte_t)((val >> 32) & 0xFF);
+    bytes[5] = (pb_byte_t)((val >> 40) & 0xFF);
+    bytes[6] = (pb_byte_t)((val >> 48) & 0xFF);
+    bytes[7] = (pb_byte_t)((val >> 56) & 0xFF);
+    return pb_write(stream, bytes, 8);
 }
+#endif
 
 bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number)
 {
-    uint64_t tag = ((uint64_t)field_number << 3) | wiretype;
+    pb_uint64_t tag = ((pb_uint64_t)field_number << 3) | wiretype;
     return pb_encode_varint(stream, tag);
 }
 
@@ -484,6 +660,7 @@
         case PB_LTYPE_BYTES:
         case PB_LTYPE_STRING:
         case PB_LTYPE_SUBMESSAGE:
+        case PB_LTYPE_FIXED_LENGTH_BYTES:
             wiretype = PB_WT_STRING;
             break;
         
@@ -494,9 +671,9 @@
     return pb_encode_tag(stream, wiretype, field->tag);
 }
 
-bool checkreturn pb_encode_string(pb_ostream_t *stream, const uint8_t *buffer, size_t size)
+bool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size)
 {
-    if (!pb_encode_varint(stream, (uint64_t)size))
+    if (!pb_encode_varint(stream, (pb_uint64_t)size))
         return false;
     
     return pb_write(stream, buffer, size);
@@ -519,7 +696,7 @@
     
     size = substream.bytes_written;
     
-    if (!pb_encode_varint(stream, (uint64_t)size))
+    if (!pb_encode_varint(stream, (pb_uint64_t)size))
         return false;
     
     if (stream->callback == NULL)
@@ -556,69 +733,89 @@
 
 static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
 {
-    int64_t value = 0;
+    pb_int64_t value = 0;
     
-    /* Cases 1 and 2 are for compilers that have smaller types for bool
-     * or enums. */
-    switch (field->data_size)
-    {
-        case 1: value = *(const int8_t*)src; break;
-        case 2: value = *(const int16_t*)src; break;
-        case 4: value = *(const int32_t*)src; break;
-        case 8: value = *(const int64_t*)src; break;
-        default: PB_RETURN_ERROR(stream, "invalid data_size");
-    }
+    if (field->data_size == sizeof(int_least8_t))
+        value = *(const int_least8_t*)src;
+    else if (field->data_size == sizeof(int_least16_t))
+        value = *(const int_least16_t*)src;
+    else if (field->data_size == sizeof(int32_t))
+        value = *(const int32_t*)src;
+    else if (field->data_size == sizeof(pb_int64_t))
+        value = *(const pb_int64_t*)src;
+    else
+        PB_RETURN_ERROR(stream, "invalid data_size");
     
-    return pb_encode_varint(stream, (uint64_t)value);
+#ifdef PB_WITHOUT_64BIT
+    if (value < 0)
+      return pb_encode_negative_varint(stream, (pb_uint64_t)value);
+    else
+#endif
+      return pb_encode_varint(stream, (pb_uint64_t)value);
 }
 
 static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
 {
-    uint64_t value = 0;
+    pb_uint64_t value = 0;
     
-    switch (field->data_size)
-    {
-        case 4: value = *(const uint32_t*)src; break;
-        case 8: value = *(const uint64_t*)src; break;
-        default: PB_RETURN_ERROR(stream, "invalid data_size");
-    }
+    if (field->data_size == sizeof(uint_least8_t))
+        value = *(const uint_least8_t*)src;
+    else if (field->data_size == sizeof(uint_least16_t))
+        value = *(const uint_least16_t*)src;
+    else if (field->data_size == sizeof(uint32_t))
+        value = *(const uint32_t*)src;
+    else if (field->data_size == sizeof(pb_uint64_t))
+        value = *(const pb_uint64_t*)src;
+    else
+        PB_RETURN_ERROR(stream, "invalid data_size");
     
     return pb_encode_varint(stream, value);
 }
 
 static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
 {
-    int64_t value = 0;
+    pb_int64_t value = 0;
     
-    switch (field->data_size)
-    {
-        case 4: value = *(const int32_t*)src; break;
-        case 8: value = *(const int64_t*)src; break;
-        default: PB_RETURN_ERROR(stream, "invalid data_size");
-    }
+    if (field->data_size == sizeof(int_least8_t))
+        value = *(const int_least8_t*)src;
+    else if (field->data_size == sizeof(int_least16_t))
+        value = *(const int_least16_t*)src;
+    else if (field->data_size == sizeof(int32_t))
+        value = *(const int32_t*)src;
+    else if (field->data_size == sizeof(pb_int64_t))
+        value = *(const pb_int64_t*)src;
+    else
+        PB_RETURN_ERROR(stream, "invalid data_size");
     
     return pb_encode_svarint(stream, value);
 }
 
 static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src)
 {
-    UNUSED(field);
+    PB_UNUSED(field);
+#ifndef PB_WITHOUT_64BIT
     return pb_encode_fixed64(stream, src);
+#else
+    PB_UNUSED(src);
+    PB_RETURN_ERROR(stream, "no 64bit support");
+#endif
 }
 
 static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src)
 {
-    UNUSED(field);
+    PB_UNUSED(field);
     return pb_encode_fixed32(stream, src);
 }
 
 static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src)
 {
-    const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)src;
+    const pb_bytes_array_t *bytes = NULL;
+
+    bytes = (const pb_bytes_array_t*)src;
     
     if (src == NULL)
     {
-        /* Threat null pointer as an empty bytes field */
+        /* Treat null pointer as an empty bytes field */
         return pb_encode_string(stream, NULL, 0);
     }
     
@@ -633,7 +830,6 @@
 
 static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src)
 {
-    /* strnlen() is not always available, so just use a loop */
     size_t size = 0;
     size_t max_size = field->data_size;
     const char *p = (const char*)src;
@@ -643,10 +839,11 @@
 
     if (src == NULL)
     {
-        size = 0; /* Threat null pointer as an empty string */
+        size = 0; /* Treat null pointer as an empty string */
     }
     else
     {
+        /* strnlen() is not always available, so just use a loop */
         while (size < max_size && *p != '\0')
         {
             size++;
@@ -654,7 +851,7 @@
         }
     }
 
-    return pb_encode_string(stream, (const uint8_t*)src, size);
+    return pb_encode_string(stream, (const pb_byte_t*)src, size);
 }
 
 static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src)
@@ -665,3 +862,8 @@
     return pb_encode_submessage(stream, (const pb_field_t*)field->ptr, src);
 }
 
+static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src)
+{
+    return pb_encode_string(stream, (const pb_byte_t*)src, field->data_size);
+}
+
diff --git a/pb_encode.h b/pb_encode.h
index f82bac8..8bf78dd 100644
--- a/pb_encode.h
+++ b/pb_encode.h
@@ -3,8 +3,8 @@
  * field descriptions created by nanopb_generator.py.
  */
 
-#ifndef _PB_ENCODE_H_
-#define _PB_ENCODE_H_
+#ifndef PB_ENCODE_H_INCLUDED
+#define PB_ENCODE_H_INCLUDED
 
 #include "pb.h"
 
@@ -24,7 +24,7 @@
  * 4) Substreams will modify max_size and bytes_written. Don't use them
  *    to calculate any pointers.
  */
-struct _pb_ostream_t
+struct pb_ostream_s
 {
 #ifdef PB_BUFFER_ONLY
     /* Callback pointer is not used in buffer-only configuration.
@@ -35,7 +35,7 @@
      */
     int *callback;
 #else
-    bool (*callback)(pb_ostream_t *stream, const uint8_t *buf, size_t count);
+    bool (*callback)(pb_ostream_t *stream, const pb_byte_t *buf, size_t count);
 #endif
     void *state;          /* Free field for use by callback implementation. */
     size_t max_size;      /* Limit number of output bytes written (or use SIZE_MAX). */
@@ -71,6 +71,12 @@
  */
 bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
 
+/* Same as pb_encode, but appends a null byte to the message for termination.
+ * NOTE: This behaviour is not supported in most other protobuf implementations, so pb_encode_delimited()
+ * is a better option for compatibility.
+ */
+bool pb_encode_nullterminated(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct);
+
 /* Encode the message to get the size of the encoded data, but do not store
  * the data. */
 bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct);
@@ -86,7 +92,7 @@
  * Alternatively, you can use a custom stream that writes directly to e.g.
  * a file or a network socket.
  */
-pb_ostream_t pb_ostream_from_buffer(uint8_t *buf, size_t bufsize);
+pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize);
 
 /* Pseudo-stream for measuring the size of a message without actually storing
  * the encoded data.
@@ -106,7 +112,7 @@
 /* Function to write into a pb_ostream_t stream. You can use this if you need
  * to append or prepend some custom headers to the message.
  */
-bool pb_write(pb_ostream_t *stream, const uint8_t *buf, size_t count);
+bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count);
 
 
 /************************************************
@@ -123,22 +129,32 @@
 
 /* Encode an integer in the varint format.
  * This works for bool, enum, int32, int64, uint32 and uint64 field types. */
+#ifndef PB_WITHOUT_64BIT
 bool pb_encode_varint(pb_ostream_t *stream, uint64_t value);
+#else
+bool pb_encode_varint(pb_ostream_t *stream, uint32_t value);
+#endif
 
 /* Encode an integer in the zig-zagged svarint format.
  * This works for sint32 and sint64. */
+#ifndef PB_WITHOUT_64BIT
 bool pb_encode_svarint(pb_ostream_t *stream, int64_t value);
+#else
+bool pb_encode_svarint(pb_ostream_t *stream, int32_t value);
+#endif
 
 /* Encode a string or bytes type field. For strings, pass strlen(s) as size. */
-bool pb_encode_string(pb_ostream_t *stream, const uint8_t *buffer, size_t size);
+bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size);
 
 /* Encode a fixed32, sfixed32 or float value.
  * You need to pass a pointer to a 4-byte wide C variable. */
 bool pb_encode_fixed32(pb_ostream_t *stream, const void *value);
 
+#ifndef PB_WITHOUT_64BIT
 /* Encode a fixed64, sfixed64 or double value.
  * You need to pass a pointer to a 8-byte wide C variable. */
 bool pb_encode_fixed64(pb_ostream_t *stream, const void *value);
+#endif
 
 /* Encode a submessage field.
  * You need to pass the pb_field_t array and pointer to struct, just like
diff --git a/tests/Makefile b/tests/Makefile
index 3c4e0b0..cee6bf6 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -10,12 +10,12 @@
 	# LCOV does not like the newer gcov format
 	scons CC=gcc-4.6 CXX=gcc-4.6
 
-	# We are only interested in pb_encode.o and pb_decode.o
-	find build -name '*.gcda' -and \! \( -name '*pb_encode*' -or -name '*pb_decode*' \) -exec rm '{}' \;
-
 	# Collect the data
 	mkdir build/coverage
 	lcov --base-directory . --directory build/ --gcov-tool gcov-4.6 -c -o build/coverage/nanopb.info
 
+	# Remove the test code from results
+	lcov -r build/coverage/nanopb.info '*tests*' -o build/coverage/nanopb.info
+
 	# Generate HTML
 	genhtml -o build/coverage build/coverage/nanopb.info
diff --git a/tests/SConstruct b/tests/SConstruct
index 7a27844..f998024 100644
--- a/tests/SConstruct
+++ b/tests/SConstruct
@@ -57,6 +57,7 @@
     if not stdbool or not stdint or not stddef or not string:
         conf.env.Append(CPPDEFINES = {'PB_SYSTEM_HEADER': '\\"pb_syshdr.h\\"'})
         conf.env.Append(CPPPATH = "#../extra")
+        conf.env.Append(SYSHDR = '\\"pb_syshdr.h\\"')
         
         if stdbool: conf.env.Append(CPPDEFINES = {'HAVE_STDBOOL_H': 1})
         if stdint: conf.env.Append(CPPDEFINES = {'HAVE_STDINT_H': 1})
@@ -71,6 +72,11 @@
     else:
         conf.env.Append(PROTOCPATH = '/usr/include')
     
+    # Check protoc version
+    status, output = conf.TryAction('$PROTOC --version > $TARGET')
+    if status:
+        conf.env['PROTOC_VERSION'] = output
+
     # Check if libmudflap is available (only with GCC)
     if 'gcc' in env['CC']:
         if conf.CheckLib('mudflap'):
@@ -87,7 +93,9 @@
             conf.env.Append(CORECFLAGS = extra)
     
     # Check if we can use undefined behaviour sanitizer (only with clang)
-    extra = '-fsanitize=undefined '
+    # TODO: Fuzz test triggers the bool sanitizer, figure out whether to
+    #       modify the fuzz test or to keep ignoring the check.
+    extra = '-fsanitize=undefined,integer -fno-sanitize-recover=undefined,integer -fsanitize-recover=bool '
     if 'clang' in env['CC']:
         if conf.CheckCCFLAGS(extra, linkflags = extra):
             conf.env.Append(CORECFLAGS = extra)
@@ -101,7 +109,7 @@
     # GNU Compiler Collection
     
     # Debug info, warnings as errors
-    env.Append(CFLAGS = '-ansi -pedantic -g -Wall -Werror -fprofile-arcs -ftest-coverage -fstack-protector-all')
+    env.Append(CFLAGS = '-ansi -pedantic -g -Wall -Werror -fprofile-arcs -ftest-coverage ')
     env.Append(CORECFLAGS = '-Wextra')
     env.Append(LINKFLAGS = '-g --coverage')
     
@@ -120,9 +128,6 @@
     
     # More strict checks on the nanopb core
     env.Append(CORECFLAGS = '/W4')
-    
-    # PB_RETURN_ERROR triggers C4127 because of while(0)
-    env.Append(CFLAGS = '/wd4127')
 elif 'tcc' in env['CC']:
     # Tiny C Compiler
     env.Append(CFLAGS = '-Wall -Werror -g')
@@ -135,12 +140,18 @@
     env.Append(CXXFLAGS = '-g -Wall -Werror -Wextra -Wno-missing-field-initializers')
 elif 'cl' in env['CXX']:
     env.Append(CXXFLAGS = '/Zi /W2 /WX')
-    
+
 # Now include the SConscript files from all subdirectories
 import os.path
 env['VARIANT_DIR'] = 'build'
 env['BUILD'] = '#' + env['VARIANT_DIR']
 env['COMMON'] = '#' + env['VARIANT_DIR'] + '/common'
-for subdir in Glob('*/SConscript'):
+
+# Include common/SConscript first to make sure its exports are available
+# to other SConscripts.
+SConscript("common/SConscript", exports = 'env', variant_dir = env['VARIANT_DIR'] + '/common')
+
+for subdir in Glob('*/SConscript') + Glob('regression/*/SConscript'):
+    if str(subdir).startswith("common"): continue
     SConscript(subdir, exports = 'env', variant_dir = env['VARIANT_DIR'] + '/' + os.path.dirname(str(subdir)))
 
diff --git a/tests/alltypes/SConscript b/tests/alltypes/SConscript
index 9c9072b..13acd4e 100644
--- a/tests/alltypes/SConscript
+++ b/tests/alltypes/SConscript
@@ -4,8 +4,8 @@
 Import("env")
 
 env.NanopbProto(["alltypes", "alltypes.options"])
-enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o"])
-dec = env.Program(["decode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_decode.o"])
+enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = env.Program(["decode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 # Test the round-trip from nanopb encoder to nanopb decoder
 env.RunTest(enc)
@@ -32,4 +32,14 @@
            MESSAGE='AllTypes')
 env.Compare(["optionals.output", "optionals.output.recoded"])
 
+# And for the _zero initializer
+env.RunTest("zeroinit.output", enc, ARGS = ['2'])
+env.RunTest("zeroinit.decout", [dec, "zeroinit.output"], ARGS = ['2'])
+env.Decode("zeroinit.output.decoded",
+           ["zeroinit.output", "alltypes.proto"],
+           MESSAGE='AllTypes')
+env.Encode("zeroinit.output.recoded",
+           ["zeroinit.output.decoded", "alltypes.proto"],
+           MESSAGE='AllTypes')
+env.Compare(["zeroinit.output", "zeroinit.output.recoded"])
 
diff --git a/tests/alltypes/alltypes.options b/tests/alltypes/alltypes.options
index b31e3cf..0d5ab12 100644
--- a/tests/alltypes/alltypes.options
+++ b/tests/alltypes/alltypes.options
@@ -1,3 +1,3 @@
 * max_size:16
 * max_count:5
-
+*.*fbytes fixed_length:true max_size:4
diff --git a/tests/alltypes/alltypes.proto b/tests/alltypes/alltypes.proto
index db83c9a..2377180 100644
--- a/tests/alltypes/alltypes.proto
+++ b/tests/alltypes/alltypes.proto
@@ -1,3 +1,6 @@
+syntax = "proto2";
+// package name placeholder
+
 message SubMessage {
     required string substuff1 = 1 [default = "1"];
     required int32 substuff2 = 2 [default = 2];
@@ -55,7 +58,7 @@
     required SubMessage req_submsg  = 16;
     required MyEnum     req_enum    = 17;
     required EmptyMessage req_emptymsg = 18;
-    
+    required bytes      req_fbytes  = 19;
     
     repeated int32      rep_int32   = 21 [packed = true];
     repeated int64      rep_int64   = 22 [packed = true];
@@ -78,6 +81,7 @@
     repeated SubMessage rep_submsg  = 36;
     repeated MyEnum     rep_enum    = 37 [packed = true];
     repeated EmptyMessage rep_emptymsg = 38;
+    repeated bytes      rep_fbytes  = 39;
     
     optional int32      opt_int32   = 41 [default = 4041];
     optional int64      opt_int64   = 42 [default = 4042];
@@ -96,11 +100,18 @@
     optional double     opt_double  = 53 [default = 4053];
     
     optional string     opt_string  = 54 [default = "4054"];
-    optional bytes      opt_bytes   = 55 [default = "4055"];
+    optional bytes      opt_bytes   = 55 [default = "\x34\x5C\x00\xff"];
     optional SubMessage opt_submsg  = 56;
     optional MyEnum     opt_enum    = 57 [default = Second];
     optional EmptyMessage opt_emptymsg = 58;
+    optional bytes      opt_fbytes  = 59 [default = "4059"];
 
+    oneof oneof
+    {
+        SubMessage oneof_msg1 = 60;
+        EmptyMessage oneof_msg2 = 61;
+    }
+    
     // Check that extreme integer values are handled correctly
     required Limits     req_limits = 98;
 
diff --git a/tests/alltypes/decode_alltypes.c b/tests/alltypes/decode_alltypes.c
index db72bb9..b74121f 100644
--- a/tests/alltypes/decode_alltypes.c
+++ b/tests/alltypes/decode_alltypes.c
@@ -19,65 +19,85 @@
    the decoding and checks the fields. */
 bool check_alltypes(pb_istream_t *stream, int mode)
 {
-    AllTypes alltypes;
+    /* Uses _init_default to just make sure that it works. */
+    AllTypes alltypes = AllTypes_init_default;
     
     /* Fill with garbage to better detect initialization errors */
     memset(&alltypes, 0xAA, sizeof(alltypes));
+    alltypes.extensions = 0;
     
     if (!pb_decode(stream, AllTypes_fields, &alltypes))
         return false;
     
-    TEST(alltypes.req_int32         == -1001);
-    TEST(alltypes.req_int64         == -1002);
-    TEST(alltypes.req_uint32        == 1003);
-    TEST(alltypes.req_uint64        == 1004);
-    TEST(alltypes.req_sint32        == -1005);
-    TEST(alltypes.req_sint64        == -1006);
-    TEST(alltypes.req_bool          == true);
-    
-    TEST(alltypes.req_fixed32       == 1008);
-    TEST(alltypes.req_sfixed32      == -1009);
-    TEST(alltypes.req_float         == 1010.0f);
-    
-    TEST(alltypes.req_fixed64       == 1011);
-    TEST(alltypes.req_sfixed64      == -1012);
-    TEST(alltypes.req_double        == 1013.0f);
-    
-    TEST(strcmp(alltypes.req_string, "1014") == 0);
-    TEST(alltypes.req_bytes.size == 4);
-    TEST(memcmp(alltypes.req_bytes.bytes, "1015", 4) == 0);
-    TEST(strcmp(alltypes.req_submsg.substuff1, "1016") == 0);
-    TEST(alltypes.req_submsg.substuff2 == 1016);
-    TEST(alltypes.req_submsg.substuff3 == 3);
-    TEST(alltypes.req_enum == MyEnum_Truth);
-    
-    TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0);
-    TEST(alltypes.rep_int64_count == 5 && alltypes.rep_int64[4] == -2002 && alltypes.rep_int64[0] == 0);
-    TEST(alltypes.rep_uint32_count == 5 && alltypes.rep_uint32[4] == 2003 && alltypes.rep_uint32[0] == 0);
-    TEST(alltypes.rep_uint64_count == 5 && alltypes.rep_uint64[4] == 2004 && alltypes.rep_uint64[0] == 0);
-    TEST(alltypes.rep_sint32_count == 5 && alltypes.rep_sint32[4] == -2005 && alltypes.rep_sint32[0] == 0);
-    TEST(alltypes.rep_sint64_count == 5 && alltypes.rep_sint64[4] == -2006 && alltypes.rep_sint64[0] == 0);
-    TEST(alltypes.rep_bool_count == 5 && alltypes.rep_bool[4] == true && alltypes.rep_bool[0] == false);
-    
-    TEST(alltypes.rep_fixed32_count == 5 && alltypes.rep_fixed32[4] == 2008 && alltypes.rep_fixed32[0] == 0);
-    TEST(alltypes.rep_sfixed32_count == 5 && alltypes.rep_sfixed32[4] == -2009 && alltypes.rep_sfixed32[0] == 0);
-    TEST(alltypes.rep_float_count == 5 && alltypes.rep_float[4] == 2010.0f && alltypes.rep_float[0] == 0.0f);
-    
-    TEST(alltypes.rep_fixed64_count == 5 && alltypes.rep_fixed64[4] == 2011 && alltypes.rep_fixed64[0] == 0);
-    TEST(alltypes.rep_sfixed64_count == 5 && alltypes.rep_sfixed64[4] == -2012 && alltypes.rep_sfixed64[0] == 0);
-    TEST(alltypes.rep_double_count == 5 && alltypes.rep_double[4] == 2013.0 && alltypes.rep_double[0] == 0.0);
-    
-    TEST(alltypes.rep_string_count == 5 && strcmp(alltypes.rep_string[4], "2014") == 0 && alltypes.rep_string[0][0] == '\0');
-    TEST(alltypes.rep_bytes_count == 5 && alltypes.rep_bytes[4].size == 4 && alltypes.rep_bytes[0].size == 0);
-    TEST(memcmp(alltypes.rep_bytes[4].bytes, "2015", 4) == 0);
+    if (mode == 0 || mode == 1)
+    {
+        TEST(alltypes.req_int32         == -1001);
+        TEST(alltypes.req_int64         == -1002);
+        TEST(alltypes.req_uint32        == 1003);
+        TEST(alltypes.req_uint64        == 1004);
+        TEST(alltypes.req_sint32        == -1005);
+        TEST(alltypes.req_sint64        == -1006);
+        TEST(alltypes.req_bool          == true);
+        
+        TEST(alltypes.req_fixed32       == 1008);
+        TEST(alltypes.req_sfixed32      == -1009);
+        TEST(alltypes.req_float         == 1010.0f);
+        
+        TEST(alltypes.req_fixed64       == 1011);
+        TEST(alltypes.req_sfixed64      == -1012);
+        TEST(alltypes.req_double        == 1013.0f);
+        
+        TEST(strcmp(alltypes.req_string, "1014") == 0);
+        TEST(alltypes.req_bytes.size == 4);
+        TEST(memcmp(alltypes.req_bytes.bytes, "1015", 4) == 0);
+        TEST(strcmp(alltypes.req_submsg.substuff1, "1016") == 0);
+        TEST(alltypes.req_submsg.substuff2 == 1016);
+        TEST(alltypes.req_submsg.substuff3 == 3);
+        TEST(alltypes.req_enum == MyEnum_Truth);
+        TEST(memcmp(alltypes.req_fbytes, "1019", 4) == 0);
+        
+        TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0);
+        TEST(alltypes.rep_int64_count == 5 && alltypes.rep_int64[4] == -2002 && alltypes.rep_int64[0] == 0);
+        TEST(alltypes.rep_uint32_count == 5 && alltypes.rep_uint32[4] == 2003 && alltypes.rep_uint32[0] == 0);
+        TEST(alltypes.rep_uint64_count == 5 && alltypes.rep_uint64[4] == 2004 && alltypes.rep_uint64[0] == 0);
+        TEST(alltypes.rep_sint32_count == 5 && alltypes.rep_sint32[4] == -2005 && alltypes.rep_sint32[0] == 0);
+        TEST(alltypes.rep_sint64_count == 5 && alltypes.rep_sint64[4] == -2006 && alltypes.rep_sint64[0] == 0);
+        TEST(alltypes.rep_bool_count == 5 && alltypes.rep_bool[4] == true && alltypes.rep_bool[0] == false);
+        
+        TEST(alltypes.rep_fixed32_count == 5 && alltypes.rep_fixed32[4] == 2008 && alltypes.rep_fixed32[0] == 0);
+        TEST(alltypes.rep_sfixed32_count == 5 && alltypes.rep_sfixed32[4] == -2009 && alltypes.rep_sfixed32[0] == 0);
+        TEST(alltypes.rep_float_count == 5 && alltypes.rep_float[4] == 2010.0f && alltypes.rep_float[0] == 0.0f);
+        
+        TEST(alltypes.rep_fixed64_count == 5 && alltypes.rep_fixed64[4] == 2011 && alltypes.rep_fixed64[0] == 0);
+        TEST(alltypes.rep_sfixed64_count == 5 && alltypes.rep_sfixed64[4] == -2012 && alltypes.rep_sfixed64[0] == 0);
+        TEST(alltypes.rep_double_count == 5 && alltypes.rep_double[4] == 2013.0 && alltypes.rep_double[0] == 0.0);
+        
+        TEST(alltypes.rep_string_count == 5 && strcmp(alltypes.rep_string[4], "2014") == 0 && alltypes.rep_string[0][0] == '\0');
+        TEST(alltypes.rep_bytes_count == 5 && alltypes.rep_bytes[4].size == 4 && alltypes.rep_bytes[0].size == 0);
+        TEST(memcmp(alltypes.rep_bytes[4].bytes, "2015", 4) == 0);
 
-    TEST(alltypes.rep_submsg_count == 5);
-    TEST(strcmp(alltypes.rep_submsg[4].substuff1, "2016") == 0 && alltypes.rep_submsg[0].substuff1[0] == '\0');
-    TEST(alltypes.rep_submsg[4].substuff2 == 2016 && alltypes.rep_submsg[0].substuff2 == 0);
-    TEST(alltypes.rep_submsg[4].substuff3 == 2016 && alltypes.rep_submsg[0].substuff3 == 3);
-    
-    TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero);
-    TEST(alltypes.rep_emptymsg_count == 5);
+        TEST(alltypes.rep_submsg_count == 5);
+        TEST(strcmp(alltypes.rep_submsg[4].substuff1, "2016") == 0 && alltypes.rep_submsg[0].substuff1[0] == '\0');
+        TEST(alltypes.rep_submsg[4].substuff2 == 2016 && alltypes.rep_submsg[0].substuff2 == 0);
+        TEST(alltypes.rep_submsg[4].substuff3 == 2016 && alltypes.rep_submsg[0].substuff3 == 3);
+        
+        TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero);
+        TEST(alltypes.rep_emptymsg_count == 5);
+        TEST(alltypes.rep_fbytes_count == 5);
+        TEST(alltypes.rep_fbytes[0][0] == 0 && alltypes.rep_fbytes[0][3] == 0);
+        TEST(memcmp(alltypes.rep_fbytes[4], "2019", 4) == 0);
+
+        TEST(alltypes.req_limits.int32_min  == INT32_MIN);
+        TEST(alltypes.req_limits.int32_max  == INT32_MAX);
+        TEST(alltypes.req_limits.uint32_min == 0);
+        TEST(alltypes.req_limits.uint32_max == UINT32_MAX);
+        TEST(alltypes.req_limits.int64_min  == INT64_MIN);
+        TEST(alltypes.req_limits.int64_max  == INT64_MAX);
+        TEST(alltypes.req_limits.uint64_min == 0);
+        TEST(alltypes.req_limits.uint64_max == UINT64_MAX);
+        TEST(alltypes.req_limits.enum_min   == HugeEnum_Negative);
+        TEST(alltypes.req_limits.enum_max   == HugeEnum_Positive);
+    }
     
     if (mode == 0)
     {
@@ -115,7 +135,7 @@
         TEST(strcmp(alltypes.opt_string, "4054") == 0);
         TEST(alltypes.has_opt_bytes     == false);
         TEST(alltypes.opt_bytes.size == 4);
-        TEST(memcmp(alltypes.opt_bytes.bytes, "4055", 4) == 0);
+        TEST(memcmp(alltypes.opt_bytes.bytes, "\x34\x5C\x00\xff", 4) == 0);
         TEST(alltypes.has_opt_submsg    == false);
         TEST(strcmp(alltypes.opt_submsg.substuff1, "1") == 0);
         TEST(alltypes.opt_submsg.substuff2 == 2);
@@ -123,8 +143,12 @@
         TEST(alltypes.has_opt_enum     == false);
         TEST(alltypes.opt_enum == MyEnum_Second);
         TEST(alltypes.has_opt_emptymsg == false);
+        TEST(alltypes.has_opt_fbytes == false);
+        TEST(memcmp(alltypes.opt_fbytes, "4059", 4) == 0);
+
+        TEST(alltypes.which_oneof == 0);
     }
-    else
+    else if (mode == 1)
     {
         /* Expect filled-in values */
         TEST(alltypes.has_opt_int32     == true);
@@ -168,18 +192,88 @@
         TEST(alltypes.has_opt_enum      == true);
         TEST(alltypes.opt_enum == MyEnum_Truth);
         TEST(alltypes.has_opt_emptymsg  == true);
+        TEST(alltypes.has_opt_fbytes == true);
+        TEST(memcmp(alltypes.opt_fbytes, "3059", 4) == 0);
+
+        TEST(alltypes.which_oneof == AllTypes_oneof_msg1_tag);
+        TEST(strcmp(alltypes.oneof.oneof_msg1.substuff1, "4059") == 0);
+        TEST(alltypes.oneof.oneof_msg1.substuff2 == 4059);
     }
+    else if (mode == 2)
+    {
+        /* Expect zero values */
+        TEST(alltypes.req_int32         == 0);
+        TEST(alltypes.req_int64         == 0);
+        TEST(alltypes.req_uint32        == 0);
+        TEST(alltypes.req_uint64        == 0);
+        TEST(alltypes.req_sint32        == 0);
+        TEST(alltypes.req_sint64        == 0);
+        TEST(alltypes.req_bool          == false);
+        
+        TEST(alltypes.req_fixed32       == 0);
+        TEST(alltypes.req_sfixed32      == 0);
+        TEST(alltypes.req_float         == 0.0f);
+        
+        TEST(alltypes.req_fixed64       == 0);
+        TEST(alltypes.req_sfixed64      == 0);
+        TEST(alltypes.req_double        == 0.0f);
+        
+        TEST(strcmp(alltypes.req_string, "") == 0);
+        TEST(alltypes.req_bytes.size == 0);
+        TEST(strcmp(alltypes.req_submsg.substuff1, "") == 0);
+        TEST(alltypes.req_submsg.substuff2 == 0);
+        TEST(alltypes.req_enum == MyEnum_Zero);
+        
+        TEST(alltypes.rep_int32_count == 0);
+        TEST(alltypes.rep_int64_count == 0);
+        TEST(alltypes.rep_uint32_count == 0);
+        TEST(alltypes.rep_uint64_count == 0);
+        TEST(alltypes.rep_sint32_count == 0);
+        TEST(alltypes.rep_sint64_count == 0);
+        TEST(alltypes.rep_bool_count == 0);
+        
+        TEST(alltypes.rep_fixed32_count == 0);
+        TEST(alltypes.rep_sfixed32_count == 0);
+        TEST(alltypes.rep_float_count == 0);
+        
+        TEST(alltypes.rep_fixed64_count == 0);
+        TEST(alltypes.rep_sfixed64_count == 0);
+        TEST(alltypes.rep_double_count == 0);
+        
+        TEST(alltypes.rep_string_count == 0);
+        TEST(alltypes.rep_bytes_count == 0);
+
+        TEST(alltypes.rep_submsg_count == 0);
+        
+        TEST(alltypes.rep_enum_count == 0);
+        TEST(alltypes.rep_emptymsg_count == 0);
+        TEST(alltypes.rep_fbytes_count == 0);
     
-    TEST(alltypes.req_limits.int32_min  == INT32_MIN);
-    TEST(alltypes.req_limits.int32_max  == INT32_MAX);
-    TEST(alltypes.req_limits.uint32_min == 0);
-    TEST(alltypes.req_limits.uint32_max == UINT32_MAX);
-    TEST(alltypes.req_limits.int64_min  == INT64_MIN);
-    TEST(alltypes.req_limits.int64_max  == INT64_MAX);
-    TEST(alltypes.req_limits.uint64_min == 0);
-    TEST(alltypes.req_limits.uint64_max == UINT64_MAX);
-    TEST(alltypes.req_limits.enum_min   == HugeEnum_Negative);
-    TEST(alltypes.req_limits.enum_max   == HugeEnum_Positive);
+        TEST(alltypes.has_opt_int32     == false);
+        TEST(alltypes.has_opt_int64     == false);
+        TEST(alltypes.has_opt_uint32    == false);
+        TEST(alltypes.has_opt_uint64    == false);
+        TEST(alltypes.has_opt_sint32    == false);
+        TEST(alltypes.has_opt_sint64    == false);
+        TEST(alltypes.has_opt_bool      == false);
+        
+        TEST(alltypes.has_opt_fixed32   == false);
+        TEST(alltypes.has_opt_sfixed32  == false);
+        TEST(alltypes.has_opt_float     == false);
+        
+        TEST(alltypes.has_opt_fixed64   == false);
+        TEST(alltypes.has_opt_sfixed64  == false);
+        TEST(alltypes.has_opt_double    == false);
+        
+        TEST(alltypes.has_opt_string    == false);
+        TEST(alltypes.has_opt_bytes     == false);
+        TEST(alltypes.has_opt_submsg    == false);
+        TEST(alltypes.has_opt_enum      == false);
+        TEST(alltypes.has_opt_emptymsg  == false);
+        TEST(alltypes.has_opt_fbytes == false);
+
+        TEST(alltypes.which_oneof == 0);
+    }
     
     TEST(alltypes.end == 1099);
     
diff --git a/tests/alltypes/encode_alltypes.c b/tests/alltypes/encode_alltypes.c
index fa8eec9..15ea7b8 100644
--- a/tests/alltypes/encode_alltypes.c
+++ b/tests/alltypes/encode_alltypes.c
@@ -13,72 +13,79 @@
     int mode = (argc > 1) ? atoi(argv[1]) : 0;
     
     /* Initialize the structure with constants */
-    AllTypes alltypes = {0};
+    AllTypes alltypes = AllTypes_init_zero;
     
-    alltypes.req_int32         = -1001;
-    alltypes.req_int64         = -1002;
-    alltypes.req_uint32        = 1003;
-    alltypes.req_uint64        = 1004;
-    alltypes.req_sint32        = -1005;
-    alltypes.req_sint64        = -1006;
-    alltypes.req_bool          = true;
-    
-    alltypes.req_fixed32       = 1008;
-    alltypes.req_sfixed32      = -1009;
-    alltypes.req_float         = 1010.0f;
-    
-    alltypes.req_fixed64       = 1011;
-    alltypes.req_sfixed64      = -1012;
-    alltypes.req_double        = 1013.0;
-    
-    strcpy(alltypes.req_string, "1014");
-    alltypes.req_bytes.size = 4;
-    memcpy(alltypes.req_bytes.bytes, "1015", 4);
-    strcpy(alltypes.req_submsg.substuff1, "1016");
-    alltypes.req_submsg.substuff2 = 1016;
-    alltypes.req_enum = MyEnum_Truth;
-    
-    alltypes.rep_int32_count = 5; alltypes.rep_int32[4] = -2001;
-    alltypes.rep_int64_count = 5; alltypes.rep_int64[4] = -2002;
-    alltypes.rep_uint32_count = 5; alltypes.rep_uint32[4] = 2003;
-    alltypes.rep_uint64_count = 5; alltypes.rep_uint64[4] = 2004;
-    alltypes.rep_sint32_count = 5; alltypes.rep_sint32[4] = -2005;
-    alltypes.rep_sint64_count = 5; alltypes.rep_sint64[4] = -2006;
-    alltypes.rep_bool_count = 5; alltypes.rep_bool[4] = true;
-    
-    alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32[4] = 2008;
-    alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32[4] = -2009;
-    alltypes.rep_float_count = 5; alltypes.rep_float[4] = 2010.0f;
-    
-    alltypes.rep_fixed64_count = 5; alltypes.rep_fixed64[4] = 2011;
-    alltypes.rep_sfixed64_count = 5; alltypes.rep_sfixed64[4] = -2012;
-    alltypes.rep_double_count = 5; alltypes.rep_double[4] = 2013.0;
-    
-    alltypes.rep_string_count = 5; strcpy(alltypes.rep_string[4], "2014");
-    alltypes.rep_bytes_count = 5; alltypes.rep_bytes[4].size = 4;
-    memcpy(alltypes.rep_bytes[4].bytes, "2015", 4);
+    if (mode == 0 || mode == 1)
+    {
+        alltypes.req_int32         = -1001;
+        alltypes.req_int64         = -1002;
+        alltypes.req_uint32        = 1003;
+        alltypes.req_uint64        = 1004;
+        alltypes.req_sint32        = -1005;
+        alltypes.req_sint64        = -1006;
+        alltypes.req_bool          = true;
+        
+        alltypes.req_fixed32       = 1008;
+        alltypes.req_sfixed32      = -1009;
+        alltypes.req_float         = 1010.0f;
+        
+        alltypes.req_fixed64       = 1011;
+        alltypes.req_sfixed64      = -1012;
+        alltypes.req_double        = 1013.0;
+        
+        strcpy(alltypes.req_string, "1014");
+        alltypes.req_bytes.size = 4;
+        memcpy(alltypes.req_bytes.bytes, "1015", 4);
+        strcpy(alltypes.req_submsg.substuff1, "1016");
+        alltypes.req_submsg.substuff2 = 1016;
+        alltypes.req_enum = MyEnum_Truth;
+        memcpy(alltypes.req_fbytes, "1019", 4);
+        
+        alltypes.rep_int32_count = 5; alltypes.rep_int32[4] = -2001;
+        alltypes.rep_int64_count = 5; alltypes.rep_int64[4] = -2002;
+        alltypes.rep_uint32_count = 5; alltypes.rep_uint32[4] = 2003;
+        alltypes.rep_uint64_count = 5; alltypes.rep_uint64[4] = 2004;
+        alltypes.rep_sint32_count = 5; alltypes.rep_sint32[4] = -2005;
+        alltypes.rep_sint64_count = 5; alltypes.rep_sint64[4] = -2006;
+        alltypes.rep_bool_count = 5; alltypes.rep_bool[4] = true;
+        
+        alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32[4] = 2008;
+        alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32[4] = -2009;
+        alltypes.rep_float_count = 5; alltypes.rep_float[4] = 2010.0f;
+        
+        alltypes.rep_fixed64_count = 5; alltypes.rep_fixed64[4] = 2011;
+        alltypes.rep_sfixed64_count = 5; alltypes.rep_sfixed64[4] = -2012;
+        alltypes.rep_double_count = 5; alltypes.rep_double[4] = 2013.0;
+        
+        alltypes.rep_string_count = 5; strcpy(alltypes.rep_string[4], "2014");
+        alltypes.rep_bytes_count = 5; alltypes.rep_bytes[4].size = 4;
+        memcpy(alltypes.rep_bytes[4].bytes, "2015", 4);
 
-    alltypes.rep_submsg_count = 5;
-    strcpy(alltypes.rep_submsg[4].substuff1, "2016");
-    alltypes.rep_submsg[4].substuff2 = 2016;
-    alltypes.rep_submsg[4].has_substuff3 = true;
-    alltypes.rep_submsg[4].substuff3 = 2016;
+        alltypes.rep_submsg_count = 5;
+        strcpy(alltypes.rep_submsg[4].substuff1, "2016");
+        alltypes.rep_submsg[4].substuff2 = 2016;
+        alltypes.rep_submsg[4].has_substuff3 = true;
+        alltypes.rep_submsg[4].substuff3 = 2016;
+        
+        alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth;
+        alltypes.rep_emptymsg_count = 5;
+        
+        alltypes.rep_fbytes_count = 5;
+        memcpy(alltypes.rep_fbytes[4], "2019", 4);
+        
+        alltypes.req_limits.int32_min  = INT32_MIN;
+        alltypes.req_limits.int32_max  = INT32_MAX;
+        alltypes.req_limits.uint32_min = 0;
+        alltypes.req_limits.uint32_max = UINT32_MAX;
+        alltypes.req_limits.int64_min  = INT64_MIN;
+        alltypes.req_limits.int64_max  = INT64_MAX;
+        alltypes.req_limits.uint64_min = 0;
+        alltypes.req_limits.uint64_max = UINT64_MAX;
+        alltypes.req_limits.enum_min   = HugeEnum_Negative;
+        alltypes.req_limits.enum_max   = HugeEnum_Positive;
+    }
     
-    alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth;
-    alltypes.rep_emptymsg_count = 5;
-    
-    alltypes.req_limits.int32_min  = INT32_MIN;
-    alltypes.req_limits.int32_max  = INT32_MAX;
-    alltypes.req_limits.uint32_min = 0;
-    alltypes.req_limits.uint32_max = UINT32_MAX;
-    alltypes.req_limits.int64_min  = INT64_MIN;
-    alltypes.req_limits.int64_max  = INT64_MAX;
-    alltypes.req_limits.uint64_min = 0;
-    alltypes.req_limits.uint64_max = UINT64_MAX;
-    alltypes.req_limits.enum_min   = HugeEnum_Negative;
-    alltypes.req_limits.enum_max   = HugeEnum_Positive;
-    
-    if (mode != 0)
+    if (mode == 1)
     {
         /* Fill in values for optional fields */
         alltypes.has_opt_int32 = true;
@@ -121,6 +128,12 @@
         alltypes.has_opt_enum = true;
         alltypes.opt_enum = MyEnum_Truth;
         alltypes.has_opt_emptymsg = true;
+        alltypes.has_opt_fbytes = true;
+        memcpy(alltypes.opt_fbytes, "3059", 4);
+
+        alltypes.which_oneof = AllTypes_oneof_msg1_tag;
+        strcpy(alltypes.oneof.oneof_msg1.substuff1, "4059");
+        alltypes.oneof.oneof_msg1.substuff2 = 4059;
     }
     
     alltypes.end = 1099;
diff --git a/tests/alltypes_callback/SConscript b/tests/alltypes_callback/SConscript
index 71b0160..8be5390 100644
--- a/tests/alltypes_callback/SConscript
+++ b/tests/alltypes_callback/SConscript
@@ -1,13 +1,13 @@
 # Test the AllTypes encoding & decoding using callbacks for all fields.
 
-Import("env")
+Import("env", "malloc_env")
 
 c = Copy("$TARGET", "$SOURCE")
 env.Command("alltypes.proto", "#alltypes/alltypes.proto", c)
 
 env.NanopbProto(["alltypes", "alltypes.options"])
-enc = env.Program(["encode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_encode.o"])
-dec = env.Program(["decode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_decode.o"])
+enc = env.Program(["encode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = env.Program(["decode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 refdec = "$BUILD/alltypes/decode_alltypes$PROGSUFFIX"
 
@@ -21,3 +21,8 @@
 env.RunTest("optionals.refdecout", [refdec, "optionals.output"], ARGS = ['1'])
 env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1'])
 
+# Try with malloc support also
+mallocbin1 = malloc_env.Object("decode_with_malloc.o", "decode_alltypes_callback.c")
+mallocbin2 = malloc_env.Object("alltypes_malloc.pb.o", "alltypes.pb.c")
+mallocdec = malloc_env.Program("decode_with_malloc", [mallocbin1, mallocbin2, "$COMMON/pb_decode_with_malloc.o", "$COMMON/pb_common_with_malloc.o", "$COMMON/malloc_wrappers.o"])
+env.RunTest("decode_with_malloc.output", [mallocdec, "encode_alltypes_callback.output"])
diff --git a/tests/alltypes_callback/alltypes.options b/tests/alltypes_callback/alltypes.options
index a9c55ec..74d7a9c 100644
--- a/tests/alltypes_callback/alltypes.options
+++ b/tests/alltypes_callback/alltypes.options
@@ -1,3 +1,8 @@
 # Generate all fields as callbacks.
 AllTypes.*              type:FT_CALLBACK
 SubMessage.substuff1    max_size:16
+AllTypes.oneof          no_unions:true
+
+# With FT_CALLBACK, these options should get ignored
+*.*fbytes fixed_length:true max_size:4
+
diff --git a/tests/alltypes_callback/decode_alltypes_callback.c b/tests/alltypes_callback/decode_alltypes_callback.c
index 81274f6..576ce30 100644
--- a/tests/alltypes_callback/decode_alltypes_callback.c
+++ b/tests/alltypes_callback/decode_alltypes_callback.c
@@ -70,11 +70,15 @@
 static bool read_submsg(pb_istream_t *stream, const pb_field_t *field, void **arg)
 {
     SubMessage submsg = {""};
+    SubMessage *ref = *arg;
     
     if (!pb_decode(stream, SubMessage_fields, &submsg))
         return false;
     
-    TEST(memcmp(&submsg, *arg, sizeof(submsg)));
+    TEST(strcmp(submsg.substuff1, ref->substuff1) == 0);
+    TEST(submsg.substuff2 == ref->substuff2);
+    TEST(submsg.has_substuff3 == ref->has_substuff3);
+    TEST(submsg.substuff3 == ref->substuff3); 
     return true;
 }
 
@@ -144,11 +148,16 @@
 static bool read_repeated_submsg(pb_istream_t *stream, const pb_field_t *field, void **arg)
 {
     SubMessage** expected = (SubMessage**)arg;
-    SubMessage decoded = {""};
-    if (!pb_decode(stream, SubMessage_fields, &decoded))
+    SubMessage submsg = {""};
+    if (!pb_decode(stream, SubMessage_fields, &submsg))
         return false;
 
-    TEST(memcmp((*expected)++, &decoded, sizeof(decoded)) == 0);
+    TEST(strcmp(submsg.substuff1, (*expected)->substuff1) == 0);
+    TEST(submsg.substuff2 == (*expected)->substuff2);
+    TEST(submsg.has_substuff3 == (*expected)->has_substuff3);
+    TEST(submsg.substuff3 == (*expected)->substuff3);
+    (*expected)++;
+
     return true;
 }
 
@@ -177,13 +186,14 @@
 bool check_alltypes(pb_istream_t *stream, int mode)
 {
     /* Values for use from callbacks through pointers. */
+    bool status;
     uint32_t    req_fixed32     = 1008;
     int32_t     req_sfixed32    = -1009;
     float       req_float       = 1010.0f;
     uint64_t    req_fixed64     = 1011;
     int64_t     req_sfixed64    = -1012;
     double      req_double      = 1013.0;
-    SubMessage  req_submsg      = {"1016", 1016};
+    SubMessage  req_submsg      = {"1016", 1016, false, 3};
     
     int32_t     rep_int32[5]    = {0, 0, 0, 0, -2001};
     int32_t     rep_int64[5]    = {0, 0, 0, 0, -2002};
@@ -213,13 +223,12 @@
     uint64_t    opt_fixed64     = 3051;
     int64_t     opt_sfixed64    = 3052;
     double      opt_double      = 3053.0f;
-    SubMessage  opt_submsg      = {"3056", 3056};
+    SubMessage  opt_submsg      = {"3056", 3056, false, 3};
+
+    SubMessage  oneof_msg1      = {"4059", 4059, false, 3};
     
     /* Bind callbacks for required fields */
-    AllTypes alltypes;
-    
-    /* Fill with garbage to better detect initialization errors */
-    memset(&alltypes, 0xAA, sizeof(alltypes));
+    AllTypes alltypes = AllTypes_init_zero;
     
     alltypes.req_int32.funcs.decode = &read_varint;
     alltypes.req_int32.arg = (void*)-1001;
@@ -391,9 +400,19 @@
         alltypes.opt_enum.arg = (void*)MyEnum_Truth;
         
         alltypes.opt_emptymsg.funcs.decode = &read_emptymsg;
+
+        alltypes.oneof_msg1.funcs.decode = &read_submsg;
+        alltypes.oneof_msg1.arg = &oneof_msg1;
     }
     
-    return pb_decode(stream, AllTypes_fields, &alltypes);
+    status = pb_decode(stream, AllTypes_fields, &alltypes);
+    
+#ifdef PB_ENABLE_MALLOC
+    /* Just to check for any interference between pb_release() and callback fields */
+    pb_release(AllTypes_fields, &alltypes);
+#endif
+
+    return status;
 }
 
 int main(int argc, char **argv)
diff --git a/tests/alltypes_callback/encode_alltypes_callback.c b/tests/alltypes_callback/encode_alltypes_callback.c
index 10560b1..b206783 100644
--- a/tests/alltypes_callback/encode_alltypes_callback.c
+++ b/tests/alltypes_callback/encode_alltypes_callback.c
@@ -202,6 +202,8 @@
     double      opt_double      = 3053.0f;
     SubMessage  opt_submsg      = {"3056", 3056};
     
+    SubMessage  oneof_msg1      = {"4059", 4059};
+
     /* Bind callbacks for required fields */
     AllTypes alltypes = {{{0}}};
     
@@ -261,6 +263,9 @@
     
     alltypes.req_emptymsg.funcs.encode = &write_emptymsg;
     
+    alltypes.req_fbytes.funcs.encode = &write_string;
+    alltypes.req_fbytes.arg = "1019";
+    
     /* Bind callbacks for repeated fields */
     alltypes.rep_int32.funcs.encode = &write_repeated_varint;
     alltypes.rep_int32.arg = (void*)-2001;
@@ -315,6 +320,9 @@
     
     alltypes.rep_emptymsg.funcs.encode = &write_repeated_emptymsg;
     
+    alltypes.rep_fbytes.funcs.encode = &write_repeated_string;
+    alltypes.rep_fbytes.arg = "2019";
+    
     alltypes.req_limits.funcs.encode = &write_limits;
     
     /* Bind callbacks for optional fields */
@@ -372,6 +380,12 @@
         alltypes.opt_enum.arg = (void*)MyEnum_Truth;
         
         alltypes.opt_emptymsg.funcs.encode = &write_emptymsg;
+
+        alltypes.opt_fbytes.funcs.encode = &write_string;
+        alltypes.opt_fbytes.arg = "3059";
+
+        alltypes.oneof_msg1.funcs.encode = &write_submsg;
+        alltypes.oneof_msg1.arg = &oneof_msg1;
     }
     
     alltypes.end.funcs.encode = &write_varint;
diff --git a/tests/alltypes_pointer/SConscript b/tests/alltypes_pointer/SConscript
index e48d6aa..b095ae0 100644
--- a/tests/alltypes_pointer/SConscript
+++ b/tests/alltypes_pointer/SConscript
@@ -1,30 +1,22 @@
 # Encode the AllTypes message using pointers for all fields, and verify the
 # output against the normal AllTypes test case.
 
-Import("env")
-
-# We need our own pb_decode.o for the malloc support
-env = env.Clone()
-env.Append(CPPDEFINES = {'PB_ENABLE_MALLOC': 1});
-
-# Disable libmudflap, because it will confuse valgrind
-# and other memory leak detection tools.
-if '-fmudflap' in env["CCFLAGS"]:
-    env["CCFLAGS"].remove("-fmudflap")
-    env["LINKFLAGS"].remove("-fmudflap")
-    env["LIBS"].remove("mudflap")
-
-strict = env.Clone()
-strict.Append(CFLAGS = strict['CORECFLAGS'])
-strict.Object("pb_decode_with_malloc.o", "$NANOPB/pb_decode.c")
-strict.Object("pb_encode_with_malloc.o", "$NANOPB/pb_encode.c")
+Import("env", "malloc_env")
 
 c = Copy("$TARGET", "$SOURCE")
 env.Command("alltypes.proto", "#alltypes/alltypes.proto", c)
 
 env.NanopbProto(["alltypes", "alltypes.options"])
-enc = env.Program(["encode_alltypes_pointer.c", "alltypes.pb.c", "pb_encode_with_malloc.o"])
-dec = env.Program(["decode_alltypes_pointer.c", "alltypes.pb.c", "pb_decode_with_malloc.o"])
+enc = malloc_env.Program(["encode_alltypes_pointer.c",
+                          "alltypes.pb.c",
+                          "$COMMON/pb_encode_with_malloc.o",
+                          "$COMMON/pb_common_with_malloc.o",
+                          "$COMMON/malloc_wrappers.o"])
+dec = malloc_env.Program(["decode_alltypes_pointer.c",
+                          "alltypes.pb.c",
+                          "$COMMON/pb_decode_with_malloc.o",
+                          "$COMMON/pb_common_with_malloc.o",
+                          "$COMMON/malloc_wrappers.o"])
 
 # Encode and compare results to non-pointer alltypes test case
 env.RunTest(enc)
@@ -35,7 +27,7 @@
 kwargs = {}
 if valgrind:
     kwargs['COMMAND'] = valgrind
-    kwargs['ARGS'] = ["-q", dec[0].abspath]
+    kwargs['ARGS'] = ["-q", "--error-exitcode=99", dec[0].abspath]
 
 env.RunTest("decode_alltypes.output", [dec, "encode_alltypes_pointer.output"], **kwargs)
 
diff --git a/tests/alltypes_pointer/alltypes.options b/tests/alltypes_pointer/alltypes.options
index 52abeb7..8699fe2 100644
--- a/tests/alltypes_pointer/alltypes.options
+++ b/tests/alltypes_pointer/alltypes.options
@@ -1,3 +1,4 @@
 # Generate all fields as pointers.
 * type:FT_POINTER
+*.*fbytes fixed_length:true max_size:4
 
diff --git a/tests/alltypes_pointer/decode_alltypes_pointer.c b/tests/alltypes_pointer/decode_alltypes_pointer.c
index 889676b..4ee6f8b 100644
--- a/tests/alltypes_pointer/decode_alltypes_pointer.c
+++ b/tests/alltypes_pointer/decode_alltypes_pointer.c
@@ -19,6 +19,7 @@
     
     /* Fill with garbage to better detect initialization errors */
     memset(&alltypes, 0xAA, sizeof(alltypes));
+    alltypes.extensions = 0;
     
     if (!pb_decode(stream, AllTypes_fields, &alltypes))
         return false;
@@ -46,7 +47,8 @@
                                 && strcmp(alltypes.req_submsg->substuff1, "1016") == 0);
     TEST(alltypes.req_submsg    && alltypes.req_submsg->substuff2
                                 && *alltypes.req_submsg->substuff2 == 1016);
-    TEST(*alltypes.req_enum == MyEnum_Truth);
+    TEST(alltypes.req_enum      && *alltypes.req_enum == MyEnum_Truth);
+    TEST(alltypes.req_fbytes    && memcmp(alltypes.req_fbytes, "1019", 4) == 0);
 
     TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0);
     TEST(alltypes.rep_int64_count == 5 && alltypes.rep_int64[4] == -2002 && alltypes.rep_int64[0] == 0);
@@ -75,6 +77,9 @@
     
     TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero);
     TEST(alltypes.rep_emptymsg_count == 5);
+    TEST(alltypes.rep_fbytes_count == 5);
+    TEST(alltypes.rep_fbytes[0][0] == 0 && alltypes.rep_fbytes[0][3] == 0);
+    TEST(memcmp(alltypes.rep_fbytes[4], "2019", 4) == 0);
 
     if (mode == 0)
     {
@@ -98,6 +103,9 @@
         TEST(alltypes.opt_bytes         == NULL);
         TEST(alltypes.opt_submsg        == NULL);
         TEST(alltypes.opt_enum          == NULL);
+        TEST(alltypes.opt_fbytes        == NULL);
+
+        TEST(alltypes.which_oneof       == 0);
     }
     else
     {
@@ -124,6 +132,11 @@
         TEST(alltypes.opt_submsg && *alltypes.opt_submsg->substuff2 == 3056);
         TEST(alltypes.opt_enum && *alltypes.opt_enum == MyEnum_Truth);
         TEST(alltypes.opt_emptymsg);
+        TEST(alltypes.opt_fbytes && memcmp(alltypes.opt_fbytes, "3059", 4) == 0);
+
+        TEST(alltypes.which_oneof == AllTypes_oneof_msg1_tag);
+        TEST(alltypes.oneof.oneof_msg1 && strcmp(alltypes.oneof.oneof_msg1->substuff1, "4059") == 0);
+        TEST(alltypes.oneof.oneof_msg1->substuff2 && *alltypes.oneof.oneof_msg1->substuff2 == 4059);
     }
     
     TEST(alltypes.req_limits->int32_min && *alltypes.req_limits->int32_min   == INT32_MIN);
diff --git a/tests/alltypes_pointer/encode_alltypes_pointer.c b/tests/alltypes_pointer/encode_alltypes_pointer.c
index c128569..a39af6f 100644
--- a/tests/alltypes_pointer/encode_alltypes_pointer.c
+++ b/tests/alltypes_pointer/encode_alltypes_pointer.c
@@ -32,6 +32,7 @@
     SubMessage  req_submsg        = {"1016", &req_substuff};
     MyEnum      req_enum          = MyEnum_Truth;
     EmptyMessage req_emptymsg     = {0};
+    pb_byte_t   req_fbytes[4]     = {'1', '0', '1', '9'};
     
     int32_t     end               = 1099;
 
@@ -62,6 +63,7 @@
                                      {"2016", &rep_substuff2, &rep_substuff3}};
     MyEnum      rep_enum[5]       = {0, 0, 0, 0, MyEnum_Truth};
     EmptyMessage rep_emptymsg[5]  = {{0}, {0}, {0}, {0}, {0}};
+    pb_byte_t   rep_fbytes[5][4]  = {{0}, {0}, {0}, {0}, {'2', '0', '1', '9'}};
 
     /* Values for optional fields */
     int32_t     opt_int32         = 3041;
@@ -83,6 +85,10 @@
     SubMessage  opt_submsg        = {"3056", &opt_substuff};
     MyEnum      opt_enum          = MyEnum_Truth;
     EmptyMessage opt_emptymsg     = {0};
+    pb_byte_t   opt_fbytes[4]     = {'3', '0', '5', '9'};
+
+    static int32_t oneof_substuff = 4059;
+    SubMessage  oneof_msg1        = {"4059", &oneof_substuff};
 
     /* Values for the Limits message. */
     static int32_t  int32_min  = INT32_MIN;
@@ -122,6 +128,7 @@
     alltypes.req_submsg        = &req_submsg;
     alltypes.req_enum          = &req_enum;
     alltypes.req_emptymsg      = &req_emptymsg;
+    alltypes.req_fbytes        = &req_fbytes;
     alltypes.req_limits        = &req_limits;
     
     alltypes.rep_int32_count    = 5; alltypes.rep_int32     = rep_int32;
@@ -142,6 +149,7 @@
     alltypes.rep_submsg_count   = 5; alltypes.rep_submsg    = rep_submsg;
     alltypes.rep_enum_count     = 5; alltypes.rep_enum      = rep_enum;
     alltypes.rep_emptymsg_count = 5; alltypes.rep_emptymsg  = rep_emptymsg;
+    alltypes.rep_fbytes_count   = 5; alltypes.rep_fbytes    = rep_fbytes;
     
     if (mode != 0)
     {
@@ -164,6 +172,10 @@
         alltypes.opt_submsg        = &opt_submsg;
         alltypes.opt_enum          = &opt_enum;
         alltypes.opt_emptymsg      = &opt_emptymsg;
+        alltypes.opt_fbytes        = &opt_fbytes;
+
+        alltypes.which_oneof = AllTypes_oneof_msg1_tag;
+        alltypes.oneof.oneof_msg1 = &oneof_msg1;
     }
     
     alltypes.end = &end;
diff --git a/tests/alltypes_proto3/SConscript b/tests/alltypes_proto3/SConscript
new file mode 100644
index 0000000..4c2388e
--- /dev/null
+++ b/tests/alltypes_proto3/SConscript
@@ -0,0 +1,45 @@
+# Version of AllTypes test case for protobuf 3 file format.
+
+Import("env")
+
+import re
+match = None
+if 'PROTOC_VERSION' in env:
+    match = re.search('([0-9]+).([0-9]+).([0-9]+)', env['PROTOC_VERSION'])
+
+if match:
+    version = list(map(int, match.groups()))
+
+# proto3 syntax is supported by protoc >= 3.0.0
+if env.GetOption('clean') or (match and version[0] >= 3):
+
+    env.NanopbProto(["alltypes", "alltypes.options"])
+    enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+    dec = env.Program(["decode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
+
+    # Test the round-trip from nanopb encoder to nanopb decoder
+    env.RunTest(enc)
+    env.RunTest([dec, "encode_alltypes.output"])
+
+    # Re-encode the data using protoc, and check that the results from nanopb
+    # match byte-per-byte to the protoc output.
+    env.Decode("encode_alltypes.output.decoded",
+               ["encode_alltypes.output", "alltypes.proto"],
+               MESSAGE='AllTypes')
+    env.Encode("encode_alltypes.output.recoded",
+               ["encode_alltypes.output.decoded", "alltypes.proto"],
+               MESSAGE='AllTypes')
+    env.Compare(["encode_alltypes.output", "encode_alltypes.output.recoded"])
+
+    # Do the same checks with the optional fields present.
+    env.RunTest("optionals.output", enc, ARGS = ['1'])
+    env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1'])
+    env.Decode("optionals.output.decoded",
+               ["optionals.output", "alltypes.proto"],
+               MESSAGE='AllTypes')
+    env.Encode("optionals.output.recoded",
+               ["optionals.output.decoded", "alltypes.proto"],
+               MESSAGE='AllTypes')
+    env.Compare(["optionals.output", "optionals.output.recoded"])
+
+
diff --git a/tests/alltypes_proto3/alltypes.options b/tests/alltypes_proto3/alltypes.options
new file mode 100644
index 0000000..78dd08d
--- /dev/null
+++ b/tests/alltypes_proto3/alltypes.options
@@ -0,0 +1,4 @@
+* max_size:16
+* max_count:5
+*.*fbytes fixed_length:true max_size:4
+
diff --git a/tests/alltypes_proto3/alltypes.proto b/tests/alltypes_proto3/alltypes.proto
new file mode 100644
index 0000000..f66109e
--- /dev/null
+++ b/tests/alltypes_proto3/alltypes.proto
@@ -0,0 +1,100 @@
+syntax = "proto3";
+// package name placeholder
+
+message SubMessage {
+    string substuff1 = 1;
+    int32 substuff2 = 2;
+    fixed32 substuff3 = 3;
+}
+
+message EmptyMessage {
+
+}
+
+enum HugeEnum {
+    HE_Zero = 0;
+    Negative = -2147483647; /* protoc doesn't accept -2147483648 here */
+    Positive =  2147483647;
+}
+
+message Limits {
+    int32      int32_min  =  1;
+    int32      int32_max  =  2;
+    uint32     uint32_min =  3;
+    uint32     uint32_max =  4;
+    int64      int64_min  =  5;
+    int64      int64_max  =  6;
+    uint64     uint64_min =  7;
+    uint64     uint64_max =  8;
+    HugeEnum   enum_min   =  9;
+    HugeEnum   enum_max   = 10;
+}
+
+enum MyEnum {
+    Zero = 0;
+    First = 1;
+    Second = 2;
+    Truth = 42;
+}
+
+message AllTypes {
+    int32      sng_int32   = 1;
+    int64      sng_int64   = 2;
+    uint32     sng_uint32  = 3;
+    uint64     sng_uint64  = 4;
+    sint32     sng_sint32  = 5;
+    sint64     sng_sint64  = 6;
+    bool       sng_bool    = 7;
+    
+    fixed32    sng_fixed32 = 8;
+    sfixed32   sng_sfixed32= 9;
+    float      sng_float   = 10;
+    
+    fixed64    sng_fixed64 = 11;
+    sfixed64   sng_sfixed64= 12;
+    double     sng_double  = 13;
+    
+    string     sng_string  = 14;
+    bytes      sng_bytes   = 15;
+    SubMessage sng_submsg  = 16;
+    MyEnum     sng_enum    = 17;
+    EmptyMessage sng_emptymsg = 18;
+    bytes      sng_fbytes  = 19;
+
+    repeated int32      rep_int32   = 21 [packed = true];
+    repeated int64      rep_int64   = 22 [packed = true];
+    repeated uint32     rep_uint32  = 23 [packed = true];
+    repeated uint64     rep_uint64  = 24 [packed = true];
+    repeated sint32     rep_sint32  = 25 [packed = true];
+    repeated sint64     rep_sint64  = 26 [packed = true];
+    repeated bool       rep_bool    = 27 [packed = true];
+    
+    repeated fixed32    rep_fixed32 = 28 [packed = true];
+    repeated sfixed32   rep_sfixed32= 29 [packed = true];
+    repeated float      rep_float   = 30 [packed = true];
+    
+    repeated fixed64    rep_fixed64 = 31 [packed = true];
+    repeated sfixed64   rep_sfixed64= 32 [packed = true];
+    repeated double     rep_double  = 33 [packed = true];
+    
+    repeated string     rep_string  = 34;
+    repeated bytes      rep_bytes   = 35;
+    repeated SubMessage rep_submsg  = 36;
+    repeated MyEnum     rep_enum    = 37 [packed = true];
+    repeated EmptyMessage rep_emptymsg = 38;
+    repeated bytes      rep_fbytes  = 39;
+    
+    oneof oneof
+    {
+        SubMessage oneof_msg1 = 59;
+        EmptyMessage oneof_msg2 = 60;
+    }
+    
+    // Check that extreme integer values are handled correctly
+    Limits     req_limits = 98;
+
+    // Just to make sure that the size of the fields has been calculated
+    // properly, i.e. otherwise a bug in last field might not be detected.
+    int32      end = 99;
+}
+
diff --git a/tests/alltypes_proto3/decode_alltypes.c b/tests/alltypes_proto3/decode_alltypes.c
new file mode 100644
index 0000000..51c1c41
--- /dev/null
+++ b/tests/alltypes_proto3/decode_alltypes.c
@@ -0,0 +1,167 @@
+/* Tests the decoding of all types.
+ * This is the counterpart of test_encode3.
+ * Run e.g. ./test_encode3 | ./test_decode3
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pb_decode.h>
+#include "alltypes.pb.h"
+#include "test_helpers.h"
+
+#define TEST(x) if (!(x)) { \
+    printf("Test " #x " failed.\n"); \
+    return false; \
+    }
+
+/* This function is called once from main(), it handles
+   the decoding and checks the fields. */
+bool check_alltypes(pb_istream_t *stream, int mode)
+{
+    AllTypes alltypes = AllTypes_init_zero;
+    
+    /* Fill with garbage to better detect initialization errors */
+    memset(&alltypes, 0xAA, sizeof(alltypes));
+    
+    if (!pb_decode(stream, AllTypes_fields, &alltypes))
+        return false;
+    
+    TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0);
+    TEST(alltypes.rep_int64_count == 5 && alltypes.rep_int64[4] == -2002 && alltypes.rep_int64[0] == 0);
+    TEST(alltypes.rep_uint32_count == 5 && alltypes.rep_uint32[4] == 2003 && alltypes.rep_uint32[0] == 0);
+    TEST(alltypes.rep_uint64_count == 5 && alltypes.rep_uint64[4] == 2004 && alltypes.rep_uint64[0] == 0);
+    TEST(alltypes.rep_sint32_count == 5 && alltypes.rep_sint32[4] == -2005 && alltypes.rep_sint32[0] == 0);
+    TEST(alltypes.rep_sint64_count == 5 && alltypes.rep_sint64[4] == -2006 && alltypes.rep_sint64[0] == 0);
+    TEST(alltypes.rep_bool_count == 5 && alltypes.rep_bool[4] == true && alltypes.rep_bool[0] == false);
+    
+    TEST(alltypes.rep_fixed32_count == 5 && alltypes.rep_fixed32[4] == 2008 && alltypes.rep_fixed32[0] == 0);
+    TEST(alltypes.rep_sfixed32_count == 5 && alltypes.rep_sfixed32[4] == -2009 && alltypes.rep_sfixed32[0] == 0);
+    TEST(alltypes.rep_float_count == 5 && alltypes.rep_float[4] == 2010.0f && alltypes.rep_float[0] == 0.0f);
+    
+    TEST(alltypes.rep_fixed64_count == 5 && alltypes.rep_fixed64[4] == 2011 && alltypes.rep_fixed64[0] == 0);
+    TEST(alltypes.rep_sfixed64_count == 5 && alltypes.rep_sfixed64[4] == -2012 && alltypes.rep_sfixed64[0] == 0);
+    TEST(alltypes.rep_double_count == 5 && alltypes.rep_double[4] == 2013.0 && alltypes.rep_double[0] == 0.0);
+    
+    TEST(alltypes.rep_string_count == 5 && strcmp(alltypes.rep_string[4], "2014") == 0 && alltypes.rep_string[0][0] == '\0');
+    TEST(alltypes.rep_bytes_count == 5 && alltypes.rep_bytes[4].size == 4 && alltypes.rep_bytes[0].size == 0);
+    TEST(memcmp(alltypes.rep_bytes[4].bytes, "2015", 4) == 0);
+
+    TEST(alltypes.rep_submsg_count == 5);
+    TEST(strcmp(alltypes.rep_submsg[4].substuff1, "2016") == 0 && alltypes.rep_submsg[0].substuff1[0] == '\0');
+    TEST(alltypes.rep_submsg[4].substuff2 == 2016 && alltypes.rep_submsg[0].substuff2 == 0);
+    TEST(alltypes.rep_submsg[4].substuff3 == 2016 && alltypes.rep_submsg[0].substuff3 == 0);
+    
+    TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero);
+    TEST(alltypes.rep_emptymsg_count == 5);
+    
+    TEST(alltypes.rep_fbytes_count == 5);
+    TEST(alltypes.rep_fbytes[0][0] == 0 && alltypes.rep_fbytes[0][3] == 0);
+    TEST(memcmp(alltypes.rep_fbytes[4], "2019", 4) == 0);
+    
+    if (mode == 0)
+    {
+        /* Expect default values */
+        TEST(alltypes.sng_int32         == 0);
+        TEST(alltypes.sng_int64         == 0);
+        TEST(alltypes.sng_uint32        == 0);
+        TEST(alltypes.sng_uint64        == 0);
+        TEST(alltypes.sng_sint32        == 0);
+        TEST(alltypes.sng_sint64        == 0);
+        TEST(alltypes.sng_bool          == false);
+        
+        TEST(alltypes.sng_fixed32       == 0);
+        TEST(alltypes.sng_sfixed32      == 0);
+        TEST(alltypes.sng_float         == 0.0f);
+        
+        TEST(alltypes.sng_fixed64       == 0);
+        TEST(alltypes.sng_sfixed64      == 0);
+        TEST(alltypes.sng_double        == 0.0);
+        
+        TEST(strcmp(alltypes.sng_string, "") == 0);
+        TEST(alltypes.sng_bytes.size == 0);
+        TEST(strcmp(alltypes.sng_submsg.substuff1, "") == 0);
+        TEST(alltypes.sng_submsg.substuff2 == 0);
+        TEST(alltypes.sng_submsg.substuff3 == 0);
+        TEST(alltypes.sng_enum == MyEnum_Zero);
+        TEST(alltypes.sng_fbytes[0] == 0 &&
+             alltypes.sng_fbytes[1] == 0 &&
+             alltypes.sng_fbytes[2] == 0 &&
+             alltypes.sng_fbytes[3] == 0);
+
+        TEST(alltypes.which_oneof == 0);
+    }
+    else
+    {
+        /* Expect filled-in values */
+        TEST(alltypes.sng_int32         == 3041);
+        TEST(alltypes.sng_int64         == 3042);
+        TEST(alltypes.sng_uint32        == 3043);
+        TEST(alltypes.sng_uint64        == 3044);
+        TEST(alltypes.sng_sint32        == 3045);
+        TEST(alltypes.sng_sint64        == 3046);
+        TEST(alltypes.sng_bool          == true);
+        
+        TEST(alltypes.sng_fixed32       == 3048);
+        TEST(alltypes.sng_sfixed32      == 3049);
+        TEST(alltypes.sng_float         == 3050.0f);
+        
+        TEST(alltypes.sng_fixed64       == 3051);
+        TEST(alltypes.sng_sfixed64      == 3052);
+        TEST(alltypes.sng_double        == 3053.0);
+        
+        TEST(strcmp(alltypes.sng_string, "3054") == 0);
+        TEST(alltypes.sng_bytes.size == 4);
+        TEST(memcmp(alltypes.sng_bytes.bytes, "3055", 4) == 0);
+        TEST(strcmp(alltypes.sng_submsg.substuff1, "3056") == 0);
+        TEST(alltypes.sng_submsg.substuff2 == 3056);
+        TEST(alltypes.sng_submsg.substuff3 == 0);
+        TEST(alltypes.sng_enum == MyEnum_Truth);
+        TEST(memcmp(alltypes.sng_fbytes, "3059", 4) == 0);
+
+        TEST(alltypes.which_oneof == AllTypes_oneof_msg1_tag);
+        TEST(strcmp(alltypes.oneof.oneof_msg1.substuff1, "4059") == 0);
+        TEST(alltypes.oneof.oneof_msg1.substuff2 == 4059);
+    }
+    
+    TEST(alltypes.req_limits.int32_min  == INT32_MIN);
+    TEST(alltypes.req_limits.int32_max  == INT32_MAX);
+    TEST(alltypes.req_limits.uint32_min == 0);
+    TEST(alltypes.req_limits.uint32_max == UINT32_MAX);
+    TEST(alltypes.req_limits.int64_min  == INT64_MIN);
+    TEST(alltypes.req_limits.int64_max  == INT64_MAX);
+    TEST(alltypes.req_limits.uint64_min == 0);
+    TEST(alltypes.req_limits.uint64_max == UINT64_MAX);
+    TEST(alltypes.req_limits.enum_min   == HugeEnum_Negative);
+    TEST(alltypes.req_limits.enum_max   == HugeEnum_Positive);
+    
+    TEST(alltypes.end == 1099);
+    
+    return true;
+}
+
+int main(int argc, char **argv)
+{
+    uint8_t buffer[1024];
+    size_t count;
+    pb_istream_t stream;
+
+    /* Whether to expect the optional values or the default values. */
+    int mode = (argc > 1) ? atoi(argv[1]) : 0;
+    
+    /* Read the data into buffer */
+    SET_BINARY_MODE(stdin);
+    count = fread(buffer, 1, sizeof(buffer), stdin);
+    
+    /* Construct a pb_istream_t for reading from the buffer */
+    stream = pb_istream_from_buffer(buffer, count);
+    
+    /* Decode and print out the stuff */
+    if (!check_alltypes(&stream, mode))
+    {
+        printf("Parsing failed: %s\n", PB_GET_ERROR(&stream));
+        return 1;
+    } else {
+        return 0;
+    }
+}
diff --git a/tests/alltypes_proto3/encode_alltypes.c b/tests/alltypes_proto3/encode_alltypes.c
new file mode 100644
index 0000000..1da0668
--- /dev/null
+++ b/tests/alltypes_proto3/encode_alltypes.c
@@ -0,0 +1,111 @@
+/* Attempts to test all the datatypes supported by ProtoBuf3.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pb_encode.h>
+#include "alltypes.pb.h"
+#include "test_helpers.h"
+
+int main(int argc, char **argv)
+{
+    int mode = (argc > 1) ? atoi(argv[1]) : 0;
+    
+    /* Initialize the structure with constants */
+    AllTypes alltypes = AllTypes_init_zero;
+    
+    alltypes.rep_int32_count = 5; alltypes.rep_int32[4] = -2001;
+    alltypes.rep_int64_count = 5; alltypes.rep_int64[4] = -2002;
+    alltypes.rep_uint32_count = 5; alltypes.rep_uint32[4] = 2003;
+    alltypes.rep_uint64_count = 5; alltypes.rep_uint64[4] = 2004;
+    alltypes.rep_sint32_count = 5; alltypes.rep_sint32[4] = -2005;
+    alltypes.rep_sint64_count = 5; alltypes.rep_sint64[4] = -2006;
+    alltypes.rep_bool_count = 5; alltypes.rep_bool[4] = true;
+    
+    alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32[4] = 2008;
+    alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32[4] = -2009;
+    alltypes.rep_float_count = 5; alltypes.rep_float[4] = 2010.0f;
+    
+    alltypes.rep_fixed64_count = 5; alltypes.rep_fixed64[4] = 2011;
+    alltypes.rep_sfixed64_count = 5; alltypes.rep_sfixed64[4] = -2012;
+    alltypes.rep_double_count = 5; alltypes.rep_double[4] = 2013.0;
+    
+    alltypes.rep_string_count = 5; strcpy(alltypes.rep_string[4], "2014");
+    alltypes.rep_bytes_count = 5; alltypes.rep_bytes[4].size = 4;
+    memcpy(alltypes.rep_bytes[4].bytes, "2015", 4);
+
+    alltypes.rep_submsg_count = 5;
+    strcpy(alltypes.rep_submsg[4].substuff1, "2016");
+    alltypes.rep_submsg[4].substuff2 = 2016;
+    alltypes.rep_submsg[4].substuff3 = 2016;
+    
+    alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth;
+    alltypes.rep_emptymsg_count = 5;
+    
+    alltypes.rep_fbytes_count = 5;
+    memcpy(alltypes.rep_fbytes[4], "2019", 4);
+    
+    alltypes.req_limits.int32_min  = INT32_MIN;
+    alltypes.req_limits.int32_max  = INT32_MAX;
+    alltypes.req_limits.uint32_min = 0;
+    alltypes.req_limits.uint32_max = UINT32_MAX;
+    alltypes.req_limits.int64_min  = INT64_MIN;
+    alltypes.req_limits.int64_max  = INT64_MAX;
+    alltypes.req_limits.uint64_min = 0;
+    alltypes.req_limits.uint64_max = UINT64_MAX;
+    alltypes.req_limits.enum_min   = HugeEnum_Negative;
+    alltypes.req_limits.enum_max   = HugeEnum_Positive;
+    
+    if (mode != 0)
+    {
+        /* Fill in values for singular fields */
+        alltypes.sng_int32         = 3041;
+        alltypes.sng_int64         = 3042;
+        alltypes.sng_uint32        = 3043;
+        alltypes.sng_uint64        = 3044;
+        alltypes.sng_sint32        = 3045;
+        alltypes.sng_sint64        = 3046;
+        alltypes.sng_bool          = true;
+        
+        alltypes.sng_fixed32       = 3048;
+        alltypes.sng_sfixed32      = 3049;
+        alltypes.sng_float         = 3050.0f;
+        
+        alltypes.sng_fixed64       = 3051;
+        alltypes.sng_sfixed64      = 3052;
+        alltypes.sng_double        = 3053.0;
+        
+        strcpy(alltypes.sng_string, "3054");
+        alltypes.sng_bytes.size = 4;
+        memcpy(alltypes.sng_bytes.bytes, "3055", 4);
+        strcpy(alltypes.sng_submsg.substuff1, "3056");
+        alltypes.sng_submsg.substuff2 = 3056;
+        alltypes.sng_enum = MyEnum_Truth;
+        memcpy(alltypes.sng_fbytes, "3059", 4);
+
+        alltypes.which_oneof = AllTypes_oneof_msg1_tag;
+        strcpy(alltypes.oneof.oneof_msg1.substuff1, "4059");
+        alltypes.oneof.oneof_msg1.substuff2 = 4059;
+    }
+    
+    alltypes.end = 1099;
+    
+    {
+        uint8_t buffer[AllTypes_size];
+        pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+        
+        /* Now encode it and check if we succeeded. */
+        if (pb_encode(&stream, AllTypes_fields, &alltypes))
+        {
+            SET_BINARY_MODE(stdout);
+            fwrite(buffer, 1, stream.bytes_written, stdout);
+            return 0; /* Success */
+        }
+        else
+        {
+            fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
+            return 1; /* Failure */
+        }
+    }
+}
diff --git a/tests/alltypes_proto3_callback/SConscript b/tests/alltypes_proto3_callback/SConscript
new file mode 100644
index 0000000..183a138
--- /dev/null
+++ b/tests/alltypes_proto3_callback/SConscript
@@ -0,0 +1,23 @@
+# Test the AllTypes encoding & decoding using callbacks for all fields.
+
+Import("env", "malloc_env")
+
+c = Copy("$TARGET", "$SOURCE")
+env.Command("alltypes.proto", "#alltypes_proto3/alltypes.proto", c)
+
+env.NanopbProto(["alltypes", "alltypes.options"])
+enc = env.Program(["encode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = env.Program(["decode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
+
+refdec = "$BUILD/alltypes_proto3/decode_alltypes$PROGSUFFIX"
+
+# Encode and compare results
+env.RunTest(enc)
+env.RunTest("decode_alltypes.output", [refdec, "encode_alltypes_callback.output"])
+env.RunTest("decode_alltypes_callback.output", [dec, "encode_alltypes_callback.output"])
+
+# Do the same thing with the optional fields present
+env.RunTest("optionals.output", enc, ARGS = ['1'])
+env.RunTest("optionals.refdecout", [refdec, "optionals.output"], ARGS = ['1'])
+env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1'])
+
diff --git a/tests/alltypes_proto3_callback/alltypes.options b/tests/alltypes_proto3_callback/alltypes.options
new file mode 100644
index 0000000..74d7a9c
--- /dev/null
+++ b/tests/alltypes_proto3_callback/alltypes.options
@@ -0,0 +1,8 @@
+# Generate all fields as callbacks.
+AllTypes.*              type:FT_CALLBACK
+SubMessage.substuff1    max_size:16
+AllTypes.oneof          no_unions:true
+
+# With FT_CALLBACK, these options should get ignored
+*.*fbytes fixed_length:true max_size:4
+
diff --git a/tests/alltypes_proto3_callback/decode_alltypes_callback.c b/tests/alltypes_proto3_callback/decode_alltypes_callback.c
new file mode 100644
index 0000000..2b3c2f3
--- /dev/null
+++ b/tests/alltypes_proto3_callback/decode_alltypes_callback.c
@@ -0,0 +1,376 @@
+/* Attempts to test all the datatypes supported by ProtoBuf when used as callback fields.
+ * Note that normally there would be no reason to use callback fields for this,
+ * because each encoder defined here only gives a single field.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pb_decode.h>
+#include "alltypes.pb.h"
+#include "test_helpers.h"
+
+#define TEST(x) if (!(x)) { \
+    printf("Test " #x " failed (in field %d).\n", field->tag); \
+    return false; \
+    }
+
+static bool read_varint(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    uint64_t value;
+    if (!pb_decode_varint(stream, &value))
+        return false;
+    
+    TEST((int64_t)value == (long)*arg);
+    return true;
+}
+
+static bool read_svarint(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    int64_t value;
+    if (!pb_decode_svarint(stream, &value))
+        return false;
+    
+    TEST(value == (long)*arg);
+    return true;
+}
+
+static bool read_fixed32(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    uint32_t value;
+    if (!pb_decode_fixed32(stream, &value))
+        return false;
+    
+    TEST(value == *(uint32_t*)*arg);
+    return true;
+}
+
+static bool read_fixed64(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    uint64_t value;
+    if (!pb_decode_fixed64(stream, &value))
+        return false;
+    
+    TEST(value == *(uint64_t*)*arg);
+    return true;
+}
+
+static bool read_string(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    uint8_t buf[16] = {0};
+    size_t len = stream->bytes_left;
+    
+    if (len > sizeof(buf) - 1 || !pb_read(stream, buf, len))
+        return false;
+    
+    TEST(strcmp((char*)buf, *arg) == 0);
+    return true;
+}
+
+static bool read_submsg(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    SubMessage submsg = {""};
+    SubMessage *ref = *arg;
+    
+    if (!pb_decode(stream, SubMessage_fields, &submsg))
+        return false;
+    
+    TEST(strcmp(submsg.substuff1, ref->substuff1) == 0);
+    TEST(submsg.substuff2 == ref->substuff2);
+    TEST(submsg.substuff3 == ref->substuff3); 
+    return true;
+}
+
+static bool read_emptymsg(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    EmptyMessage emptymsg = {0};
+    return pb_decode(stream, EmptyMessage_fields, &emptymsg);
+}
+
+static bool read_repeated_varint(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    int32_t** expected = (int32_t**)arg;
+    uint64_t value;
+    if (!pb_decode_varint(stream, &value))
+        return false;
+
+    TEST(*(*expected)++ == value);
+    return true;
+}
+
+static bool read_repeated_svarint(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    int32_t** expected = (int32_t**)arg;
+    int64_t value;
+    if (!pb_decode_svarint(stream, &value))
+        return false;
+
+    TEST(*(*expected)++ == value);
+    return true;
+}
+
+static bool read_repeated_fixed32(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    uint32_t** expected = (uint32_t**)arg;
+    uint32_t value;
+    if (!pb_decode_fixed32(stream, &value))
+        return false;
+
+    TEST(*(*expected)++ == value);
+    return true;
+}
+
+static bool read_repeated_fixed64(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    uint64_t** expected = (uint64_t**)arg;
+    uint64_t value;
+    if (!pb_decode_fixed64(stream, &value))
+        return false;
+
+    TEST(*(*expected)++ == value);
+    return true;
+}
+
+static bool read_repeated_string(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    uint8_t*** expected = (uint8_t***)arg;
+    uint8_t buf[16] = {0};
+    size_t len = stream->bytes_left;
+    
+    if (len > sizeof(buf) - 1 || !pb_read(stream, buf, len))
+        return false;
+    
+    TEST(strcmp((char*)*(*expected)++, (char*)buf) == 0);
+    return true;
+}
+
+static bool read_repeated_submsg(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    SubMessage** expected = (SubMessage**)arg;
+    SubMessage submsg = {""};
+    if (!pb_decode(stream, SubMessage_fields, &submsg))
+        return false;
+
+    TEST(strcmp(submsg.substuff1, (*expected)->substuff1) == 0);
+    TEST(submsg.substuff2 == (*expected)->substuff2);
+    TEST(submsg.substuff3 == (*expected)->substuff3);
+    (*expected)++;
+
+    return true;
+}
+
+static bool read_limits(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    Limits decoded = {0};
+    if (!pb_decode(stream, Limits_fields, &decoded))
+        return false;
+
+    TEST(decoded.int32_min  == INT32_MIN);
+    TEST(decoded.int32_max  == INT32_MAX);
+    TEST(decoded.uint32_min == 0);
+    TEST(decoded.uint32_max == UINT32_MAX);
+    TEST(decoded.int64_min  == INT64_MIN);
+    TEST(decoded.int64_max  == INT64_MAX);
+    TEST(decoded.uint64_min == 0);
+    TEST(decoded.uint64_max == UINT64_MAX);
+    TEST(decoded.enum_min   == HugeEnum_Negative);
+    TEST(decoded.enum_max   == HugeEnum_Positive);
+    
+    return true;
+}
+
+/* This function is called once from main(), it handles
+   the decoding and checks the fields. */
+bool check_alltypes(pb_istream_t *stream, int mode)
+{
+    /* Values for use from callbacks through pointers. */
+    bool status;
+    
+    int32_t     rep_int32[5]    = {0, 0, 0, 0, -2001};
+    int32_t     rep_int64[5]    = {0, 0, 0, 0, -2002};
+    int32_t     rep_uint32[5]   = {0, 0, 0, 0,  2003};
+    int32_t     rep_uint64[5]   = {0, 0, 0, 0,  2004};
+    int32_t     rep_sint32[5]   = {0, 0, 0, 0, -2005};
+    int32_t     rep_sint64[5]   = {0, 0, 0, 0, -2006};
+    int32_t     rep_bool[5]     = {false, false, false, false, true};
+    uint32_t    rep_fixed32[5]  = {0, 0, 0, 0,  2008};
+    int32_t     rep_sfixed32[5] = {0, 0, 0, 0, -2009};
+    float       rep_float[5]    = {0, 0, 0, 0,  2010.0f};
+    uint64_t    rep_fixed64[5]  = {0, 0, 0, 0,  2011};
+    int64_t     rep_sfixed64[5] = {0, 0, 0, 0, -2012};
+    double      rep_double[5]   = {0, 0, 0, 0,  2013.0};
+    char*       rep_string[5]   = {"", "", "", "", "2014"};
+    char*       rep_bytes[5]    = {"", "", "", "", "2015"};
+    SubMessage  rep_submsg[5]   = {{"", 0, 0},
+                                   {"", 0, 0},
+                                   {"", 0, 0},
+                                   {"", 0, 0},
+                                   {"2016", 2016, 2016}};
+    int32_t     rep_enum[5]     = {0, 0, 0, 0, MyEnum_Truth};
+    
+    uint32_t    sng_fixed32     = 3048;
+    int32_t     sng_sfixed32    = 3049;
+    float       sng_float       = 3050.0f;
+    uint64_t    sng_fixed64     = 3051;
+    int64_t     sng_sfixed64    = 3052;
+    double      sng_double      = 3053.0f;
+    SubMessage  sng_submsg      = {"3056", 3056};
+
+    SubMessage  oneof_msg1      = {"4059", 4059};
+    
+    AllTypes alltypes = AllTypes_init_zero;
+
+    /* Bind callbacks for repeated fields */
+    alltypes.rep_int32.funcs.decode = &read_repeated_varint;
+    alltypes.rep_int32.arg = rep_int32;
+    
+    alltypes.rep_int64.funcs.decode = &read_repeated_varint;
+    alltypes.rep_int64.arg = rep_int64;
+    
+    alltypes.rep_uint32.funcs.decode = &read_repeated_varint;
+    alltypes.rep_uint32.arg = rep_uint32;
+    
+    alltypes.rep_uint64.funcs.decode = &read_repeated_varint;
+    alltypes.rep_uint64.arg = rep_uint64;
+    
+    alltypes.rep_sint32.funcs.decode = &read_repeated_svarint;
+    alltypes.rep_sint32.arg = rep_sint32;
+    
+    alltypes.rep_sint64.funcs.decode = &read_repeated_svarint;
+    alltypes.rep_sint64.arg = rep_sint64;
+    
+    alltypes.rep_bool.funcs.decode = &read_repeated_varint;
+    alltypes.rep_bool.arg = rep_bool;
+    
+    alltypes.rep_fixed32.funcs.decode = &read_repeated_fixed32;
+    alltypes.rep_fixed32.arg = rep_fixed32;
+    
+    alltypes.rep_sfixed32.funcs.decode = &read_repeated_fixed32;
+    alltypes.rep_sfixed32.arg = rep_sfixed32;
+    
+    alltypes.rep_float.funcs.decode = &read_repeated_fixed32;
+    alltypes.rep_float.arg = rep_float;
+    
+    alltypes.rep_fixed64.funcs.decode = &read_repeated_fixed64;
+    alltypes.rep_fixed64.arg = rep_fixed64;
+    
+    alltypes.rep_sfixed64.funcs.decode = &read_repeated_fixed64;
+    alltypes.rep_sfixed64.arg = rep_sfixed64;
+    
+    alltypes.rep_double.funcs.decode = &read_repeated_fixed64;
+    alltypes.rep_double.arg = rep_double;
+    
+    alltypes.rep_string.funcs.decode = &read_repeated_string;
+    alltypes.rep_string.arg = rep_string;
+    
+    alltypes.rep_bytes.funcs.decode = &read_repeated_string;
+    alltypes.rep_bytes.arg = rep_bytes;
+    
+    alltypes.rep_submsg.funcs.decode = &read_repeated_submsg;
+    alltypes.rep_submsg.arg = rep_submsg;
+    
+    alltypes.rep_enum.funcs.decode = &read_repeated_varint;
+    alltypes.rep_enum.arg = rep_enum;
+    
+    alltypes.rep_emptymsg.funcs.decode = &read_emptymsg;
+    
+    alltypes.req_limits.funcs.decode = &read_limits;
+    
+    alltypes.end.funcs.decode = &read_varint;
+    alltypes.end.arg = (void*)1099;
+    
+    /* Bind callbacks for optional fields */
+    if (mode == 1)
+    {
+        alltypes.sng_int32.funcs.decode = &read_varint;
+        alltypes.sng_int32.arg = (void*)3041;
+        
+        alltypes.sng_int64.funcs.decode = &read_varint;
+        alltypes.sng_int64.arg = (void*)3042;
+        
+        alltypes.sng_uint32.funcs.decode = &read_varint;
+        alltypes.sng_uint32.arg = (void*)3043;
+        
+        alltypes.sng_uint64.funcs.decode = &read_varint;
+        alltypes.sng_uint64.arg = (void*)3044;
+        
+        alltypes.sng_sint32.funcs.decode = &read_svarint;
+        alltypes.sng_sint32.arg = (void*)3045;
+        
+        alltypes.sng_sint64.funcs.decode = &read_svarint;
+        alltypes.sng_sint64.arg = (void*)3046;
+        
+        alltypes.sng_bool.funcs.decode = &read_varint;
+        alltypes.sng_bool.arg = (void*)true;
+
+        alltypes.sng_fixed32.funcs.decode = &read_fixed32;
+        alltypes.sng_fixed32.arg = &sng_fixed32;
+        
+        alltypes.sng_sfixed32.funcs.decode = &read_fixed32;
+        alltypes.sng_sfixed32.arg = &sng_sfixed32;
+        
+        alltypes.sng_float.funcs.decode = &read_fixed32;
+        alltypes.sng_float.arg = &sng_float;
+        
+        alltypes.sng_fixed64.funcs.decode = &read_fixed64;
+        alltypes.sng_fixed64.arg = &sng_fixed64;
+        
+        alltypes.sng_sfixed64.funcs.decode = &read_fixed64;
+        alltypes.sng_sfixed64.arg = &sng_sfixed64;
+        
+        alltypes.sng_double.funcs.decode = &read_fixed64;
+        alltypes.sng_double.arg = &sng_double;
+        
+        alltypes.sng_string.funcs.decode = &read_string;
+        alltypes.sng_string.arg = "3054";
+        
+        alltypes.sng_bytes.funcs.decode = &read_string;
+        alltypes.sng_bytes.arg = "3055";
+        
+        alltypes.sng_submsg.funcs.decode = &read_submsg;
+        alltypes.sng_submsg.arg = &sng_submsg;
+        
+        alltypes.sng_enum.funcs.decode = &read_varint;
+        alltypes.sng_enum.arg = (void*)MyEnum_Truth;
+        
+        alltypes.sng_emptymsg.funcs.decode = &read_emptymsg;
+
+        alltypes.oneof_msg1.funcs.decode = &read_submsg;
+        alltypes.oneof_msg1.arg = &oneof_msg1;
+    }
+    
+    status = pb_decode(stream, AllTypes_fields, &alltypes);
+    
+#ifdef PB_ENABLE_MALLOC
+    /* Just to check for any interference between pb_release() and callback fields */
+    pb_release(AllTypes_fields, &alltypes);
+#endif
+
+    return status;
+}
+
+int main(int argc, char **argv)
+{
+    uint8_t buffer[1024];
+    size_t count;
+    pb_istream_t stream;
+
+    /* Whether to expect the optional values or the default values. */
+    int mode = (argc > 1) ? atoi(argv[1]) : 0;
+    
+    /* Read the data into buffer */
+    SET_BINARY_MODE(stdin);
+    count = fread(buffer, 1, sizeof(buffer), stdin);
+    
+    /* Construct a pb_istream_t for reading from the buffer */
+    stream = pb_istream_from_buffer(buffer, count);
+    
+    /* Decode and print out the stuff */
+    if (!check_alltypes(&stream, mode))
+    {
+        printf("Parsing failed: %s\n", PB_GET_ERROR(&stream));
+        return 1;
+    } else {
+        return 0;
+    }
+}
diff --git a/tests/alltypes_proto3_callback/encode_alltypes_callback.c b/tests/alltypes_proto3_callback/encode_alltypes_callback.c
new file mode 100644
index 0000000..8c7bdd6
--- /dev/null
+++ b/tests/alltypes_proto3_callback/encode_alltypes_callback.c
@@ -0,0 +1,343 @@
+/* Attempts to test all the datatypes supported by ProtoBuf when used as callback fields.
+ * Note that normally there would be no reason to use callback fields for this,
+ * because each encoder defined here only gives a single field.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pb_encode.h>
+#include "alltypes.pb.h"
+#include "test_helpers.h"
+
+static bool write_varint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_varint(stream, (long)*arg);
+}
+
+static bool write_svarint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_svarint(stream, (long)*arg);
+}
+
+static bool write_fixed32(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_fixed32(stream, *arg);
+}
+
+static bool write_fixed64(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_fixed64(stream, *arg);
+}
+
+static bool write_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_string(stream, *arg, strlen(*arg));
+}
+
+static bool write_submsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+   
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, SubMessage_fields, *arg);
+}
+
+static bool write_emptymsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    EmptyMessage emptymsg = {0};
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg);
+}
+
+static bool write_repeated_varint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_varint(stream, 0) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_varint(stream, 0) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_varint(stream, 0) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_varint(stream, 0) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_varint(stream, (long)*arg);
+}
+
+static bool write_repeated_svarint(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_svarint(stream, 0) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_svarint(stream, 0) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_svarint(stream, 0) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_svarint(stream, 0) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_svarint(stream, (long)*arg);
+}
+
+static bool write_repeated_fixed32(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    uint32_t dummy = 0;
+
+    /* Make it a packed field */
+    return pb_encode_tag(stream, PB_WT_STRING, field->tag) &&
+           pb_encode_varint(stream, 5 * 4) && /* Number of bytes */
+           pb_encode_fixed32(stream, &dummy) &&
+           pb_encode_fixed32(stream, &dummy) &&
+           pb_encode_fixed32(stream, &dummy) &&
+           pb_encode_fixed32(stream, &dummy) &&
+           pb_encode_fixed32(stream, *arg);
+}
+
+static bool write_repeated_fixed64(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    uint64_t dummy = 0;
+
+    /* Make it a packed field */
+    return pb_encode_tag(stream, PB_WT_STRING, field->tag) &&
+           pb_encode_varint(stream, 5 * 8) && /* Number of bytes */
+           pb_encode_fixed64(stream, &dummy) &&
+           pb_encode_fixed64(stream, &dummy) &&
+           pb_encode_fixed64(stream, &dummy) &&
+           pb_encode_fixed64(stream, &dummy) &&
+           pb_encode_fixed64(stream, *arg);
+}
+
+static bool write_repeated_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_string(stream, 0, 0) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_string(stream, 0, 0) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_string(stream, 0, 0) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_string(stream, 0, 0) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_string(stream, *arg, strlen(*arg));
+}
+
+static bool write_repeated_submsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    SubMessage dummy = {""};
+
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, SubMessage_fields, &dummy) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, SubMessage_fields, &dummy) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, SubMessage_fields, &dummy) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, SubMessage_fields, &dummy) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, SubMessage_fields, *arg);
+}
+
+static bool write_limits(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    Limits limits = {0};
+    limits.int32_min  = INT32_MIN;
+    limits.int32_max  = INT32_MAX;
+    limits.uint32_min = 0;
+    limits.uint32_max = UINT32_MAX;
+    limits.int64_min  = INT64_MIN;
+    limits.int64_max  = INT64_MAX;
+    limits.uint64_min = 0;
+    limits.uint64_max = UINT64_MAX;
+    limits.enum_min   = HugeEnum_Negative;
+    limits.enum_max   = HugeEnum_Positive;
+   
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, Limits_fields, &limits);
+}
+
+static bool write_repeated_emptymsg(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    EmptyMessage emptymsg = {0};
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg) &&
+           pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, EmptyMessage_fields, &emptymsg);
+}
+
+int main(int argc, char **argv)
+{
+    int mode = (argc > 1) ? atoi(argv[1]) : 0;
+
+    /* Values for use from callbacks through pointers. */
+    uint32_t    rep_fixed32     = 2008;
+    int32_t     rep_sfixed32    = -2009;
+    float       rep_float       = 2010.0f;
+    uint64_t    rep_fixed64     = 2011;
+    int64_t     rep_sfixed64    = -2012;
+    double      rep_double      = 2013.0;
+    SubMessage  rep_submsg      = {"2016", 2016, 2016};
+    
+    uint32_t    sng_fixed32     = 3048;
+    int32_t     sng_sfixed32    = 3049;
+    float       sng_float       = 3050.0f;
+    uint64_t    sng_fixed64     = 3051;
+    int64_t     sng_sfixed64    = 3052;
+    double      sng_double      = 3053.0f;
+    SubMessage  sng_submsg      = {"3056", 3056};
+    
+    SubMessage  oneof_msg1      = {"4059", 4059};
+
+    AllTypes alltypes = AllTypes_init_zero;
+    
+    /* Bind callbacks for repeated fields */
+    alltypes.rep_int32.funcs.encode = &write_repeated_varint;
+    alltypes.rep_int32.arg = (void*)-2001;
+    
+    alltypes.rep_int64.funcs.encode = &write_repeated_varint;
+    alltypes.rep_int64.arg = (void*)-2002;
+    
+    alltypes.rep_uint32.funcs.encode = &write_repeated_varint;
+    alltypes.rep_uint32.arg = (void*)2003;
+    
+    alltypes.rep_uint64.funcs.encode = &write_repeated_varint;
+    alltypes.rep_uint64.arg = (void*)2004;
+    
+    alltypes.rep_sint32.funcs.encode = &write_repeated_svarint;
+    alltypes.rep_sint32.arg = (void*)-2005;
+    
+    alltypes.rep_sint64.funcs.encode = &write_repeated_svarint;
+    alltypes.rep_sint64.arg = (void*)-2006;
+    
+    alltypes.rep_bool.funcs.encode = &write_repeated_varint;
+    alltypes.rep_bool.arg = (void*)true;
+    
+    alltypes.rep_fixed32.funcs.encode = &write_repeated_fixed32;
+    alltypes.rep_fixed32.arg = &rep_fixed32;
+
+    alltypes.rep_sfixed32.funcs.encode = &write_repeated_fixed32;
+    alltypes.rep_sfixed32.arg = &rep_sfixed32;
+    
+    alltypes.rep_float.funcs.encode = &write_repeated_fixed32;
+    alltypes.rep_float.arg = &rep_float;
+    
+    alltypes.rep_fixed64.funcs.encode = &write_repeated_fixed64;
+    alltypes.rep_fixed64.arg = &rep_fixed64;
+
+    alltypes.rep_sfixed64.funcs.encode = &write_repeated_fixed64;
+    alltypes.rep_sfixed64.arg = &rep_sfixed64;
+    
+    alltypes.rep_double.funcs.encode = &write_repeated_fixed64;
+    alltypes.rep_double.arg = &rep_double;
+    
+    alltypes.rep_string.funcs.encode = &write_repeated_string;
+    alltypes.rep_string.arg = "2014";
+    
+    alltypes.rep_bytes.funcs.encode = &write_repeated_string;
+    alltypes.rep_bytes.arg = "2015";
+    
+    alltypes.rep_submsg.funcs.encode = &write_repeated_submsg;
+    alltypes.rep_submsg.arg = &rep_submsg;
+    
+    alltypes.rep_enum.funcs.encode = &write_repeated_varint;
+    alltypes.rep_enum.arg = (void*)MyEnum_Truth;
+    
+    alltypes.rep_emptymsg.funcs.encode = &write_repeated_emptymsg;
+    
+    alltypes.rep_fbytes.funcs.encode = &write_repeated_string;
+    alltypes.rep_fbytes.arg = "2019";
+    
+    alltypes.req_limits.funcs.encode = &write_limits;
+    
+    /* Bind callbacks for singular fields */
+    if (mode != 0)
+    {
+        alltypes.sng_int32.funcs.encode = &write_varint;
+        alltypes.sng_int32.arg = (void*)3041;
+        
+        alltypes.sng_int64.funcs.encode = &write_varint;
+        alltypes.sng_int64.arg = (void*)3042;
+        
+        alltypes.sng_uint32.funcs.encode = &write_varint;
+        alltypes.sng_uint32.arg = (void*)3043;
+        
+        alltypes.sng_uint64.funcs.encode = &write_varint;
+        alltypes.sng_uint64.arg = (void*)3044;
+        
+        alltypes.sng_sint32.funcs.encode = &write_svarint;
+        alltypes.sng_sint32.arg = (void*)3045;
+        
+        alltypes.sng_sint64.funcs.encode = &write_svarint;
+        alltypes.sng_sint64.arg = (void*)3046;
+        
+        alltypes.sng_bool.funcs.encode = &write_varint;
+        alltypes.sng_bool.arg = (void*)true;
+
+        alltypes.sng_fixed32.funcs.encode = &write_fixed32;
+        alltypes.sng_fixed32.arg = &sng_fixed32;
+        
+        alltypes.sng_sfixed32.funcs.encode = &write_fixed32;
+        alltypes.sng_sfixed32.arg = &sng_sfixed32;
+        
+        alltypes.sng_float.funcs.encode = &write_fixed32;
+        alltypes.sng_float.arg = &sng_float;
+        
+        alltypes.sng_fixed64.funcs.encode = &write_fixed64;
+        alltypes.sng_fixed64.arg = &sng_fixed64;
+        
+        alltypes.sng_sfixed64.funcs.encode = &write_fixed64;
+        alltypes.sng_sfixed64.arg = &sng_sfixed64;
+        
+        alltypes.sng_double.funcs.encode = &write_fixed64;
+        alltypes.sng_double.arg = &sng_double;
+        
+        alltypes.sng_string.funcs.encode = &write_string;
+        alltypes.sng_string.arg = "3054";
+        
+        alltypes.sng_bytes.funcs.encode = &write_string;
+        alltypes.sng_bytes.arg = "3055";
+        
+        alltypes.sng_submsg.funcs.encode = &write_submsg;
+        alltypes.sng_submsg.arg = &sng_submsg;
+        
+        alltypes.sng_enum.funcs.encode = &write_varint;
+        alltypes.sng_enum.arg = (void*)MyEnum_Truth;
+        
+        alltypes.sng_emptymsg.funcs.encode = &write_emptymsg;
+
+        alltypes.sng_fbytes.funcs.encode = &write_string;
+        alltypes.sng_fbytes.arg = "3059";
+
+        alltypes.oneof_msg1.funcs.encode = &write_submsg;
+        alltypes.oneof_msg1.arg = &oneof_msg1;
+    }
+    
+    alltypes.end.funcs.encode = &write_varint;
+    alltypes.end.arg = (void*)1099;
+    
+    {
+        uint8_t buffer[2048];
+        pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+        
+        /* Now encode it and check if we succeeded. */
+        if (pb_encode(&stream, AllTypes_fields, &alltypes))
+        {
+            SET_BINARY_MODE(stdout);
+            fwrite(buffer, 1, stream.bytes_written, stdout);
+            return 0; /* Success */
+        }
+        else
+        {
+            fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
+            return 1; /* Failure */
+        }
+    }
+}
diff --git a/tests/anonymous_oneof/SConscript b/tests/anonymous_oneof/SConscript
new file mode 100644
index 0000000..20fd1cc
--- /dev/null
+++ b/tests/anonymous_oneof/SConscript
@@ -0,0 +1,30 @@
+# Test anonymous_oneof generator option
+
+Import('env')
+
+import re
+
+match = None
+if 'PROTOC_VERSION' in env:
+    match = re.search('([0-9]+).([0-9]+).([0-9]+)', env['PROTOC_VERSION'])
+
+if match:
+    version = list(map(int, match.groups()))
+
+# Oneof is supported by protoc >= 2.6.0
+if env.GetOption('clean') or (match and (version[0] > 2 or (version[0] == 2 and version[1] >= 6))):
+    # Anonymous oneofs are supported by clang and gcc
+    if 'clang' in env['CC'] or 'gcc' in env['CC']:
+        env2 = env.Clone()
+        if '-pedantic' in env2['CFLAGS']:
+            env2['CFLAGS'].remove('-pedantic')
+        env2.NanopbProto('oneof')
+
+        dec = env2.Program(['decode_oneof.c',
+                            'oneof.pb.c',
+                            '$COMMON/pb_decode.o',
+                            '$COMMON/pb_common.o'])
+
+        env2.RunTest("message1.txt", [dec, '$BUILD/oneof/message1.pb'], ARGS = ['1'])
+        env2.RunTest("message2.txt", [dec, '$BUILD/oneof/message2.pb'], ARGS = ['2'])
+        env2.RunTest("message3.txt", [dec, '$BUILD/oneof/message3.pb'], ARGS = ['3'])
diff --git a/tests/anonymous_oneof/decode_oneof.c b/tests/anonymous_oneof/decode_oneof.c
new file mode 100644
index 0000000..0f774db
--- /dev/null
+++ b/tests/anonymous_oneof/decode_oneof.c
@@ -0,0 +1,88 @@
+/* Decode a message using oneof fields */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pb_decode.h>
+#include "oneof.pb.h"
+#include "test_helpers.h"
+#include "unittests.h"
+
+/* Test the 'AnonymousOneOfMessage' */
+int test_oneof_1(pb_istream_t *stream, int option)
+{
+    AnonymousOneOfMessage msg;
+    int status = 0;
+
+    /* To better catch initialization errors */
+    memset(&msg, 0xAA, sizeof(msg));
+
+    if (!pb_decode(stream, AnonymousOneOfMessage_fields, &msg))
+    {
+        printf("Decoding failed: %s\n", PB_GET_ERROR(stream));
+        return 1;
+    }
+
+    /* Check that the basic fields work normally */
+    TEST(msg.prefix == 123);
+    TEST(msg.suffix == 321);
+
+    /* Check that we got the right oneof according to command line */
+    if (option == 1)
+    {
+        TEST(msg.which_values == AnonymousOneOfMessage_first_tag);
+        TEST(msg.first == 999);
+    }
+    else if (option == 2)
+    {
+        TEST(msg.which_values == AnonymousOneOfMessage_second_tag);
+        TEST(strcmp(msg.second, "abcd") == 0);
+    }
+    else if (option == 3)
+    {
+        TEST(msg.which_values == AnonymousOneOfMessage_third_tag);
+        TEST(msg.third.array[0] == 1);
+        TEST(msg.third.array[1] == 2);
+        TEST(msg.third.array[2] == 3);
+        TEST(msg.third.array[3] == 4);
+        TEST(msg.third.array[4] == 5);
+    }
+
+    return status;
+}
+
+int main(int argc, char **argv)
+{
+    uint8_t buffer[AnonymousOneOfMessage_size];
+    size_t count;
+    int option;
+
+    if (argc != 2)
+    {
+        fprintf(stderr, "Usage: decode_oneof [number]\n");
+        return 1;
+    }
+    option = atoi(argv[1]);
+
+    SET_BINARY_MODE(stdin);
+    count = fread(buffer, 1, sizeof(buffer), stdin);
+
+    if (!feof(stdin))
+    {
+        printf("Message does not fit in buffer\n");
+        return 1;
+    }
+
+    {
+        int status = 0;
+        pb_istream_t stream;
+
+        stream = pb_istream_from_buffer(buffer, count);
+        status = test_oneof_1(&stream, option);
+
+        if (status != 0)
+            return status;
+    }
+
+    return 0;
+}
diff --git a/tests/anonymous_oneof/oneof.proto b/tests/anonymous_oneof/oneof.proto
new file mode 100644
index 0000000..d56285c
--- /dev/null
+++ b/tests/anonymous_oneof/oneof.proto
@@ -0,0 +1,23 @@
+syntax = "proto2";
+
+import 'nanopb.proto';
+
+message SubMessage
+{
+    repeated int32 array = 1 [(nanopb).max_count = 8];
+}
+
+/* Oneof in a message with other fields */
+message AnonymousOneOfMessage
+{
+    option (nanopb_msgopt).anonymous_oneof = true;
+    required int32 prefix = 1;
+    oneof values
+    {
+        int32 first = 5;
+        string second = 6 [(nanopb).max_size = 8];
+        SubMessage third = 7;
+    }
+    required int32 suffix = 99;
+}
+
diff --git a/tests/backwards_compatibility/SConscript b/tests/backwards_compatibility/SConscript
index 777ef40..81b0318 100644
--- a/tests/backwards_compatibility/SConscript
+++ b/tests/backwards_compatibility/SConscript
@@ -3,8 +3,8 @@
 
 Import("env")
 
-enc = env.Program(["encode_legacy.c", "alltypes_legacy.c", "$COMMON/pb_encode.o"])
-dec = env.Program(["decode_legacy.c", "alltypes_legacy.c", "$COMMON/pb_decode.o"])
+enc = env.Program(["encode_legacy.c", "alltypes_legacy.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = env.Program(["decode_legacy.c", "alltypes_legacy.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_legacy.output"])
diff --git a/tests/backwards_compatibility/alltypes_legacy.c b/tests/backwards_compatibility/alltypes_legacy.c
index 9134d5e..7311fd4 100644
--- a/tests/backwards_compatibility/alltypes_legacy.c
+++ b/tests/backwards_compatibility/alltypes_legacy.c
@@ -1,27 +1,37 @@
 /* Automatically generated nanopb constant definitions */
-/* Generated by 0.2.0-dev at Sun Feb 17 00:09:53 2013. */
-/* This is a file generated using nanopb-0.2.0-dev.
- * It is used as a part of test suite in order to detect any
- * incompatible changes made to the generator in future versions.
- */
+/* Generated by nanopb-0.3.0-dev at Tue Aug 19 17:53:24 2014. */
 
 #include "alltypes_legacy.h"
 
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
 const char SubMessage_substuff1_default[16] = "1";
 const int32_t SubMessage_substuff2_default = 2;
-const uint32_t SubMessage_substuff3_default = 3;
+const uint32_t SubMessage_substuff3_default = 3u;
+const int32_t Limits_int32_min_default = 2147483647;
+const int32_t Limits_int32_max_default = -2147483647;
+const uint32_t Limits_uint32_min_default = 4294967295u;
+const uint32_t Limits_uint32_max_default = 0u;
+const int64_t Limits_int64_min_default = 9223372036854775807ll;
+const int64_t Limits_int64_max_default = -9223372036854775807ll;
+const uint64_t Limits_uint64_min_default = 18446744073709551615ull;
+const uint64_t Limits_uint64_max_default = 0ull;
+const HugeEnum Limits_enum_min_default = HugeEnum_Positive;
+const HugeEnum Limits_enum_max_default = HugeEnum_Negative;
 const int32_t AllTypes_opt_int32_default = 4041;
-const int64_t AllTypes_opt_int64_default = 4042;
-const uint32_t AllTypes_opt_uint32_default = 4043;
-const uint64_t AllTypes_opt_uint64_default = 4044;
+const int64_t AllTypes_opt_int64_default = 4042ll;
+const uint32_t AllTypes_opt_uint32_default = 4043u;
+const uint64_t AllTypes_opt_uint64_default = 4044ull;
 const int32_t AllTypes_opt_sint32_default = 4045;
 const int64_t AllTypes_opt_sint64_default = 4046;
 const bool AllTypes_opt_bool_default = false;
-const uint32_t AllTypes_opt_fixed32_default = 4048;
+const uint32_t AllTypes_opt_fixed32_default = 4048u;
 const int32_t AllTypes_opt_sfixed32_default = 4049;
 const float AllTypes_opt_float_default = 4050;
-const uint64_t AllTypes_opt_fixed64_default = 4051;
-const int64_t AllTypes_opt_sfixed64_default = 4052;
+const uint64_t AllTypes_opt_fixed64_default = 4051ull;
+const int64_t AllTypes_opt_sfixed64_default = 4052ll;
 const double AllTypes_opt_double_default = 4053;
 const char AllTypes_opt_string_default[16] = "4054";
 const AllTypes_opt_bytes_t AllTypes_opt_bytes_default = {4, {0x34,0x30,0x35,0x35}};
@@ -29,65 +39,115 @@
 
 
 const pb_field_t SubMessage_fields[4] = {
-    PB_FIELD(  1, STRING  , REQUIRED, STATIC, SubMessage, substuff1, substuff1, &SubMessage_substuff1_default),
-    PB_FIELD(  2, INT32   , REQUIRED, STATIC, SubMessage, substuff2, substuff1, &SubMessage_substuff2_default),
-    PB_FIELD(  3, FIXED32 , OPTIONAL, STATIC, SubMessage, substuff3, substuff2, &SubMessage_substuff3_default),
+    PB_FIELD(  1, STRING  , REQUIRED, STATIC  , FIRST, SubMessage, substuff1, substuff1, &SubMessage_substuff1_default),
+    PB_FIELD(  2, INT32   , REQUIRED, STATIC  , OTHER, SubMessage, substuff2, substuff1, &SubMessage_substuff2_default),
+    PB_FIELD(  3, FIXED32 , OPTIONAL, STATIC  , OTHER, SubMessage, substuff3, substuff2, &SubMessage_substuff3_default),
     PB_LAST_FIELD
 };
 
-const pb_field_t AllTypes_fields[53] = {
-    PB_FIELD(  1, INT32   , REQUIRED, STATIC, AllTypes, req_int32, req_int32, 0),
-    PB_FIELD(  2, INT64   , REQUIRED, STATIC, AllTypes, req_int64, req_int32, 0),
-    PB_FIELD(  3, UINT32  , REQUIRED, STATIC, AllTypes, req_uint32, req_int64, 0),
-    PB_FIELD(  4, UINT64  , REQUIRED, STATIC, AllTypes, req_uint64, req_uint32, 0),
-    PB_FIELD(  5, SINT32  , REQUIRED, STATIC, AllTypes, req_sint32, req_uint64, 0),
-    PB_FIELD(  6, SINT64  , REQUIRED, STATIC, AllTypes, req_sint64, req_sint32, 0),
-    PB_FIELD(  7, BOOL    , REQUIRED, STATIC, AllTypes, req_bool, req_sint64, 0),
-    PB_FIELD(  8, FIXED32 , REQUIRED, STATIC, AllTypes, req_fixed32, req_bool, 0),
-    PB_FIELD(  9, SFIXED32, REQUIRED, STATIC, AllTypes, req_sfixed32, req_fixed32, 0),
-    PB_FIELD( 10, FLOAT   , REQUIRED, STATIC, AllTypes, req_float, req_sfixed32, 0),
-    PB_FIELD( 11, FIXED64 , REQUIRED, STATIC, AllTypes, req_fixed64, req_float, 0),
-    PB_FIELD( 12, SFIXED64, REQUIRED, STATIC, AllTypes, req_sfixed64, req_fixed64, 0),
-    PB_FIELD( 13, DOUBLE  , REQUIRED, STATIC, AllTypes, req_double, req_sfixed64, 0),
-    PB_FIELD( 14, STRING  , REQUIRED, STATIC, AllTypes, req_string, req_double, 0),
-    PB_FIELD( 15, BYTES   , REQUIRED, STATIC, AllTypes, req_bytes, req_string, 0),
-    PB_FIELD( 16, MESSAGE , REQUIRED, STATIC, AllTypes, req_submsg, req_bytes, &SubMessage_fields),
-    PB_FIELD( 17, ENUM    , REQUIRED, STATIC, AllTypes, req_enum, req_submsg, 0),
-    PB_FIELD( 21, INT32   , REPEATED, STATIC, AllTypes, rep_int32, req_enum, 0),
-    PB_FIELD( 22, INT64   , REPEATED, STATIC, AllTypes, rep_int64, rep_int32, 0),
-    PB_FIELD( 23, UINT32  , REPEATED, STATIC, AllTypes, rep_uint32, rep_int64, 0),
-    PB_FIELD( 24, UINT64  , REPEATED, STATIC, AllTypes, rep_uint64, rep_uint32, 0),
-    PB_FIELD( 25, SINT32  , REPEATED, STATIC, AllTypes, rep_sint32, rep_uint64, 0),
-    PB_FIELD( 26, SINT64  , REPEATED, STATIC, AllTypes, rep_sint64, rep_sint32, 0),
-    PB_FIELD( 27, BOOL    , REPEATED, STATIC, AllTypes, rep_bool, rep_sint64, 0),
-    PB_FIELD( 28, FIXED32 , REPEATED, STATIC, AllTypes, rep_fixed32, rep_bool, 0),
-    PB_FIELD( 29, SFIXED32, REPEATED, STATIC, AllTypes, rep_sfixed32, rep_fixed32, 0),
-    PB_FIELD( 30, FLOAT   , REPEATED, STATIC, AllTypes, rep_float, rep_sfixed32, 0),
-    PB_FIELD( 31, FIXED64 , REPEATED, STATIC, AllTypes, rep_fixed64, rep_float, 0),
-    PB_FIELD( 32, SFIXED64, REPEATED, STATIC, AllTypes, rep_sfixed64, rep_fixed64, 0),
-    PB_FIELD( 33, DOUBLE  , REPEATED, STATIC, AllTypes, rep_double, rep_sfixed64, 0),
-    PB_FIELD( 34, STRING  , REPEATED, STATIC, AllTypes, rep_string, rep_double, 0),
-    PB_FIELD( 35, BYTES   , REPEATED, STATIC, AllTypes, rep_bytes, rep_string, 0),
-    PB_FIELD( 36, MESSAGE , REPEATED, STATIC, AllTypes, rep_submsg, rep_bytes, &SubMessage_fields),
-    PB_FIELD( 37, ENUM    , REPEATED, STATIC, AllTypes, rep_enum, rep_submsg, 0),
-    PB_FIELD( 41, INT32   , OPTIONAL, STATIC, AllTypes, opt_int32, rep_enum, &AllTypes_opt_int32_default),
-    PB_FIELD( 42, INT64   , OPTIONAL, STATIC, AllTypes, opt_int64, opt_int32, &AllTypes_opt_int64_default),
-    PB_FIELD( 43, UINT32  , OPTIONAL, STATIC, AllTypes, opt_uint32, opt_int64, &AllTypes_opt_uint32_default),
-    PB_FIELD( 44, UINT64  , OPTIONAL, STATIC, AllTypes, opt_uint64, opt_uint32, &AllTypes_opt_uint64_default),
-    PB_FIELD( 45, SINT32  , OPTIONAL, STATIC, AllTypes, opt_sint32, opt_uint64, &AllTypes_opt_sint32_default),
-    PB_FIELD( 46, SINT64  , OPTIONAL, STATIC, AllTypes, opt_sint64, opt_sint32, &AllTypes_opt_sint64_default),
-    PB_FIELD( 47, BOOL    , OPTIONAL, STATIC, AllTypes, opt_bool, opt_sint64, &AllTypes_opt_bool_default),
-    PB_FIELD( 48, FIXED32 , OPTIONAL, STATIC, AllTypes, opt_fixed32, opt_bool, &AllTypes_opt_fixed32_default),
-    PB_FIELD( 49, SFIXED32, OPTIONAL, STATIC, AllTypes, opt_sfixed32, opt_fixed32, &AllTypes_opt_sfixed32_default),
-    PB_FIELD( 50, FLOAT   , OPTIONAL, STATIC, AllTypes, opt_float, opt_sfixed32, &AllTypes_opt_float_default),
-    PB_FIELD( 51, FIXED64 , OPTIONAL, STATIC, AllTypes, opt_fixed64, opt_float, &AllTypes_opt_fixed64_default),
-    PB_FIELD( 52, SFIXED64, OPTIONAL, STATIC, AllTypes, opt_sfixed64, opt_fixed64, &AllTypes_opt_sfixed64_default),
-    PB_FIELD( 53, DOUBLE  , OPTIONAL, STATIC, AllTypes, opt_double, opt_sfixed64, &AllTypes_opt_double_default),
-    PB_FIELD( 54, STRING  , OPTIONAL, STATIC, AllTypes, opt_string, opt_double, &AllTypes_opt_string_default),
-    PB_FIELD( 55, BYTES   , OPTIONAL, STATIC, AllTypes, opt_bytes, opt_string, &AllTypes_opt_bytes_default),
-    PB_FIELD( 56, MESSAGE , OPTIONAL, STATIC, AllTypes, opt_submsg, opt_bytes, &SubMessage_fields),
-    PB_FIELD( 57, ENUM    , OPTIONAL, STATIC, AllTypes, opt_enum, opt_submsg, &AllTypes_opt_enum_default),
-    PB_FIELD( 99, INT32   , REQUIRED, STATIC, AllTypes, end, opt_enum, 0),
+const pb_field_t EmptyMessage_fields[1] = {
     PB_LAST_FIELD
 };
 
+const pb_field_t Limits_fields[11] = {
+    PB_FIELD(  1, INT32   , REQUIRED, STATIC  , FIRST, Limits, int32_min, int32_min, &Limits_int32_min_default),
+    PB_FIELD(  2, INT32   , REQUIRED, STATIC  , OTHER, Limits, int32_max, int32_min, &Limits_int32_max_default),
+    PB_FIELD(  3, UINT32  , REQUIRED, STATIC  , OTHER, Limits, uint32_min, int32_max, &Limits_uint32_min_default),
+    PB_FIELD(  4, UINT32  , REQUIRED, STATIC  , OTHER, Limits, uint32_max, uint32_min, &Limits_uint32_max_default),
+    PB_FIELD(  5, INT64   , REQUIRED, STATIC  , OTHER, Limits, int64_min, uint32_max, &Limits_int64_min_default),
+    PB_FIELD(  6, INT64   , REQUIRED, STATIC  , OTHER, Limits, int64_max, int64_min, &Limits_int64_max_default),
+    PB_FIELD(  7, UINT64  , REQUIRED, STATIC  , OTHER, Limits, uint64_min, int64_max, &Limits_uint64_min_default),
+    PB_FIELD(  8, UINT64  , REQUIRED, STATIC  , OTHER, Limits, uint64_max, uint64_min, &Limits_uint64_max_default),
+    PB_FIELD(  9, ENUM    , REQUIRED, STATIC  , OTHER, Limits, enum_min, uint64_max, &Limits_enum_min_default),
+    PB_FIELD( 10, ENUM    , REQUIRED, STATIC  , OTHER, Limits, enum_max, enum_min, &Limits_enum_max_default),
+    PB_LAST_FIELD
+};
+
+const pb_field_t AllTypes_fields[54] = {
+    PB_FIELD(  1, INT32   , REQUIRED, STATIC  , FIRST, AllTypes, req_int32, req_int32, 0),
+    PB_FIELD(  2, INT64   , REQUIRED, STATIC  , OTHER, AllTypes, req_int64, req_int32, 0),
+    PB_FIELD(  3, UINT32  , REQUIRED, STATIC  , OTHER, AllTypes, req_uint32, req_int64, 0),
+    PB_FIELD(  4, UINT64  , REQUIRED, STATIC  , OTHER, AllTypes, req_uint64, req_uint32, 0),
+    PB_FIELD(  5, SINT32  , REQUIRED, STATIC  , OTHER, AllTypes, req_sint32, req_uint64, 0),
+    PB_FIELD(  6, SINT64  , REQUIRED, STATIC  , OTHER, AllTypes, req_sint64, req_sint32, 0),
+    PB_FIELD(  7, BOOL    , REQUIRED, STATIC  , OTHER, AllTypes, req_bool, req_sint64, 0),
+    PB_FIELD(  8, FIXED32 , REQUIRED, STATIC  , OTHER, AllTypes, req_fixed32, req_bool, 0),
+    PB_FIELD(  9, SFIXED32, REQUIRED, STATIC  , OTHER, AllTypes, req_sfixed32, req_fixed32, 0),
+    PB_FIELD( 10, FLOAT   , REQUIRED, STATIC  , OTHER, AllTypes, req_float, req_sfixed32, 0),
+    PB_FIELD( 11, FIXED64 , REQUIRED, STATIC  , OTHER, AllTypes, req_fixed64, req_float, 0),
+    PB_FIELD( 12, SFIXED64, REQUIRED, STATIC  , OTHER, AllTypes, req_sfixed64, req_fixed64, 0),
+    PB_FIELD( 13, DOUBLE  , REQUIRED, STATIC  , OTHER, AllTypes, req_double, req_sfixed64, 0),
+    PB_FIELD( 14, STRING  , REQUIRED, STATIC  , OTHER, AllTypes, req_string, req_double, 0),
+    PB_FIELD( 15, BYTES   , REQUIRED, STATIC  , OTHER, AllTypes, req_bytes, req_string, 0),
+    PB_FIELD( 16, MESSAGE , REQUIRED, STATIC  , OTHER, AllTypes, req_submsg, req_bytes, &SubMessage_fields),
+    PB_FIELD( 17, ENUM    , REQUIRED, STATIC  , OTHER, AllTypes, req_enum, req_submsg, 0),
+    PB_FIELD( 21, INT32   , REPEATED, STATIC  , OTHER, AllTypes, rep_int32, req_enum, 0),
+    PB_FIELD( 22, INT64   , REPEATED, STATIC  , OTHER, AllTypes, rep_int64, rep_int32, 0),
+    PB_FIELD( 23, UINT32  , REPEATED, STATIC  , OTHER, AllTypes, rep_uint32, rep_int64, 0),
+    PB_FIELD( 24, UINT64  , REPEATED, STATIC  , OTHER, AllTypes, rep_uint64, rep_uint32, 0),
+    PB_FIELD( 25, SINT32  , REPEATED, STATIC  , OTHER, AllTypes, rep_sint32, rep_uint64, 0),
+    PB_FIELD( 26, SINT64  , REPEATED, STATIC  , OTHER, AllTypes, rep_sint64, rep_sint32, 0),
+    PB_FIELD( 27, BOOL    , REPEATED, STATIC  , OTHER, AllTypes, rep_bool, rep_sint64, 0),
+    PB_FIELD( 28, FIXED32 , REPEATED, STATIC  , OTHER, AllTypes, rep_fixed32, rep_bool, 0),
+    PB_FIELD( 29, SFIXED32, REPEATED, STATIC  , OTHER, AllTypes, rep_sfixed32, rep_fixed32, 0),
+    PB_FIELD( 30, FLOAT   , REPEATED, STATIC  , OTHER, AllTypes, rep_float, rep_sfixed32, 0),
+    PB_FIELD( 31, FIXED64 , REPEATED, STATIC  , OTHER, AllTypes, rep_fixed64, rep_float, 0),
+    PB_FIELD( 32, SFIXED64, REPEATED, STATIC  , OTHER, AllTypes, rep_sfixed64, rep_fixed64, 0),
+    PB_FIELD( 33, DOUBLE  , REPEATED, STATIC  , OTHER, AllTypes, rep_double, rep_sfixed64, 0),
+    PB_FIELD( 34, STRING  , REPEATED, STATIC  , OTHER, AllTypes, rep_string, rep_double, 0),
+    PB_FIELD( 35, BYTES   , REPEATED, STATIC  , OTHER, AllTypes, rep_bytes, rep_string, 0),
+    PB_FIELD( 36, MESSAGE , REPEATED, STATIC  , OTHER, AllTypes, rep_submsg, rep_bytes, &SubMessage_fields),
+    PB_FIELD( 37, ENUM    , REPEATED, STATIC  , OTHER, AllTypes, rep_enum, rep_submsg, 0),
+    PB_FIELD( 41, INT32   , OPTIONAL, STATIC  , OTHER, AllTypes, opt_int32, rep_enum, &AllTypes_opt_int32_default),
+    PB_FIELD( 42, INT64   , OPTIONAL, STATIC  , OTHER, AllTypes, opt_int64, opt_int32, &AllTypes_opt_int64_default),
+    PB_FIELD( 43, UINT32  , OPTIONAL, STATIC  , OTHER, AllTypes, opt_uint32, opt_int64, &AllTypes_opt_uint32_default),
+    PB_FIELD( 44, UINT64  , OPTIONAL, STATIC  , OTHER, AllTypes, opt_uint64, opt_uint32, &AllTypes_opt_uint64_default),
+    PB_FIELD( 45, SINT32  , OPTIONAL, STATIC  , OTHER, AllTypes, opt_sint32, opt_uint64, &AllTypes_opt_sint32_default),
+    PB_FIELD( 46, SINT64  , OPTIONAL, STATIC  , OTHER, AllTypes, opt_sint64, opt_sint32, &AllTypes_opt_sint64_default),
+    PB_FIELD( 47, BOOL    , OPTIONAL, STATIC  , OTHER, AllTypes, opt_bool, opt_sint64, &AllTypes_opt_bool_default),
+    PB_FIELD( 48, FIXED32 , OPTIONAL, STATIC  , OTHER, AllTypes, opt_fixed32, opt_bool, &AllTypes_opt_fixed32_default),
+    PB_FIELD( 49, SFIXED32, OPTIONAL, STATIC  , OTHER, AllTypes, opt_sfixed32, opt_fixed32, &AllTypes_opt_sfixed32_default),
+    PB_FIELD( 50, FLOAT   , OPTIONAL, STATIC  , OTHER, AllTypes, opt_float, opt_sfixed32, &AllTypes_opt_float_default),
+    PB_FIELD( 51, FIXED64 , OPTIONAL, STATIC  , OTHER, AllTypes, opt_fixed64, opt_float, &AllTypes_opt_fixed64_default),
+    PB_FIELD( 52, SFIXED64, OPTIONAL, STATIC  , OTHER, AllTypes, opt_sfixed64, opt_fixed64, &AllTypes_opt_sfixed64_default),
+    PB_FIELD( 53, DOUBLE  , OPTIONAL, STATIC  , OTHER, AllTypes, opt_double, opt_sfixed64, &AllTypes_opt_double_default),
+    PB_FIELD( 54, STRING  , OPTIONAL, STATIC  , OTHER, AllTypes, opt_string, opt_double, &AllTypes_opt_string_default),
+    PB_FIELD( 55, BYTES   , OPTIONAL, STATIC  , OTHER, AllTypes, opt_bytes, opt_string, &AllTypes_opt_bytes_default),
+    PB_FIELD( 56, MESSAGE , OPTIONAL, STATIC  , OTHER, AllTypes, opt_submsg, opt_bytes, &SubMessage_fields),
+    PB_FIELD( 57, ENUM    , OPTIONAL, STATIC  , OTHER, AllTypes, opt_enum, opt_submsg, &AllTypes_opt_enum_default),
+    PB_FIELD( 99, INT32   , REQUIRED, STATIC  , OTHER, AllTypes, end, opt_enum, 0),
+    PB_FIELD(200, EXTENSION, OPTIONAL, CALLBACK, OTHER, AllTypes, extensions, end, 0),
+    PB_LAST_FIELD
+};
+
+
+/* Check that field information fits in pb_field_t */
+#if !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_32BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ * 
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in 8 or 16 bit
+ * field descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(AllTypes, req_submsg) < 65536 && pb_membersize(AllTypes, rep_submsg[0]) < 65536 && pb_membersize(AllTypes, opt_submsg) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_SubMessage_EmptyMessage_Limits_AllTypes)
+#endif
+
+#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_16BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ * 
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in the default
+ * 8 bit descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(AllTypes, req_submsg) < 256 && pb_membersize(AllTypes, rep_submsg[0]) < 256 && pb_membersize(AllTypes, opt_submsg) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_SubMessage_EmptyMessage_Limits_AllTypes)
+#endif
+
+
+/* On some platforms (such as AVR), double is really float.
+ * These are not directly supported by nanopb, but see example_avr_double.
+ * To get rid of this error, remove any double fields from your .proto.
+ */
+PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES)
+
diff --git a/tests/backwards_compatibility/alltypes_legacy.h b/tests/backwards_compatibility/alltypes_legacy.h
index 037b347..4e0a63b 100644
--- a/tests/backwards_compatibility/alltypes_legacy.h
+++ b/tests/backwards_compatibility/alltypes_legacy.h
@@ -1,18 +1,24 @@
 /* Automatically generated nanopb header */
-/* This is a file generated using nanopb-0.2.0-dev.
- * It is used as a part of test suite in order to detect any
- * incompatible changes made to the generator in future versions.
- */
+/* Generated by nanopb-0.3.0-dev at Tue Aug 19 17:53:24 2014. */
 
-#ifndef _PB_ALLTYPES_PB_H_
-#define _PB_ALLTYPES_PB_H_
+#ifndef PB_ALLTYPES_LEGACY_H_INCLUDED
+#define PB_ALLTYPES_LEGACY_H_INCLUDED
 #include <pb.h>
 
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /* Enum definitions */
+typedef enum _HugeEnum {
+    HugeEnum_Negative = -2147483647,
+    HugeEnum_Positive = 2147483647
+} HugeEnum;
+
 typedef enum _MyEnum {
     MyEnum_Zero = 0,
     MyEnum_First = 1,
@@ -21,6 +27,23 @@
 } MyEnum;
 
 /* Struct definitions */
+typedef struct _EmptyMessage {
+    uint8_t dummy_field;
+} EmptyMessage;
+
+typedef struct _Limits {
+    int32_t int32_min;
+    int32_t int32_max;
+    uint32_t uint32_min;
+    uint32_t uint32_max;
+    int64_t int64_min;
+    int64_t int64_max;
+    uint64_t uint64_min;
+    uint64_t uint64_max;
+    HugeEnum enum_min;
+    HugeEnum enum_max;
+} Limits;
+
 typedef struct _SubMessage {
     char substuff1[16];
     int32_t substuff2;
@@ -28,20 +51,11 @@
     uint32_t substuff3;
 } SubMessage;
 
-typedef struct {
-    size_t size;
-    uint8_t bytes[16];
-} AllTypes_req_bytes_t;
+typedef PB_BYTES_ARRAY_T(16) AllTypes_req_bytes_t;
 
-typedef struct {
-    size_t size;
-    uint8_t bytes[16];
-} AllTypes_rep_bytes_t;
+typedef PB_BYTES_ARRAY_T(16) AllTypes_rep_bytes_t;
 
-typedef struct {
-    size_t size;
-    uint8_t bytes[16];
-} AllTypes_opt_bytes_t;
+typedef PB_BYTES_ARRAY_T(16) AllTypes_opt_bytes_t;
 
 typedef struct _AllTypes {
     int32_t req_int32;
@@ -61,39 +75,39 @@
     AllTypes_req_bytes_t req_bytes;
     SubMessage req_submsg;
     MyEnum req_enum;
-    size_t rep_int32_count;
+    pb_size_t rep_int32_count;
     int32_t rep_int32[5];
-    size_t rep_int64_count;
+    pb_size_t rep_int64_count;
     int64_t rep_int64[5];
-    size_t rep_uint32_count;
+    pb_size_t rep_uint32_count;
     uint32_t rep_uint32[5];
-    size_t rep_uint64_count;
+    pb_size_t rep_uint64_count;
     uint64_t rep_uint64[5];
-    size_t rep_sint32_count;
+    pb_size_t rep_sint32_count;
     int32_t rep_sint32[5];
-    size_t rep_sint64_count;
+    pb_size_t rep_sint64_count;
     int64_t rep_sint64[5];
-    size_t rep_bool_count;
+    pb_size_t rep_bool_count;
     bool rep_bool[5];
-    size_t rep_fixed32_count;
+    pb_size_t rep_fixed32_count;
     uint32_t rep_fixed32[5];
-    size_t rep_sfixed32_count;
+    pb_size_t rep_sfixed32_count;
     int32_t rep_sfixed32[5];
-    size_t rep_float_count;
+    pb_size_t rep_float_count;
     float rep_float[5];
-    size_t rep_fixed64_count;
+    pb_size_t rep_fixed64_count;
     uint64_t rep_fixed64[5];
-    size_t rep_sfixed64_count;
+    pb_size_t rep_sfixed64_count;
     int64_t rep_sfixed64[5];
-    size_t rep_double_count;
+    pb_size_t rep_double_count;
     double rep_double[5];
-    size_t rep_string_count;
+    pb_size_t rep_string_count;
     char rep_string[5][16];
-    size_t rep_bytes_count;
+    pb_size_t rep_bytes_count;
     AllTypes_rep_bytes_t rep_bytes[5];
-    size_t rep_submsg_count;
+    pb_size_t rep_submsg_count;
     SubMessage rep_submsg[5];
-    size_t rep_enum_count;
+    pb_size_t rep_enum_count;
     MyEnum rep_enum[5];
     bool has_opt_int32;
     int32_t opt_int32;
@@ -130,12 +144,23 @@
     bool has_opt_enum;
     MyEnum opt_enum;
     int32_t end;
+    pb_extension_t *extensions;
 } AllTypes;
 
 /* Default values for struct fields */
 extern const char SubMessage_substuff1_default[16];
 extern const int32_t SubMessage_substuff2_default;
 extern const uint32_t SubMessage_substuff3_default;
+extern const int32_t Limits_int32_min_default;
+extern const int32_t Limits_int32_max_default;
+extern const uint32_t Limits_uint32_min_default;
+extern const uint32_t Limits_uint32_max_default;
+extern const int64_t Limits_int64_min_default;
+extern const int64_t Limits_int64_max_default;
+extern const uint64_t Limits_uint64_min_default;
+extern const uint64_t Limits_uint64_max_default;
+extern const HugeEnum Limits_enum_min_default;
+extern const HugeEnum Limits_enum_max_default;
 extern const int32_t AllTypes_opt_int32_default;
 extern const int64_t AllTypes_opt_int64_default;
 extern const uint32_t AllTypes_opt_uint32_default;
@@ -153,23 +178,94 @@
 extern const AllTypes_opt_bytes_t AllTypes_opt_bytes_default;
 extern const MyEnum AllTypes_opt_enum_default;
 
+/* Initializer values for message structs */
+#define SubMessage_init_default                  {"1", 2, false, 3u}
+#define EmptyMessage_init_default                {0}
+#define Limits_init_default                      {2147483647, -2147483647, 4294967295u, 0u, 9223372036854775807ll, -9223372036854775807ll, 18446744073709551615ull, 0ull, HugeEnum_Positive, HugeEnum_Negative}
+#define AllTypes_init_default                    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", {0, {0}}, SubMessage_init_default, (MyEnum)0, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {"", "", "", "", ""}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, 0, {SubMessage_init_default, SubMessage_init_default, SubMessage_init_default, SubMessage_init_default, SubMessage_init_default}, 0, {(MyEnum)0, (MyEnum)0, (MyEnum)0, (MyEnum)0, (MyEnum)0}, false, 4041, false, 4042ll, false, 4043u, false, 4044ull, false, 4045, false, 4046, false, false, false, 4048u, false, 4049, false, 4050, false, 4051ull, false, 4052ll, false, 4053, false, "4054", false, {4, {0x34,0x30,0x35,0x35}}, false, SubMessage_init_default, false, MyEnum_Second, 0, NULL}
+#define SubMessage_init_zero                     {"", 0, false, 0}
+#define EmptyMessage_init_zero                   {0}
+#define Limits_init_zero                         {0, 0, 0, 0, 0, 0, 0, 0, (HugeEnum)0, (HugeEnum)0}
+#define AllTypes_init_zero                       {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", {0, {0}}, SubMessage_init_zero, (MyEnum)0, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {"", "", "", "", ""}, 0, {{0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}, {0, {0}}}, 0, {SubMessage_init_zero, SubMessage_init_zero, SubMessage_init_zero, SubMessage_init_zero, SubMessage_init_zero}, 0, {(MyEnum)0, (MyEnum)0, (MyEnum)0, (MyEnum)0, (MyEnum)0}, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, "", false, {0, {0}}, false, SubMessage_init_zero, false, (MyEnum)0, 0, NULL}
+
+/* Field tags (for use in manual encoding/decoding) */
+#define Limits_int32_min_tag                     1
+#define Limits_int32_max_tag                     2
+#define Limits_uint32_min_tag                    3
+#define Limits_uint32_max_tag                    4
+#define Limits_int64_min_tag                     5
+#define Limits_int64_max_tag                     6
+#define Limits_uint64_min_tag                    7
+#define Limits_uint64_max_tag                    8
+#define Limits_enum_min_tag                      9
+#define Limits_enum_max_tag                      10
+#define SubMessage_substuff1_tag                 1
+#define SubMessage_substuff2_tag                 2
+#define SubMessage_substuff3_tag                 3
+#define AllTypes_req_int32_tag                   1
+#define AllTypes_req_int64_tag                   2
+#define AllTypes_req_uint32_tag                  3
+#define AllTypes_req_uint64_tag                  4
+#define AllTypes_req_sint32_tag                  5
+#define AllTypes_req_sint64_tag                  6
+#define AllTypes_req_bool_tag                    7
+#define AllTypes_req_fixed32_tag                 8
+#define AllTypes_req_sfixed32_tag                9
+#define AllTypes_req_float_tag                   10
+#define AllTypes_req_fixed64_tag                 11
+#define AllTypes_req_sfixed64_tag                12
+#define AllTypes_req_double_tag                  13
+#define AllTypes_req_string_tag                  14
+#define AllTypes_req_bytes_tag                   15
+#define AllTypes_req_submsg_tag                  16
+#define AllTypes_req_enum_tag                    17
+#define AllTypes_rep_int32_tag                   21
+#define AllTypes_rep_int64_tag                   22
+#define AllTypes_rep_uint32_tag                  23
+#define AllTypes_rep_uint64_tag                  24
+#define AllTypes_rep_sint32_tag                  25
+#define AllTypes_rep_sint64_tag                  26
+#define AllTypes_rep_bool_tag                    27
+#define AllTypes_rep_fixed32_tag                 28
+#define AllTypes_rep_sfixed32_tag                29
+#define AllTypes_rep_float_tag                   30
+#define AllTypes_rep_fixed64_tag                 31
+#define AllTypes_rep_sfixed64_tag                32
+#define AllTypes_rep_double_tag                  33
+#define AllTypes_rep_string_tag                  34
+#define AllTypes_rep_bytes_tag                   35
+#define AllTypes_rep_submsg_tag                  36
+#define AllTypes_rep_enum_tag                    37
+#define AllTypes_opt_int32_tag                   41
+#define AllTypes_opt_int64_tag                   42
+#define AllTypes_opt_uint32_tag                  43
+#define AllTypes_opt_uint64_tag                  44
+#define AllTypes_opt_sint32_tag                  45
+#define AllTypes_opt_sint64_tag                  46
+#define AllTypes_opt_bool_tag                    47
+#define AllTypes_opt_fixed32_tag                 48
+#define AllTypes_opt_sfixed32_tag                49
+#define AllTypes_opt_float_tag                   50
+#define AllTypes_opt_fixed64_tag                 51
+#define AllTypes_opt_sfixed64_tag                52
+#define AllTypes_opt_double_tag                  53
+#define AllTypes_opt_string_tag                  54
+#define AllTypes_opt_bytes_tag                   55
+#define AllTypes_opt_submsg_tag                  56
+#define AllTypes_opt_enum_tag                    57
+#define AllTypes_end_tag                         99
+
 /* Struct field encoding specification for nanopb */
 extern const pb_field_t SubMessage_fields[4];
-extern const pb_field_t AllTypes_fields[53];
+extern const pb_field_t EmptyMessage_fields[1];
+extern const pb_field_t Limits_fields[11];
+extern const pb_field_t AllTypes_fields[54];
 
-/* Check that field information fits in pb_field_t */
-#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
-STATIC_ASSERT((pb_membersize(AllTypes, req_submsg) < 256 && pb_membersize(AllTypes, rep_submsg[0]) < 256 && pb_membersize(AllTypes, opt_submsg) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_SubMessage_AllTypes)
-#endif
-
-#if !defined(PB_FIELD_32BIT)
-STATIC_ASSERT((pb_membersize(AllTypes, req_submsg) < 65536 && pb_membersize(AllTypes, rep_submsg[0]) < 65536 && pb_membersize(AllTypes, opt_submsg) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_SubMessage_AllTypes)
-#endif
-
-/* On some platforms (such as AVR), double is really float.
- * These are not directly supported by nanopb, but see example_avr_double.
- */
-STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES)
+/* Maximum encoded size of messages (where known) */
+#define SubMessage_size                          34
+#define EmptyMessage_size                        0
+#define Limits_size                              90
+#define AllTypes_size                            1362
 
 #ifdef __cplusplus
 } /* extern "C" */
diff --git a/tests/backwards_compatibility/alltypes_legacy.options b/tests/backwards_compatibility/alltypes_legacy.options
new file mode 100644
index 0000000..b31e3cf
--- /dev/null
+++ b/tests/backwards_compatibility/alltypes_legacy.options
@@ -0,0 +1,3 @@
+* max_size:16
+* max_count:5
+
diff --git a/tests/backwards_compatibility/alltypes_legacy.proto b/tests/backwards_compatibility/alltypes_legacy.proto
new file mode 100644
index 0000000..f5bc35c
--- /dev/null
+++ b/tests/backwards_compatibility/alltypes_legacy.proto
@@ -0,0 +1,110 @@
+syntax = "proto2";
+
+message SubMessage {
+    required string substuff1 = 1 [default = "1"];
+    required int32 substuff2 = 2 [default = 2];
+    optional fixed32 substuff3 = 3 [default = 3];
+}
+
+message EmptyMessage {
+
+}
+
+enum HugeEnum {
+    Negative = -2147483647; /* protoc doesn't accept -2147483648 here */
+    Positive =  2147483647;
+}
+
+message Limits {
+    required int32      int32_min  =  1 [default = 2147483647];
+    required int32      int32_max  =  2 [default = -2147483647];
+    required uint32     uint32_min =  3 [default = 4294967295];
+    required uint32     uint32_max =  4 [default = 0];
+    required int64      int64_min  =  5 [default = 9223372036854775807];
+    required int64      int64_max  =  6 [default = -9223372036854775807];
+    required uint64     uint64_min =  7 [default = 18446744073709551615];
+    required uint64     uint64_max =  8 [default = 0];
+    required HugeEnum   enum_min   =  9 [default = Positive];
+    required HugeEnum   enum_max   = 10 [default = Negative];
+}
+
+enum MyEnum {
+    Zero = 0;
+    First = 1;
+    Second = 2;
+    Truth = 42;
+}
+
+message AllTypes {
+    required int32      req_int32   = 1;
+    required int64      req_int64   = 2;
+    required uint32     req_uint32  = 3;
+    required uint64     req_uint64  = 4;
+    required sint32     req_sint32  = 5;
+    required sint64     req_sint64  = 6;
+    required bool       req_bool    = 7;
+    
+    required fixed32    req_fixed32 = 8;
+    required sfixed32   req_sfixed32= 9;
+    required float      req_float   = 10;
+    
+    required fixed64    req_fixed64 = 11;
+    required sfixed64   req_sfixed64= 12;
+    required double     req_double  = 13;
+    
+    required string     req_string  = 14;
+    required bytes      req_bytes   = 15;
+    required SubMessage req_submsg  = 16;
+    required MyEnum     req_enum    = 17;
+    
+    
+    repeated int32      rep_int32   = 21 [packed = true];
+    repeated int64      rep_int64   = 22 [packed = true];
+    repeated uint32     rep_uint32  = 23 [packed = true];
+    repeated uint64     rep_uint64  = 24 [packed = true];
+    repeated sint32     rep_sint32  = 25 [packed = true];
+    repeated sint64     rep_sint64  = 26 [packed = true];
+    repeated bool       rep_bool    = 27 [packed = true];
+    
+    repeated fixed32    rep_fixed32 = 28 [packed = true];
+    repeated sfixed32   rep_sfixed32= 29 [packed = true];
+    repeated float      rep_float   = 30 [packed = true];
+    
+    repeated fixed64    rep_fixed64 = 31 [packed = true];
+    repeated sfixed64   rep_sfixed64= 32 [packed = true];
+    repeated double     rep_double  = 33 [packed = true];
+    
+    repeated string     rep_string  = 34;
+    repeated bytes      rep_bytes   = 35;
+    repeated SubMessage rep_submsg  = 36;
+    repeated MyEnum     rep_enum    = 37 [packed = true];
+    
+    optional int32      opt_int32   = 41 [default = 4041];
+    optional int64      opt_int64   = 42 [default = 4042];
+    optional uint32     opt_uint32  = 43 [default = 4043];
+    optional uint64     opt_uint64  = 44 [default = 4044];
+    optional sint32     opt_sint32  = 45 [default = 4045];
+    optional sint64     opt_sint64  = 46 [default = 4046];
+    optional bool       opt_bool    = 47 [default = false];
+    
+    optional fixed32    opt_fixed32 = 48 [default = 4048];
+    optional sfixed32   opt_sfixed32= 49 [default = 4049];
+    optional float      opt_float   = 50 [default = 4050];
+    
+    optional fixed64    opt_fixed64 = 51 [default = 4051];
+    optional sfixed64   opt_sfixed64= 52 [default = 4052];
+    optional double     opt_double  = 53 [default = 4053];
+    
+    optional string     opt_string  = 54 [default = "4054"];
+    optional bytes      opt_bytes   = 55 [default = "4055"];
+    optional SubMessage opt_submsg  = 56;
+    optional MyEnum     opt_enum    = 57 [default = Second];
+
+    // Just to make sure that the size of the fields has been calculated
+    // properly, i.e. otherwise a bug in last field might not be detected.
+    required int32      end = 99;
+
+
+    extensions 200 to 255;
+}
+
diff --git a/tests/backwards_compatibility/decode_legacy.c b/tests/backwards_compatibility/decode_legacy.c
index 9dfe437..5f5b6bb 100644
--- a/tests/backwards_compatibility/decode_legacy.c
+++ b/tests/backwards_compatibility/decode_legacy.c
@@ -22,10 +22,7 @@
    the decoding and checks the fields. */
 bool check_alltypes(pb_istream_t *stream, int mode)
 {
-    AllTypes alltypes;
-    
-    /* Fill with garbage to better detect initialization errors */
-    memset(&alltypes, 0xAA, sizeof(alltypes));
+    AllTypes alltypes = {0};
     
     if (!pb_decode(stream, AllTypes_fields, &alltypes))
         return false;
diff --git a/tests/basic_buffer/SConscript b/tests/basic_buffer/SConscript
index 2546aaa..acaf5ff 100644
--- a/tests/basic_buffer/SConscript
+++ b/tests/basic_buffer/SConscript
@@ -2,8 +2,8 @@
 
 Import("env")
 
-enc = env.Program(["encode_buffer.c", "$COMMON/person.pb.c", "$COMMON/pb_encode.o"])
-dec = env.Program(["decode_buffer.c", "$COMMON/person.pb.c", "$COMMON/pb_decode.o"])
+enc = env.Program(["encode_buffer.c", "$COMMON/person.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = env.Program(["decode_buffer.c", "$COMMON/person.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_buffer.output"])
diff --git a/tests/basic_buffer/decode_buffer.c b/tests/basic_buffer/decode_buffer.c
index fae9e2f..291d164 100644
--- a/tests/basic_buffer/decode_buffer.c
+++ b/tests/basic_buffer/decode_buffer.c
@@ -16,7 +16,7 @@
 bool print_person(pb_istream_t *stream)
 {
     int i;
-    Person person;
+    Person person = Person_init_zero;
     
     if (!pb_decode(stream, Person_fields, &person))
         return false;
diff --git a/tests/basic_stream/SConscript b/tests/basic_stream/SConscript
index 46db8c4..7d66856 100644
--- a/tests/basic_stream/SConscript
+++ b/tests/basic_stream/SConscript
@@ -2,8 +2,8 @@
 
 Import("env")
 
-enc = env.Program(["encode_stream.c", "$COMMON/person.pb.c", "$COMMON/pb_encode.o"])
-dec = env.Program(["decode_stream.c", "$COMMON/person.pb.c", "$COMMON/pb_decode.o"])
+enc = env.Program(["encode_stream.c", "$COMMON/person.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = env.Program(["decode_stream.c", "$COMMON/person.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_stream.output"])
diff --git a/tests/basic_stream/decode_stream.c b/tests/basic_stream/decode_stream.c
index 667bf3c..798dcc5 100644
--- a/tests/basic_stream/decode_stream.c
+++ b/tests/basic_stream/decode_stream.c
@@ -12,7 +12,7 @@
 bool print_person(pb_istream_t *stream)
 {
     int i;
-    Person person;
+    Person person = Person_init_zero;
     
     if (!pb_decode(stream, Person_fields, &person))
         return false;
diff --git a/tests/buffer_only/SConscript b/tests/buffer_only/SConscript
index cddbb04..55b747b 100644
--- a/tests/buffer_only/SConscript
+++ b/tests/buffer_only/SConscript
@@ -18,10 +18,11 @@
 strict.Append(CFLAGS = strict['CORECFLAGS'])
 strict.Object("pb_decode_bufonly.o", "$NANOPB/pb_decode.c")
 strict.Object("pb_encode_bufonly.o", "$NANOPB/pb_encode.c")
+strict.Object("pb_common_bufonly.o", "$NANOPB/pb_common.c")
 
 # Now build and run the test normally.
-enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_bufonly.o"])
-dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_bufonly.o"])
+enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_bufonly.o", "pb_common_bufonly.o"])
+dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_bufonly.o", "pb_common_bufonly.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_alltypes.output"])
diff --git a/tests/callbacks/SConscript b/tests/callbacks/SConscript
index 9ec8a43..4452143 100644
--- a/tests/callbacks/SConscript
+++ b/tests/callbacks/SConscript
@@ -3,8 +3,8 @@
 Import("env")
 
 env.NanopbProto("callbacks")
-enc = env.Program(["encode_callbacks.c", "callbacks.pb.c", "$COMMON/pb_encode.o"])
-dec = env.Program(["decode_callbacks.c", "callbacks.pb.c", "$COMMON/pb_decode.o"])
+enc = env.Program(["encode_callbacks.c", "callbacks.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = env.Program(["decode_callbacks.c", "callbacks.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_callbacks.output"])
diff --git a/tests/callbacks/callbacks.proto b/tests/callbacks/callbacks.proto
index ccd1edd..96ac744 100644
--- a/tests/callbacks/callbacks.proto
+++ b/tests/callbacks/callbacks.proto
@@ -1,3 +1,5 @@
+syntax = "proto2";
+
 message SubMessage {
     optional string stringvalue = 1;
     repeated int32 int32value = 2;
diff --git a/tests/common/SConscript b/tests/common/SConscript
index 144f149..05e2f85 100644
--- a/tests/common/SConscript
+++ b/tests/common/SConscript
@@ -8,10 +8,41 @@
 # Protocol definitions for basic_buffer/stream tests
 env.NanopbProto("person")
 
+#--------------------------------------------
 # Binaries of the pb_decode.c and pb_encode.c
 # These are built using more strict warning flags.
 strict = env.Clone()
 strict.Append(CFLAGS = strict['CORECFLAGS'])
 strict.Object("pb_decode.o", "$NANOPB/pb_decode.c")
 strict.Object("pb_encode.o", "$NANOPB/pb_encode.c")
+strict.Object("pb_common.o", "$NANOPB/pb_common.c")
+
+#-----------------------------------------------
+# Binaries of pb_decode etc. with malloc support
+# Uses malloc_wrappers.c to count allocations.
+malloc_env = env.Clone()
+malloc_env.Append(CPPDEFINES = {'PB_ENABLE_MALLOC': 1,
+                                'PB_SYSTEM_HEADER': '\\"malloc_wrappers_syshdr.h\\"'})
+malloc_env.Append(CPPPATH = ["$COMMON"])
+
+if 'SYSHDR' in malloc_env:
+    malloc_env.Append(CPPDEFINES = {'PB_OLD_SYSHDR': malloc_env['SYSHDR']})
+
+# Disable libmudflap, because it will confuse valgrind
+# and other memory leak detection tools.
+if '-fmudflap' in env["CCFLAGS"]:
+    malloc_env["CCFLAGS"].remove("-fmudflap")
+    malloc_env["LINKFLAGS"].remove("-fmudflap")
+    malloc_env["LIBS"].remove("mudflap")
+
+malloc_strict = malloc_env.Clone()
+malloc_strict.Append(CFLAGS = malloc_strict['CORECFLAGS'])
+malloc_strict.Object("pb_decode_with_malloc.o", "$NANOPB/pb_decode.c")
+malloc_strict.Object("pb_encode_with_malloc.o", "$NANOPB/pb_encode.c")
+malloc_strict.Object("pb_common_with_malloc.o", "$NANOPB/pb_common.c")
+
+malloc_env.Object("malloc_wrappers.o", "malloc_wrappers.c")
+malloc_env.Depends("$NANOPB/pb.h", ["malloc_wrappers_syshdr.h", "malloc_wrappers.h"])
+
+Export("malloc_env")
 
diff --git a/tests/common/malloc_wrappers.c b/tests/common/malloc_wrappers.c
new file mode 100644
index 0000000..ad69f1c
--- /dev/null
+++ b/tests/common/malloc_wrappers.c
@@ -0,0 +1,54 @@
+#include "malloc_wrappers.h"
+#include <stdint.h>
+#include <assert.h>
+#include <string.h>
+
+static size_t alloc_count = 0;
+
+/* Allocate memory and place check values before and after. */
+void* malloc_with_check(size_t size)
+{
+    size_t size32 = (size + 3) / 4 + 3;
+    uint32_t *buf = malloc(size32 * sizeof(uint32_t));
+    buf[0] = size32;
+    buf[1] = 0xDEADBEEF;
+    buf[size32 - 1] = 0xBADBAD;
+    return buf + 2;
+}
+
+/* Free memory allocated with malloc_with_check() and do the checks. */
+void free_with_check(void *mem)
+{
+    uint32_t *buf = (uint32_t*)mem - 2;
+    assert(buf[1] == 0xDEADBEEF);
+    assert(buf[buf[0] - 1] == 0xBADBAD);
+    free(buf);
+}
+
+/* Track memory usage */
+void* counting_realloc(void *ptr, size_t size)
+{
+    /* Don't allocate crazy amounts of RAM when fuzzing */
+    if (size > 1000000)
+        return NULL;
+
+    if (!ptr && size)
+        alloc_count++;
+    
+    return realloc(ptr, size);
+}
+
+void counting_free(void *ptr)
+{
+    if (ptr)
+    {
+        assert(alloc_count > 0);
+        alloc_count--;
+        free(ptr);
+    }
+}
+
+size_t get_alloc_count()
+{
+    return alloc_count;
+}
diff --git a/tests/common/malloc_wrappers.h b/tests/common/malloc_wrappers.h
new file mode 100644
index 0000000..7eec795
--- /dev/null
+++ b/tests/common/malloc_wrappers.h
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+
+void* malloc_with_check(size_t size);
+void free_with_check(void *mem);
+void* counting_realloc(void *ptr, size_t size);
+void counting_free(void *ptr);
+size_t get_alloc_count();
diff --git a/tests/common/malloc_wrappers_syshdr.h b/tests/common/malloc_wrappers_syshdr.h
new file mode 100644
index 0000000..d295d9e
--- /dev/null
+++ b/tests/common/malloc_wrappers_syshdr.h
@@ -0,0 +1,15 @@
+/* This is just a wrapper in order to get our own malloc wrappers into nanopb core. */
+
+#define pb_realloc(ptr,size) counting_realloc(ptr,size)
+#define pb_free(ptr) counting_free(ptr)
+
+#ifdef PB_OLD_SYSHDR
+#include PB_OLD_SYSHDR
+#else
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#endif
+
+#include <malloc_wrappers.h>
diff --git a/tests/common/person.proto b/tests/common/person.proto
index dafcf93..becefdf 100644
--- a/tests/common/person.proto
+++ b/tests/common/person.proto
@@ -1,3 +1,5 @@
+syntax = "proto2";
+
 import "nanopb.proto";
 
 message Person {
diff --git a/tests/common/unittestproto.proto b/tests/common/unittestproto.proto
index eb3e7de..23b5b97 100644
--- a/tests/common/unittestproto.proto
+++ b/tests/common/unittestproto.proto
@@ -1,3 +1,5 @@
+syntax = "proto2";
+
 import 'nanopb.proto';
 
 message IntegerArray {
@@ -34,3 +36,8 @@
 message CallbackContainerContainer {
     required CallbackContainer submsg = 1;
 }
+
+message StringPointerContainer {
+    repeated string rep_str = 1 [(nanopb).type = FT_POINTER];
+}
+
diff --git a/tests/cxx_main_program/SConscript b/tests/cxx_main_program/SConscript
index e78c6b3..edb8812 100644
--- a/tests/cxx_main_program/SConscript
+++ b/tests/cxx_main_program/SConscript
@@ -11,14 +11,15 @@
 c = Copy("$TARGET", "$SOURCE")
 env.Command("pb_encode.cxx", "#../pb_encode.c", c)
 env.Command("pb_decode.cxx", "#../pb_decode.c", c)
+env.Command("pb_common.cxx", "#../pb_common.c", c)
 env.Command("alltypes.pb.h", "$BUILD/alltypes/alltypes.pb.h", c)
 env.Command("alltypes.pb.cxx", "$BUILD/alltypes/alltypes.pb.c", c)
 env.Command("encode_alltypes.cxx", "$BUILD/alltypes/encode_alltypes.c", c)
 env.Command("decode_alltypes.cxx", "$BUILD/alltypes/decode_alltypes.c", c)
 
 # Now build and run the test normally.
-enc = env.Program(["encode_alltypes.cxx", "alltypes.pb.cxx", "pb_encode.cxx"])
-dec = env.Program(["decode_alltypes.cxx", "alltypes.pb.cxx", "pb_decode.cxx"])
+enc = env.Program(["encode_alltypes.cxx", "alltypes.pb.cxx", "pb_encode.cxx", "pb_common.cxx"])
+dec = env.Program(["decode_alltypes.cxx", "alltypes.pb.cxx", "pb_decode.cxx", "pb_common.cxx"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_alltypes.output"])
diff --git a/tests/cyclic_messages/SConscript b/tests/cyclic_messages/SConscript
new file mode 100644
index 0000000..c782001
--- /dev/null
+++ b/tests/cyclic_messages/SConscript
@@ -0,0 +1,11 @@
+Import("env")
+
+# Encode cyclic messages with callback fields
+
+c = Copy("$TARGET", "$SOURCE")
+env.Command("cyclic_callback.proto", "cyclic.proto", c)
+env.NanopbProto(["cyclic_callback", "cyclic_callback.options"])
+
+enc_callback = env.Program(["encode_cyclic_callback.c", "cyclic_callback.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+
+
diff --git a/tests/cyclic_messages/cyclic.proto b/tests/cyclic_messages/cyclic.proto
new file mode 100644
index 0000000..8cab0b1
--- /dev/null
+++ b/tests/cyclic_messages/cyclic.proto
@@ -0,0 +1,27 @@
+// Test structures with cyclic references.
+// These can only be handled in pointer/callback mode,
+// see associated .options files.
+
+syntax = "proto2";
+
+message TreeNode
+{
+    optional int32 leaf = 1;
+    optional TreeNode left = 2;
+    optional TreeNode right = 3;
+}
+
+message Dictionary
+{
+    repeated KeyValuePair dictItem = 1;
+}
+
+message KeyValuePair
+{
+    required string key = 1;
+    optional string stringValue = 2;
+    optional int32 intValue = 3;
+    optional Dictionary dictValue = 4;
+    optional TreeNode treeValue = 5;
+}
+
diff --git a/tests/cyclic_messages/cyclic_callback.options b/tests/cyclic_messages/cyclic_callback.options
new file mode 100644
index 0000000..fd4e1e1
--- /dev/null
+++ b/tests/cyclic_messages/cyclic_callback.options
@@ -0,0 +1,7 @@
+TreeNode.left               type:FT_CALLBACK
+TreeNode.right              type:FT_CALLBACK
+
+Dictionary.data             type:FT_CALLBACK
+KeyValuePair.key            max_size:8
+KeyValuePair.stringValue    max_size:8
+KeyValuePair.treeValue      type:FT_CALLBACK
diff --git a/tests/cyclic_messages/encode_cyclic_callback.c b/tests/cyclic_messages/encode_cyclic_callback.c
new file mode 100644
index 0000000..7f67e70
--- /dev/null
+++ b/tests/cyclic_messages/encode_cyclic_callback.c
@@ -0,0 +1,148 @@
+/* This program parses an input string in a format a bit like JSON:
+ * {'foobar': 1234, 'xyz': 'abc', 'tree': [[[1, 2], 3], [4, 5]]}
+ * and encodes it as protobuf
+ *
+ * Note: The string parsing here is not in any way intended to be robust
+ *       nor safe against buffer overflows. It is just for this test.
+ */
+
+#include <pb_encode.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "cyclic_callback.pb.h"
+
+static char *find_end_of_item(char *p)
+{
+    int depth = 0;
+    do {
+        if (*p == '[' || *p == '{') depth++;
+        if (*p == ']' || *p == '}') depth--;
+        p++;
+    } while (depth > 0 || (*p != ',' && *p != '}'));
+    
+    if (*p == '}')
+        return p; /* End of parent dict */
+    
+    p++;
+    while (*p == ' ') p++;
+    return p;
+}
+
+/* Parse a tree in format [[1 2] 3] and encode it directly to protobuf */
+static bool encode_tree(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    TreeNode tree = TreeNode_init_zero;
+    char *p = (char*)*arg;
+    
+    if (*p == '[')
+    {
+        /* This is a tree branch */
+        p++;
+        tree.left.funcs.encode = encode_tree;
+        tree.left.arg = p;
+        
+        p = find_end_of_item(p);
+        tree.right.funcs.encode = encode_tree;
+        tree.right.arg = p;
+    }
+    else
+    {
+        /* This is a leaf node */
+        tree.has_leaf = true;
+        tree.leaf = atoi(p);
+    }
+    
+    return pb_encode_tag_for_field(stream, field) &&
+           pb_encode_submessage(stream, TreeNode_fields, &tree);
+}
+
+/* Parse a dictionary in format {'name': value} and encode it directly to protobuf */
+static bool encode_dictionary(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    int textlen;
+    char *p = (char*)*arg;
+    if (*p == '{') p++;
+    while (*p != '}')
+    {
+        KeyValuePair pair = KeyValuePair_init_zero;
+        
+        if (*p != '\'')
+            PB_RETURN_ERROR(stream, "invalid key, missing quote");
+        
+        p++; /* Starting quote of key */
+        textlen = strchr(p, '\'') - p;
+        strncpy(pair.key, p, textlen);
+        pair.key[textlen] = 0;
+        p += textlen + 2;
+        
+        while (*p == ' ') p++;
+        
+        if (*p == '[')
+        {
+            /* Value is a tree */
+            pair.treeValue.funcs.encode = encode_tree;
+            pair.treeValue.arg = p;
+        }
+        else if (*p == '\'')
+        {
+            /* Value is a string */
+            pair.has_stringValue = true;
+            p++;
+            textlen = strchr(p, '\'') - p;
+            strncpy(pair.stringValue, p, textlen);
+            pair.stringValue[textlen] = 0;
+        }
+        else if (*p == '{')
+        {
+            /* Value is a dictionary */
+            pair.has_dictValue = true;
+            pair.dictValue.dictItem.funcs.encode = encode_dictionary;
+            pair.dictValue.dictItem.arg = p;
+        }
+        else
+        {
+            /* Value is integer */
+            pair.has_intValue = true;
+            pair.intValue = atoi(p);
+        }
+        
+        p = find_end_of_item(p);
+        
+        if (!pb_encode_tag_for_field(stream, field))
+            return false;
+        
+        if (!pb_encode_submessage(stream, KeyValuePair_fields, &pair))
+            return false;
+    }
+
+    return true;
+}
+
+
+int main(int argc, char *argv[])
+{
+    uint8_t buffer[256];
+    pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+    Dictionary dict = Dictionary_init_zero;
+    
+    if (argc <= 1)
+    {
+        fprintf(stderr, "Usage: %s \"{'foobar': 1234, ...}\"\n", argv[0]);
+        return 1;
+    }
+    
+    dict.dictItem.funcs.encode = encode_dictionary;
+    dict.dictItem.arg = argv[1];
+
+    if (!pb_encode(&stream, Dictionary_fields, &dict))
+    {
+        fprintf(stderr, "Encoding error: %s\n", PB_GET_ERROR(&stream));
+        return 1;
+    }
+    
+    fwrite(buffer, 1, stream.bytes_written, stdout);
+    return 0;
+}
+
+
diff --git a/tests/decode_unittests/decode_unittests.c b/tests/decode_unittests/decode_unittests.c
index 1be0191..dc1e719 100644
--- a/tests/decode_unittests/decode_unittests.c
+++ b/tests/decode_unittests/decode_unittests.c
@@ -1,4 +1,6 @@
 /* This includes the whole .c file to get access to static functions. */
+#define PB_ENABLE_MALLOC
+#include "pb_common.c"
 #include "pb_decode.c"
 
 #include <stdio.h>
@@ -85,6 +87,23 @@
               pb_decode_varint(&s, (uint64_t*)&i) && i == -1));
         TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"),
               pb_decode_varint(&s, &u) && u == UINT64_MAX));
+        TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"),
+              !pb_decode_varint(&s, &u)));
+    }
+    
+    {
+        pb_istream_t s;
+        uint32_t u;
+        
+        COMMENT("Test pb_decode_varint32");
+        TEST((s = S("\x00"), pb_decode_varint32(&s, &u) && u == 0));
+        TEST((s = S("\x01"), pb_decode_varint32(&s, &u) && u == 1));
+        TEST((s = S("\xAC\x02"), pb_decode_varint32(&s, &u) && u == 300));
+        TEST((s = S("\xFF\xFF\xFF\xFF\x0F"), pb_decode_varint32(&s, &u) && u == UINT32_MAX));
+        TEST((s = S("\xFF\xFF\xFF\xFF\x8F\x00"), pb_decode_varint32(&s, &u) && u == UINT32_MAX));
+        TEST((s = S("\xFF\xFF\xFF\xFF\x10"), !pb_decode_varint32(&s, &u)));
+        TEST((s = S("\xFF\xFF\xFF\xFF\x40"), !pb_decode_varint32(&s, &u)));
+        TEST((s = S("\xFF\xFF\xFF\xFF\xFF\x01"), !pb_decode_varint32(&s, &u)));
     }
     
     {
@@ -107,16 +126,16 @@
     }
     
     {
-        pb_istream_t s = S("\x01\xFF\xFF\x03");
+        pb_istream_t s = S("\x01\x00");
         pb_field_t f = {1, PB_LTYPE_VARINT, 0, 0, 4, 0, 0};
         uint32_t d;
         COMMENT("Test pb_dec_varint using uint32_t")
         TEST(pb_dec_varint(&s, &f, &d) && d == 1)
         
         /* Verify that no more than data_size is written. */
-        d = 0;
+        d = 0xFFFFFFFF;
         f.data_size = 1;
-        TEST(pb_dec_varint(&s, &f, &d) && (d == 0xFF || d == 0xFF000000))
+        TEST(pb_dec_varint(&s, &f, &d) && (d == 0xFFFFFF00 || d == 0x00FFFFFF))
     }
     
     {
@@ -134,9 +153,9 @@
     {
         pb_istream_t s;
         pb_field_t f = {1, PB_LTYPE_SVARINT, 0, 0, 8, 0, 0};
-        uint64_t d;
+        int64_t d;
         
-        COMMENT("Test pb_dec_svarint using uint64_t")
+        COMMENT("Test pb_dec_svarint using int64_t")
         TEST((s = S("\x01"), pb_dec_svarint(&s, &f, &d) && d == -1))
         TEST((s = S("\x02"), pb_dec_svarint(&s, &f, &d) && d == 1))
         TEST((s = S("\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"), pb_dec_svarint(&s, &f, &d) && d == INT64_MAX))
@@ -145,6 +164,50 @@
     
     {
         pb_istream_t s;
+        pb_field_t f = {1, PB_LTYPE_SVARINT, 0, 0, 4, 0, 0};
+        int32_t d;
+        
+        COMMENT("Test pb_dec_svarint overflow detection using int32_t");
+        TEST((s = S("\xfe\xff\xff\xff\x0f"), pb_dec_svarint(&s, &f, &d)));
+        TEST((s = S("\xfe\xff\xff\xff\x10"), !pb_dec_svarint(&s, &f, &d)));
+        TEST((s = S("\xff\xff\xff\xff\x0f"), pb_dec_svarint(&s, &f, &d)));
+        TEST((s = S("\xff\xff\xff\xff\x10"), !pb_dec_svarint(&s, &f, &d)));
+    }
+    
+    {
+        pb_istream_t s;
+        pb_field_t f = {1, PB_LTYPE_SVARINT, 0, 0, 4, 0, 0};
+        uint32_t d;
+        
+        COMMENT("Test pb_dec_uvarint using uint32_t")
+        TEST((s = S("\x01"), pb_dec_uvarint(&s, &f, &d) && d == 1))
+        TEST((s = S("\x02"), pb_dec_uvarint(&s, &f, &d) && d == 2))
+        TEST((s = S("\xff\xff\xff\xff\x0f"), pb_dec_uvarint(&s, &f, &d) && d == UINT32_MAX))
+    }
+    
+    {
+        pb_istream_t s;
+        pb_field_t f = {1, PB_LTYPE_SVARINT, 0, 0, 8, 0, 0};
+        uint64_t d;
+        
+        COMMENT("Test pb_dec_uvarint using uint64_t")
+        TEST((s = S("\x01"), pb_dec_uvarint(&s, &f, &d) && d == 1))
+        TEST((s = S("\x02"), pb_dec_uvarint(&s, &f, &d) && d == 2))
+        TEST((s = S("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01"), pb_dec_uvarint(&s, &f, &d) && d == UINT64_MAX))
+    }
+    
+    {
+        pb_istream_t s;
+        pb_field_t f = {1, PB_LTYPE_SVARINT, 0, 0, 4, 0, 0};
+        uint32_t d;
+        
+        COMMENT("Test pb_dec_uvarint overflow detection using int32_t");
+        TEST((s = S("\xff\xff\xff\xff\x0f"), pb_dec_uvarint(&s, &f, &d)));
+        TEST((s = S("\xff\xff\xff\xff\x10"), !pb_dec_uvarint(&s, &f, &d)));
+    }
+    
+    {
+        pb_istream_t s;
         pb_field_t f = {1, PB_LTYPE_FIXED32, 0, 0, 4, 0, 0};
         float d;
         
@@ -168,7 +231,7 @@
     
     {
         pb_istream_t s;
-        struct { size_t size; uint8_t bytes[5]; } d;
+        struct { pb_size_t size; uint8_t bytes[5]; } d;
         pb_field_t f = {1, PB_LTYPE_BYTES, 0, 0, sizeof(d), 0, 0};
         
         COMMENT("Test pb_dec_bytes")
@@ -249,7 +312,7 @@
     {
         pb_istream_t s;
         CallbackArray dest;
-        struct { size_t size; uint8_t bytes[10]; } ref;
+        struct { pb_size_t size; uint8_t bytes[10]; } ref;
         dest.data.funcs.decode = &callback_check;
         dest.data.arg = &ref;
         
@@ -291,6 +354,14 @@
     
     {
         pb_istream_t s;
+        IntegerArray dest;
+        
+        COMMENT("Testing pb_decode with invalid tag numbers")
+        TEST((s = S("\x9f\xea"), !pb_decode(&s, IntegerArray_fields, &dest)));
+    }
+    
+    {
+        pb_istream_t s;
         IntegerContainer dest = {{0}};
         
         COMMENT("Testing pb_decode_delimited")
@@ -299,6 +370,28 @@
               dest.submsg.data_count == 5)
     }
     
+    {
+        pb_istream_t s = {0};
+        void *data = NULL;
+        
+        COMMENT("Testing allocate_field")
+        TEST(allocate_field(&s, &data, 10, 10) && data != NULL);
+        TEST(allocate_field(&s, &data, 10, 20) && data != NULL);
+        
+        {
+            void *oldvalue = data;
+            size_t very_big = (size_t)-1;
+            size_t somewhat_big = very_big / 2 + 1;
+            size_t not_so_big = (size_t)1 << (4 * sizeof(size_t));
+        
+            TEST(!allocate_field(&s, &data, very_big, 2) && data == oldvalue);
+            TEST(!allocate_field(&s, &data, somewhat_big, 2) && data == oldvalue);
+            TEST(!allocate_field(&s, &data, not_so_big, not_so_big) && data == oldvalue);
+        }
+        
+        pb_free(data);
+    }
+    
     if (status != 0)
         fprintf(stdout, "\n\nSome tests FAILED!\n");
     
diff --git a/tests/encode_unittests/encode_unittests.c b/tests/encode_unittests/encode_unittests.c
index 06935f9..583af5c 100644
--- a/tests/encode_unittests/encode_unittests.c
+++ b/tests/encode_unittests/encode_unittests.c
@@ -1,4 +1,5 @@
 /* This includes the whole .c file to get access to static functions. */
+#include "pb_common.c"
 #include "pb_encode.c"
 
 #include <stdio.h>
@@ -169,7 +170,7 @@
     {
         uint8_t buffer[30];
         pb_ostream_t s;
-        struct { size_t size; uint8_t bytes[5]; } value = {5, {'x', 'y', 'z', 'z', 'y'}};
+        struct { pb_size_t size; uint8_t bytes[5]; } value = {5, {'x', 'y', 'z', 'z', 'y'}};
     
         COMMENT("Test pb_enc_bytes")
         TEST(WRITES(pb_enc_bytes(&s, &BytesMessage_fields[0], &value), "\x05xyzzy"))
@@ -330,6 +331,23 @@
         TEST(s.bytes_written == StringMessage_size);
     }
     
+    {
+        uint8_t buffer[128];
+        pb_ostream_t s;
+        StringPointerContainer msg = StringPointerContainer_init_zero;
+        char *strs[1] = {NULL};
+        char zstr[] = "Z";
+        
+        COMMENT("Test string pointer encoding.");
+        
+        msg.rep_str = strs;
+        msg.rep_str_count = 1;
+        TEST(WRITES(pb_encode(&s, StringPointerContainer_fields, &msg), "\x0a\x00"))
+        
+        strs[0] = zstr;
+        TEST(WRITES(pb_encode(&s, StringPointerContainer_fields, &msg), "\x0a\x01Z"))
+    }
+    
     if (status != 0)
         fprintf(stdout, "\n\nSome tests FAILED!\n");
     
diff --git a/tests/enum_sizes/SConscript b/tests/enum_sizes/SConscript
new file mode 100644
index 0000000..048592e
--- /dev/null
+++ b/tests/enum_sizes/SConscript
@@ -0,0 +1,12 @@
+# Test that different sizes of enum fields are properly encoded and decoded.
+
+Import('env')
+
+env.NanopbProto('enumsizes')
+
+p = env.Program(["enumsizes_unittests.c",
+                 "enumsizes.pb.c",
+                 "$COMMON/pb_encode.o",
+                 "$COMMON/pb_decode.o",
+                 "$COMMON/pb_common.o"])
+env.RunTest(p)
diff --git a/tests/enum_sizes/enumsizes.proto b/tests/enum_sizes/enumsizes.proto
new file mode 100644
index 0000000..a85d416
--- /dev/null
+++ b/tests/enum_sizes/enumsizes.proto
@@ -0,0 +1,86 @@
+/* Test handling of enums with different value ranges.
+ * Depending on compiler and the packed_enum setting, the datatypes
+ * for enums can be either signed or unsigned. In past this has caused
+ * a bit of a problem for the encoder/decoder (issue #164).
+ */
+
+syntax = "proto2";
+
+import 'nanopb.proto';
+
+option (nanopb_fileopt).long_names = false;
+
+enum UnpackedUint8 {
+    option (nanopb_enumopt).packed_enum = false;
+    UU8_MIN = 0;
+    UU8_MAX = 255;
+}
+
+enum PackedUint8 {
+    option (nanopb_enumopt).packed_enum = true;
+    PU8_MIN = 0;
+    PU8_MAX = 255;
+}
+
+enum UnpackedInt8 {
+    option (nanopb_enumopt).packed_enum = false;
+    UI8_MIN = -128;
+    UI8_MAX = 127;
+}
+
+enum PackedInt8 {
+    option (nanopb_enumopt).packed_enum = true;
+    PI8_MIN = -128;
+    PI8_MAX = 127;
+}
+
+enum UnpackedUint16 {
+    option (nanopb_enumopt).packed_enum = false;
+    UU16_MIN = 0;
+    UU16_MAX = 65535;
+}
+
+enum PackedUint16 {
+    option (nanopb_enumopt).packed_enum = true;
+    PU16_MIN = 0;
+    PU16_MAX = 65535;
+}
+
+enum UnpackedInt16 {
+    option (nanopb_enumopt).packed_enum = false;
+    UI16_MIN = -32768;
+    UI16_MAX = 32767;
+}
+
+enum PackedInt16 {
+    option (nanopb_enumopt).packed_enum = true;
+    PI16_MIN = -32768;
+    PI16_MAX = 32767;
+}
+
+/* Protobuf supports enums up to 32 bits.
+ * The 32 bit case is covered by HugeEnum in the alltypes test.
+ */
+
+message PackedEnums {
+    required PackedUint8  u8_min  = 1;
+    required PackedUint8  u8_max  = 2;
+    required PackedInt8   i8_min  = 3;
+    required PackedInt8   i8_max  = 4;
+    required PackedUint16 u16_min = 5;
+    required PackedUint16 u16_max = 6;
+    required PackedInt16  i16_min = 7;
+    required PackedInt16  i16_max = 8;
+}
+
+message UnpackedEnums {
+    required UnpackedUint8  u8_min  = 1;
+    required UnpackedUint8  u8_max  = 2;
+    required UnpackedInt8   i8_min  = 3;
+    required UnpackedInt8   i8_max  = 4;
+    required UnpackedUint16 u16_min = 5;
+    required UnpackedUint16 u16_max = 6;
+    required UnpackedInt16  i16_min = 7;
+    required UnpackedInt16  i16_max = 8;
+}
+
diff --git a/tests/enum_sizes/enumsizes_unittests.c b/tests/enum_sizes/enumsizes_unittests.c
new file mode 100644
index 0000000..5606895
--- /dev/null
+++ b/tests/enum_sizes/enumsizes_unittests.c
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <string.h>
+#include <pb_decode.h>
+#include <pb_encode.h>
+#include "unittests.h"
+#include "enumsizes.pb.h"
+
+int main()
+{
+    int status = 0;
+
+    UnpackedEnums msg1 = {
+        UU8_MIN,  UU8_MAX,
+        UI8_MIN,  UI8_MAX,
+        UU16_MIN, UU16_MAX,
+        UI16_MIN, UI16_MAX,
+    };
+    
+    PackedEnums msg2;
+    UnpackedEnums msg3;
+    uint8_t buf[256];
+    size_t msgsize;
+    
+    COMMENT("Step 1: unpacked enums -> protobuf");
+    {
+        pb_ostream_t s = pb_ostream_from_buffer(buf, sizeof(buf));
+        TEST(pb_encode(&s, UnpackedEnums_fields, &msg1));
+        msgsize = s.bytes_written;
+    }
+    
+    COMMENT("Step 2: protobuf -> packed enums");
+    {
+        pb_istream_t s = pb_istream_from_buffer(buf, msgsize);
+        TEST(pb_decode(&s, PackedEnums_fields, &msg2));
+        
+        TEST(msg1.u8_min  == (int)msg2.u8_min);
+        TEST(msg1.u8_max  == (int)msg2.u8_max);
+        TEST(msg1.i8_min  == (int)msg2.i8_min);
+        TEST(msg1.i8_max  == (int)msg2.i8_max);
+        TEST(msg1.u16_min == (int)msg2.u16_min);
+        TEST(msg1.u16_max == (int)msg2.u16_max);
+        TEST(msg1.i16_min == (int)msg2.i16_min);
+        TEST(msg1.i16_max == (int)msg2.i16_max);
+    }
+    
+    COMMENT("Step 3: packed enums -> protobuf");
+    {
+        pb_ostream_t s = pb_ostream_from_buffer(buf, sizeof(buf));
+        TEST(pb_encode(&s, PackedEnums_fields, &msg2));
+        msgsize = s.bytes_written;
+    }
+    
+    COMMENT("Step 4: protobuf -> unpacked enums");
+    {
+        pb_istream_t s = pb_istream_from_buffer(buf, msgsize);
+        TEST(pb_decode(&s, UnpackedEnums_fields, &msg3));
+
+        TEST(msg1.u8_min  == (int)msg3.u8_min);
+        TEST(msg1.u8_max  == (int)msg3.u8_max);
+        TEST(msg1.i8_min  == (int)msg3.i8_min);
+        TEST(msg1.i8_max  == (int)msg3.i8_max);
+        TEST(msg1.u16_min == (int)msg2.u16_min);
+        TEST(msg1.u16_max == (int)msg2.u16_max);
+        TEST(msg1.i16_min == (int)msg2.i16_min);
+        TEST(msg1.i16_max == (int)msg2.i16_max);
+    }
+
+    if (status != 0)
+        fprintf(stdout, "\n\nSome tests FAILED!\n");
+
+    return status;
+}
diff --git a/tests/enum_to_string/SConscript b/tests/enum_to_string/SConscript
new file mode 100644
index 0000000..e86fcca
--- /dev/null
+++ b/tests/enum_to_string/SConscript
@@ -0,0 +1,7 @@
+# Test enum to string functionality
+
+Import('env')
+env.NanopbProto("enum.proto")
+p = env.Program(["enum_to_string.c", "enum.pb.c"])
+env.RunTest(p)
+
diff --git a/tests/enum_to_string/enum.proto b/tests/enum_to_string/enum.proto
new file mode 100644
index 0000000..07c6736
--- /dev/null
+++ b/tests/enum_to_string/enum.proto
@@ -0,0 +1,19 @@
+/* Test enum to string function generation */
+
+syntax = "proto2";
+
+import "nanopb.proto";
+
+option (nanopb_fileopt).enum_to_string = true;
+
+enum MyEnum {
+    VALUE1 = 1;
+    VALUE2 = 2;
+    VALUE15 = 15;
+}
+
+enum MyShortNameEnum {
+    option (nanopb_enumopt).long_names = false;
+    MSNE_VALUE256 = 256;
+}
+
diff --git a/tests/enum_to_string/enum_to_string.c b/tests/enum_to_string/enum_to_string.c
new file mode 100644
index 0000000..c4fb31d
--- /dev/null
+++ b/tests/enum_to_string/enum_to_string.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include "unittests.h"
+#include "enum.pb.h"
+
+int main()
+{
+    int status = 0;
+    TEST(strcmp(MyEnum_name(MyEnum_VALUE1), "VALUE1") == 0);
+    TEST(strcmp(MyEnum_name(MyEnum_VALUE2), "VALUE2") == 0);
+    TEST(strcmp(MyEnum_name(MyEnum_VALUE15), "VALUE15") == 0);
+    TEST(strcmp(MyShortNameEnum_name(MSNE_VALUE256), "MSNE_VALUE256") == 0);
+    TEST(strcmp(MyShortNameEnum_name(9999), "unknown") == 0);
+    
+    if (status != 0)
+        fprintf(stdout, "\n\nSome tests FAILED!\n");
+
+    return status;
+}
+
diff --git a/tests/extensions/SConscript b/tests/extensions/SConscript
index 26fc5a3..a2c8742 100644
--- a/tests/extensions/SConscript
+++ b/tests/extensions/SConscript
@@ -8,8 +8,8 @@
 incpath.Append(CPPPATH = '$BUILD/alltypes')
 
 incpath.NanopbProto(["extensions", "extensions.options"])
-enc = incpath.Program(["encode_extensions.c", "extensions.pb.c", "$BUILD/alltypes/alltypes.pb$OBJSUFFIX", "$COMMON/pb_encode.o"])
-dec = incpath.Program(["decode_extensions.c", "extensions.pb.c", "$BUILD/alltypes/alltypes.pb$OBJSUFFIX", "$COMMON/pb_decode.o"])
+enc = incpath.Program(["encode_extensions.c", "extensions.pb.c", "$BUILD/alltypes/alltypes.pb$OBJSUFFIX", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = incpath.Program(["decode_extensions.c", "extensions.pb.c", "$BUILD/alltypes/alltypes.pb$OBJSUFFIX", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_extensions.output"])
diff --git a/tests/extensions/extensions.proto b/tests/extensions/extensions.proto
index da8432e..fcd5b43 100644
--- a/tests/extensions/extensions.proto
+++ b/tests/extensions/extensions.proto
@@ -1,3 +1,5 @@
+syntax = "proto2";
+
 import 'alltypes.proto';
 
 extend AllTypes {
@@ -7,8 +9,8 @@
 message ExtensionMessage {
     extend AllTypes {
         optional ExtensionMessage AllTypes_extensionfield2 = 254;
-	required ExtensionMessage AllTypes_extensionfield3 = 253;
-	repeated ExtensionMessage AllTypes_extensionfield4 = 252;
+        // required ExtensionMessage AllTypes_extensionfield3 = 253; // No longer allowed by protobuf 3
+        repeated ExtensionMessage AllTypes_extensionfield4 = 252;
     }
     
     required string test1 = 1;
diff --git a/tests/field_size_16/SConscript b/tests/field_size_16/SConscript
index 8fee004..99bc344 100644
--- a/tests/field_size_16/SConscript
+++ b/tests/field_size_16/SConscript
@@ -19,10 +19,14 @@
 strict.Append(CFLAGS = strict['CORECFLAGS'])
 strict.Object("pb_decode_fields16.o", "$NANOPB/pb_decode.c")
 strict.Object("pb_encode_fields16.o", "$NANOPB/pb_encode.c")
+strict.Object("pb_common_fields16.o", "$NANOPB/pb_common.c")
 
 # Now build and run the test normally.
-enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_fields16.o"])
-dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_fields16.o"])
+enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_fields16.o", "pb_common_fields16.o"])
+dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_fields16.o", "pb_common_fields16.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_alltypes.output"])
+
+env.RunTest("optionals.output", enc, ARGS = ['1'])
+env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1'])
diff --git a/tests/field_size_16/alltypes.options b/tests/field_size_16/alltypes.options
index b31e3cf..78dd08d 100644
--- a/tests/field_size_16/alltypes.options
+++ b/tests/field_size_16/alltypes.options
@@ -1,3 +1,4 @@
 * max_size:16
 * max_count:5
+*.*fbytes fixed_length:true max_size:4
 
diff --git a/tests/field_size_16/alltypes.proto b/tests/field_size_16/alltypes.proto
index 7494853..4e27059 100644
--- a/tests/field_size_16/alltypes.proto
+++ b/tests/field_size_16/alltypes.proto
@@ -1,3 +1,5 @@
+syntax = "proto2";
+
 message SubMessage {
     required string substuff1 = 1 [default = "1"];
     required int32 substuff2 = 2 [default = 2];
@@ -55,7 +57,7 @@
     required SubMessage req_submsg  = 16;
     required MyEnum     req_enum    = 17;
     required EmptyMessage req_emptymsg = 18;
-    
+    required bytes      req_fbytes  = 19;
     
     repeated int32      rep_int32   = 21;
     repeated int64      rep_int64   = 22;
@@ -78,6 +80,7 @@
     repeated SubMessage rep_submsg  = 10036;
     repeated MyEnum     rep_enum    = 10037;
     repeated EmptyMessage rep_emptymsg = 10038;
+    repeated bytes      rep_fbytes  = 10039;
     
     optional int32      opt_int32   = 10041 [default = 4041];
     optional int64      opt_int64   = 10042 [default = 4042];
@@ -96,10 +99,17 @@
     optional double     opt_double  = 10053 [default = 4053];
     
     optional string     opt_string  = 10054 [default = "4054"];
-    optional bytes      opt_bytes   = 10055 [default = "4055"];
+    optional bytes      opt_bytes   = 10055 [default = "\x34\x5C\x00\xff"];
     optional SubMessage opt_submsg  = 10056;
     optional MyEnum     opt_enum    = 10057 [default = Second];
     optional EmptyMessage opt_emptymsg = 10058;
+    optional bytes      opt_fbytes  = 10059 [default = "4059"];
+
+    oneof oneof
+    {
+        SubMessage oneof_msg1 = 10060;
+        EmptyMessage oneof_msg2 = 10061;
+    }
 
     // Check that extreme integer values are handled correctly
     required Limits     req_limits = 98;
@@ -107,5 +117,7 @@
     // Just to make sure that the size of the fields has been calculated
     // properly, i.e. otherwise a bug in last field might not be detected.
     required int32      end = 10099;
+
+    extensions 200 to 255;
 }
 
diff --git a/tests/field_size_16_proto3/SConscript b/tests/field_size_16_proto3/SConscript
new file mode 100644
index 0000000..4a8e16d
--- /dev/null
+++ b/tests/field_size_16_proto3/SConscript
@@ -0,0 +1,34 @@
+# Version of AllTypes test case for protobuf 3 file format.
+
+Import("env")
+
+import re
+match = None
+if 'PROTOC_VERSION' in env:
+    match = re.search('([0-9]+).([0-9]+).([0-9]+)', env['PROTOC_VERSION'])
+
+if match:
+    version = list(map(int, match.groups()))
+
+# proto3 syntax is supported by protoc >= 3.0.0
+if env.GetOption('clean') or (match and version[0] >= 3):
+
+    env.NanopbProto(["alltypes", "alltypes.options"])
+
+    # Define the compilation options
+    opts = env.Clone()
+    opts.Append(CPPDEFINES = {'PB_FIELD_16BIT': 1})
+
+    # Build new version of core
+    strict = opts.Clone()
+    strict.Append(CFLAGS = strict['CORECFLAGS'])
+    strict.Object("pb_decode_fields16.o", "$NANOPB/pb_decode.c")
+    strict.Object("pb_encode_fields16.o", "$NANOPB/pb_encode.c")
+    strict.Object("pb_common_fields16.o", "$NANOPB/pb_common.c")
+
+    # Now build and run the test normally.
+    enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_fields16.o", "pb_common_fields16.o"])
+    dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_fields16.o", "pb_common_fields16.o"])
+
+    env.RunTest(enc)
+    env.RunTest([dec, "encode_alltypes.output"])
diff --git a/tests/field_size_16_proto3/alltypes.options b/tests/field_size_16_proto3/alltypes.options
new file mode 100644
index 0000000..edfbe78
--- /dev/null
+++ b/tests/field_size_16_proto3/alltypes.options
@@ -0,0 +1,4 @@
+* max_size:16
+* max_count:5
+*.*fbytes fixed_length:true max_size:4
+SubMessage.substuff1 max_size:256
diff --git a/tests/field_size_16_proto3/alltypes.proto b/tests/field_size_16_proto3/alltypes.proto
new file mode 100644
index 0000000..f66109e
--- /dev/null
+++ b/tests/field_size_16_proto3/alltypes.proto
@@ -0,0 +1,100 @@
+syntax = "proto3";
+// package name placeholder
+
+message SubMessage {
+    string substuff1 = 1;
+    int32 substuff2 = 2;
+    fixed32 substuff3 = 3;
+}
+
+message EmptyMessage {
+
+}
+
+enum HugeEnum {
+    HE_Zero = 0;
+    Negative = -2147483647; /* protoc doesn't accept -2147483648 here */
+    Positive =  2147483647;
+}
+
+message Limits {
+    int32      int32_min  =  1;
+    int32      int32_max  =  2;
+    uint32     uint32_min =  3;
+    uint32     uint32_max =  4;
+    int64      int64_min  =  5;
+    int64      int64_max  =  6;
+    uint64     uint64_min =  7;
+    uint64     uint64_max =  8;
+    HugeEnum   enum_min   =  9;
+    HugeEnum   enum_max   = 10;
+}
+
+enum MyEnum {
+    Zero = 0;
+    First = 1;
+    Second = 2;
+    Truth = 42;
+}
+
+message AllTypes {
+    int32      sng_int32   = 1;
+    int64      sng_int64   = 2;
+    uint32     sng_uint32  = 3;
+    uint64     sng_uint64  = 4;
+    sint32     sng_sint32  = 5;
+    sint64     sng_sint64  = 6;
+    bool       sng_bool    = 7;
+    
+    fixed32    sng_fixed32 = 8;
+    sfixed32   sng_sfixed32= 9;
+    float      sng_float   = 10;
+    
+    fixed64    sng_fixed64 = 11;
+    sfixed64   sng_sfixed64= 12;
+    double     sng_double  = 13;
+    
+    string     sng_string  = 14;
+    bytes      sng_bytes   = 15;
+    SubMessage sng_submsg  = 16;
+    MyEnum     sng_enum    = 17;
+    EmptyMessage sng_emptymsg = 18;
+    bytes      sng_fbytes  = 19;
+
+    repeated int32      rep_int32   = 21 [packed = true];
+    repeated int64      rep_int64   = 22 [packed = true];
+    repeated uint32     rep_uint32  = 23 [packed = true];
+    repeated uint64     rep_uint64  = 24 [packed = true];
+    repeated sint32     rep_sint32  = 25 [packed = true];
+    repeated sint64     rep_sint64  = 26 [packed = true];
+    repeated bool       rep_bool    = 27 [packed = true];
+    
+    repeated fixed32    rep_fixed32 = 28 [packed = true];
+    repeated sfixed32   rep_sfixed32= 29 [packed = true];
+    repeated float      rep_float   = 30 [packed = true];
+    
+    repeated fixed64    rep_fixed64 = 31 [packed = true];
+    repeated sfixed64   rep_sfixed64= 32 [packed = true];
+    repeated double     rep_double  = 33 [packed = true];
+    
+    repeated string     rep_string  = 34;
+    repeated bytes      rep_bytes   = 35;
+    repeated SubMessage rep_submsg  = 36;
+    repeated MyEnum     rep_enum    = 37 [packed = true];
+    repeated EmptyMessage rep_emptymsg = 38;
+    repeated bytes      rep_fbytes  = 39;
+    
+    oneof oneof
+    {
+        SubMessage oneof_msg1 = 59;
+        EmptyMessage oneof_msg2 = 60;
+    }
+    
+    // Check that extreme integer values are handled correctly
+    Limits     req_limits = 98;
+
+    // Just to make sure that the size of the fields has been calculated
+    // properly, i.e. otherwise a bug in last field might not be detected.
+    int32      end = 99;
+}
+
diff --git a/tests/field_size_16_proto3/decode_alltypes.c b/tests/field_size_16_proto3/decode_alltypes.c
new file mode 100644
index 0000000..6611f8c
--- /dev/null
+++ b/tests/field_size_16_proto3/decode_alltypes.c
@@ -0,0 +1,167 @@
+/* Tests the decoding of all types.
+ * This is the counterpart of test_encode3.
+ * Run e.g. ./test_encode3 | ./test_decode3
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pb_decode.h>
+#include "alltypes.pb.h"
+#include "test_helpers.h"
+
+#define TEST(x) if (!(x)) { \
+    printf("Test " #x " failed.\n"); \
+    return false; \
+    }
+
+/* This function is called once from main(), it handles
+   the decoding and checks the fields. */
+bool check_alltypes(pb_istream_t *stream, int mode)
+{
+    AllTypes alltypes = AllTypes_init_zero;
+
+    /* Fill with garbage to better detect initialization errors */
+    memset(&alltypes, 0xAA, sizeof(alltypes));
+
+    if (!pb_decode(stream, AllTypes_fields, &alltypes))
+        return false;
+
+    TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0);
+    TEST(alltypes.rep_int64_count == 5 && alltypes.rep_int64[4] == -2002 && alltypes.rep_int64[0] == 0);
+    TEST(alltypes.rep_uint32_count == 5 && alltypes.rep_uint32[4] == 2003 && alltypes.rep_uint32[0] == 0);
+    TEST(alltypes.rep_uint64_count == 5 && alltypes.rep_uint64[4] == 2004 && alltypes.rep_uint64[0] == 0);
+    TEST(alltypes.rep_sint32_count == 5 && alltypes.rep_sint32[4] == -2005 && alltypes.rep_sint32[0] == 0);
+    TEST(alltypes.rep_sint64_count == 5 && alltypes.rep_sint64[4] == -2006 && alltypes.rep_sint64[0] == 0);
+    TEST(alltypes.rep_bool_count == 5 && alltypes.rep_bool[4] == true && alltypes.rep_bool[0] == false);
+
+    TEST(alltypes.rep_fixed32_count == 5 && alltypes.rep_fixed32[4] == 2008 && alltypes.rep_fixed32[0] == 0);
+    TEST(alltypes.rep_sfixed32_count == 5 && alltypes.rep_sfixed32[4] == -2009 && alltypes.rep_sfixed32[0] == 0);
+    TEST(alltypes.rep_float_count == 5 && alltypes.rep_float[4] == 2010.0f && alltypes.rep_float[0] == 0.0f);
+
+    TEST(alltypes.rep_fixed64_count == 5 && alltypes.rep_fixed64[4] == 2011 && alltypes.rep_fixed64[0] == 0);
+    TEST(alltypes.rep_sfixed64_count == 5 && alltypes.rep_sfixed64[4] == -2012 && alltypes.rep_sfixed64[0] == 0);
+    TEST(alltypes.rep_double_count == 5 && alltypes.rep_double[4] == 2013.0 && alltypes.rep_double[0] == 0.0);
+
+    TEST(alltypes.rep_string_count == 5 && strcmp(alltypes.rep_string[4], "2014") == 0 && alltypes.rep_string[0][0] == '\0');
+    TEST(alltypes.rep_bytes_count == 5 && alltypes.rep_bytes[4].size == 4 && alltypes.rep_bytes[0].size == 0);
+    TEST(memcmp(alltypes.rep_bytes[4].bytes, "2015", 4) == 0);
+
+    TEST(alltypes.rep_submsg_count == 5);
+    TEST(strcmp(alltypes.rep_submsg[4].substuff1, "2016") == 0 && alltypes.rep_submsg[0].substuff1[0] == '\0');
+    TEST(alltypes.rep_submsg[4].substuff2 == 2016 && alltypes.rep_submsg[0].substuff2 == 0);
+    TEST(alltypes.rep_submsg[4].substuff3 == 2016 && alltypes.rep_submsg[0].substuff3 == 0);
+
+    TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero);
+    TEST(alltypes.rep_emptymsg_count == 5);
+
+    TEST(alltypes.rep_fbytes_count == 5);
+    TEST(alltypes.rep_fbytes[0][0] == 0 && alltypes.rep_fbytes[0][3] == 0);
+    TEST(memcmp(alltypes.rep_fbytes[4], "2019", 4) == 0);
+
+    if (mode == 0)
+    {
+        /* Expect default values */
+        TEST(alltypes.sng_int32         == 0);
+        TEST(alltypes.sng_int64         == 0);
+        TEST(alltypes.sng_uint32        == 0);
+        TEST(alltypes.sng_uint64        == 0);
+        TEST(alltypes.sng_sint32        == 0);
+        TEST(alltypes.sng_sint64        == 0);
+        TEST(alltypes.sng_bool          == false);
+
+        TEST(alltypes.sng_fixed32       == 0);
+        TEST(alltypes.sng_sfixed32      == 0);
+        TEST(alltypes.sng_float         == 0.0f);
+
+        TEST(alltypes.sng_fixed64       == 0);
+        TEST(alltypes.sng_sfixed64      == 0);
+        TEST(alltypes.sng_double        == 0.0);
+
+        TEST(strcmp(alltypes.sng_string, "") == 0);
+        TEST(alltypes.sng_bytes.size == 0);
+        TEST(strcmp(alltypes.sng_submsg.substuff1, "") == 0);
+        TEST(alltypes.sng_submsg.substuff2 == 0);
+        TEST(alltypes.sng_submsg.substuff3 == 0);
+        TEST(alltypes.sng_enum == MyEnum_Zero);
+        TEST(alltypes.sng_fbytes[0] == 0 &&
+             alltypes.sng_fbytes[1] == 0 &&
+             alltypes.sng_fbytes[2] == 0 &&
+             alltypes.sng_fbytes[3] == 0);
+
+        TEST(alltypes.which_oneof == 0);
+    }
+    else
+    {
+        /* Expect filled-in values */
+        TEST(alltypes.sng_int32         == 3041);
+        TEST(alltypes.sng_int64         == 3042);
+        TEST(alltypes.sng_uint32        == 3043);
+        TEST(alltypes.sng_uint64        == 3044);
+        TEST(alltypes.sng_sint32        == 3045);
+        TEST(alltypes.sng_sint64        == 3046);
+        TEST(alltypes.sng_bool          == true);
+
+        TEST(alltypes.sng_fixed32       == 3048);
+        TEST(alltypes.sng_sfixed32      == 3049);
+        TEST(alltypes.sng_float         == 3050.0f);
+
+        TEST(alltypes.sng_fixed64       == 3051);
+        TEST(alltypes.sng_sfixed64      == 3052);
+        TEST(alltypes.sng_double        == 3053.0);
+
+        TEST(strcmp(alltypes.sng_string, "3054") == 0);
+        TEST(alltypes.sng_bytes.size == 4);
+        TEST(memcmp(alltypes.sng_bytes.bytes, "3055", 4) == 0);
+        TEST(strcmp(alltypes.sng_submsg.substuff1, "3056") == 0);
+        TEST(alltypes.sng_submsg.substuff2 == 3056);
+        TEST(alltypes.sng_submsg.substuff3 == 0);
+        TEST(alltypes.sng_enum == MyEnum_Truth);
+        TEST(memcmp(alltypes.sng_fbytes, "3059", 4) == 0);
+
+        TEST(alltypes.which_oneof == AllTypes_oneof_msg1_tag);
+        TEST(strcmp(alltypes.oneof.oneof_msg1.substuff1, "4059") == 0);
+        TEST(alltypes.oneof.oneof_msg1.substuff2 == 4059);
+    }
+
+    TEST(alltypes.req_limits.int32_min  == INT32_MIN);
+    TEST(alltypes.req_limits.int32_max  == INT32_MAX);
+    TEST(alltypes.req_limits.uint32_min == 0);
+    TEST(alltypes.req_limits.uint32_max == UINT32_MAX);
+    TEST(alltypes.req_limits.int64_min  == INT64_MIN);
+    TEST(alltypes.req_limits.int64_max  == INT64_MAX);
+    TEST(alltypes.req_limits.uint64_min == 0);
+    TEST(alltypes.req_limits.uint64_max == UINT64_MAX);
+    TEST(alltypes.req_limits.enum_min   == HugeEnum_Negative);
+    TEST(alltypes.req_limits.enum_max   == HugeEnum_Positive);
+
+    TEST(alltypes.end == 1099);
+
+    return true;
+}
+
+int main(int argc, char **argv)
+{
+    uint8_t buffer[2048];
+    size_t count;
+    pb_istream_t stream;
+
+    /* Whether to expect the optional values or the default values. */
+    int mode = (argc > 1) ? atoi(argv[1]) : 0;
+
+    /* Read the data into buffer */
+    SET_BINARY_MODE(stdin);
+    count = fread(buffer, 1, sizeof(buffer), stdin);
+
+    /* Construct a pb_istream_t for reading from the buffer */
+    stream = pb_istream_from_buffer(buffer, count);
+
+    /* Decode and print out the stuff */
+    if (!check_alltypes(&stream, mode))
+    {
+        printf("Parsing failed: %s\n", PB_GET_ERROR(&stream));
+        return 1;
+    } else {
+        return 0;
+    }
+}
diff --git a/tests/field_size_16_proto3/encode_alltypes.c b/tests/field_size_16_proto3/encode_alltypes.c
new file mode 100644
index 0000000..1da0668
--- /dev/null
+++ b/tests/field_size_16_proto3/encode_alltypes.c
@@ -0,0 +1,111 @@
+/* Attempts to test all the datatypes supported by ProtoBuf3.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pb_encode.h>
+#include "alltypes.pb.h"
+#include "test_helpers.h"
+
+int main(int argc, char **argv)
+{
+    int mode = (argc > 1) ? atoi(argv[1]) : 0;
+    
+    /* Initialize the structure with constants */
+    AllTypes alltypes = AllTypes_init_zero;
+    
+    alltypes.rep_int32_count = 5; alltypes.rep_int32[4] = -2001;
+    alltypes.rep_int64_count = 5; alltypes.rep_int64[4] = -2002;
+    alltypes.rep_uint32_count = 5; alltypes.rep_uint32[4] = 2003;
+    alltypes.rep_uint64_count = 5; alltypes.rep_uint64[4] = 2004;
+    alltypes.rep_sint32_count = 5; alltypes.rep_sint32[4] = -2005;
+    alltypes.rep_sint64_count = 5; alltypes.rep_sint64[4] = -2006;
+    alltypes.rep_bool_count = 5; alltypes.rep_bool[4] = true;
+    
+    alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32[4] = 2008;
+    alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32[4] = -2009;
+    alltypes.rep_float_count = 5; alltypes.rep_float[4] = 2010.0f;
+    
+    alltypes.rep_fixed64_count = 5; alltypes.rep_fixed64[4] = 2011;
+    alltypes.rep_sfixed64_count = 5; alltypes.rep_sfixed64[4] = -2012;
+    alltypes.rep_double_count = 5; alltypes.rep_double[4] = 2013.0;
+    
+    alltypes.rep_string_count = 5; strcpy(alltypes.rep_string[4], "2014");
+    alltypes.rep_bytes_count = 5; alltypes.rep_bytes[4].size = 4;
+    memcpy(alltypes.rep_bytes[4].bytes, "2015", 4);
+
+    alltypes.rep_submsg_count = 5;
+    strcpy(alltypes.rep_submsg[4].substuff1, "2016");
+    alltypes.rep_submsg[4].substuff2 = 2016;
+    alltypes.rep_submsg[4].substuff3 = 2016;
+    
+    alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth;
+    alltypes.rep_emptymsg_count = 5;
+    
+    alltypes.rep_fbytes_count = 5;
+    memcpy(alltypes.rep_fbytes[4], "2019", 4);
+    
+    alltypes.req_limits.int32_min  = INT32_MIN;
+    alltypes.req_limits.int32_max  = INT32_MAX;
+    alltypes.req_limits.uint32_min = 0;
+    alltypes.req_limits.uint32_max = UINT32_MAX;
+    alltypes.req_limits.int64_min  = INT64_MIN;
+    alltypes.req_limits.int64_max  = INT64_MAX;
+    alltypes.req_limits.uint64_min = 0;
+    alltypes.req_limits.uint64_max = UINT64_MAX;
+    alltypes.req_limits.enum_min   = HugeEnum_Negative;
+    alltypes.req_limits.enum_max   = HugeEnum_Positive;
+    
+    if (mode != 0)
+    {
+        /* Fill in values for singular fields */
+        alltypes.sng_int32         = 3041;
+        alltypes.sng_int64         = 3042;
+        alltypes.sng_uint32        = 3043;
+        alltypes.sng_uint64        = 3044;
+        alltypes.sng_sint32        = 3045;
+        alltypes.sng_sint64        = 3046;
+        alltypes.sng_bool          = true;
+        
+        alltypes.sng_fixed32       = 3048;
+        alltypes.sng_sfixed32      = 3049;
+        alltypes.sng_float         = 3050.0f;
+        
+        alltypes.sng_fixed64       = 3051;
+        alltypes.sng_sfixed64      = 3052;
+        alltypes.sng_double        = 3053.0;
+        
+        strcpy(alltypes.sng_string, "3054");
+        alltypes.sng_bytes.size = 4;
+        memcpy(alltypes.sng_bytes.bytes, "3055", 4);
+        strcpy(alltypes.sng_submsg.substuff1, "3056");
+        alltypes.sng_submsg.substuff2 = 3056;
+        alltypes.sng_enum = MyEnum_Truth;
+        memcpy(alltypes.sng_fbytes, "3059", 4);
+
+        alltypes.which_oneof = AllTypes_oneof_msg1_tag;
+        strcpy(alltypes.oneof.oneof_msg1.substuff1, "4059");
+        alltypes.oneof.oneof_msg1.substuff2 = 4059;
+    }
+    
+    alltypes.end = 1099;
+    
+    {
+        uint8_t buffer[AllTypes_size];
+        pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+        
+        /* Now encode it and check if we succeeded. */
+        if (pb_encode(&stream, AllTypes_fields, &alltypes))
+        {
+            SET_BINARY_MODE(stdout);
+            fwrite(buffer, 1, stream.bytes_written, stdout);
+            return 0; /* Success */
+        }
+        else
+        {
+            fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
+            return 1; /* Failure */
+        }
+    }
+}
diff --git a/tests/field_size_32/SConscript b/tests/field_size_32/SConscript
index 2a64c6c..650c626 100644
--- a/tests/field_size_32/SConscript
+++ b/tests/field_size_32/SConscript
@@ -19,10 +19,14 @@
 strict.Append(CFLAGS = strict['CORECFLAGS'])
 strict.Object("pb_decode_fields32.o", "$NANOPB/pb_decode.c")
 strict.Object("pb_encode_fields32.o", "$NANOPB/pb_encode.c")
+strict.Object("pb_common_fields32.o", "$NANOPB/pb_common.c")
 
 # Now build and run the test normally.
-enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_fields32.o"])
-dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_fields32.o"])
+enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_fields32.o", "pb_common_fields32.o"])
+dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_fields32.o", "pb_common_fields32.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_alltypes.output"])
+
+env.RunTest("optionals.output", enc, ARGS = ['1'])
+env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1'])
diff --git a/tests/field_size_32/alltypes.options b/tests/field_size_32/alltypes.options
index b31e3cf..0d5ab12 100644
--- a/tests/field_size_32/alltypes.options
+++ b/tests/field_size_32/alltypes.options
@@ -1,3 +1,3 @@
 * max_size:16
 * max_count:5
-
+*.*fbytes fixed_length:true max_size:4
diff --git a/tests/field_size_32/alltypes.proto b/tests/field_size_32/alltypes.proto
index 17f17ee..a05e3b9 100644
--- a/tests/field_size_32/alltypes.proto
+++ b/tests/field_size_32/alltypes.proto
@@ -1,3 +1,5 @@
+syntax = "proto2";
+
 message SubMessage {
     required string substuff1 = 1 [default = "1"];
     required int32 substuff2 = 2 [default = 2];
@@ -55,7 +57,7 @@
     required SubMessage req_submsg  = 16;
     required MyEnum     req_enum    = 17;
     required EmptyMessage req_emptymsg = 18;
-    
+    required bytes      req_fbytes  = 19;
     
     repeated int32      rep_int32   = 21;
     repeated int64      rep_int64   = 22;
@@ -78,6 +80,7 @@
     repeated SubMessage rep_submsg  = 10036;
     repeated MyEnum     rep_enum    = 10037;
     repeated EmptyMessage rep_emptymsg = 10038;
+    repeated bytes      rep_fbytes  = 10039;
     
     optional int32      opt_int32   = 10041 [default = 4041];
     optional int64      opt_int64   = 10042 [default = 4042];
@@ -96,10 +99,17 @@
     optional double     opt_double  = 10053 [default = 4053];
     
     optional string     opt_string  = 10054 [default = "4054"];
-    optional bytes      opt_bytes   = 10055 [default = "4055"];
+    optional bytes      opt_bytes   = 10055 [default = "\x34\x5C\x00\xff"];
     optional SubMessage opt_submsg  = 10056;
     optional MyEnum     opt_enum    = 10057 [default = Second];
     optional EmptyMessage opt_emptymsg = 10058;
+    optional bytes      opt_fbytes  = 10059 [default = "4059"];
+
+    oneof oneof
+    {
+        SubMessage oneof_msg1 = 10060;
+        EmptyMessage oneof_msg2 = 10061;
+    }
 
     // Check that extreme integer values are handled correctly
     required Limits     req_limits = 98;
@@ -107,5 +117,7 @@
     // Just to make sure that the size of the fields has been calculated
     // properly, i.e. otherwise a bug in last field might not be detected.
     required int32      end = 13432099;
+
+    extensions 200 to 255;
 }
 
diff --git a/tests/fixed_count/SConscript b/tests/fixed_count/SConscript
new file mode 100644
index 0000000..3cecb12
--- /dev/null
+++ b/tests/fixed_count/SConscript
@@ -0,0 +1,14 @@
+# Test that fixed count option works.
+
+Import("env")
+
+env.NanopbProto("fixed_count")
+env.Object("fixed_count.pb.c")
+
+p = env.Program(["fixed_count_unittests.c",
+                 "fixed_count.pb.c",
+                 "$COMMON/pb_encode.o",
+                 "$COMMON/pb_decode.o",
+                 "$COMMON/pb_common.o"])
+
+env.RunTest(p)
diff --git a/tests/fixed_count/fixed_count.proto b/tests/fixed_count/fixed_count.proto
new file mode 100644
index 0000000..e96d1ec
--- /dev/null
+++ b/tests/fixed_count/fixed_count.proto
@@ -0,0 +1,21 @@
+/* Test nanopb fixed count option. */
+
+syntax = "proto2";
+
+import "nanopb.proto";
+
+message Message1
+{
+    repeated int32 data = 1 [(nanopb).max_count = 3, (nanopb).fixed_count = true];
+}
+
+message Message2
+{
+    repeated Message1 data = 1 [(nanopb).max_count = 2, (nanopb).fixed_count = true];
+}
+
+message Message3
+{
+    repeated Message2 data1 = 1 [(nanopb).max_count = 2, (nanopb).fixed_count = true];
+    repeated Message2 data2 = 2 [(nanopb).max_count = 2, (nanopb).fixed_count = true];
+}
diff --git a/tests/fixed_count/fixed_count_unittests.c b/tests/fixed_count/fixed_count_unittests.c
new file mode 100644
index 0000000..02bacac
--- /dev/null
+++ b/tests/fixed_count/fixed_count_unittests.c
@@ -0,0 +1,116 @@
+#include <stdio.h>
+#include <string.h>
+#include <pb_decode.h>
+#include <pb_encode.h>
+#include "unittests.h"
+#include "fixed_count.pb.h"
+
+int main()
+{
+    int status = 0;
+    COMMENT("Test encoding and decoding of repeated fixed count fields");
+
+    {
+      pb_byte_t buffer[Message1_size];
+      Message1 msg_a = Message1_init_zero;
+      Message1 msg_b = Message1_init_zero;
+
+      pb_ostream_t ostream;
+      pb_istream_t istream;
+      size_t message_length;
+
+      msg_a.data[0] = 1;
+      msg_a.data[0] = 2;
+      msg_a.data[0] = 3;
+
+      ostream = pb_ostream_from_buffer(buffer, Message1_size);
+      TEST(pb_encode(&ostream, Message1_fields, &msg_a));
+      message_length = ostream.bytes_written;
+
+      istream = pb_istream_from_buffer(buffer, message_length);
+      TEST(pb_decode(&istream, Message1_fields, &msg_b));
+
+      TEST(istream.bytes_left == 0);
+      TEST(memcmp(&msg_b, &msg_a, sizeof(msg_a)) == 0);
+    }
+
+    {
+      pb_byte_t buffer[Message2_size];
+      Message2 msg_a = Message2_init_zero;
+      Message2 msg_b = Message2_init_zero;
+
+      pb_ostream_t ostream;
+      pb_istream_t istream;
+      size_t message_length;
+
+      msg_a.data[0].data[0] = 1;
+      msg_a.data[0].data[1] = 2;
+      msg_a.data[0].data[2] = 3;
+      msg_a.data[1].data[0] = 4;
+      msg_a.data[1].data[1] = 5;
+      msg_a.data[1].data[2] = 6;
+
+      ostream = pb_ostream_from_buffer(buffer, Message2_size);
+      TEST(pb_encode(&ostream, Message2_fields, &msg_a));
+      message_length = ostream.bytes_written;
+
+      istream = pb_istream_from_buffer(buffer, message_length);
+      TEST(pb_decode(&istream, Message2_fields, &msg_b));
+
+      TEST(istream.bytes_left == 0);
+      TEST(memcmp(&msg_b, &msg_a, sizeof(msg_a)) == 0);
+    }
+
+    {
+      pb_byte_t buffer[Message3_size];
+      Message3 msg_a = Message3_init_zero;
+      Message3 msg_b = Message3_init_zero;
+
+      pb_ostream_t ostream;
+      pb_istream_t istream;
+      size_t message_length;
+
+      msg_a.data1[0].data[0].data[0] = 1;
+      msg_a.data1[0].data[0].data[1] = 2;
+      msg_a.data1[0].data[0].data[2] = 3;
+      msg_a.data1[0].data[1].data[0] = 4;
+      msg_a.data1[0].data[1].data[1] = 5;
+      msg_a.data1[0].data[1].data[2] = 6;
+
+      msg_a.data1[1].data[0].data[0] = 7;
+      msg_a.data1[1].data[0].data[1] = 8;
+      msg_a.data1[1].data[0].data[2] = 9;
+      msg_a.data1[1].data[1].data[0] = 10;
+      msg_a.data1[1].data[1].data[1] = 11;
+      msg_a.data1[1].data[1].data[2] = 12;
+
+      msg_a.data2[0].data[0].data[0] = 11;
+      msg_a.data2[0].data[0].data[1] = 12;
+      msg_a.data2[0].data[0].data[2] = 13;
+      msg_a.data2[0].data[1].data[0] = 14;
+      msg_a.data2[0].data[1].data[1] = 15;
+      msg_a.data2[0].data[1].data[2] = 16;
+
+      msg_a.data2[1].data[0].data[0] = 17;
+      msg_a.data2[1].data[0].data[1] = 18;
+      msg_a.data2[1].data[0].data[2] = 19;
+      msg_a.data2[1].data[1].data[0] = 110;
+      msg_a.data2[1].data[1].data[1] = 111;
+      msg_a.data2[1].data[1].data[2] = 112;
+
+      ostream = pb_ostream_from_buffer(buffer, Message3_size);
+      TEST(pb_encode(&ostream, Message3_fields, &msg_a));
+      message_length = ostream.bytes_written;
+
+      istream = pb_istream_from_buffer(buffer, message_length);
+      TEST(pb_decode(&istream, Message3_fields, &msg_b));
+
+      TEST(istream.bytes_left == 0);
+      TEST(memcmp(&msg_b, &msg_a, sizeof(msg_a)) == 0);
+    }
+
+    if (status != 0)
+        fprintf(stdout, "\n\nSome tests FAILED!\n");
+
+    return status;
+}
diff --git a/tests/fuzztest/SConscript b/tests/fuzztest/SConscript
new file mode 100644
index 0000000..d2fb689
--- /dev/null
+++ b/tests/fuzztest/SConscript
@@ -0,0 +1,43 @@
+# Run a fuzz test to verify robustness against corrupted/malicious data.
+
+Import("env", "malloc_env")
+
+def set_pkgname(src, dst, pkgname):
+    data = open(str(src)).read()
+    placeholder = '// package name placeholder'
+    assert placeholder in data
+    data = data.replace(placeholder, 'package %s;' % pkgname)
+    open(str(dst), 'w').write(data)
+
+# We want both pointer and static versions of the AllTypes message
+# Prefix them with package name.
+env.Command("alltypes_static.proto", "#alltypes/alltypes.proto",
+            lambda target, source, env: set_pkgname(source[0], target[0], 'alltypes_static'))
+env.Command("alltypes_pointer.proto", "#alltypes/alltypes.proto",
+            lambda target, source, env: set_pkgname(source[0], target[0], 'alltypes_pointer'))
+
+p1 = env.NanopbProto(["alltypes_pointer", "alltypes_pointer.options"])
+p2 = env.NanopbProto(["alltypes_static", "alltypes_static.options"])
+fuzz = malloc_env.Program(["fuzztest.c",
+                    "alltypes_pointer.pb.c",
+                    "alltypes_static.pb.c",
+                    "$COMMON/pb_encode_with_malloc.o",
+                    "$COMMON/pb_decode_with_malloc.o",
+                    "$COMMON/pb_common_with_malloc.o",
+                    "$COMMON/malloc_wrappers.o"])
+
+env.RunTest(fuzz)
+
+fuzzstub = malloc_env.Program(["fuzzstub.c",
+                    "alltypes_pointer.pb.c",
+                    "alltypes_static.pb.c",
+                    "$COMMON/pb_encode_with_malloc.o",
+                    "$COMMON/pb_decode_with_malloc.o",
+                    "$COMMON/pb_common_with_malloc.o",
+                    "$COMMON/malloc_wrappers.o"])
+
+generate_message = malloc_env.Program(["generate_message.c",
+                    "alltypes_static.pb.c",
+                    "$COMMON/pb_encode.o",
+                    "$COMMON/pb_common.o"])
+
diff --git a/tests/fuzztest/alltypes_pointer.options b/tests/fuzztest/alltypes_pointer.options
new file mode 100644
index 0000000..7e3ad1e
--- /dev/null
+++ b/tests/fuzztest/alltypes_pointer.options
@@ -0,0 +1,3 @@
+# Generate all fields as pointers.
+* type:FT_POINTER
+*.*fbytes fixed_length:true max_size:4
diff --git a/tests/fuzztest/alltypes_static.options b/tests/fuzztest/alltypes_static.options
new file mode 100644
index 0000000..e197e1d
--- /dev/null
+++ b/tests/fuzztest/alltypes_static.options
@@ -0,0 +1,4 @@
+* max_size:32
+* max_count:8
+*.extensions type:FT_IGNORE
+*.*fbytes fixed_length:true max_size:4
diff --git a/tests/fuzztest/fuzzstub.c b/tests/fuzztest/fuzzstub.c
new file mode 100644
index 0000000..ec9e2af
--- /dev/null
+++ b/tests/fuzztest/fuzzstub.c
@@ -0,0 +1,189 @@
+/* Fuzz testing for the nanopb core.
+ * This can be used with external fuzzers, e.g. radamsa.
+ * It performs most of the same checks as fuzztest, but does not feature data generation.
+ */
+
+#include <pb_decode.h>
+#include <pb_encode.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include <malloc_wrappers.h>
+#include "alltypes_static.pb.h"
+#include "alltypes_pointer.pb.h"
+
+#define BUFSIZE 4096
+
+static bool do_static_decode(uint8_t *buffer, size_t msglen, bool assert_success)
+{
+    pb_istream_t stream;
+    bool status;
+    
+    alltypes_static_AllTypes *msg = malloc_with_check(sizeof(alltypes_static_AllTypes));
+    stream = pb_istream_from_buffer(buffer, msglen);
+    status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg);
+    
+    if (!status && assert_success)
+    {
+        /* Anything that was successfully encoded, should be decodeable.
+         * One exception: strings without null terminator are encoded up
+         * to end of buffer, but refused on decode because the terminator
+         * would not fit. */
+        if (strcmp(stream.errmsg, "string overflow") != 0)
+            assert(status);
+    }
+    
+    free_with_check(msg);
+    return status;
+}
+
+static bool do_pointer_decode(uint8_t *buffer, size_t msglen, bool assert_success)
+{
+    pb_istream_t stream;
+    bool status;
+    alltypes_pointer_AllTypes *msg;
+    
+    msg = malloc_with_check(sizeof(alltypes_pointer_AllTypes));
+    memset(msg, 0, sizeof(alltypes_pointer_AllTypes));
+    stream = pb_istream_from_buffer(buffer, msglen);
+
+    assert(get_alloc_count() == 0);
+    status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg);
+    
+    if (assert_success)
+        assert(status);
+    
+    pb_release(alltypes_pointer_AllTypes_fields, msg);    
+    assert(get_alloc_count() == 0);
+    
+    free_with_check(msg);
+
+    return status;
+}
+
+/* Do a decode -> encode -> decode -> encode roundtrip */
+static void do_static_roundtrip(uint8_t *buffer, size_t msglen)
+{
+    bool status;
+    uint8_t *buf2 = malloc_with_check(BUFSIZE);
+    uint8_t *buf3 = malloc_with_check(BUFSIZE);
+    size_t msglen2, msglen3;
+    alltypes_static_AllTypes *msg1 = malloc_with_check(sizeof(alltypes_static_AllTypes));
+    alltypes_static_AllTypes *msg2 = malloc_with_check(sizeof(alltypes_static_AllTypes));
+    memset(msg1, 0, sizeof(alltypes_static_AllTypes));
+    memset(msg2, 0, sizeof(alltypes_static_AllTypes));
+    
+    {
+        pb_istream_t stream = pb_istream_from_buffer(buffer, msglen);
+        status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg1);
+        assert(status);
+    }
+    
+    {
+        pb_ostream_t stream = pb_ostream_from_buffer(buf2, BUFSIZE);
+        status = pb_encode(&stream, alltypes_static_AllTypes_fields, msg1);
+        assert(status);
+        msglen2 = stream.bytes_written;
+    }
+    
+    {
+        pb_istream_t stream = pb_istream_from_buffer(buf2, msglen2);
+        status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg2);
+        assert(status);
+    }
+    
+    {
+        pb_ostream_t stream = pb_ostream_from_buffer(buf3, BUFSIZE);
+        status = pb_encode(&stream, alltypes_static_AllTypes_fields, msg2);
+        assert(status);
+        msglen3 = stream.bytes_written;
+    }
+    
+    assert(msglen2 == msglen3);
+    assert(memcmp(buf2, buf3, msglen2) == 0);
+    
+    free_with_check(msg1);
+    free_with_check(msg2);
+    free_with_check(buf2);
+    free_with_check(buf3);
+}
+
+/* Do decode -> encode -> decode -> encode roundtrip */
+static void do_pointer_roundtrip(uint8_t *buffer, size_t msglen)
+{
+    bool status;
+    uint8_t *buf2 = malloc_with_check(BUFSIZE);
+    uint8_t *buf3 = malloc_with_check(BUFSIZE);
+    size_t msglen2, msglen3;
+    alltypes_pointer_AllTypes *msg1 = malloc_with_check(sizeof(alltypes_pointer_AllTypes));
+    alltypes_pointer_AllTypes *msg2 = malloc_with_check(sizeof(alltypes_pointer_AllTypes));
+    memset(msg1, 0, sizeof(alltypes_pointer_AllTypes));
+    memset(msg2, 0, sizeof(alltypes_pointer_AllTypes));
+    
+    {
+        pb_istream_t stream = pb_istream_from_buffer(buffer, msglen);
+        status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg1);
+        assert(status);
+    }
+    
+    {
+        pb_ostream_t stream = pb_ostream_from_buffer(buf2, BUFSIZE);
+        status = pb_encode(&stream, alltypes_pointer_AllTypes_fields, msg1);
+        assert(status);
+        msglen2 = stream.bytes_written;
+    }
+    
+    {
+        pb_istream_t stream = pb_istream_from_buffer(buf2, msglen2);
+        status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg2);
+        assert(status);
+    }
+    
+    {
+        pb_ostream_t stream = pb_ostream_from_buffer(buf3, BUFSIZE);
+        status = pb_encode(&stream, alltypes_pointer_AllTypes_fields, msg2);
+        assert(status);
+        msglen3 = stream.bytes_written;
+    }
+    
+    assert(msglen2 == msglen3);
+    assert(memcmp(buf2, buf3, msglen2) == 0);
+    
+    pb_release(alltypes_pointer_AllTypes_fields, msg1);
+    pb_release(alltypes_pointer_AllTypes_fields, msg2);
+    free_with_check(msg1);
+    free_with_check(msg2);
+    free_with_check(buf2);
+    free_with_check(buf3);
+}
+
+static void run_iteration()
+{
+    uint8_t *buffer = malloc_with_check(BUFSIZE);
+    size_t msglen;
+    bool status;
+    
+    msglen = fread(buffer, 1, BUFSIZE, stdin);
+
+    status = do_static_decode(buffer, msglen, false);
+    
+    if (status)
+        do_static_roundtrip(buffer, msglen);
+    
+    status = do_pointer_decode(buffer, msglen, false);
+    
+    if (status)
+        do_pointer_roundtrip(buffer, msglen);
+    
+    free_with_check(buffer);
+}
+
+int main(int argc, char **argv)
+{
+    run_iteration();
+    
+    return 0;
+}
+
diff --git a/tests/fuzztest/fuzztest.c b/tests/fuzztest/fuzztest.c
new file mode 100644
index 0000000..ee851ec
--- /dev/null
+++ b/tests/fuzztest/fuzztest.c
@@ -0,0 +1,432 @@
+/* Fuzz testing for the nanopb core.
+ * Attempts to verify all the properties defined in the security model document.
+ */
+
+#include <pb_decode.h>
+#include <pb_encode.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include <malloc_wrappers.h>
+#include "alltypes_static.pb.h"
+#include "alltypes_pointer.pb.h"
+
+static uint64_t random_seed;
+
+/* Uses xorshift64 here instead of rand() for both speed and
+ * reproducibility across platforms. */
+static uint32_t rand_word()
+{
+    random_seed ^= random_seed >> 12;
+    random_seed ^= random_seed << 25;
+    random_seed ^= random_seed >> 27;
+    return random_seed * 2685821657736338717ULL;
+}
+
+/* Get a random integer in range, with approximately flat distribution. */
+static int rand_int(int min, int max)
+{
+    return rand_word() % (max + 1 - min) + min;
+}
+
+static bool rand_bool()
+{
+    return rand_word() & 1;
+}
+
+/* Get a random byte, with skewed distribution.
+ * Important corner cases like 0xFF, 0x00 and 0xFE occur more
+ * often than other values. */
+static uint8_t rand_byte()
+{
+    uint32_t w = rand_word();
+    uint8_t b = w & 0xFF;
+    if (w & 0x100000)
+        b >>= (w >> 8) & 7;
+    if (w & 0x200000)
+        b <<= (w >> 12) & 7;
+    if (w & 0x400000)
+        b ^= 0xFF;
+    return b;
+}
+
+/* Get a random length, with skewed distribution.
+ * Favors the shorter lengths, but always atleast 1. */
+static size_t rand_len(size_t max)
+{
+    uint32_t w = rand_word();
+    size_t s;
+    if (w & 0x800000)
+        w &= 3;
+    else if (w & 0x400000)
+        w &= 15;
+    else if (w & 0x200000)
+        w &= 255;
+
+    s = (w % max);
+    if (s == 0)
+        s = 1;
+    
+    return s;
+}
+
+/* Fills a buffer with random data with skewed distribution. */
+static void rand_fill(uint8_t *buf, size_t count)
+{
+    while (count--)
+        *buf++ = rand_byte();
+}
+
+/* Fill with random protobuf-like data */
+static size_t rand_fill_protobuf(uint8_t *buf, size_t min_bytes, size_t max_bytes, int min_tag)
+{
+    pb_ostream_t stream = pb_ostream_from_buffer(buf, max_bytes);
+
+    while(stream.bytes_written < min_bytes)
+    {
+        pb_wire_type_t wt = rand_int(0, 3);
+        if (wt == 3) wt = 5; /* Gap in values */
+        
+        if (!pb_encode_tag(&stream, wt, rand_int(min_tag, min_tag + 512)))
+            break;
+    
+        if (wt == PB_WT_VARINT)
+        {
+            uint64_t value;
+            rand_fill((uint8_t*)&value, sizeof(value));
+            pb_encode_varint(&stream, value);
+        }
+        else if (wt == PB_WT_64BIT)
+        {
+            uint64_t value;
+            rand_fill((uint8_t*)&value, sizeof(value));
+            pb_encode_fixed64(&stream, &value);
+        }
+        else if (wt == PB_WT_32BIT)
+        {
+            uint32_t value;
+            rand_fill((uint8_t*)&value, sizeof(value));
+            pb_encode_fixed32(&stream, &value);
+        }
+        else if (wt == PB_WT_STRING)
+        {
+            size_t len;
+            uint8_t *buf;
+            
+            if (min_bytes > stream.bytes_written)
+                len = rand_len(min_bytes - stream.bytes_written);
+            else
+                len = 0;
+            
+            buf = malloc(len);
+            pb_encode_varint(&stream, len);
+            rand_fill(buf, len);
+            pb_write(&stream, buf, len);
+            free(buf);
+        }
+    }
+    
+    return stream.bytes_written;
+}
+
+/* Given a buffer of data, mess it up a bit */
+static void rand_mess(uint8_t *buf, size_t count)
+{
+    int m = rand_int(0, 3);
+    
+    if (m == 0)
+    {
+        /* Replace random substring */
+        int s = rand_int(0, count - 1);
+        int l = rand_len(count - s);
+        rand_fill(buf + s, l);
+    }
+    else if (m == 1)
+    {
+        /* Swap random bytes */
+        int a = rand_int(0, count - 1);
+        int b = rand_int(0, count - 1);
+        int x = buf[a];
+        buf[a] = buf[b];
+        buf[b] = x;
+    }
+    else if (m == 2)
+    {
+        /* Duplicate substring */
+        int s = rand_int(0, count - 2);
+        int l = rand_len((count - s) / 2);
+        memcpy(buf + s + l, buf + s, l);
+    }
+    else if (m == 3)
+    {
+        /* Add random protobuf noise */
+        int s = rand_int(0, count - 1);
+        int l = rand_len(count - s);
+        rand_fill_protobuf(buf + s, l, count - s, 1);
+    }
+}
+
+/* Some default data to put in the message */
+static const alltypes_static_AllTypes initval = alltypes_static_AllTypes_init_default;
+
+#define BUFSIZE 4096
+
+static bool do_static_encode(uint8_t *buffer, size_t *msglen)
+{
+    pb_ostream_t stream;
+    bool status;
+
+    /* Allocate a message and fill it with defaults */
+    alltypes_static_AllTypes *msg = malloc_with_check(sizeof(alltypes_static_AllTypes));
+    memcpy(msg, &initval, sizeof(initval));
+
+    /* Apply randomness to the data before encoding */
+    while (rand_int(0, 7))
+        rand_mess((uint8_t*)msg, sizeof(alltypes_static_AllTypes));
+
+    stream = pb_ostream_from_buffer(buffer, BUFSIZE);
+    status = pb_encode(&stream, alltypes_static_AllTypes_fields, msg);
+    assert(stream.bytes_written <= BUFSIZE);
+    assert(stream.bytes_written <= alltypes_static_AllTypes_size);
+    
+    *msglen = stream.bytes_written;
+    pb_release(alltypes_static_AllTypes_fields, msg);
+    free_with_check(msg);
+    
+    return status;
+}
+
+/* Append or prepend protobuf noise */
+static void do_protobuf_noise(uint8_t *buffer, size_t *msglen)
+{
+    int m = rand_int(0, 2);
+    size_t max_size = BUFSIZE - 32 - *msglen;
+    if (m == 1)
+    {
+        /* Prepend */
+        uint8_t *tmp = malloc_with_check(BUFSIZE);
+        size_t s = rand_fill_protobuf(tmp, rand_len(max_size), BUFSIZE - *msglen, 512);
+        memmove(buffer + s, buffer, *msglen);
+        memcpy(buffer, tmp, s);
+        free_with_check(tmp);
+        *msglen += s;
+    }
+    else if (m == 2)
+    {
+        /* Append */
+        size_t s = rand_fill_protobuf(buffer + *msglen, rand_len(max_size), BUFSIZE - *msglen, 512);
+        *msglen += s;
+    }
+}
+
+static bool do_static_decode(uint8_t *buffer, size_t msglen, bool assert_success)
+{
+    pb_istream_t stream;
+    bool status;
+    
+    alltypes_static_AllTypes *msg = malloc_with_check(sizeof(alltypes_static_AllTypes));
+    rand_fill((uint8_t*)msg, sizeof(alltypes_static_AllTypes));
+    stream = pb_istream_from_buffer(buffer, msglen);
+    status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg);
+    
+    if (!status && assert_success)
+    {
+        /* Anything that was successfully encoded, should be decodeable.
+         * One exception: strings without null terminator are encoded up
+         * to end of buffer, but refused on decode because the terminator
+         * would not fit. */
+        if (strcmp(stream.errmsg, "string overflow") != 0)
+            assert(status);
+    }
+    
+    free_with_check(msg);
+    return status;
+}
+
+static bool do_pointer_decode(uint8_t *buffer, size_t msglen, bool assert_success)
+{
+    pb_istream_t stream;
+    bool status;
+    alltypes_pointer_AllTypes *msg;
+    
+    msg = malloc_with_check(sizeof(alltypes_pointer_AllTypes));
+    memset(msg, 0, sizeof(alltypes_pointer_AllTypes));
+    stream = pb_istream_from_buffer(buffer, msglen);
+
+    assert(get_alloc_count() == 0);
+    status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg);
+    
+    if (assert_success)
+        assert(status);
+    
+    pb_release(alltypes_pointer_AllTypes_fields, msg);    
+    assert(get_alloc_count() == 0);
+    
+    free_with_check(msg);
+
+    return status;
+}
+
+/* Do a decode -> encode -> decode -> encode roundtrip */
+static void do_static_roundtrip(uint8_t *buffer, size_t msglen)
+{
+    bool status;
+    uint8_t *buf2 = malloc_with_check(BUFSIZE);
+    uint8_t *buf3 = malloc_with_check(BUFSIZE);
+    size_t msglen2, msglen3;
+    alltypes_static_AllTypes *msg1 = malloc_with_check(sizeof(alltypes_static_AllTypes));
+    alltypes_static_AllTypes *msg2 = malloc_with_check(sizeof(alltypes_static_AllTypes));
+    memset(msg1, 0, sizeof(alltypes_static_AllTypes));
+    memset(msg2, 0, sizeof(alltypes_static_AllTypes));
+    
+    {
+        pb_istream_t stream = pb_istream_from_buffer(buffer, msglen);
+        status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg1);
+        assert(status);
+    }
+    
+    {
+        pb_ostream_t stream = pb_ostream_from_buffer(buf2, BUFSIZE);
+        status = pb_encode(&stream, alltypes_static_AllTypes_fields, msg1);
+        assert(status);
+        msglen2 = stream.bytes_written;
+    }
+    
+    {
+        pb_istream_t stream = pb_istream_from_buffer(buf2, msglen2);
+        status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg2);
+        assert(status);
+    }
+    
+    {
+        pb_ostream_t stream = pb_ostream_from_buffer(buf3, BUFSIZE);
+        status = pb_encode(&stream, alltypes_static_AllTypes_fields, msg2);
+        assert(status);
+        msglen3 = stream.bytes_written;
+    }
+    
+    assert(msglen2 == msglen3);
+    assert(memcmp(buf2, buf3, msglen2) == 0);
+    
+    free_with_check(msg1);
+    free_with_check(msg2);
+    free_with_check(buf2);
+    free_with_check(buf3);
+}
+
+/* Do decode -> encode -> decode -> encode roundtrip */
+static void do_pointer_roundtrip(uint8_t *buffer, size_t msglen)
+{
+    bool status;
+    uint8_t *buf2 = malloc_with_check(BUFSIZE);
+    uint8_t *buf3 = malloc_with_check(BUFSIZE);
+    size_t msglen2, msglen3;
+    alltypes_pointer_AllTypes *msg1 = malloc_with_check(sizeof(alltypes_pointer_AllTypes));
+    alltypes_pointer_AllTypes *msg2 = malloc_with_check(sizeof(alltypes_pointer_AllTypes));
+    memset(msg1, 0, sizeof(alltypes_pointer_AllTypes));
+    memset(msg2, 0, sizeof(alltypes_pointer_AllTypes));
+    
+    {
+        pb_istream_t stream = pb_istream_from_buffer(buffer, msglen);
+        status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg1);
+        assert(status);
+    }
+    
+    {
+        pb_ostream_t stream = pb_ostream_from_buffer(buf2, BUFSIZE);
+        status = pb_encode(&stream, alltypes_pointer_AllTypes_fields, msg1);
+        assert(status);
+        msglen2 = stream.bytes_written;
+    }
+    
+    {
+        pb_istream_t stream = pb_istream_from_buffer(buf2, msglen2);
+        status = pb_decode(&stream, alltypes_pointer_AllTypes_fields, msg2);
+        assert(status);
+    }
+    
+    {
+        pb_ostream_t stream = pb_ostream_from_buffer(buf3, BUFSIZE);
+        status = pb_encode(&stream, alltypes_pointer_AllTypes_fields, msg2);
+        assert(status);
+        msglen3 = stream.bytes_written;
+    }
+    
+    assert(msglen2 == msglen3);
+    assert(memcmp(buf2, buf3, msglen2) == 0);
+    
+    pb_release(alltypes_pointer_AllTypes_fields, msg1);
+    pb_release(alltypes_pointer_AllTypes_fields, msg2);
+    free_with_check(msg1);
+    free_with_check(msg2);
+    free_with_check(buf2);
+    free_with_check(buf3);
+}
+
+static void run_iteration()
+{
+    uint8_t *buffer = malloc_with_check(BUFSIZE);
+    size_t msglen;
+    bool status;
+    
+    rand_fill(buffer, BUFSIZE);
+
+    if (do_static_encode(buffer, &msglen))
+    {
+        do_protobuf_noise(buffer, &msglen);
+    
+        status = do_static_decode(buffer, msglen, true);
+        
+        if (status)
+            do_static_roundtrip(buffer, msglen);
+        
+        status = do_pointer_decode(buffer, msglen, true);
+        
+        if (status)
+            do_pointer_roundtrip(buffer, msglen);
+        
+        /* Apply randomness to the encoded data */
+        while (rand_bool())
+            rand_mess(buffer, BUFSIZE);
+        
+        /* Apply randomness to encoded data length */
+        if (rand_bool())
+            msglen = rand_int(0, BUFSIZE);
+        
+        status = do_static_decode(buffer, msglen, false);
+        do_pointer_decode(buffer, msglen, status);
+        
+        if (status)
+        {
+            do_static_roundtrip(buffer, msglen);
+            do_pointer_roundtrip(buffer, msglen);
+        }
+    }
+    
+    free_with_check(buffer);
+}
+
+int main(int argc, char **argv)
+{
+    int i;
+    if (argc > 1)
+    {
+        random_seed = atol(argv[1]);
+    }
+    else
+    {
+        random_seed = time(NULL);
+    }
+    
+    fprintf(stderr, "Random seed: %llu\n", (long long unsigned)random_seed);
+    
+    for (i = 0; i < 10000; i++)
+    {
+        run_iteration();
+    }
+    
+    return 0;
+}
+
diff --git a/tests/fuzztest/generate_message.c b/tests/fuzztest/generate_message.c
new file mode 100644
index 0000000..6e49299
--- /dev/null
+++ b/tests/fuzztest/generate_message.c
@@ -0,0 +1,101 @@
+/* Generates a random, valid protobuf message. Useful to seed
+ * external fuzzers such as afl-fuzz.
+ */
+
+#include <pb_encode.h>
+#include <pb_common.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include "alltypes_static.pb.h"
+
+static uint64_t random_seed;
+
+/* Uses xorshift64 here instead of rand() for both speed and
+ * reproducibility across platforms. */
+static uint32_t rand_word()
+{
+    random_seed ^= random_seed >> 12;
+    random_seed ^= random_seed << 25;
+    random_seed ^= random_seed >> 27;
+    return random_seed * 2685821657736338717ULL;
+}
+
+/* Fills a buffer with random data. */
+static void rand_fill(uint8_t *buf, size_t count)
+{
+    while (count--)
+    {
+        *buf++ = rand_word() & 0xff;
+    }
+}
+
+/* Check that size/count fields do not exceed their max size.
+ * Otherwise we would have to loop pretty long in generate_message().
+ * Note that there may still be a few encoding errors from submessages.
+ */
+static void limit_sizes(alltypes_static_AllTypes *msg)
+{
+    pb_field_iter_t iter;
+    pb_field_iter_begin(&iter, alltypes_static_AllTypes_fields, msg);
+    while (pb_field_iter_next(&iter))
+    {
+        if (PB_LTYPE(iter.pos->type) == PB_LTYPE_BYTES)
+        {
+            ((pb_bytes_array_t*)iter.pData)->size %= iter.pos->data_size - PB_BYTES_ARRAY_T_ALLOCSIZE(0);
+        }
+        
+        if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REPEATED)
+        {
+            *((pb_size_t*)iter.pSize) %= iter.pos->array_size;
+        }
+        
+        if (PB_HTYPE(iter.pos->type) == PB_HTYPE_ONEOF)
+        {
+            /* Set the oneof to this message type with 50% chance. */
+            if (rand_word() & 1)
+            {
+                *((pb_size_t*)iter.pSize) = iter.pos->tag;
+            }
+        }
+    }
+}
+
+static void generate_message()
+{
+    alltypes_static_AllTypes msg;
+    uint8_t buf[8192];
+    pb_ostream_t stream = {0};
+    
+    do {
+        if (stream.errmsg)
+            fprintf(stderr, "Encoder error: %s\n", stream.errmsg);
+        
+        stream = pb_ostream_from_buffer(buf, sizeof(buf));
+        rand_fill((void*)&msg, sizeof(msg));
+        limit_sizes(&msg);
+    } while (!pb_encode(&stream, alltypes_static_AllTypes_fields, &msg));
+    
+    fwrite(buf, 1, stream.bytes_written, stdout);
+}
+
+int main(int argc, char **argv)
+{
+    if (argc > 1)
+    {
+        random_seed = atol(argv[1]);
+    }
+    else
+    {
+        random_seed = time(NULL);
+    }
+    
+    fprintf(stderr, "Random seed: %llu\n", (long long unsigned)random_seed);
+    
+    generate_message();
+    
+    return 0;
+}
+
diff --git a/tests/fuzztest/run_radamsa.sh b/tests/fuzztest/run_radamsa.sh
new file mode 100755
index 0000000..52cd40a
--- /dev/null
+++ b/tests/fuzztest/run_radamsa.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+TMP=`tempfile`
+
+echo $TMP
+while true
+do
+   radamsa sample_data/* > $TMP
+   $1 < $TMP
+   test $? -gt 127 && break
+done
+ 
diff --git a/tests/fuzztest/sample_data/sample1.pb b/tests/fuzztest/sample_data/sample1.pb
new file mode 100644
index 0000000..0752788
--- /dev/null
+++ b/tests/fuzztest/sample_data/sample1.pb
Binary files differ
diff --git a/tests/fuzztest/sample_data/sample2.pb b/tests/fuzztest/sample_data/sample2.pb
new file mode 100644
index 0000000..cc89f91
--- /dev/null
+++ b/tests/fuzztest/sample_data/sample2.pb
Binary files differ
diff --git a/tests/inline/SConscript b/tests/inline/SConscript
new file mode 100644
index 0000000..34371fd
--- /dev/null
+++ b/tests/inline/SConscript
@@ -0,0 +1,16 @@
+# Test that inlined bytes fields work.
+
+Import("env")
+
+env.NanopbProto("inline")
+env.Object("inline.pb.c")
+
+env.Match(["inline.pb.h", "inline.expected"])
+
+p = env.Program(["inline_unittests.c",
+                 "inline.pb.c",
+                 "$COMMON/pb_encode.o",
+                 "$COMMON/pb_decode.o",
+                 "$COMMON/pb_common.o"])
+
+env.RunTest(p)
diff --git a/tests/inline/inline.expected b/tests/inline/inline.expected
new file mode 100644
index 0000000..593e972
--- /dev/null
+++ b/tests/inline/inline.expected
@@ -0,0 +1,3 @@
+pb_byte_t data\[32\];
+bool has_data;
+pb_byte_t data\[64\];
diff --git a/tests/inline/inline.proto b/tests/inline/inline.proto
new file mode 100644
index 0000000..6e511f0
--- /dev/null
+++ b/tests/inline/inline.proto
@@ -0,0 +1,17 @@
+/* Test nanopb option parsing.
+ * options.expected lists the patterns that are searched for in the output.
+ */
+
+syntax = "proto2";
+
+import "nanopb.proto";
+
+message Message1
+{
+    required bytes data = 1 [(nanopb).type = FT_INLINE, (nanopb).max_size = 32];
+}
+
+message Message2
+{
+    optional bytes data = 1 [(nanopb).type = FT_INLINE, (nanopb).max_size = 64];
+}
diff --git a/tests/inline/inline_unittests.c b/tests/inline/inline_unittests.c
new file mode 100644
index 0000000..b5834c7
--- /dev/null
+++ b/tests/inline/inline_unittests.c
@@ -0,0 +1,73 @@
+#include <stdio.h>
+#include <string.h>
+#include <pb_decode.h>
+#include <pb_encode.h>
+#include "unittests.h"
+#include "inline.pb.h"
+
+int main()
+{
+    int status = 0;
+    int i = 0;
+    COMMENT("Test inline byte fields");
+
+    {
+      Message1 msg1 = Message1_init_zero;
+      TEST(sizeof(msg1.data) == 32);
+    }
+
+    {
+      Message1 msg1 = Message1_init_zero;
+      pb_byte_t msg1_buffer[Message1_size];
+      pb_ostream_t ostream = pb_ostream_from_buffer(msg1_buffer, Message1_size);
+      Message1 msg1_deserialized = Message1_init_zero;
+      pb_istream_t istream = pb_istream_from_buffer(msg1_buffer, Message1_size);
+
+      for (i = 0; i < 32; i++) {
+        msg1.data[i] = i;
+      }
+
+      TEST(pb_encode(&ostream, Message1_fields, &msg1));
+      TEST(ostream.bytes_written == Message1_size);
+
+      TEST(pb_decode(&istream, Message1_fields, &msg1_deserialized));
+
+      TEST(istream.bytes_left == 0);
+      TEST(memcmp(&msg1_deserialized, &msg1, sizeof(msg1)) == 0);
+    }
+
+    {
+      Message2 msg2 = {true, {0}};
+      Message2 msg2_no_data = {false, {1}};
+      pb_byte_t msg2_buffer[Message2_size];
+      pb_ostream_t ostream = pb_ostream_from_buffer(msg2_buffer, Message2_size);
+      Message2 msg2_deserialized = Message2_init_zero;
+      pb_istream_t istream = pb_istream_from_buffer(msg2_buffer, Message2_size);
+
+      for (i = 0; i < 64; i++) {
+        msg2.data[i] = i;
+      }
+
+      TEST(pb_encode(&ostream, Message2_fields, &msg2));
+      TEST(ostream.bytes_written == Message2_size);
+
+      TEST(pb_decode(&istream, Message2_fields, &msg2_deserialized));
+
+      TEST(istream.bytes_left == 0);
+      TEST(memcmp(&msg2_deserialized, &msg2, sizeof(msg2)) == 0);
+      TEST(msg2_deserialized.has_data);
+
+      memset(msg2_buffer, 0, sizeof(msg2_buffer));
+      ostream = pb_ostream_from_buffer(msg2_buffer, Message2_size);
+      TEST(pb_encode(&ostream, Message2_fields, &msg2_no_data));
+      istream = pb_istream_from_buffer(msg2_buffer, Message2_size);
+      TEST(pb_decode(&istream, Message2_fields, &msg2_deserialized));
+      TEST(!msg2_deserialized.has_data);
+      TEST(memcmp(&msg2_deserialized, &msg2, sizeof(msg2)) != 0);
+    }
+
+    if (status != 0)
+        fprintf(stdout, "\n\nSome tests FAILED!\n");
+
+    return status;
+}
diff --git a/tests/intsizes/SConscript b/tests/intsizes/SConscript
new file mode 100644
index 0000000..a90680b
--- /dev/null
+++ b/tests/intsizes/SConscript
@@ -0,0 +1,12 @@
+# Test that the int_size option in .proto works.
+
+Import('env')
+
+env.NanopbProto('intsizes')
+
+p = env.Program(["intsizes_unittests.c",
+                 "intsizes.pb.c",
+                 "$COMMON/pb_encode.o",
+                 "$COMMON/pb_decode.o",
+                 "$COMMON/pb_common.o"])
+env.RunTest(p)
diff --git a/tests/intsizes/intsizes.proto b/tests/intsizes/intsizes.proto
new file mode 100644
index 0000000..91444d4
--- /dev/null
+++ b/tests/intsizes/intsizes.proto
@@ -0,0 +1,41 @@
+/* Test the integer size overriding in nanopb options.
+ * This allows to use 8- and 16-bit integer variables, which are not supported
+ * directly by Google Protobuf.
+ *
+ * The int_size setting will override the number of bits, but keep the type
+ * otherwise. E.g. uint32 + IS_8 => uint8_t
+ */
+
+syntax = "proto2";
+
+import 'nanopb.proto';
+
+message IntSizes {
+    required int32  req_int8 =   1  [(nanopb).int_size = IS_8];
+    required uint32 req_uint8 =  2  [(nanopb).int_size = IS_8];
+    required sint32 req_sint8 =  3  [(nanopb).int_size = IS_8];
+    required int32  req_int16 =  4  [(nanopb).int_size = IS_16];
+    required uint32 req_uint16 = 5  [(nanopb).int_size = IS_16];
+    required sint32 req_sint16 = 6  [(nanopb).int_size = IS_16];
+    required int32  req_int32 =  7  [(nanopb).int_size = IS_32];
+    required uint32 req_uint32 = 8  [(nanopb).int_size = IS_32];
+    required sint32 req_sint32 = 9  [(nanopb).int_size = IS_32];
+    required int32  req_int64 =  10 [(nanopb).int_size = IS_64];
+    required uint32 req_uint64 = 11 [(nanopb).int_size = IS_64];
+    required sint32 req_sint64 = 12 [(nanopb).int_size = IS_64];
+}
+
+message DefaultSizes {
+    required int32  req_int8 =   1 ;
+    required uint32 req_uint8 =  2 ;
+    required sint32 req_sint8 =  3 ;
+    required int32  req_int16 =  4 ;
+    required uint32 req_uint16 = 5 ;
+    required sint32 req_sint16 = 6 ;
+    required int32  req_int32 =  7 ;
+    required uint32 req_uint32 = 8 ;
+    required sint32 req_sint32 = 9 ;
+    required int64  req_int64 =  10;
+    required uint64 req_uint64 = 11;
+    required sint64 req_sint64 = 12;
+}
diff --git a/tests/intsizes/intsizes_unittests.c b/tests/intsizes/intsizes_unittests.c
new file mode 100644
index 0000000..79ef036
--- /dev/null
+++ b/tests/intsizes/intsizes_unittests.c
@@ -0,0 +1,122 @@
+#include <stdio.h>
+#include <string.h>
+#include <pb_decode.h>
+#include <pb_encode.h>
+#include "unittests.h"
+#include "intsizes.pb.h"
+
+#define S(x) pb_istream_from_buffer((uint8_t*)x, sizeof(x) - 1)
+
+/* This is a macro instead of function in order to get the actual values
+ * into the TEST() lines in output */
+#define TEST_ROUNDTRIP(int8, uint8, sint8, \
+                       int16, uint16, sint16, \
+                       int32, uint32, sint32, \
+                       int64, uint64, sint64, expected_result) \
+{                                                                           \
+    uint8_t buffer1[128], buffer2[128];                                     \
+    size_t msgsize;                                                         \
+    DefaultSizes msg1 = DefaultSizes_init_zero;                             \
+    IntSizes msg2 = IntSizes_init_zero;                                     \
+                                                                            \
+    msg1.req_int8   = int8;                                                 \
+    msg1.req_uint8  = uint8;                                                \
+    msg1.req_sint8  = sint8;                                                \
+    msg1.req_int16  = int16;                                                \
+    msg1.req_uint16 = uint16;                                               \
+    msg1.req_sint16 = sint16;                                               \
+    msg1.req_int32  = int32;                                                \
+    msg1.req_uint32 = uint32;                                               \
+    msg1.req_sint32 = sint32;                                               \
+    msg1.req_int64  = int64;                                                \
+    msg1.req_uint64 = uint64;                                               \
+    msg1.req_sint64 = sint64;                                               \
+                                                                            \
+    {                                                                       \
+        pb_ostream_t s = pb_ostream_from_buffer(buffer1, sizeof(buffer1));  \
+        TEST(pb_encode(&s, DefaultSizes_fields, &msg1));                    \
+        msgsize = s.bytes_written;                                          \
+    }                                                                       \
+                                                                            \
+    {                                                                       \
+        pb_istream_t s = pb_istream_from_buffer(buffer1, msgsize);          \
+        TEST(pb_decode(&s, IntSizes_fields, &msg2) == expected_result);     \
+        if (expected_result)                                                \
+        {                                                                   \
+            TEST( (int64_t)msg2.req_int8   == int8);                        \
+            TEST((uint64_t)msg2.req_uint8  == uint8);                       \
+            TEST( (int64_t)msg2.req_sint8  == sint8);                       \
+            TEST( (int64_t)msg2.req_int16  == int16);                       \
+            TEST((uint64_t)msg2.req_uint16 == uint16);                      \
+            TEST( (int64_t)msg2.req_sint16 == sint16);                      \
+            TEST( (int64_t)msg2.req_int32  == int32);                       \
+            TEST((uint64_t)msg2.req_uint32 == uint32);                      \
+            TEST( (int64_t)msg2.req_sint32 == sint32);                      \
+            TEST( (int64_t)msg2.req_int64  == int64);                       \
+            TEST((uint64_t)msg2.req_uint64 == uint64);                      \
+            TEST( (int64_t)msg2.req_sint64 == sint64);                      \
+        }                                                                   \
+    }                                                                       \
+                                                                            \
+    if (expected_result)                                                    \
+    {                                                                       \
+        pb_ostream_t s = pb_ostream_from_buffer(buffer2, sizeof(buffer2));  \
+        TEST(pb_encode(&s, IntSizes_fields, &msg2));                        \
+        TEST(s.bytes_written == msgsize);                                   \
+        TEST(memcmp(buffer1, buffer2, msgsize) == 0);                       \
+    }                                                                       \
+}
+
+int main()
+{
+    int status = 0;
+
+    {
+        IntSizes msg = IntSizes_init_zero;
+
+        COMMENT("Test field sizes");
+        TEST(sizeof(msg.req_int8) == 1);
+        TEST(sizeof(msg.req_uint8) == 1);
+        TEST(sizeof(msg.req_sint8) == 1);
+        TEST(sizeof(msg.req_int16) == 2);
+        TEST(sizeof(msg.req_uint16) == 2);
+        TEST(sizeof(msg.req_sint16) == 2);
+        TEST(sizeof(msg.req_int32) == 4);
+        TEST(sizeof(msg.req_uint32) == 4);
+        TEST(sizeof(msg.req_sint32) == 4);
+        TEST(sizeof(msg.req_int64) == 8);
+        TEST(sizeof(msg.req_uint64) == 8);
+        TEST(sizeof(msg.req_sint64) == 8);
+    }
+
+    COMMENT("Test roundtrip at maximum value");
+    TEST_ROUNDTRIP(127,     255,    127,
+                   32767, 65535,  32767,
+                   INT32_MAX, UINT32_MAX, INT32_MAX,
+                   INT64_MAX, UINT64_MAX, INT64_MAX, true);
+
+    COMMENT("Test roundtrip at minimum value");
+    TEST_ROUNDTRIP(-128,      0,   -128,
+                   -32768,    0, -32768,
+                   INT32_MIN, 0, INT32_MIN,
+                   INT64_MIN, 0, INT64_MIN, true);
+
+    COMMENT("Test overflow detection");
+    TEST_ROUNDTRIP(-129,      0,   -128,
+                   -32768,    0, -32768,
+                   INT32_MIN, 0, INT32_MIN,
+                   INT64_MIN, 0, INT64_MIN, false);
+    TEST_ROUNDTRIP(127,     256,    127,
+                   32767, 65535,  32767,
+                   INT32_MAX, UINT32_MAX, INT32_MAX,
+                   INT64_MAX, UINT64_MAX, INT64_MAX, false);
+    TEST_ROUNDTRIP(-128,      0,   -128,
+                   -32768,    0, -32769,
+                   INT32_MIN, 0, INT32_MIN,
+                   INT64_MIN, 0, INT64_MIN, false);
+
+    if (status != 0)
+        fprintf(stdout, "\n\nSome tests FAILED!\n");
+
+    return status;
+}
\ No newline at end of file
diff --git a/tests/io_errors/SConscript b/tests/io_errors/SConscript
new file mode 100644
index 0000000..60146cc
--- /dev/null
+++ b/tests/io_errors/SConscript
@@ -0,0 +1,15 @@
+# Simulate io errors when encoding and decoding
+
+Import("env")
+
+c = Copy("$TARGET", "$SOURCE")
+env.Command("alltypes.proto", "#alltypes/alltypes.proto", c)
+
+env.NanopbProto(["alltypes", "alltypes.options"])
+
+ioerr = env.Program(["io_errors.c", "alltypes.pb.c",
+                     "$COMMON/pb_encode.o", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
+
+env.RunTest("io_errors.output", [ioerr, "$BUILD/alltypes/encode_alltypes.output"])
+
+
diff --git a/tests/io_errors/alltypes.options b/tests/io_errors/alltypes.options
new file mode 100644
index 0000000..0d5ab12
--- /dev/null
+++ b/tests/io_errors/alltypes.options
@@ -0,0 +1,3 @@
+* max_size:16
+* max_count:5
+*.*fbytes fixed_length:true max_size:4
diff --git a/tests/io_errors/io_errors.c b/tests/io_errors/io_errors.c
new file mode 100644
index 0000000..76f35b0
--- /dev/null
+++ b/tests/io_errors/io_errors.c
@@ -0,0 +1,140 @@
+/* Simulate IO errors after each byte in a stream.
+ * Verifies proper error propagation.
+ */
+
+#include <stdio.h>
+#include <pb_decode.h>
+#include <pb_encode.h>
+#include "alltypes.pb.h"
+#include "test_helpers.h"
+
+typedef struct
+{
+    uint8_t *buffer;
+    size_t fail_after;
+} faulty_stream_t;
+
+bool read_callback(pb_istream_t *stream, uint8_t *buf, size_t count)
+{
+    faulty_stream_t *state = stream->state;
+    
+    while (count--)
+    {
+        if (state->fail_after == 0)
+            PB_RETURN_ERROR(stream, "simulated");
+        state->fail_after--;
+        *buf++ = *state->buffer++;
+    }
+    
+    return true;
+}
+bool write_callback(pb_ostream_t *stream, const uint8_t *buf, size_t count)
+{
+    faulty_stream_t *state = stream->state;
+    
+    while (count--)
+    {
+        if (state->fail_after == 0)
+            PB_RETURN_ERROR(stream, "simulated");
+        state->fail_after--;
+        *state->buffer++ = *buf++;
+    }
+    
+    return true;
+}
+
+int main()
+{
+    uint8_t buffer[2048];
+    size_t msglen;
+    AllTypes msg = AllTypes_init_zero;
+    
+    /* Get some base data to run the tests with */
+    SET_BINARY_MODE(stdin);
+    msglen = fread(buffer, 1, sizeof(buffer), stdin);
+    
+    /* Test IO errors on decoding */
+    {
+        bool status;
+        pb_istream_t stream = {&read_callback, NULL, SIZE_MAX};
+        faulty_stream_t fs;
+        size_t i;
+        
+        for (i = 0; i < msglen; i++)
+        {
+            stream.bytes_left = msglen;
+            stream.state = &fs;
+            fs.buffer = buffer;
+            fs.fail_after = i;
+
+            status = pb_decode(&stream, AllTypes_fields, &msg);
+            if (status != false)
+            {
+                fprintf(stderr, "Unexpected success in decode\n");
+                return 2;
+            }
+            else if (strcmp(stream.errmsg, "simulated") != 0)
+            {
+                fprintf(stderr, "Wrong error in decode: %s\n", stream.errmsg);
+                return 3;
+            }
+        }
+        
+        stream.bytes_left = msglen;
+        stream.state = &fs;
+        fs.buffer = buffer;
+        fs.fail_after = msglen;
+        status = pb_decode(&stream, AllTypes_fields, &msg);
+        
+        if (!status)
+        {
+            fprintf(stderr, "Decoding failed: %s\n", stream.errmsg);
+            return 4;
+        }
+    }
+    
+    /* Test IO errors on encoding */
+    {
+        bool status;
+        pb_ostream_t stream = {&write_callback, NULL, SIZE_MAX, 0};
+        faulty_stream_t fs;
+        size_t i;
+        
+        for (i = 0; i < msglen; i++)
+        {
+            stream.max_size = msglen;
+            stream.bytes_written = 0;
+            stream.state = &fs;
+            fs.buffer = buffer;
+            fs.fail_after = i;
+
+            status = pb_encode(&stream, AllTypes_fields, &msg);
+            if (status != false)
+            {
+                fprintf(stderr, "Unexpected success in encode\n");
+                return 5;
+            }
+            else if (strcmp(stream.errmsg, "simulated") != 0)
+            {
+                fprintf(stderr, "Wrong error in encode: %s\n", stream.errmsg);
+                return 6;
+            }
+        }
+        
+        stream.max_size = msglen;
+        stream.bytes_written = 0;
+        stream.state = &fs;
+        fs.buffer = buffer;
+        fs.fail_after = msglen;
+        status = pb_encode(&stream, AllTypes_fields, &msg);
+        
+        if (!status)
+        {
+            fprintf(stderr, "Encoding failed: %s\n", stream.errmsg);
+            return 7;
+        }
+    }
+
+    return 0;   
+}
+
diff --git a/tests/io_errors_pointers/SConscript b/tests/io_errors_pointers/SConscript
new file mode 100644
index 0000000..03727df
--- /dev/null
+++ b/tests/io_errors_pointers/SConscript
@@ -0,0 +1,26 @@
+# Simulate io errors when encoding and decoding
+
+Import("env", "malloc_env")
+
+c = Copy("$TARGET", "$SOURCE")
+env.Command("alltypes.proto", "#alltypes/alltypes.proto", c)
+env.Command("io_errors.c", "#io_errors/io_errors.c", c)
+
+env.NanopbProto(["alltypes", "alltypes.options"])
+
+ioerr = env.Program(["io_errors.c", "alltypes.pb.c",
+                     "$COMMON/pb_encode_with_malloc.o",
+                     "$COMMON/pb_decode_with_malloc.o",
+                     "$COMMON/pb_common_with_malloc.o",
+                     "$COMMON/malloc_wrappers.o"])
+
+# Run tests under valgrind if available
+valgrind = env.WhereIs('valgrind')
+kwargs = {}
+if valgrind:
+    kwargs['COMMAND'] = valgrind
+    kwargs['ARGS'] = ["-q", "--error-exitcode=99", ioerr[0].abspath]
+
+env.RunTest("io_errors.output", [ioerr, "$BUILD/alltypes/encode_alltypes.output"], **kwargs)
+
+
diff --git a/tests/io_errors_pointers/alltypes.options b/tests/io_errors_pointers/alltypes.options
new file mode 100644
index 0000000..7e3ad1e
--- /dev/null
+++ b/tests/io_errors_pointers/alltypes.options
@@ -0,0 +1,3 @@
+# Generate all fields as pointers.
+* type:FT_POINTER
+*.*fbytes fixed_length:true max_size:4
diff --git a/tests/map/SConscript b/tests/map/SConscript
new file mode 100644
index 0000000..f23e8ee
--- /dev/null
+++ b/tests/map/SConscript
@@ -0,0 +1,21 @@
+# Example / test for handling 'map' type using the backwards compatibility
+# in protobuf specification:
+# https://developers.google.com/protocol-buffers/docs/proto3#maps
+
+Import('env')
+
+env.NanopbProto(['map', 'map.options'])
+
+enc = env.Program(['encode_map.c',
+                'map.pb.c',
+                '$COMMON/pb_encode.o',
+                '$COMMON/pb_common.o'])
+
+dec = env.Program(['decode_map.c',
+                'map.pb.c',
+                '$COMMON/pb_decode.o',
+                '$COMMON/pb_common.o'])
+
+env.RunTest("message.pb", enc)
+env.RunTest("message.txt", [dec, 'message.pb'])
+
diff --git a/tests/map/decode_map.c b/tests/map/decode_map.c
new file mode 100644
index 0000000..c798b03
--- /dev/null
+++ b/tests/map/decode_map.c
@@ -0,0 +1,60 @@
+/* Decode a message using map field */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pb_decode.h>
+#include "map.pb.h"
+#include "test_helpers.h"
+#include "unittests.h"
+
+/* Helper function to find an entry in the list. Not as efficient as a real
+ * hashmap or similar would be, but suitable for small arrays. */
+MyMessage_NumbersEntry *find_entry(MyMessage *msg, const char *key)
+{
+    int i;
+    for (i = 0; i < msg->numbers_count; i++)
+    {
+        if (strcmp(msg->numbers[i].key, key) == 0)
+        {
+            return &msg->numbers[i];
+        }
+    }
+    return NULL;
+}
+
+int main(int argc, char **argv)
+{
+    uint8_t buffer[MyMessage_size];
+    size_t count;
+    
+    SET_BINARY_MODE(stdin);
+    count = fread(buffer, 1, sizeof(buffer), stdin);
+
+    if (!feof(stdin))
+    {
+        printf("Message does not fit in buffer\n");
+        return 1;
+    }
+
+    {
+        int status = 0;
+        MyMessage msg = MyMessage_init_zero;
+        MyMessage_NumbersEntry *e;
+        pb_istream_t stream = pb_istream_from_buffer(buffer, count);
+        
+        if (!pb_decode(&stream, MyMessage_fields, &msg))
+        {
+            fprintf(stderr, "Decoding failed\n");     
+            return 2;   
+        }
+        
+        TEST((e = find_entry(&msg, "one")) && e->value == 1);
+        TEST((e = find_entry(&msg, "two")) && e->value == 2);
+        TEST((e = find_entry(&msg, "seven")) && e->value == 7);
+        TEST(!find_entry(&msg, "zero"));
+        
+        return status;
+    }
+}
+
diff --git a/tests/map/encode_map.c b/tests/map/encode_map.c
new file mode 100644
index 0000000..bd4ec12
--- /dev/null
+++ b/tests/map/encode_map.c
@@ -0,0 +1,37 @@
+/* Encode a message using map field */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pb_encode.h>
+#include "map.pb.h"
+#include "test_helpers.h"
+
+int main(int argc, char **argv)
+{
+    uint8_t buffer[MyMessage_size];
+    MyMessage msg = MyMessage_init_zero;
+    pb_ostream_t stream;
+
+    /* Fill in the map entries */
+    msg.numbers_count = 3;
+    strncpy(msg.numbers[0].key, "one", sizeof(msg.numbers[0].key));
+    strncpy(msg.numbers[1].key, "two", sizeof(msg.numbers[1].key));
+    strncpy(msg.numbers[2].key, "seven", sizeof(msg.numbers[2].key));
+    msg.numbers[0].value = 1;
+    msg.numbers[1].value = 2;
+    msg.numbers[2].value = 7;
+
+    stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+    
+    if (pb_encode(&stream, MyMessage_fields, &msg))
+    {
+        SET_BINARY_MODE(stdout);
+        fwrite(buffer, 1, stream.bytes_written, stdout);
+        return 0;
+    }
+    else
+    {
+        fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
+        return 1;
+    }
+}
diff --git a/tests/map/map.options b/tests/map/map.options
new file mode 100644
index 0000000..1d7ebb6
--- /dev/null
+++ b/tests/map/map.options
@@ -0,0 +1,2 @@
+MyMessage.numbers         max_count:10
+MyMessage.NumbersEntry.key max_size:16
diff --git a/tests/map/map.proto b/tests/map/map.proto
new file mode 100644
index 0000000..f503625
--- /dev/null
+++ b/tests/map/map.proto
@@ -0,0 +1,6 @@
+syntax = "proto3";
+
+message MyMessage {
+    map<string,uint32> numbers = 1;
+}
+
diff --git a/tests/mem_release/SConscript b/tests/mem_release/SConscript
new file mode 100644
index 0000000..6754e28
--- /dev/null
+++ b/tests/mem_release/SConscript
@@ -0,0 +1,13 @@
+Import("env", "malloc_env")
+
+env.NanopbProto("mem_release.proto")
+
+test = malloc_env.Program(["mem_release.c",
+                    "mem_release.pb.c",
+                    "$COMMON/pb_encode_with_malloc.o",
+                    "$COMMON/pb_decode_with_malloc.o",
+                    "$COMMON/pb_common_with_malloc.o",
+                    "$COMMON/malloc_wrappers.o"])
+
+env.RunTest(test)
+
diff --git a/tests/mem_release/mem_release.c b/tests/mem_release/mem_release.c
new file mode 100644
index 0000000..dc6f87d
--- /dev/null
+++ b/tests/mem_release/mem_release.c
@@ -0,0 +1,187 @@
+/* Make sure that all fields are freed in various scenarios. */
+
+#include <pb_decode.h>
+#include <pb_encode.h>
+#include <malloc_wrappers.h>
+#include <stdio.h>
+#include <test_helpers.h>
+#include "mem_release.pb.h"
+
+#define TEST(x) if (!(x)) { \
+    fprintf(stderr, "Test " #x " on line %d failed.\n", __LINE__); \
+    return false; \
+    }
+
+static char *test_str_arr[] = {"1", "2", ""};
+static SubMessage test_msg_arr[] = {SubMessage_init_zero, SubMessage_init_zero};
+static pb_extension_t ext1, ext2;
+
+static void fill_TestMessage(TestMessage *msg)
+{
+    msg->static_req_submsg.dynamic_str = "12345";
+    msg->static_req_submsg.dynamic_str_arr_count = 3;
+    msg->static_req_submsg.dynamic_str_arr = test_str_arr;
+    msg->static_req_submsg.dynamic_submsg_count = 2;
+    msg->static_req_submsg.dynamic_submsg = test_msg_arr;
+    msg->static_req_submsg.dynamic_submsg[1].dynamic_str = "abc";
+    msg->static_opt_submsg.dynamic_str = "abc";
+    msg->static_rep_submsg_count = 2;
+    msg->static_rep_submsg[1].dynamic_str = "abc";
+    msg->has_static_opt_submsg = true;
+    msg->dynamic_submsg = &msg->static_req_submsg;
+
+    msg->extensions = &ext1;
+    ext1.type = &dynamic_ext;
+    ext1.dest = &msg->static_req_submsg;
+    ext1.next = &ext2;
+    ext2.type = &static_ext;
+    ext2.dest = &msg->static_req_submsg;
+    ext2.next = NULL;
+}
+
+/* Basic fields, nested submessages, extensions */
+static bool test_TestMessage()
+{
+    uint8_t buffer[256];
+    size_t msgsize;
+    
+    /* Construct a message with various fields filled in */
+    {
+        TestMessage msg = TestMessage_init_zero;
+        pb_ostream_t stream;
+
+        fill_TestMessage(&msg);
+        
+        stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+        if (!pb_encode(&stream, TestMessage_fields, &msg))
+        {
+            fprintf(stderr, "Encode failed: %s\n", PB_GET_ERROR(&stream));
+            return false;
+        }
+        msgsize = stream.bytes_written;
+    }
+    
+    /* Output encoded message for debug */
+    SET_BINARY_MODE(stdout);
+    fwrite(buffer, 1, msgsize, stdout);
+    
+    /* Decode memory using dynamic allocation */
+    {
+        TestMessage msg = TestMessage_init_zero;
+        pb_istream_t stream;
+        SubMessage ext2_dest;
+
+        msg.extensions = &ext1;
+        ext1.type = &dynamic_ext;
+        ext1.dest = NULL;
+        ext1.next = &ext2;
+        ext2.type = &static_ext;
+        ext2.dest = &ext2_dest;
+        ext2.next = NULL;
+        
+        stream = pb_istream_from_buffer(buffer, msgsize);
+        if (!pb_decode(&stream, TestMessage_fields, &msg))
+        {
+            fprintf(stderr, "Decode failed: %s\n", PB_GET_ERROR(&stream));
+            return false;
+        }
+        
+        /* Make sure it encodes back to same data */
+        {
+            uint8_t buffer2[256];
+            pb_ostream_t ostream = pb_ostream_from_buffer(buffer2, sizeof(buffer2));
+            TEST(pb_encode(&ostream, TestMessage_fields, &msg));
+            TEST(ostream.bytes_written == msgsize);
+            TEST(memcmp(buffer, buffer2, msgsize) == 0);
+        }
+        
+        /* Make sure that malloc counters work */
+        TEST(get_alloc_count() > 0);
+        
+        /* Make sure that pb_release releases everything */
+        pb_release(TestMessage_fields, &msg);
+        TEST(get_alloc_count() == 0);
+        
+        /* Check that double-free is a no-op */
+        pb_release(TestMessage_fields, &msg);
+        TEST(get_alloc_count() == 0);
+    }
+    
+    return true;
+}
+
+/* Oneofs */
+static bool test_OneofMessage()
+{
+    uint8_t buffer[256];
+    size_t msgsize;
+
+    {
+        pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+
+        /* Encode first with TestMessage */
+        {
+            OneofMessage msg = OneofMessage_init_zero;
+            msg.which_msgs = OneofMessage_msg1_tag;
+
+            fill_TestMessage(&msg.msgs.msg1);
+
+            if (!pb_encode(&stream, OneofMessage_fields, &msg))
+            {
+                fprintf(stderr, "Encode failed: %s\n", PB_GET_ERROR(&stream));
+                return false;
+            }
+        }
+
+        /* Encode second with SubMessage, invoking 'merge' behaviour */
+        {
+            OneofMessage msg = OneofMessage_init_zero;
+            msg.which_msgs = OneofMessage_msg2_tag;
+
+            msg.first = 999;
+            msg.msgs.msg2.dynamic_str = "ABCD";
+            msg.last = 888;
+
+            if (!pb_encode(&stream, OneofMessage_fields, &msg))
+            {
+                fprintf(stderr, "Encode failed: %s\n", PB_GET_ERROR(&stream));
+                return false;
+            }
+        }
+        msgsize = stream.bytes_written;
+    }
+
+    {
+        OneofMessage msg = OneofMessage_init_zero;
+        pb_istream_t stream = pb_istream_from_buffer(buffer, msgsize);
+        if (!pb_decode(&stream, OneofMessage_fields, &msg))
+        {
+            fprintf(stderr, "Decode failed: %s\n", PB_GET_ERROR(&stream));
+            return false;
+        }
+
+        TEST(msg.first == 999);
+        TEST(msg.which_msgs == OneofMessage_msg2_tag);
+        TEST(msg.msgs.msg2.dynamic_str);
+        TEST(strcmp(msg.msgs.msg2.dynamic_str, "ABCD") == 0);
+        TEST(msg.msgs.msg2.dynamic_str_arr == NULL);
+        TEST(msg.msgs.msg2.dynamic_submsg == NULL);
+        TEST(msg.last == 888);
+
+        pb_release(OneofMessage_fields, &msg);
+        TEST(get_alloc_count() == 0);
+        pb_release(OneofMessage_fields, &msg);
+        TEST(get_alloc_count() == 0);
+    }
+
+    return true;
+}
+
+int main()
+{
+    if (test_TestMessage() && test_OneofMessage())
+        return 0;
+    else
+        return 1;
+}
+
diff --git a/tests/mem_release/mem_release.proto b/tests/mem_release/mem_release.proto
new file mode 100644
index 0000000..0816dc2
--- /dev/null
+++ b/tests/mem_release/mem_release.proto
@@ -0,0 +1,35 @@
+syntax = "proto2";
+import "nanopb.proto";
+
+message SubMessage
+{
+    optional string dynamic_str = 1 [(nanopb).type = FT_POINTER];
+    repeated string dynamic_str_arr = 2 [(nanopb).type = FT_POINTER];
+    repeated SubMessage dynamic_submsg = 3 [(nanopb).type = FT_POINTER];
+}
+
+message TestMessage
+{
+    required SubMessage static_req_submsg = 1 [(nanopb).type = FT_STATIC];
+    optional SubMessage dynamic_submsg = 2 [(nanopb).type = FT_POINTER];
+    optional SubMessage static_opt_submsg = 3 [(nanopb).type = FT_STATIC];
+    repeated SubMessage static_rep_submsg = 4 [(nanopb).type = FT_STATIC, (nanopb).max_count=2];
+    extensions 100 to 200;
+}
+
+extend TestMessage
+{
+    optional SubMessage dynamic_ext = 100 [(nanopb).type = FT_POINTER];
+    optional SubMessage static_ext = 101 [(nanopb).type = FT_STATIC];
+}
+
+message OneofMessage
+{
+    required int32 first = 1;
+    oneof msgs
+    {
+        TestMessage msg1 = 2;
+        SubMessage msg2 = 3;
+    }
+    required int32 last = 4;
+}
diff --git a/tests/message_sizes/messages1.proto b/tests/message_sizes/messages1.proto
index 48af55a..b66fad7 100644
--- a/tests/message_sizes/messages1.proto
+++ b/tests/message_sizes/messages1.proto
@@ -1,3 +1,5 @@
+syntax = "proto2";
+
 enum MessageStatus {
     FAIL = 0;
     OK = 1;
diff --git a/tests/message_sizes/messages2.proto b/tests/message_sizes/messages2.proto
index 19fc11e..6761408 100644
--- a/tests/message_sizes/messages2.proto
+++ b/tests/message_sizes/messages2.proto
@@ -1,3 +1,5 @@
+syntax = "proto2";
+
 import 'nanopb.proto';
 import 'messages1.proto';
 
diff --git a/tests/missing_fields/SConscript b/tests/missing_fields/SConscript
index 9926efa..86ba083 100644
--- a/tests/missing_fields/SConscript
+++ b/tests/missing_fields/SConscript
@@ -3,6 +3,6 @@
 Import("env")
 
 env.NanopbProto("missing_fields")
-test = env.Program(["missing_fields.c", "missing_fields.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_decode.o"])
+test = env.Program(["missing_fields.c", "missing_fields.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 env.RunTest(test)
 
diff --git a/tests/missing_fields/missing_fields.proto b/tests/missing_fields/missing_fields.proto
index cbb23ba..cc5e550 100644
--- a/tests/missing_fields/missing_fields.proto
+++ b/tests/missing_fields/missing_fields.proto
@@ -1,5 +1,7 @@
 /* Test for one missing field among many */
 
+syntax = "proto2";
+
 message AllFields
 {
     required int32 field1 = 1;
diff --git a/tests/multiple_files/SConscript b/tests/multiple_files/SConscript
index 6b4f6b6..b1281e1 100644
--- a/tests/multiple_files/SConscript
+++ b/tests/multiple_files/SConscript
@@ -4,10 +4,13 @@
 
 incpath = env.Clone()
 incpath.Append(PROTOCPATH = '#multiple_files')
+incpath.Append(CPPPATH = '$BUILD/multiple_files')
 
-incpath.NanopbProto("callbacks")
-incpath.NanopbProto("callbacks2")
-test = incpath.Program(["test_multiple_files.c", "callbacks.pb.c", "callbacks2.pb.c"])
+incpath.NanopbProto(["multifile1", "multifile1.options"])
+incpath.NanopbProto("multifile2")
+incpath.NanopbProto("subdir/multifile2")
+test = incpath.Program(["test_multiple_files.c", "multifile1.pb.c",
+                        "multifile2.pb.c", "subdir/multifile2.pb.c"])
 
 env.RunTest(test)
 
diff --git a/tests/multiple_files/callbacks2.proto b/tests/multiple_files/callbacks2.proto
deleted file mode 100644
index 9a55e15..0000000
--- a/tests/multiple_files/callbacks2.proto
+++ /dev/null
@@ -1,9 +0,0 @@
-// Test if including generated header file for this file + implicit include of
-// callbacks.pb.h still compiles. Used with test_compiles.c.
-import "callbacks.proto";
-
-message Callback2Message {
-    required TestMessage tstmsg = 1;
-    required SubMessage submsg = 2;
-}
-
diff --git a/tests/multiple_files/multifile1.options b/tests/multiple_files/multifile1.options
new file mode 100644
index 0000000..c44d266
--- /dev/null
+++ b/tests/multiple_files/multifile1.options
@@ -0,0 +1 @@
+StaticMessage.repint32 max_count:5
diff --git a/tests/multiple_files/callbacks.proto b/tests/multiple_files/multifile1.proto
similarity index 68%
rename from tests/multiple_files/callbacks.proto
rename to tests/multiple_files/multifile1.proto
index ccd1edd..18f2c67 100644
--- a/tests/multiple_files/callbacks.proto
+++ b/tests/multiple_files/multifile1.proto
@@ -1,3 +1,5 @@
+syntax = "proto2";
+
 message SubMessage {
     optional string stringvalue = 1;
     repeated int32 int32value = 2;
@@ -14,3 +16,19 @@
     repeated string repeatedstring = 6;
 }
 
+message StaticMessage {
+    repeated fixed32 repint32 = 1;
+}
+
+enum SignedEnum {
+    SE_MIN = -128;
+    SE_MAX = 127;
+}
+
+enum UnsignedEnum {
+    UE_MIN = 0;
+    UE_MAX = 255;
+}
+
+
+
diff --git a/tests/multiple_files/multifile2.proto b/tests/multiple_files/multifile2.proto
new file mode 100644
index 0000000..4af45fd
--- /dev/null
+++ b/tests/multiple_files/multifile2.proto
@@ -0,0 +1,22 @@
+// Test if including generated header file for this file + implicit include of
+// multifile2.pb.h still compiles. Used with test_compiles.c.
+syntax = "proto2";
+
+import "multifile1.proto";
+
+message Callback2Message {
+    required TestMessage tstmsg = 1;
+    required SubMessage submsg = 2;
+}
+
+message OneofMessage {
+    oneof msgs {
+        StaticMessage tstmsg = 1;
+    }
+}
+
+message Enums {
+    required SignedEnum senum = 1;
+    required UnsignedEnum uenum = 2;
+}
+
diff --git a/tests/multiple_files/subdir/multifile2.proto b/tests/multiple_files/subdir/multifile2.proto
new file mode 100644
index 0000000..847a929
--- /dev/null
+++ b/tests/multiple_files/subdir/multifile2.proto
@@ -0,0 +1,25 @@
+syntax = "proto2";
+
+package subdir;
+
+import "multifile1.proto";
+
+message Callback2Message {
+    required TestMessage tstmsg = 1;
+    required SubMessage submsg = 2;
+}
+
+message OneofMessage {
+    oneof msgs {
+        StaticMessage tstmsg = 1;
+    }
+}
+
+message Enums {
+    required SignedEnum senum = 1;
+    required UnsignedEnum uenum = 2;
+}
+
+message SubdirMessage {
+    required int32 foo = 1 [default = 15];
+}
diff --git a/tests/multiple_files/test_multiple_files.c b/tests/multiple_files/test_multiple_files.c
index 05722dc..70a3e59 100644
--- a/tests/multiple_files/test_multiple_files.c
+++ b/tests/multiple_files/test_multiple_files.c
@@ -4,9 +4,27 @@
 
 #include <stdio.h>
 #include <pb_encode.h>
-#include "callbacks2.pb.h"
+#include "unittests.h"
+#include "multifile2.pb.h"
+#include "subdir/multifile2.pb.h"
 
 int main()
 {
-	return 0;
+    int status = 0;
+    
+    /* Test that included file options are properly loaded */
+    TEST(OneofMessage_size == 27);
+    
+    /* Check that enum signedness is detected properly */
+    TEST(PB_LTYPE(Enums_fields[0].type) == PB_LTYPE_VARINT);
+    TEST(PB_LTYPE(Enums_fields[1].type) == PB_LTYPE_UVARINT);
+    
+    /* Test that subdir file is correctly included */
+    {
+        subdir_SubdirMessage foo = subdir_SubdirMessage_init_default;
+        TEST(foo.foo == 15);
+        /* TEST(subdir_OneofMessage_size == 27); */ /* TODO: Issue #172 */
+    }
+    
+    return status;
 }
diff --git a/tests/no_errmsg/SConscript b/tests/no_errmsg/SConscript
index ed46705..629bfa6 100644
--- a/tests/no_errmsg/SConscript
+++ b/tests/no_errmsg/SConscript
@@ -18,10 +18,11 @@
 strict.Append(CFLAGS = strict['CORECFLAGS'])
 strict.Object("pb_decode_noerr.o", "$NANOPB/pb_decode.c")
 strict.Object("pb_encode_noerr.o", "$NANOPB/pb_encode.c")
+strict.Object("pb_common_noerr.o", "$NANOPB/pb_common.c")
 
 # Now build and run the test normally.
-enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_noerr.o"])
-dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_noerr.o"])
+enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_noerr.o", "pb_common_noerr.o"])
+dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_noerr.o", "pb_common_noerr.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_alltypes.output"])
diff --git a/tests/no_messages/no_messages.proto b/tests/no_messages/no_messages.proto
index 279216b..45bb2e6 100644
--- a/tests/no_messages/no_messages.proto
+++ b/tests/no_messages/no_messages.proto
@@ -1,5 +1,7 @@
 /* Test that a file without any messages works. */
 
+syntax = "proto2";
+
 enum Test {
     First = 1;
 }
diff --git a/tests/oneof/SConscript b/tests/oneof/SConscript
new file mode 100644
index 0000000..928ce63
--- /dev/null
+++ b/tests/oneof/SConscript
@@ -0,0 +1,33 @@
+# Test the 'oneof' feature for generating C unions.
+
+Import('env')
+
+import re
+
+match = None
+if 'PROTOC_VERSION' in env:
+    match = re.search('([0-9]+).([0-9]+).([0-9]+)', env['PROTOC_VERSION'])
+
+if match:
+    version = list(map(int, match.groups()))
+
+# Oneof is supported by protoc >= 2.6.0
+if env.GetOption('clean') or (match and (version[0] > 2 or (version[0] == 2 and version[1] >= 6))):
+    env.NanopbProto('oneof')
+
+    enc = env.Program(['encode_oneof.c',
+                    'oneof.pb.c',
+                    '$COMMON/pb_encode.o',
+                    '$COMMON/pb_common.o'])
+
+    dec = env.Program(['decode_oneof.c',
+                    'oneof.pb.c',
+                    '$COMMON/pb_decode.o',
+                    '$COMMON/pb_common.o'])
+
+    env.RunTest("message1.pb", enc, ARGS = ['1'])
+    env.RunTest("message1.txt", [dec, 'message1.pb'], ARGS = ['1'])
+    env.RunTest("message2.pb", enc, ARGS = ['2'])
+    env.RunTest("message2.txt", [dec, 'message2.pb'], ARGS = ['2'])
+    env.RunTest("message3.pb", enc, ARGS = ['3'])
+    env.RunTest("message3.txt", [dec, 'message3.pb'], ARGS = ['3'])
diff --git a/tests/oneof/decode_oneof.c b/tests/oneof/decode_oneof.c
new file mode 100644
index 0000000..37075cd
--- /dev/null
+++ b/tests/oneof/decode_oneof.c
@@ -0,0 +1,131 @@
+/* Decode a message using oneof fields */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pb_decode.h>
+#include "oneof.pb.h"
+#include "test_helpers.h"
+#include "unittests.h"
+
+/* Test the 'OneOfMessage' */
+int test_oneof_1(pb_istream_t *stream, int option)
+{
+    OneOfMessage msg;
+    int status = 0;
+
+    /* To better catch initialization errors */
+    memset(&msg, 0xAA, sizeof(msg));
+
+    if (!pb_decode(stream, OneOfMessage_fields, &msg))
+    {
+        printf("Decoding failed: %s\n", PB_GET_ERROR(stream));
+        return 1;
+    }
+
+    /* Check that the basic fields work normally */
+    TEST(msg.prefix == 123);
+    TEST(msg.suffix == 321);
+
+    /* Check that we got the right oneof according to command line */
+    if (option == 1)
+    {
+        TEST(msg.which_values == OneOfMessage_first_tag);
+        TEST(msg.values.first == 999);
+    }
+    else if (option == 2)
+    {
+        TEST(msg.which_values == OneOfMessage_second_tag);
+        TEST(strcmp(msg.values.second, "abcd") == 0);
+    }
+    else if (option == 3)
+    {
+        TEST(msg.which_values == OneOfMessage_third_tag);
+        TEST(msg.values.third.array[0] == 1);
+        TEST(msg.values.third.array[1] == 2);
+        TEST(msg.values.third.array[2] == 3);
+        TEST(msg.values.third.array[3] == 4);
+        TEST(msg.values.third.array[4] == 5);
+    }
+
+    return status;
+}
+
+
+/* Test the 'PlainOneOfMessage' */
+int test_oneof_2(pb_istream_t *stream, int option)
+{
+    PlainOneOfMessage msg = PlainOneOfMessage_init_zero;
+    int status = 0;
+
+    if (!pb_decode(stream, PlainOneOfMessage_fields, &msg))
+    {
+        printf("Decoding failed: %s\n", PB_GET_ERROR(stream));
+        return 1;
+    }
+
+    /* Check that we got the right oneof according to command line */
+    if (option == 1)
+    {
+        TEST(msg.which_values == OneOfMessage_first_tag);
+        TEST(msg.values.first == 999);
+    }
+    else if (option == 2)
+    {
+        TEST(msg.which_values == OneOfMessage_second_tag);
+        TEST(strcmp(msg.values.second, "abcd") == 0);
+    }
+    else if (option == 3)
+    {
+        TEST(msg.which_values == OneOfMessage_third_tag);
+        TEST(msg.values.third.array[0] == 1);
+        TEST(msg.values.third.array[1] == 2);
+        TEST(msg.values.third.array[2] == 3);
+        TEST(msg.values.third.array[3] == 4);
+        TEST(msg.values.third.array[4] == 5);
+    }
+
+    return status;
+}
+
+int main(int argc, char **argv)
+{
+    uint8_t buffer[OneOfMessage_size];
+    size_t count;
+    int option;
+
+    if (argc != 2)
+    {
+        fprintf(stderr, "Usage: decode_oneof [number]\n");
+        return 1;
+    }
+    option = atoi(argv[1]);
+
+    SET_BINARY_MODE(stdin);
+    count = fread(buffer, 1, sizeof(buffer), stdin);
+
+    if (!feof(stdin))
+    {
+        printf("Message does not fit in buffer\n");
+        return 1;
+    }
+
+    {
+        int status = 0;
+        pb_istream_t stream;
+
+        stream = pb_istream_from_buffer(buffer, count);
+        status = test_oneof_1(&stream, option);
+
+        if (status != 0)
+            return status;
+
+        stream = pb_istream_from_buffer(buffer, count);
+        status = test_oneof_2(&stream, option);
+
+        if (status != 0)
+            return status;
+    }
+
+    return 0;
+}
diff --git a/tests/oneof/encode_oneof.c b/tests/oneof/encode_oneof.c
new file mode 100644
index 0000000..913d2d4
--- /dev/null
+++ b/tests/oneof/encode_oneof.c
@@ -0,0 +1,64 @@
+/* Encode a message using oneof fields */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pb_encode.h>
+#include "oneof.pb.h"
+#include "test_helpers.h"
+
+int main(int argc, char **argv)
+{
+    uint8_t buffer[OneOfMessage_size];
+    OneOfMessage msg = OneOfMessage_init_zero;
+    pb_ostream_t stream;
+    int option;
+
+    if (argc != 2)
+    {
+        fprintf(stderr, "Usage: encode_oneof [number]\n");
+        return 1;
+    }
+    option = atoi(argv[1]);
+
+    /* Prefix and suffix are used to test that the union does not disturb
+     * other fields in the same message. */
+    msg.prefix = 123;
+
+    /* We encode one of the 'values' fields based on command line argument */
+    if (option == 1)
+    {
+        msg.which_values = OneOfMessage_first_tag;
+        msg.values.first = 999;
+    }
+    else if (option == 2)
+    {
+        msg.which_values = OneOfMessage_second_tag;
+        strcpy(msg.values.second, "abcd");
+    }
+    else if (option == 3)
+    {
+        msg.which_values = OneOfMessage_third_tag;
+        msg.values.third.array_count = 5;
+        msg.values.third.array[0] = 1;
+        msg.values.third.array[1] = 2;
+        msg.values.third.array[2] = 3;
+        msg.values.third.array[3] = 4;
+        msg.values.third.array[4] = 5;
+    }
+
+    msg.suffix = 321;
+
+    stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+
+    if (pb_encode(&stream, OneOfMessage_fields, &msg))
+    {
+        SET_BINARY_MODE(stdout);
+        fwrite(buffer, 1, stream.bytes_written, stdout);
+        return 0;
+    }
+    else
+    {
+        fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
+        return 1;
+    }
+}
diff --git a/tests/oneof/oneof.proto b/tests/oneof/oneof.proto
new file mode 100644
index 0000000..b4fe56f
--- /dev/null
+++ b/tests/oneof/oneof.proto
@@ -0,0 +1,32 @@
+syntax = "proto2";
+
+import 'nanopb.proto';
+
+message SubMessage
+{
+    repeated int32 array = 1 [(nanopb).max_count = 8];
+}
+
+/* Oneof in a message with other fields */
+message OneOfMessage
+{
+    required int32 prefix = 1;
+    oneof values
+    {
+        int32 first = 5;
+        string second = 6 [(nanopb).max_size = 8];
+        SubMessage third = 7;
+    }
+    required int32 suffix = 99;
+}
+
+/* Oneof in a message by itself */
+message PlainOneOfMessage
+{
+    oneof values
+    {
+        int32 first = 5;
+        string second = 6 [(nanopb).max_size = 8];
+        SubMessage third = 7;
+    }
+}
\ No newline at end of file
diff --git a/tests/options/SConscript b/tests/options/SConscript
index 89a00fa..215e3bd 100644
--- a/tests/options/SConscript
+++ b/tests/options/SConscript
@@ -4,6 +4,9 @@
 
 env.NanopbProto("options")
 env.Object('options.pb.c')
-
 env.Match(['options.pb.h', 'options.expected'])
 
+env.NanopbProto("proto3_options")
+env.Object('proto3_options.pb.c')
+env.Match(['proto3_options.pb.h', 'proto3_options.expected'])
+
diff --git a/tests/options/options.expected b/tests/options/options.expected
index e6179a2..9e47e6a 100644
--- a/tests/options/options.expected
+++ b/tests/options/options.expected
@@ -1,7 +1,20 @@
 char filesize\[20\];
 char msgsize\[30\];
 char fieldsize\[40\];
+char fieldlen\[41\];
 pb_callback_t int32_callback;
 \sEnumValue1 = 1
 Message5_EnumValue1
 } pb_packed my_packed_struct;
+! skipped_field
+! SkippedMessage
+#define PB_MSG_103 Message3
+#define PB_MSG_104 Message4
+#define PB_MSG_105 Message5
+#define OPTIONS_MESSAGES \\
+\s+PB_MSG\(103,[0-9]*,Message3\) \\
+\s+PB_MSG\(104,-1,Message4\) \\
+\s+PB_MSG\(105,[0-9]*,Message5\) \\
+#define Message5_msgid 105
+! has_proto3field
+
diff --git a/tests/options/options.proto b/tests/options/options.proto
index b5badcf..c6ca5e2 100644
--- a/tests/options/options.proto
+++ b/tests/options/options.proto
@@ -2,6 +2,8 @@
  * options.expected lists the patterns that are searched for in the output.
  */
 
+syntax = "proto2";
+
 import "nanopb.proto";
 
 // File level options
@@ -22,12 +24,15 @@
 // Field level options
 message Message3
 {
+    option (nanopb_msgopt).msgid = 103;
     required string fieldsize = 1 [(nanopb).max_size = 40];
+    required string fieldlen = 2 [(nanopb).max_length = 40];
 }
 
 // Forced callback field
 message Message4
 {
+    option (nanopb_msgopt).msgid = 104;
     required int32 int32_callback = 1 [(nanopb).type = FT_CALLBACK];
 }
 
@@ -47,6 +52,7 @@
 // Short enum names inside message
 message Message5
 {
+    option (nanopb_msgopt).msgid = 105;
     enum Enum2
     {
        option (nanopb_enumopt).long_names = false;
@@ -63,11 +69,30 @@
 }
 
 // Message with ignored field
-// Note: doesn't really test if the field is missing in the output,
-// but atleast tests that the output compiles.
 message Message6
 {
     required int32 field1 = 1;
-    optional int32 field2 = 2 [(nanopb).type = FT_IGNORE];
+    optional int32 skipped_field = 2 [(nanopb).type = FT_IGNORE];
+}
+
+// Message that is skipped
+message SkippedMessage
+{
+    option (nanopb_msgopt).skip_message = true;
+    required int32 foo = 1;
+}
+
+// Message with oneof field
+message OneofMessage
+{
+    oneof foo {
+        int32 bar = 1;
+    }
+}
+
+// Proto3-style optional field in proto2 file
+message Proto3Field
+{
+    optional int32 proto3field = 1 [(nanopb).proto3 = true];
 }
 
diff --git a/tests/options/proto3_options.expected b/tests/options/proto3_options.expected
new file mode 100644
index 0000000..cc2f29c
--- /dev/null
+++ b/tests/options/proto3_options.expected
@@ -0,0 +1,4 @@
+! bool has_proto3_default
+bool has_proto3_off
+! bool has_proto3_on
+
diff --git a/tests/options/proto3_options.proto b/tests/options/proto3_options.proto
new file mode 100644
index 0000000..1017f04
--- /dev/null
+++ b/tests/options/proto3_options.proto
@@ -0,0 +1,11 @@
+syntax = "proto3";
+
+import "nanopb.proto";
+
+message Message1
+{
+    int32 proto3_default = 1;
+    int32 proto3_off = 2 [(nanopb).proto3 = false];
+    int32 proto3_on = 3 [(nanopb).proto3 = true];
+}
+
diff --git a/tests/package_name/SConscript b/tests/package_name/SConscript
index 8f1b902..4afc503 100644
--- a/tests/package_name/SConscript
+++ b/tests/package_name/SConscript
@@ -3,14 +3,16 @@
 
 Import("env")
 
-# Build a modified alltypes.proto
-def modify_proto(target, source, env):
-    '''Add a "package test.package;" directive to the beginning of the .proto file.'''
-    data = open(str(source[0]), 'r').read()
-    open(str(target[0]), 'w').write("package test.package;\n\n" + data)
-    return 0
+def set_pkgname(src, dst, pkgname):
+    data = open(str(src)).read()
+    placeholder = '// package name placeholder'
+    assert placeholder in data
+    data = data.replace(placeholder, 'package %s;' % pkgname)
+    open(str(dst), 'w').write(data)
 
-env.Command("alltypes.proto", "#alltypes/alltypes.proto", modify_proto)
+# Build a modified alltypes.proto
+env.Command("alltypes.proto", "#alltypes/alltypes.proto",
+            lambda target, source, env: set_pkgname(source[0], target[0], 'test.package'))
 env.Command("alltypes.options", "#alltypes/alltypes.options", Copy("$TARGET", "$SOURCE"))
 env.NanopbProto(["alltypes", "alltypes.options"])
 
@@ -29,7 +31,7 @@
 env.Command("encode_alltypes.c", "#alltypes/encode_alltypes.c", modify_c)
 
 # Encode and compare results to original alltypes testcase
-enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o"])
+enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
 refdec = "$BUILD/alltypes/decode_alltypes$PROGSUFFIX"
 env.RunTest(enc)
 env.Compare(["encode_alltypes.output", "$BUILD/alltypes/encode_alltypes.output"])
diff --git a/tests/regression/issue_118/SConscript b/tests/regression/issue_118/SConscript
new file mode 100644
index 0000000..833d9de
--- /dev/null
+++ b/tests/regression/issue_118/SConscript
@@ -0,0 +1,12 @@
+# Regression test for Issue 118: Short enum names in imported proto files are not honoured
+
+Import("env")
+env = env.Clone()
+env.Append(PROTOCPATH = "#regression/issue_118")
+
+env.NanopbProto("enumdef")
+env.Object('enumdef.pb.c')
+
+env.NanopbProto(["enumuse", "enumdef.proto"])
+env.Object('enumuse.pb.c')
+
diff --git a/tests/regression/issue_118/enumdef.proto b/tests/regression/issue_118/enumdef.proto
new file mode 100644
index 0000000..46845bc
--- /dev/null
+++ b/tests/regression/issue_118/enumdef.proto
@@ -0,0 +1,8 @@
+syntax = "proto2";
+
+import 'nanopb.proto';
+
+enum MyEnum {
+	option (nanopb_enumopt).long_names = false;
+	FOOBAR = 1;
+}
diff --git a/tests/regression/issue_118/enumuse.proto b/tests/regression/issue_118/enumuse.proto
new file mode 100644
index 0000000..4afc452
--- /dev/null
+++ b/tests/regression/issue_118/enumuse.proto
@@ -0,0 +1,7 @@
+syntax = "proto2";
+
+import 'enumdef.proto';
+
+message MyMessage {
+	required MyEnum myenum = 1 [default = FOOBAR];
+}
diff --git a/tests/regression/issue_125/SConscript b/tests/regression/issue_125/SConscript
new file mode 100644
index 0000000..f2155e6
--- /dev/null
+++ b/tests/regression/issue_125/SConscript
@@ -0,0 +1,9 @@
+# Regression test for Issue 125: Wrong identifier name for extension fields
+
+Import("env")
+
+env.NanopbProto(["extensionbug", "extensionbug.options"])
+env.Object('extensionbug.pb.c')
+
+env.Match(['extensionbug.pb.h', 'extensionbug.expected'])
+
diff --git a/tests/regression/issue_125/extensionbug.expected b/tests/regression/issue_125/extensionbug.expected
new file mode 100644
index 0000000..fc21335
--- /dev/null
+++ b/tests/regression/issue_125/extensionbug.expected
@@ -0,0 +1,3 @@
+pb_extension_type_t Message2_extras
+uint32_t field2
+
diff --git a/tests/regression/issue_125/extensionbug.options b/tests/regression/issue_125/extensionbug.options
new file mode 100644
index 0000000..30b464a
--- /dev/null
+++ b/tests/regression/issue_125/extensionbug.options
@@ -0,0 +1,4 @@
+* type:FT_IGNORE
+
+Message2.extras type:FT_STATIC
+Message2.field2 type:FT_STATIC
diff --git a/tests/regression/issue_125/extensionbug.proto b/tests/regression/issue_125/extensionbug.proto
new file mode 100644
index 0000000..fd1e74f
--- /dev/null
+++ b/tests/regression/issue_125/extensionbug.proto
@@ -0,0 +1,18 @@
+syntax = "proto2";
+
+message Message1
+{
+	optional uint32	fieldA = 1;
+	extensions 30 to max;
+}
+
+message Message2
+{
+	extend Message1
+	{
+		optional Message2 extras = 30;
+	}
+	
+	optional uint32	field1 = 1;
+	optional uint32 field2 = 2;
+}
diff --git a/tests/regression/issue_141/SConscript b/tests/regression/issue_141/SConscript
new file mode 100644
index 0000000..b6526be
--- /dev/null
+++ b/tests/regression/issue_141/SConscript
@@ -0,0 +1,8 @@
+# Regression test for issue 141: wrong encoded size #define for oneof messages
+
+Import("env")
+
+env.NanopbProto("testproto")
+env.Object('testproto.pb.c')
+env.Match(['testproto.pb.h', 'testproto.expected'])
+
diff --git a/tests/regression/issue_141/testproto.expected b/tests/regression/issue_141/testproto.expected
new file mode 100644
index 0000000..75bc195
--- /dev/null
+++ b/tests/regression/issue_141/testproto.expected
@@ -0,0 +1,7 @@
+define SubMessage_size \s* 88
+define OneOfMessage_size \s* 113
+define topMessage_size \s* 70
+define MyMessage1_size \s* 46
+define MyMessage2_size \s* 8
+define MyMessage3_size \s* 5
+define MyMessage4_size \s* 18
diff --git a/tests/regression/issue_141/testproto.proto b/tests/regression/issue_141/testproto.proto
new file mode 100644
index 0000000..a445c68
--- /dev/null
+++ b/tests/regression/issue_141/testproto.proto
@@ -0,0 +1,52 @@
+syntax = "proto2";
+
+import 'nanopb.proto';
+
+message SubMessage
+{
+    repeated int32 array = 1 [(nanopb).max_count = 8];
+}
+
+message OneOfMessage
+{
+    required int32 prefix = 1;
+    oneof values
+    {
+        int32 first = 5;
+        string second = 6 [(nanopb).max_size = 8];
+        SubMessage third = 7;
+    }
+    required int32 suffix = 99;
+}
+
+message topMessage {
+	required int32 start = 1;
+	oneof msg {
+		MyMessage1 msg1 = 2;
+		MyMessage2 msg2 = 3;
+	}
+	required int32 end = 4;
+}
+
+message MyMessage1 {
+	required uint32 n1 = 1;
+	required uint32 n2 = 2;
+	required string s = 3 [(nanopb).max_size = 32];
+}
+
+message MyMessage2 {
+	required uint32 num = 1;
+	required bool b = 2;
+}
+
+message MyMessage3 {
+	required bool bbb = 1;
+	required string ss = 2 [(nanopb).max_size = 1];
+}
+
+message MyMessage4 {
+	required bool bbbb = 1;
+	required string sss = 2 [(nanopb).max_size = 2];
+	required uint32 num = 3;
+	required uint32 num2 = 4;
+}
diff --git a/tests/regression/issue_145/SConscript b/tests/regression/issue_145/SConscript
new file mode 100644
index 0000000..0b793a7
--- /dev/null
+++ b/tests/regression/issue_145/SConscript
@@ -0,0 +1,9 @@
+# Regression test for Issue 145: Allow /* */ and // comments in .options files
+
+Import("env")
+
+env.NanopbProto(["comments", "comments.options"])
+env.Object('comments.pb.c')
+
+env.Match(['comments.pb.h', 'comments.expected'])
+
diff --git a/tests/regression/issue_145/comments.expected b/tests/regression/issue_145/comments.expected
new file mode 100644
index 0000000..7f87458
--- /dev/null
+++ b/tests/regression/issue_145/comments.expected
@@ -0,0 +1,3 @@
+char foo\[5\];
+char bar\[16\];
+
diff --git a/tests/regression/issue_145/comments.options b/tests/regression/issue_145/comments.options
new file mode 100644
index 0000000..89959ba
--- /dev/null
+++ b/tests/regression/issue_145/comments.options
@@ -0,0 +1,6 @@
+/* Block comment */
+# Line comment
+// Line comment
+DummyMessage.foo /* Block comment */ max_size:5
+DummyMessage.bar max_size:16 # Line comment ###
+
diff --git a/tests/regression/issue_145/comments.proto b/tests/regression/issue_145/comments.proto
new file mode 100644
index 0000000..621779f
--- /dev/null
+++ b/tests/regression/issue_145/comments.proto
@@ -0,0 +1,7 @@
+syntax = "proto2";
+
+message DummyMessage {
+    required string foo = 1;
+    required string bar = 2;
+}
+
diff --git a/tests/regression/issue_166/SConscript b/tests/regression/issue_166/SConscript
new file mode 100644
index 0000000..c50b919
--- /dev/null
+++ b/tests/regression/issue_166/SConscript
@@ -0,0 +1,13 @@
+# Verify that the maximum encoded size is calculated properly
+# for enums.
+
+Import('env')
+
+env.NanopbProto('enums')
+
+p = env.Program(["enum_encoded_size.c",
+                 "enums.pb.c",
+                 "$COMMON/pb_encode.o",
+                 "$COMMON/pb_common.o"])
+env.RunTest(p)
+
diff --git a/tests/regression/issue_166/enum_encoded_size.c b/tests/regression/issue_166/enum_encoded_size.c
new file mode 100644
index 0000000..84e1c7d
--- /dev/null
+++ b/tests/regression/issue_166/enum_encoded_size.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <string.h>
+#include <pb_encode.h>
+#include "unittests.h"
+#include "enums.pb.h"
+
+int main()
+{
+    int status = 0;
+    
+    uint8_t buf[256];
+    SignedMsg msg1;
+    UnsignedMsg msg2;
+    pb_ostream_t s;
+    
+    {
+        COMMENT("Test negative value of signed enum");
+        /* Negative value should take up the maximum size */
+        msg1.value = SignedEnum_SE_MIN;
+        s = pb_ostream_from_buffer(buf, sizeof(buf));
+        TEST(pb_encode(&s, SignedMsg_fields, &msg1));
+        TEST(s.bytes_written == SignedMsg_size);
+        
+        COMMENT("Test positive value of signed enum");
+        /* Positive value should be smaller */
+        msg1.value = SignedEnum_SE_MAX;
+        s = pb_ostream_from_buffer(buf, sizeof(buf));
+        TEST(pb_encode(&s, SignedMsg_fields, &msg1));
+        TEST(s.bytes_written < SignedMsg_size);
+    }
+    
+    {
+        COMMENT("Test positive value of unsigned enum");
+        /* This should take up the maximum size */
+        msg2.value = UnsignedEnum_UE_MAX;
+        s = pb_ostream_from_buffer(buf, sizeof(buf));
+        TEST(pb_encode(&s, UnsignedMsg_fields, &msg2));
+        TEST(s.bytes_written == UnsignedMsg_size);
+    }
+    
+    return status;
+}
+
diff --git a/tests/regression/issue_166/enums.proto b/tests/regression/issue_166/enums.proto
new file mode 100644
index 0000000..3694804
--- /dev/null
+++ b/tests/regression/issue_166/enums.proto
@@ -0,0 +1,18 @@
+syntax = "proto2";
+
+enum SignedEnum {
+    SE_MIN = -1;
+    SE_MAX = 255;
+}
+
+enum UnsignedEnum {
+    UE_MAX = 65536;
+}
+
+message SignedMsg {
+    required SignedEnum value = 1;
+}
+
+message UnsignedMsg {
+    required UnsignedEnum value = 1;
+}
diff --git a/tests/regression/issue_172/SConscript b/tests/regression/issue_172/SConscript
new file mode 100644
index 0000000..49c919e
--- /dev/null
+++ b/tests/regression/issue_172/SConscript
@@ -0,0 +1,16 @@
+# Verify that _size define is generated for messages that have
+# includes from another directory.
+
+Import('env')
+
+incpath = env.Clone()
+incpath.Append(PROTOCPATH="#regression/issue_172/submessage")
+incpath.Append(CPPPATH="$BUILD/regression/issue_172/submessage")
+incpath.NanopbProto('test')
+incpath.NanopbProto(['submessage/submessage', 'submessage/submessage.options'])
+
+p = incpath.Program(["msg_size.c",
+                     "test.pb.c",
+                     "submessage/submessage.pb.c"])
+
+
diff --git a/tests/regression/issue_172/msg_size.c b/tests/regression/issue_172/msg_size.c
new file mode 100644
index 0000000..be45acb
--- /dev/null
+++ b/tests/regression/issue_172/msg_size.c
@@ -0,0 +1,9 @@
+#include "test.pb.h"
+
+PB_STATIC_ASSERT(testmessage_size >= 1+1+1+1+16, TESTMESSAGE_SIZE_IS_WRONG)
+
+int main()
+{
+    return 0;
+}
+
diff --git a/tests/regression/issue_172/submessage/submessage.options b/tests/regression/issue_172/submessage/submessage.options
new file mode 100644
index 0000000..12fb198
--- /dev/null
+++ b/tests/regression/issue_172/submessage/submessage.options
@@ -0,0 +1 @@
+submessage.data max_size: 16
diff --git a/tests/regression/issue_172/submessage/submessage.proto b/tests/regression/issue_172/submessage/submessage.proto
new file mode 100644
index 0000000..ce6804a
--- /dev/null
+++ b/tests/regression/issue_172/submessage/submessage.proto
@@ -0,0 +1,4 @@
+syntax = "proto2";
+message submessage {
+    required bytes data = 1;
+}
diff --git a/tests/regression/issue_172/test.proto b/tests/regression/issue_172/test.proto
new file mode 100644
index 0000000..fbd97be
--- /dev/null
+++ b/tests/regression/issue_172/test.proto
@@ -0,0 +1,6 @@
+syntax = "proto2";
+import "submessage.proto";
+
+message testmessage {
+ optional submessage sub = 1;
+}
diff --git a/tests/regression/issue_188/SConscript b/tests/regression/issue_188/SConscript
new file mode 100644
index 0000000..6bc3271
--- /dev/null
+++ b/tests/regression/issue_188/SConscript
@@ -0,0 +1,6 @@
+# Regression test for issue with Enums inside OneOf.
+
+Import('env')
+
+env.NanopbProto('oneof')
+
diff --git a/tests/regression/issue_188/oneof.proto b/tests/regression/issue_188/oneof.proto
new file mode 100644
index 0000000..e37f5c0
--- /dev/null
+++ b/tests/regression/issue_188/oneof.proto
@@ -0,0 +1,29 @@
+syntax = "proto2";
+
+message MessageOne
+{
+    required uint32 one = 1;
+    required uint32 two = 2;
+    required uint32 three = 3;
+    required int32 four = 4;
+}
+
+enum EnumTwo
+{
+    SOME_ENUM_1 = 1;
+    SOME_ENUM_2 = 5;
+    SOME_ENUM_3 = 6;
+    SOME_ENUM_4 = 9;
+    SOME_ENUM_5 = 10;
+    SOME_ENUM_6 = 12;
+    SOME_ENUM_7 = 39;  
+    SOME_ENUM_8 = 401;
+}
+
+message OneofMessage
+{
+    oneof payload {
+        MessageOne message = 1;
+        EnumTwo enum = 2;
+    }
+}
diff --git a/tests/regression/issue_195/SConscript b/tests/regression/issue_195/SConscript
new file mode 100644
index 0000000..78326d3
--- /dev/null
+++ b/tests/regression/issue_195/SConscript
@@ -0,0 +1,10 @@
+# Regression test for Issue 195: Message size not calculated if a submessage includes 
+# bytes. Basically a non-working #define being generated.
+
+Import("env")
+
+env.NanopbProto(["test"])
+env.Object('test.pb.c')
+
+env.Match(['test.pb.h', 'test.expected'])
+
diff --git a/tests/regression/issue_195/test.expected b/tests/regression/issue_195/test.expected
new file mode 100644
index 0000000..83ea7ab
--- /dev/null
+++ b/tests/regression/issue_195/test.expected
@@ -0,0 +1 @@
+/\* TestMessage_size depends
diff --git a/tests/regression/issue_195/test.proto b/tests/regression/issue_195/test.proto
new file mode 100644
index 0000000..7a77d69
--- /dev/null
+++ b/tests/regression/issue_195/test.proto
@@ -0,0 +1,8 @@
+message TestMessage {
+    required uint32 id = 1;
+    required bytes payload = 2;
+}
+message EncapsulatedMessage {
+    required uint32 id = 1;
+    required TestMessage test = 2;
+}
diff --git a/tests/regression/issue_203/SConscript b/tests/regression/issue_203/SConscript
new file mode 100644
index 0000000..8b4d6cc
--- /dev/null
+++ b/tests/regression/issue_203/SConscript
@@ -0,0 +1,9 @@
+# Regression test for issue with multiple files generated at once
+
+Import('env')
+
+env.Command(['file1.pb.c', 'file1.pb.h', 'file2.pb.c', 'file2.pb.h'], ['file1.proto', 'file2.proto'],
+            env['NANOPB_PROTO_CMD'])
+
+env.Object('file1.pb.c')
+env.Object('file2.pb.c')
diff --git a/tests/regression/issue_203/file1.proto b/tests/regression/issue_203/file1.proto
new file mode 100644
index 0000000..dae250b
--- /dev/null
+++ b/tests/regression/issue_203/file1.proto
@@ -0,0 +1,10 @@
+syntax = "proto2";
+
+message SubMessage1 {
+	required int32 foo = 1;
+}
+
+message Message1 {
+	required SubMessage1 bar = 1;
+}
+
diff --git a/tests/regression/issue_203/file2.proto b/tests/regression/issue_203/file2.proto
new file mode 100644
index 0000000..513b0f0
--- /dev/null
+++ b/tests/regression/issue_203/file2.proto
@@ -0,0 +1,10 @@
+syntax = "proto2";
+
+message SubMessage2 {
+	required int32 foo = 1;
+}
+
+message Message2 {
+	required SubMessage2 bar = 1;
+}
+
diff --git a/tests/regression/issue_205/SConscript b/tests/regression/issue_205/SConscript
new file mode 100644
index 0000000..ed8899d
--- /dev/null
+++ b/tests/regression/issue_205/SConscript
@@ -0,0 +1,14 @@
+# Check that pb_release() correctly handles corrupted size fields of
+# static arrays.
+
+Import('env', 'malloc_env')
+
+env.NanopbProto('size_corruption')
+
+p = malloc_env.Program(["size_corruption.c",
+                         "size_corruption.pb.c",
+                         "$COMMON/pb_decode_with_malloc.o",
+                         "$COMMON/pb_common_with_malloc.o",
+                         "$COMMON/malloc_wrappers.o"])
+env.RunTest(p)
+
diff --git a/tests/regression/issue_205/size_corruption.c b/tests/regression/issue_205/size_corruption.c
new file mode 100644
index 0000000..08cef45
--- /dev/null
+++ b/tests/regression/issue_205/size_corruption.c
@@ -0,0 +1,12 @@
+#include "size_corruption.pb.h"
+#include <pb_decode.h>
+
+int main()
+{
+    MainMessage msg = MainMessage_init_zero;
+    msg.bar_count = (pb_size_t)-1;
+    pb_release(MainMessage_fields, &msg);
+    
+    return 0;
+}
+
diff --git a/tests/regression/issue_205/size_corruption.proto b/tests/regression/issue_205/size_corruption.proto
new file mode 100644
index 0000000..6c9c245
--- /dev/null
+++ b/tests/regression/issue_205/size_corruption.proto
@@ -0,0 +1,11 @@
+syntax = "proto2";
+import 'nanopb.proto';
+
+message SubMessage {
+    repeated int32 foo = 1 [(nanopb).type = FT_POINTER];
+}
+
+message MainMessage {
+    repeated SubMessage bar = 1 [(nanopb).max_count = 5];
+}
+
diff --git a/tests/regression/issue_227/SConscript b/tests/regression/issue_227/SConscript
new file mode 100644
index 0000000..1074124
--- /dev/null
+++ b/tests/regression/issue_227/SConscript
@@ -0,0 +1,14 @@
+# Regression test for Issue 227:Using proto3 type fields can cause unaligned access
+# NOTE: This test will only detect problems when run with clang sanitizer (which
+# is done regularly by a jenkins run).
+
+Import('env')
+
+env.NanopbProto('unaligned_uint64')
+
+p = env.Program(["unaligned_uint64.c",
+                 "unaligned_uint64.pb.c",
+                 "$COMMON/pb_encode.o",
+                 "$COMMON/pb_common.o"])
+env.RunTest(p)
+
diff --git a/tests/regression/issue_227/unaligned_uint64.c b/tests/regression/issue_227/unaligned_uint64.c
new file mode 100644
index 0000000..17c1d77
--- /dev/null
+++ b/tests/regression/issue_227/unaligned_uint64.c
@@ -0,0 +1,14 @@
+#include "unaligned_uint64.pb.h"
+#include <pb_encode.h>
+
+int main()
+{
+    uint8_t buf[128];
+    pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf));
+    MainMessage msg = MainMessage_init_zero;
+    msg.bar[0] = 'A';
+    pb_encode(&stream, MainMessage_fields, &msg);
+    
+    return 0;
+}
+
diff --git a/tests/regression/issue_227/unaligned_uint64.proto b/tests/regression/issue_227/unaligned_uint64.proto
new file mode 100644
index 0000000..f0269f6
--- /dev/null
+++ b/tests/regression/issue_227/unaligned_uint64.proto
@@ -0,0 +1,8 @@
+syntax = "proto3";
+import 'nanopb.proto';
+
+message MainMessage {
+    string foo = 1 [(nanopb).max_size = 3];
+    string bar = 2 [(nanopb).max_size = 8];
+}
+
diff --git a/tests/regression/issue_229/SConscript b/tests/regression/issue_229/SConscript
new file mode 100644
index 0000000..b0f8376
--- /dev/null
+++ b/tests/regression/issue_229/SConscript
@@ -0,0 +1,13 @@
+# Regression test for Issue 229: problem encoding message that has
+# multiple oneof fields
+Import('env')
+
+env.NanopbProto('multiple_oneof')
+
+p = env.Program(["multiple_oneof.c",
+                 "multiple_oneof.pb.c",
+                 "$COMMON/pb_decode.o",
+                 "$COMMON/pb_encode.o",
+                 "$COMMON/pb_common.o"])
+env.RunTest(p)
+
diff --git a/tests/regression/issue_229/multiple_oneof.c b/tests/regression/issue_229/multiple_oneof.c
new file mode 100644
index 0000000..902248d
--- /dev/null
+++ b/tests/regression/issue_229/multiple_oneof.c
@@ -0,0 +1,35 @@
+#include "multiple_oneof.pb.h"
+#include <unittests.h>
+#include <pb_encode.h>
+#include <pb_decode.h>
+
+int main()
+{
+    int status = 0;
+    uint8_t buf[128];
+    size_t msglen;
+
+    {
+        pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf));
+        MainMessage msg = MainMessage_init_zero;
+        msg.which_oneof1 = MainMessage_oneof1_uint32_tag;
+        msg.oneof1.oneof1_uint32 = 1234;
+        msg.which_oneof2 = MainMessage_oneof2_uint32_tag;
+        msg.oneof2.oneof2_uint32 = 5678;
+        TEST(pb_encode(&stream, MainMessage_fields, &msg));
+        msglen = stream.bytes_written;
+    }
+    
+    {
+        pb_istream_t stream = pb_istream_from_buffer(buf, msglen);
+        MainMessage msg = MainMessage_init_zero;
+        TEST(pb_decode(&stream, MainMessage_fields, &msg));
+        TEST(msg.which_oneof1 == MainMessage_oneof1_uint32_tag);
+        TEST(msg.oneof1.oneof1_uint32 == 1234);
+        TEST(msg.which_oneof2 == MainMessage_oneof2_uint32_tag);
+        TEST(msg.oneof2.oneof2_uint32 == 5678);
+    }
+    
+    return status;
+}
+
diff --git a/tests/regression/issue_229/multiple_oneof.proto b/tests/regression/issue_229/multiple_oneof.proto
new file mode 100644
index 0000000..22373e1
--- /dev/null
+++ b/tests/regression/issue_229/multiple_oneof.proto
@@ -0,0 +1,11 @@
+syntax = "proto2";
+
+message MainMessage {
+    oneof oneof1 {
+        uint32 oneof1_uint32 = 1;
+    }
+    oneof oneof2 {
+        uint32 oneof2_uint32 = 2;
+    }
+}
+
diff --git a/tests/regression/issue_242/SConscript b/tests/regression/issue_242/SConscript
new file mode 100644
index 0000000..000063e
--- /dev/null
+++ b/tests/regression/issue_242/SConscript
@@ -0,0 +1,13 @@
+# Regression test for Issue 242: pb_encode does not encode tag for
+# extension fields that is all zeros
+Import('env')
+
+env.NanopbProto('zero_value')
+
+p = env.Program(["zero_value.c",
+                 "zero_value.pb.c",
+                 "$COMMON/pb_decode.o",
+                 "$COMMON/pb_encode.o",
+                 "$COMMON/pb_common.o"])
+env.RunTest(p)
+
diff --git a/tests/regression/issue_242/zero_value.c b/tests/regression/issue_242/zero_value.c
new file mode 100644
index 0000000..b3d96b7
--- /dev/null
+++ b/tests/regression/issue_242/zero_value.c
@@ -0,0 +1,51 @@
+#include <unittests.h>
+#include <pb_encode.h>
+#include <pb_decode.h>
+#include <string.h>
+#include "zero_value.pb.h"
+
+int main()
+{
+    int status = 0;
+    
+    COMMENT("Test extension fields with zero values");
+    {
+        uint8_t buffer[256] = {0};
+        pb_ostream_t ostream;
+        int32_t value = 0;
+        Extendable source = {0};
+
+        pb_extension_t source_ext = {0};
+        source_ext.type = &opt_int32;
+        source_ext.dest = &value;
+        source.extensions = &source_ext;
+
+        ostream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+        TEST(pb_encode(&ostream, Extendable_fields, &source));
+
+        TEST(ostream.bytes_written == 2);
+        TEST(memcmp(buffer, "\x58\x00", 2) == 0);
+    }
+    
+    /* Note: There never was a bug here, but this check is included
+     * in the regression test because the logic is closely related.
+     */
+    COMMENT("Test pointer fields with zero values");
+    {
+        uint8_t buffer[256] = {0};
+        pb_ostream_t ostream;
+        int32_t value = 0;
+        PointerMessage source = {0};
+
+        source.opt_int32 = &value;
+
+        ostream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+        TEST(pb_encode(&ostream, PointerMessage_fields, &source));
+
+        TEST(ostream.bytes_written == 2);
+        TEST(memcmp(buffer, "\x58\x00", 2) == 0);
+    }    
+    
+    return status;
+}
+
diff --git a/tests/regression/issue_242/zero_value.proto b/tests/regression/issue_242/zero_value.proto
new file mode 100644
index 0000000..020a39a
--- /dev/null
+++ b/tests/regression/issue_242/zero_value.proto
@@ -0,0 +1,15 @@
+syntax = "proto2";
+import "nanopb.proto";
+
+message Extendable {
+    extensions 10 to 100;
+}
+
+extend Extendable {
+    optional int32 opt_int32 = 11;
+}
+
+message PointerMessage {
+    optional int32 opt_int32 = 11 [(nanopb).type = FT_POINTER];
+}
+
diff --git a/tests/regression/issue_247/SConscript b/tests/regression/issue_247/SConscript
new file mode 100644
index 0000000..b41e9f2
--- /dev/null
+++ b/tests/regression/issue_247/SConscript
@@ -0,0 +1,14 @@
+# Test that pb_check_proto3_default_value() correctly skips padding
+# bytes in submessage structures.
+
+Import("env")
+
+env.NanopbProto("padding")
+
+p = env.Program(["padding.c",
+                 "padding.pb.c",
+                 "$COMMON/pb_encode.o",
+                 "$COMMON/pb_common.o"])
+
+env.RunTest(p)
+
diff --git a/tests/regression/issue_247/padding.c b/tests/regression/issue_247/padding.c
new file mode 100644
index 0000000..8860179
--- /dev/null
+++ b/tests/regression/issue_247/padding.c
@@ -0,0 +1,32 @@
+#include <pb_encode.h>
+#include <unittests.h>
+#include <string.h>
+#include "padding.pb.h"
+
+int main()
+{
+    int status = 0;
+    
+    TestMessage msg;
+    
+    /* Set padding bytes to garbage */
+    memset(&msg, 0xAA, sizeof(msg));
+    
+    /* Set all meaningful fields to 0 */
+    msg.submsg.boolfield = false;
+    msg.submsg.intfield = 0;
+    
+    /* Test encoding */
+    {
+        pb_byte_t buf[128] = {0};
+        pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf));
+        TEST(pb_encode(&stream, TestMessage_fields, &msg));
+        
+        /* Because all fields have zero values, proto3 encoder
+         * shouldn't write out anything. */
+        TEST(stream.bytes_written == 0);
+    }
+    
+    return status;
+}
+
diff --git a/tests/regression/issue_247/padding.proto b/tests/regression/issue_247/padding.proto
new file mode 100644
index 0000000..20bddac
--- /dev/null
+++ b/tests/regression/issue_247/padding.proto
@@ -0,0 +1,12 @@
+syntax = "proto3";
+import "nanopb.proto";
+
+message SubMessage {
+    bool boolfield = 1;
+    int64 intfield = 2;
+}
+
+message TestMessage {
+    SubMessage submsg = 1;
+}
+
diff --git a/tests/regression/issue_249/SConscript b/tests/regression/issue_249/SConscript
new file mode 100644
index 0000000..ba66712
--- /dev/null
+++ b/tests/regression/issue_249/SConscript
@@ -0,0 +1,12 @@
+# Regression test for Issue 249: proto3 mode pb_decode() corrupts callback fields
+Import('env')
+
+env.NanopbProto('test')
+
+p = env.Program(["test.c",
+                 "test.pb.c",
+                 "$COMMON/pb_decode.o",
+                 "$COMMON/pb_encode.o",
+                 "$COMMON/pb_common.o"])
+env.RunTest(p)
+
diff --git a/tests/regression/issue_249/test.c b/tests/regression/issue_249/test.c
new file mode 100644
index 0000000..a37180f
--- /dev/null
+++ b/tests/regression/issue_249/test.c
@@ -0,0 +1,59 @@
+#include "test.pb.h"
+#include <unittests.h>
+#include <pb_encode.h>
+#include <pb_decode.h>
+
+static bool write_array(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+    int i;
+    for (i = 0; i < 5; i++)
+    {
+        if (!pb_encode_tag_for_field(stream, field))
+            return false;
+        if (!pb_encode_varint(stream, 1000 + i))
+            return false;
+    }
+    
+    return true;
+}
+
+static bool read_array(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    uint32_t i;
+    int *sum = *arg;
+    
+    if (!pb_decode_varint32(stream, &i))
+        return false;
+    
+    *sum += i;
+    
+    return true;
+}
+
+int main()
+{
+    int status = 0;
+    pb_byte_t buf[128] = {0};
+    pb_size_t msglen;
+    
+    {
+        MainMessage msg = MainMessage_init_zero;
+        pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf));
+        msg.submsg.foo.funcs.encode = &write_array;
+        TEST(pb_encode(&stream, MainMessage_fields, &msg));
+        msglen = stream.bytes_written;
+    }
+    
+    {
+        MainMessage msg = MainMessage_init_zero;
+        pb_istream_t stream = pb_istream_from_buffer(buf, msglen);
+        int sum = 0;
+        msg.submsg.foo.funcs.decode = &read_array;
+        msg.submsg.foo.arg = &sum;
+        TEST(pb_decode(&stream, MainMessage_fields, &msg));
+        TEST(sum == 1000 + 1001 + 1002 + 1003 + 1004);
+    }
+    
+    return status;
+}
+
diff --git a/tests/regression/issue_249/test.proto b/tests/regression/issue_249/test.proto
new file mode 100644
index 0000000..eaa2abd
--- /dev/null
+++ b/tests/regression/issue_249/test.proto
@@ -0,0 +1,10 @@
+syntax = "proto3";
+
+message SubMessage {
+    repeated int32 foo = 1;
+}
+
+message MainMessage {
+    SubMessage submsg = 1;
+}
+
diff --git a/tests/regression/issue_253/SConscript b/tests/regression/issue_253/SConscript
new file mode 100644
index 0000000..5a16948
--- /dev/null
+++ b/tests/regression/issue_253/SConscript
@@ -0,0 +1,15 @@
+# Regression test for Issue 253: Wrong calculated message maximum size
+
+Import('env')
+
+env.NanopbProto('short_array')
+
+p = env.Program(['short_array.c',
+                 'short_array.pb.c', 
+                 "$COMMON/pb_decode.o",
+                 "$COMMON/pb_encode.o",
+                 "$COMMON/pb_common.o"])
+
+env.RunTest(p)
+
+
diff --git a/tests/regression/issue_253/short_array.c b/tests/regression/issue_253/short_array.c
new file mode 100644
index 0000000..5ed6c3f
--- /dev/null
+++ b/tests/regression/issue_253/short_array.c
@@ -0,0 +1,24 @@
+#include <unittests.h>
+#include <pb_encode.h>
+#include "short_array.pb.h"
+
+int main()
+{
+    int status = 0;
+    
+    COMMENT("Test message length calculation for short arrays");
+    {
+        uint8_t buffer[TestMessage_size] = {0};
+        pb_ostream_t ostream = pb_ostream_from_buffer(buffer, TestMessage_size);
+        TestMessage msg = TestMessage_init_zero;
+        
+        msg.rep_uint32_count = 1;
+        msg.rep_uint32[0] = (1 << 31);
+        
+        TEST(pb_encode(&ostream, TestMessage_fields, &msg));
+        TEST(ostream.bytes_written == TestMessage_size);
+    }
+    
+    return status;
+}
+
diff --git a/tests/regression/issue_253/short_array.proto b/tests/regression/issue_253/short_array.proto
new file mode 100644
index 0000000..5a5d8a3
--- /dev/null
+++ b/tests/regression/issue_253/short_array.proto
@@ -0,0 +1,7 @@
+syntax = "proto2";
+import "nanopb.proto";
+
+message TestMessage {
+    repeated uint32 rep_uint32 = 1 [(nanopb).max_count = 1];
+}
+
diff --git a/tests/regression/issue_256/SConscript b/tests/regression/issue_256/SConscript
new file mode 100644
index 0000000..b2c3e86
--- /dev/null
+++ b/tests/regression/issue_256/SConscript
@@ -0,0 +1,16 @@
+# Regression test for Issue 256: Proto3 mode skips submessages even when
+# later array fields have non-zero value
+
+Import('env')
+
+env.NanopbProto('submsg_array')
+
+p = env.Program(['submsg_array.c',
+                 'submsg_array.pb.c', 
+                 "$COMMON/pb_decode.o",
+                 "$COMMON/pb_encode.o",
+                 "$COMMON/pb_common.o"])
+
+env.RunTest(p)
+
+
diff --git a/tests/regression/issue_256/submsg_array.c b/tests/regression/issue_256/submsg_array.c
new file mode 100644
index 0000000..c63bd30
--- /dev/null
+++ b/tests/regression/issue_256/submsg_array.c
@@ -0,0 +1,38 @@
+#include <unittests.h>
+#include <pb_encode.h>
+#include <pb_decode.h>
+#include "submsg_array.pb.h"
+
+int main()
+{
+    int status = 0;
+    
+    COMMENT("Test encoding for submessage with array");
+    {
+        uint8_t buffer[TestMessage_size] = {0};
+        pb_ostream_t ostream = pb_ostream_from_buffer(buffer, TestMessage_size);
+        TestMessage msg = TestMessage_init_zero;
+        
+        msg.submsg.rep_uint32_count = 3;
+        msg.submsg.rep_uint32[0] = 0;
+        msg.submsg.rep_uint32[1] = 1;
+        msg.submsg.rep_uint32[2] = 2;
+        
+        TEST(pb_encode(&ostream, TestMessage_fields, &msg));
+        TEST(ostream.bytes_written > 0);
+        
+        {
+            pb_istream_t istream = pb_istream_from_buffer(buffer, ostream.bytes_written);
+            TestMessage msg2 = TestMessage_init_zero;
+
+            TEST(pb_decode(&istream, TestMessage_fields, &msg2));
+            TEST(msg2.submsg.rep_uint32_count == 3);
+            TEST(msg2.submsg.rep_uint32[0] == 0);
+            TEST(msg2.submsg.rep_uint32[1] == 1);
+            TEST(msg2.submsg.rep_uint32[2] == 2);
+        }
+    }
+    
+    return status;
+}
+
diff --git a/tests/regression/issue_256/submsg_array.proto b/tests/regression/issue_256/submsg_array.proto
new file mode 100644
index 0000000..4964a05
--- /dev/null
+++ b/tests/regression/issue_256/submsg_array.proto
@@ -0,0 +1,11 @@
+syntax = "proto3";
+import "nanopb.proto";
+
+message SubMessage {
+    repeated uint32 rep_uint32 = 1 [(nanopb).max_count = 3];
+}
+
+message TestMessage {
+    SubMessage submsg = 1;
+}
+
diff --git a/tests/regression/issue_259/SConscript b/tests/regression/issue_259/SConscript
new file mode 100644
index 0000000..8340d45
--- /dev/null
+++ b/tests/regression/issue_259/SConscript
@@ -0,0 +1,22 @@
+# Check that callback fields inside malloc()ed messages
+# are correctly initialized.
+
+Import('env', 'malloc_env')
+
+env.NanopbProto('callback_pointer')
+
+p = malloc_env.Program(["callback_pointer.c",
+                         "callback_pointer.pb.c",
+                         "$COMMON/pb_decode_with_malloc.o",
+                         "$COMMON/pb_common_with_malloc.o",
+                         "$COMMON/malloc_wrappers.o"])
+
+# Run test under valgrind if available
+valgrind = env.WhereIs('valgrind')
+kwargs = {}
+if valgrind:
+    kwargs['COMMAND'] = valgrind
+    kwargs['ARGS'] = ["-q", "--error-exitcode=99", p[0].abspath]
+
+env.RunTest(p, **kwargs)
+
diff --git a/tests/regression/issue_259/callback_pointer.c b/tests/regression/issue_259/callback_pointer.c
new file mode 100644
index 0000000..f150fbe
--- /dev/null
+++ b/tests/regression/issue_259/callback_pointer.c
@@ -0,0 +1,30 @@
+#include "callback_pointer.pb.h"
+#include <unittests.h>
+#include <pb_decode.h>
+
+int main()
+{
+    int status = 0;
+    const uint8_t msgdata[] = {0x0A, 0x02, 0x08, 0x7F};
+
+    MainMessage msg = MainMessage_init_zero;
+    
+    {
+        pb_istream_t stream = pb_istream_from_buffer(msgdata, sizeof(msgdata));
+        COMMENT("Running first decode");
+        TEST(pb_decode(&stream, MainMessage_fields, &msg));
+        pb_release(MainMessage_fields, &msg);
+    }
+    
+    {
+        pb_istream_t stream = pb_istream_from_buffer(msgdata, sizeof(msgdata));
+        COMMENT("Running second decode");
+        TEST(pb_decode(&stream, MainMessage_fields, &msg));
+        pb_release(MainMessage_fields, &msg);
+    }
+    
+    TEST(get_alloc_count() == 0);
+    
+    return status;
+}
+
diff --git a/tests/regression/issue_259/callback_pointer.proto b/tests/regression/issue_259/callback_pointer.proto
new file mode 100644
index 0000000..a2d04e4
--- /dev/null
+++ b/tests/regression/issue_259/callback_pointer.proto
@@ -0,0 +1,11 @@
+syntax = "proto2";
+import 'nanopb.proto';
+
+message SubMessage {
+    optional int32 foo = 1 [(nanopb).type = FT_CALLBACK];
+}
+
+message MainMessage {
+    optional SubMessage bar = 1 [(nanopb).type = FT_POINTER];
+}
+
diff --git a/tests/regression/issue_306/SConscript b/tests/regression/issue_306/SConscript
new file mode 100644
index 0000000..d3badec
--- /dev/null
+++ b/tests/regression/issue_306/SConscript
@@ -0,0 +1,7 @@
+# Check that generator gives a warning about large extension field number.
+
+Import('env')
+
+env.NanopbProto('large_extension')
+
+env.Match(['large_extension.pb.c', 'large_extension.expected'])
diff --git a/tests/regression/issue_306/large_extension.expected b/tests/regression/issue_306/large_extension.expected
new file mode 100644
index 0000000..a90bc32
--- /dev/null
+++ b/tests/regression/issue_306/large_extension.expected
@@ -0,0 +1 @@
+PB_FIELD_32BIT
diff --git a/tests/regression/issue_306/large_extension.proto b/tests/regression/issue_306/large_extension.proto
new file mode 100644
index 0000000..c3c8f6f
--- /dev/null
+++ b/tests/regression/issue_306/large_extension.proto
@@ -0,0 +1,10 @@
+syntax = "proto2";
+
+message Foo {
+  extensions 1 to max;
+}
+
+extend Foo {
+  optional int32 foo_ext = 99999;
+}
+
diff --git a/tests/regression/issue_322/SConscript b/tests/regression/issue_322/SConscript
new file mode 100644
index 0000000..ec08e74
--- /dev/null
+++ b/tests/regression/issue_322/SConscript
@@ -0,0 +1,14 @@
+# Check that default values with special characters are
+# correctly handled.
+
+Import('env')
+
+env.NanopbProto('defaults')
+
+p = env.Program(["defaults.c",
+                 "defaults.pb.c",
+                 "$COMMON/pb_decode.o",
+                 "$COMMON/pb_common.o"])
+
+env.RunTest(p)
+
diff --git a/tests/regression/issue_322/defaults.c b/tests/regression/issue_322/defaults.c
new file mode 100644
index 0000000..b285754
--- /dev/null
+++ b/tests/regression/issue_322/defaults.c
@@ -0,0 +1,44 @@
+#include "defaults.pb.h"
+#include <unittests.h>
+#include <pb_decode.h>
+
+int check_defaults(const DefaultsMsg *msg)
+{
+    int status = 0;
+    
+    TEST(msg->b1[0] == 0xDE && msg->b1[1] == 0xAD && msg->b1[2] == 0x00 &&
+         msg->b1[3] == 0xBE && msg->b1[4] == 0xEF);
+    TEST(msg->b2.bytes[0] == 0xDE && msg->b2.bytes[1] == 0xAD &&
+         msg->b2.bytes[2] == 0x00 && msg->b2.bytes[3] == 0xBE &&
+         msg->b2.bytes[4] == 0xEF && msg->b2.size == 5);
+    TEST(msg->b3.bytes[0] == 0xDE && msg->b3.bytes[1] == 0xAD &&
+         msg->b3.bytes[2] == 0x00 && msg->b3.bytes[3] == 0xBE &&
+         msg->b3.bytes[4] == 0xEF && msg->b2.size == 5);
+    TEST(msg->s1[0] == (char)0xC3 && msg->s1[1] == (char)0xA4 &&
+         msg->s1[2] == (char)0xC3 && msg->s1[3] == (char)0xB6 &&
+         msg->s1[4] == '\0');
+    
+    return status;
+}
+
+int main()
+{
+    int status = 0;
+    
+    {
+        DefaultsMsg msg = DefaultsMsg_init_default;
+        COMMENT("Checking defaults from static initializer");
+        status += check_defaults(&msg);
+    }
+
+    {
+        DefaultsMsg msg = DefaultsMsg_init_zero;
+        pb_istream_t empty = {0,0,0};
+        pb_decode(&empty, DefaultsMsg_fields, &msg);
+        COMMENT("Checking defaults set at runtime");
+        status += check_defaults(&msg);
+    }
+
+    return status;
+}
+
diff --git a/tests/regression/issue_322/defaults.proto b/tests/regression/issue_322/defaults.proto
new file mode 100644
index 0000000..359344d
--- /dev/null
+++ b/tests/regression/issue_322/defaults.proto
@@ -0,0 +1,11 @@
+syntax = "proto2";
+import 'nanopb.proto';
+
+message DefaultsMsg {
+    optional bytes b1 = 1 [default = "\xDE\xAD\x00\xBE\xEF", (nanopb).max_size = 5, (nanopb).fixed_length=true];
+    optional bytes b2 = 2 [default = "\xDE\xAD\x00\xBE\xEF", (nanopb).max_size = 5];
+    optional bytes b3 = 3 [default = "\xDE\xAD\000\xBE\xEF", (nanopb).max_size = 15];
+    optional string s1 = 4 [default = "äö", (nanopb).max_size = 8];
+}
+
+
diff --git a/tests/site_scons/site_init.py b/tests/site_scons/site_init.py
index 5fb06d6..56e227b 100644
--- a/tests/site_scons/site_init.py
+++ b/tests/site_scons/site_init.py
@@ -27,16 +27,16 @@
         if env.has_key('ARGS'):
             args.extend(env['ARGS'])
         
-        print 'Command line: ' + str(args)
+        print('Command line: ' + str(args))
         pipe = subprocess.Popen(args,
                                 stdin = infile,
                                 stdout = open(str(target[0]), 'w'),
                                 stderr = sys.stderr)
         result = pipe.wait()
         if result == 0:
-            print '\033[32m[ OK ]\033[0m   Ran ' + args[0]
+            print('\033[32m[ OK ]\033[0m   Ran ' + args[0])
         else:
-            print '\033[31m[FAIL]\033[0m   Program ' + args[0] + ' returned ' + str(result)
+            print('\033[31m[FAIL]\033[0m   Program ' + args[0] + ' returned ' + str(result))
         return result
         
     run_test_builder = Builder(action = run_test,
@@ -70,10 +70,10 @@
         data1 = open(str(source[0]), 'rb').read()
         data2 = open(str(source[1]), 'rb').read()
         if data1 == data2:
-            print '\033[32m[ OK ]\033[0m   Files equal: ' + str(source[0]) + ' and ' + str(source[1])
+            print('\033[32m[ OK ]\033[0m   Files equal: ' + str(source[0]) + ' and ' + str(source[1]))
             return 0
         else:
-            print '\033[31m[FAIL]\033[0m   Files differ: ' + str(source[0]) + ' and ' + str(source[1])
+            print('\033[31m[FAIL]\033[0m   Files differ: ' + str(source[0]) + ' and ' + str(source[1]))
             return 1
 
     compare_builder = Builder(action = compare_files,
@@ -85,11 +85,22 @@
         data = open(str(source[0]), 'rU').read()
         patterns = open(str(source[1]))
         for pattern in patterns:
-            if pattern.strip() and not re.search(pattern.strip(), data, re.MULTILINE):
-                print '\033[31m[FAIL]\033[0m   Pattern not found in ' + str(source[0]) + ': ' + pattern
-                return 1
+            if pattern.strip():
+                invert = False
+                if pattern.startswith('! '):
+                    invert = True
+                    pattern = pattern[2:]
+                
+                status = re.search(pattern.strip(), data, re.MULTILINE)
+                
+                if not status and not invert:
+                    print('\033[31m[FAIL]\033[0m   Pattern not found in ' + str(source[0]) + ': ' + pattern)
+                    return 1
+                elif status and invert:
+                    print('\033[31m[FAIL]\033[0m   Pattern should not exist, but does in ' + str(source[0]) + ': ' + pattern)
+                    return 1
         else:
-            print '\033[32m[ OK ]\033[0m   All patterns found in ' + str(source[0])
+            print('\033[32m[ OK ]\033[0m   All patterns found in ' + str(source[0]))
             return 0
 
     match_builder = Builder(action = match_files, suffix = '.matched')
diff --git a/tests/site_scons/site_tools/nanopb.py b/tests/site_scons/site_tools/nanopb.py
index b3e58fa..c72a45d 100644
--- a/tests/site_scons/site_tools/nanopb.py
+++ b/tests/site_scons/site_tools/nanopb.py
@@ -118,7 +118,7 @@
     
     env.SetDefault(PROTOCPATH = ['.', os.path.join(env['NANOPB'], 'generator', 'proto')])
     
-    env.SetDefault(NANOPB_PROTO_CMD = '$PROTOC $PROTOC_OPTS --nanopb_out=. $SOURCE')
+    env.SetDefault(NANOPB_PROTO_CMD = '$PROTOC $PROTOCFLAGS --nanopb_out=. $SOURCES')
     env['BUILDERS']['NanopbProto'] = _nanopb_proto_builder
     
 def exists(env):
diff --git a/tests/special_characters/funny-proto+name has.characters.proto b/tests/special_characters/funny-proto+name has.characters.proto
index e69de29..26b2cb1 100644
--- a/tests/special_characters/funny-proto+name has.characters.proto
+++ b/tests/special_characters/funny-proto+name has.characters.proto
@@ -0,0 +1 @@
+syntax="proto2";
diff --git a/tests/splint/SConscript b/tests/splint/SConscript
index c1432dd..cd4b5b9 100644
--- a/tests/splint/SConscript
+++ b/tests/splint/SConscript
@@ -11,3 +11,6 @@
     env.Command('pb_encode.splint', '$NANOPB/pb_encode.c',
         'splint -f splint/splint.rc $SOURCE 2> $TARGET')
 
+    env.Command('pb_common.splint', '$NANOPB/pb_common.c',
+        'splint -f splint/splint.rc $SOURCE 2> $TARGET')
+
diff --git a/tests/splint/splint.rc b/tests/splint/splint.rc
index 421f567..e47d3c2 100644
--- a/tests/splint/splint.rc
+++ b/tests/splint/splint.rc
@@ -2,7 +2,6 @@
 +partial
 +matchanyintegral
 +strictlib
--isoreserved		# to be fixed in 0.3
 -nullassign
 -predboolint
 -predboolptr
@@ -28,6 +27,7 @@
 -kepttrans
 -branchstate
 -immediatetrans
+-mustfreefresh
 
 # These tests give false positives, compiler typically has
 # better warnings for these.
diff --git a/tests/without_64bit/SConscript b/tests/without_64bit/SConscript
new file mode 100644
index 0000000..be415d8
--- /dev/null
+++ b/tests/without_64bit/SConscript
@@ -0,0 +1,49 @@
+# Run the alltypes test case, but compile with PB_WITHOUT_64BIT.
+
+Import("env")
+
+env.NanopbProto(["alltypes", "alltypes.options"])
+
+# Define the compilation options
+opts = env.Clone()
+opts.Append(CPPDEFINES = {'PB_WITHOUT_64BIT': 1, 'HAVE_STDINT_H': 0, 'PB_SYSTEM_HEADER': '\\"no_64bit_syshdr.h\\"'})
+opts.Append(CPPPATH = "#without_64bit")
+
+if 'SYSHDR' in opts:
+    opts.Append(CPPDEFINES = {'PB_OLD_SYSHDR': opts['SYSHDR']})
+
+# Build new version of core
+strict = opts.Clone()
+strict.Append(CFLAGS = strict['CORECFLAGS'])
+strict.Object("pb_decode_no64bit.o", "$NANOPB/pb_decode.c")
+strict.Object("pb_encode_no64bit.o", "$NANOPB/pb_encode.c")
+strict.Object("pb_common_no64bit.o", "$NANOPB/pb_common.c")
+
+# Now build and run the test normally.
+enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_no64bit.o", "pb_common_no64bit.o"])
+dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_no64bit.o", "pb_common_no64bit.o"])
+
+env.RunTest(enc)
+env.RunTest([dec, "encode_alltypes.output"])
+
+# Re-encode the data using protoc, and check that the results from nanopb
+# match byte-per-byte to the protoc output.
+env.Decode("encode_alltypes.output.decoded",
+           ["encode_alltypes.output", "alltypes.proto"],
+           MESSAGE='AllTypes')
+env.Encode("encode_alltypes.output.recoded",
+           ["encode_alltypes.output.decoded", "alltypes.proto"],
+           MESSAGE='AllTypes')
+env.Compare(["encode_alltypes.output", "encode_alltypes.output.recoded"])
+
+
+# Do the same checks with the optional fields present.
+env.RunTest("optionals.output", enc, ARGS = ['1'])
+env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1'])
+env.Decode("optionals.output.decoded",
+           ["optionals.output", "alltypes.proto"],
+           MESSAGE='AllTypes')
+env.Encode("optionals.output.recoded",
+           ["optionals.output.decoded", "alltypes.proto"],
+           MESSAGE='AllTypes')
+env.Compare(["optionals.output", "optionals.output.recoded"])
diff --git a/tests/without_64bit/alltypes.options b/tests/without_64bit/alltypes.options
new file mode 100644
index 0000000..0d5ab12
--- /dev/null
+++ b/tests/without_64bit/alltypes.options
@@ -0,0 +1,3 @@
+* max_size:16
+* max_count:5
+*.*fbytes fixed_length:true max_size:4
diff --git a/tests/without_64bit/alltypes.proto b/tests/without_64bit/alltypes.proto
new file mode 100644
index 0000000..240685b
--- /dev/null
+++ b/tests/without_64bit/alltypes.proto
@@ -0,0 +1,100 @@
+syntax = "proto2";
+// package name placeholder
+
+message SubMessage {
+    required string substuff1 = 1 [default = "1"];
+    required int32 substuff2 = 2 [default = 2];
+    optional fixed32 substuff3 = 3 [default = 3];
+}
+
+message EmptyMessage {
+
+}
+
+enum HugeEnum {
+    Negative = -2147483647; /* protoc doesn't accept -2147483648 here */
+    Positive =  2147483647;
+}
+
+message Limits {
+    required int32      int32_min  =  1 [default = 2147483647];
+    required int32      int32_max  =  2 [default = -2147483647];
+    required uint32     uint32_min =  3 [default = 4294967295];
+    required uint32     uint32_max =  4 [default = 0];
+    required HugeEnum   enum_min   =  9 [default = Positive];
+    required HugeEnum   enum_max   = 10 [default = Negative];
+}
+
+enum MyEnum {
+    Zero = 0;
+    First = 1;
+    Second = 2;
+    Truth = 42;
+}
+
+message AllTypes {
+    required int32      req_int32   = 1;
+    required uint32     req_uint32  = 3;
+    required sint32     req_sint32  = 5;
+    required bool       req_bool    = 7;
+    
+    required fixed32    req_fixed32 = 8;
+    required sfixed32   req_sfixed32= 9;
+    required float      req_float   = 10;
+    
+    required string     req_string  = 14;
+    required bytes      req_bytes   = 15;
+    required SubMessage req_submsg  = 16;
+    required MyEnum     req_enum    = 17;
+    required EmptyMessage req_emptymsg = 18;
+    required bytes      req_fbytes  = 19;
+    
+    repeated int32      rep_int32   = 21 [packed = true];
+    repeated uint32     rep_uint32  = 23 [packed = true];
+    repeated sint32     rep_sint32  = 25 [packed = true];
+    repeated bool       rep_bool    = 27 [packed = true];
+    
+    repeated fixed32    rep_fixed32 = 28 [packed = true];
+    repeated sfixed32   rep_sfixed32= 29 [packed = true];
+    repeated float      rep_float   = 30 [packed = true];
+    
+    repeated string     rep_string  = 34;
+    repeated bytes      rep_bytes   = 35;
+    repeated SubMessage rep_submsg  = 36;
+    repeated MyEnum     rep_enum    = 37 [packed = true];
+    repeated EmptyMessage rep_emptymsg = 38;
+    repeated bytes      rep_fbytes  = 39;
+    
+    optional int32      opt_int32   = 41 [default = 4041];
+    optional uint32     opt_uint32  = 43 [default = 4043];
+    optional sint32     opt_sint32  = 45 [default = 4045];
+    optional bool       opt_bool    = 47 [default = false];
+    
+    optional fixed32    opt_fixed32 = 48 [default = 4048];
+    optional sfixed32   opt_sfixed32= 49 [default = 4049];
+    optional float      opt_float   = 50 [default = 4050];
+    
+    optional string     opt_string  = 54 [default = "4054"];
+    optional bytes      opt_bytes   = 55 [default = "4055"];
+    optional SubMessage opt_submsg  = 56;
+    optional MyEnum     opt_enum    = 57 [default = Second];
+    optional EmptyMessage opt_emptymsg = 58;
+    optional bytes      opt_fbytes  = 59 [default = "4059"];
+
+    oneof oneof
+    {
+        SubMessage oneof_msg1 = 60;
+        EmptyMessage oneof_msg2 = 61;
+    }
+    
+    // Check that extreme integer values are handled correctly
+    required Limits     req_limits = 98;
+
+    // Just to make sure that the size of the fields has been calculated
+    // properly, i.e. otherwise a bug in last field might not be detected.
+    required int32      end = 99;
+
+
+    extensions 200 to 255;
+}
+
diff --git a/tests/without_64bit/decode_alltypes.c b/tests/without_64bit/decode_alltypes.c
new file mode 100644
index 0000000..6b5ff8e
--- /dev/null
+++ b/tests/without_64bit/decode_alltypes.c
@@ -0,0 +1,185 @@
+/* Tests the decoding of all types.
+ * This is the counterpart of test_encode3.
+ * Run e.g. ./test_encode3 | ./test_decode3
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pb_decode.h>
+#include "alltypes.pb.h"
+#include "test_helpers.h"
+
+#define TEST(x) if (!(x)) { \
+    printf("Test " #x " failed.\n"); \
+    return false; \
+    }
+
+/* This function is called once from main(), it handles
+   the decoding and checks the fields. */
+bool check_alltypes(pb_istream_t *stream, int mode)
+{
+    /* Uses _init_default to just make sure that it works. */
+    AllTypes alltypes = AllTypes_init_default;
+    
+    /* Fill with garbage to better detect initialization errors */
+    memset(&alltypes, 0xAA, sizeof(alltypes));
+    alltypes.extensions = 0;
+    
+    if (!pb_decode(stream, AllTypes_fields, &alltypes))
+        return false;
+    
+    TEST(alltypes.req_int32         == -1001);
+    TEST(alltypes.req_uint32        == 1003);
+    TEST(alltypes.req_sint32        == -1005);
+    TEST(alltypes.req_bool          == true);
+    
+    TEST(alltypes.req_fixed32       == 1008);
+    TEST(alltypes.req_sfixed32      == -1009);
+    TEST(alltypes.req_float         == 1010.0f);
+    
+    TEST(strcmp(alltypes.req_string, "1014") == 0);
+    TEST(alltypes.req_bytes.size == 4);
+    TEST(memcmp(alltypes.req_bytes.bytes, "1015", 4) == 0);
+    TEST(strcmp(alltypes.req_submsg.substuff1, "1016") == 0);
+    TEST(alltypes.req_submsg.substuff2 == 1016);
+    TEST(alltypes.req_submsg.substuff3 == 3);
+    TEST(alltypes.req_enum == MyEnum_Truth);
+    TEST(memcmp(alltypes.req_fbytes, "1019", 4) == 0);
+    
+    TEST(alltypes.rep_int32_count == 5 && alltypes.rep_int32[4] == -2001 && alltypes.rep_int32[0] == 0);
+    TEST(alltypes.rep_uint32_count == 5 && alltypes.rep_uint32[4] == 2003 && alltypes.rep_uint32[0] == 0);
+    TEST(alltypes.rep_sint32_count == 5 && alltypes.rep_sint32[4] == -2005 && alltypes.rep_sint32[0] == 0);
+    TEST(alltypes.rep_bool_count == 5 && alltypes.rep_bool[4] == true && alltypes.rep_bool[0] == false);
+    
+    TEST(alltypes.rep_fixed32_count == 5 && alltypes.rep_fixed32[4] == 2008 && alltypes.rep_fixed32[0] == 0);
+    TEST(alltypes.rep_sfixed32_count == 5 && alltypes.rep_sfixed32[4] == -2009 && alltypes.rep_sfixed32[0] == 0);
+    TEST(alltypes.rep_float_count == 5 && alltypes.rep_float[4] == 2010.0f && alltypes.rep_float[0] == 0.0f);
+    
+    TEST(alltypes.rep_string_count == 5 && strcmp(alltypes.rep_string[4], "2014") == 0 && alltypes.rep_string[0][0] == '\0');
+    TEST(alltypes.rep_bytes_count == 5 && alltypes.rep_bytes[4].size == 4 && alltypes.rep_bytes[0].size == 0);
+    TEST(memcmp(alltypes.rep_bytes[4].bytes, "2015", 4) == 0);
+
+    TEST(alltypes.rep_submsg_count == 5);
+    TEST(strcmp(alltypes.rep_submsg[4].substuff1, "2016") == 0 && alltypes.rep_submsg[0].substuff1[0] == '\0');
+    TEST(alltypes.rep_submsg[4].substuff2 == 2016 && alltypes.rep_submsg[0].substuff2 == 0);
+    TEST(alltypes.rep_submsg[4].substuff3 == 2016 && alltypes.rep_submsg[0].substuff3 == 3);
+    
+    TEST(alltypes.rep_enum_count == 5 && alltypes.rep_enum[4] == MyEnum_Truth && alltypes.rep_enum[0] == MyEnum_Zero);
+    TEST(alltypes.rep_emptymsg_count == 5);
+    TEST(alltypes.rep_fbytes_count == 5);
+    TEST(alltypes.rep_fbytes[0][0] == 0 && alltypes.rep_fbytes[0][3] == 0);
+    TEST(memcmp(alltypes.rep_fbytes[4], "2019", 4) == 0);
+    
+    if (mode == 0)
+    {
+        /* Expect default values */
+        TEST(alltypes.has_opt_int32     == false);
+        TEST(alltypes.opt_int32         == 4041);
+        TEST(alltypes.has_opt_uint32    == false);
+        TEST(alltypes.opt_uint32        == 4043);
+        TEST(alltypes.has_opt_sint32    == false);
+        TEST(alltypes.opt_sint32        == 4045);
+        TEST(alltypes.has_opt_bool      == false);
+        TEST(alltypes.opt_bool          == false);
+        
+        TEST(alltypes.has_opt_fixed32   == false);
+        TEST(alltypes.opt_fixed32       == 4048);
+        TEST(alltypes.has_opt_sfixed32  == false);
+        TEST(alltypes.opt_sfixed32      == 4049);
+        TEST(alltypes.has_opt_float     == false);
+        TEST(alltypes.opt_float         == 4050.0f);
+        
+        TEST(alltypes.has_opt_string    == false);
+        TEST(strcmp(alltypes.opt_string, "4054") == 0);
+        TEST(alltypes.has_opt_bytes     == false);
+        TEST(alltypes.opt_bytes.size == 4);
+        TEST(memcmp(alltypes.opt_bytes.bytes, "4055", 4) == 0);
+        TEST(alltypes.has_opt_submsg    == false);
+        TEST(strcmp(alltypes.opt_submsg.substuff1, "1") == 0);
+        TEST(alltypes.opt_submsg.substuff2 == 2);
+        TEST(alltypes.opt_submsg.substuff3 == 3);
+        TEST(alltypes.has_opt_enum     == false);
+        TEST(alltypes.opt_enum == MyEnum_Second);
+        TEST(alltypes.has_opt_emptymsg == false);
+        TEST(alltypes.has_opt_fbytes == false);
+        TEST(memcmp(alltypes.opt_fbytes, "4059", 4) == 0);
+
+        TEST(alltypes.which_oneof == 0);
+    }
+    else
+    {
+        /* Expect filled-in values */
+        TEST(alltypes.has_opt_int32     == true);
+        TEST(alltypes.opt_int32         == 3041);
+        TEST(alltypes.has_opt_uint32    == true);
+        TEST(alltypes.opt_uint32        == 3043);
+        TEST(alltypes.has_opt_sint32    == true);
+        TEST(alltypes.opt_sint32        == 3045);
+        TEST(alltypes.has_opt_bool      == true);
+        TEST(alltypes.opt_bool          == true);
+        
+        TEST(alltypes.has_opt_fixed32   == true);
+        TEST(alltypes.opt_fixed32       == 3048);
+        TEST(alltypes.has_opt_sfixed32  == true);
+        TEST(alltypes.opt_sfixed32      == 3049);
+        TEST(alltypes.has_opt_float     == true);
+        TEST(alltypes.opt_float         == 3050.0f);
+        
+        TEST(alltypes.has_opt_string    == true);
+        TEST(strcmp(alltypes.opt_string, "3054") == 0);
+        TEST(alltypes.has_opt_bytes     == true);
+        TEST(alltypes.opt_bytes.size == 4);
+        TEST(memcmp(alltypes.opt_bytes.bytes, "3055", 4) == 0);
+        TEST(alltypes.has_opt_submsg    == true);
+        TEST(strcmp(alltypes.opt_submsg.substuff1, "3056") == 0);
+        TEST(alltypes.opt_submsg.substuff2 == 3056);
+        TEST(alltypes.opt_submsg.substuff3 == 3);
+        TEST(alltypes.has_opt_enum      == true);
+        TEST(alltypes.opt_enum == MyEnum_Truth);
+        TEST(alltypes.has_opt_emptymsg  == true);
+        TEST(alltypes.has_opt_fbytes == true);
+        TEST(memcmp(alltypes.opt_fbytes, "3059", 4) == 0);
+
+        TEST(alltypes.which_oneof == AllTypes_oneof_msg1_tag);
+        TEST(strcmp(alltypes.oneof.oneof_msg1.substuff1, "4059") == 0);
+        TEST(alltypes.oneof.oneof_msg1.substuff2 == 4059);
+    }
+    
+    TEST(alltypes.req_limits.int32_min  == INT32_MIN);
+    TEST(alltypes.req_limits.int32_max  == INT32_MAX);
+    TEST(alltypes.req_limits.uint32_min == 0);
+    TEST(alltypes.req_limits.uint32_max == UINT32_MAX);
+    TEST(alltypes.req_limits.enum_min   == HugeEnum_Negative);
+    TEST(alltypes.req_limits.enum_max   == HugeEnum_Positive);
+    
+    TEST(alltypes.end == 1099);
+    
+    return true;
+}
+
+int main(int argc, char **argv)
+{
+    uint8_t buffer[1024];
+    size_t count;
+    pb_istream_t stream;
+
+    /* Whether to expect the optional values or the default values. */
+    int mode = (argc > 1) ? atoi(argv[1]) : 0;
+    
+    /* Read the data into buffer */
+    SET_BINARY_MODE(stdin);
+    count = fread(buffer, 1, sizeof(buffer), stdin);
+    
+    /* Construct a pb_istream_t for reading from the buffer */
+    stream = pb_istream_from_buffer(buffer, count);
+    
+    /* Decode and print out the stuff */
+    if (!check_alltypes(&stream, mode))
+    {
+        printf("Parsing failed: %s\n", PB_GET_ERROR(&stream));
+        return 1;
+    } else {
+        return 0;
+    }
+}
diff --git a/tests/without_64bit/encode_alltypes.c b/tests/without_64bit/encode_alltypes.c
new file mode 100644
index 0000000..9fe26f6
--- /dev/null
+++ b/tests/without_64bit/encode_alltypes.c
@@ -0,0 +1,124 @@
+/* Attempts to test all the datatypes supported by ProtoBuf.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pb_encode.h>
+#include "alltypes.pb.h"
+#include "test_helpers.h"
+
+int main(int argc, char **argv)
+{
+    int mode = (argc > 1) ? atoi(argv[1]) : 0;
+    
+    /* Initialize the structure with constants */
+    AllTypes alltypes = AllTypes_init_zero;
+    
+    alltypes.req_int32         = -1001;
+    alltypes.req_uint32        = 1003;
+    alltypes.req_sint32        = -1005;
+    alltypes.req_bool          = true;
+    
+    alltypes.req_fixed32       = 1008;
+    alltypes.req_sfixed32      = -1009;
+    alltypes.req_float         = 1010.0f;
+    
+    strcpy(alltypes.req_string, "1014");
+    alltypes.req_bytes.size = 4;
+    memcpy(alltypes.req_bytes.bytes, "1015", 4);
+    strcpy(alltypes.req_submsg.substuff1, "1016");
+    alltypes.req_submsg.substuff2 = 1016;
+    alltypes.req_enum = MyEnum_Truth;
+    memcpy(alltypes.req_fbytes, "1019", 4);
+    
+    alltypes.rep_int32_count = 5; alltypes.rep_int32[4] = -2001;
+    alltypes.rep_uint32_count = 5; alltypes.rep_uint32[4] = 2003;
+    alltypes.rep_sint32_count = 5; alltypes.rep_sint32[4] = -2005;
+    alltypes.rep_bool_count = 5; alltypes.rep_bool[4] = true;
+    
+    alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32[4] = 2008;
+    alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32[4] = -2009;
+    alltypes.rep_float_count = 5; alltypes.rep_float[4] = 2010.0f;
+    
+    alltypes.rep_string_count = 5; strcpy(alltypes.rep_string[4], "2014");
+    alltypes.rep_bytes_count = 5; alltypes.rep_bytes[4].size = 4;
+    memcpy(alltypes.rep_bytes[4].bytes, "2015", 4);
+
+    alltypes.rep_submsg_count = 5;
+    strcpy(alltypes.rep_submsg[4].substuff1, "2016");
+    alltypes.rep_submsg[4].substuff2 = 2016;
+    alltypes.rep_submsg[4].has_substuff3 = true;
+    alltypes.rep_submsg[4].substuff3 = 2016;
+    
+    alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth;
+    alltypes.rep_emptymsg_count = 5;
+    
+    alltypes.rep_fbytes_count = 5;
+    memcpy(alltypes.rep_fbytes[4], "2019", 4);
+    
+    alltypes.req_limits.int32_min  = INT32_MIN;
+    alltypes.req_limits.int32_max  = INT32_MAX;
+    alltypes.req_limits.uint32_min = 0;
+    alltypes.req_limits.uint32_max = UINT32_MAX;
+    alltypes.req_limits.enum_min   = HugeEnum_Negative;
+    alltypes.req_limits.enum_max   = HugeEnum_Positive;
+    
+    if (mode != 0)
+    {
+        /* Fill in values for optional fields */
+        alltypes.has_opt_int32 = true;
+        alltypes.opt_int32         = 3041;
+        alltypes.has_opt_uint32 = true;
+        alltypes.opt_uint32        = 3043;
+        alltypes.has_opt_sint32 = true;
+        alltypes.opt_sint32        = 3045;
+        alltypes.has_opt_bool = true;
+        alltypes.opt_bool          = true;
+        
+        alltypes.has_opt_fixed32 = true;
+        alltypes.opt_fixed32       = 3048;
+        alltypes.has_opt_sfixed32 = true;
+        alltypes.opt_sfixed32      = 3049;
+        alltypes.has_opt_float = true;
+        alltypes.opt_float         = 3050.0f;
+        
+        alltypes.has_opt_string = true;
+        strcpy(alltypes.opt_string, "3054");
+        alltypes.has_opt_bytes = true;
+        alltypes.opt_bytes.size = 4;
+        memcpy(alltypes.opt_bytes.bytes, "3055", 4);
+        alltypes.has_opt_submsg = true;
+        strcpy(alltypes.opt_submsg.substuff1, "3056");
+        alltypes.opt_submsg.substuff2 = 3056;
+        alltypes.has_opt_enum = true;
+        alltypes.opt_enum = MyEnum_Truth;
+        alltypes.has_opt_emptymsg = true;
+        alltypes.has_opt_fbytes = true;
+        memcpy(alltypes.opt_fbytes, "3059", 4);
+
+        alltypes.which_oneof = AllTypes_oneof_msg1_tag;
+        strcpy(alltypes.oneof.oneof_msg1.substuff1, "4059");
+        alltypes.oneof.oneof_msg1.substuff2 = 4059;
+    }
+    
+    alltypes.end = 1099;
+    
+    {
+        uint8_t buffer[AllTypes_size];
+        pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+        
+        /* Now encode it and check if we succeeded. */
+        if (pb_encode(&stream, AllTypes_fields, &alltypes))
+        {
+            SET_BINARY_MODE(stdout);
+            fwrite(buffer, 1, stream.bytes_written, stdout);
+            return 0; /* Success */
+        }
+        else
+        {
+            fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
+            return 1; /* Failure */
+        }
+    }
+}
diff --git a/tests/without_64bit/no_64bit_syshdr.h b/tests/without_64bit/no_64bit_syshdr.h
new file mode 100644
index 0000000..970178f
--- /dev/null
+++ b/tests/without_64bit/no_64bit_syshdr.h
@@ -0,0 +1,14 @@
+/* This wrapper undefines (u)int64_t */
+
+#ifdef PB_OLD_SYSHDR
+#include PB_OLD_SYSHDR
+#else
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#endif
+
+#define uint64_t disabled_uint64_t
+#define int64_t disabled_int64_t
+
diff --git a/tools/make_linux_package.sh b/tools/make_linux_package.sh
index 332c281..0bcba7d 100755
--- a/tools/make_linux_package.sh
+++ b/tools/make_linux_package.sh
@@ -3,6 +3,8 @@
 # Run this script in the top nanopb directory to create a binary package
 # for Linux users.
 
+# Requires: protobuf, python-protobuf, pyinstaller
+
 set -e
 set -x
 
@@ -18,20 +20,21 @@
 # Rebuild the Python .proto files
 make -BC $DEST/generator/proto
 
-# Make the nanopb generator available as a protoc plugin
-cp $DEST/generator/nanopb_generator.py $DEST/generator/protoc-gen-nanopb.py
-
 # Package the Python libraries
-( cd $DEST/generator; bbfreeze nanopb_generator.py protoc-gen-nanopb.py )
-mv $DEST/generator/dist $DEST/generator-bin
+( cd $DEST/generator; pyinstaller nanopb_generator.py )
+mv $DEST/generator/dist/nanopb_generator $DEST/generator-bin
 
-# Remove temp file
-rm $DEST/generator/protoc-gen-nanopb.py
+# Remove temp files
+rm -rf $DEST/generator/dist $DEST/generator/build $DEST/generator/nanopb_generator.spec
+
+# Make the nanopb generator available as a protoc plugin
+cp $DEST/generator-bin/nanopb_generator $DEST/generator-bin/protoc-gen-nanopb
 
 # Package the protoc compiler
 cp `which protoc` $DEST/generator-bin/protoc.bin
 LIBPROTOC=$(ldd `which protoc` | grep -o '/.*libprotoc[^ ]*')
-cp $LIBPROTOC $DEST/generator-bin/
+LIBPROTOBUF=$(ldd `which protoc` | grep -o '/.*libprotobuf[^ ]*')
+cp $LIBPROTOC $LIBPROTOBUF $DEST/generator-bin/
 cat > $DEST/generator-bin/protoc << EOF
 #!/bin/bash
 SCRIPTDIR=\$(dirname "\$0")
@@ -41,6 +44,9 @@
 EOF
 chmod +x $DEST/generator-bin/protoc
 
+# Remove debugging symbols to reduce size of package
+( cd $DEST/generator-bin; strip *.so *.so.* )
+
 # Tar it all up
 ( cd dist; tar -czf $VERSION.tar.gz $VERSION )
 
diff --git a/tools/make_mac_package.sh b/tools/make_mac_package.sh
index 21cd170..32bba5c 100755
--- a/tools/make_mac_package.sh
+++ b/tools/make_mac_package.sh
@@ -45,5 +45,5 @@
 chmod +x $DEST/generator-bin/protoc
 
 # Tar it all up
-( cd dist; zip -r $VERSION.zip $VERSION )
+( cd dist; tar -czf $VERSION.tar.gz $VERSION )
 
diff --git a/tools/set_version.sh b/tools/set_version.sh
index e15a859..0adb597 100755
--- a/tools/set_version.sh
+++ b/tools/set_version.sh
@@ -6,5 +6,9 @@
 
 sed -i -e 's/nanopb_version\s*=\s*"[^"]*"/nanopb_version = "'$1'"/' generator/nanopb_generator.py
 sed -i -e 's/#define\s*NANOPB_VERSION\s*.*/#define NANOPB_VERSION '$1'/' pb.h
+sed -i -e 's/set(\s*nanopb_VERSION_STRING\s*[^)]*)/set(nanopb_VERSION_STRING '$1')/' CMakeLists.txt
 
-
+VERSION_ONLY=$(echo $1 | sed 's/nanopb-//')
+if [[ $1 != *dev ]]
+then sed -i -e 's/"version":\s*"[^"]*"/"version": "'$VERSION_ONLY'"/' library.json
+fi