Merge pull request #591 from golang/master-merge

Merge remote-tracking branch 'origin/dev' into master
diff --git a/.gitignore b/.gitignore
index 8f5b596..c7dd405 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,5 +12,6 @@
 _obj
 _test
 _testmain.go
-protoc-gen-go/testdata/multi/*.pb.go
-_conformance/_conformance
+
+# Conformance test output and transient files.
+conformance/failing_tests.txt
diff --git a/.travis.yml b/.travis.yml
index 93c6780..455fa66 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,17 +2,29 @@
 language: go
 go:
 - 1.6.x
-- 1.7.x
-- 1.8.x
-- 1.9.x
+- 1.10.x
+- 1.x
 
 install:
   - go get -v -d -t github.com/golang/protobuf/...
-  - curl -L https://github.com/google/protobuf/releases/download/v3.3.0/protoc-3.3.0-linux-x86_64.zip -o /tmp/protoc.zip
-  - unzip /tmp/protoc.zip -d $HOME/protoc
+  - curl -L https://github.com/google/protobuf/releases/download/v3.5.1/protoc-3.5.1-linux-x86_64.zip -o /tmp/protoc.zip
+  - unzip /tmp/protoc.zip -d "$HOME"/protoc
+  - mkdir -p "$HOME"/src && ln -s "$HOME"/protoc "$HOME"/src/protobuf
 
 env:
   - PATH=$HOME/protoc/bin:$PATH
 
 script:
-  - make all test
+  - make all
+  - make regenerate
+  # TODO(tamird): When https://github.com/travis-ci/gimme/pull/130 is
+  # released, make this look for "1.x".
+  - if [[ "$TRAVIS_GO_VERSION" == 1.10* ]]; then
+      if [[ "$(git status --porcelain 2>&1)" != "" ]]; then
+        git status >&2;
+        git diff -a >&2;
+        exit 1;
+      fi;
+      echo "git status is clean.";
+    fi;
+  - make test
diff --git a/Make.protobuf b/Make.protobuf
deleted file mode 100644
index 15071de..0000000
--- a/Make.protobuf
+++ /dev/null
@@ -1,40 +0,0 @@
-# Go support for Protocol Buffers - Google's data interchange format
-#
-# Copyright 2010 The Go Authors.  All rights reserved.
-# https://github.com/golang/protobuf
-#
-# 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.
-
-# Includable Makefile to add a rule for generating .pb.go files from .proto files
-# (Google protocol buffer descriptions).
-# Typical use if myproto.proto is a file in package mypackage in this directory:
-#
-#	include $(GOROOT)/src/pkg/github.com/golang/protobuf/Make.protobuf
-
-%.pb.go:	%.proto
-	protoc --go_out=. $<
-
diff --git a/Makefile b/Makefile
index a1421d8..2bc2621 100644
--- a/Makefile
+++ b/Makefile
@@ -29,16 +29,14 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-
 all:	install
 
 install:
-	go install ./proto ./jsonpb ./ptypes
-	go install ./protoc-gen-go
+	go install ./proto ./jsonpb ./ptypes ./protoc-gen-go
 
 test:
-	go test ./proto ./jsonpb ./ptypes
-	make -C protoc-gen-go/testdata test
+	go test ./... ./protoc-gen-go/testdata
+	make -C conformance test
 
 clean:
 	go clean ./...
@@ -47,9 +45,4 @@
 	go clean -i ./...
 
 regenerate:
-	make -C protoc-gen-go/descriptor regenerate
-	make -C protoc-gen-go/plugin regenerate
-	make -C protoc-gen-go/testdata regenerate
-	make -C proto/testdata regenerate
-	make -C jsonpb/jsonpb_test_proto regenerate
-	make -C _conformance regenerate
+	./regenerate.sh
diff --git a/README.md b/README.md
index 9c4c815..01b29da 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
 Copyright 2010 The Go Authors.
 https://github.com/golang/protobuf
 
-This package and the code it generates requires at least Go 1.4.
+This package and the code it generates requires at least Go 1.6.
 
 This software implements Go bindings for protocol buffers.  For
 information about protocol buffers themselves, see
@@ -56,13 +56,49 @@
 The generated files will be suffixed .pb.go.  See the Test code below
 for an example using such a file.
 
+## Packages and input paths ##
+
+The protocol buffer language has a concept of "packages" which does not
+correspond well to the Go notion of packages. In generated Go code,
+each source `.proto` file is associated with a single Go package. The
+name and import path for this package is specified with the `go_package`
+proto option:
+
+	option go_package = "github.com/golang/protobuf/ptypes/any";
+
+The protocol buffer compiler will attempt to derive a package name and
+import path if a `go_package` option is not present, but it is
+best to always specify one explicitly.
+
+There is a one-to-one relationship between source `.proto` files and
+generated `.pb.go` files, but any number of `.pb.go` files may be
+contained in the same Go package.
+
+The output name of a generated file is produced by replacing the
+`.proto` suffix with `.pb.go` (e.g., `foo.proto` produces `foo.pb.go`).
+However, the output directory is selected in one of two ways.  Let
+us say we have `inputs/x.proto` with a `go_package` option of
+`github.com/golang/protobuf/p`. The corresponding output file may
+be:
+
+- Relative to the import path:
+
+	protoc --go_out=. inputs/x.proto
+	# writes ./github.com/golang/protobuf/p/x.pb.go
+
+  (This can work well with `--go_out=$GOPATH`.)
+
+- Relative to the input file:
+
+	protoc --go_out=paths=source_relative:. inputs/x.proto
+	# generate ./inputs/x.pb.go
+
+## Generated code ##
 
 The package comment for the proto library contains text describing
 the interface provided in Go for protocol buffers. Here is an edited
 version.
 
-==========
-
 The proto package converts data structures to and from the
 wire format of protocol buffers.  It works in concert with the
 Go source code generated for .proto files by the protocol compiler.
@@ -114,9 +150,9 @@
 ```proto
 	syntax = "proto2";
 	package example;
-	
+
 	enum FOO { X = 17; };
-	
+
 	message Test {
 	  required string label = 1;
 	  optional int32 type = 2 [default=77];
@@ -170,22 +206,25 @@
 To pass extra parameters to the plugin, use a comma-separated
 parameter list separated from the output directory by a colon:
 
-
 	protoc --go_out=plugins=grpc,import_path=mypackage:. *.proto
 
-
-- `import_prefix=xxx` - a prefix that is added onto the beginning of
-  all imports. Useful for things like generating protos in a
-  subdirectory, or regenerating vendored protobufs in-place.
-- `import_path=foo/bar` - used as the package if no input files
-  declare `go_package`. If it contains slashes, everything up to the
-  rightmost slash is ignored.
+- `paths=(import | source_relative)` - specifies how the paths of
+  generated files are structured. See the "Packages and imports paths"
+  section above. The default is `import`.
 - `plugins=plugin1+plugin2` - specifies the list of sub-plugins to
   load. The only plugin in this repo is `grpc`.
 - `Mfoo/bar.proto=quux/shme` - declares that foo/bar.proto is
   associated with Go package quux/shme.  This is subject to the
   import_prefix parameter.
 
+The following parameters are deprecated and should not be used:
+
+- `import_prefix=xxx` - a prefix that is added onto the beginning of
+  all imports.
+- `import_path=foo/bar` - used as the package if no input files
+  declare `go_package`. If it contains slashes, everything up to the
+  rightmost slash is ignored.
+
 ## gRPC Support ##
 
 If a proto file specifies RPC services, protoc-gen-go can be instructed to
diff --git a/_conformance/conformance_proto/conformance.pb.go b/_conformance/conformance_proto/conformance.pb.go
deleted file mode 100644
index ec354ea..0000000
--- a/_conformance/conformance_proto/conformance.pb.go
+++ /dev/null
@@ -1,1885 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: conformance_proto/conformance.proto
-
-/*
-Package conformance is a generated protocol buffer package.
-
-It is generated from these files:
-	conformance_proto/conformance.proto
-
-It has these top-level messages:
-	ConformanceRequest
-	ConformanceResponse
-	TestAllTypes
-	ForeignMessage
-*/
-package conformance
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import math "math"
-import google_protobuf "github.com/golang/protobuf/ptypes/any"
-import google_protobuf1 "github.com/golang/protobuf/ptypes/duration"
-import google_protobuf2 "google.golang.org/genproto/protobuf"
-import google_protobuf3 "github.com/golang/protobuf/ptypes/struct"
-import google_protobuf4 "github.com/golang/protobuf/ptypes/timestamp"
-import google_protobuf5 "github.com/golang/protobuf/ptypes/wrappers"
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-type WireFormat int32
-
-const (
-	WireFormat_UNSPECIFIED WireFormat = 0
-	WireFormat_PROTOBUF    WireFormat = 1
-	WireFormat_JSON        WireFormat = 2
-)
-
-var WireFormat_name = map[int32]string{
-	0: "UNSPECIFIED",
-	1: "PROTOBUF",
-	2: "JSON",
-}
-var WireFormat_value = map[string]int32{
-	"UNSPECIFIED": 0,
-	"PROTOBUF":    1,
-	"JSON":        2,
-}
-
-func (x WireFormat) String() string {
-	return proto.EnumName(WireFormat_name, int32(x))
-}
-func (WireFormat) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
-
-type ForeignEnum int32
-
-const (
-	ForeignEnum_FOREIGN_FOO ForeignEnum = 0
-	ForeignEnum_FOREIGN_BAR ForeignEnum = 1
-	ForeignEnum_FOREIGN_BAZ ForeignEnum = 2
-)
-
-var ForeignEnum_name = map[int32]string{
-	0: "FOREIGN_FOO",
-	1: "FOREIGN_BAR",
-	2: "FOREIGN_BAZ",
-}
-var ForeignEnum_value = map[string]int32{
-	"FOREIGN_FOO": 0,
-	"FOREIGN_BAR": 1,
-	"FOREIGN_BAZ": 2,
-}
-
-func (x ForeignEnum) String() string {
-	return proto.EnumName(ForeignEnum_name, int32(x))
-}
-func (ForeignEnum) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
-
-type TestAllTypes_NestedEnum int32
-
-const (
-	TestAllTypes_FOO TestAllTypes_NestedEnum = 0
-	TestAllTypes_BAR TestAllTypes_NestedEnum = 1
-	TestAllTypes_BAZ TestAllTypes_NestedEnum = 2
-	TestAllTypes_NEG TestAllTypes_NestedEnum = -1
-)
-
-var TestAllTypes_NestedEnum_name = map[int32]string{
-	0:  "FOO",
-	1:  "BAR",
-	2:  "BAZ",
-	-1: "NEG",
-}
-var TestAllTypes_NestedEnum_value = map[string]int32{
-	"FOO": 0,
-	"BAR": 1,
-	"BAZ": 2,
-	"NEG": -1,
-}
-
-func (x TestAllTypes_NestedEnum) String() string {
-	return proto.EnumName(TestAllTypes_NestedEnum_name, int32(x))
-}
-func (TestAllTypes_NestedEnum) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 0} }
-
-// Represents a single test case's input.  The testee should:
-//
-//   1. parse this proto (which should always succeed)
-//   2. parse the protobuf or JSON payload in "payload" (which may fail)
-//   3. if the parse succeeded, serialize the message in the requested format.
-type ConformanceRequest struct {
-	// The payload (whether protobuf of JSON) is always for a TestAllTypes proto
-	// (see below).
-	//
-	// Types that are valid to be assigned to Payload:
-	//	*ConformanceRequest_ProtobufPayload
-	//	*ConformanceRequest_JsonPayload
-	Payload isConformanceRequest_Payload `protobuf_oneof:"payload"`
-	// Which format should the testee serialize its message to?
-	RequestedOutputFormat WireFormat `protobuf:"varint,3,opt,name=requested_output_format,json=requestedOutputFormat,enum=conformance.WireFormat" json:"requested_output_format,omitempty"`
-}
-
-func (m *ConformanceRequest) Reset()                    { *m = ConformanceRequest{} }
-func (m *ConformanceRequest) String() string            { return proto.CompactTextString(m) }
-func (*ConformanceRequest) ProtoMessage()               {}
-func (*ConformanceRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
-
-type isConformanceRequest_Payload interface {
-	isConformanceRequest_Payload()
-}
-
-type ConformanceRequest_ProtobufPayload struct {
-	ProtobufPayload []byte `protobuf:"bytes,1,opt,name=protobuf_payload,json=protobufPayload,proto3,oneof"`
-}
-type ConformanceRequest_JsonPayload struct {
-	JsonPayload string `protobuf:"bytes,2,opt,name=json_payload,json=jsonPayload,oneof"`
-}
-
-func (*ConformanceRequest_ProtobufPayload) isConformanceRequest_Payload() {}
-func (*ConformanceRequest_JsonPayload) isConformanceRequest_Payload()     {}
-
-func (m *ConformanceRequest) GetPayload() isConformanceRequest_Payload {
-	if m != nil {
-		return m.Payload
-	}
-	return nil
-}
-
-func (m *ConformanceRequest) GetProtobufPayload() []byte {
-	if x, ok := m.GetPayload().(*ConformanceRequest_ProtobufPayload); ok {
-		return x.ProtobufPayload
-	}
-	return nil
-}
-
-func (m *ConformanceRequest) GetJsonPayload() string {
-	if x, ok := m.GetPayload().(*ConformanceRequest_JsonPayload); ok {
-		return x.JsonPayload
-	}
-	return ""
-}
-
-func (m *ConformanceRequest) GetRequestedOutputFormat() WireFormat {
-	if m != nil {
-		return m.RequestedOutputFormat
-	}
-	return WireFormat_UNSPECIFIED
-}
-
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*ConformanceRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
-	return _ConformanceRequest_OneofMarshaler, _ConformanceRequest_OneofUnmarshaler, _ConformanceRequest_OneofSizer, []interface{}{
-		(*ConformanceRequest_ProtobufPayload)(nil),
-		(*ConformanceRequest_JsonPayload)(nil),
-	}
-}
-
-func _ConformanceRequest_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*ConformanceRequest)
-	// payload
-	switch x := m.Payload.(type) {
-	case *ConformanceRequest_ProtobufPayload:
-		b.EncodeVarint(1<<3 | proto.WireBytes)
-		b.EncodeRawBytes(x.ProtobufPayload)
-	case *ConformanceRequest_JsonPayload:
-		b.EncodeVarint(2<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.JsonPayload)
-	case nil:
-	default:
-		return fmt.Errorf("ConformanceRequest.Payload has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _ConformanceRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*ConformanceRequest)
-	switch tag {
-	case 1: // payload.protobuf_payload
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeRawBytes(true)
-		m.Payload = &ConformanceRequest_ProtobufPayload{x}
-		return true, err
-	case 2: // payload.json_payload
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.Payload = &ConformanceRequest_JsonPayload{x}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _ConformanceRequest_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*ConformanceRequest)
-	// payload
-	switch x := m.Payload.(type) {
-	case *ConformanceRequest_ProtobufPayload:
-		n += proto.SizeVarint(1<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(len(x.ProtobufPayload)))
-		n += len(x.ProtobufPayload)
-	case *ConformanceRequest_JsonPayload:
-		n += proto.SizeVarint(2<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(len(x.JsonPayload)))
-		n += len(x.JsonPayload)
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
-// Represents a single test case's output.
-type ConformanceResponse struct {
-	// Types that are valid to be assigned to Result:
-	//	*ConformanceResponse_ParseError
-	//	*ConformanceResponse_SerializeError
-	//	*ConformanceResponse_RuntimeError
-	//	*ConformanceResponse_ProtobufPayload
-	//	*ConformanceResponse_JsonPayload
-	//	*ConformanceResponse_Skipped
-	Result isConformanceResponse_Result `protobuf_oneof:"result"`
-}
-
-func (m *ConformanceResponse) Reset()                    { *m = ConformanceResponse{} }
-func (m *ConformanceResponse) String() string            { return proto.CompactTextString(m) }
-func (*ConformanceResponse) ProtoMessage()               {}
-func (*ConformanceResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
-
-type isConformanceResponse_Result interface {
-	isConformanceResponse_Result()
-}
-
-type ConformanceResponse_ParseError struct {
-	ParseError string `protobuf:"bytes,1,opt,name=parse_error,json=parseError,oneof"`
-}
-type ConformanceResponse_SerializeError struct {
-	SerializeError string `protobuf:"bytes,6,opt,name=serialize_error,json=serializeError,oneof"`
-}
-type ConformanceResponse_RuntimeError struct {
-	RuntimeError string `protobuf:"bytes,2,opt,name=runtime_error,json=runtimeError,oneof"`
-}
-type ConformanceResponse_ProtobufPayload struct {
-	ProtobufPayload []byte `protobuf:"bytes,3,opt,name=protobuf_payload,json=protobufPayload,proto3,oneof"`
-}
-type ConformanceResponse_JsonPayload struct {
-	JsonPayload string `protobuf:"bytes,4,opt,name=json_payload,json=jsonPayload,oneof"`
-}
-type ConformanceResponse_Skipped struct {
-	Skipped string `protobuf:"bytes,5,opt,name=skipped,oneof"`
-}
-
-func (*ConformanceResponse_ParseError) isConformanceResponse_Result()      {}
-func (*ConformanceResponse_SerializeError) isConformanceResponse_Result()  {}
-func (*ConformanceResponse_RuntimeError) isConformanceResponse_Result()    {}
-func (*ConformanceResponse_ProtobufPayload) isConformanceResponse_Result() {}
-func (*ConformanceResponse_JsonPayload) isConformanceResponse_Result()     {}
-func (*ConformanceResponse_Skipped) isConformanceResponse_Result()         {}
-
-func (m *ConformanceResponse) GetResult() isConformanceResponse_Result {
-	if m != nil {
-		return m.Result
-	}
-	return nil
-}
-
-func (m *ConformanceResponse) GetParseError() string {
-	if x, ok := m.GetResult().(*ConformanceResponse_ParseError); ok {
-		return x.ParseError
-	}
-	return ""
-}
-
-func (m *ConformanceResponse) GetSerializeError() string {
-	if x, ok := m.GetResult().(*ConformanceResponse_SerializeError); ok {
-		return x.SerializeError
-	}
-	return ""
-}
-
-func (m *ConformanceResponse) GetRuntimeError() string {
-	if x, ok := m.GetResult().(*ConformanceResponse_RuntimeError); ok {
-		return x.RuntimeError
-	}
-	return ""
-}
-
-func (m *ConformanceResponse) GetProtobufPayload() []byte {
-	if x, ok := m.GetResult().(*ConformanceResponse_ProtobufPayload); ok {
-		return x.ProtobufPayload
-	}
-	return nil
-}
-
-func (m *ConformanceResponse) GetJsonPayload() string {
-	if x, ok := m.GetResult().(*ConformanceResponse_JsonPayload); ok {
-		return x.JsonPayload
-	}
-	return ""
-}
-
-func (m *ConformanceResponse) GetSkipped() string {
-	if x, ok := m.GetResult().(*ConformanceResponse_Skipped); ok {
-		return x.Skipped
-	}
-	return ""
-}
-
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*ConformanceResponse) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
-	return _ConformanceResponse_OneofMarshaler, _ConformanceResponse_OneofUnmarshaler, _ConformanceResponse_OneofSizer, []interface{}{
-		(*ConformanceResponse_ParseError)(nil),
-		(*ConformanceResponse_SerializeError)(nil),
-		(*ConformanceResponse_RuntimeError)(nil),
-		(*ConformanceResponse_ProtobufPayload)(nil),
-		(*ConformanceResponse_JsonPayload)(nil),
-		(*ConformanceResponse_Skipped)(nil),
-	}
-}
-
-func _ConformanceResponse_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*ConformanceResponse)
-	// result
-	switch x := m.Result.(type) {
-	case *ConformanceResponse_ParseError:
-		b.EncodeVarint(1<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.ParseError)
-	case *ConformanceResponse_SerializeError:
-		b.EncodeVarint(6<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.SerializeError)
-	case *ConformanceResponse_RuntimeError:
-		b.EncodeVarint(2<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.RuntimeError)
-	case *ConformanceResponse_ProtobufPayload:
-		b.EncodeVarint(3<<3 | proto.WireBytes)
-		b.EncodeRawBytes(x.ProtobufPayload)
-	case *ConformanceResponse_JsonPayload:
-		b.EncodeVarint(4<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.JsonPayload)
-	case *ConformanceResponse_Skipped:
-		b.EncodeVarint(5<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.Skipped)
-	case nil:
-	default:
-		return fmt.Errorf("ConformanceResponse.Result has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _ConformanceResponse_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*ConformanceResponse)
-	switch tag {
-	case 1: // result.parse_error
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.Result = &ConformanceResponse_ParseError{x}
-		return true, err
-	case 6: // result.serialize_error
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.Result = &ConformanceResponse_SerializeError{x}
-		return true, err
-	case 2: // result.runtime_error
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.Result = &ConformanceResponse_RuntimeError{x}
-		return true, err
-	case 3: // result.protobuf_payload
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeRawBytes(true)
-		m.Result = &ConformanceResponse_ProtobufPayload{x}
-		return true, err
-	case 4: // result.json_payload
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.Result = &ConformanceResponse_JsonPayload{x}
-		return true, err
-	case 5: // result.skipped
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.Result = &ConformanceResponse_Skipped{x}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _ConformanceResponse_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*ConformanceResponse)
-	// result
-	switch x := m.Result.(type) {
-	case *ConformanceResponse_ParseError:
-		n += proto.SizeVarint(1<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(len(x.ParseError)))
-		n += len(x.ParseError)
-	case *ConformanceResponse_SerializeError:
-		n += proto.SizeVarint(6<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(len(x.SerializeError)))
-		n += len(x.SerializeError)
-	case *ConformanceResponse_RuntimeError:
-		n += proto.SizeVarint(2<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(len(x.RuntimeError)))
-		n += len(x.RuntimeError)
-	case *ConformanceResponse_ProtobufPayload:
-		n += proto.SizeVarint(3<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(len(x.ProtobufPayload)))
-		n += len(x.ProtobufPayload)
-	case *ConformanceResponse_JsonPayload:
-		n += proto.SizeVarint(4<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(len(x.JsonPayload)))
-		n += len(x.JsonPayload)
-	case *ConformanceResponse_Skipped:
-		n += proto.SizeVarint(5<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(len(x.Skipped)))
-		n += len(x.Skipped)
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
-// This proto includes every type of field in both singular and repeated
-// forms.
-type TestAllTypes struct {
-	// Singular
-	OptionalInt32          int32                       `protobuf:"varint,1,opt,name=optional_int32,json=optionalInt32" json:"optional_int32,omitempty"`
-	OptionalInt64          int64                       `protobuf:"varint,2,opt,name=optional_int64,json=optionalInt64" json:"optional_int64,omitempty"`
-	OptionalUint32         uint32                      `protobuf:"varint,3,opt,name=optional_uint32,json=optionalUint32" json:"optional_uint32,omitempty"`
-	OptionalUint64         uint64                      `protobuf:"varint,4,opt,name=optional_uint64,json=optionalUint64" json:"optional_uint64,omitempty"`
-	OptionalSint32         int32                       `protobuf:"zigzag32,5,opt,name=optional_sint32,json=optionalSint32" json:"optional_sint32,omitempty"`
-	OptionalSint64         int64                       `protobuf:"zigzag64,6,opt,name=optional_sint64,json=optionalSint64" json:"optional_sint64,omitempty"`
-	OptionalFixed32        uint32                      `protobuf:"fixed32,7,opt,name=optional_fixed32,json=optionalFixed32" json:"optional_fixed32,omitempty"`
-	OptionalFixed64        uint64                      `protobuf:"fixed64,8,opt,name=optional_fixed64,json=optionalFixed64" json:"optional_fixed64,omitempty"`
-	OptionalSfixed32       int32                       `protobuf:"fixed32,9,opt,name=optional_sfixed32,json=optionalSfixed32" json:"optional_sfixed32,omitempty"`
-	OptionalSfixed64       int64                       `protobuf:"fixed64,10,opt,name=optional_sfixed64,json=optionalSfixed64" json:"optional_sfixed64,omitempty"`
-	OptionalFloat          float32                     `protobuf:"fixed32,11,opt,name=optional_float,json=optionalFloat" json:"optional_float,omitempty"`
-	OptionalDouble         float64                     `protobuf:"fixed64,12,opt,name=optional_double,json=optionalDouble" json:"optional_double,omitempty"`
-	OptionalBool           bool                        `protobuf:"varint,13,opt,name=optional_bool,json=optionalBool" json:"optional_bool,omitempty"`
-	OptionalString         string                      `protobuf:"bytes,14,opt,name=optional_string,json=optionalString" json:"optional_string,omitempty"`
-	OptionalBytes          []byte                      `protobuf:"bytes,15,opt,name=optional_bytes,json=optionalBytes,proto3" json:"optional_bytes,omitempty"`
-	OptionalNestedMessage  *TestAllTypes_NestedMessage `protobuf:"bytes,18,opt,name=optional_nested_message,json=optionalNestedMessage" json:"optional_nested_message,omitempty"`
-	OptionalForeignMessage *ForeignMessage             `protobuf:"bytes,19,opt,name=optional_foreign_message,json=optionalForeignMessage" json:"optional_foreign_message,omitempty"`
-	OptionalNestedEnum     TestAllTypes_NestedEnum     `protobuf:"varint,21,opt,name=optional_nested_enum,json=optionalNestedEnum,enum=conformance.TestAllTypes_NestedEnum" json:"optional_nested_enum,omitempty"`
-	OptionalForeignEnum    ForeignEnum                 `protobuf:"varint,22,opt,name=optional_foreign_enum,json=optionalForeignEnum,enum=conformance.ForeignEnum" json:"optional_foreign_enum,omitempty"`
-	OptionalStringPiece    string                      `protobuf:"bytes,24,opt,name=optional_string_piece,json=optionalStringPiece" json:"optional_string_piece,omitempty"`
-	OptionalCord           string                      `protobuf:"bytes,25,opt,name=optional_cord,json=optionalCord" json:"optional_cord,omitempty"`
-	RecursiveMessage       *TestAllTypes               `protobuf:"bytes,27,opt,name=recursive_message,json=recursiveMessage" json:"recursive_message,omitempty"`
-	// Repeated
-	RepeatedInt32          []int32                       `protobuf:"varint,31,rep,packed,name=repeated_int32,json=repeatedInt32" json:"repeated_int32,omitempty"`
-	RepeatedInt64          []int64                       `protobuf:"varint,32,rep,packed,name=repeated_int64,json=repeatedInt64" json:"repeated_int64,omitempty"`
-	RepeatedUint32         []uint32                      `protobuf:"varint,33,rep,packed,name=repeated_uint32,json=repeatedUint32" json:"repeated_uint32,omitempty"`
-	RepeatedUint64         []uint64                      `protobuf:"varint,34,rep,packed,name=repeated_uint64,json=repeatedUint64" json:"repeated_uint64,omitempty"`
-	RepeatedSint32         []int32                       `protobuf:"zigzag32,35,rep,packed,name=repeated_sint32,json=repeatedSint32" json:"repeated_sint32,omitempty"`
-	RepeatedSint64         []int64                       `protobuf:"zigzag64,36,rep,packed,name=repeated_sint64,json=repeatedSint64" json:"repeated_sint64,omitempty"`
-	RepeatedFixed32        []uint32                      `protobuf:"fixed32,37,rep,packed,name=repeated_fixed32,json=repeatedFixed32" json:"repeated_fixed32,omitempty"`
-	RepeatedFixed64        []uint64                      `protobuf:"fixed64,38,rep,packed,name=repeated_fixed64,json=repeatedFixed64" json:"repeated_fixed64,omitempty"`
-	RepeatedSfixed32       []int32                       `protobuf:"fixed32,39,rep,packed,name=repeated_sfixed32,json=repeatedSfixed32" json:"repeated_sfixed32,omitempty"`
-	RepeatedSfixed64       []int64                       `protobuf:"fixed64,40,rep,packed,name=repeated_sfixed64,json=repeatedSfixed64" json:"repeated_sfixed64,omitempty"`
-	RepeatedFloat          []float32                     `protobuf:"fixed32,41,rep,packed,name=repeated_float,json=repeatedFloat" json:"repeated_float,omitempty"`
-	RepeatedDouble         []float64                     `protobuf:"fixed64,42,rep,packed,name=repeated_double,json=repeatedDouble" json:"repeated_double,omitempty"`
-	RepeatedBool           []bool                        `protobuf:"varint,43,rep,packed,name=repeated_bool,json=repeatedBool" json:"repeated_bool,omitempty"`
-	RepeatedString         []string                      `protobuf:"bytes,44,rep,name=repeated_string,json=repeatedString" json:"repeated_string,omitempty"`
-	RepeatedBytes          [][]byte                      `protobuf:"bytes,45,rep,name=repeated_bytes,json=repeatedBytes,proto3" json:"repeated_bytes,omitempty"`
-	RepeatedNestedMessage  []*TestAllTypes_NestedMessage `protobuf:"bytes,48,rep,name=repeated_nested_message,json=repeatedNestedMessage" json:"repeated_nested_message,omitempty"`
-	RepeatedForeignMessage []*ForeignMessage             `protobuf:"bytes,49,rep,name=repeated_foreign_message,json=repeatedForeignMessage" json:"repeated_foreign_message,omitempty"`
-	RepeatedNestedEnum     []TestAllTypes_NestedEnum     `protobuf:"varint,51,rep,packed,name=repeated_nested_enum,json=repeatedNestedEnum,enum=conformance.TestAllTypes_NestedEnum" json:"repeated_nested_enum,omitempty"`
-	RepeatedForeignEnum    []ForeignEnum                 `protobuf:"varint,52,rep,packed,name=repeated_foreign_enum,json=repeatedForeignEnum,enum=conformance.ForeignEnum" json:"repeated_foreign_enum,omitempty"`
-	RepeatedStringPiece    []string                      `protobuf:"bytes,54,rep,name=repeated_string_piece,json=repeatedStringPiece" json:"repeated_string_piece,omitempty"`
-	RepeatedCord           []string                      `protobuf:"bytes,55,rep,name=repeated_cord,json=repeatedCord" json:"repeated_cord,omitempty"`
-	// Map
-	MapInt32Int32           map[int32]int32                        `protobuf:"bytes,56,rep,name=map_int32_int32,json=mapInt32Int32" json:"map_int32_int32,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
-	MapInt64Int64           map[int64]int64                        `protobuf:"bytes,57,rep,name=map_int64_int64,json=mapInt64Int64" json:"map_int64_int64,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
-	MapUint32Uint32         map[uint32]uint32                      `protobuf:"bytes,58,rep,name=map_uint32_uint32,json=mapUint32Uint32" json:"map_uint32_uint32,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
-	MapUint64Uint64         map[uint64]uint64                      `protobuf:"bytes,59,rep,name=map_uint64_uint64,json=mapUint64Uint64" json:"map_uint64_uint64,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
-	MapSint32Sint32         map[int32]int32                        `protobuf:"bytes,60,rep,name=map_sint32_sint32,json=mapSint32Sint32" json:"map_sint32_sint32,omitempty" protobuf_key:"zigzag32,1,opt,name=key" protobuf_val:"zigzag32,2,opt,name=value"`
-	MapSint64Sint64         map[int64]int64                        `protobuf:"bytes,61,rep,name=map_sint64_sint64,json=mapSint64Sint64" json:"map_sint64_sint64,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"zigzag64,2,opt,name=value"`
-	MapFixed32Fixed32       map[uint32]uint32                      `protobuf:"bytes,62,rep,name=map_fixed32_fixed32,json=mapFixed32Fixed32" json:"map_fixed32_fixed32,omitempty" protobuf_key:"fixed32,1,opt,name=key" protobuf_val:"fixed32,2,opt,name=value"`
-	MapFixed64Fixed64       map[uint64]uint64                      `protobuf:"bytes,63,rep,name=map_fixed64_fixed64,json=mapFixed64Fixed64" json:"map_fixed64_fixed64,omitempty" protobuf_key:"fixed64,1,opt,name=key" protobuf_val:"fixed64,2,opt,name=value"`
-	MapSfixed32Sfixed32     map[int32]int32                        `protobuf:"bytes,64,rep,name=map_sfixed32_sfixed32,json=mapSfixed32Sfixed32" json:"map_sfixed32_sfixed32,omitempty" protobuf_key:"fixed32,1,opt,name=key" protobuf_val:"fixed32,2,opt,name=value"`
-	MapSfixed64Sfixed64     map[int64]int64                        `protobuf:"bytes,65,rep,name=map_sfixed64_sfixed64,json=mapSfixed64Sfixed64" json:"map_sfixed64_sfixed64,omitempty" protobuf_key:"fixed64,1,opt,name=key" protobuf_val:"fixed64,2,opt,name=value"`
-	MapInt32Float           map[int32]float32                      `protobuf:"bytes,66,rep,name=map_int32_float,json=mapInt32Float" json:"map_int32_float,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"fixed32,2,opt,name=value"`
-	MapInt32Double          map[int32]float64                      `protobuf:"bytes,67,rep,name=map_int32_double,json=mapInt32Double" json:"map_int32_double,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"fixed64,2,opt,name=value"`
-	MapBoolBool             map[bool]bool                          `protobuf:"bytes,68,rep,name=map_bool_bool,json=mapBoolBool" json:"map_bool_bool,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
-	MapStringString         map[string]string                      `protobuf:"bytes,69,rep,name=map_string_string,json=mapStringString" json:"map_string_string,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	MapStringBytes          map[string][]byte                      `protobuf:"bytes,70,rep,name=map_string_bytes,json=mapStringBytes" json:"map_string_bytes,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"`
-	MapStringNestedMessage  map[string]*TestAllTypes_NestedMessage `protobuf:"bytes,71,rep,name=map_string_nested_message,json=mapStringNestedMessage" json:"map_string_nested_message,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	MapStringForeignMessage map[string]*ForeignMessage             `protobuf:"bytes,72,rep,name=map_string_foreign_message,json=mapStringForeignMessage" json:"map_string_foreign_message,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	MapStringNestedEnum     map[string]TestAllTypes_NestedEnum     `protobuf:"bytes,73,rep,name=map_string_nested_enum,json=mapStringNestedEnum" json:"map_string_nested_enum,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value,enum=conformance.TestAllTypes_NestedEnum"`
-	MapStringForeignEnum    map[string]ForeignEnum                 `protobuf:"bytes,74,rep,name=map_string_foreign_enum,json=mapStringForeignEnum" json:"map_string_foreign_enum,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value,enum=conformance.ForeignEnum"`
-	// Types that are valid to be assigned to OneofField:
-	//	*TestAllTypes_OneofUint32
-	//	*TestAllTypes_OneofNestedMessage
-	//	*TestAllTypes_OneofString
-	//	*TestAllTypes_OneofBytes
-	//	*TestAllTypes_OneofBool
-	//	*TestAllTypes_OneofUint64
-	//	*TestAllTypes_OneofFloat
-	//	*TestAllTypes_OneofDouble
-	//	*TestAllTypes_OneofEnum
-	OneofField isTestAllTypes_OneofField `protobuf_oneof:"oneof_field"`
-	// Well-known types
-	OptionalBoolWrapper   *google_protobuf5.BoolValue     `protobuf:"bytes,201,opt,name=optional_bool_wrapper,json=optionalBoolWrapper" json:"optional_bool_wrapper,omitempty"`
-	OptionalInt32Wrapper  *google_protobuf5.Int32Value    `protobuf:"bytes,202,opt,name=optional_int32_wrapper,json=optionalInt32Wrapper" json:"optional_int32_wrapper,omitempty"`
-	OptionalInt64Wrapper  *google_protobuf5.Int64Value    `protobuf:"bytes,203,opt,name=optional_int64_wrapper,json=optionalInt64Wrapper" json:"optional_int64_wrapper,omitempty"`
-	OptionalUint32Wrapper *google_protobuf5.UInt32Value   `protobuf:"bytes,204,opt,name=optional_uint32_wrapper,json=optionalUint32Wrapper" json:"optional_uint32_wrapper,omitempty"`
-	OptionalUint64Wrapper *google_protobuf5.UInt64Value   `protobuf:"bytes,205,opt,name=optional_uint64_wrapper,json=optionalUint64Wrapper" json:"optional_uint64_wrapper,omitempty"`
-	OptionalFloatWrapper  *google_protobuf5.FloatValue    `protobuf:"bytes,206,opt,name=optional_float_wrapper,json=optionalFloatWrapper" json:"optional_float_wrapper,omitempty"`
-	OptionalDoubleWrapper *google_protobuf5.DoubleValue   `protobuf:"bytes,207,opt,name=optional_double_wrapper,json=optionalDoubleWrapper" json:"optional_double_wrapper,omitempty"`
-	OptionalStringWrapper *google_protobuf5.StringValue   `protobuf:"bytes,208,opt,name=optional_string_wrapper,json=optionalStringWrapper" json:"optional_string_wrapper,omitempty"`
-	OptionalBytesWrapper  *google_protobuf5.BytesValue    `protobuf:"bytes,209,opt,name=optional_bytes_wrapper,json=optionalBytesWrapper" json:"optional_bytes_wrapper,omitempty"`
-	RepeatedBoolWrapper   []*google_protobuf5.BoolValue   `protobuf:"bytes,211,rep,name=repeated_bool_wrapper,json=repeatedBoolWrapper" json:"repeated_bool_wrapper,omitempty"`
-	RepeatedInt32Wrapper  []*google_protobuf5.Int32Value  `protobuf:"bytes,212,rep,name=repeated_int32_wrapper,json=repeatedInt32Wrapper" json:"repeated_int32_wrapper,omitempty"`
-	RepeatedInt64Wrapper  []*google_protobuf5.Int64Value  `protobuf:"bytes,213,rep,name=repeated_int64_wrapper,json=repeatedInt64Wrapper" json:"repeated_int64_wrapper,omitempty"`
-	RepeatedUint32Wrapper []*google_protobuf5.UInt32Value `protobuf:"bytes,214,rep,name=repeated_uint32_wrapper,json=repeatedUint32Wrapper" json:"repeated_uint32_wrapper,omitempty"`
-	RepeatedUint64Wrapper []*google_protobuf5.UInt64Value `protobuf:"bytes,215,rep,name=repeated_uint64_wrapper,json=repeatedUint64Wrapper" json:"repeated_uint64_wrapper,omitempty"`
-	RepeatedFloatWrapper  []*google_protobuf5.FloatValue  `protobuf:"bytes,216,rep,name=repeated_float_wrapper,json=repeatedFloatWrapper" json:"repeated_float_wrapper,omitempty"`
-	RepeatedDoubleWrapper []*google_protobuf5.DoubleValue `protobuf:"bytes,217,rep,name=repeated_double_wrapper,json=repeatedDoubleWrapper" json:"repeated_double_wrapper,omitempty"`
-	RepeatedStringWrapper []*google_protobuf5.StringValue `protobuf:"bytes,218,rep,name=repeated_string_wrapper,json=repeatedStringWrapper" json:"repeated_string_wrapper,omitempty"`
-	RepeatedBytesWrapper  []*google_protobuf5.BytesValue  `protobuf:"bytes,219,rep,name=repeated_bytes_wrapper,json=repeatedBytesWrapper" json:"repeated_bytes_wrapper,omitempty"`
-	OptionalDuration      *google_protobuf1.Duration      `protobuf:"bytes,301,opt,name=optional_duration,json=optionalDuration" json:"optional_duration,omitempty"`
-	OptionalTimestamp     *google_protobuf4.Timestamp     `protobuf:"bytes,302,opt,name=optional_timestamp,json=optionalTimestamp" json:"optional_timestamp,omitempty"`
-	OptionalFieldMask     *google_protobuf2.FieldMask     `protobuf:"bytes,303,opt,name=optional_field_mask,json=optionalFieldMask" json:"optional_field_mask,omitempty"`
-	OptionalStruct        *google_protobuf3.Struct        `protobuf:"bytes,304,opt,name=optional_struct,json=optionalStruct" json:"optional_struct,omitempty"`
-	OptionalAny           *google_protobuf.Any            `protobuf:"bytes,305,opt,name=optional_any,json=optionalAny" json:"optional_any,omitempty"`
-	OptionalValue         *google_protobuf3.Value         `protobuf:"bytes,306,opt,name=optional_value,json=optionalValue" json:"optional_value,omitempty"`
-	RepeatedDuration      []*google_protobuf1.Duration    `protobuf:"bytes,311,rep,name=repeated_duration,json=repeatedDuration" json:"repeated_duration,omitempty"`
-	RepeatedTimestamp     []*google_protobuf4.Timestamp   `protobuf:"bytes,312,rep,name=repeated_timestamp,json=repeatedTimestamp" json:"repeated_timestamp,omitempty"`
-	RepeatedFieldmask     []*google_protobuf2.FieldMask   `protobuf:"bytes,313,rep,name=repeated_fieldmask,json=repeatedFieldmask" json:"repeated_fieldmask,omitempty"`
-	RepeatedStruct        []*google_protobuf3.Struct      `protobuf:"bytes,324,rep,name=repeated_struct,json=repeatedStruct" json:"repeated_struct,omitempty"`
-	RepeatedAny           []*google_protobuf.Any          `protobuf:"bytes,315,rep,name=repeated_any,json=repeatedAny" json:"repeated_any,omitempty"`
-	RepeatedValue         []*google_protobuf3.Value       `protobuf:"bytes,316,rep,name=repeated_value,json=repeatedValue" json:"repeated_value,omitempty"`
-	// Test field-name-to-JSON-name convention.
-	// (protobuf says names can be any valid C/C++ identifier.)
-	Fieldname1    int32 `protobuf:"varint,401,opt,name=fieldname1" json:"fieldname1,omitempty"`
-	FieldName2    int32 `protobuf:"varint,402,opt,name=field_name2,json=fieldName2" json:"field_name2,omitempty"`
-	XFieldName3   int32 `protobuf:"varint,403,opt,name=_field_name3,json=FieldName3" json:"_field_name3,omitempty"`
-	Field_Name4_  int32 `protobuf:"varint,404,opt,name=field__name4_,json=fieldName4" json:"field__name4_,omitempty"`
-	Field0Name5   int32 `protobuf:"varint,405,opt,name=field0name5" json:"field0name5,omitempty"`
-	Field_0Name6  int32 `protobuf:"varint,406,opt,name=field_0_name6,json=field0Name6" json:"field_0_name6,omitempty"`
-	FieldName7    int32 `protobuf:"varint,407,opt,name=fieldName7" json:"fieldName7,omitempty"`
-	FieldName8    int32 `protobuf:"varint,408,opt,name=FieldName8" json:"FieldName8,omitempty"`
-	Field_Name9   int32 `protobuf:"varint,409,opt,name=field_Name9,json=fieldName9" json:"field_Name9,omitempty"`
-	Field_Name10  int32 `protobuf:"varint,410,opt,name=Field_Name10,json=FieldName10" json:"Field_Name10,omitempty"`
-	FIELD_NAME11  int32 `protobuf:"varint,411,opt,name=FIELD_NAME11,json=FIELDNAME11" json:"FIELD_NAME11,omitempty"`
-	FIELDName12   int32 `protobuf:"varint,412,opt,name=FIELD_name12,json=FIELDName12" json:"FIELD_name12,omitempty"`
-	XFieldName13  int32 `protobuf:"varint,413,opt,name=__field_name13,json=FieldName13" json:"__field_name13,omitempty"`
-	X_FieldName14 int32 `protobuf:"varint,414,opt,name=__Field_name14,json=FieldName14" json:"__Field_name14,omitempty"`
-	Field_Name15  int32 `protobuf:"varint,415,opt,name=field__name15,json=fieldName15" json:"field__name15,omitempty"`
-	Field__Name16 int32 `protobuf:"varint,416,opt,name=field__Name16,json=fieldName16" json:"field__Name16,omitempty"`
-	FieldName17__ int32 `protobuf:"varint,417,opt,name=field_name17__,json=fieldName17" json:"field_name17__,omitempty"`
-	FieldName18__ int32 `protobuf:"varint,418,opt,name=Field_name18__,json=FieldName18" json:"Field_name18__,omitempty"`
-}
-
-func (m *TestAllTypes) Reset()                    { *m = TestAllTypes{} }
-func (m *TestAllTypes) String() string            { return proto.CompactTextString(m) }
-func (*TestAllTypes) ProtoMessage()               {}
-func (*TestAllTypes) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
-
-type isTestAllTypes_OneofField interface {
-	isTestAllTypes_OneofField()
-}
-
-type TestAllTypes_OneofUint32 struct {
-	OneofUint32 uint32 `protobuf:"varint,111,opt,name=oneof_uint32,json=oneofUint32,oneof"`
-}
-type TestAllTypes_OneofNestedMessage struct {
-	OneofNestedMessage *TestAllTypes_NestedMessage `protobuf:"bytes,112,opt,name=oneof_nested_message,json=oneofNestedMessage,oneof"`
-}
-type TestAllTypes_OneofString struct {
-	OneofString string `protobuf:"bytes,113,opt,name=oneof_string,json=oneofString,oneof"`
-}
-type TestAllTypes_OneofBytes struct {
-	OneofBytes []byte `protobuf:"bytes,114,opt,name=oneof_bytes,json=oneofBytes,proto3,oneof"`
-}
-type TestAllTypes_OneofBool struct {
-	OneofBool bool `protobuf:"varint,115,opt,name=oneof_bool,json=oneofBool,oneof"`
-}
-type TestAllTypes_OneofUint64 struct {
-	OneofUint64 uint64 `protobuf:"varint,116,opt,name=oneof_uint64,json=oneofUint64,oneof"`
-}
-type TestAllTypes_OneofFloat struct {
-	OneofFloat float32 `protobuf:"fixed32,117,opt,name=oneof_float,json=oneofFloat,oneof"`
-}
-type TestAllTypes_OneofDouble struct {
-	OneofDouble float64 `protobuf:"fixed64,118,opt,name=oneof_double,json=oneofDouble,oneof"`
-}
-type TestAllTypes_OneofEnum struct {
-	OneofEnum TestAllTypes_NestedEnum `protobuf:"varint,119,opt,name=oneof_enum,json=oneofEnum,enum=conformance.TestAllTypes_NestedEnum,oneof"`
-}
-
-func (*TestAllTypes_OneofUint32) isTestAllTypes_OneofField()        {}
-func (*TestAllTypes_OneofNestedMessage) isTestAllTypes_OneofField() {}
-func (*TestAllTypes_OneofString) isTestAllTypes_OneofField()        {}
-func (*TestAllTypes_OneofBytes) isTestAllTypes_OneofField()         {}
-func (*TestAllTypes_OneofBool) isTestAllTypes_OneofField()          {}
-func (*TestAllTypes_OneofUint64) isTestAllTypes_OneofField()        {}
-func (*TestAllTypes_OneofFloat) isTestAllTypes_OneofField()         {}
-func (*TestAllTypes_OneofDouble) isTestAllTypes_OneofField()        {}
-func (*TestAllTypes_OneofEnum) isTestAllTypes_OneofField()          {}
-
-func (m *TestAllTypes) GetOneofField() isTestAllTypes_OneofField {
-	if m != nil {
-		return m.OneofField
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalInt32() int32 {
-	if m != nil {
-		return m.OptionalInt32
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOptionalInt64() int64 {
-	if m != nil {
-		return m.OptionalInt64
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOptionalUint32() uint32 {
-	if m != nil {
-		return m.OptionalUint32
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOptionalUint64() uint64 {
-	if m != nil {
-		return m.OptionalUint64
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOptionalSint32() int32 {
-	if m != nil {
-		return m.OptionalSint32
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOptionalSint64() int64 {
-	if m != nil {
-		return m.OptionalSint64
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOptionalFixed32() uint32 {
-	if m != nil {
-		return m.OptionalFixed32
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOptionalFixed64() uint64 {
-	if m != nil {
-		return m.OptionalFixed64
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOptionalSfixed32() int32 {
-	if m != nil {
-		return m.OptionalSfixed32
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOptionalSfixed64() int64 {
-	if m != nil {
-		return m.OptionalSfixed64
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOptionalFloat() float32 {
-	if m != nil {
-		return m.OptionalFloat
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOptionalDouble() float64 {
-	if m != nil {
-		return m.OptionalDouble
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOptionalBool() bool {
-	if m != nil {
-		return m.OptionalBool
-	}
-	return false
-}
-
-func (m *TestAllTypes) GetOptionalString() string {
-	if m != nil {
-		return m.OptionalString
-	}
-	return ""
-}
-
-func (m *TestAllTypes) GetOptionalBytes() []byte {
-	if m != nil {
-		return m.OptionalBytes
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalNestedMessage() *TestAllTypes_NestedMessage {
-	if m != nil {
-		return m.OptionalNestedMessage
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalForeignMessage() *ForeignMessage {
-	if m != nil {
-		return m.OptionalForeignMessage
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalNestedEnum() TestAllTypes_NestedEnum {
-	if m != nil {
-		return m.OptionalNestedEnum
-	}
-	return TestAllTypes_FOO
-}
-
-func (m *TestAllTypes) GetOptionalForeignEnum() ForeignEnum {
-	if m != nil {
-		return m.OptionalForeignEnum
-	}
-	return ForeignEnum_FOREIGN_FOO
-}
-
-func (m *TestAllTypes) GetOptionalStringPiece() string {
-	if m != nil {
-		return m.OptionalStringPiece
-	}
-	return ""
-}
-
-func (m *TestAllTypes) GetOptionalCord() string {
-	if m != nil {
-		return m.OptionalCord
-	}
-	return ""
-}
-
-func (m *TestAllTypes) GetRecursiveMessage() *TestAllTypes {
-	if m != nil {
-		return m.RecursiveMessage
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedInt32() []int32 {
-	if m != nil {
-		return m.RepeatedInt32
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedInt64() []int64 {
-	if m != nil {
-		return m.RepeatedInt64
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedUint32() []uint32 {
-	if m != nil {
-		return m.RepeatedUint32
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedUint64() []uint64 {
-	if m != nil {
-		return m.RepeatedUint64
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedSint32() []int32 {
-	if m != nil {
-		return m.RepeatedSint32
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedSint64() []int64 {
-	if m != nil {
-		return m.RepeatedSint64
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedFixed32() []uint32 {
-	if m != nil {
-		return m.RepeatedFixed32
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedFixed64() []uint64 {
-	if m != nil {
-		return m.RepeatedFixed64
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedSfixed32() []int32 {
-	if m != nil {
-		return m.RepeatedSfixed32
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedSfixed64() []int64 {
-	if m != nil {
-		return m.RepeatedSfixed64
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedFloat() []float32 {
-	if m != nil {
-		return m.RepeatedFloat
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedDouble() []float64 {
-	if m != nil {
-		return m.RepeatedDouble
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedBool() []bool {
-	if m != nil {
-		return m.RepeatedBool
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedString() []string {
-	if m != nil {
-		return m.RepeatedString
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedBytes() [][]byte {
-	if m != nil {
-		return m.RepeatedBytes
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedNestedMessage() []*TestAllTypes_NestedMessage {
-	if m != nil {
-		return m.RepeatedNestedMessage
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedForeignMessage() []*ForeignMessage {
-	if m != nil {
-		return m.RepeatedForeignMessage
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedNestedEnum() []TestAllTypes_NestedEnum {
-	if m != nil {
-		return m.RepeatedNestedEnum
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedForeignEnum() []ForeignEnum {
-	if m != nil {
-		return m.RepeatedForeignEnum
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedStringPiece() []string {
-	if m != nil {
-		return m.RepeatedStringPiece
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedCord() []string {
-	if m != nil {
-		return m.RepeatedCord
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapInt32Int32() map[int32]int32 {
-	if m != nil {
-		return m.MapInt32Int32
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapInt64Int64() map[int64]int64 {
-	if m != nil {
-		return m.MapInt64Int64
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapUint32Uint32() map[uint32]uint32 {
-	if m != nil {
-		return m.MapUint32Uint32
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapUint64Uint64() map[uint64]uint64 {
-	if m != nil {
-		return m.MapUint64Uint64
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapSint32Sint32() map[int32]int32 {
-	if m != nil {
-		return m.MapSint32Sint32
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapSint64Sint64() map[int64]int64 {
-	if m != nil {
-		return m.MapSint64Sint64
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapFixed32Fixed32() map[uint32]uint32 {
-	if m != nil {
-		return m.MapFixed32Fixed32
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapFixed64Fixed64() map[uint64]uint64 {
-	if m != nil {
-		return m.MapFixed64Fixed64
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapSfixed32Sfixed32() map[int32]int32 {
-	if m != nil {
-		return m.MapSfixed32Sfixed32
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapSfixed64Sfixed64() map[int64]int64 {
-	if m != nil {
-		return m.MapSfixed64Sfixed64
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapInt32Float() map[int32]float32 {
-	if m != nil {
-		return m.MapInt32Float
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapInt32Double() map[int32]float64 {
-	if m != nil {
-		return m.MapInt32Double
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapBoolBool() map[bool]bool {
-	if m != nil {
-		return m.MapBoolBool
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapStringString() map[string]string {
-	if m != nil {
-		return m.MapStringString
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapStringBytes() map[string][]byte {
-	if m != nil {
-		return m.MapStringBytes
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapStringNestedMessage() map[string]*TestAllTypes_NestedMessage {
-	if m != nil {
-		return m.MapStringNestedMessage
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapStringForeignMessage() map[string]*ForeignMessage {
-	if m != nil {
-		return m.MapStringForeignMessage
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapStringNestedEnum() map[string]TestAllTypes_NestedEnum {
-	if m != nil {
-		return m.MapStringNestedEnum
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetMapStringForeignEnum() map[string]ForeignEnum {
-	if m != nil {
-		return m.MapStringForeignEnum
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOneofUint32() uint32 {
-	if x, ok := m.GetOneofField().(*TestAllTypes_OneofUint32); ok {
-		return x.OneofUint32
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOneofNestedMessage() *TestAllTypes_NestedMessage {
-	if x, ok := m.GetOneofField().(*TestAllTypes_OneofNestedMessage); ok {
-		return x.OneofNestedMessage
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOneofString() string {
-	if x, ok := m.GetOneofField().(*TestAllTypes_OneofString); ok {
-		return x.OneofString
-	}
-	return ""
-}
-
-func (m *TestAllTypes) GetOneofBytes() []byte {
-	if x, ok := m.GetOneofField().(*TestAllTypes_OneofBytes); ok {
-		return x.OneofBytes
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOneofBool() bool {
-	if x, ok := m.GetOneofField().(*TestAllTypes_OneofBool); ok {
-		return x.OneofBool
-	}
-	return false
-}
-
-func (m *TestAllTypes) GetOneofUint64() uint64 {
-	if x, ok := m.GetOneofField().(*TestAllTypes_OneofUint64); ok {
-		return x.OneofUint64
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOneofFloat() float32 {
-	if x, ok := m.GetOneofField().(*TestAllTypes_OneofFloat); ok {
-		return x.OneofFloat
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOneofDouble() float64 {
-	if x, ok := m.GetOneofField().(*TestAllTypes_OneofDouble); ok {
-		return x.OneofDouble
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetOneofEnum() TestAllTypes_NestedEnum {
-	if x, ok := m.GetOneofField().(*TestAllTypes_OneofEnum); ok {
-		return x.OneofEnum
-	}
-	return TestAllTypes_FOO
-}
-
-func (m *TestAllTypes) GetOptionalBoolWrapper() *google_protobuf5.BoolValue {
-	if m != nil {
-		return m.OptionalBoolWrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalInt32Wrapper() *google_protobuf5.Int32Value {
-	if m != nil {
-		return m.OptionalInt32Wrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalInt64Wrapper() *google_protobuf5.Int64Value {
-	if m != nil {
-		return m.OptionalInt64Wrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalUint32Wrapper() *google_protobuf5.UInt32Value {
-	if m != nil {
-		return m.OptionalUint32Wrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalUint64Wrapper() *google_protobuf5.UInt64Value {
-	if m != nil {
-		return m.OptionalUint64Wrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalFloatWrapper() *google_protobuf5.FloatValue {
-	if m != nil {
-		return m.OptionalFloatWrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalDoubleWrapper() *google_protobuf5.DoubleValue {
-	if m != nil {
-		return m.OptionalDoubleWrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalStringWrapper() *google_protobuf5.StringValue {
-	if m != nil {
-		return m.OptionalStringWrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalBytesWrapper() *google_protobuf5.BytesValue {
-	if m != nil {
-		return m.OptionalBytesWrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedBoolWrapper() []*google_protobuf5.BoolValue {
-	if m != nil {
-		return m.RepeatedBoolWrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedInt32Wrapper() []*google_protobuf5.Int32Value {
-	if m != nil {
-		return m.RepeatedInt32Wrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedInt64Wrapper() []*google_protobuf5.Int64Value {
-	if m != nil {
-		return m.RepeatedInt64Wrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedUint32Wrapper() []*google_protobuf5.UInt32Value {
-	if m != nil {
-		return m.RepeatedUint32Wrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedUint64Wrapper() []*google_protobuf5.UInt64Value {
-	if m != nil {
-		return m.RepeatedUint64Wrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedFloatWrapper() []*google_protobuf5.FloatValue {
-	if m != nil {
-		return m.RepeatedFloatWrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedDoubleWrapper() []*google_protobuf5.DoubleValue {
-	if m != nil {
-		return m.RepeatedDoubleWrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedStringWrapper() []*google_protobuf5.StringValue {
-	if m != nil {
-		return m.RepeatedStringWrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedBytesWrapper() []*google_protobuf5.BytesValue {
-	if m != nil {
-		return m.RepeatedBytesWrapper
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalDuration() *google_protobuf1.Duration {
-	if m != nil {
-		return m.OptionalDuration
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalTimestamp() *google_protobuf4.Timestamp {
-	if m != nil {
-		return m.OptionalTimestamp
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalFieldMask() *google_protobuf2.FieldMask {
-	if m != nil {
-		return m.OptionalFieldMask
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalStruct() *google_protobuf3.Struct {
-	if m != nil {
-		return m.OptionalStruct
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalAny() *google_protobuf.Any {
-	if m != nil {
-		return m.OptionalAny
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetOptionalValue() *google_protobuf3.Value {
-	if m != nil {
-		return m.OptionalValue
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedDuration() []*google_protobuf1.Duration {
-	if m != nil {
-		return m.RepeatedDuration
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedTimestamp() []*google_protobuf4.Timestamp {
-	if m != nil {
-		return m.RepeatedTimestamp
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedFieldmask() []*google_protobuf2.FieldMask {
-	if m != nil {
-		return m.RepeatedFieldmask
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedStruct() []*google_protobuf3.Struct {
-	if m != nil {
-		return m.RepeatedStruct
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedAny() []*google_protobuf.Any {
-	if m != nil {
-		return m.RepeatedAny
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetRepeatedValue() []*google_protobuf3.Value {
-	if m != nil {
-		return m.RepeatedValue
-	}
-	return nil
-}
-
-func (m *TestAllTypes) GetFieldname1() int32 {
-	if m != nil {
-		return m.Fieldname1
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetFieldName2() int32 {
-	if m != nil {
-		return m.FieldName2
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetXFieldName3() int32 {
-	if m != nil {
-		return m.XFieldName3
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetField_Name4_() int32 {
-	if m != nil {
-		return m.Field_Name4_
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetField0Name5() int32 {
-	if m != nil {
-		return m.Field0Name5
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetField_0Name6() int32 {
-	if m != nil {
-		return m.Field_0Name6
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetFieldName7() int32 {
-	if m != nil {
-		return m.FieldName7
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetFieldName8() int32 {
-	if m != nil {
-		return m.FieldName8
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetField_Name9() int32 {
-	if m != nil {
-		return m.Field_Name9
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetField_Name10() int32 {
-	if m != nil {
-		return m.Field_Name10
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetFIELD_NAME11() int32 {
-	if m != nil {
-		return m.FIELD_NAME11
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetFIELDName12() int32 {
-	if m != nil {
-		return m.FIELDName12
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetXFieldName13() int32 {
-	if m != nil {
-		return m.XFieldName13
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetX_FieldName14() int32 {
-	if m != nil {
-		return m.X_FieldName14
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetField_Name15() int32 {
-	if m != nil {
-		return m.Field_Name15
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetField__Name16() int32 {
-	if m != nil {
-		return m.Field__Name16
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetFieldName17__() int32 {
-	if m != nil {
-		return m.FieldName17__
-	}
-	return 0
-}
-
-func (m *TestAllTypes) GetFieldName18__() int32 {
-	if m != nil {
-		return m.FieldName18__
-	}
-	return 0
-}
-
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*TestAllTypes) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
-	return _TestAllTypes_OneofMarshaler, _TestAllTypes_OneofUnmarshaler, _TestAllTypes_OneofSizer, []interface{}{
-		(*TestAllTypes_OneofUint32)(nil),
-		(*TestAllTypes_OneofNestedMessage)(nil),
-		(*TestAllTypes_OneofString)(nil),
-		(*TestAllTypes_OneofBytes)(nil),
-		(*TestAllTypes_OneofBool)(nil),
-		(*TestAllTypes_OneofUint64)(nil),
-		(*TestAllTypes_OneofFloat)(nil),
-		(*TestAllTypes_OneofDouble)(nil),
-		(*TestAllTypes_OneofEnum)(nil),
-	}
-}
-
-func _TestAllTypes_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*TestAllTypes)
-	// oneof_field
-	switch x := m.OneofField.(type) {
-	case *TestAllTypes_OneofUint32:
-		b.EncodeVarint(111<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.OneofUint32))
-	case *TestAllTypes_OneofNestedMessage:
-		b.EncodeVarint(112<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.OneofNestedMessage); err != nil {
-			return err
-		}
-	case *TestAllTypes_OneofString:
-		b.EncodeVarint(113<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.OneofString)
-	case *TestAllTypes_OneofBytes:
-		b.EncodeVarint(114<<3 | proto.WireBytes)
-		b.EncodeRawBytes(x.OneofBytes)
-	case *TestAllTypes_OneofBool:
-		t := uint64(0)
-		if x.OneofBool {
-			t = 1
-		}
-		b.EncodeVarint(115<<3 | proto.WireVarint)
-		b.EncodeVarint(t)
-	case *TestAllTypes_OneofUint64:
-		b.EncodeVarint(116<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.OneofUint64))
-	case *TestAllTypes_OneofFloat:
-		b.EncodeVarint(117<<3 | proto.WireFixed32)
-		b.EncodeFixed32(uint64(math.Float32bits(x.OneofFloat)))
-	case *TestAllTypes_OneofDouble:
-		b.EncodeVarint(118<<3 | proto.WireFixed64)
-		b.EncodeFixed64(math.Float64bits(x.OneofDouble))
-	case *TestAllTypes_OneofEnum:
-		b.EncodeVarint(119<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.OneofEnum))
-	case nil:
-	default:
-		return fmt.Errorf("TestAllTypes.OneofField has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _TestAllTypes_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*TestAllTypes)
-	switch tag {
-	case 111: // oneof_field.oneof_uint32
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofField = &TestAllTypes_OneofUint32{uint32(x)}
-		return true, err
-	case 112: // oneof_field.oneof_nested_message
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(TestAllTypes_NestedMessage)
-		err := b.DecodeMessage(msg)
-		m.OneofField = &TestAllTypes_OneofNestedMessage{msg}
-		return true, err
-	case 113: // oneof_field.oneof_string
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.OneofField = &TestAllTypes_OneofString{x}
-		return true, err
-	case 114: // oneof_field.oneof_bytes
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeRawBytes(true)
-		m.OneofField = &TestAllTypes_OneofBytes{x}
-		return true, err
-	case 115: // oneof_field.oneof_bool
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofField = &TestAllTypes_OneofBool{x != 0}
-		return true, err
-	case 116: // oneof_field.oneof_uint64
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofField = &TestAllTypes_OneofUint64{x}
-		return true, err
-	case 117: // oneof_field.oneof_float
-		if wire != proto.WireFixed32 {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeFixed32()
-		m.OneofField = &TestAllTypes_OneofFloat{math.Float32frombits(uint32(x))}
-		return true, err
-	case 118: // oneof_field.oneof_double
-		if wire != proto.WireFixed64 {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeFixed64()
-		m.OneofField = &TestAllTypes_OneofDouble{math.Float64frombits(x)}
-		return true, err
-	case 119: // oneof_field.oneof_enum
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofField = &TestAllTypes_OneofEnum{TestAllTypes_NestedEnum(x)}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _TestAllTypes_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*TestAllTypes)
-	// oneof_field
-	switch x := m.OneofField.(type) {
-	case *TestAllTypes_OneofUint32:
-		n += proto.SizeVarint(111<<3 | proto.WireVarint)
-		n += proto.SizeVarint(uint64(x.OneofUint32))
-	case *TestAllTypes_OneofNestedMessage:
-		s := proto.Size(x.OneofNestedMessage)
-		n += proto.SizeVarint(112<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case *TestAllTypes_OneofString:
-		n += proto.SizeVarint(113<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(len(x.OneofString)))
-		n += len(x.OneofString)
-	case *TestAllTypes_OneofBytes:
-		n += proto.SizeVarint(114<<3 | proto.WireBytes)
-		n += proto.SizeVarint(uint64(len(x.OneofBytes)))
-		n += len(x.OneofBytes)
-	case *TestAllTypes_OneofBool:
-		n += proto.SizeVarint(115<<3 | proto.WireVarint)
-		n += 1
-	case *TestAllTypes_OneofUint64:
-		n += proto.SizeVarint(116<<3 | proto.WireVarint)
-		n += proto.SizeVarint(uint64(x.OneofUint64))
-	case *TestAllTypes_OneofFloat:
-		n += proto.SizeVarint(117<<3 | proto.WireFixed32)
-		n += 4
-	case *TestAllTypes_OneofDouble:
-		n += proto.SizeVarint(118<<3 | proto.WireFixed64)
-		n += 8
-	case *TestAllTypes_OneofEnum:
-		n += proto.SizeVarint(119<<3 | proto.WireVarint)
-		n += proto.SizeVarint(uint64(x.OneofEnum))
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
-type TestAllTypes_NestedMessage struct {
-	A           int32         `protobuf:"varint,1,opt,name=a" json:"a,omitempty"`
-	Corecursive *TestAllTypes `protobuf:"bytes,2,opt,name=corecursive" json:"corecursive,omitempty"`
-}
-
-func (m *TestAllTypes_NestedMessage) Reset()                    { *m = TestAllTypes_NestedMessage{} }
-func (m *TestAllTypes_NestedMessage) String() string            { return proto.CompactTextString(m) }
-func (*TestAllTypes_NestedMessage) ProtoMessage()               {}
-func (*TestAllTypes_NestedMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 0} }
-
-func (m *TestAllTypes_NestedMessage) GetA() int32 {
-	if m != nil {
-		return m.A
-	}
-	return 0
-}
-
-func (m *TestAllTypes_NestedMessage) GetCorecursive() *TestAllTypes {
-	if m != nil {
-		return m.Corecursive
-	}
-	return nil
-}
-
-type ForeignMessage struct {
-	C int32 `protobuf:"varint,1,opt,name=c" json:"c,omitempty"`
-}
-
-func (m *ForeignMessage) Reset()                    { *m = ForeignMessage{} }
-func (m *ForeignMessage) String() string            { return proto.CompactTextString(m) }
-func (*ForeignMessage) ProtoMessage()               {}
-func (*ForeignMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
-
-func (m *ForeignMessage) GetC() int32 {
-	if m != nil {
-		return m.C
-	}
-	return 0
-}
-
-func init() {
-	proto.RegisterType((*ConformanceRequest)(nil), "conformance.ConformanceRequest")
-	proto.RegisterType((*ConformanceResponse)(nil), "conformance.ConformanceResponse")
-	proto.RegisterType((*TestAllTypes)(nil), "conformance.TestAllTypes")
-	proto.RegisterType((*TestAllTypes_NestedMessage)(nil), "conformance.TestAllTypes.NestedMessage")
-	proto.RegisterType((*ForeignMessage)(nil), "conformance.ForeignMessage")
-	proto.RegisterEnum("conformance.WireFormat", WireFormat_name, WireFormat_value)
-	proto.RegisterEnum("conformance.ForeignEnum", ForeignEnum_name, ForeignEnum_value)
-	proto.RegisterEnum("conformance.TestAllTypes_NestedEnum", TestAllTypes_NestedEnum_name, TestAllTypes_NestedEnum_value)
-}
-
-func init() { proto.RegisterFile("conformance_proto/conformance.proto", fileDescriptor0) }
-
-var fileDescriptor0 = []byte{
-	// 2737 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x5a, 0xd9, 0x72, 0xdb, 0xc8,
-	0xd5, 0x16, 0x08, 0x59, 0x4b, 0x93, 0x92, 0xa8, 0xd6, 0xd6, 0x96, 0x5d, 0x63, 0x58, 0xb2, 0x7f,
-	0xd3, 0xf6, 0x8c, 0xac, 0x05, 0x86, 0x65, 0xcf, 0x3f, 0x8e, 0x45, 0x9b, 0xb4, 0xe4, 0x8c, 0x25,
-	0x17, 0x64, 0x8d, 0xab, 0x9c, 0x0b, 0x06, 0xa6, 0x20, 0x15, 0xc7, 0x24, 0xc1, 0x01, 0x48, 0x4f,
-	0x94, 0xcb, 0xbc, 0x41, 0xf6, 0x7d, 0xbd, 0xcf, 0x7a, 0x93, 0xa4, 0x92, 0xab, 0x54, 0x6e, 0xb2,
-	0x27, 0x95, 0x3d, 0x79, 0x85, 0xbc, 0x43, 0x52, 0xbd, 0xa2, 0xbb, 0x01, 0x50, 0xf4, 0x54, 0x0d,
-	0x25, 0x1e, 0x7c, 0xfd, 0x9d, 0xd3, 0xe7, 0x1c, 0x7c, 0x2d, 0x1c, 0x18, 0x2c, 0xd7, 0x83, 0xf6,
-	0x51, 0x10, 0xb6, 0xbc, 0x76, 0xdd, 0xaf, 0x75, 0xc2, 0xa0, 0x1b, 0xdc, 0x90, 0x2c, 0x2b, 0xc4,
-	0x02, 0xf3, 0x92, 0x69, 0xf1, 0xec, 0x71, 0x10, 0x1c, 0x37, 0xfd, 0x1b, 0xe4, 0xd2, 0x8b, 0xde,
-	0xd1, 0x0d, 0xaf, 0x7d, 0x42, 0x71, 0x8b, 0x6f, 0xe8, 0x97, 0x0e, 0x7b, 0xa1, 0xd7, 0x6d, 0x04,
-	0x6d, 0x76, 0xdd, 0xd2, 0xaf, 0x1f, 0x35, 0xfc, 0xe6, 0x61, 0xad, 0xe5, 0x45, 0x2f, 0x19, 0xe2,
-	0xbc, 0x8e, 0x88, 0xba, 0x61, 0xaf, 0xde, 0x65, 0x57, 0x2f, 0xe8, 0x57, 0xbb, 0x8d, 0x96, 0x1f,
-	0x75, 0xbd, 0x56, 0x27, 0x2b, 0x80, 0x0f, 0x43, 0xaf, 0xd3, 0xf1, 0xc3, 0x88, 0x5e, 0x5f, 0xfa,
-	0x85, 0x01, 0xe0, 0xfd, 0x78, 0x2f, 0xae, 0xff, 0x41, 0xcf, 0x8f, 0xba, 0xf0, 0x3a, 0x28, 0xf2,
-	0x15, 0xb5, 0x8e, 0x77, 0xd2, 0x0c, 0xbc, 0x43, 0x64, 0x58, 0x46, 0xa9, 0xb0, 0x3d, 0xe4, 0x4e,
-	0xf1, 0x2b, 0x4f, 0xe8, 0x05, 0xb8, 0x0c, 0x0a, 0xef, 0x47, 0x41, 0x5b, 0x00, 0x73, 0x96, 0x51,
-	0x1a, 0xdf, 0x1e, 0x72, 0xf3, 0xd8, 0xca, 0x41, 0x7b, 0x60, 0x21, 0xa4, 0xe4, 0xfe, 0x61, 0x2d,
-	0xe8, 0x75, 0x3b, 0xbd, 0x6e, 0x8d, 0x78, 0xed, 0x22, 0xd3, 0x32, 0x4a, 0x93, 0xeb, 0x0b, 0x2b,
-	0x72, 0x9a, 0x9f, 0x35, 0x42, 0xbf, 0x4a, 0x2e, 0xbb, 0x73, 0x62, 0xdd, 0x1e, 0x59, 0x46, 0xcd,
-	0xe5, 0x71, 0x30, 0xca, 0x1c, 0x2e, 0x7d, 0x2a, 0x07, 0x66, 0x94, 0x4d, 0x44, 0x9d, 0xa0, 0x1d,
-	0xf9, 0xf0, 0x22, 0xc8, 0x77, 0xbc, 0x30, 0xf2, 0x6b, 0x7e, 0x18, 0x06, 0x21, 0xd9, 0x00, 0x8e,
-	0x0b, 0x10, 0x63, 0x05, 0xdb, 0xe0, 0x55, 0x30, 0x15, 0xf9, 0x61, 0xc3, 0x6b, 0x36, 0x3e, 0xc9,
-	0x61, 0x23, 0x0c, 0x36, 0x29, 0x2e, 0x50, 0xe8, 0x65, 0x30, 0x11, 0xf6, 0xda, 0x38, 0xc1, 0x0c,
-	0xc8, 0xf7, 0x59, 0x60, 0x66, 0x0a, 0x4b, 0x4b, 0x9d, 0x39, 0x68, 0xea, 0x86, 0xd3, 0x52, 0xb7,
-	0x08, 0x46, 0xa3, 0x97, 0x8d, 0x4e, 0xc7, 0x3f, 0x44, 0x67, 0xd8, 0x75, 0x6e, 0x28, 0x8f, 0x81,
-	0x91, 0xd0, 0x8f, 0x7a, 0xcd, 0xee, 0xd2, 0x7f, 0xaa, 0xa0, 0xf0, 0xd4, 0x8f, 0xba, 0x5b, 0xcd,
-	0xe6, 0xd3, 0x93, 0x8e, 0x1f, 0xc1, 0xcb, 0x60, 0x32, 0xe8, 0xe0, 0x5e, 0xf3, 0x9a, 0xb5, 0x46,
-	0xbb, 0xbb, 0xb1, 0x4e, 0x12, 0x70, 0xc6, 0x9d, 0xe0, 0xd6, 0x1d, 0x6c, 0xd4, 0x61, 0x8e, 0x4d,
-	0xf6, 0x65, 0x2a, 0x30, 0xc7, 0x86, 0x57, 0xc0, 0x94, 0x80, 0xf5, 0x28, 0x1d, 0xde, 0xd5, 0x84,
-	0x2b, 0x56, 0x1f, 0x10, 0x6b, 0x02, 0xe8, 0xd8, 0x64, 0x57, 0xc3, 0x2a, 0x50, 0x63, 0x8c, 0x28,
-	0x23, 0xde, 0xde, 0x74, 0x0c, 0xdc, 0x4f, 0x32, 0x46, 0x94, 0x11, 0xd7, 0x08, 0xaa, 0x40, 0xc7,
-	0x86, 0x57, 0x41, 0x51, 0x00, 0x8f, 0x1a, 0x9f, 0xf0, 0x0f, 0x37, 0xd6, 0xd1, 0xa8, 0x65, 0x94,
-	0x46, 0x5d, 0x41, 0x50, 0xa5, 0xe6, 0x24, 0xd4, 0xb1, 0xd1, 0x98, 0x65, 0x94, 0x46, 0x34, 0xa8,
-	0x63, 0xc3, 0xeb, 0x60, 0x3a, 0x76, 0xcf, 0x69, 0xc7, 0x2d, 0xa3, 0x34, 0xe5, 0x0a, 0x8e, 0x7d,
-	0x66, 0x4f, 0x01, 0x3b, 0x36, 0x02, 0x96, 0x51, 0x2a, 0xea, 0x60, 0xc7, 0x56, 0x52, 0x7f, 0xd4,
-	0x0c, 0xbc, 0x2e, 0xca, 0x5b, 0x46, 0x29, 0x17, 0xa7, 0xbe, 0x8a, 0x8d, 0xca, 0xfe, 0x0f, 0x83,
-	0xde, 0x8b, 0xa6, 0x8f, 0x0a, 0x96, 0x51, 0x32, 0xe2, 0xfd, 0x3f, 0x20, 0x56, 0xb8, 0x0c, 0xc4,
-	0xca, 0xda, 0x8b, 0x20, 0x68, 0xa2, 0x09, 0xcb, 0x28, 0x8d, 0xb9, 0x05, 0x6e, 0x2c, 0x07, 0x41,
-	0x53, 0xcd, 0x66, 0x37, 0x6c, 0xb4, 0x8f, 0xd1, 0x24, 0xee, 0x2a, 0x29, 0x9b, 0xc4, 0xaa, 0x44,
-	0xf7, 0xe2, 0xa4, 0xeb, 0x47, 0x68, 0x0a, 0xb7, 0x71, 0x1c, 0x5d, 0x19, 0x1b, 0x61, 0x0d, 0x2c,
-	0x08, 0x58, 0x9b, 0xde, 0xde, 0x2d, 0x3f, 0x8a, 0xbc, 0x63, 0x1f, 0x41, 0xcb, 0x28, 0xe5, 0xd7,
-	0xaf, 0x28, 0x37, 0xb6, 0xdc, 0xa2, 0x2b, 0xbb, 0x04, 0xff, 0x98, 0xc2, 0xdd, 0x39, 0xce, 0xa3,
-	0x98, 0xe1, 0x01, 0x40, 0x71, 0x96, 0x82, 0xd0, 0x6f, 0x1c, 0xb7, 0x85, 0x87, 0x19, 0xe2, 0xe1,
-	0x9c, 0xe2, 0xa1, 0x4a, 0x31, 0x9c, 0x75, 0x5e, 0x24, 0x53, 0xb1, 0xc3, 0xf7, 0xc0, 0xac, 0x1e,
-	0xb7, 0xdf, 0xee, 0xb5, 0xd0, 0x1c, 0x51, 0xa3, 0x4b, 0xa7, 0x05, 0x5d, 0x69, 0xf7, 0x5a, 0x2e,
-	0x54, 0x23, 0xc6, 0x36, 0xf8, 0x2e, 0x98, 0x4b, 0x84, 0x4b, 0x88, 0xe7, 0x09, 0x31, 0x4a, 0x8b,
-	0x95, 0x90, 0xcd, 0x68, 0x81, 0x12, 0x36, 0x47, 0x62, 0xa3, 0xd5, 0xaa, 0x75, 0x1a, 0x7e, 0xdd,
-	0x47, 0x08, 0xd7, 0xac, 0x9c, 0x1b, 0xcb, 0xc5, 0xeb, 0x68, 0xdd, 0x9e, 0xe0, 0xcb, 0xf0, 0x8a,
-	0xd4, 0x0a, 0xf5, 0x20, 0x3c, 0x44, 0x67, 0x19, 0xde, 0x88, 0xdb, 0xe1, 0x7e, 0x10, 0x1e, 0xc2,
-	0x2a, 0x98, 0x0e, 0xfd, 0x7a, 0x2f, 0x8c, 0x1a, 0xaf, 0x7c, 0x91, 0xd6, 0x73, 0x24, 0xad, 0x67,
-	0x33, 0x73, 0xe0, 0x16, 0xc5, 0x1a, 0x9e, 0xce, 0xcb, 0x60, 0x32, 0xf4, 0x3b, 0xbe, 0x87, 0xf3,
-	0x48, 0x6f, 0xe6, 0x0b, 0x96, 0x89, 0xd5, 0x86, 0x5b, 0x85, 0xda, 0xc8, 0x30, 0xc7, 0x46, 0x96,
-	0x65, 0x62, 0xb5, 0x91, 0x60, 0x54, 0x1b, 0x04, 0x8c, 0xa9, 0xcd, 0x45, 0xcb, 0xc4, 0x6a, 0xc3,
-	0xcd, 0xb1, 0xda, 0x28, 0x40, 0xc7, 0x46, 0x4b, 0x96, 0x89, 0xd5, 0x46, 0x06, 0x6a, 0x8c, 0x4c,
-	0x6d, 0x96, 0x2d, 0x13, 0xab, 0x0d, 0x37, 0xef, 0x27, 0x19, 0x99, 0xda, 0x5c, 0xb2, 0x4c, 0xac,
-	0x36, 0x32, 0x90, 0xaa, 0x8d, 0x00, 0x72, 0x59, 0xb8, 0x6c, 0x99, 0x58, 0x6d, 0xb8, 0x5d, 0x52,
-	0x1b, 0x15, 0xea, 0xd8, 0xe8, 0xff, 0x2c, 0x13, 0xab, 0x8d, 0x02, 0xa5, 0x6a, 0x13, 0xbb, 0xe7,
-	0xb4, 0x57, 0x2c, 0x13, 0xab, 0x8d, 0x08, 0x40, 0x52, 0x1b, 0x0d, 0xec, 0xd8, 0xa8, 0x64, 0x99,
-	0x58, 0x6d, 0x54, 0x30, 0x55, 0x9b, 0x38, 0x08, 0xa2, 0x36, 0x57, 0x2d, 0x13, 0xab, 0x8d, 0x08,
-	0x81, 0xab, 0x8d, 0x80, 0x31, 0xb5, 0xb9, 0x66, 0x99, 0x58, 0x6d, 0xb8, 0x39, 0x56, 0x1b, 0x01,
-	0x24, 0x6a, 0x73, 0xdd, 0x32, 0xb1, 0xda, 0x70, 0x23, 0x57, 0x9b, 0x38, 0x42, 0xaa, 0x36, 0x6f,
-	0x5a, 0x26, 0x56, 0x1b, 0x11, 0x9f, 0x50, 0x9b, 0x98, 0x8d, 0xa8, 0xcd, 0x5b, 0x96, 0x89, 0xd5,
-	0x46, 0xd0, 0x71, 0xb5, 0x11, 0x30, 0x4d, 0x6d, 0x56, 0x2d, 0xf3, 0xb5, 0xd4, 0x86, 0xf3, 0x24,
-	0xd4, 0x26, 0xce, 0x92, 0xa6, 0x36, 0x6b, 0xc4, 0x43, 0x7f, 0xb5, 0x11, 0xc9, 0x4c, 0xa8, 0x8d,
-	0x1e, 0x37, 0x11, 0x85, 0x0d, 0xcb, 0x1c, 0x5c, 0x6d, 0xd4, 0x88, 0xb9, 0xda, 0x24, 0xc2, 0x25,
-	0xc4, 0x36, 0x21, 0xee, 0xa3, 0x36, 0x5a, 0xa0, 0x5c, 0x6d, 0xb4, 0x6a, 0x31, 0xb5, 0x71, 0x70,
-	0xcd, 0xa8, 0xda, 0xa8, 0x75, 0x13, 0x6a, 0x23, 0xd6, 0x11, 0xb5, 0xb9, 0xc5, 0xf0, 0x46, 0xdc,
-	0x0e, 0x44, 0x6d, 0x9e, 0x82, 0xa9, 0x96, 0xd7, 0xa1, 0x02, 0xc1, 0x64, 0x62, 0x93, 0x24, 0xf5,
-	0xcd, 0xec, 0x0c, 0x3c, 0xf6, 0x3a, 0x44, 0x3b, 0xc8, 0x47, 0xa5, 0xdd, 0x0d, 0x4f, 0xdc, 0x89,
-	0x96, 0x6c, 0x93, 0x58, 0x1d, 0x9b, 0xa9, 0xca, 0xed, 0xc1, 0x58, 0x1d, 0x9b, 0x7c, 0x28, 0xac,
-	0xcc, 0x06, 0x9f, 0x83, 0x69, 0xcc, 0x4a, 0xe5, 0x87, 0xab, 0xd0, 0x1d, 0xc2, 0xbb, 0xd2, 0x97,
-	0x97, 0x4a, 0x13, 0xfd, 0xa4, 0xcc, 0x38, 0x3c, 0xd9, 0x2a, 0x73, 0x3b, 0x36, 0x17, 0xae, 0xb7,
-	0x07, 0xe4, 0x76, 0x6c, 0xfa, 0xa9, 0x72, 0x73, 0x2b, 0xe7, 0xa6, 0x22, 0xc7, 0xb5, 0xee, 0xff,
-	0x07, 0xe0, 0xa6, 0x02, 0xb8, 0xaf, 0xc5, 0x2d, 0x5b, 0x65, 0x6e, 0xc7, 0xe6, 0xf2, 0xf8, 0xce,
-	0x80, 0xdc, 0x8e, 0xbd, 0xaf, 0xc5, 0x2d, 0x5b, 0xe1, 0xc7, 0xc1, 0x0c, 0xe6, 0x66, 0xda, 0x26,
-	0x24, 0xf5, 0x2e, 0x61, 0x5f, 0xed, 0xcb, 0xce, 0x74, 0x96, 0xfd, 0xa0, 0xfc, 0x38, 0x50, 0xd5,
-	0xae, 0x78, 0x70, 0x6c, 0xa1, 0xc4, 0x1f, 0x19, 0xd4, 0x83, 0x63, 0xb3, 0x1f, 0x9a, 0x07, 0x61,
-	0x87, 0x47, 0x60, 0x8e, 0xe4, 0x87, 0x6f, 0x42, 0x28, 0xf8, 0x3d, 0xe2, 0x63, 0xbd, 0x7f, 0x8e,
-	0x18, 0x98, 0xff, 0xa4, 0x5e, 0x70, 0xc8, 0xfa, 0x15, 0xd5, 0x0f, 0xae, 0x04, 0xdf, 0xcb, 0xd6,
-	0xc0, 0x7e, 0x1c, 0x9b, 0xff, 0xd4, 0xfd, 0xc4, 0x57, 0xd4, 0xfb, 0x95, 0x1e, 0x1a, 0xe5, 0x41,
-	0xef, 0x57, 0x72, 0x9c, 0x68, 0xf7, 0x2b, 0x3d, 0x62, 0x9e, 0x81, 0x62, 0xcc, 0xca, 0xce, 0x98,
-	0xfb, 0x84, 0xf6, 0xad, 0xd3, 0x69, 0xe9, 0xe9, 0x43, 0x79, 0x27, 0x5b, 0x8a, 0x11, 0xee, 0x02,
-	0xec, 0x89, 0x9c, 0x46, 0xf4, 0x48, 0x7a, 0x40, 0x58, 0xaf, 0xf5, 0x65, 0xc5, 0xe7, 0x14, 0xfe,
-	0x9f, 0x52, 0xe6, 0x5b, 0xb1, 0x45, 0xb4, 0x3b, 0x95, 0x42, 0x76, 0x7e, 0x55, 0x06, 0x69, 0x77,
-	0x02, 0xa5, 0x9f, 0x52, 0xbb, 0x4b, 0x56, 0x9e, 0x04, 0xc6, 0x4d, 0x8f, 0xbc, 0xea, 0x00, 0x49,
-	0xa0, 0xcb, 0xc9, 0x69, 0x18, 0x27, 0x41, 0x32, 0xc2, 0x0e, 0x38, 0x2b, 0x11, 0x6b, 0x87, 0xe4,
-	0x43, 0xe2, 0xe1, 0xe6, 0x00, 0x1e, 0x94, 0x63, 0x91, 0x7a, 0x9a, 0x6f, 0xa5, 0x5e, 0x84, 0x11,
-	0x58, 0x94, 0x3c, 0xea, 0xa7, 0xe6, 0x36, 0x71, 0xe9, 0x0c, 0xe0, 0x52, 0x3d, 0x33, 0xa9, 0xcf,
-	0x85, 0x56, 0xfa, 0x55, 0x78, 0x0c, 0xe6, 0x93, 0xdb, 0x24, 0x47, 0xdf, 0xce, 0x20, 0xf7, 0x80,
-	0xb4, 0x0d, 0x7c, 0xf4, 0x49, 0xf7, 0x80, 0x76, 0x05, 0xbe, 0x0f, 0x16, 0x52, 0x76, 0x47, 0x3c,
-	0x3d, 0x22, 0x9e, 0x36, 0x06, 0xdf, 0x5a, 0xec, 0x6a, 0xb6, 0x95, 0x72, 0x09, 0x2e, 0x83, 0x42,
-	0xd0, 0xf6, 0x83, 0x23, 0x7e, 0xdc, 0x04, 0xf8, 0x11, 0x7b, 0x7b, 0xc8, 0xcd, 0x13, 0x2b, 0x3b,
-	0x3c, 0x3e, 0x06, 0x66, 0x29, 0x48, 0xab, 0x6d, 0xe7, 0xb5, 0x1e, 0xb7, 0xb6, 0x87, 0x5c, 0x48,
-	0x68, 0xd4, 0x5a, 0x8a, 0x08, 0x58, 0xb7, 0x7f, 0xc0, 0x27, 0x12, 0xc4, 0xca, 0x7a, 0xf7, 0x22,
-	0xa0, 0x5f, 0x59, 0xdb, 0x86, 0x6c, 0xbc, 0x01, 0x88, 0x91, 0x76, 0xe1, 0x05, 0x00, 0x18, 0x04,
-	0xdf, 0x87, 0x11, 0x7e, 0x10, 0xdd, 0x1e, 0x72, 0xc7, 0x29, 0x02, 0xdf, 0x5b, 0xca, 0x56, 0x1d,
-	0x1b, 0x75, 0x2d, 0xa3, 0x34, 0xac, 0x6c, 0xd5, 0xb1, 0x63, 0x47, 0x54, 0x7b, 0x7a, 0xf8, 0xf1,
-	0x58, 0x38, 0xa2, 0x62, 0x22, 0x78, 0x98, 0x90, 0xbc, 0xc2, 0x8f, 0xc6, 0x82, 0x87, 0x09, 0x43,
-	0x85, 0x47, 0x43, 0xca, 0xf6, 0xe1, 0xe0, 0x8f, 0x78, 0x22, 0x66, 0x52, 0x9e, 0x3d, 0xe9, 0x69,
-	0x8c, 0x88, 0x0c, 0x9b, 0xa6, 0xa1, 0x5f, 0x19, 0x24, 0xf7, 0x8b, 0x2b, 0x74, 0xdc, 0xb6, 0xc2,
-	0xe7, 0x3c, 0x2b, 0x78, 0xab, 0xef, 0x79, 0xcd, 0x9e, 0x1f, 0x3f, 0xa6, 0x61, 0xd3, 0x33, 0xba,
-	0x0e, 0xba, 0x60, 0x5e, 0x9d, 0xd1, 0x08, 0xc6, 0x5f, 0x1b, 0xec, 0xd1, 0x56, 0x67, 0x24, 0x7a,
-	0x47, 0x29, 0x67, 0x95, 0x49, 0x4e, 0x06, 0xa7, 0x63, 0x0b, 0xce, 0xdf, 0xf4, 0xe1, 0x74, 0xec,
-	0x24, 0xa7, 0x63, 0x73, 0xce, 0x03, 0xe9, 0x21, 0xbf, 0xa7, 0x06, 0xfa, 0x5b, 0x4a, 0x7a, 0x3e,
-	0x41, 0x7a, 0x20, 0x45, 0x3a, 0xa7, 0x0e, 0x89, 0xb2, 0x68, 0xa5, 0x58, 0x7f, 0xd7, 0x8f, 0x96,
-	0x07, 0x3b, 0xa7, 0x8e, 0x94, 0xd2, 0x32, 0x40, 0x1a, 0x47, 0xb0, 0xfe, 0x3e, 0x2b, 0x03, 0xa4,
-	0x97, 0xb4, 0x0c, 0x10, 0x5b, 0x5a, 0xa8, 0xb4, 0xd3, 0x04, 0xe9, 0x1f, 0xb2, 0x42, 0xa5, 0xcd,
-	0xa7, 0x85, 0x4a, 0x8d, 0x69, 0xb4, 0x4c, 0x61, 0x38, 0xed, 0x1f, 0xb3, 0x68, 0xe9, 0x4d, 0xa8,
-	0xd1, 0x52, 0x63, 0x5a, 0x06, 0xc8, 0x3d, 0x2a, 0x58, 0xff, 0x94, 0x95, 0x01, 0x72, 0xdb, 0x6a,
-	0x19, 0x20, 0x36, 0xce, 0xb9, 0x27, 0x3d, 0x1c, 0x28, 0xcd, 0xff, 0x67, 0x83, 0xc8, 0x60, 0xdf,
-	0xe6, 0x97, 0x1f, 0x0a, 0xa5, 0x20, 0xd5, 0x91, 0x81, 0x60, 0xfc, 0x8b, 0xc1, 0x9e, 0xb4, 0xfa,
-	0x35, 0xbf, 0x32, 0x58, 0xc8, 0xe0, 0x94, 0x1a, 0xea, 0xaf, 0x7d, 0x38, 0x45, 0xf3, 0x2b, 0x53,
-	0x08, 0xa9, 0x46, 0xda, 0x30, 0x42, 0x90, 0xfe, 0x8d, 0x92, 0x9e, 0xd2, 0xfc, 0xea, 0xcc, 0x22,
-	0x8b, 0x56, 0x8a, 0xf5, 0xef, 0xfd, 0x68, 0x45, 0xf3, 0xab, 0x13, 0x8e, 0xb4, 0x0c, 0xa8, 0xcd,
-	0xff, 0x8f, 0xac, 0x0c, 0xc8, 0xcd, 0xaf, 0x0c, 0x03, 0xd2, 0x42, 0xd5, 0x9a, 0xff, 0x9f, 0x59,
-	0xa1, 0x2a, 0xcd, 0xaf, 0x8e, 0x0e, 0xd2, 0x68, 0xb5, 0xe6, 0xff, 0x57, 0x16, 0xad, 0xd2, 0xfc,
-	0xea, 0xb3, 0x68, 0x5a, 0x06, 0xd4, 0xe6, 0xff, 0x77, 0x56, 0x06, 0xe4, 0xe6, 0x57, 0x06, 0x0e,
-	0x9c, 0xf3, 0xa1, 0x34, 0xd7, 0xe5, 0xef, 0x70, 0xd0, 0x77, 0x73, 0x6c, 0x4e, 0x96, 0xd8, 0x3b,
-	0x43, 0xc4, 0x33, 0x5f, 0x6e, 0x81, 0x8f, 0x80, 0x18, 0x1a, 0xd6, 0xc4, 0xcb, 0x1a, 0xf4, 0xbd,
-	0x5c, 0xc6, 0xf9, 0xf1, 0x94, 0x43, 0x5c, 0xe1, 0x5f, 0x98, 0xe0, 0x47, 0xc1, 0x8c, 0x34, 0xc4,
-	0xe6, 0x2f, 0x8e, 0xd0, 0xf7, 0xb3, 0xc8, 0xaa, 0x18, 0xf3, 0xd8, 0x8b, 0x5e, 0xc6, 0x64, 0xc2,
-	0x04, 0xb7, 0xd4, 0xb9, 0x70, 0xaf, 0xde, 0x45, 0x3f, 0xa0, 0x44, 0x0b, 0x69, 0x45, 0xe8, 0xd5,
-	0xbb, 0xca, 0xc4, 0xb8, 0x57, 0xef, 0xc2, 0x4d, 0x20, 0x66, 0x8b, 0x35, 0xaf, 0x7d, 0x82, 0x7e,
-	0x48, 0xd7, 0xcf, 0x26, 0xd6, 0x6f, 0xb5, 0x4f, 0xdc, 0x3c, 0x87, 0x6e, 0xb5, 0x4f, 0xe0, 0x5d,
-	0x69, 0xd6, 0xfc, 0x0a, 0x97, 0x01, 0xfd, 0x88, 0xae, 0x9d, 0x4f, 0xac, 0xa5, 0x55, 0x12, 0xd3,
-	0x4d, 0xf2, 0x15, 0x97, 0x27, 0x6e, 0x50, 0x5e, 0x9e, 0x1f, 0xe7, 0x48, 0xb5, 0xfb, 0x95, 0x47,
-	0xf4, 0xa5, 0x54, 0x1e, 0x41, 0x14, 0x97, 0xe7, 0x27, 0xb9, 0x0c, 0x85, 0x93, 0xca, 0xc3, 0x97,
-	0xc5, 0xe5, 0x91, 0xb9, 0x48, 0x79, 0x48, 0x75, 0x7e, 0x9a, 0xc5, 0x25, 0x55, 0x27, 0x1e, 0x0a,
-	0xb2, 0x55, 0xb8, 0x3a, 0xf2, 0xad, 0x82, 0xab, 0xf3, 0x4b, 0x4a, 0x94, 0x5d, 0x1d, 0xe9, 0xee,
-	0x60, 0xd5, 0x11, 0x14, 0xb8, 0x3a, 0x3f, 0xa3, 0xeb, 0x33, 0xaa, 0xc3, 0xa1, 0xac, 0x3a, 0x62,
-	0x25, 0xad, 0xce, 0xcf, 0xe9, 0xda, 0xcc, 0xea, 0x70, 0x38, 0xad, 0xce, 0x05, 0x00, 0xc8, 0xfe,
-	0xdb, 0x5e, 0xcb, 0x5f, 0x43, 0x9f, 0x36, 0xc9, 0x6b, 0x28, 0xc9, 0x04, 0x2d, 0x90, 0xa7, 0xfd,
-	0x8b, 0xbf, 0xae, 0xa3, 0xcf, 0xc8, 0x88, 0x5d, 0x6c, 0x82, 0x17, 0x41, 0xa1, 0x16, 0x43, 0x36,
-	0xd0, 0x67, 0x19, 0xa4, 0xca, 0x21, 0x1b, 0x70, 0x09, 0x4c, 0x50, 0x04, 0x81, 0xd8, 0x35, 0xf4,
-	0x39, 0x9d, 0x86, 0xfc, 0x3d, 0x49, 0xbe, 0xad, 0x62, 0xc8, 0x4d, 0xf4, 0x79, 0x8a, 0x90, 0x6d,
-	0x70, 0x99, 0xd3, 0xac, 0x12, 0x1e, 0x07, 0x7d, 0x41, 0x01, 0x61, 0x1e, 0x47, 0xec, 0x08, 0x7f,
-	0xbb, 0x85, 0xbe, 0xa8, 0x3b, 0xba, 0x85, 0x01, 0x22, 0xb4, 0x4d, 0xf4, 0x25, 0x3d, 0xda, 0xcd,
-	0x78, 0xcb, 0xf8, 0xeb, 0x6d, 0xf4, 0x65, 0x9d, 0xe2, 0x36, 0x5c, 0x02, 0x85, 0xaa, 0x40, 0xac,
-	0xad, 0xa2, 0xaf, 0xb0, 0x38, 0x04, 0xc9, 0xda, 0x2a, 0xc1, 0xec, 0x54, 0xde, 0x7d, 0x50, 0xdb,
-	0xdd, 0x7a, 0x5c, 0x59, 0x5b, 0x43, 0x5f, 0xe5, 0x18, 0x6c, 0xa4, 0xb6, 0x18, 0x43, 0x72, 0xbd,
-	0x8e, 0xbe, 0xa6, 0x60, 0x88, 0x0d, 0x5e, 0x02, 0x93, 0x35, 0x29, 0xbf, 0x6b, 0x1b, 0xe8, 0xeb,
-	0x09, 0x6f, 0x1b, 0x14, 0x55, 0x8d, 0x51, 0x36, 0xfa, 0x46, 0x02, 0x65, 0xc7, 0x09, 0xa4, 0xa0,
-	0x9b, 0xe8, 0x9b, 0x72, 0x02, 0x09, 0x48, 0xca, 0x32, 0xdd, 0x9d, 0x83, 0xbe, 0x95, 0x00, 0x39,
-	0xd8, 0x9f, 0x14, 0xd3, 0xad, 0x5a, 0x0d, 0x7d, 0x3b, 0x81, 0xba, 0x85, 0x51, 0x52, 0x4c, 0x9b,
-	0xb5, 0x1a, 0xfa, 0x4e, 0x22, 0xaa, 0xcd, 0xc5, 0xe7, 0x60, 0x42, 0x7d, 0xd0, 0x29, 0x00, 0xc3,
-	0x63, 0x6f, 0x44, 0x0d, 0x0f, 0xbe, 0x0d, 0xf2, 0xf5, 0x40, 0xbc, 0xd4, 0x40, 0xb9, 0xd3, 0x5e,
-	0x80, 0xc8, 0xe8, 0xc5, 0x7b, 0x00, 0x26, 0x87, 0x94, 0xb0, 0x08, 0xcc, 0x97, 0xfe, 0x09, 0x73,
-	0x81, 0x7f, 0x85, 0xb3, 0xe0, 0x0c, 0xbd, 0x7d, 0x72, 0xc4, 0x46, 0xbf, 0xdc, 0xc9, 0x6d, 0x1a,
-	0x31, 0x83, 0x3c, 0x90, 0x94, 0x19, 0xcc, 0x14, 0x06, 0x53, 0x66, 0x28, 0x83, 0xd9, 0xb4, 0xd1,
-	0xa3, 0xcc, 0x31, 0x91, 0xc2, 0x31, 0x91, 0xce, 0xa1, 0x8c, 0x18, 0x65, 0x8e, 0xe1, 0x14, 0x8e,
-	0xe1, 0x24, 0x47, 0x62, 0x94, 0x28, 0x73, 0x4c, 0xa7, 0x70, 0x4c, 0xa7, 0x73, 0x28, 0x23, 0x43,
-	0x99, 0x03, 0xa6, 0x70, 0x40, 0x99, 0xe3, 0x01, 0x98, 0x4f, 0x1f, 0x0c, 0xca, 0x2c, 0xa3, 0x29,
-	0x2c, 0xa3, 0x19, 0x2c, 0xea, 0xf0, 0x4f, 0x66, 0x19, 0x49, 0x61, 0x19, 0x91, 0x59, 0xaa, 0x00,
-	0x65, 0x8d, 0xf7, 0x64, 0x9e, 0xa9, 0x14, 0x9e, 0xa9, 0x2c, 0x1e, 0x6d, 0x7c, 0x27, 0xf3, 0x14,
-	0x53, 0x78, 0x8a, 0xa9, 0xdd, 0x26, 0x0f, 0xe9, 0x4e, 0xeb, 0xd7, 0x9c, 0xcc, 0xb0, 0x05, 0x66,
-	0x52, 0xe6, 0x71, 0xa7, 0x51, 0x18, 0x32, 0xc5, 0x5d, 0x50, 0xd4, 0x87, 0x6f, 0xf2, 0xfa, 0xb1,
-	0x94, 0xf5, 0x63, 0x29, 0x4d, 0xa2, 0x0f, 0xda, 0x64, 0x8e, 0xf1, 0x14, 0x8e, 0xf1, 0xe4, 0x36,
-	0xf4, 0x89, 0xda, 0x69, 0x14, 0x05, 0x99, 0x22, 0x04, 0xe7, 0xfa, 0x8c, 0xcc, 0x52, 0xa8, 0xde,
-	0x91, 0xa9, 0x5e, 0xe3, 0x7d, 0x95, 0xe4, 0xf3, 0x18, 0x9c, 0xef, 0x37, 0x33, 0x4b, 0x71, 0xba,
-	0xa6, 0x3a, 0xed, 0xfb, 0x0a, 0x4b, 0x72, 0xd4, 0xa4, 0x0d, 0x97, 0x36, 0x2b, 0x4b, 0x71, 0x72,
-	0x47, 0x76, 0x32, 0xe8, 0x4b, 0x2d, 0xc9, 0x9b, 0x07, 0xce, 0x66, 0xce, 0xcb, 0x52, 0xdc, 0xad,
-	0xa8, 0xee, 0xb2, 0x5f, 0x75, 0xc5, 0x2e, 0x96, 0x6e, 0x03, 0x20, 0x4d, 0xf6, 0x46, 0x81, 0x59,
-	0xdd, 0xdb, 0x2b, 0x0e, 0xe1, 0x5f, 0xca, 0x5b, 0x6e, 0xd1, 0xa0, 0xbf, 0x3c, 0x2f, 0xe6, 0xb0,
-	0xbb, 0xdd, 0xca, 0xc3, 0xe2, 0x7f, 0xf9, 0x7f, 0x46, 0x79, 0x42, 0x8c, 0xa2, 0xf0, 0xa9, 0xb2,
-	0xf4, 0x06, 0x98, 0xd4, 0x06, 0x92, 0x05, 0x60, 0xd4, 0xf9, 0x81, 0x52, 0xbf, 0x76, 0x13, 0x80,
-	0xf8, 0xdf, 0x30, 0xc1, 0x29, 0x90, 0x3f, 0xd8, 0xdd, 0x7f, 0x52, 0xb9, 0xbf, 0x53, 0xdd, 0xa9,
-	0x3c, 0x28, 0x0e, 0xc1, 0x02, 0x18, 0x7b, 0xe2, 0xee, 0x3d, 0xdd, 0x2b, 0x1f, 0x54, 0x8b, 0x06,
-	0x1c, 0x03, 0xc3, 0x8f, 0xf6, 0xf7, 0x76, 0x8b, 0xb9, 0x6b, 0xf7, 0x40, 0x5e, 0x9e, 0x07, 0x4e,
-	0x81, 0x7c, 0x75, 0xcf, 0xad, 0xec, 0x3c, 0xdc, 0xad, 0xd1, 0x48, 0x25, 0x03, 0x8d, 0x58, 0x31,
-	0x3c, 0x2f, 0xe6, 0xca, 0x17, 0xc1, 0x85, 0x7a, 0xd0, 0x4a, 0xfc, 0x61, 0x26, 0x25, 0xe7, 0xc5,
-	0x08, 0xb1, 0x6e, 0xfc, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x33, 0xc2, 0x0c, 0xb6, 0xeb, 0x26, 0x00,
-	0x00,
-}
diff --git a/_conformance/Makefile b/conformance/Makefile
similarity index 76%
rename from _conformance/Makefile
rename to conformance/Makefile
index 89800e2..b99e4ed 100644
--- a/_conformance/Makefile
+++ b/conformance/Makefile
@@ -29,5 +29,21 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-regenerate:
-	protoc --go_out=Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any,Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration,Mgoogle/protobuf/struct.proto=github.com/golang/protobuf/ptypes/struct,Mgoogle/protobuf/timestamp.proto=github.com/golang/protobuf/ptypes/timestamp,Mgoogle/protobuf/wrappers.proto=github.com/golang/protobuf/ptypes/wrappers,Mgoogle/protobuf/field_mask.proto=google.golang.org/genproto/protobuf:. conformance_proto/conformance.proto
+PROTOBUF_ROOT=$(HOME)/src/protobuf
+
+all:
+	@echo To run the tests in this directory, acquire the main protobuf
+	@echo distribution from:
+	@echo
+	@echo '   https://github.com/google/protobuf'
+	@echo
+	@echo Build the test runner with:
+	@echo
+	@echo '   cd conformance && make conformance-test-runner'
+	@echo
+	@echo And run the tests in this directory with:
+	@echo
+	@echo '   make test PROTOBUF_ROOT=<protobuf distribution>'
+
+test:
+	./test.sh $(PROTOBUF_ROOT)
diff --git a/_conformance/conformance.go b/conformance/conformance.go
similarity index 94%
rename from _conformance/conformance.go
rename to conformance/conformance.go
index c54212c..3029312 100644
--- a/_conformance/conformance.go
+++ b/conformance/conformance.go
@@ -39,7 +39,7 @@
 	"io"
 	"os"
 
-	pb "github.com/golang/protobuf/_conformance/conformance_proto"
+	pb "github.com/golang/protobuf/conformance/internal/conformance_proto"
 	"github.com/golang/protobuf/jsonpb"
 	"github.com/golang/protobuf/proto"
 )
@@ -101,13 +101,6 @@
 		err = proto.Unmarshal(p.ProtobufPayload, &msg)
 	case *pb.ConformanceRequest_JsonPayload:
 		err = jsonpb.UnmarshalString(p.JsonPayload, &msg)
-		if err != nil && err.Error() == "unmarshaling Any not supported yet" {
-			return &pb.ConformanceResponse{
-				Result: &pb.ConformanceResponse_Skipped{
-					Skipped: err.Error(),
-				},
-			}
-		}
 	default:
 		return &pb.ConformanceResponse{
 			Result: &pb.ConformanceResponse_RuntimeError{
diff --git a/conformance/conformance.sh b/conformance/conformance.sh
new file mode 100755
index 0000000..8532f57
--- /dev/null
+++ b/conformance/conformance.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cd $(dirname $0)
+exec go run conformance.go $*
diff --git a/conformance/failure_list_go.txt b/conformance/failure_list_go.txt
new file mode 100644
index 0000000..d372808
--- /dev/null
+++ b/conformance/failure_list_go.txt
@@ -0,0 +1,61 @@
+# This is the list of conformance tests that are known ot fail right now.
+# TODO: These should be fixed.
+
+DurationProtoInputTooLarge.JsonOutput
+DurationProtoInputTooSmall.JsonOutput
+FieldMaskNumbersDontRoundTrip.JsonOutput
+FieldMaskPathsDontRoundTrip.JsonOutput
+FieldMaskTooManyUnderscore.JsonOutput
+JsonInput.AnyWithFieldMask.JsonOutput
+JsonInput.AnyWithFieldMask.ProtobufOutput
+JsonInput.DoubleFieldQuotedValue.JsonOutput
+JsonInput.DoubleFieldQuotedValue.ProtobufOutput
+JsonInput.DurationHas3FractionalDigits.Validator
+JsonInput.DurationHas6FractionalDigits.Validator
+JsonInput.DurationHas9FractionalDigits.Validator
+JsonInput.DurationHasZeroFractionalDigit.Validator
+JsonInput.DurationMaxValue.JsonOutput
+JsonInput.DurationMaxValue.ProtobufOutput
+JsonInput.DurationMinValue.JsonOutput
+JsonInput.DurationMinValue.ProtobufOutput
+JsonInput.EnumFieldUnknownValue.Validator
+JsonInput.FieldMask.JsonOutput
+JsonInput.FieldMask.ProtobufOutput
+JsonInput.FieldNameInLowerCamelCase.Validator
+JsonInput.FieldNameWithMixedCases.JsonOutput
+JsonInput.FieldNameWithMixedCases.ProtobufOutput
+JsonInput.FieldNameWithMixedCases.Validator
+JsonInput.FieldNameWithNumbers.Validator
+JsonInput.FloatFieldQuotedValue.JsonOutput
+JsonInput.FloatFieldQuotedValue.ProtobufOutput
+JsonInput.Int32FieldExponentialFormat.JsonOutput
+JsonInput.Int32FieldExponentialFormat.ProtobufOutput
+JsonInput.Int32FieldFloatTrailingZero.JsonOutput
+JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
+JsonInput.Int32FieldMaxFloatValue.JsonOutput
+JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
+JsonInput.Int32FieldMinFloatValue.JsonOutput
+JsonInput.Int32FieldMinFloatValue.ProtobufOutput
+JsonInput.Int32FieldStringValue.JsonOutput
+JsonInput.Int32FieldStringValue.ProtobufOutput
+JsonInput.Int32FieldStringValueEscaped.JsonOutput
+JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
+JsonInput.Int64FieldBeString.Validator
+JsonInput.MapFieldValueIsNull
+JsonInput.OneofFieldDuplicate
+JsonInput.RepeatedFieldMessageElementIsNull
+JsonInput.RepeatedFieldPrimitiveElementIsNull
+JsonInput.StringFieldSurrogateInWrongOrder
+JsonInput.StringFieldUnpairedHighSurrogate
+JsonInput.StringFieldUnpairedLowSurrogate
+JsonInput.TimestampHas3FractionalDigits.Validator
+JsonInput.TimestampHas6FractionalDigits.Validator
+JsonInput.TimestampHas9FractionalDigits.Validator
+JsonInput.TimestampHasZeroFractionalDigit.Validator
+JsonInput.TimestampJsonInputTooSmall
+JsonInput.TimestampZeroNormalized.Validator
+JsonInput.Uint32FieldMaxFloatValue.JsonOutput
+JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
+JsonInput.Uint64FieldBeString.Validator
+TimestampProtoInputTooLarge.JsonOutput
+TimestampProtoInputTooSmall.JsonOutput
diff --git a/conformance/internal/conformance_proto/conformance.pb.go b/conformance/internal/conformance_proto/conformance.pb.go
new file mode 100644
index 0000000..82d4541
--- /dev/null
+++ b/conformance/internal/conformance_proto/conformance.pb.go
@@ -0,0 +1,1816 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: conformance.proto
+
+package conformance
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import any "github.com/golang/protobuf/ptypes/any"
+import duration "github.com/golang/protobuf/ptypes/duration"
+import _struct "github.com/golang/protobuf/ptypes/struct"
+import timestamp "github.com/golang/protobuf/ptypes/timestamp"
+import wrappers "github.com/golang/protobuf/ptypes/wrappers"
+import field_mask "google.golang.org/genproto/protobuf/field_mask"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type WireFormat int32
+
+const (
+	WireFormat_UNSPECIFIED WireFormat = 0
+	WireFormat_PROTOBUF    WireFormat = 1
+	WireFormat_JSON        WireFormat = 2
+)
+
+var WireFormat_name = map[int32]string{
+	0: "UNSPECIFIED",
+	1: "PROTOBUF",
+	2: "JSON",
+}
+var WireFormat_value = map[string]int32{
+	"UNSPECIFIED": 0,
+	"PROTOBUF":    1,
+	"JSON":        2,
+}
+
+func (x WireFormat) String() string {
+	return proto.EnumName(WireFormat_name, int32(x))
+}
+func (WireFormat) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_conformance_48ac832451f5d6c3, []int{0}
+}
+
+type ForeignEnum int32
+
+const (
+	ForeignEnum_FOREIGN_FOO ForeignEnum = 0
+	ForeignEnum_FOREIGN_BAR ForeignEnum = 1
+	ForeignEnum_FOREIGN_BAZ ForeignEnum = 2
+)
+
+var ForeignEnum_name = map[int32]string{
+	0: "FOREIGN_FOO",
+	1: "FOREIGN_BAR",
+	2: "FOREIGN_BAZ",
+}
+var ForeignEnum_value = map[string]int32{
+	"FOREIGN_FOO": 0,
+	"FOREIGN_BAR": 1,
+	"FOREIGN_BAZ": 2,
+}
+
+func (x ForeignEnum) String() string {
+	return proto.EnumName(ForeignEnum_name, int32(x))
+}
+func (ForeignEnum) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_conformance_48ac832451f5d6c3, []int{1}
+}
+
+type TestAllTypes_NestedEnum int32
+
+const (
+	TestAllTypes_FOO TestAllTypes_NestedEnum = 0
+	TestAllTypes_BAR TestAllTypes_NestedEnum = 1
+	TestAllTypes_BAZ TestAllTypes_NestedEnum = 2
+	TestAllTypes_NEG TestAllTypes_NestedEnum = -1
+)
+
+var TestAllTypes_NestedEnum_name = map[int32]string{
+	0:  "FOO",
+	1:  "BAR",
+	2:  "BAZ",
+	-1: "NEG",
+}
+var TestAllTypes_NestedEnum_value = map[string]int32{
+	"FOO": 0,
+	"BAR": 1,
+	"BAZ": 2,
+	"NEG": -1,
+}
+
+func (x TestAllTypes_NestedEnum) String() string {
+	return proto.EnumName(TestAllTypes_NestedEnum_name, int32(x))
+}
+func (TestAllTypes_NestedEnum) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_conformance_48ac832451f5d6c3, []int{2, 0}
+}
+
+// Represents a single test case's input.  The testee should:
+//
+//   1. parse this proto (which should always succeed)
+//   2. parse the protobuf or JSON payload in "payload" (which may fail)
+//   3. if the parse succeeded, serialize the message in the requested format.
+type ConformanceRequest struct {
+	// The payload (whether protobuf of JSON) is always for a TestAllTypes proto
+	// (see below).
+	//
+	// Types that are valid to be assigned to Payload:
+	//	*ConformanceRequest_ProtobufPayload
+	//	*ConformanceRequest_JsonPayload
+	Payload isConformanceRequest_Payload `protobuf_oneof:"payload"`
+	// Which format should the testee serialize its message to?
+	RequestedOutputFormat WireFormat `protobuf:"varint,3,opt,name=requested_output_format,json=requestedOutputFormat,enum=conformance.WireFormat" json:"requested_output_format,omitempty"`
+	XXX_NoUnkeyedLiteral  struct{}   `json:"-"`
+	XXX_unrecognized      []byte     `json:"-"`
+	XXX_sizecache         int32      `json:"-"`
+}
+
+func (m *ConformanceRequest) Reset()         { *m = ConformanceRequest{} }
+func (m *ConformanceRequest) String() string { return proto.CompactTextString(m) }
+func (*ConformanceRequest) ProtoMessage()    {}
+func (*ConformanceRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_conformance_48ac832451f5d6c3, []int{0}
+}
+func (m *ConformanceRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ConformanceRequest.Unmarshal(m, b)
+}
+func (m *ConformanceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ConformanceRequest.Marshal(b, m, deterministic)
+}
+func (dst *ConformanceRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ConformanceRequest.Merge(dst, src)
+}
+func (m *ConformanceRequest) XXX_Size() int {
+	return xxx_messageInfo_ConformanceRequest.Size(m)
+}
+func (m *ConformanceRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_ConformanceRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ConformanceRequest proto.InternalMessageInfo
+
+type isConformanceRequest_Payload interface {
+	isConformanceRequest_Payload()
+}
+
+type ConformanceRequest_ProtobufPayload struct {
+	ProtobufPayload []byte `protobuf:"bytes,1,opt,name=protobuf_payload,json=protobufPayload,proto3,oneof"`
+}
+type ConformanceRequest_JsonPayload struct {
+	JsonPayload string `protobuf:"bytes,2,opt,name=json_payload,json=jsonPayload,oneof"`
+}
+
+func (*ConformanceRequest_ProtobufPayload) isConformanceRequest_Payload() {}
+func (*ConformanceRequest_JsonPayload) isConformanceRequest_Payload()     {}
+
+func (m *ConformanceRequest) GetPayload() isConformanceRequest_Payload {
+	if m != nil {
+		return m.Payload
+	}
+	return nil
+}
+
+func (m *ConformanceRequest) GetProtobufPayload() []byte {
+	if x, ok := m.GetPayload().(*ConformanceRequest_ProtobufPayload); ok {
+		return x.ProtobufPayload
+	}
+	return nil
+}
+
+func (m *ConformanceRequest) GetJsonPayload() string {
+	if x, ok := m.GetPayload().(*ConformanceRequest_JsonPayload); ok {
+		return x.JsonPayload
+	}
+	return ""
+}
+
+func (m *ConformanceRequest) GetRequestedOutputFormat() WireFormat {
+	if m != nil {
+		return m.RequestedOutputFormat
+	}
+	return WireFormat_UNSPECIFIED
+}
+
+// XXX_OneofFuncs is for the internal use of the proto package.
+func (*ConformanceRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
+	return _ConformanceRequest_OneofMarshaler, _ConformanceRequest_OneofUnmarshaler, _ConformanceRequest_OneofSizer, []interface{}{
+		(*ConformanceRequest_ProtobufPayload)(nil),
+		(*ConformanceRequest_JsonPayload)(nil),
+	}
+}
+
+func _ConformanceRequest_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
+	m := msg.(*ConformanceRequest)
+	// payload
+	switch x := m.Payload.(type) {
+	case *ConformanceRequest_ProtobufPayload:
+		b.EncodeVarint(1<<3 | proto.WireBytes)
+		b.EncodeRawBytes(x.ProtobufPayload)
+	case *ConformanceRequest_JsonPayload:
+		b.EncodeVarint(2<<3 | proto.WireBytes)
+		b.EncodeStringBytes(x.JsonPayload)
+	case nil:
+	default:
+		return fmt.Errorf("ConformanceRequest.Payload has unexpected type %T", x)
+	}
+	return nil
+}
+
+func _ConformanceRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
+	m := msg.(*ConformanceRequest)
+	switch tag {
+	case 1: // payload.protobuf_payload
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeRawBytes(true)
+		m.Payload = &ConformanceRequest_ProtobufPayload{x}
+		return true, err
+	case 2: // payload.json_payload
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeStringBytes()
+		m.Payload = &ConformanceRequest_JsonPayload{x}
+		return true, err
+	default:
+		return false, nil
+	}
+}
+
+func _ConformanceRequest_OneofSizer(msg proto.Message) (n int) {
+	m := msg.(*ConformanceRequest)
+	// payload
+	switch x := m.Payload.(type) {
+	case *ConformanceRequest_ProtobufPayload:
+		n += 1 // tag and wire
+		n += proto.SizeVarint(uint64(len(x.ProtobufPayload)))
+		n += len(x.ProtobufPayload)
+	case *ConformanceRequest_JsonPayload:
+		n += 1 // tag and wire
+		n += proto.SizeVarint(uint64(len(x.JsonPayload)))
+		n += len(x.JsonPayload)
+	case nil:
+	default:
+		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
+	}
+	return n
+}
+
+// Represents a single test case's output.
+type ConformanceResponse struct {
+	// Types that are valid to be assigned to Result:
+	//	*ConformanceResponse_ParseError
+	//	*ConformanceResponse_SerializeError
+	//	*ConformanceResponse_RuntimeError
+	//	*ConformanceResponse_ProtobufPayload
+	//	*ConformanceResponse_JsonPayload
+	//	*ConformanceResponse_Skipped
+	Result               isConformanceResponse_Result `protobuf_oneof:"result"`
+	XXX_NoUnkeyedLiteral struct{}                     `json:"-"`
+	XXX_unrecognized     []byte                       `json:"-"`
+	XXX_sizecache        int32                        `json:"-"`
+}
+
+func (m *ConformanceResponse) Reset()         { *m = ConformanceResponse{} }
+func (m *ConformanceResponse) String() string { return proto.CompactTextString(m) }
+func (*ConformanceResponse) ProtoMessage()    {}
+func (*ConformanceResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_conformance_48ac832451f5d6c3, []int{1}
+}
+func (m *ConformanceResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ConformanceResponse.Unmarshal(m, b)
+}
+func (m *ConformanceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ConformanceResponse.Marshal(b, m, deterministic)
+}
+func (dst *ConformanceResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ConformanceResponse.Merge(dst, src)
+}
+func (m *ConformanceResponse) XXX_Size() int {
+	return xxx_messageInfo_ConformanceResponse.Size(m)
+}
+func (m *ConformanceResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_ConformanceResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ConformanceResponse proto.InternalMessageInfo
+
+type isConformanceResponse_Result interface {
+	isConformanceResponse_Result()
+}
+
+type ConformanceResponse_ParseError struct {
+	ParseError string `protobuf:"bytes,1,opt,name=parse_error,json=parseError,oneof"`
+}
+type ConformanceResponse_SerializeError struct {
+	SerializeError string `protobuf:"bytes,6,opt,name=serialize_error,json=serializeError,oneof"`
+}
+type ConformanceResponse_RuntimeError struct {
+	RuntimeError string `protobuf:"bytes,2,opt,name=runtime_error,json=runtimeError,oneof"`
+}
+type ConformanceResponse_ProtobufPayload struct {
+	ProtobufPayload []byte `protobuf:"bytes,3,opt,name=protobuf_payload,json=protobufPayload,proto3,oneof"`
+}
+type ConformanceResponse_JsonPayload struct {
+	JsonPayload string `protobuf:"bytes,4,opt,name=json_payload,json=jsonPayload,oneof"`
+}
+type ConformanceResponse_Skipped struct {
+	Skipped string `protobuf:"bytes,5,opt,name=skipped,oneof"`
+}
+
+func (*ConformanceResponse_ParseError) isConformanceResponse_Result()      {}
+func (*ConformanceResponse_SerializeError) isConformanceResponse_Result()  {}
+func (*ConformanceResponse_RuntimeError) isConformanceResponse_Result()    {}
+func (*ConformanceResponse_ProtobufPayload) isConformanceResponse_Result() {}
+func (*ConformanceResponse_JsonPayload) isConformanceResponse_Result()     {}
+func (*ConformanceResponse_Skipped) isConformanceResponse_Result()         {}
+
+func (m *ConformanceResponse) GetResult() isConformanceResponse_Result {
+	if m != nil {
+		return m.Result
+	}
+	return nil
+}
+
+func (m *ConformanceResponse) GetParseError() string {
+	if x, ok := m.GetResult().(*ConformanceResponse_ParseError); ok {
+		return x.ParseError
+	}
+	return ""
+}
+
+func (m *ConformanceResponse) GetSerializeError() string {
+	if x, ok := m.GetResult().(*ConformanceResponse_SerializeError); ok {
+		return x.SerializeError
+	}
+	return ""
+}
+
+func (m *ConformanceResponse) GetRuntimeError() string {
+	if x, ok := m.GetResult().(*ConformanceResponse_RuntimeError); ok {
+		return x.RuntimeError
+	}
+	return ""
+}
+
+func (m *ConformanceResponse) GetProtobufPayload() []byte {
+	if x, ok := m.GetResult().(*ConformanceResponse_ProtobufPayload); ok {
+		return x.ProtobufPayload
+	}
+	return nil
+}
+
+func (m *ConformanceResponse) GetJsonPayload() string {
+	if x, ok := m.GetResult().(*ConformanceResponse_JsonPayload); ok {
+		return x.JsonPayload
+	}
+	return ""
+}
+
+func (m *ConformanceResponse) GetSkipped() string {
+	if x, ok := m.GetResult().(*ConformanceResponse_Skipped); ok {
+		return x.Skipped
+	}
+	return ""
+}
+
+// XXX_OneofFuncs is for the internal use of the proto package.
+func (*ConformanceResponse) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
+	return _ConformanceResponse_OneofMarshaler, _ConformanceResponse_OneofUnmarshaler, _ConformanceResponse_OneofSizer, []interface{}{
+		(*ConformanceResponse_ParseError)(nil),
+		(*ConformanceResponse_SerializeError)(nil),
+		(*ConformanceResponse_RuntimeError)(nil),
+		(*ConformanceResponse_ProtobufPayload)(nil),
+		(*ConformanceResponse_JsonPayload)(nil),
+		(*ConformanceResponse_Skipped)(nil),
+	}
+}
+
+func _ConformanceResponse_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
+	m := msg.(*ConformanceResponse)
+	// result
+	switch x := m.Result.(type) {
+	case *ConformanceResponse_ParseError:
+		b.EncodeVarint(1<<3 | proto.WireBytes)
+		b.EncodeStringBytes(x.ParseError)
+	case *ConformanceResponse_SerializeError:
+		b.EncodeVarint(6<<3 | proto.WireBytes)
+		b.EncodeStringBytes(x.SerializeError)
+	case *ConformanceResponse_RuntimeError:
+		b.EncodeVarint(2<<3 | proto.WireBytes)
+		b.EncodeStringBytes(x.RuntimeError)
+	case *ConformanceResponse_ProtobufPayload:
+		b.EncodeVarint(3<<3 | proto.WireBytes)
+		b.EncodeRawBytes(x.ProtobufPayload)
+	case *ConformanceResponse_JsonPayload:
+		b.EncodeVarint(4<<3 | proto.WireBytes)
+		b.EncodeStringBytes(x.JsonPayload)
+	case *ConformanceResponse_Skipped:
+		b.EncodeVarint(5<<3 | proto.WireBytes)
+		b.EncodeStringBytes(x.Skipped)
+	case nil:
+	default:
+		return fmt.Errorf("ConformanceResponse.Result has unexpected type %T", x)
+	}
+	return nil
+}
+
+func _ConformanceResponse_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
+	m := msg.(*ConformanceResponse)
+	switch tag {
+	case 1: // result.parse_error
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeStringBytes()
+		m.Result = &ConformanceResponse_ParseError{x}
+		return true, err
+	case 6: // result.serialize_error
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeStringBytes()
+		m.Result = &ConformanceResponse_SerializeError{x}
+		return true, err
+	case 2: // result.runtime_error
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeStringBytes()
+		m.Result = &ConformanceResponse_RuntimeError{x}
+		return true, err
+	case 3: // result.protobuf_payload
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeRawBytes(true)
+		m.Result = &ConformanceResponse_ProtobufPayload{x}
+		return true, err
+	case 4: // result.json_payload
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeStringBytes()
+		m.Result = &ConformanceResponse_JsonPayload{x}
+		return true, err
+	case 5: // result.skipped
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeStringBytes()
+		m.Result = &ConformanceResponse_Skipped{x}
+		return true, err
+	default:
+		return false, nil
+	}
+}
+
+func _ConformanceResponse_OneofSizer(msg proto.Message) (n int) {
+	m := msg.(*ConformanceResponse)
+	// result
+	switch x := m.Result.(type) {
+	case *ConformanceResponse_ParseError:
+		n += 1 // tag and wire
+		n += proto.SizeVarint(uint64(len(x.ParseError)))
+		n += len(x.ParseError)
+	case *ConformanceResponse_SerializeError:
+		n += 1 // tag and wire
+		n += proto.SizeVarint(uint64(len(x.SerializeError)))
+		n += len(x.SerializeError)
+	case *ConformanceResponse_RuntimeError:
+		n += 1 // tag and wire
+		n += proto.SizeVarint(uint64(len(x.RuntimeError)))
+		n += len(x.RuntimeError)
+	case *ConformanceResponse_ProtobufPayload:
+		n += 1 // tag and wire
+		n += proto.SizeVarint(uint64(len(x.ProtobufPayload)))
+		n += len(x.ProtobufPayload)
+	case *ConformanceResponse_JsonPayload:
+		n += 1 // tag and wire
+		n += proto.SizeVarint(uint64(len(x.JsonPayload)))
+		n += len(x.JsonPayload)
+	case *ConformanceResponse_Skipped:
+		n += 1 // tag and wire
+		n += proto.SizeVarint(uint64(len(x.Skipped)))
+		n += len(x.Skipped)
+	case nil:
+	default:
+		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
+	}
+	return n
+}
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+type TestAllTypes struct {
+	// Singular
+	OptionalInt32          int32                       `protobuf:"varint,1,opt,name=optional_int32,json=optionalInt32" json:"optional_int32,omitempty"`
+	OptionalInt64          int64                       `protobuf:"varint,2,opt,name=optional_int64,json=optionalInt64" json:"optional_int64,omitempty"`
+	OptionalUint32         uint32                      `protobuf:"varint,3,opt,name=optional_uint32,json=optionalUint32" json:"optional_uint32,omitempty"`
+	OptionalUint64         uint64                      `protobuf:"varint,4,opt,name=optional_uint64,json=optionalUint64" json:"optional_uint64,omitempty"`
+	OptionalSint32         int32                       `protobuf:"zigzag32,5,opt,name=optional_sint32,json=optionalSint32" json:"optional_sint32,omitempty"`
+	OptionalSint64         int64                       `protobuf:"zigzag64,6,opt,name=optional_sint64,json=optionalSint64" json:"optional_sint64,omitempty"`
+	OptionalFixed32        uint32                      `protobuf:"fixed32,7,opt,name=optional_fixed32,json=optionalFixed32" json:"optional_fixed32,omitempty"`
+	OptionalFixed64        uint64                      `protobuf:"fixed64,8,opt,name=optional_fixed64,json=optionalFixed64" json:"optional_fixed64,omitempty"`
+	OptionalSfixed32       int32                       `protobuf:"fixed32,9,opt,name=optional_sfixed32,json=optionalSfixed32" json:"optional_sfixed32,omitempty"`
+	OptionalSfixed64       int64                       `protobuf:"fixed64,10,opt,name=optional_sfixed64,json=optionalSfixed64" json:"optional_sfixed64,omitempty"`
+	OptionalFloat          float32                     `protobuf:"fixed32,11,opt,name=optional_float,json=optionalFloat" json:"optional_float,omitempty"`
+	OptionalDouble         float64                     `protobuf:"fixed64,12,opt,name=optional_double,json=optionalDouble" json:"optional_double,omitempty"`
+	OptionalBool           bool                        `protobuf:"varint,13,opt,name=optional_bool,json=optionalBool" json:"optional_bool,omitempty"`
+	OptionalString         string                      `protobuf:"bytes,14,opt,name=optional_string,json=optionalString" json:"optional_string,omitempty"`
+	OptionalBytes          []byte                      `protobuf:"bytes,15,opt,name=optional_bytes,json=optionalBytes,proto3" json:"optional_bytes,omitempty"`
+	OptionalNestedMessage  *TestAllTypes_NestedMessage `protobuf:"bytes,18,opt,name=optional_nested_message,json=optionalNestedMessage" json:"optional_nested_message,omitempty"`
+	OptionalForeignMessage *ForeignMessage             `protobuf:"bytes,19,opt,name=optional_foreign_message,json=optionalForeignMessage" json:"optional_foreign_message,omitempty"`
+	OptionalNestedEnum     TestAllTypes_NestedEnum     `protobuf:"varint,21,opt,name=optional_nested_enum,json=optionalNestedEnum,enum=conformance.TestAllTypes_NestedEnum" json:"optional_nested_enum,omitempty"`
+	OptionalForeignEnum    ForeignEnum                 `protobuf:"varint,22,opt,name=optional_foreign_enum,json=optionalForeignEnum,enum=conformance.ForeignEnum" json:"optional_foreign_enum,omitempty"`
+	OptionalStringPiece    string                      `protobuf:"bytes,24,opt,name=optional_string_piece,json=optionalStringPiece" json:"optional_string_piece,omitempty"`
+	OptionalCord           string                      `protobuf:"bytes,25,opt,name=optional_cord,json=optionalCord" json:"optional_cord,omitempty"`
+	RecursiveMessage       *TestAllTypes               `protobuf:"bytes,27,opt,name=recursive_message,json=recursiveMessage" json:"recursive_message,omitempty"`
+	// Repeated
+	RepeatedInt32          []int32                       `protobuf:"varint,31,rep,packed,name=repeated_int32,json=repeatedInt32" json:"repeated_int32,omitempty"`
+	RepeatedInt64          []int64                       `protobuf:"varint,32,rep,packed,name=repeated_int64,json=repeatedInt64" json:"repeated_int64,omitempty"`
+	RepeatedUint32         []uint32                      `protobuf:"varint,33,rep,packed,name=repeated_uint32,json=repeatedUint32" json:"repeated_uint32,omitempty"`
+	RepeatedUint64         []uint64                      `protobuf:"varint,34,rep,packed,name=repeated_uint64,json=repeatedUint64" json:"repeated_uint64,omitempty"`
+	RepeatedSint32         []int32                       `protobuf:"zigzag32,35,rep,packed,name=repeated_sint32,json=repeatedSint32" json:"repeated_sint32,omitempty"`
+	RepeatedSint64         []int64                       `protobuf:"zigzag64,36,rep,packed,name=repeated_sint64,json=repeatedSint64" json:"repeated_sint64,omitempty"`
+	RepeatedFixed32        []uint32                      `protobuf:"fixed32,37,rep,packed,name=repeated_fixed32,json=repeatedFixed32" json:"repeated_fixed32,omitempty"`
+	RepeatedFixed64        []uint64                      `protobuf:"fixed64,38,rep,packed,name=repeated_fixed64,json=repeatedFixed64" json:"repeated_fixed64,omitempty"`
+	RepeatedSfixed32       []int32                       `protobuf:"fixed32,39,rep,packed,name=repeated_sfixed32,json=repeatedSfixed32" json:"repeated_sfixed32,omitempty"`
+	RepeatedSfixed64       []int64                       `protobuf:"fixed64,40,rep,packed,name=repeated_sfixed64,json=repeatedSfixed64" json:"repeated_sfixed64,omitempty"`
+	RepeatedFloat          []float32                     `protobuf:"fixed32,41,rep,packed,name=repeated_float,json=repeatedFloat" json:"repeated_float,omitempty"`
+	RepeatedDouble         []float64                     `protobuf:"fixed64,42,rep,packed,name=repeated_double,json=repeatedDouble" json:"repeated_double,omitempty"`
+	RepeatedBool           []bool                        `protobuf:"varint,43,rep,packed,name=repeated_bool,json=repeatedBool" json:"repeated_bool,omitempty"`
+	RepeatedString         []string                      `protobuf:"bytes,44,rep,name=repeated_string,json=repeatedString" json:"repeated_string,omitempty"`
+	RepeatedBytes          [][]byte                      `protobuf:"bytes,45,rep,name=repeated_bytes,json=repeatedBytes,proto3" json:"repeated_bytes,omitempty"`
+	RepeatedNestedMessage  []*TestAllTypes_NestedMessage `protobuf:"bytes,48,rep,name=repeated_nested_message,json=repeatedNestedMessage" json:"repeated_nested_message,omitempty"`
+	RepeatedForeignMessage []*ForeignMessage             `protobuf:"bytes,49,rep,name=repeated_foreign_message,json=repeatedForeignMessage" json:"repeated_foreign_message,omitempty"`
+	RepeatedNestedEnum     []TestAllTypes_NestedEnum     `protobuf:"varint,51,rep,packed,name=repeated_nested_enum,json=repeatedNestedEnum,enum=conformance.TestAllTypes_NestedEnum" json:"repeated_nested_enum,omitempty"`
+	RepeatedForeignEnum    []ForeignEnum                 `protobuf:"varint,52,rep,packed,name=repeated_foreign_enum,json=repeatedForeignEnum,enum=conformance.ForeignEnum" json:"repeated_foreign_enum,omitempty"`
+	RepeatedStringPiece    []string                      `protobuf:"bytes,54,rep,name=repeated_string_piece,json=repeatedStringPiece" json:"repeated_string_piece,omitempty"`
+	RepeatedCord           []string                      `protobuf:"bytes,55,rep,name=repeated_cord,json=repeatedCord" json:"repeated_cord,omitempty"`
+	// Map
+	MapInt32Int32           map[int32]int32                        `protobuf:"bytes,56,rep,name=map_int32_int32,json=mapInt32Int32" json:"map_int32_int32,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	MapInt64Int64           map[int64]int64                        `protobuf:"bytes,57,rep,name=map_int64_int64,json=mapInt64Int64" json:"map_int64_int64,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	MapUint32Uint32         map[uint32]uint32                      `protobuf:"bytes,58,rep,name=map_uint32_uint32,json=mapUint32Uint32" json:"map_uint32_uint32,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	MapUint64Uint64         map[uint64]uint64                      `protobuf:"bytes,59,rep,name=map_uint64_uint64,json=mapUint64Uint64" json:"map_uint64_uint64,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	MapSint32Sint32         map[int32]int32                        `protobuf:"bytes,60,rep,name=map_sint32_sint32,json=mapSint32Sint32" json:"map_sint32_sint32,omitempty" protobuf_key:"zigzag32,1,opt,name=key" protobuf_val:"zigzag32,2,opt,name=value"`
+	MapSint64Sint64         map[int64]int64                        `protobuf:"bytes,61,rep,name=map_sint64_sint64,json=mapSint64Sint64" json:"map_sint64_sint64,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"zigzag64,2,opt,name=value"`
+	MapFixed32Fixed32       map[uint32]uint32                      `protobuf:"bytes,62,rep,name=map_fixed32_fixed32,json=mapFixed32Fixed32" json:"map_fixed32_fixed32,omitempty" protobuf_key:"fixed32,1,opt,name=key" protobuf_val:"fixed32,2,opt,name=value"`
+	MapFixed64Fixed64       map[uint64]uint64                      `protobuf:"bytes,63,rep,name=map_fixed64_fixed64,json=mapFixed64Fixed64" json:"map_fixed64_fixed64,omitempty" protobuf_key:"fixed64,1,opt,name=key" protobuf_val:"fixed64,2,opt,name=value"`
+	MapSfixed32Sfixed32     map[int32]int32                        `protobuf:"bytes,64,rep,name=map_sfixed32_sfixed32,json=mapSfixed32Sfixed32" json:"map_sfixed32_sfixed32,omitempty" protobuf_key:"fixed32,1,opt,name=key" protobuf_val:"fixed32,2,opt,name=value"`
+	MapSfixed64Sfixed64     map[int64]int64                        `protobuf:"bytes,65,rep,name=map_sfixed64_sfixed64,json=mapSfixed64Sfixed64" json:"map_sfixed64_sfixed64,omitempty" protobuf_key:"fixed64,1,opt,name=key" protobuf_val:"fixed64,2,opt,name=value"`
+	MapInt32Float           map[int32]float32                      `protobuf:"bytes,66,rep,name=map_int32_float,json=mapInt32Float" json:"map_int32_float,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"fixed32,2,opt,name=value"`
+	MapInt32Double          map[int32]float64                      `protobuf:"bytes,67,rep,name=map_int32_double,json=mapInt32Double" json:"map_int32_double,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"fixed64,2,opt,name=value"`
+	MapBoolBool             map[bool]bool                          `protobuf:"bytes,68,rep,name=map_bool_bool,json=mapBoolBool" json:"map_bool_bool,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	MapStringString         map[string]string                      `protobuf:"bytes,69,rep,name=map_string_string,json=mapStringString" json:"map_string_string,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	MapStringBytes          map[string][]byte                      `protobuf:"bytes,70,rep,name=map_string_bytes,json=mapStringBytes" json:"map_string_bytes,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	MapStringNestedMessage  map[string]*TestAllTypes_NestedMessage `protobuf:"bytes,71,rep,name=map_string_nested_message,json=mapStringNestedMessage" json:"map_string_nested_message,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	MapStringForeignMessage map[string]*ForeignMessage             `protobuf:"bytes,72,rep,name=map_string_foreign_message,json=mapStringForeignMessage" json:"map_string_foreign_message,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	MapStringNestedEnum     map[string]TestAllTypes_NestedEnum     `protobuf:"bytes,73,rep,name=map_string_nested_enum,json=mapStringNestedEnum" json:"map_string_nested_enum,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value,enum=conformance.TestAllTypes_NestedEnum"`
+	MapStringForeignEnum    map[string]ForeignEnum                 `protobuf:"bytes,74,rep,name=map_string_foreign_enum,json=mapStringForeignEnum" json:"map_string_foreign_enum,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value,enum=conformance.ForeignEnum"`
+	// Types that are valid to be assigned to OneofField:
+	//	*TestAllTypes_OneofUint32
+	//	*TestAllTypes_OneofNestedMessage
+	//	*TestAllTypes_OneofString
+	//	*TestAllTypes_OneofBytes
+	OneofField isTestAllTypes_OneofField `protobuf_oneof:"oneof_field"`
+	// Well-known types
+	OptionalBoolWrapper   *wrappers.BoolValue     `protobuf:"bytes,201,opt,name=optional_bool_wrapper,json=optionalBoolWrapper" json:"optional_bool_wrapper,omitempty"`
+	OptionalInt32Wrapper  *wrappers.Int32Value    `protobuf:"bytes,202,opt,name=optional_int32_wrapper,json=optionalInt32Wrapper" json:"optional_int32_wrapper,omitempty"`
+	OptionalInt64Wrapper  *wrappers.Int64Value    `protobuf:"bytes,203,opt,name=optional_int64_wrapper,json=optionalInt64Wrapper" json:"optional_int64_wrapper,omitempty"`
+	OptionalUint32Wrapper *wrappers.UInt32Value   `protobuf:"bytes,204,opt,name=optional_uint32_wrapper,json=optionalUint32Wrapper" json:"optional_uint32_wrapper,omitempty"`
+	OptionalUint64Wrapper *wrappers.UInt64Value   `protobuf:"bytes,205,opt,name=optional_uint64_wrapper,json=optionalUint64Wrapper" json:"optional_uint64_wrapper,omitempty"`
+	OptionalFloatWrapper  *wrappers.FloatValue    `protobuf:"bytes,206,opt,name=optional_float_wrapper,json=optionalFloatWrapper" json:"optional_float_wrapper,omitempty"`
+	OptionalDoubleWrapper *wrappers.DoubleValue   `protobuf:"bytes,207,opt,name=optional_double_wrapper,json=optionalDoubleWrapper" json:"optional_double_wrapper,omitempty"`
+	OptionalStringWrapper *wrappers.StringValue   `protobuf:"bytes,208,opt,name=optional_string_wrapper,json=optionalStringWrapper" json:"optional_string_wrapper,omitempty"`
+	OptionalBytesWrapper  *wrappers.BytesValue    `protobuf:"bytes,209,opt,name=optional_bytes_wrapper,json=optionalBytesWrapper" json:"optional_bytes_wrapper,omitempty"`
+	RepeatedBoolWrapper   []*wrappers.BoolValue   `protobuf:"bytes,211,rep,name=repeated_bool_wrapper,json=repeatedBoolWrapper" json:"repeated_bool_wrapper,omitempty"`
+	RepeatedInt32Wrapper  []*wrappers.Int32Value  `protobuf:"bytes,212,rep,name=repeated_int32_wrapper,json=repeatedInt32Wrapper" json:"repeated_int32_wrapper,omitempty"`
+	RepeatedInt64Wrapper  []*wrappers.Int64Value  `protobuf:"bytes,213,rep,name=repeated_int64_wrapper,json=repeatedInt64Wrapper" json:"repeated_int64_wrapper,omitempty"`
+	RepeatedUint32Wrapper []*wrappers.UInt32Value `protobuf:"bytes,214,rep,name=repeated_uint32_wrapper,json=repeatedUint32Wrapper" json:"repeated_uint32_wrapper,omitempty"`
+	RepeatedUint64Wrapper []*wrappers.UInt64Value `protobuf:"bytes,215,rep,name=repeated_uint64_wrapper,json=repeatedUint64Wrapper" json:"repeated_uint64_wrapper,omitempty"`
+	RepeatedFloatWrapper  []*wrappers.FloatValue  `protobuf:"bytes,216,rep,name=repeated_float_wrapper,json=repeatedFloatWrapper" json:"repeated_float_wrapper,omitempty"`
+	RepeatedDoubleWrapper []*wrappers.DoubleValue `protobuf:"bytes,217,rep,name=repeated_double_wrapper,json=repeatedDoubleWrapper" json:"repeated_double_wrapper,omitempty"`
+	RepeatedStringWrapper []*wrappers.StringValue `protobuf:"bytes,218,rep,name=repeated_string_wrapper,json=repeatedStringWrapper" json:"repeated_string_wrapper,omitempty"`
+	RepeatedBytesWrapper  []*wrappers.BytesValue  `protobuf:"bytes,219,rep,name=repeated_bytes_wrapper,json=repeatedBytesWrapper" json:"repeated_bytes_wrapper,omitempty"`
+	OptionalDuration      *duration.Duration      `protobuf:"bytes,301,opt,name=optional_duration,json=optionalDuration" json:"optional_duration,omitempty"`
+	OptionalTimestamp     *timestamp.Timestamp    `protobuf:"bytes,302,opt,name=optional_timestamp,json=optionalTimestamp" json:"optional_timestamp,omitempty"`
+	OptionalFieldMask     *field_mask.FieldMask   `protobuf:"bytes,303,opt,name=optional_field_mask,json=optionalFieldMask" json:"optional_field_mask,omitempty"`
+	OptionalStruct        *_struct.Struct         `protobuf:"bytes,304,opt,name=optional_struct,json=optionalStruct" json:"optional_struct,omitempty"`
+	OptionalAny           *any.Any                `protobuf:"bytes,305,opt,name=optional_any,json=optionalAny" json:"optional_any,omitempty"`
+	OptionalValue         *_struct.Value          `protobuf:"bytes,306,opt,name=optional_value,json=optionalValue" json:"optional_value,omitempty"`
+	RepeatedDuration      []*duration.Duration    `protobuf:"bytes,311,rep,name=repeated_duration,json=repeatedDuration" json:"repeated_duration,omitempty"`
+	RepeatedTimestamp     []*timestamp.Timestamp  `protobuf:"bytes,312,rep,name=repeated_timestamp,json=repeatedTimestamp" json:"repeated_timestamp,omitempty"`
+	RepeatedFieldmask     []*field_mask.FieldMask `protobuf:"bytes,313,rep,name=repeated_fieldmask,json=repeatedFieldmask" json:"repeated_fieldmask,omitempty"`
+	RepeatedStruct        []*_struct.Struct       `protobuf:"bytes,324,rep,name=repeated_struct,json=repeatedStruct" json:"repeated_struct,omitempty"`
+	RepeatedAny           []*any.Any              `protobuf:"bytes,315,rep,name=repeated_any,json=repeatedAny" json:"repeated_any,omitempty"`
+	RepeatedValue         []*_struct.Value        `protobuf:"bytes,316,rep,name=repeated_value,json=repeatedValue" json:"repeated_value,omitempty"`
+	// Test field-name-to-JSON-name convention.
+	Fieldname1           int32    `protobuf:"varint,401,opt,name=fieldname1" json:"fieldname1,omitempty"`
+	FieldName2           int32    `protobuf:"varint,402,opt,name=field_name2,json=fieldName2" json:"field_name2,omitempty"`
+	XFieldName3          int32    `protobuf:"varint,403,opt,name=_field_name3,json=FieldName3" json:"_field_name3,omitempty"`
+	Field_Name4_         int32    `protobuf:"varint,404,opt,name=field__name4_,json=fieldName4" json:"field__name4_,omitempty"`
+	Field0Name5          int32    `protobuf:"varint,405,opt,name=field0name5" json:"field0name5,omitempty"`
+	Field_0Name6         int32    `protobuf:"varint,406,opt,name=field_0_name6,json=field0Name6" json:"field_0_name6,omitempty"`
+	FieldName7           int32    `protobuf:"varint,407,opt,name=fieldName7" json:"fieldName7,omitempty"`
+	FieldName8           int32    `protobuf:"varint,408,opt,name=FieldName8" json:"FieldName8,omitempty"`
+	Field_Name9          int32    `protobuf:"varint,409,opt,name=field_Name9,json=fieldName9" json:"field_Name9,omitempty"`
+	Field_Name10         int32    `protobuf:"varint,410,opt,name=Field_Name10,json=FieldName10" json:"Field_Name10,omitempty"`
+	FIELD_NAME11         int32    `protobuf:"varint,411,opt,name=FIELD_NAME11,json=FIELDNAME11" json:"FIELD_NAME11,omitempty"`
+	FIELDName12          int32    `protobuf:"varint,412,opt,name=FIELD_name12,json=FIELDName12" json:"FIELD_name12,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *TestAllTypes) Reset()         { *m = TestAllTypes{} }
+func (m *TestAllTypes) String() string { return proto.CompactTextString(m) }
+func (*TestAllTypes) ProtoMessage()    {}
+func (*TestAllTypes) Descriptor() ([]byte, []int) {
+	return fileDescriptor_conformance_48ac832451f5d6c3, []int{2}
+}
+func (m *TestAllTypes) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TestAllTypes.Unmarshal(m, b)
+}
+func (m *TestAllTypes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TestAllTypes.Marshal(b, m, deterministic)
+}
+func (dst *TestAllTypes) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TestAllTypes.Merge(dst, src)
+}
+func (m *TestAllTypes) XXX_Size() int {
+	return xxx_messageInfo_TestAllTypes.Size(m)
+}
+func (m *TestAllTypes) XXX_DiscardUnknown() {
+	xxx_messageInfo_TestAllTypes.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TestAllTypes proto.InternalMessageInfo
+
+type isTestAllTypes_OneofField interface {
+	isTestAllTypes_OneofField()
+}
+
+type TestAllTypes_OneofUint32 struct {
+	OneofUint32 uint32 `protobuf:"varint,111,opt,name=oneof_uint32,json=oneofUint32,oneof"`
+}
+type TestAllTypes_OneofNestedMessage struct {
+	OneofNestedMessage *TestAllTypes_NestedMessage `protobuf:"bytes,112,opt,name=oneof_nested_message,json=oneofNestedMessage,oneof"`
+}
+type TestAllTypes_OneofString struct {
+	OneofString string `protobuf:"bytes,113,opt,name=oneof_string,json=oneofString,oneof"`
+}
+type TestAllTypes_OneofBytes struct {
+	OneofBytes []byte `protobuf:"bytes,114,opt,name=oneof_bytes,json=oneofBytes,proto3,oneof"`
+}
+
+func (*TestAllTypes_OneofUint32) isTestAllTypes_OneofField()        {}
+func (*TestAllTypes_OneofNestedMessage) isTestAllTypes_OneofField() {}
+func (*TestAllTypes_OneofString) isTestAllTypes_OneofField()        {}
+func (*TestAllTypes_OneofBytes) isTestAllTypes_OneofField()         {}
+
+func (m *TestAllTypes) GetOneofField() isTestAllTypes_OneofField {
+	if m != nil {
+		return m.OneofField
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalInt32() int32 {
+	if m != nil {
+		return m.OptionalInt32
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetOptionalInt64() int64 {
+	if m != nil {
+		return m.OptionalInt64
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetOptionalUint32() uint32 {
+	if m != nil {
+		return m.OptionalUint32
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetOptionalUint64() uint64 {
+	if m != nil {
+		return m.OptionalUint64
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetOptionalSint32() int32 {
+	if m != nil {
+		return m.OptionalSint32
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetOptionalSint64() int64 {
+	if m != nil {
+		return m.OptionalSint64
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetOptionalFixed32() uint32 {
+	if m != nil {
+		return m.OptionalFixed32
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetOptionalFixed64() uint64 {
+	if m != nil {
+		return m.OptionalFixed64
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetOptionalSfixed32() int32 {
+	if m != nil {
+		return m.OptionalSfixed32
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetOptionalSfixed64() int64 {
+	if m != nil {
+		return m.OptionalSfixed64
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetOptionalFloat() float32 {
+	if m != nil {
+		return m.OptionalFloat
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetOptionalDouble() float64 {
+	if m != nil {
+		return m.OptionalDouble
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetOptionalBool() bool {
+	if m != nil {
+		return m.OptionalBool
+	}
+	return false
+}
+
+func (m *TestAllTypes) GetOptionalString() string {
+	if m != nil {
+		return m.OptionalString
+	}
+	return ""
+}
+
+func (m *TestAllTypes) GetOptionalBytes() []byte {
+	if m != nil {
+		return m.OptionalBytes
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalNestedMessage() *TestAllTypes_NestedMessage {
+	if m != nil {
+		return m.OptionalNestedMessage
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalForeignMessage() *ForeignMessage {
+	if m != nil {
+		return m.OptionalForeignMessage
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalNestedEnum() TestAllTypes_NestedEnum {
+	if m != nil {
+		return m.OptionalNestedEnum
+	}
+	return TestAllTypes_FOO
+}
+
+func (m *TestAllTypes) GetOptionalForeignEnum() ForeignEnum {
+	if m != nil {
+		return m.OptionalForeignEnum
+	}
+	return ForeignEnum_FOREIGN_FOO
+}
+
+func (m *TestAllTypes) GetOptionalStringPiece() string {
+	if m != nil {
+		return m.OptionalStringPiece
+	}
+	return ""
+}
+
+func (m *TestAllTypes) GetOptionalCord() string {
+	if m != nil {
+		return m.OptionalCord
+	}
+	return ""
+}
+
+func (m *TestAllTypes) GetRecursiveMessage() *TestAllTypes {
+	if m != nil {
+		return m.RecursiveMessage
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedInt32() []int32 {
+	if m != nil {
+		return m.RepeatedInt32
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedInt64() []int64 {
+	if m != nil {
+		return m.RepeatedInt64
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedUint32() []uint32 {
+	if m != nil {
+		return m.RepeatedUint32
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedUint64() []uint64 {
+	if m != nil {
+		return m.RepeatedUint64
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedSint32() []int32 {
+	if m != nil {
+		return m.RepeatedSint32
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedSint64() []int64 {
+	if m != nil {
+		return m.RepeatedSint64
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedFixed32() []uint32 {
+	if m != nil {
+		return m.RepeatedFixed32
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedFixed64() []uint64 {
+	if m != nil {
+		return m.RepeatedFixed64
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedSfixed32() []int32 {
+	if m != nil {
+		return m.RepeatedSfixed32
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedSfixed64() []int64 {
+	if m != nil {
+		return m.RepeatedSfixed64
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedFloat() []float32 {
+	if m != nil {
+		return m.RepeatedFloat
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedDouble() []float64 {
+	if m != nil {
+		return m.RepeatedDouble
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedBool() []bool {
+	if m != nil {
+		return m.RepeatedBool
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedString() []string {
+	if m != nil {
+		return m.RepeatedString
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedBytes() [][]byte {
+	if m != nil {
+		return m.RepeatedBytes
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedNestedMessage() []*TestAllTypes_NestedMessage {
+	if m != nil {
+		return m.RepeatedNestedMessage
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedForeignMessage() []*ForeignMessage {
+	if m != nil {
+		return m.RepeatedForeignMessage
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedNestedEnum() []TestAllTypes_NestedEnum {
+	if m != nil {
+		return m.RepeatedNestedEnum
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedForeignEnum() []ForeignEnum {
+	if m != nil {
+		return m.RepeatedForeignEnum
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedStringPiece() []string {
+	if m != nil {
+		return m.RepeatedStringPiece
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedCord() []string {
+	if m != nil {
+		return m.RepeatedCord
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapInt32Int32() map[int32]int32 {
+	if m != nil {
+		return m.MapInt32Int32
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapInt64Int64() map[int64]int64 {
+	if m != nil {
+		return m.MapInt64Int64
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapUint32Uint32() map[uint32]uint32 {
+	if m != nil {
+		return m.MapUint32Uint32
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapUint64Uint64() map[uint64]uint64 {
+	if m != nil {
+		return m.MapUint64Uint64
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapSint32Sint32() map[int32]int32 {
+	if m != nil {
+		return m.MapSint32Sint32
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapSint64Sint64() map[int64]int64 {
+	if m != nil {
+		return m.MapSint64Sint64
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapFixed32Fixed32() map[uint32]uint32 {
+	if m != nil {
+		return m.MapFixed32Fixed32
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapFixed64Fixed64() map[uint64]uint64 {
+	if m != nil {
+		return m.MapFixed64Fixed64
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapSfixed32Sfixed32() map[int32]int32 {
+	if m != nil {
+		return m.MapSfixed32Sfixed32
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapSfixed64Sfixed64() map[int64]int64 {
+	if m != nil {
+		return m.MapSfixed64Sfixed64
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapInt32Float() map[int32]float32 {
+	if m != nil {
+		return m.MapInt32Float
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapInt32Double() map[int32]float64 {
+	if m != nil {
+		return m.MapInt32Double
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapBoolBool() map[bool]bool {
+	if m != nil {
+		return m.MapBoolBool
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapStringString() map[string]string {
+	if m != nil {
+		return m.MapStringString
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapStringBytes() map[string][]byte {
+	if m != nil {
+		return m.MapStringBytes
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapStringNestedMessage() map[string]*TestAllTypes_NestedMessage {
+	if m != nil {
+		return m.MapStringNestedMessage
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapStringForeignMessage() map[string]*ForeignMessage {
+	if m != nil {
+		return m.MapStringForeignMessage
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapStringNestedEnum() map[string]TestAllTypes_NestedEnum {
+	if m != nil {
+		return m.MapStringNestedEnum
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetMapStringForeignEnum() map[string]ForeignEnum {
+	if m != nil {
+		return m.MapStringForeignEnum
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOneofUint32() uint32 {
+	if x, ok := m.GetOneofField().(*TestAllTypes_OneofUint32); ok {
+		return x.OneofUint32
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetOneofNestedMessage() *TestAllTypes_NestedMessage {
+	if x, ok := m.GetOneofField().(*TestAllTypes_OneofNestedMessage); ok {
+		return x.OneofNestedMessage
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOneofString() string {
+	if x, ok := m.GetOneofField().(*TestAllTypes_OneofString); ok {
+		return x.OneofString
+	}
+	return ""
+}
+
+func (m *TestAllTypes) GetOneofBytes() []byte {
+	if x, ok := m.GetOneofField().(*TestAllTypes_OneofBytes); ok {
+		return x.OneofBytes
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalBoolWrapper() *wrappers.BoolValue {
+	if m != nil {
+		return m.OptionalBoolWrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalInt32Wrapper() *wrappers.Int32Value {
+	if m != nil {
+		return m.OptionalInt32Wrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalInt64Wrapper() *wrappers.Int64Value {
+	if m != nil {
+		return m.OptionalInt64Wrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalUint32Wrapper() *wrappers.UInt32Value {
+	if m != nil {
+		return m.OptionalUint32Wrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalUint64Wrapper() *wrappers.UInt64Value {
+	if m != nil {
+		return m.OptionalUint64Wrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalFloatWrapper() *wrappers.FloatValue {
+	if m != nil {
+		return m.OptionalFloatWrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalDoubleWrapper() *wrappers.DoubleValue {
+	if m != nil {
+		return m.OptionalDoubleWrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalStringWrapper() *wrappers.StringValue {
+	if m != nil {
+		return m.OptionalStringWrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalBytesWrapper() *wrappers.BytesValue {
+	if m != nil {
+		return m.OptionalBytesWrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedBoolWrapper() []*wrappers.BoolValue {
+	if m != nil {
+		return m.RepeatedBoolWrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedInt32Wrapper() []*wrappers.Int32Value {
+	if m != nil {
+		return m.RepeatedInt32Wrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedInt64Wrapper() []*wrappers.Int64Value {
+	if m != nil {
+		return m.RepeatedInt64Wrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedUint32Wrapper() []*wrappers.UInt32Value {
+	if m != nil {
+		return m.RepeatedUint32Wrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedUint64Wrapper() []*wrappers.UInt64Value {
+	if m != nil {
+		return m.RepeatedUint64Wrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedFloatWrapper() []*wrappers.FloatValue {
+	if m != nil {
+		return m.RepeatedFloatWrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedDoubleWrapper() []*wrappers.DoubleValue {
+	if m != nil {
+		return m.RepeatedDoubleWrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedStringWrapper() []*wrappers.StringValue {
+	if m != nil {
+		return m.RepeatedStringWrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedBytesWrapper() []*wrappers.BytesValue {
+	if m != nil {
+		return m.RepeatedBytesWrapper
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalDuration() *duration.Duration {
+	if m != nil {
+		return m.OptionalDuration
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalTimestamp() *timestamp.Timestamp {
+	if m != nil {
+		return m.OptionalTimestamp
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalFieldMask() *field_mask.FieldMask {
+	if m != nil {
+		return m.OptionalFieldMask
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalStruct() *_struct.Struct {
+	if m != nil {
+		return m.OptionalStruct
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalAny() *any.Any {
+	if m != nil {
+		return m.OptionalAny
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetOptionalValue() *_struct.Value {
+	if m != nil {
+		return m.OptionalValue
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedDuration() []*duration.Duration {
+	if m != nil {
+		return m.RepeatedDuration
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedTimestamp() []*timestamp.Timestamp {
+	if m != nil {
+		return m.RepeatedTimestamp
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedFieldmask() []*field_mask.FieldMask {
+	if m != nil {
+		return m.RepeatedFieldmask
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedStruct() []*_struct.Struct {
+	if m != nil {
+		return m.RepeatedStruct
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedAny() []*any.Any {
+	if m != nil {
+		return m.RepeatedAny
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetRepeatedValue() []*_struct.Value {
+	if m != nil {
+		return m.RepeatedValue
+	}
+	return nil
+}
+
+func (m *TestAllTypes) GetFieldname1() int32 {
+	if m != nil {
+		return m.Fieldname1
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetFieldName2() int32 {
+	if m != nil {
+		return m.FieldName2
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetXFieldName3() int32 {
+	if m != nil {
+		return m.XFieldName3
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetField_Name4_() int32 {
+	if m != nil {
+		return m.Field_Name4_
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetField0Name5() int32 {
+	if m != nil {
+		return m.Field0Name5
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetField_0Name6() int32 {
+	if m != nil {
+		return m.Field_0Name6
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetFieldName7() int32 {
+	if m != nil {
+		return m.FieldName7
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetFieldName8() int32 {
+	if m != nil {
+		return m.FieldName8
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetField_Name9() int32 {
+	if m != nil {
+		return m.Field_Name9
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetField_Name10() int32 {
+	if m != nil {
+		return m.Field_Name10
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetFIELD_NAME11() int32 {
+	if m != nil {
+		return m.FIELD_NAME11
+	}
+	return 0
+}
+
+func (m *TestAllTypes) GetFIELDName12() int32 {
+	if m != nil {
+		return m.FIELDName12
+	}
+	return 0
+}
+
+// XXX_OneofFuncs is for the internal use of the proto package.
+func (*TestAllTypes) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
+	return _TestAllTypes_OneofMarshaler, _TestAllTypes_OneofUnmarshaler, _TestAllTypes_OneofSizer, []interface{}{
+		(*TestAllTypes_OneofUint32)(nil),
+		(*TestAllTypes_OneofNestedMessage)(nil),
+		(*TestAllTypes_OneofString)(nil),
+		(*TestAllTypes_OneofBytes)(nil),
+	}
+}
+
+func _TestAllTypes_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
+	m := msg.(*TestAllTypes)
+	// oneof_field
+	switch x := m.OneofField.(type) {
+	case *TestAllTypes_OneofUint32:
+		b.EncodeVarint(111<<3 | proto.WireVarint)
+		b.EncodeVarint(uint64(x.OneofUint32))
+	case *TestAllTypes_OneofNestedMessage:
+		b.EncodeVarint(112<<3 | proto.WireBytes)
+		if err := b.EncodeMessage(x.OneofNestedMessage); err != nil {
+			return err
+		}
+	case *TestAllTypes_OneofString:
+		b.EncodeVarint(113<<3 | proto.WireBytes)
+		b.EncodeStringBytes(x.OneofString)
+	case *TestAllTypes_OneofBytes:
+		b.EncodeVarint(114<<3 | proto.WireBytes)
+		b.EncodeRawBytes(x.OneofBytes)
+	case nil:
+	default:
+		return fmt.Errorf("TestAllTypes.OneofField has unexpected type %T", x)
+	}
+	return nil
+}
+
+func _TestAllTypes_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
+	m := msg.(*TestAllTypes)
+	switch tag {
+	case 111: // oneof_field.oneof_uint32
+		if wire != proto.WireVarint {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeVarint()
+		m.OneofField = &TestAllTypes_OneofUint32{uint32(x)}
+		return true, err
+	case 112: // oneof_field.oneof_nested_message
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		msg := new(TestAllTypes_NestedMessage)
+		err := b.DecodeMessage(msg)
+		m.OneofField = &TestAllTypes_OneofNestedMessage{msg}
+		return true, err
+	case 113: // oneof_field.oneof_string
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeStringBytes()
+		m.OneofField = &TestAllTypes_OneofString{x}
+		return true, err
+	case 114: // oneof_field.oneof_bytes
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeRawBytes(true)
+		m.OneofField = &TestAllTypes_OneofBytes{x}
+		return true, err
+	default:
+		return false, nil
+	}
+}
+
+func _TestAllTypes_OneofSizer(msg proto.Message) (n int) {
+	m := msg.(*TestAllTypes)
+	// oneof_field
+	switch x := m.OneofField.(type) {
+	case *TestAllTypes_OneofUint32:
+		n += 2 // tag and wire
+		n += proto.SizeVarint(uint64(x.OneofUint32))
+	case *TestAllTypes_OneofNestedMessage:
+		s := proto.Size(x.OneofNestedMessage)
+		n += 2 // tag and wire
+		n += proto.SizeVarint(uint64(s))
+		n += s
+	case *TestAllTypes_OneofString:
+		n += 2 // tag and wire
+		n += proto.SizeVarint(uint64(len(x.OneofString)))
+		n += len(x.OneofString)
+	case *TestAllTypes_OneofBytes:
+		n += 2 // tag and wire
+		n += proto.SizeVarint(uint64(len(x.OneofBytes)))
+		n += len(x.OneofBytes)
+	case nil:
+	default:
+		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
+	}
+	return n
+}
+
+type TestAllTypes_NestedMessage struct {
+	A                    int32         `protobuf:"varint,1,opt,name=a" json:"a,omitempty"`
+	Corecursive          *TestAllTypes `protobuf:"bytes,2,opt,name=corecursive" json:"corecursive,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}      `json:"-"`
+	XXX_unrecognized     []byte        `json:"-"`
+	XXX_sizecache        int32         `json:"-"`
+}
+
+func (m *TestAllTypes_NestedMessage) Reset()         { *m = TestAllTypes_NestedMessage{} }
+func (m *TestAllTypes_NestedMessage) String() string { return proto.CompactTextString(m) }
+func (*TestAllTypes_NestedMessage) ProtoMessage()    {}
+func (*TestAllTypes_NestedMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_conformance_48ac832451f5d6c3, []int{2, 0}
+}
+func (m *TestAllTypes_NestedMessage) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TestAllTypes_NestedMessage.Unmarshal(m, b)
+}
+func (m *TestAllTypes_NestedMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TestAllTypes_NestedMessage.Marshal(b, m, deterministic)
+}
+func (dst *TestAllTypes_NestedMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TestAllTypes_NestedMessage.Merge(dst, src)
+}
+func (m *TestAllTypes_NestedMessage) XXX_Size() int {
+	return xxx_messageInfo_TestAllTypes_NestedMessage.Size(m)
+}
+func (m *TestAllTypes_NestedMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_TestAllTypes_NestedMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TestAllTypes_NestedMessage proto.InternalMessageInfo
+
+func (m *TestAllTypes_NestedMessage) GetA() int32 {
+	if m != nil {
+		return m.A
+	}
+	return 0
+}
+
+func (m *TestAllTypes_NestedMessage) GetCorecursive() *TestAllTypes {
+	if m != nil {
+		return m.Corecursive
+	}
+	return nil
+}
+
+type ForeignMessage struct {
+	C                    int32    `protobuf:"varint,1,opt,name=c" json:"c,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *ForeignMessage) Reset()         { *m = ForeignMessage{} }
+func (m *ForeignMessage) String() string { return proto.CompactTextString(m) }
+func (*ForeignMessage) ProtoMessage()    {}
+func (*ForeignMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_conformance_48ac832451f5d6c3, []int{3}
+}
+func (m *ForeignMessage) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_ForeignMessage.Unmarshal(m, b)
+}
+func (m *ForeignMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_ForeignMessage.Marshal(b, m, deterministic)
+}
+func (dst *ForeignMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_ForeignMessage.Merge(dst, src)
+}
+func (m *ForeignMessage) XXX_Size() int {
+	return xxx_messageInfo_ForeignMessage.Size(m)
+}
+func (m *ForeignMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_ForeignMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ForeignMessage proto.InternalMessageInfo
+
+func (m *ForeignMessage) GetC() int32 {
+	if m != nil {
+		return m.C
+	}
+	return 0
+}
+
+func init() {
+	proto.RegisterType((*ConformanceRequest)(nil), "conformance.ConformanceRequest")
+	proto.RegisterType((*ConformanceResponse)(nil), "conformance.ConformanceResponse")
+	proto.RegisterType((*TestAllTypes)(nil), "conformance.TestAllTypes")
+	proto.RegisterMapType((map[bool]bool)(nil), "conformance.TestAllTypes.MapBoolBoolEntry")
+	proto.RegisterMapType((map[uint32]uint32)(nil), "conformance.TestAllTypes.MapFixed32Fixed32Entry")
+	proto.RegisterMapType((map[uint64]uint64)(nil), "conformance.TestAllTypes.MapFixed64Fixed64Entry")
+	proto.RegisterMapType((map[int32]float64)(nil), "conformance.TestAllTypes.MapInt32DoubleEntry")
+	proto.RegisterMapType((map[int32]float32)(nil), "conformance.TestAllTypes.MapInt32FloatEntry")
+	proto.RegisterMapType((map[int32]int32)(nil), "conformance.TestAllTypes.MapInt32Int32Entry")
+	proto.RegisterMapType((map[int64]int64)(nil), "conformance.TestAllTypes.MapInt64Int64Entry")
+	proto.RegisterMapType((map[int32]int32)(nil), "conformance.TestAllTypes.MapSfixed32Sfixed32Entry")
+	proto.RegisterMapType((map[int64]int64)(nil), "conformance.TestAllTypes.MapSfixed64Sfixed64Entry")
+	proto.RegisterMapType((map[int32]int32)(nil), "conformance.TestAllTypes.MapSint32Sint32Entry")
+	proto.RegisterMapType((map[int64]int64)(nil), "conformance.TestAllTypes.MapSint64Sint64Entry")
+	proto.RegisterMapType((map[string][]byte)(nil), "conformance.TestAllTypes.MapStringBytesEntry")
+	proto.RegisterMapType((map[string]ForeignEnum)(nil), "conformance.TestAllTypes.MapStringForeignEnumEntry")
+	proto.RegisterMapType((map[string]*ForeignMessage)(nil), "conformance.TestAllTypes.MapStringForeignMessageEntry")
+	proto.RegisterMapType((map[string]TestAllTypes_NestedEnum)(nil), "conformance.TestAllTypes.MapStringNestedEnumEntry")
+	proto.RegisterMapType((map[string]*TestAllTypes_NestedMessage)(nil), "conformance.TestAllTypes.MapStringNestedMessageEntry")
+	proto.RegisterMapType((map[string]string)(nil), "conformance.TestAllTypes.MapStringStringEntry")
+	proto.RegisterMapType((map[uint32]uint32)(nil), "conformance.TestAllTypes.MapUint32Uint32Entry")
+	proto.RegisterMapType((map[uint64]uint64)(nil), "conformance.TestAllTypes.MapUint64Uint64Entry")
+	proto.RegisterType((*TestAllTypes_NestedMessage)(nil), "conformance.TestAllTypes.NestedMessage")
+	proto.RegisterType((*ForeignMessage)(nil), "conformance.ForeignMessage")
+	proto.RegisterEnum("conformance.WireFormat", WireFormat_name, WireFormat_value)
+	proto.RegisterEnum("conformance.ForeignEnum", ForeignEnum_name, ForeignEnum_value)
+	proto.RegisterEnum("conformance.TestAllTypes_NestedEnum", TestAllTypes_NestedEnum_name, TestAllTypes_NestedEnum_value)
+}
+
+func init() { proto.RegisterFile("conformance.proto", fileDescriptor_conformance_48ac832451f5d6c3) }
+
+var fileDescriptor_conformance_48ac832451f5d6c3 = []byte{
+	// 2600 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x5a, 0x5b, 0x73, 0x13, 0xc9,
+	0x15, 0xf6, 0x68, 0xc0, 0x36, 0x2d, 0xd9, 0x96, 0xdb, 0xb7, 0xc6, 0x50, 0xcb, 0x60, 0x96, 0x20,
+	0x60, 0xd7, 0xeb, 0xcb, 0x30, 0x5c, 0x36, 0x4b, 0xb0, 0xc0, 0x02, 0x93, 0xc5, 0xa2, 0xc6, 0x78,
+	0xa9, 0x22, 0x0f, 0xca, 0x20, 0x8f, 0x5d, 0x5a, 0x24, 0x8d, 0x76, 0x66, 0xb4, 0x89, 0xf3, 0x98,
+	0x7f, 0x90, 0xfb, 0xf5, 0x2f, 0xe4, 0x5a, 0x95, 0x4a, 0x52, 0xc9, 0x53, 0x2a, 0x2f, 0xb9, 0x27,
+	0x95, 0x7b, 0xf2, 0x63, 0x92, 0xea, 0xeb, 0x74, 0xb7, 0x7a, 0x64, 0xb1, 0x55, 0x2b, 0x5b, 0xa7,
+	0xbf, 0xfe, 0xce, 0xe9, 0xd3, 0x67, 0xbe, 0x76, 0x9f, 0x01, 0xcc, 0x36, 0xa3, 0xee, 0x61, 0x14,
+	0x77, 0x82, 0x6e, 0x33, 0x5c, 0xed, 0xc5, 0x51, 0x1a, 0xc1, 0xa2, 0x64, 0x5a, 0x3e, 0x7b, 0x14,
+	0x45, 0x47, 0xed, 0xf0, 0x1d, 0x32, 0xf4, 0xb2, 0x7f, 0xf8, 0x4e, 0xd0, 0x3d, 0xa6, 0xb8, 0xe5,
+	0x37, 0xf4, 0xa1, 0x83, 0x7e, 0x1c, 0xa4, 0xad, 0xa8, 0xcb, 0xc6, 0x1d, 0x7d, 0xfc, 0xb0, 0x15,
+	0xb6, 0x0f, 0x1a, 0x9d, 0x20, 0x79, 0xc5, 0x10, 0xe7, 0x75, 0x44, 0x92, 0xc6, 0xfd, 0x66, 0xca,
+	0x46, 0x2f, 0xe8, 0xa3, 0x69, 0xab, 0x13, 0x26, 0x69, 0xd0, 0xe9, 0xe5, 0x05, 0xf0, 0xb9, 0x38,
+	0xe8, 0xf5, 0xc2, 0x38, 0xa1, 0xe3, 0x2b, 0xbf, 0xb2, 0x00, 0xbc, 0x9f, 0xad, 0xc5, 0x0f, 0x3f,
+	0xea, 0x87, 0x49, 0x0a, 0xaf, 0x83, 0x32, 0x9f, 0xd1, 0xe8, 0x05, 0xc7, 0xed, 0x28, 0x38, 0x40,
+	0x96, 0x63, 0x55, 0x4a, 0x8f, 0xc6, 0xfc, 0x19, 0x3e, 0xf2, 0x94, 0x0e, 0xc0, 0x4b, 0xa0, 0xf4,
+	0x61, 0x12, 0x75, 0x05, 0xb0, 0xe0, 0x58, 0x95, 0x33, 0x8f, 0xc6, 0xfc, 0x22, 0xb6, 0x72, 0x50,
+	0x1d, 0x2c, 0xc5, 0x94, 0x3c, 0x3c, 0x68, 0x44, 0xfd, 0xb4, 0xd7, 0x4f, 0x1b, 0xc4, 0x6b, 0x8a,
+	0x6c, 0xc7, 0xaa, 0x4c, 0x6f, 0x2c, 0xad, 0xca, 0x69, 0x7e, 0xde, 0x8a, 0xc3, 0x1a, 0x19, 0xf6,
+	0x17, 0xc4, 0xbc, 0x3a, 0x99, 0x46, 0xcd, 0xd5, 0x33, 0x60, 0x82, 0x39, 0x5c, 0xf9, 0x62, 0x01,
+	0xcc, 0x29, 0x8b, 0x48, 0x7a, 0x51, 0x37, 0x09, 0xe1, 0x45, 0x50, 0xec, 0x05, 0x71, 0x12, 0x36,
+	0xc2, 0x38, 0x8e, 0x62, 0xb2, 0x00, 0x1c, 0x17, 0x20, 0xc6, 0x6d, 0x6c, 0x83, 0x57, 0xc1, 0x4c,
+	0x12, 0xc6, 0xad, 0xa0, 0xdd, 0xfa, 0x02, 0x87, 0x8d, 0x33, 0xd8, 0xb4, 0x18, 0xa0, 0xd0, 0xcb,
+	0x60, 0x2a, 0xee, 0x77, 0x71, 0x82, 0x19, 0x90, 0xaf, 0xb3, 0xc4, 0xcc, 0x14, 0x66, 0x4a, 0x9d,
+	0x3d, 0x6a, 0xea, 0x4e, 0x99, 0x52, 0xb7, 0x0c, 0x26, 0x92, 0x57, 0xad, 0x5e, 0x2f, 0x3c, 0x40,
+	0xa7, 0xd9, 0x38, 0x37, 0x54, 0x27, 0xc1, 0x78, 0x1c, 0x26, 0xfd, 0x76, 0xba, 0xf2, 0x93, 0xfb,
+	0xa0, 0xf4, 0x2c, 0x4c, 0xd2, 0xad, 0x76, 0xfb, 0xd9, 0x71, 0x2f, 0x4c, 0xe0, 0x65, 0x30, 0x1d,
+	0xf5, 0x70, 0xad, 0x05, 0xed, 0x46, 0xab, 0x9b, 0x6e, 0x6e, 0x90, 0x04, 0x9c, 0xf6, 0xa7, 0xb8,
+	0x75, 0x07, 0x1b, 0x75, 0x98, 0xe7, 0x92, 0x75, 0xd9, 0x0a, 0xcc, 0x73, 0xe1, 0x15, 0x30, 0x23,
+	0x60, 0x7d, 0x4a, 0x87, 0x57, 0x35, 0xe5, 0x8b, 0xd9, 0xfb, 0xc4, 0x3a, 0x00, 0xf4, 0x5c, 0xb2,
+	0xaa, 0x53, 0x2a, 0x50, 0x63, 0x4c, 0x28, 0x23, 0x5e, 0xde, 0x6c, 0x06, 0xdc, 0x1b, 0x64, 0x4c,
+	0x28, 0x23, 0xde, 0x23, 0xa8, 0x02, 0x3d, 0x17, 0x5e, 0x05, 0x65, 0x01, 0x3c, 0x6c, 0x7d, 0x3e,
+	0x3c, 0xd8, 0xdc, 0x40, 0x13, 0x8e, 0x55, 0x99, 0xf0, 0x05, 0x41, 0x8d, 0x9a, 0x07, 0xa1, 0x9e,
+	0x8b, 0x26, 0x1d, 0xab, 0x32, 0xae, 0x41, 0x3d, 0x17, 0x5e, 0x07, 0xb3, 0x99, 0x7b, 0x4e, 0x7b,
+	0xc6, 0xb1, 0x2a, 0x33, 0xbe, 0xe0, 0xd8, 0x63, 0x76, 0x03, 0xd8, 0x73, 0x11, 0x70, 0xac, 0x4a,
+	0x59, 0x07, 0x7b, 0xae, 0x92, 0xfa, 0xc3, 0x76, 0x14, 0xa4, 0xa8, 0xe8, 0x58, 0x95, 0x42, 0x96,
+	0xfa, 0x1a, 0x36, 0x2a, 0xeb, 0x3f, 0x88, 0xfa, 0x2f, 0xdb, 0x21, 0x2a, 0x39, 0x56, 0xc5, 0xca,
+	0xd6, 0xff, 0x80, 0x58, 0xe1, 0x25, 0x20, 0x66, 0x36, 0x5e, 0x46, 0x51, 0x1b, 0x4d, 0x39, 0x56,
+	0x65, 0xd2, 0x2f, 0x71, 0x63, 0x35, 0x8a, 0xda, 0x6a, 0x36, 0xd3, 0xb8, 0xd5, 0x3d, 0x42, 0xd3,
+	0xb8, 0xaa, 0xa4, 0x6c, 0x12, 0xab, 0x12, 0xdd, 0xcb, 0xe3, 0x34, 0x4c, 0xd0, 0x0c, 0x2e, 0xe3,
+	0x2c, 0xba, 0x2a, 0x36, 0xc2, 0x06, 0x58, 0x12, 0xb0, 0x2e, 0x7d, 0xbc, 0x3b, 0x61, 0x92, 0x04,
+	0x47, 0x21, 0x82, 0x8e, 0x55, 0x29, 0x6e, 0x5c, 0x51, 0x1e, 0x6c, 0xb9, 0x44, 0x57, 0x77, 0x09,
+	0xfe, 0x09, 0x85, 0xfb, 0x0b, 0x9c, 0x47, 0x31, 0xc3, 0x7d, 0x80, 0xb2, 0x2c, 0x45, 0x71, 0xd8,
+	0x3a, 0xea, 0x0a, 0x0f, 0x73, 0xc4, 0xc3, 0x39, 0xc5, 0x43, 0x8d, 0x62, 0x38, 0xeb, 0xa2, 0x48,
+	0xa6, 0x62, 0x87, 0x1f, 0x80, 0x79, 0x3d, 0xee, 0xb0, 0xdb, 0xef, 0xa0, 0x05, 0xa2, 0x46, 0x6f,
+	0x9e, 0x14, 0xf4, 0x76, 0xb7, 0xdf, 0xf1, 0xa1, 0x1a, 0x31, 0xb6, 0xc1, 0xf7, 0xc1, 0xc2, 0x40,
+	0xb8, 0x84, 0x78, 0x91, 0x10, 0x23, 0x53, 0xac, 0x84, 0x6c, 0x4e, 0x0b, 0x94, 0xb0, 0x79, 0x12,
+	0x1b, 0xdd, 0xad, 0x46, 0xaf, 0x15, 0x36, 0x43, 0x84, 0xf0, 0x9e, 0x55, 0x0b, 0x93, 0x85, 0x6c,
+	0x1e, 0xdd, 0xb7, 0xa7, 0x78, 0x18, 0x5e, 0x91, 0x4a, 0xa1, 0x19, 0xc5, 0x07, 0xe8, 0x2c, 0xc3,
+	0x5b, 0x59, 0x39, 0xdc, 0x8f, 0xe2, 0x03, 0x58, 0x03, 0xb3, 0x71, 0xd8, 0xec, 0xc7, 0x49, 0xeb,
+	0xe3, 0x50, 0xa4, 0xf5, 0x1c, 0x49, 0xeb, 0xd9, 0xdc, 0x1c, 0xf8, 0x65, 0x31, 0x87, 0xa7, 0xf3,
+	0x32, 0x98, 0x8e, 0xc3, 0x5e, 0x18, 0xe0, 0x3c, 0xd2, 0x87, 0xf9, 0x82, 0x63, 0x63, 0xb5, 0xe1,
+	0x56, 0xa1, 0x36, 0x32, 0xcc, 0x73, 0x91, 0xe3, 0xd8, 0x58, 0x6d, 0x24, 0x18, 0xd5, 0x06, 0x01,
+	0x63, 0x6a, 0x73, 0xd1, 0xb1, 0xb1, 0xda, 0x70, 0x73, 0xa6, 0x36, 0x0a, 0xd0, 0x73, 0xd1, 0x8a,
+	0x63, 0x63, 0xb5, 0x91, 0x81, 0x1a, 0x23, 0x53, 0x9b, 0x4b, 0x8e, 0x8d, 0xd5, 0x86, 0x9b, 0xf7,
+	0x06, 0x19, 0x99, 0xda, 0xbc, 0xe9, 0xd8, 0x58, 0x6d, 0x64, 0x20, 0x55, 0x1b, 0x01, 0xe4, 0xb2,
+	0x70, 0xd9, 0xb1, 0xb1, 0xda, 0x70, 0xbb, 0xa4, 0x36, 0x2a, 0xd4, 0x73, 0xd1, 0x27, 0x1c, 0x1b,
+	0xab, 0x8d, 0x02, 0xa5, 0x6a, 0x93, 0xb9, 0xe7, 0xb4, 0x57, 0x1c, 0x1b, 0xab, 0x8d, 0x08, 0x40,
+	0x52, 0x1b, 0x0d, 0xec, 0xb9, 0xa8, 0xe2, 0xd8, 0x58, 0x6d, 0x54, 0x30, 0x55, 0x9b, 0x2c, 0x08,
+	0xa2, 0x36, 0x57, 0x1d, 0x1b, 0xab, 0x8d, 0x08, 0x81, 0xab, 0x8d, 0x80, 0x31, 0xb5, 0xb9, 0xe6,
+	0xd8, 0x58, 0x6d, 0xb8, 0x39, 0x53, 0x1b, 0x01, 0x24, 0x6a, 0x73, 0xdd, 0xb1, 0xb1, 0xda, 0x70,
+	0x23, 0x57, 0x9b, 0x2c, 0x42, 0xaa, 0x36, 0x6f, 0x39, 0x36, 0x56, 0x1b, 0x11, 0x9f, 0x50, 0x9b,
+	0x8c, 0x8d, 0xa8, 0xcd, 0xdb, 0x8e, 0x8d, 0xd5, 0x46, 0xd0, 0x71, 0xb5, 0x11, 0x30, 0x4d, 0x6d,
+	0xd6, 0x1c, 0xfb, 0xb5, 0xd4, 0x86, 0xf3, 0x0c, 0xa8, 0x4d, 0x96, 0x25, 0x4d, 0x6d, 0xd6, 0x89,
+	0x87, 0xe1, 0x6a, 0x23, 0x92, 0x39, 0xa0, 0x36, 0x7a, 0xdc, 0x44, 0x14, 0x36, 0x1d, 0x7b, 0x74,
+	0xb5, 0x51, 0x23, 0xe6, 0x6a, 0x33, 0x10, 0x2e, 0x21, 0x76, 0x09, 0xf1, 0x10, 0xb5, 0xd1, 0x02,
+	0xe5, 0x6a, 0xa3, 0xed, 0x16, 0x53, 0x1b, 0x0f, 0xef, 0x19, 0x55, 0x1b, 0x75, 0xdf, 0x84, 0xda,
+	0x88, 0x79, 0x44, 0x6d, 0x6e, 0x32, 0xbc, 0x95, 0x95, 0x03, 0x51, 0x9b, 0x67, 0x60, 0xa6, 0x13,
+	0xf4, 0xa8, 0x40, 0x30, 0x99, 0xb8, 0x45, 0x92, 0xfa, 0x56, 0x7e, 0x06, 0x9e, 0x04, 0x3d, 0xa2,
+	0x1d, 0xe4, 0x63, 0xbb, 0x9b, 0xc6, 0xc7, 0xfe, 0x54, 0x47, 0xb6, 0x49, 0xac, 0x9e, 0xcb, 0x54,
+	0xe5, 0xf6, 0x68, 0xac, 0x9e, 0x4b, 0x3e, 0x14, 0x56, 0x66, 0x83, 0x2f, 0xc0, 0x2c, 0x66, 0xa5,
+	0xf2, 0xc3, 0x55, 0xe8, 0x0e, 0xe1, 0x5d, 0x1d, 0xca, 0x4b, 0xa5, 0x89, 0x7e, 0x52, 0x66, 0x1c,
+	0x9e, 0x6c, 0x95, 0xb9, 0x3d, 0x97, 0x0b, 0xd7, 0xbb, 0x23, 0x72, 0x7b, 0x2e, 0xfd, 0x54, 0xb9,
+	0xb9, 0x95, 0x73, 0x53, 0x91, 0xe3, 0x5a, 0xf7, 0xc9, 0x11, 0xb8, 0xa9, 0x00, 0xee, 0x69, 0x71,
+	0xcb, 0x56, 0x99, 0xdb, 0x73, 0xb9, 0x3c, 0xbe, 0x37, 0x22, 0xb7, 0xe7, 0xee, 0x69, 0x71, 0xcb,
+	0x56, 0xf8, 0x59, 0x30, 0x87, 0xb9, 0x99, 0xb6, 0x09, 0x49, 0xbd, 0x4b, 0xd8, 0xd7, 0x86, 0xb2,
+	0x33, 0x9d, 0x65, 0x3f, 0x28, 0x3f, 0x0e, 0x54, 0xb5, 0x2b, 0x1e, 0x3c, 0x57, 0x28, 0xf1, 0xa7,
+	0x46, 0xf5, 0xe0, 0xb9, 0xec, 0x87, 0xe6, 0x41, 0xd8, 0xe1, 0x21, 0x58, 0x20, 0xf9, 0xe1, 0x8b,
+	0x10, 0x0a, 0x7e, 0x8f, 0xf8, 0xd8, 0x18, 0x9e, 0x23, 0x06, 0xe6, 0x3f, 0xa9, 0x17, 0x1c, 0xb2,
+	0x3e, 0xa2, 0xfa, 0xc1, 0x3b, 0xc1, 0xd7, 0xb2, 0x35, 0xb2, 0x1f, 0xcf, 0xe5, 0x3f, 0x75, 0x3f,
+	0xd9, 0x88, 0xfa, 0xbc, 0xd2, 0x43, 0xa3, 0x3a, 0xea, 0xf3, 0x4a, 0x8e, 0x13, 0xed, 0x79, 0xa5,
+	0x47, 0xcc, 0x73, 0x50, 0xce, 0x58, 0xd9, 0x19, 0x73, 0x9f, 0xd0, 0xbe, 0x7d, 0x32, 0x2d, 0x3d,
+	0x7d, 0x28, 0xef, 0x74, 0x47, 0x31, 0xc2, 0x5d, 0x80, 0x3d, 0x91, 0xd3, 0x88, 0x1e, 0x49, 0x0f,
+	0x08, 0xeb, 0xb5, 0xa1, 0xac, 0xf8, 0x9c, 0xc2, 0xff, 0x53, 0xca, 0x62, 0x27, 0xb3, 0x88, 0x72,
+	0xa7, 0x52, 0xc8, 0xce, 0xaf, 0xed, 0x51, 0xca, 0x9d, 0x40, 0xe9, 0xa7, 0x54, 0xee, 0x92, 0x95,
+	0x27, 0x81, 0x71, 0xd3, 0x23, 0xaf, 0x36, 0x42, 0x12, 0xe8, 0x74, 0x72, 0x1a, 0x66, 0x49, 0x90,
+	0x8c, 0xb0, 0x07, 0xce, 0x4a, 0xc4, 0xda, 0x21, 0xf9, 0x90, 0x78, 0xb8, 0x31, 0x82, 0x07, 0xe5,
+	0x58, 0xa4, 0x9e, 0x16, 0x3b, 0xc6, 0x41, 0x98, 0x80, 0x65, 0xc9, 0xa3, 0x7e, 0x6a, 0x3e, 0x22,
+	0x2e, 0xbd, 0x11, 0x5c, 0xaa, 0x67, 0x26, 0xf5, 0xb9, 0xd4, 0x31, 0x8f, 0xc2, 0x23, 0xb0, 0x38,
+	0xb8, 0x4c, 0x72, 0xf4, 0xed, 0x8c, 0xf2, 0x0c, 0x48, 0xcb, 0xc0, 0x47, 0x9f, 0xf4, 0x0c, 0x68,
+	0x23, 0xf0, 0x43, 0xb0, 0x64, 0x58, 0x1d, 0xf1, 0xf4, 0x98, 0x78, 0xda, 0x1c, 0x7d, 0x69, 0x99,
+	0xab, 0xf9, 0x8e, 0x61, 0x08, 0x5e, 0x02, 0xa5, 0xa8, 0x1b, 0x46, 0x87, 0xfc, 0xb8, 0x89, 0xf0,
+	0x15, 0xfb, 0xd1, 0x98, 0x5f, 0x24, 0x56, 0x76, 0x78, 0x7c, 0x06, 0xcc, 0x53, 0x90, 0xb6, 0xb7,
+	0xbd, 0xd7, 0xba, 0x6e, 0x3d, 0x1a, 0xf3, 0x21, 0xa1, 0x51, 0xf7, 0x52, 0x44, 0xc0, 0xaa, 0xfd,
+	0x23, 0xde, 0x91, 0x20, 0x56, 0x56, 0xbb, 0x17, 0x01, 0xfd, 0xca, 0xca, 0x36, 0x66, 0xed, 0x0d,
+	0x40, 0x8c, 0xb4, 0x0a, 0xeb, 0xd2, 0xc5, 0x85, 0x3c, 0x8f, 0xac, 0xf1, 0x84, 0x7e, 0x63, 0x91,
+	0x30, 0x97, 0x57, 0x69, 0x67, 0x6a, 0x95, 0xb7, 0x44, 0x56, 0xf1, 0x13, 0xf7, 0x41, 0xd0, 0xee,
+	0x87, 0xd9, 0x8d, 0x06, 0x9b, 0x9e, 0xd3, 0x79, 0xd0, 0x07, 0x8b, 0x6a, 0x3b, 0x43, 0x30, 0xfe,
+	0xd6, 0x62, 0xb7, 0x40, 0x9d, 0x91, 0x48, 0x03, 0xa5, 0x9c, 0x57, 0x9a, 0x1e, 0x39, 0x9c, 0x9e,
+	0x2b, 0x38, 0x7f, 0x37, 0x84, 0xd3, 0x73, 0x07, 0x39, 0x3d, 0x97, 0x73, 0xee, 0x4b, 0xf7, 0xe1,
+	0xbe, 0x1a, 0xe8, 0xef, 0x29, 0xe9, 0xf9, 0x01, 0xd2, 0x7d, 0x29, 0xd2, 0x05, 0xb5, 0x9f, 0x92,
+	0x47, 0x2b, 0xc5, 0xfa, 0x87, 0x61, 0xb4, 0x3c, 0xd8, 0x05, 0xb5, 0xfb, 0x62, 0xca, 0x00, 0xd1,
+	0x77, 0xc1, 0xfa, 0xc7, 0xbc, 0x0c, 0x10, 0x0d, 0xd7, 0x32, 0x40, 0x6c, 0xa6, 0x50, 0xa9, 0xba,
+	0x0b, 0xd2, 0x3f, 0xe5, 0x85, 0x4a, 0x05, 0x5c, 0x0b, 0x95, 0x1a, 0x4d, 0xb4, 0xec, 0x61, 0xe4,
+	0xb4, 0x7f, 0xce, 0xa3, 0xa5, 0xf5, 0xaa, 0xd1, 0x52, 0xa3, 0x29, 0x03, 0xa4, 0x9c, 0x05, 0xeb,
+	0x5f, 0xf2, 0x32, 0x40, 0x2a, 0x5c, 0xcb, 0x00, 0xb1, 0x71, 0xce, 0xba, 0xf4, 0x77, 0xb4, 0x52,
+	0xfc, 0x7f, 0xb5, 0x88, 0x62, 0x0c, 0x2d, 0x7e, 0xf9, 0xfe, 0x24, 0x05, 0xa9, 0xde, 0xae, 0x05,
+	0xe3, 0xdf, 0x2c, 0x76, 0x29, 0x19, 0x56, 0xfc, 0xca, 0x1d, 0x3c, 0x87, 0x53, 0x2a, 0xa8, 0xbf,
+	0x0f, 0xe1, 0x14, 0xc5, 0xaf, 0x5c, 0xd8, 0xa5, 0x3d, 0xd2, 0xee, 0xed, 0x82, 0xf4, 0x1f, 0x94,
+	0xf4, 0x84, 0xe2, 0x57, 0xaf, 0xf7, 0x79, 0xb4, 0x52, 0xac, 0xff, 0x1c, 0x46, 0x2b, 0x8a, 0x5f,
+	0x6d, 0x06, 0x98, 0x32, 0xa0, 0x16, 0xff, 0xbf, 0xf2, 0x32, 0x20, 0x17, 0xbf, 0x72, 0x6f, 0x36,
+	0x85, 0xaa, 0x15, 0xff, 0xbf, 0xf3, 0x42, 0x55, 0x8a, 0x5f, 0xbd, 0x65, 0x9b, 0x68, 0xb5, 0xe2,
+	0xff, 0x4f, 0x1e, 0xad, 0x52, 0xfc, 0xea, 0xb5, 0xcd, 0x94, 0x01, 0xb5, 0xf8, 0xff, 0x9b, 0x97,
+	0x01, 0xb9, 0xf8, 0x95, 0xbb, 0x39, 0xe7, 0x7c, 0x28, 0xb5, 0x40, 0xf9, 0xeb, 0x0e, 0xf4, 0xbd,
+	0x02, 0x6b, 0x29, 0x0d, 0xac, 0x9d, 0x21, 0xb2, 0xf6, 0x28, 0xb7, 0xc0, 0xc7, 0x40, 0xf4, 0xd7,
+	0x1a, 0xe2, 0xbd, 0x06, 0xfa, 0x7e, 0x21, 0xe7, 0xfc, 0x78, 0xc6, 0x21, 0xbe, 0xf0, 0x2f, 0x4c,
+	0xf0, 0xd3, 0x60, 0x4e, 0xea, 0xf7, 0xf2, 0x77, 0x2c, 0xe8, 0x07, 0x79, 0x64, 0x35, 0x8c, 0x79,
+	0x12, 0x24, 0xaf, 0x32, 0x32, 0x61, 0x82, 0x5b, 0x6a, 0x0b, 0xb5, 0xdf, 0x4c, 0xd1, 0x0f, 0x29,
+	0xd1, 0x92, 0x69, 0x13, 0xfa, 0xcd, 0x54, 0x69, 0xae, 0xf6, 0x9b, 0x29, 0xbc, 0x05, 0x44, 0x1b,
+	0xae, 0x11, 0x74, 0x8f, 0xd1, 0x8f, 0xe8, 0xfc, 0xf9, 0x81, 0xf9, 0x5b, 0xdd, 0x63, 0xbf, 0xc8,
+	0xa1, 0x5b, 0xdd, 0x63, 0x78, 0x57, 0x6a, 0xcb, 0x7e, 0x8c, 0xb7, 0x01, 0xfd, 0x98, 0xce, 0x5d,
+	0x1c, 0x98, 0x4b, 0x77, 0x49, 0x34, 0x02, 0xc9, 0x57, 0xbc, 0x3d, 0x59, 0x81, 0xf2, 0xed, 0xf9,
+	0x69, 0x81, 0xec, 0xf6, 0xb0, 0xed, 0x11, 0x75, 0x29, 0x6d, 0x8f, 0x20, 0xca, 0xb6, 0xe7, 0x67,
+	0x85, 0x1c, 0x85, 0x93, 0xb6, 0x87, 0x4f, 0xcb, 0xb6, 0x47, 0xe6, 0x22, 0xdb, 0x43, 0x76, 0xe7,
+	0xe7, 0x79, 0x5c, 0xd2, 0xee, 0x64, 0xfd, 0x33, 0x36, 0x0b, 0xef, 0x8e, 0xfc, 0xa8, 0xe0, 0xdd,
+	0xf9, 0x35, 0x25, 0xca, 0xdf, 0x1d, 0xe9, 0xe9, 0x60, 0xbb, 0x23, 0x28, 0xf0, 0xee, 0xfc, 0x82,
+	0xce, 0xcf, 0xd9, 0x1d, 0x0e, 0x65, 0xbb, 0x23, 0x66, 0xd2, 0xdd, 0xf9, 0x25, 0x9d, 0x9b, 0xbb,
+	0x3b, 0x1c, 0x4e, 0x77, 0xe7, 0x02, 0x00, 0x64, 0xfd, 0xdd, 0xa0, 0x13, 0xae, 0xa3, 0x2f, 0xd9,
+	0xe4, 0x8d, 0x8d, 0x64, 0x82, 0x0e, 0x28, 0xd2, 0xfa, 0xc5, 0x5f, 0x37, 0xd0, 0x97, 0x65, 0xc4,
+	0x2e, 0x36, 0xc1, 0x8b, 0xa0, 0xd4, 0xc8, 0x20, 0x9b, 0xe8, 0x2b, 0x0c, 0x52, 0xe3, 0x90, 0x4d,
+	0xb8, 0x02, 0xa6, 0x28, 0x82, 0x40, 0xdc, 0x06, 0xfa, 0xaa, 0x4e, 0xe3, 0xe2, 0xbf, 0xf1, 0xc8,
+	0xb7, 0x35, 0x0c, 0xb9, 0x81, 0xbe, 0x46, 0x11, 0xb2, 0x0d, 0x5e, 0xe2, 0x34, 0x6b, 0x84, 0xc7,
+	0x43, 0x5f, 0x57, 0x40, 0x98, 0xc7, 0x13, 0x2b, 0xc2, 0xdf, 0x6e, 0xa2, 0x6f, 0xe8, 0x8e, 0x6e,
+	0x62, 0x80, 0x08, 0xed, 0x16, 0xfa, 0xa6, 0x1e, 0xed, 0xad, 0x6c, 0xc9, 0xf8, 0xeb, 0x6d, 0xf4,
+	0x2d, 0x9d, 0xe2, 0x36, 0x5c, 0x01, 0xa5, 0x9a, 0x40, 0xac, 0xaf, 0xa1, 0x6f, 0xb3, 0x38, 0x04,
+	0xc9, 0xfa, 0x1a, 0xc1, 0xec, 0x6c, 0xbf, 0xff, 0xa0, 0xb1, 0xbb, 0xf5, 0x64, 0x7b, 0x7d, 0x1d,
+	0x7d, 0x87, 0x63, 0xb0, 0x91, 0xda, 0x32, 0x0c, 0xc9, 0xf5, 0x06, 0xfa, 0xae, 0x82, 0x21, 0xb6,
+	0xe5, 0x17, 0x60, 0x4a, 0xfd, 0x8b, 0xb9, 0x04, 0xac, 0x80, 0xbd, 0x5a, 0xb3, 0x02, 0xf8, 0x2e,
+	0x28, 0x36, 0x23, 0xd1, 0x1d, 0x47, 0x85, 0x93, 0x3a, 0xe9, 0x32, 0x7a, 0xf9, 0x1e, 0x80, 0x83,
+	0xdd, 0x2e, 0x58, 0x06, 0xf6, 0xab, 0xf0, 0x98, 0xb9, 0xc0, 0xbf, 0xc2, 0x79, 0x70, 0x9a, 0x16,
+	0x57, 0x81, 0xd8, 0xe8, 0x97, 0x3b, 0x85, 0x5b, 0x56, 0xc6, 0x20, 0x77, 0xb6, 0x64, 0x06, 0xdb,
+	0xc0, 0x60, 0xcb, 0x0c, 0x55, 0x30, 0x6f, 0xea, 0x61, 0xc9, 0x1c, 0x53, 0x06, 0x8e, 0x29, 0x33,
+	0x87, 0xd2, 0xab, 0x92, 0x39, 0x4e, 0x19, 0x38, 0x4e, 0x0d, 0x72, 0x0c, 0xf4, 0xa4, 0x64, 0x8e,
+	0x59, 0x03, 0xc7, 0xac, 0x99, 0x43, 0xe9, 0x3d, 0xc9, 0x1c, 0xd0, 0xc0, 0x01, 0x65, 0x8e, 0x07,
+	0x60, 0xd1, 0xdc, 0x61, 0x92, 0x59, 0x26, 0x0c, 0x2c, 0x13, 0x39, 0x2c, 0x6a, 0x17, 0x49, 0x66,
+	0x19, 0x37, 0xb0, 0x8c, 0xcb, 0x2c, 0x35, 0x80, 0xf2, 0xfa, 0x44, 0x32, 0xcf, 0x8c, 0x81, 0x67,
+	0x26, 0x8f, 0x47, 0xeb, 0x03, 0xc9, 0x3c, 0x65, 0x03, 0x4f, 0xd9, 0x58, 0x6d, 0x72, 0xb7, 0xe7,
+	0xa4, 0x7a, 0x2d, 0xc8, 0x0c, 0x5b, 0x60, 0xce, 0xd0, 0xd8, 0x39, 0x89, 0xc2, 0x92, 0x29, 0xee,
+	0x82, 0xb2, 0xde, 0xc5, 0x91, 0xe7, 0x4f, 0x1a, 0xe6, 0x4f, 0x1a, 0x8a, 0x44, 0xef, 0xd8, 0xc8,
+	0x1c, 0x67, 0x0c, 0x1c, 0x67, 0x06, 0x97, 0xa1, 0xb7, 0x66, 0x4e, 0xa2, 0x28, 0xc9, 0x14, 0x31,
+	0x38, 0x37, 0xa4, 0xf7, 0x62, 0xa0, 0x7a, 0x4f, 0xa6, 0x7a, 0x8d, 0x17, 0x1f, 0x92, 0xcf, 0x23,
+	0x70, 0x7e, 0x58, 0xf3, 0xc5, 0xe0, 0x74, 0x5d, 0x75, 0x3a, 0xf4, 0x5d, 0x88, 0xe4, 0xa8, 0x4d,
+	0x0b, 0xce, 0xd4, 0x74, 0x31, 0x38, 0xb9, 0x23, 0x3b, 0x19, 0xf5, 0xed, 0x88, 0xe4, 0x2d, 0x00,
+	0x67, 0x73, 0x1b, 0x2f, 0x06, 0x77, 0xab, 0xaa, 0xbb, 0xfc, 0x77, 0x26, 0x99, 0x8b, 0x95, 0xdb,
+	0x00, 0x48, 0x2d, 0xa2, 0x09, 0x60, 0xd7, 0xea, 0xf5, 0xf2, 0x18, 0xfe, 0xa5, 0xba, 0xe5, 0x97,
+	0x2d, 0xfa, 0xcb, 0x8b, 0x72, 0x01, 0xbb, 0xdb, 0xdd, 0x7e, 0x58, 0xfe, 0x1f, 0xff, 0xcf, 0xaa,
+	0x4e, 0xf1, 0xe6, 0x09, 0x39, 0xc0, 0x56, 0xde, 0x00, 0xd3, 0x5a, 0x67, 0xab, 0x04, 0xac, 0x26,
+	0x3f, 0x50, 0x9a, 0xd7, 0x6e, 0x00, 0x90, 0xfd, 0x63, 0x18, 0x38, 0x03, 0x8a, 0xfb, 0xbb, 0x7b,
+	0x4f, 0xb7, 0xef, 0xef, 0xd4, 0x76, 0xb6, 0x1f, 0x94, 0xc7, 0x60, 0x09, 0x4c, 0x3e, 0xf5, 0xeb,
+	0xcf, 0xea, 0xd5, 0xfd, 0x5a, 0xd9, 0x82, 0x93, 0xe0, 0xd4, 0xe3, 0xbd, 0xfa, 0x6e, 0xb9, 0x70,
+	0xed, 0x1e, 0x28, 0xca, 0x8d, 0xa5, 0x19, 0x50, 0xac, 0xd5, 0xfd, 0xed, 0x9d, 0x87, 0xbb, 0x0d,
+	0x1a, 0xa9, 0x64, 0xa0, 0x11, 0x2b, 0x86, 0x17, 0xe5, 0x42, 0xf5, 0x22, 0xb8, 0xd0, 0x8c, 0x3a,
+	0x03, 0x7f, 0xb6, 0x48, 0xc9, 0x79, 0x39, 0x4e, 0xac, 0x9b, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff,
+	0x29, 0x30, 0x51, 0x54, 0x22, 0x25, 0x00, 0x00,
+}
diff --git a/_conformance/conformance_proto/conformance.proto b/conformance/internal/conformance_proto/conformance.proto
similarity index 96%
rename from _conformance/conformance_proto/conformance.proto
rename to conformance/internal/conformance_proto/conformance.proto
index 95a8fd1..fc96074 100644
--- a/_conformance/conformance_proto/conformance.proto
+++ b/conformance/internal/conformance_proto/conformance.proto
@@ -210,11 +210,6 @@
     NestedMessage oneof_nested_message = 112;
     string oneof_string = 113;
     bytes oneof_bytes = 114;
-    bool oneof_bool = 115;
-    uint64 oneof_uint64 = 116;
-    float oneof_float = 117;
-    double oneof_double = 118;
-    NestedEnum oneof_enum = 119;
   }
 
   // Well-known types
@@ -253,7 +248,6 @@
   repeated google.protobuf.Value repeated_value = 316;
 
   // Test field-name-to-JSON-name convention.
-  // (protobuf says names can be any valid C/C++ identifier.)
   int32 fieldname1 = 401;
   int32 field_name2 = 402;
   int32 _field_name3 = 403;
@@ -266,12 +260,6 @@
   int32 Field_Name10 = 410;
   int32 FIELD_NAME11 = 411;
   int32 FIELD_name12 = 412;
-  int32 __field_name13 = 413;
-  int32 __Field_name14 = 414;
-  int32 field__name15 = 415;
-  int32 field__Name16 = 416;
-  int32 field_name17__ = 417;
-  int32 Field_name18__ = 418;
 }
 
 message ForeignMessage {
diff --git a/conformance/test.sh b/conformance/test.sh
new file mode 100755
index 0000000..e6de29b
--- /dev/null
+++ b/conformance/test.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+PROTOBUF_ROOT=$1
+CONFORMANCE_ROOT=$1/conformance
+CONFORMANCE_TEST_RUNNER=$CONFORMANCE_ROOT/conformance-test-runner
+
+cd $(dirname $0)
+
+if [[ $PROTOBUF_ROOT == "" ]]; then
+  echo "usage: test.sh <protobuf-root>" >/dev/stderr
+  exit 1
+fi
+
+if [[ ! -x $CONFORMANCE_TEST_RUNNER ]]; then
+  echo "SKIP: conformance test runner not installed" >/dev/stderr
+  exit 0
+fi
+
+a=$CONFORMANCE_ROOT/conformance.proto
+b=internal/conformance_proto/conformance.proto
+if [[ $(diff $a $b) != "" ]]; then
+  cp $a $b
+  echo "WARNING: conformance.proto is out of date" >/dev/stderr
+fi
+
+$CONFORMANCE_TEST_RUNNER --failure_list failure_list_go.txt ./conformance.sh
diff --git a/descriptor/descriptor_test.go b/descriptor/descriptor_test.go
index 27b0729..bf5174d 100644
--- a/descriptor/descriptor_test.go
+++ b/descriptor/descriptor_test.go
@@ -5,7 +5,7 @@
 	"testing"
 
 	"github.com/golang/protobuf/descriptor"
-	tpb "github.com/golang/protobuf/proto/testdata"
+	tpb "github.com/golang/protobuf/proto/test_proto"
 	protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor"
 )
 
@@ -20,7 +20,7 @@
 	}
 }
 
-func Example_Options() {
+func Example_options() {
 	var msg *tpb.MyMessageSet
 	_, md := descriptor.ForMessage(msg)
 	if md.GetOptions().GetMessageSetWireFormat() {
diff --git a/jsonpb/jsonpb.go b/jsonpb/jsonpb.go
index 110ae13..ff368f3 100644
--- a/jsonpb/jsonpb.go
+++ b/jsonpb/jsonpb.go
@@ -56,6 +56,8 @@
 	stpb "github.com/golang/protobuf/ptypes/struct"
 )
 
+const secondInNanos = int64(time.Second / time.Nanosecond)
+
 // Marshaler is a configurable object for converting between
 // protocol buffer objects and a JSON representation for them.
 type Marshaler struct {
@@ -118,6 +120,14 @@
 
 // Marshal marshals a protocol buffer into JSON.
 func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error {
+	v := reflect.ValueOf(pb)
+	if pb == nil || (v.Kind() == reflect.Ptr && v.IsNil()) {
+		return errors.New("Marshal called with nil")
+	}
+	// Check for unset required fields first.
+	if err := checkRequiredFields(pb); err != nil {
+		return err
+	}
 	writer := &errWriter{writer: out}
 	return m.marshalObject(writer, pb, "", "")
 }
@@ -190,13 +200,22 @@
 			// Any is a bit more involved.
 			return m.marshalAny(out, v, indent)
 		case "Duration":
-			// "Generated output always contains 3, 6, or 9 fractional digits,
+			// "Generated output always contains 0, 3, 6, or 9 fractional digits,
 			//  depending on required precision."
 			s, ns := s.Field(0).Int(), s.Field(1).Int()
-			d := time.Duration(s)*time.Second + time.Duration(ns)*time.Nanosecond
-			x := fmt.Sprintf("%.9f", d.Seconds())
+			if ns <= -secondInNanos || ns >= secondInNanos {
+				return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos)
+			}
+			if (s > 0 && ns < 0) || (s < 0 && ns > 0) {
+				return errors.New("signs of seconds and nanos do not match")
+			}
+			if s < 0 {
+				ns = -ns
+			}
+			x := fmt.Sprintf("%d.%09d", s, ns)
 			x = strings.TrimSuffix(x, "000")
 			x = strings.TrimSuffix(x, "000")
+			x = strings.TrimSuffix(x, ".000")
 			out.write(`"`)
 			out.write(x)
 			out.write(`s"`)
@@ -207,13 +226,17 @@
 			return m.marshalValue(out, &proto.Properties{}, s.Field(0), indent)
 		case "Timestamp":
 			// "RFC 3339, where generated output will always be Z-normalized
-			//  and uses 3, 6 or 9 fractional digits."
+			//  and uses 0, 3, 6 or 9 fractional digits."
 			s, ns := s.Field(0).Int(), s.Field(1).Int()
+			if ns < 0 || ns >= secondInNanos {
+				return fmt.Errorf("ns out of range [0, %v)", secondInNanos)
+			}
 			t := time.Unix(s, ns).UTC()
 			// time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits).
 			x := t.Format("2006-01-02T15:04:05.000000000")
 			x = strings.TrimSuffix(x, "000")
 			x = strings.TrimSuffix(x, "000")
+			x = strings.TrimSuffix(x, ".000")
 			out.write(`"`)
 			out.write(x)
 			out.write(`Z"`)
@@ -632,7 +655,10 @@
 	if err := dec.Decode(&inputValue); err != nil {
 		return err
 	}
-	return u.unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil)
+	if err := u.unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil); err != nil {
+		return err
+	}
+	return checkRequiredFields(pb)
 }
 
 // Unmarshal unmarshals a JSON object stream into a protocol
@@ -803,7 +829,7 @@
 				return fmt.Errorf("bad ListValue: %v", err)
 			}
 
-			target.Field(0).Set(reflect.ValueOf(make([]*stpb.Value, len(s), len(s))))
+			target.Field(0).Set(reflect.ValueOf(make([]*stpb.Value, len(s))))
 			for i, sv := range s {
 				if err := u.unmarshalValue(target.Field(0).Index(i), sv, prop); err != nil {
 					return err
@@ -973,13 +999,6 @@
 		}
 		if mp != nil {
 			target.Set(reflect.MakeMap(targetType))
-			var keyprop, valprop *proto.Properties
-			if prop != nil {
-				// These could still be nil if the protobuf metadata is broken somehow.
-				// TODO: This won't work because the fields are unexported.
-				// We should probably just reparse them.
-				//keyprop, valprop = prop.mkeyprop, prop.mvalprop
-			}
 			for ks, raw := range mp {
 				// Unmarshal map key. The core json library already decoded the key into a
 				// string, so we handle that specially. Other types were quoted post-serialization.
@@ -988,14 +1007,16 @@
 					k = reflect.ValueOf(ks)
 				} else {
 					k = reflect.New(targetType.Key()).Elem()
-					if err := u.unmarshalValue(k, json.RawMessage(ks), keyprop); err != nil {
+					// TODO: pass the correct Properties if needed.
+					if err := u.unmarshalValue(k, json.RawMessage(ks), nil); err != nil {
 						return err
 					}
 				}
 
 				// Unmarshal map value.
 				v := reflect.New(targetType.Elem()).Elem()
-				if err := u.unmarshalValue(v, raw, valprop); err != nil {
+				// TODO: pass the correct Properties if needed.
+				if err := u.unmarshalValue(v, raw, nil); err != nil {
 					return err
 				}
 				target.SetMapIndex(k, v)
@@ -1081,3 +1102,140 @@
 	}
 	return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface())
 }
+
+// checkRequiredFields returns an error if any required field in the given proto message is not set.
+// This function is used by both Marshal and Unmarshal.  While required fields only exist in a
+// proto2 message, a proto3 message can contain proto2 message(s).
+func checkRequiredFields(pb proto.Message) error {
+	// Most well-known type messages do not contain required fields.  The "Any" type may contain
+	// a message that has required fields.
+	//
+	// When an Any message is being marshaled, the code will invoked proto.Unmarshal on Any.Value
+	// field in order to transform that into JSON, and that should have returned an error if a
+	// required field is not set in the embedded message.
+	//
+	// When an Any message is being unmarshaled, the code will have invoked proto.Marshal on the
+	// embedded message to store the serialized message in Any.Value field, and that should have
+	// returned an error if a required field is not set.
+	if _, ok := pb.(wkt); ok {
+		return nil
+	}
+
+	v := reflect.ValueOf(pb)
+	// Skip message if it is not a struct pointer.
+	if v.Kind() != reflect.Ptr {
+		return nil
+	}
+	v = v.Elem()
+	if v.Kind() != reflect.Struct {
+		return nil
+	}
+
+	for i := 0; i < v.NumField(); i++ {
+		field := v.Field(i)
+		sfield := v.Type().Field(i)
+
+		if sfield.PkgPath != "" {
+			// blank PkgPath means the field is exported; skip if not exported
+			continue
+		}
+
+		if strings.HasPrefix(sfield.Name, "XXX_") {
+			continue
+		}
+
+		// Oneof field is an interface implemented by wrapper structs containing the actual oneof
+		// field, i.e. an interface containing &T{real_value}.
+		if sfield.Tag.Get("protobuf_oneof") != "" {
+			if field.Kind() != reflect.Interface {
+				continue
+			}
+			v := field.Elem()
+			if v.Kind() != reflect.Ptr || v.IsNil() {
+				continue
+			}
+			v = v.Elem()
+			if v.Kind() != reflect.Struct || v.NumField() < 1 {
+				continue
+			}
+			field = v.Field(0)
+			sfield = v.Type().Field(0)
+		}
+
+		protoTag := sfield.Tag.Get("protobuf")
+		if protoTag == "" {
+			continue
+		}
+		var prop proto.Properties
+		prop.Init(sfield.Type, sfield.Name, protoTag, &sfield)
+
+		switch field.Kind() {
+		case reflect.Map:
+			if field.IsNil() {
+				continue
+			}
+			// Check each map value.
+			keys := field.MapKeys()
+			for _, k := range keys {
+				v := field.MapIndex(k)
+				if err := checkRequiredFieldsInValue(v); err != nil {
+					return err
+				}
+			}
+		case reflect.Slice:
+			// Handle non-repeated type, e.g. bytes.
+			if !prop.Repeated {
+				if prop.Required && field.IsNil() {
+					return fmt.Errorf("required field %q is not set", prop.Name)
+				}
+				continue
+			}
+
+			// Handle repeated type.
+			if field.IsNil() {
+				continue
+			}
+			// Check each slice item.
+			for i := 0; i < field.Len(); i++ {
+				v := field.Index(i)
+				if err := checkRequiredFieldsInValue(v); err != nil {
+					return err
+				}
+			}
+		case reflect.Ptr:
+			if field.IsNil() {
+				if prop.Required {
+					return fmt.Errorf("required field %q is not set", prop.Name)
+				}
+				continue
+			}
+			if err := checkRequiredFieldsInValue(field); err != nil {
+				return err
+			}
+		}
+	}
+
+	// Handle proto2 extensions.
+	for _, ext := range proto.RegisteredExtensions(pb) {
+		if !proto.HasExtension(pb, ext) {
+			continue
+		}
+		ep, err := proto.GetExtension(pb, ext)
+		if err != nil {
+			return err
+		}
+		err = checkRequiredFieldsInValue(reflect.ValueOf(ep))
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func checkRequiredFieldsInValue(v reflect.Value) error {
+	if pm, ok := v.Interface().(proto.Message); ok {
+		return checkRequiredFields(pm)
+	}
+	return nil
+}
diff --git a/jsonpb/jsonpb_test.go b/jsonpb/jsonpb_test.go
index 2428d05..c9934d9 100644
--- a/jsonpb/jsonpb_test.go
+++ b/jsonpb/jsonpb_test.go
@@ -406,7 +406,10 @@
 	{"Any with message and indent", marshalerAllOptions, anySimple, anySimplePrettyJSON},
 	{"Any with WKT", marshaler, anyWellKnown, anyWellKnownJSON},
 	{"Any with WKT and indent", marshalerAllOptions, anyWellKnown, anyWellKnownPrettyJSON},
-	{"Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}, `{"dur":"3.000s"}`},
+	{"Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}, `{"dur":"3s"}`},
+	{"Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3, Nanos: 1e6}}, `{"dur":"3.001s"}`},
+	{"Duration beyond float64 precision", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 100000000, Nanos: 1}}, `{"dur":"100000000.000000001s"}`},
+	{"negative Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: -123, Nanos: -456}}, `{"dur":"-123.000000456s"}`},
 	{"Struct", marshaler, &pb.KnownTypes{St: &stpb.Struct{
 		Fields: map[string]*stpb.Value{
 			"one": {Kind: &stpb.Value_StringValue{"loneliest number"}},
@@ -421,6 +424,7 @@
 		{Kind: &stpb.Value_BoolValue{true}},
 	}}}, `{"lv":["x",null,3,true]}`},
 	{"Timestamp", marshaler, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 21e6}}, `{"ts":"2014-05-13T16:53:20.021Z"}`},
+	{"Timestamp", marshaler, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 0}}, `{"ts":"2014-05-13T16:53:20Z"}`},
 	{"number Value", marshaler, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NumberValue{1}}}, `{"val":1}`},
 	{"null Value", marshaler, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NullValue{stpb.NullValue_NULL_VALUE}}}, `{"val":null}`},
 	{"string number value", marshaler, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_StringValue{"9223372036854775807"}}}, `{"val":"9223372036854775807"}`},
@@ -449,6 +453,9 @@
 	{"BoolValue", marshaler, &pb.KnownTypes{Bool: &wpb.BoolValue{Value: true}}, `{"bool":true}`},
 	{"StringValue", marshaler, &pb.KnownTypes{Str: &wpb.StringValue{Value: "plush"}}, `{"str":"plush"}`},
 	{"BytesValue", marshaler, &pb.KnownTypes{Bytes: &wpb.BytesValue{Value: []byte("wow")}}, `{"bytes":"d293"}`},
+
+	{"required", marshaler, &pb.MsgWithRequired{Str: proto.String("hello")}, `{"str":"hello"}`},
+	{"required bytes", marshaler, &pb.MsgWithRequiredBytes{Byts: []byte{}}, `{"byts":""}`},
 }
 
 func TestMarshaling(t *testing.T) {
@@ -462,6 +469,40 @@
 	}
 }
 
+func TestMarshalingNil(t *testing.T) {
+	var msg *pb.Simple
+	m := &Marshaler{}
+	if _, err := m.MarshalToString(msg); err == nil {
+		t.Errorf("mashaling nil returned no error")
+	}
+}
+
+func TestMarshalIllegalTime(t *testing.T) {
+	tests := []struct {
+		pb   proto.Message
+		fail bool
+	}{
+		{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: 1, Nanos: 0}}, false},
+		{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: -1, Nanos: 0}}, false},
+		{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: 1, Nanos: -1}}, true},
+		{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: -1, Nanos: 1}}, true},
+		{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: 1, Nanos: 1000000000}}, true},
+		{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: -1, Nanos: -1000000000}}, true},
+		{&pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 1, Nanos: 1}}, false},
+		{&pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 1, Nanos: -1}}, true},
+		{&pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 1, Nanos: 1000000000}}, true},
+	}
+	for _, tt := range tests {
+		_, err := marshaler.MarshalToString(tt.pb)
+		if err == nil && tt.fail {
+			t.Errorf("marshaler.MarshalToString(%v) = _, <nil>; want _, <non-nil>", tt.pb)
+		}
+		if err != nil && !tt.fail {
+			t.Errorf("marshaler.MarshalToString(%v) = _, %v; want _, <nil>", tt.pb, err)
+		}
+	}
+}
+
 func TestMarshalJSONPBMarshaler(t *testing.T) {
 	rawJson := `{ "foo": "bar", "baz": [0, 1, 2, 3] }`
 	msg := dynamicMessage{rawJson: rawJson}
@@ -492,6 +533,104 @@
 	}
 }
 
+func TestMarshalWithCustomValidation(t *testing.T) {
+	msg := dynamicMessage{rawJson: `{ "foo": "bar", "baz": [0, 1, 2, 3] }`, dummy: &dynamicMessage{}}
+
+	js, err := new(Marshaler).MarshalToString(&msg)
+	if err != nil {
+		t.Errorf("an unexpected error occurred when marshalling to json: %v", err)
+	}
+	err = Unmarshal(strings.NewReader(js), &msg)
+	if err != nil {
+		t.Errorf("an unexpected error occurred when unmarshalling from json: %v", err)
+	}
+}
+
+// Test marshaling message containing unset required fields should produce error.
+func TestMarshalUnsetRequiredFields(t *testing.T) {
+	msgExt := &pb.Real{}
+	proto.SetExtension(msgExt, pb.E_Extm, &pb.MsgWithRequired{})
+
+	tests := []struct {
+		desc      string
+		marshaler *Marshaler
+		pb        proto.Message
+	}{
+		{
+			desc:      "direct required field",
+			marshaler: &Marshaler{},
+			pb:        &pb.MsgWithRequired{},
+		},
+		{
+			desc:      "direct required field + emit defaults",
+			marshaler: &Marshaler{EmitDefaults: true},
+			pb:        &pb.MsgWithRequired{},
+		},
+		{
+			desc:      "indirect required field",
+			marshaler: &Marshaler{},
+			pb:        &pb.MsgWithIndirectRequired{Subm: &pb.MsgWithRequired{}},
+		},
+		{
+			desc:      "indirect required field + emit defaults",
+			marshaler: &Marshaler{EmitDefaults: true},
+			pb:        &pb.MsgWithIndirectRequired{Subm: &pb.MsgWithRequired{}},
+		},
+		{
+			desc:      "direct required wkt field",
+			marshaler: &Marshaler{},
+			pb:        &pb.MsgWithRequiredWKT{},
+		},
+		{
+			desc:      "direct required wkt field + emit defaults",
+			marshaler: &Marshaler{EmitDefaults: true},
+			pb:        &pb.MsgWithRequiredWKT{},
+		},
+		{
+			desc:      "direct required bytes field",
+			marshaler: &Marshaler{},
+			pb:        &pb.MsgWithRequiredBytes{},
+		},
+		{
+			desc:      "required in map value",
+			marshaler: &Marshaler{},
+			pb: &pb.MsgWithIndirectRequired{
+				MapField: map[string]*pb.MsgWithRequired{
+					"key": {},
+				},
+			},
+		},
+		{
+			desc:      "required in repeated item",
+			marshaler: &Marshaler{},
+			pb: &pb.MsgWithIndirectRequired{
+				SliceField: []*pb.MsgWithRequired{
+					{Str: proto.String("hello")},
+					{},
+				},
+			},
+		},
+		{
+			desc:      "required inside oneof",
+			marshaler: &Marshaler{},
+			pb: &pb.MsgWithOneof{
+				Union: &pb.MsgWithOneof_MsgWithRequired{&pb.MsgWithRequired{}},
+			},
+		},
+		{
+			desc:      "required inside extension",
+			marshaler: &Marshaler{},
+			pb:        msgExt,
+		},
+	}
+
+	for _, tc := range tests {
+		if _, err := tc.marshaler.MarshalToString(tc.pb); err == nil {
+			t.Errorf("%s: expecting error in marshaling with unset required fields %+v", tc.desc, tc.pb)
+		}
+	}
+}
+
 var unmarshalingTests = []struct {
 	desc        string
 	unmarshaler Unmarshaler
@@ -553,8 +692,10 @@
 	{"camelName input", Unmarshaler{}, `{"oBool":true}`, &pb.Simple{OBool: proto.Bool(true)}},
 
 	{"Duration", Unmarshaler{}, `{"dur":"3.000s"}`, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}},
+	{"Duration", Unmarshaler{}, `{"dur":"4s"}`, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 4}}},
 	{"null Duration", Unmarshaler{}, `{"dur":null}`, &pb.KnownTypes{Dur: nil}},
 	{"Timestamp", Unmarshaler{}, `{"ts":"2014-05-13T16:53:20.021Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 21e6}}},
+	{"Timestamp", Unmarshaler{}, `{"ts":"2014-05-13T16:53:20Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 0}}},
 	{"PreEpochTimestamp", Unmarshaler{}, `{"ts":"1969-12-31T23:59:58.999999995Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: -2, Nanos: 999999995}}},
 	{"ZeroTimeTimestamp", Unmarshaler{}, `{"ts":"0001-01-01T00:00:00Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: -62135596800, Nanos: 0}}},
 	{"null Timestamp", Unmarshaler{}, `{"ts":null}`, &pb.KnownTypes{Ts: nil}},
@@ -623,6 +764,9 @@
 	{"null BoolValue", Unmarshaler{}, `{"bool":null}`, &pb.KnownTypes{Bool: nil}},
 	{"null StringValue", Unmarshaler{}, `{"str":null}`, &pb.KnownTypes{Str: nil}},
 	{"null BytesValue", Unmarshaler{}, `{"bytes":null}`, &pb.KnownTypes{Bytes: nil}},
+
+	{"required", Unmarshaler{}, `{"str":"hello"}`, &pb.MsgWithRequired{Str: proto.String("hello")}},
+	{"required bytes", Unmarshaler{}, `{"byts": []}`, &pb.MsgWithRequiredBytes{Byts: []byte{}}},
 }
 
 func TestUnmarshaling(t *testing.T) {
@@ -821,7 +965,7 @@
 	}
 
 	if !proto.Equal(&got, &want) {
-		t.Errorf("message contents not set correctly after unmarshalling JSON: got %s, wanted %s", got, want)
+		t.Errorf("message contents not set correctly after unmarshalling JSON: got %v, wanted %v", got, want)
 	}
 }
 
@@ -873,6 +1017,10 @@
 // It provides implementations of JSONPBMarshaler and JSONPBUnmarshaler for JSON support.
 type dynamicMessage struct {
 	rawJson string `protobuf:"bytes,1,opt,name=rawJson"`
+
+	// an unexported nested message is present just to ensure that it
+	// won't result in a panic (see issue #509)
+	dummy *dynamicMessage `protobuf:"bytes,2,opt,name=dummy"`
 }
 
 func (m *dynamicMessage) Reset() {
@@ -894,3 +1042,109 @@
 	m.rawJson = string(js)
 	return nil
 }
+
+// Test unmarshaling message containing unset required fields should produce error.
+func TestUnmarshalUnsetRequiredFields(t *testing.T) {
+	tests := []struct {
+		desc string
+		pb   proto.Message
+		json string
+	}{
+		{
+			desc: "direct required field missing",
+			pb:   &pb.MsgWithRequired{},
+			json: `{}`,
+		},
+		{
+			desc: "direct required field set to null",
+			pb:   &pb.MsgWithRequired{},
+			json: `{"str": null}`,
+		},
+		{
+			desc: "indirect required field missing",
+			pb:   &pb.MsgWithIndirectRequired{},
+			json: `{"subm": {}}`,
+		},
+		{
+			desc: "indirect required field set to null",
+			pb:   &pb.MsgWithIndirectRequired{},
+			json: `{"subm": {"str": null}}`,
+		},
+		{
+			desc: "direct required bytes field missing",
+			pb:   &pb.MsgWithRequiredBytes{},
+			json: `{}`,
+		},
+		{
+			desc: "direct required bytes field set to null",
+			pb:   &pb.MsgWithRequiredBytes{},
+			json: `{"byts": null}`,
+		},
+		{
+			desc: "direct required wkt field missing",
+			pb:   &pb.MsgWithRequiredWKT{},
+			json: `{}`,
+		},
+		{
+			desc: "direct required wkt field set to null",
+			pb:   &pb.MsgWithRequiredWKT{},
+			json: `{"str": null}`,
+		},
+		{
+			desc: "any containing message with required field set to null",
+			pb:   &pb.KnownTypes{},
+			json: `{"an": {"@type": "example.com/jsonpb.MsgWithRequired", "str": null}}`,
+		},
+		{
+			desc: "any containing message with missing required field",
+			pb:   &pb.KnownTypes{},
+			json: `{"an": {"@type": "example.com/jsonpb.MsgWithRequired"}}`,
+		},
+		{
+			desc: "missing required in map value",
+			pb:   &pb.MsgWithIndirectRequired{},
+			json: `{"map_field": {"a": {}, "b": {"str": "hi"}}}`,
+		},
+		{
+			desc: "required in map value set to null",
+			pb:   &pb.MsgWithIndirectRequired{},
+			json: `{"map_field": {"a": {"str": "hello"}, "b": {"str": null}}}`,
+		},
+		{
+			desc: "missing required in slice item",
+			pb:   &pb.MsgWithIndirectRequired{},
+			json: `{"slice_field": [{}, {"str": "hi"}]}`,
+		},
+		{
+			desc: "required in slice item set to null",
+			pb:   &pb.MsgWithIndirectRequired{},
+			json: `{"slice_field": [{"str": "hello"}, {"str": null}]}`,
+		},
+		{
+			desc: "required inside oneof missing",
+			pb:   &pb.MsgWithOneof{},
+			json: `{"msgWithRequired": {}}`,
+		},
+		{
+			desc: "required inside oneof set to null",
+			pb:   &pb.MsgWithOneof{},
+			json: `{"msgWithRequired": {"str": null}}`,
+		},
+		{
+			desc: "required field in extension missing",
+			pb:   &pb.Real{},
+			json: `{"[jsonpb.extm]":{}}`,
+		},
+		{
+			desc: "required field in extension set to null",
+			pb:   &pb.Real{},
+			json: `{"[jsonpb.extm]":{"str": null}}`,
+		},
+	}
+
+	for _, tc := range tests {
+		if err := UnmarshalString(tc.json, tc.pb); err == nil {
+			t.Errorf("%s: expecting error in unmarshaling with unset required fields %s", tc.desc, tc.json)
+		}
+	}
+}
diff --git a/jsonpb/jsonpb_test_proto/Makefile b/jsonpb/jsonpb_test_proto/Makefile
deleted file mode 100644
index eeda8ae..0000000
--- a/jsonpb/jsonpb_test_proto/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-# Go support for Protocol Buffers - Google's data interchange format
-#
-# Copyright 2015 The Go Authors.  All rights reserved.
-# https://github.com/golang/protobuf
-#
-# 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.
-
-regenerate:
-	protoc --go_out=Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any,Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration,Mgoogle/protobuf/struct.proto=github.com/golang/protobuf/ptypes/struct,Mgoogle/protobuf/timestamp.proto=github.com/golang/protobuf/ptypes/timestamp,Mgoogle/protobuf/wrappers.proto=github.com/golang/protobuf/ptypes/wrappers:. *.proto
diff --git a/jsonpb/jsonpb_test_proto/more_test_objects.pb.go b/jsonpb/jsonpb_test_proto/more_test_objects.pb.go
index ebb180e..1bcce02 100644
--- a/jsonpb/jsonpb_test_proto/more_test_objects.pb.go
+++ b/jsonpb/jsonpb_test_proto/more_test_objects.pb.go
@@ -1,29 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // source: more_test_objects.proto
 
-/*
-Package jsonpb is a generated protocol buffer package.
-
-It is generated from these files:
-	more_test_objects.proto
-	test_objects.proto
-
-It has these top-level messages:
-	Simple3
-	SimpleSlice3
-	SimpleMap3
-	SimpleNull3
-	Mappy
-	Simple
-	NonFinites
-	Repeats
-	Widget
-	Maps
-	MsgWithOneof
-	Real
-	Complex
-	KnownTypes
-*/
 package jsonpb
 
 import proto "github.com/golang/protobuf/proto"
@@ -63,16 +40,40 @@
 func (x Numeral) String() string {
 	return proto.EnumName(Numeral_name, int32(x))
 }
-func (Numeral) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
-
-type Simple3 struct {
-	Dub float64 `protobuf:"fixed64,1,opt,name=dub" json:"dub,omitempty"`
+func (Numeral) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_more_test_objects_bef0d79b901f4c4a, []int{0}
 }
 
-func (m *Simple3) Reset()                    { *m = Simple3{} }
-func (m *Simple3) String() string            { return proto.CompactTextString(m) }
-func (*Simple3) ProtoMessage()               {}
-func (*Simple3) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+type Simple3 struct {
+	Dub                  float64  `protobuf:"fixed64,1,opt,name=dub" json:"dub,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Simple3) Reset()         { *m = Simple3{} }
+func (m *Simple3) String() string { return proto.CompactTextString(m) }
+func (*Simple3) ProtoMessage()    {}
+func (*Simple3) Descriptor() ([]byte, []int) {
+	return fileDescriptor_more_test_objects_bef0d79b901f4c4a, []int{0}
+}
+func (m *Simple3) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Simple3.Unmarshal(m, b)
+}
+func (m *Simple3) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Simple3.Marshal(b, m, deterministic)
+}
+func (dst *Simple3) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Simple3.Merge(dst, src)
+}
+func (m *Simple3) XXX_Size() int {
+	return xxx_messageInfo_Simple3.Size(m)
+}
+func (m *Simple3) XXX_DiscardUnknown() {
+	xxx_messageInfo_Simple3.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Simple3 proto.InternalMessageInfo
 
 func (m *Simple3) GetDub() float64 {
 	if m != nil {
@@ -82,13 +83,35 @@
 }
 
 type SimpleSlice3 struct {
-	Slices []string `protobuf:"bytes,1,rep,name=slices" json:"slices,omitempty"`
+	Slices               []string `protobuf:"bytes,1,rep,name=slices" json:"slices,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
 }
 
-func (m *SimpleSlice3) Reset()                    { *m = SimpleSlice3{} }
-func (m *SimpleSlice3) String() string            { return proto.CompactTextString(m) }
-func (*SimpleSlice3) ProtoMessage()               {}
-func (*SimpleSlice3) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
+func (m *SimpleSlice3) Reset()         { *m = SimpleSlice3{} }
+func (m *SimpleSlice3) String() string { return proto.CompactTextString(m) }
+func (*SimpleSlice3) ProtoMessage()    {}
+func (*SimpleSlice3) Descriptor() ([]byte, []int) {
+	return fileDescriptor_more_test_objects_bef0d79b901f4c4a, []int{1}
+}
+func (m *SimpleSlice3) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_SimpleSlice3.Unmarshal(m, b)
+}
+func (m *SimpleSlice3) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_SimpleSlice3.Marshal(b, m, deterministic)
+}
+func (dst *SimpleSlice3) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_SimpleSlice3.Merge(dst, src)
+}
+func (m *SimpleSlice3) XXX_Size() int {
+	return xxx_messageInfo_SimpleSlice3.Size(m)
+}
+func (m *SimpleSlice3) XXX_DiscardUnknown() {
+	xxx_messageInfo_SimpleSlice3.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SimpleSlice3 proto.InternalMessageInfo
 
 func (m *SimpleSlice3) GetSlices() []string {
 	if m != nil {
@@ -98,13 +121,35 @@
 }
 
 type SimpleMap3 struct {
-	Stringy map[string]string `protobuf:"bytes,1,rep,name=stringy" json:"stringy,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	Stringy              map[string]string `protobuf:"bytes,1,rep,name=stringy" json:"stringy,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
+	XXX_unrecognized     []byte            `json:"-"`
+	XXX_sizecache        int32             `json:"-"`
 }
 
-func (m *SimpleMap3) Reset()                    { *m = SimpleMap3{} }
-func (m *SimpleMap3) String() string            { return proto.CompactTextString(m) }
-func (*SimpleMap3) ProtoMessage()               {}
-func (*SimpleMap3) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
+func (m *SimpleMap3) Reset()         { *m = SimpleMap3{} }
+func (m *SimpleMap3) String() string { return proto.CompactTextString(m) }
+func (*SimpleMap3) ProtoMessage()    {}
+func (*SimpleMap3) Descriptor() ([]byte, []int) {
+	return fileDescriptor_more_test_objects_bef0d79b901f4c4a, []int{2}
+}
+func (m *SimpleMap3) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_SimpleMap3.Unmarshal(m, b)
+}
+func (m *SimpleMap3) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_SimpleMap3.Marshal(b, m, deterministic)
+}
+func (dst *SimpleMap3) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_SimpleMap3.Merge(dst, src)
+}
+func (m *SimpleMap3) XXX_Size() int {
+	return xxx_messageInfo_SimpleMap3.Size(m)
+}
+func (m *SimpleMap3) XXX_DiscardUnknown() {
+	xxx_messageInfo_SimpleMap3.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SimpleMap3 proto.InternalMessageInfo
 
 func (m *SimpleMap3) GetStringy() map[string]string {
 	if m != nil {
@@ -114,13 +159,35 @@
 }
 
 type SimpleNull3 struct {
-	Simple *Simple3 `protobuf:"bytes,1,opt,name=simple" json:"simple,omitempty"`
+	Simple               *Simple3 `protobuf:"bytes,1,opt,name=simple" json:"simple,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
 }
 
-func (m *SimpleNull3) Reset()                    { *m = SimpleNull3{} }
-func (m *SimpleNull3) String() string            { return proto.CompactTextString(m) }
-func (*SimpleNull3) ProtoMessage()               {}
-func (*SimpleNull3) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
+func (m *SimpleNull3) Reset()         { *m = SimpleNull3{} }
+func (m *SimpleNull3) String() string { return proto.CompactTextString(m) }
+func (*SimpleNull3) ProtoMessage()    {}
+func (*SimpleNull3) Descriptor() ([]byte, []int) {
+	return fileDescriptor_more_test_objects_bef0d79b901f4c4a, []int{3}
+}
+func (m *SimpleNull3) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_SimpleNull3.Unmarshal(m, b)
+}
+func (m *SimpleNull3) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_SimpleNull3.Marshal(b, m, deterministic)
+}
+func (dst *SimpleNull3) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_SimpleNull3.Merge(dst, src)
+}
+func (m *SimpleNull3) XXX_Size() int {
+	return xxx_messageInfo_SimpleNull3.Size(m)
+}
+func (m *SimpleNull3) XXX_DiscardUnknown() {
+	xxx_messageInfo_SimpleNull3.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SimpleNull3 proto.InternalMessageInfo
 
 func (m *SimpleNull3) GetSimple() *Simple3 {
 	if m != nil {
@@ -130,22 +197,44 @@
 }
 
 type Mappy struct {
-	Nummy    map[int64]int32    `protobuf:"bytes,1,rep,name=nummy" json:"nummy,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
-	Strry    map[string]string  `protobuf:"bytes,2,rep,name=strry" json:"strry,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	Objjy    map[int32]*Simple3 `protobuf:"bytes,3,rep,name=objjy" json:"objjy,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	Buggy    map[int64]string   `protobuf:"bytes,4,rep,name=buggy" json:"buggy,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	Booly    map[bool]bool      `protobuf:"bytes,5,rep,name=booly" json:"booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
-	Enumy    map[string]Numeral `protobuf:"bytes,6,rep,name=enumy" json:"enumy,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value,enum=jsonpb.Numeral"`
-	S32Booly map[int32]bool     `protobuf:"bytes,7,rep,name=s32booly" json:"s32booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
-	S64Booly map[int64]bool     `protobuf:"bytes,8,rep,name=s64booly" json:"s64booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
-	U32Booly map[uint32]bool    `protobuf:"bytes,9,rep,name=u32booly" json:"u32booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
-	U64Booly map[uint64]bool    `protobuf:"bytes,10,rep,name=u64booly" json:"u64booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	Nummy                map[int64]int32    `protobuf:"bytes,1,rep,name=nummy" json:"nummy,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	Strry                map[string]string  `protobuf:"bytes,2,rep,name=strry" json:"strry,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	Objjy                map[int32]*Simple3 `protobuf:"bytes,3,rep,name=objjy" json:"objjy,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	Buggy                map[int64]string   `protobuf:"bytes,4,rep,name=buggy" json:"buggy,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	Booly                map[bool]bool      `protobuf:"bytes,5,rep,name=booly" json:"booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	Enumy                map[string]Numeral `protobuf:"bytes,6,rep,name=enumy" json:"enumy,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value,enum=jsonpb.Numeral"`
+	S32Booly             map[int32]bool     `protobuf:"bytes,7,rep,name=s32booly" json:"s32booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	S64Booly             map[int64]bool     `protobuf:"bytes,8,rep,name=s64booly" json:"s64booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	U32Booly             map[uint32]bool    `protobuf:"bytes,9,rep,name=u32booly" json:"u32booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	U64Booly             map[uint64]bool    `protobuf:"bytes,10,rep,name=u64booly" json:"u64booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	XXX_NoUnkeyedLiteral struct{}           `json:"-"`
+	XXX_unrecognized     []byte             `json:"-"`
+	XXX_sizecache        int32              `json:"-"`
 }
 
-func (m *Mappy) Reset()                    { *m = Mappy{} }
-func (m *Mappy) String() string            { return proto.CompactTextString(m) }
-func (*Mappy) ProtoMessage()               {}
-func (*Mappy) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
+func (m *Mappy) Reset()         { *m = Mappy{} }
+func (m *Mappy) String() string { return proto.CompactTextString(m) }
+func (*Mappy) ProtoMessage()    {}
+func (*Mappy) Descriptor() ([]byte, []int) {
+	return fileDescriptor_more_test_objects_bef0d79b901f4c4a, []int{4}
+}
+func (m *Mappy) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Mappy.Unmarshal(m, b)
+}
+func (m *Mappy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Mappy.Marshal(b, m, deterministic)
+}
+func (dst *Mappy) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Mappy.Merge(dst, src)
+}
+func (m *Mappy) XXX_Size() int {
+	return xxx_messageInfo_Mappy.Size(m)
+}
+func (m *Mappy) XXX_DiscardUnknown() {
+	xxx_messageInfo_Mappy.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Mappy proto.InternalMessageInfo
 
 func (m *Mappy) GetNummy() map[int64]int32 {
 	if m != nil {
@@ -221,14 +310,27 @@
 	proto.RegisterType((*Simple3)(nil), "jsonpb.Simple3")
 	proto.RegisterType((*SimpleSlice3)(nil), "jsonpb.SimpleSlice3")
 	proto.RegisterType((*SimpleMap3)(nil), "jsonpb.SimpleMap3")
+	proto.RegisterMapType((map[string]string)(nil), "jsonpb.SimpleMap3.StringyEntry")
 	proto.RegisterType((*SimpleNull3)(nil), "jsonpb.SimpleNull3")
 	proto.RegisterType((*Mappy)(nil), "jsonpb.Mappy")
+	proto.RegisterMapType((map[bool]bool)(nil), "jsonpb.Mappy.BoolyEntry")
+	proto.RegisterMapType((map[int64]string)(nil), "jsonpb.Mappy.BuggyEntry")
+	proto.RegisterMapType((map[string]Numeral)(nil), "jsonpb.Mappy.EnumyEntry")
+	proto.RegisterMapType((map[int64]int32)(nil), "jsonpb.Mappy.NummyEntry")
+	proto.RegisterMapType((map[int32]*Simple3)(nil), "jsonpb.Mappy.ObjjyEntry")
+	proto.RegisterMapType((map[int32]bool)(nil), "jsonpb.Mappy.S32boolyEntry")
+	proto.RegisterMapType((map[int64]bool)(nil), "jsonpb.Mappy.S64boolyEntry")
+	proto.RegisterMapType((map[string]string)(nil), "jsonpb.Mappy.StrryEntry")
+	proto.RegisterMapType((map[uint32]bool)(nil), "jsonpb.Mappy.U32boolyEntry")
+	proto.RegisterMapType((map[uint64]bool)(nil), "jsonpb.Mappy.U64boolyEntry")
 	proto.RegisterEnum("jsonpb.Numeral", Numeral_name, Numeral_value)
 }
 
-func init() { proto.RegisterFile("more_test_objects.proto", fileDescriptor0) }
+func init() {
+	proto.RegisterFile("more_test_objects.proto", fileDescriptor_more_test_objects_bef0d79b901f4c4a)
+}
 
-var fileDescriptor0 = []byte{
+var fileDescriptor_more_test_objects_bef0d79b901f4c4a = []byte{
 	// 526 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0xdd, 0x6b, 0xdb, 0x3c,
 	0x14, 0x87, 0x5f, 0x27, 0xf5, 0xd7, 0x49, 0xfb, 0x2e, 0x88, 0xb1, 0x99, 0xf4, 0x62, 0xc5, 0xb0,
diff --git a/jsonpb/jsonpb_test_proto/test_objects.pb.go b/jsonpb/jsonpb_test_proto/test_objects.pb.go
index d413d74..d9e24db 100644
--- a/jsonpb/jsonpb_test_proto/test_objects.pb.go
+++ b/jsonpb/jsonpb_test_proto/test_objects.pb.go
@@ -6,17 +6,23 @@
 import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import math "math"
-import google_protobuf "github.com/golang/protobuf/ptypes/any"
-import google_protobuf1 "github.com/golang/protobuf/ptypes/duration"
-import google_protobuf2 "github.com/golang/protobuf/ptypes/struct"
-import google_protobuf3 "github.com/golang/protobuf/ptypes/timestamp"
-import google_protobuf4 "github.com/golang/protobuf/ptypes/wrappers"
+import any "github.com/golang/protobuf/ptypes/any"
+import duration "github.com/golang/protobuf/ptypes/duration"
+import _struct "github.com/golang/protobuf/ptypes/struct"
+import timestamp "github.com/golang/protobuf/ptypes/timestamp"
+import wrappers "github.com/golang/protobuf/ptypes/wrappers"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
 var _ = fmt.Errorf
 var _ = math.Inf
 
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
 type Widget_Color int32
 
 const (
@@ -52,28 +58,51 @@
 	*x = Widget_Color(value)
 	return nil
 }
-func (Widget_Color) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{3, 0} }
+func (Widget_Color) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{3, 0}
+}
 
 // Test message for holding primitive types.
 type Simple struct {
-	OBool            *bool    `protobuf:"varint,1,opt,name=o_bool,json=oBool" json:"o_bool,omitempty"`
-	OInt32           *int32   `protobuf:"varint,2,opt,name=o_int32,json=oInt32" json:"o_int32,omitempty"`
-	OInt64           *int64   `protobuf:"varint,3,opt,name=o_int64,json=oInt64" json:"o_int64,omitempty"`
-	OUint32          *uint32  `protobuf:"varint,4,opt,name=o_uint32,json=oUint32" json:"o_uint32,omitempty"`
-	OUint64          *uint64  `protobuf:"varint,5,opt,name=o_uint64,json=oUint64" json:"o_uint64,omitempty"`
-	OSint32          *int32   `protobuf:"zigzag32,6,opt,name=o_sint32,json=oSint32" json:"o_sint32,omitempty"`
-	OSint64          *int64   `protobuf:"zigzag64,7,opt,name=o_sint64,json=oSint64" json:"o_sint64,omitempty"`
-	OFloat           *float32 `protobuf:"fixed32,8,opt,name=o_float,json=oFloat" json:"o_float,omitempty"`
-	ODouble          *float64 `protobuf:"fixed64,9,opt,name=o_double,json=oDouble" json:"o_double,omitempty"`
-	OString          *string  `protobuf:"bytes,10,opt,name=o_string,json=oString" json:"o_string,omitempty"`
-	OBytes           []byte   `protobuf:"bytes,11,opt,name=o_bytes,json=oBytes" json:"o_bytes,omitempty"`
-	XXX_unrecognized []byte   `json:"-"`
+	OBool                *bool    `protobuf:"varint,1,opt,name=o_bool,json=oBool" json:"o_bool,omitempty"`
+	OInt32               *int32   `protobuf:"varint,2,opt,name=o_int32,json=oInt32" json:"o_int32,omitempty"`
+	OInt64               *int64   `protobuf:"varint,3,opt,name=o_int64,json=oInt64" json:"o_int64,omitempty"`
+	OUint32              *uint32  `protobuf:"varint,4,opt,name=o_uint32,json=oUint32" json:"o_uint32,omitempty"`
+	OUint64              *uint64  `protobuf:"varint,5,opt,name=o_uint64,json=oUint64" json:"o_uint64,omitempty"`
+	OSint32              *int32   `protobuf:"zigzag32,6,opt,name=o_sint32,json=oSint32" json:"o_sint32,omitempty"`
+	OSint64              *int64   `protobuf:"zigzag64,7,opt,name=o_sint64,json=oSint64" json:"o_sint64,omitempty"`
+	OFloat               *float32 `protobuf:"fixed32,8,opt,name=o_float,json=oFloat" json:"o_float,omitempty"`
+	ODouble              *float64 `protobuf:"fixed64,9,opt,name=o_double,json=oDouble" json:"o_double,omitempty"`
+	OString              *string  `protobuf:"bytes,10,opt,name=o_string,json=oString" json:"o_string,omitempty"`
+	OBytes               []byte   `protobuf:"bytes,11,opt,name=o_bytes,json=oBytes" json:"o_bytes,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
 }
 
-func (m *Simple) Reset()                    { *m = Simple{} }
-func (m *Simple) String() string            { return proto.CompactTextString(m) }
-func (*Simple) ProtoMessage()               {}
-func (*Simple) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
+func (m *Simple) Reset()         { *m = Simple{} }
+func (m *Simple) String() string { return proto.CompactTextString(m) }
+func (*Simple) ProtoMessage()    {}
+func (*Simple) Descriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{0}
+}
+func (m *Simple) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Simple.Unmarshal(m, b)
+}
+func (m *Simple) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Simple.Marshal(b, m, deterministic)
+}
+func (dst *Simple) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Simple.Merge(dst, src)
+}
+func (m *Simple) XXX_Size() int {
+	return xxx_messageInfo_Simple.Size(m)
+}
+func (m *Simple) XXX_DiscardUnknown() {
+	xxx_messageInfo_Simple.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Simple proto.InternalMessageInfo
 
 func (m *Simple) GetOBool() bool {
 	if m != nil && m.OBool != nil {
@@ -154,19 +183,40 @@
 
 // Test message for holding special non-finites primitives.
 type NonFinites struct {
-	FNan             *float32 `protobuf:"fixed32,1,opt,name=f_nan,json=fNan" json:"f_nan,omitempty"`
-	FPinf            *float32 `protobuf:"fixed32,2,opt,name=f_pinf,json=fPinf" json:"f_pinf,omitempty"`
-	FNinf            *float32 `protobuf:"fixed32,3,opt,name=f_ninf,json=fNinf" json:"f_ninf,omitempty"`
-	DNan             *float64 `protobuf:"fixed64,4,opt,name=d_nan,json=dNan" json:"d_nan,omitempty"`
-	DPinf            *float64 `protobuf:"fixed64,5,opt,name=d_pinf,json=dPinf" json:"d_pinf,omitempty"`
-	DNinf            *float64 `protobuf:"fixed64,6,opt,name=d_ninf,json=dNinf" json:"d_ninf,omitempty"`
-	XXX_unrecognized []byte   `json:"-"`
+	FNan                 *float32 `protobuf:"fixed32,1,opt,name=f_nan,json=fNan" json:"f_nan,omitempty"`
+	FPinf                *float32 `protobuf:"fixed32,2,opt,name=f_pinf,json=fPinf" json:"f_pinf,omitempty"`
+	FNinf                *float32 `protobuf:"fixed32,3,opt,name=f_ninf,json=fNinf" json:"f_ninf,omitempty"`
+	DNan                 *float64 `protobuf:"fixed64,4,opt,name=d_nan,json=dNan" json:"d_nan,omitempty"`
+	DPinf                *float64 `protobuf:"fixed64,5,opt,name=d_pinf,json=dPinf" json:"d_pinf,omitempty"`
+	DNinf                *float64 `protobuf:"fixed64,6,opt,name=d_ninf,json=dNinf" json:"d_ninf,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
 }
 
-func (m *NonFinites) Reset()                    { *m = NonFinites{} }
-func (m *NonFinites) String() string            { return proto.CompactTextString(m) }
-func (*NonFinites) ProtoMessage()               {}
-func (*NonFinites) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} }
+func (m *NonFinites) Reset()         { *m = NonFinites{} }
+func (m *NonFinites) String() string { return proto.CompactTextString(m) }
+func (*NonFinites) ProtoMessage()    {}
+func (*NonFinites) Descriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{1}
+}
+func (m *NonFinites) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_NonFinites.Unmarshal(m, b)
+}
+func (m *NonFinites) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_NonFinites.Marshal(b, m, deterministic)
+}
+func (dst *NonFinites) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_NonFinites.Merge(dst, src)
+}
+func (m *NonFinites) XXX_Size() int {
+	return xxx_messageInfo_NonFinites.Size(m)
+}
+func (m *NonFinites) XXX_DiscardUnknown() {
+	xxx_messageInfo_NonFinites.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_NonFinites proto.InternalMessageInfo
 
 func (m *NonFinites) GetFNan() float32 {
 	if m != nil && m.FNan != nil {
@@ -212,24 +262,45 @@
 
 // Test message for holding repeated primitives.
 type Repeats struct {
-	RBool            []bool    `protobuf:"varint,1,rep,name=r_bool,json=rBool" json:"r_bool,omitempty"`
-	RInt32           []int32   `protobuf:"varint,2,rep,name=r_int32,json=rInt32" json:"r_int32,omitempty"`
-	RInt64           []int64   `protobuf:"varint,3,rep,name=r_int64,json=rInt64" json:"r_int64,omitempty"`
-	RUint32          []uint32  `protobuf:"varint,4,rep,name=r_uint32,json=rUint32" json:"r_uint32,omitempty"`
-	RUint64          []uint64  `protobuf:"varint,5,rep,name=r_uint64,json=rUint64" json:"r_uint64,omitempty"`
-	RSint32          []int32   `protobuf:"zigzag32,6,rep,name=r_sint32,json=rSint32" json:"r_sint32,omitempty"`
-	RSint64          []int64   `protobuf:"zigzag64,7,rep,name=r_sint64,json=rSint64" json:"r_sint64,omitempty"`
-	RFloat           []float32 `protobuf:"fixed32,8,rep,name=r_float,json=rFloat" json:"r_float,omitempty"`
-	RDouble          []float64 `protobuf:"fixed64,9,rep,name=r_double,json=rDouble" json:"r_double,omitempty"`
-	RString          []string  `protobuf:"bytes,10,rep,name=r_string,json=rString" json:"r_string,omitempty"`
-	RBytes           [][]byte  `protobuf:"bytes,11,rep,name=r_bytes,json=rBytes" json:"r_bytes,omitempty"`
-	XXX_unrecognized []byte    `json:"-"`
+	RBool                []bool    `protobuf:"varint,1,rep,name=r_bool,json=rBool" json:"r_bool,omitempty"`
+	RInt32               []int32   `protobuf:"varint,2,rep,name=r_int32,json=rInt32" json:"r_int32,omitempty"`
+	RInt64               []int64   `protobuf:"varint,3,rep,name=r_int64,json=rInt64" json:"r_int64,omitempty"`
+	RUint32              []uint32  `protobuf:"varint,4,rep,name=r_uint32,json=rUint32" json:"r_uint32,omitempty"`
+	RUint64              []uint64  `protobuf:"varint,5,rep,name=r_uint64,json=rUint64" json:"r_uint64,omitempty"`
+	RSint32              []int32   `protobuf:"zigzag32,6,rep,name=r_sint32,json=rSint32" json:"r_sint32,omitempty"`
+	RSint64              []int64   `protobuf:"zigzag64,7,rep,name=r_sint64,json=rSint64" json:"r_sint64,omitempty"`
+	RFloat               []float32 `protobuf:"fixed32,8,rep,name=r_float,json=rFloat" json:"r_float,omitempty"`
+	RDouble              []float64 `protobuf:"fixed64,9,rep,name=r_double,json=rDouble" json:"r_double,omitempty"`
+	RString              []string  `protobuf:"bytes,10,rep,name=r_string,json=rString" json:"r_string,omitempty"`
+	RBytes               [][]byte  `protobuf:"bytes,11,rep,name=r_bytes,json=rBytes" json:"r_bytes,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
+	XXX_unrecognized     []byte    `json:"-"`
+	XXX_sizecache        int32     `json:"-"`
 }
 
-func (m *Repeats) Reset()                    { *m = Repeats{} }
-func (m *Repeats) String() string            { return proto.CompactTextString(m) }
-func (*Repeats) ProtoMessage()               {}
-func (*Repeats) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} }
+func (m *Repeats) Reset()         { *m = Repeats{} }
+func (m *Repeats) String() string { return proto.CompactTextString(m) }
+func (*Repeats) ProtoMessage()    {}
+func (*Repeats) Descriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{2}
+}
+func (m *Repeats) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Repeats.Unmarshal(m, b)
+}
+func (m *Repeats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Repeats.Marshal(b, m, deterministic)
+}
+func (dst *Repeats) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Repeats.Merge(dst, src)
+}
+func (m *Repeats) XXX_Size() int {
+	return xxx_messageInfo_Repeats.Size(m)
+}
+func (m *Repeats) XXX_DiscardUnknown() {
+	xxx_messageInfo_Repeats.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Repeats proto.InternalMessageInfo
 
 func (m *Repeats) GetRBool() []bool {
 	if m != nil {
@@ -310,19 +381,40 @@
 
 // Test message for holding enums and nested messages.
 type Widget struct {
-	Color            *Widget_Color  `protobuf:"varint,1,opt,name=color,enum=jsonpb.Widget_Color" json:"color,omitempty"`
-	RColor           []Widget_Color `protobuf:"varint,2,rep,name=r_color,json=rColor,enum=jsonpb.Widget_Color" json:"r_color,omitempty"`
-	Simple           *Simple        `protobuf:"bytes,10,opt,name=simple" json:"simple,omitempty"`
-	RSimple          []*Simple      `protobuf:"bytes,11,rep,name=r_simple,json=rSimple" json:"r_simple,omitempty"`
-	Repeats          *Repeats       `protobuf:"bytes,20,opt,name=repeats" json:"repeats,omitempty"`
-	RRepeats         []*Repeats     `protobuf:"bytes,21,rep,name=r_repeats,json=rRepeats" json:"r_repeats,omitempty"`
-	XXX_unrecognized []byte         `json:"-"`
+	Color                *Widget_Color  `protobuf:"varint,1,opt,name=color,enum=jsonpb.Widget_Color" json:"color,omitempty"`
+	RColor               []Widget_Color `protobuf:"varint,2,rep,name=r_color,json=rColor,enum=jsonpb.Widget_Color" json:"r_color,omitempty"`
+	Simple               *Simple        `protobuf:"bytes,10,opt,name=simple" json:"simple,omitempty"`
+	RSimple              []*Simple      `protobuf:"bytes,11,rep,name=r_simple,json=rSimple" json:"r_simple,omitempty"`
+	Repeats              *Repeats       `protobuf:"bytes,20,opt,name=repeats" json:"repeats,omitempty"`
+	RRepeats             []*Repeats     `protobuf:"bytes,21,rep,name=r_repeats,json=rRepeats" json:"r_repeats,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}       `json:"-"`
+	XXX_unrecognized     []byte         `json:"-"`
+	XXX_sizecache        int32          `json:"-"`
 }
 
-func (m *Widget) Reset()                    { *m = Widget{} }
-func (m *Widget) String() string            { return proto.CompactTextString(m) }
-func (*Widget) ProtoMessage()               {}
-func (*Widget) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{3} }
+func (m *Widget) Reset()         { *m = Widget{} }
+func (m *Widget) String() string { return proto.CompactTextString(m) }
+func (*Widget) ProtoMessage()    {}
+func (*Widget) Descriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{3}
+}
+func (m *Widget) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Widget.Unmarshal(m, b)
+}
+func (m *Widget) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Widget.Marshal(b, m, deterministic)
+}
+func (dst *Widget) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Widget.Merge(dst, src)
+}
+func (m *Widget) XXX_Size() int {
+	return xxx_messageInfo_Widget.Size(m)
+}
+func (m *Widget) XXX_DiscardUnknown() {
+	xxx_messageInfo_Widget.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Widget proto.InternalMessageInfo
 
 func (m *Widget) GetColor() Widget_Color {
 	if m != nil && m.Color != nil {
@@ -367,15 +459,36 @@
 }
 
 type Maps struct {
-	MInt64Str        map[int64]string `protobuf:"bytes,1,rep,name=m_int64_str,json=mInt64Str" json:"m_int64_str,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	MBoolSimple      map[bool]*Simple `protobuf:"bytes,2,rep,name=m_bool_simple,json=mBoolSimple" json:"m_bool_simple,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	XXX_unrecognized []byte           `json:"-"`
+	MInt64Str            map[int64]string `protobuf:"bytes,1,rep,name=m_int64_str,json=mInt64Str" json:"m_int64_str,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	MBoolSimple          map[bool]*Simple `protobuf:"bytes,2,rep,name=m_bool_simple,json=mBoolSimple" json:"m_bool_simple,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	XXX_NoUnkeyedLiteral struct{}         `json:"-"`
+	XXX_unrecognized     []byte           `json:"-"`
+	XXX_sizecache        int32            `json:"-"`
 }
 
-func (m *Maps) Reset()                    { *m = Maps{} }
-func (m *Maps) String() string            { return proto.CompactTextString(m) }
-func (*Maps) ProtoMessage()               {}
-func (*Maps) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{4} }
+func (m *Maps) Reset()         { *m = Maps{} }
+func (m *Maps) String() string { return proto.CompactTextString(m) }
+func (*Maps) ProtoMessage()    {}
+func (*Maps) Descriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{4}
+}
+func (m *Maps) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Maps.Unmarshal(m, b)
+}
+func (m *Maps) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Maps.Marshal(b, m, deterministic)
+}
+func (dst *Maps) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Maps.Merge(dst, src)
+}
+func (m *Maps) XXX_Size() int {
+	return xxx_messageInfo_Maps.Size(m)
+}
+func (m *Maps) XXX_DiscardUnknown() {
+	xxx_messageInfo_Maps.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Maps proto.InternalMessageInfo
 
 func (m *Maps) GetMInt64Str() map[int64]string {
 	if m != nil {
@@ -397,14 +510,36 @@
 	//	*MsgWithOneof_Salary
 	//	*MsgWithOneof_Country
 	//	*MsgWithOneof_HomeAddress
-	Union            isMsgWithOneof_Union `protobuf_oneof:"union"`
-	XXX_unrecognized []byte               `json:"-"`
+	//	*MsgWithOneof_MsgWithRequired
+	Union                isMsgWithOneof_Union `protobuf_oneof:"union"`
+	XXX_NoUnkeyedLiteral struct{}             `json:"-"`
+	XXX_unrecognized     []byte               `json:"-"`
+	XXX_sizecache        int32                `json:"-"`
 }
 
-func (m *MsgWithOneof) Reset()                    { *m = MsgWithOneof{} }
-func (m *MsgWithOneof) String() string            { return proto.CompactTextString(m) }
-func (*MsgWithOneof) ProtoMessage()               {}
-func (*MsgWithOneof) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{5} }
+func (m *MsgWithOneof) Reset()         { *m = MsgWithOneof{} }
+func (m *MsgWithOneof) String() string { return proto.CompactTextString(m) }
+func (*MsgWithOneof) ProtoMessage()    {}
+func (*MsgWithOneof) Descriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{5}
+}
+func (m *MsgWithOneof) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_MsgWithOneof.Unmarshal(m, b)
+}
+func (m *MsgWithOneof) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_MsgWithOneof.Marshal(b, m, deterministic)
+}
+func (dst *MsgWithOneof) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_MsgWithOneof.Merge(dst, src)
+}
+func (m *MsgWithOneof) XXX_Size() int {
+	return xxx_messageInfo_MsgWithOneof.Size(m)
+}
+func (m *MsgWithOneof) XXX_DiscardUnknown() {
+	xxx_messageInfo_MsgWithOneof.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgWithOneof proto.InternalMessageInfo
 
 type isMsgWithOneof_Union interface {
 	isMsgWithOneof_Union()
@@ -422,11 +557,15 @@
 type MsgWithOneof_HomeAddress struct {
 	HomeAddress string `protobuf:"bytes,4,opt,name=home_address,json=homeAddress,oneof"`
 }
+type MsgWithOneof_MsgWithRequired struct {
+	MsgWithRequired *MsgWithRequired `protobuf:"bytes,5,opt,name=msg_with_required,json=msgWithRequired,oneof"`
+}
 
-func (*MsgWithOneof_Title) isMsgWithOneof_Union()       {}
-func (*MsgWithOneof_Salary) isMsgWithOneof_Union()      {}
-func (*MsgWithOneof_Country) isMsgWithOneof_Union()     {}
-func (*MsgWithOneof_HomeAddress) isMsgWithOneof_Union() {}
+func (*MsgWithOneof_Title) isMsgWithOneof_Union()           {}
+func (*MsgWithOneof_Salary) isMsgWithOneof_Union()          {}
+func (*MsgWithOneof_Country) isMsgWithOneof_Union()         {}
+func (*MsgWithOneof_HomeAddress) isMsgWithOneof_Union()     {}
+func (*MsgWithOneof_MsgWithRequired) isMsgWithOneof_Union() {}
 
 func (m *MsgWithOneof) GetUnion() isMsgWithOneof_Union {
 	if m != nil {
@@ -463,6 +602,13 @@
 	return ""
 }
 
+func (m *MsgWithOneof) GetMsgWithRequired() *MsgWithRequired {
+	if x, ok := m.GetUnion().(*MsgWithOneof_MsgWithRequired); ok {
+		return x.MsgWithRequired
+	}
+	return nil
+}
+
 // XXX_OneofFuncs is for the internal use of the proto package.
 func (*MsgWithOneof) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
 	return _MsgWithOneof_OneofMarshaler, _MsgWithOneof_OneofUnmarshaler, _MsgWithOneof_OneofSizer, []interface{}{
@@ -470,6 +616,7 @@
 		(*MsgWithOneof_Salary)(nil),
 		(*MsgWithOneof_Country)(nil),
 		(*MsgWithOneof_HomeAddress)(nil),
+		(*MsgWithOneof_MsgWithRequired)(nil),
 	}
 }
 
@@ -489,6 +636,11 @@
 	case *MsgWithOneof_HomeAddress:
 		b.EncodeVarint(4<<3 | proto.WireBytes)
 		b.EncodeStringBytes(x.HomeAddress)
+	case *MsgWithOneof_MsgWithRequired:
+		b.EncodeVarint(5<<3 | proto.WireBytes)
+		if err := b.EncodeMessage(x.MsgWithRequired); err != nil {
+			return err
+		}
 	case nil:
 	default:
 		return fmt.Errorf("MsgWithOneof.Union has unexpected type %T", x)
@@ -527,6 +679,14 @@
 		x, err := b.DecodeStringBytes()
 		m.Union = &MsgWithOneof_HomeAddress{x}
 		return true, err
+	case 5: // union.msg_with_required
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		msg := new(MsgWithRequired)
+		err := b.DecodeMessage(msg)
+		m.Union = &MsgWithOneof_MsgWithRequired{msg}
+		return true, err
 	default:
 		return false, nil
 	}
@@ -537,20 +697,25 @@
 	// union
 	switch x := m.Union.(type) {
 	case *MsgWithOneof_Title:
-		n += proto.SizeVarint(1<<3 | proto.WireBytes)
+		n += 1 // tag and wire
 		n += proto.SizeVarint(uint64(len(x.Title)))
 		n += len(x.Title)
 	case *MsgWithOneof_Salary:
-		n += proto.SizeVarint(2<<3 | proto.WireVarint)
+		n += 1 // tag and wire
 		n += proto.SizeVarint(uint64(x.Salary))
 	case *MsgWithOneof_Country:
-		n += proto.SizeVarint(3<<3 | proto.WireBytes)
+		n += 1 // tag and wire
 		n += proto.SizeVarint(uint64(len(x.Country)))
 		n += len(x.Country)
 	case *MsgWithOneof_HomeAddress:
-		n += proto.SizeVarint(4<<3 | proto.WireBytes)
+		n += 1 // tag and wire
 		n += proto.SizeVarint(uint64(len(x.HomeAddress)))
 		n += len(x.HomeAddress)
+	case *MsgWithOneof_MsgWithRequired:
+		s := proto.Size(x.MsgWithRequired)
+		n += 1 // tag and wire
+		n += proto.SizeVarint(uint64(s))
+		n += s
 	case nil:
 	default:
 		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
@@ -560,22 +725,43 @@
 
 type Real struct {
 	Value                        *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"`
+	XXX_NoUnkeyedLiteral         struct{} `json:"-"`
 	proto.XXX_InternalExtensions `json:"-"`
 	XXX_unrecognized             []byte `json:"-"`
+	XXX_sizecache                int32  `json:"-"`
 }
 
-func (m *Real) Reset()                    { *m = Real{} }
-func (m *Real) String() string            { return proto.CompactTextString(m) }
-func (*Real) ProtoMessage()               {}
-func (*Real) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{6} }
+func (m *Real) Reset()         { *m = Real{} }
+func (m *Real) String() string { return proto.CompactTextString(m) }
+func (*Real) ProtoMessage()    {}
+func (*Real) Descriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{6}
+}
 
 var extRange_Real = []proto.ExtensionRange{
-	{100, 536870911},
+	{Start: 100, End: 536870911},
 }
 
 func (*Real) ExtensionRangeArray() []proto.ExtensionRange {
 	return extRange_Real
 }
+func (m *Real) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Real.Unmarshal(m, b)
+}
+func (m *Real) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Real.Marshal(b, m, deterministic)
+}
+func (dst *Real) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Real.Merge(dst, src)
+}
+func (m *Real) XXX_Size() int {
+	return xxx_messageInfo_Real.Size(m)
+}
+func (m *Real) XXX_DiscardUnknown() {
+	xxx_messageInfo_Real.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Real proto.InternalMessageInfo
 
 func (m *Real) GetValue() float64 {
 	if m != nil && m.Value != nil {
@@ -586,22 +772,43 @@
 
 type Complex struct {
 	Imaginary                    *float64 `protobuf:"fixed64,1,opt,name=imaginary" json:"imaginary,omitempty"`
+	XXX_NoUnkeyedLiteral         struct{} `json:"-"`
 	proto.XXX_InternalExtensions `json:"-"`
 	XXX_unrecognized             []byte `json:"-"`
+	XXX_sizecache                int32  `json:"-"`
 }
 
-func (m *Complex) Reset()                    { *m = Complex{} }
-func (m *Complex) String() string            { return proto.CompactTextString(m) }
-func (*Complex) ProtoMessage()               {}
-func (*Complex) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{7} }
+func (m *Complex) Reset()         { *m = Complex{} }
+func (m *Complex) String() string { return proto.CompactTextString(m) }
+func (*Complex) ProtoMessage()    {}
+func (*Complex) Descriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{7}
+}
 
 var extRange_Complex = []proto.ExtensionRange{
-	{100, 536870911},
+	{Start: 100, End: 536870911},
 }
 
 func (*Complex) ExtensionRangeArray() []proto.ExtensionRange {
 	return extRange_Complex
 }
+func (m *Complex) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Complex.Unmarshal(m, b)
+}
+func (m *Complex) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Complex.Marshal(b, m, deterministic)
+}
+func (dst *Complex) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Complex.Merge(dst, src)
+}
+func (m *Complex) XXX_Size() int {
+	return xxx_messageInfo_Complex.Size(m)
+}
+func (m *Complex) XXX_DiscardUnknown() {
+	xxx_messageInfo_Complex.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Complex proto.InternalMessageInfo
 
 func (m *Complex) GetImaginary() float64 {
 	if m != nil && m.Imaginary != nil {
@@ -620,134 +827,324 @@
 }
 
 type KnownTypes struct {
-	An               *google_protobuf.Any          `protobuf:"bytes,14,opt,name=an" json:"an,omitempty"`
-	Dur              *google_protobuf1.Duration    `protobuf:"bytes,1,opt,name=dur" json:"dur,omitempty"`
-	St               *google_protobuf2.Struct      `protobuf:"bytes,12,opt,name=st" json:"st,omitempty"`
-	Ts               *google_protobuf3.Timestamp   `protobuf:"bytes,2,opt,name=ts" json:"ts,omitempty"`
-	Lv               *google_protobuf2.ListValue   `protobuf:"bytes,15,opt,name=lv" json:"lv,omitempty"`
-	Val              *google_protobuf2.Value       `protobuf:"bytes,16,opt,name=val" json:"val,omitempty"`
-	Dbl              *google_protobuf4.DoubleValue `protobuf:"bytes,3,opt,name=dbl" json:"dbl,omitempty"`
-	Flt              *google_protobuf4.FloatValue  `protobuf:"bytes,4,opt,name=flt" json:"flt,omitempty"`
-	I64              *google_protobuf4.Int64Value  `protobuf:"bytes,5,opt,name=i64" json:"i64,omitempty"`
-	U64              *google_protobuf4.UInt64Value `protobuf:"bytes,6,opt,name=u64" json:"u64,omitempty"`
-	I32              *google_protobuf4.Int32Value  `protobuf:"bytes,7,opt,name=i32" json:"i32,omitempty"`
-	U32              *google_protobuf4.UInt32Value `protobuf:"bytes,8,opt,name=u32" json:"u32,omitempty"`
-	Bool             *google_protobuf4.BoolValue   `protobuf:"bytes,9,opt,name=bool" json:"bool,omitempty"`
-	Str              *google_protobuf4.StringValue `protobuf:"bytes,10,opt,name=str" json:"str,omitempty"`
-	Bytes            *google_protobuf4.BytesValue  `protobuf:"bytes,11,opt,name=bytes" json:"bytes,omitempty"`
-	XXX_unrecognized []byte                        `json:"-"`
+	An                   *any.Any              `protobuf:"bytes,14,opt,name=an" json:"an,omitempty"`
+	Dur                  *duration.Duration    `protobuf:"bytes,1,opt,name=dur" json:"dur,omitempty"`
+	St                   *_struct.Struct       `protobuf:"bytes,12,opt,name=st" json:"st,omitempty"`
+	Ts                   *timestamp.Timestamp  `protobuf:"bytes,2,opt,name=ts" json:"ts,omitempty"`
+	Lv                   *_struct.ListValue    `protobuf:"bytes,15,opt,name=lv" json:"lv,omitempty"`
+	Val                  *_struct.Value        `protobuf:"bytes,16,opt,name=val" json:"val,omitempty"`
+	Dbl                  *wrappers.DoubleValue `protobuf:"bytes,3,opt,name=dbl" json:"dbl,omitempty"`
+	Flt                  *wrappers.FloatValue  `protobuf:"bytes,4,opt,name=flt" json:"flt,omitempty"`
+	I64                  *wrappers.Int64Value  `protobuf:"bytes,5,opt,name=i64" json:"i64,omitempty"`
+	U64                  *wrappers.UInt64Value `protobuf:"bytes,6,opt,name=u64" json:"u64,omitempty"`
+	I32                  *wrappers.Int32Value  `protobuf:"bytes,7,opt,name=i32" json:"i32,omitempty"`
+	U32                  *wrappers.UInt32Value `protobuf:"bytes,8,opt,name=u32" json:"u32,omitempty"`
+	Bool                 *wrappers.BoolValue   `protobuf:"bytes,9,opt,name=bool" json:"bool,omitempty"`
+	Str                  *wrappers.StringValue `protobuf:"bytes,10,opt,name=str" json:"str,omitempty"`
+	Bytes                *wrappers.BytesValue  `protobuf:"bytes,11,opt,name=bytes" json:"bytes,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}              `json:"-"`
+	XXX_unrecognized     []byte                `json:"-"`
+	XXX_sizecache        int32                 `json:"-"`
 }
 
-func (m *KnownTypes) Reset()                    { *m = KnownTypes{} }
-func (m *KnownTypes) String() string            { return proto.CompactTextString(m) }
-func (*KnownTypes) ProtoMessage()               {}
-func (*KnownTypes) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{8} }
+func (m *KnownTypes) Reset()         { *m = KnownTypes{} }
+func (m *KnownTypes) String() string { return proto.CompactTextString(m) }
+func (*KnownTypes) ProtoMessage()    {}
+func (*KnownTypes) Descriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{8}
+}
+func (m *KnownTypes) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_KnownTypes.Unmarshal(m, b)
+}
+func (m *KnownTypes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_KnownTypes.Marshal(b, m, deterministic)
+}
+func (dst *KnownTypes) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_KnownTypes.Merge(dst, src)
+}
+func (m *KnownTypes) XXX_Size() int {
+	return xxx_messageInfo_KnownTypes.Size(m)
+}
+func (m *KnownTypes) XXX_DiscardUnknown() {
+	xxx_messageInfo_KnownTypes.DiscardUnknown(m)
+}
 
-func (m *KnownTypes) GetAn() *google_protobuf.Any {
+var xxx_messageInfo_KnownTypes proto.InternalMessageInfo
+
+func (m *KnownTypes) GetAn() *any.Any {
 	if m != nil {
 		return m.An
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetDur() *google_protobuf1.Duration {
+func (m *KnownTypes) GetDur() *duration.Duration {
 	if m != nil {
 		return m.Dur
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetSt() *google_protobuf2.Struct {
+func (m *KnownTypes) GetSt() *_struct.Struct {
 	if m != nil {
 		return m.St
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetTs() *google_protobuf3.Timestamp {
+func (m *KnownTypes) GetTs() *timestamp.Timestamp {
 	if m != nil {
 		return m.Ts
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetLv() *google_protobuf2.ListValue {
+func (m *KnownTypes) GetLv() *_struct.ListValue {
 	if m != nil {
 		return m.Lv
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetVal() *google_protobuf2.Value {
+func (m *KnownTypes) GetVal() *_struct.Value {
 	if m != nil {
 		return m.Val
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetDbl() *google_protobuf4.DoubleValue {
+func (m *KnownTypes) GetDbl() *wrappers.DoubleValue {
 	if m != nil {
 		return m.Dbl
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetFlt() *google_protobuf4.FloatValue {
+func (m *KnownTypes) GetFlt() *wrappers.FloatValue {
 	if m != nil {
 		return m.Flt
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetI64() *google_protobuf4.Int64Value {
+func (m *KnownTypes) GetI64() *wrappers.Int64Value {
 	if m != nil {
 		return m.I64
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetU64() *google_protobuf4.UInt64Value {
+func (m *KnownTypes) GetU64() *wrappers.UInt64Value {
 	if m != nil {
 		return m.U64
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetI32() *google_protobuf4.Int32Value {
+func (m *KnownTypes) GetI32() *wrappers.Int32Value {
 	if m != nil {
 		return m.I32
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetU32() *google_protobuf4.UInt32Value {
+func (m *KnownTypes) GetU32() *wrappers.UInt32Value {
 	if m != nil {
 		return m.U32
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetBool() *google_protobuf4.BoolValue {
+func (m *KnownTypes) GetBool() *wrappers.BoolValue {
 	if m != nil {
 		return m.Bool
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetStr() *google_protobuf4.StringValue {
+func (m *KnownTypes) GetStr() *wrappers.StringValue {
 	if m != nil {
 		return m.Str
 	}
 	return nil
 }
 
-func (m *KnownTypes) GetBytes() *google_protobuf4.BytesValue {
+func (m *KnownTypes) GetBytes() *wrappers.BytesValue {
 	if m != nil {
 		return m.Bytes
 	}
 	return nil
 }
 
+// Test messages for marshaling/unmarshaling required fields.
+type MsgWithRequired struct {
+	Str                  *string  `protobuf:"bytes,1,req,name=str" json:"str,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *MsgWithRequired) Reset()         { *m = MsgWithRequired{} }
+func (m *MsgWithRequired) String() string { return proto.CompactTextString(m) }
+func (*MsgWithRequired) ProtoMessage()    {}
+func (*MsgWithRequired) Descriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{9}
+}
+func (m *MsgWithRequired) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_MsgWithRequired.Unmarshal(m, b)
+}
+func (m *MsgWithRequired) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_MsgWithRequired.Marshal(b, m, deterministic)
+}
+func (dst *MsgWithRequired) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_MsgWithRequired.Merge(dst, src)
+}
+func (m *MsgWithRequired) XXX_Size() int {
+	return xxx_messageInfo_MsgWithRequired.Size(m)
+}
+func (m *MsgWithRequired) XXX_DiscardUnknown() {
+	xxx_messageInfo_MsgWithRequired.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgWithRequired proto.InternalMessageInfo
+
+func (m *MsgWithRequired) GetStr() string {
+	if m != nil && m.Str != nil {
+		return *m.Str
+	}
+	return ""
+}
+
+type MsgWithIndirectRequired struct {
+	Subm                 *MsgWithRequired            `protobuf:"bytes,1,opt,name=subm" json:"subm,omitempty"`
+	MapField             map[string]*MsgWithRequired `protobuf:"bytes,2,rep,name=map_field,json=mapField" json:"map_field,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	SliceField           []*MsgWithRequired          `protobuf:"bytes,3,rep,name=slice_field,json=sliceField" json:"slice_field,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                    `json:"-"`
+	XXX_unrecognized     []byte                      `json:"-"`
+	XXX_sizecache        int32                       `json:"-"`
+}
+
+func (m *MsgWithIndirectRequired) Reset()         { *m = MsgWithIndirectRequired{} }
+func (m *MsgWithIndirectRequired) String() string { return proto.CompactTextString(m) }
+func (*MsgWithIndirectRequired) ProtoMessage()    {}
+func (*MsgWithIndirectRequired) Descriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{10}
+}
+func (m *MsgWithIndirectRequired) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_MsgWithIndirectRequired.Unmarshal(m, b)
+}
+func (m *MsgWithIndirectRequired) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_MsgWithIndirectRequired.Marshal(b, m, deterministic)
+}
+func (dst *MsgWithIndirectRequired) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_MsgWithIndirectRequired.Merge(dst, src)
+}
+func (m *MsgWithIndirectRequired) XXX_Size() int {
+	return xxx_messageInfo_MsgWithIndirectRequired.Size(m)
+}
+func (m *MsgWithIndirectRequired) XXX_DiscardUnknown() {
+	xxx_messageInfo_MsgWithIndirectRequired.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgWithIndirectRequired proto.InternalMessageInfo
+
+func (m *MsgWithIndirectRequired) GetSubm() *MsgWithRequired {
+	if m != nil {
+		return m.Subm
+	}
+	return nil
+}
+
+func (m *MsgWithIndirectRequired) GetMapField() map[string]*MsgWithRequired {
+	if m != nil {
+		return m.MapField
+	}
+	return nil
+}
+
+func (m *MsgWithIndirectRequired) GetSliceField() []*MsgWithRequired {
+	if m != nil {
+		return m.SliceField
+	}
+	return nil
+}
+
+type MsgWithRequiredBytes struct {
+	Byts                 []byte   `protobuf:"bytes,1,req,name=byts" json:"byts,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *MsgWithRequiredBytes) Reset()         { *m = MsgWithRequiredBytes{} }
+func (m *MsgWithRequiredBytes) String() string { return proto.CompactTextString(m) }
+func (*MsgWithRequiredBytes) ProtoMessage()    {}
+func (*MsgWithRequiredBytes) Descriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{11}
+}
+func (m *MsgWithRequiredBytes) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_MsgWithRequiredBytes.Unmarshal(m, b)
+}
+func (m *MsgWithRequiredBytes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_MsgWithRequiredBytes.Marshal(b, m, deterministic)
+}
+func (dst *MsgWithRequiredBytes) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_MsgWithRequiredBytes.Merge(dst, src)
+}
+func (m *MsgWithRequiredBytes) XXX_Size() int {
+	return xxx_messageInfo_MsgWithRequiredBytes.Size(m)
+}
+func (m *MsgWithRequiredBytes) XXX_DiscardUnknown() {
+	xxx_messageInfo_MsgWithRequiredBytes.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgWithRequiredBytes proto.InternalMessageInfo
+
+func (m *MsgWithRequiredBytes) GetByts() []byte {
+	if m != nil {
+		return m.Byts
+	}
+	return nil
+}
+
+type MsgWithRequiredWKT struct {
+	Str                  *wrappers.StringValue `protobuf:"bytes,1,req,name=str" json:"str,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}              `json:"-"`
+	XXX_unrecognized     []byte                `json:"-"`
+	XXX_sizecache        int32                 `json:"-"`
+}
+
+func (m *MsgWithRequiredWKT) Reset()         { *m = MsgWithRequiredWKT{} }
+func (m *MsgWithRequiredWKT) String() string { return proto.CompactTextString(m) }
+func (*MsgWithRequiredWKT) ProtoMessage()    {}
+func (*MsgWithRequiredWKT) Descriptor() ([]byte, []int) {
+	return fileDescriptor_test_objects_c6f6c615ab823e65, []int{12}
+}
+func (m *MsgWithRequiredWKT) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_MsgWithRequiredWKT.Unmarshal(m, b)
+}
+func (m *MsgWithRequiredWKT) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_MsgWithRequiredWKT.Marshal(b, m, deterministic)
+}
+func (dst *MsgWithRequiredWKT) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_MsgWithRequiredWKT.Merge(dst, src)
+}
+func (m *MsgWithRequiredWKT) XXX_Size() int {
+	return xxx_messageInfo_MsgWithRequiredWKT.Size(m)
+}
+func (m *MsgWithRequiredWKT) XXX_DiscardUnknown() {
+	xxx_messageInfo_MsgWithRequiredWKT.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgWithRequiredWKT proto.InternalMessageInfo
+
+func (m *MsgWithRequiredWKT) GetStr() *wrappers.StringValue {
+	if m != nil {
+		return m.Str
+	}
+	return nil
+}
+
 var E_Name = &proto.ExtensionDesc{
 	ExtendedType:  (*Real)(nil),
 	ExtensionType: (*string)(nil),
@@ -757,96 +1154,125 @@
 	Filename:      "test_objects.proto",
 }
 
+var E_Extm = &proto.ExtensionDesc{
+	ExtendedType:  (*Real)(nil),
+	ExtensionType: (*MsgWithRequired)(nil),
+	Field:         125,
+	Name:          "jsonpb.extm",
+	Tag:           "bytes,125,opt,name=extm",
+	Filename:      "test_objects.proto",
+}
+
 func init() {
 	proto.RegisterType((*Simple)(nil), "jsonpb.Simple")
 	proto.RegisterType((*NonFinites)(nil), "jsonpb.NonFinites")
 	proto.RegisterType((*Repeats)(nil), "jsonpb.Repeats")
 	proto.RegisterType((*Widget)(nil), "jsonpb.Widget")
 	proto.RegisterType((*Maps)(nil), "jsonpb.Maps")
+	proto.RegisterMapType((map[bool]*Simple)(nil), "jsonpb.Maps.MBoolSimpleEntry")
+	proto.RegisterMapType((map[int64]string)(nil), "jsonpb.Maps.MInt64StrEntry")
 	proto.RegisterType((*MsgWithOneof)(nil), "jsonpb.MsgWithOneof")
 	proto.RegisterType((*Real)(nil), "jsonpb.Real")
 	proto.RegisterType((*Complex)(nil), "jsonpb.Complex")
 	proto.RegisterType((*KnownTypes)(nil), "jsonpb.KnownTypes")
+	proto.RegisterType((*MsgWithRequired)(nil), "jsonpb.MsgWithRequired")
+	proto.RegisterType((*MsgWithIndirectRequired)(nil), "jsonpb.MsgWithIndirectRequired")
+	proto.RegisterMapType((map[string]*MsgWithRequired)(nil), "jsonpb.MsgWithIndirectRequired.MapFieldEntry")
+	proto.RegisterType((*MsgWithRequiredBytes)(nil), "jsonpb.MsgWithRequiredBytes")
+	proto.RegisterType((*MsgWithRequiredWKT)(nil), "jsonpb.MsgWithRequiredWKT")
 	proto.RegisterEnum("jsonpb.Widget_Color", Widget_Color_name, Widget_Color_value)
 	proto.RegisterExtension(E_Complex_RealExtension)
 	proto.RegisterExtension(E_Name)
+	proto.RegisterExtension(E_Extm)
 }
 
-func init() { proto.RegisterFile("test_objects.proto", fileDescriptor1) }
+func init() { proto.RegisterFile("test_objects.proto", fileDescriptor_test_objects_c6f6c615ab823e65) }
 
-var fileDescriptor1 = []byte{
-	// 1160 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x95, 0x41, 0x73, 0xdb, 0x44,
-	0x14, 0xc7, 0x23, 0xc9, 0x92, 0xed, 0x75, 0x92, 0x9a, 0x6d, 0xda, 0x2a, 0x26, 0x80, 0xc6, 0x94,
-	0x22, 0x0a, 0x75, 0x07, 0xc7, 0xe3, 0x61, 0x0a, 0x97, 0xa4, 0x71, 0x29, 0x43, 0x13, 0x98, 0x4d,
-	0x43, 0x8f, 0x1e, 0x39, 0x5a, 0xbb, 0x2a, 0xf2, 0xae, 0x67, 0x77, 0x95, 0xd4, 0x03, 0x87, 0x9c,
-	0x39, 0x32, 0x7c, 0x05, 0xf8, 0x08, 0x1c, 0xf8, 0x74, 0xcc, 0xdb, 0x95, 0xac, 0xc4, 0x8e, 0x4f,
-	0xf1, 0x7b, 0xef, 0xff, 0xfe, 0x59, 0xed, 0x6f, 0x77, 0x1f, 0xc2, 0x8a, 0x4a, 0x35, 0xe4, 0xa3,
-	0x77, 0xf4, 0x5c, 0xc9, 0xce, 0x4c, 0x70, 0xc5, 0xb1, 0xf7, 0x4e, 0x72, 0x36, 0x1b, 0xb5, 0x76,
-	0x27, 0x9c, 0x4f, 0x52, 0xfa, 0x54, 0x67, 0x47, 0xd9, 0xf8, 0x69, 0xc4, 0xe6, 0x46, 0xd2, 0xfa,
-	0x78, 0xb9, 0x14, 0x67, 0x22, 0x52, 0x09, 0x67, 0x79, 0x7d, 0x6f, 0xb9, 0x2e, 0x95, 0xc8, 0xce,
-	0x55, 0x5e, 0xfd, 0x64, 0xb9, 0xaa, 0x92, 0x29, 0x95, 0x2a, 0x9a, 0xce, 0xd6, 0xd9, 0x5f, 0x8a,
-	0x68, 0x36, 0xa3, 0x22, 0x5f, 0x61, 0xfb, 0x6f, 0x1b, 0x79, 0xa7, 0xc9, 0x74, 0x96, 0x52, 0x7c,
-	0x0f, 0x79, 0x7c, 0x38, 0xe2, 0x3c, 0xf5, 0xad, 0xc0, 0x0a, 0x6b, 0xc4, 0xe5, 0x87, 0x9c, 0xa7,
-	0xf8, 0x01, 0xaa, 0xf2, 0x61, 0xc2, 0xd4, 0x7e, 0xd7, 0xb7, 0x03, 0x2b, 0x74, 0x89, 0xc7, 0x7f,
-	0x80, 0x68, 0x51, 0xe8, 0xf7, 0x7c, 0x27, 0xb0, 0x42, 0xc7, 0x14, 0xfa, 0x3d, 0xbc, 0x8b, 0x6a,
-	0x7c, 0x98, 0x99, 0x96, 0x4a, 0x60, 0x85, 0x5b, 0xa4, 0xca, 0xcf, 0x74, 0x58, 0x96, 0xfa, 0x3d,
-	0xdf, 0x0d, 0xac, 0xb0, 0x92, 0x97, 0x8a, 0x2e, 0x69, 0xba, 0xbc, 0xc0, 0x0a, 0x3f, 0x20, 0x55,
-	0x7e, 0x7a, 0xad, 0x4b, 0x9a, 0xae, 0x6a, 0x60, 0x85, 0x38, 0x2f, 0xf5, 0x7b, 0x66, 0x11, 0xe3,
-	0x94, 0x47, 0xca, 0xaf, 0x05, 0x56, 0x68, 0x13, 0x8f, 0xbf, 0x80, 0xc8, 0xf4, 0xc4, 0x3c, 0x1b,
-	0xa5, 0xd4, 0xaf, 0x07, 0x56, 0x68, 0x91, 0x2a, 0x3f, 0xd2, 0x61, 0x6e, 0xa7, 0x44, 0xc2, 0x26,
-	0x3e, 0x0a, 0xac, 0xb0, 0x0e, 0x76, 0x3a, 0x34, 0x76, 0xa3, 0xb9, 0xa2, 0xd2, 0x6f, 0x04, 0x56,
-	0xb8, 0x49, 0x3c, 0x7e, 0x08, 0x51, 0xfb, 0x4f, 0x0b, 0xa1, 0x13, 0xce, 0x5e, 0x24, 0x2c, 0x51,
-	0x54, 0xe2, 0xbb, 0xc8, 0x1d, 0x0f, 0x59, 0xc4, 0xf4, 0x56, 0xd9, 0xa4, 0x32, 0x3e, 0x89, 0x18,
-	0x6c, 0xe0, 0x78, 0x38, 0x4b, 0xd8, 0x58, 0x6f, 0x94, 0x4d, 0xdc, 0xf1, 0xcf, 0x09, 0x1b, 0x9b,
-	0x34, 0x83, 0xb4, 0x93, 0xa7, 0x4f, 0x20, 0x7d, 0x17, 0xb9, 0xb1, 0xb6, 0xa8, 0xe8, 0xd5, 0x55,
-	0xe2, 0xdc, 0x22, 0x36, 0x16, 0xae, 0xce, 0xba, 0x71, 0x61, 0x11, 0x1b, 0x0b, 0x2f, 0x4f, 0x83,
-	0x45, 0xfb, 0x1f, 0x1b, 0x55, 0x09, 0x9d, 0xd1, 0x48, 0x49, 0x90, 0x88, 0x82, 0x9e, 0x03, 0xf4,
-	0x44, 0x41, 0x4f, 0x2c, 0xe8, 0x39, 0x40, 0x4f, 0x2c, 0xe8, 0x89, 0x05, 0x3d, 0x07, 0xe8, 0x89,
-	0x05, 0x3d, 0x51, 0xd2, 0x73, 0x80, 0x9e, 0x28, 0xe9, 0x89, 0x92, 0x9e, 0x03, 0xf4, 0x44, 0x49,
-	0x4f, 0x94, 0xf4, 0x1c, 0xa0, 0x27, 0x4e, 0xaf, 0x75, 0x2d, 0xe8, 0x39, 0x40, 0x4f, 0x94, 0xf4,
-	0xc4, 0x82, 0x9e, 0x03, 0xf4, 0xc4, 0x82, 0x9e, 0x28, 0xe9, 0x39, 0x40, 0x4f, 0x94, 0xf4, 0x44,
-	0x49, 0xcf, 0x01, 0x7a, 0xa2, 0xa4, 0x27, 0x16, 0xf4, 0x1c, 0xa0, 0x27, 0x0c, 0xbd, 0x7f, 0x6d,
-	0xe4, 0xbd, 0x49, 0xe2, 0x09, 0x55, 0xf8, 0x31, 0x72, 0xcf, 0x79, 0xca, 0x85, 0x26, 0xb7, 0xdd,
-	0xdd, 0xe9, 0x98, 0x2b, 0xda, 0x31, 0xe5, 0xce, 0x73, 0xa8, 0x11, 0x23, 0xc1, 0x4f, 0xc0, 0xcf,
-	0xa8, 0x61, 0xf3, 0xd6, 0xa9, 0x3d, 0xa1, 0xff, 0xe2, 0x47, 0xc8, 0x93, 0xfa, 0x2a, 0xe9, 0x53,
-	0xd5, 0xe8, 0x6e, 0x17, 0x6a, 0x73, 0xc1, 0x48, 0x5e, 0xc5, 0x5f, 0x98, 0x0d, 0xd1, 0x4a, 0x58,
-	0xe7, 0xaa, 0x12, 0x36, 0x28, 0x97, 0x56, 0x85, 0x01, 0xec, 0xef, 0x68, 0xcf, 0x3b, 0x85, 0x32,
-	0xe7, 0x4e, 0x8a, 0x3a, 0xfe, 0x0a, 0xd5, 0xc5, 0xb0, 0x10, 0xdf, 0xd3, 0xb6, 0x2b, 0xe2, 0x9a,
-	0xc8, 0x7f, 0xb5, 0x3f, 0x43, 0xae, 0x59, 0x74, 0x15, 0x39, 0x64, 0x70, 0xd4, 0xdc, 0xc0, 0x75,
-	0xe4, 0x7e, 0x4f, 0x06, 0x83, 0x93, 0xa6, 0x85, 0x6b, 0xa8, 0x72, 0xf8, 0xea, 0x6c, 0xd0, 0xb4,
-	0xdb, 0x7f, 0xd9, 0xa8, 0x72, 0x1c, 0xcd, 0x24, 0xfe, 0x16, 0x35, 0xa6, 0xe6, 0xb8, 0xc0, 0xde,
-	0xeb, 0x33, 0xd6, 0xe8, 0x7e, 0x58, 0xf8, 0x83, 0xa4, 0x73, 0xac, 0xcf, 0xcf, 0xa9, 0x12, 0x03,
-	0xa6, 0xc4, 0x9c, 0xd4, 0xa7, 0x45, 0x8c, 0x0f, 0xd0, 0xd6, 0x54, 0x9f, 0xcd, 0xe2, 0xab, 0x6d,
-	0xdd, 0xfe, 0xd1, 0xcd, 0x76, 0x38, 0xaf, 0xe6, 0xb3, 0x8d, 0x41, 0x63, 0x5a, 0x66, 0x5a, 0xdf,
-	0xa1, 0xed, 0x9b, 0xfe, 0xb8, 0x89, 0x9c, 0x5f, 0xe9, 0x5c, 0x63, 0x74, 0x08, 0xfc, 0xc4, 0x3b,
-	0xc8, 0xbd, 0x88, 0xd2, 0x8c, 0xea, 0xeb, 0x57, 0x27, 0x26, 0x78, 0x66, 0x7f, 0x63, 0xb5, 0x4e,
-	0x50, 0x73, 0xd9, 0xfe, 0x7a, 0x7f, 0xcd, 0xf4, 0x3f, 0xbc, 0xde, 0xbf, 0x0a, 0xa5, 0xf4, 0x6b,
-	0xff, 0x61, 0xa1, 0xcd, 0x63, 0x39, 0x79, 0x93, 0xa8, 0xb7, 0x3f, 0x31, 0xca, 0xc7, 0xf8, 0x3e,
-	0x72, 0x55, 0xa2, 0x52, 0xaa, 0xed, 0xea, 0x2f, 0x37, 0x88, 0x09, 0xb1, 0x8f, 0x3c, 0x19, 0xa5,
-	0x91, 0x98, 0x6b, 0x4f, 0xe7, 0xe5, 0x06, 0xc9, 0x63, 0xdc, 0x42, 0xd5, 0xe7, 0x3c, 0x83, 0x95,
-	0xe8, 0x67, 0x01, 0x7a, 0x8a, 0x04, 0xfe, 0x14, 0x6d, 0xbe, 0xe5, 0x53, 0x3a, 0x8c, 0xe2, 0x58,
-	0x50, 0x29, 0xf5, 0x0b, 0x01, 0x82, 0x06, 0x64, 0x0f, 0x4c, 0xf2, 0xb0, 0x8a, 0xdc, 0x8c, 0x25,
-	0x9c, 0xb5, 0x1f, 0xa1, 0x0a, 0xa1, 0x51, 0x5a, 0x7e, 0xbe, 0x65, 0xde, 0x08, 0x1d, 0x3c, 0xae,
-	0xd5, 0xe2, 0xe6, 0xd5, 0xd5, 0xd5, 0x95, 0xdd, 0xbe, 0x84, 0xff, 0x08, 0x5f, 0xf2, 0x1e, 0xef,
-	0xa1, 0x7a, 0x32, 0x8d, 0x26, 0x09, 0x83, 0x95, 0x19, 0x79, 0x99, 0x28, 0x5b, 0xba, 0x47, 0x68,
-	0x5b, 0xd0, 0x28, 0x1d, 0xd2, 0xf7, 0x8a, 0x32, 0x99, 0x70, 0x86, 0x37, 0xcb, 0x23, 0x15, 0xa5,
-	0xfe, 0x6f, 0x37, 0xcf, 0x64, 0x6e, 0x4f, 0xb6, 0xa0, 0x69, 0x50, 0xf4, 0xb4, 0xff, 0x73, 0x11,
-	0xfa, 0x91, 0xf1, 0x4b, 0xf6, 0x7a, 0x3e, 0xa3, 0x12, 0x3f, 0x44, 0x76, 0xc4, 0xfc, 0x6d, 0xdd,
-	0xba, 0xd3, 0x31, 0xf3, 0xa9, 0x53, 0xcc, 0xa7, 0xce, 0x01, 0x9b, 0x13, 0x3b, 0x62, 0xf8, 0x4b,
-	0xe4, 0xc4, 0x99, 0xb9, 0xa5, 0x8d, 0xee, 0xee, 0x8a, 0xec, 0x28, 0x9f, 0x92, 0x04, 0x54, 0xf8,
-	0x73, 0x64, 0x4b, 0xe5, 0x6f, 0x6a, 0xed, 0x83, 0x15, 0xed, 0xa9, 0x9e, 0x98, 0xc4, 0x96, 0x70,
-	0xfb, 0x6d, 0x25, 0x73, 0xbe, 0xad, 0x15, 0xe1, 0xeb, 0x62, 0x78, 0x12, 0x5b, 0x49, 0xd0, 0xa6,
-	0x17, 0xfe, 0x9d, 0x35, 0xda, 0x57, 0x89, 0x54, 0xbf, 0xc0, 0x0e, 0x13, 0x3b, 0xbd, 0xc0, 0x21,
-	0x72, 0x2e, 0xa2, 0xd4, 0x6f, 0x6a, 0xf1, 0xfd, 0x15, 0xb1, 0x11, 0x82, 0x04, 0x77, 0x90, 0x13,
-	0x8f, 0x52, 0xcd, 0xbc, 0xd1, 0xdd, 0x5b, 0xfd, 0x2e, 0xfd, 0xc8, 0xe5, 0xfa, 0x78, 0x94, 0xe2,
-	0x27, 0xc8, 0x19, 0xa7, 0x4a, 0x1f, 0x01, 0xb8, 0x70, 0xcb, 0x7a, 0xfd, 0x5c, 0xe6, 0xf2, 0x71,
-	0xaa, 0x40, 0x9e, 0xe4, 0xb3, 0xf5, 0x36, 0xb9, 0xbe, 0x42, 0xb9, 0x3c, 0xe9, 0xf7, 0x60, 0x35,
-	0x59, 0xbf, 0xa7, 0xa7, 0xca, 0x6d, 0xab, 0x39, 0xbb, 0xae, 0xcf, 0xfa, 0x3d, 0x6d, 0xbf, 0xdf,
-	0xd5, 0x43, 0x78, 0x8d, 0xfd, 0x7e, 0xb7, 0xb0, 0xdf, 0xef, 0x6a, 0xfb, 0xfd, 0xae, 0x9e, 0xcc,
-	0xeb, 0xec, 0x17, 0xfa, 0x4c, 0xeb, 0x2b, 0x7a, 0x84, 0xd5, 0xd7, 0x6c, 0x3a, 0xdc, 0x61, 0x23,
-	0xd7, 0x3a, 0xf0, 0x87, 0xd7, 0x08, 0xad, 0xf1, 0x37, 0x63, 0x21, 0xf7, 0x97, 0x4a, 0xe0, 0xaf,
-	0x91, 0x5b, 0x0e, 0xf7, 0xdb, 0x3e, 0x40, 0x8f, 0x0b, 0xd3, 0x60, 0x94, 0xcf, 0x02, 0x54, 0x61,
-	0xd1, 0x94, 0x2e, 0x1d, 0xfc, 0xdf, 0xf5, 0x0b, 0xa3, 0x2b, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff,
-	0xd5, 0x39, 0x32, 0x09, 0xf9, 0x09, 0x00, 0x00,
+var fileDescriptor_test_objects_c6f6c615ab823e65 = []byte{
+	// 1357 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xdd, 0x72, 0x13, 0xc7,
+	0x12, 0xf6, 0xee, 0x6a, 0xf5, 0xd3, 0xf2, 0x1f, 0x83, 0x81, 0xc5, 0x87, 0x73, 0x8e, 0x4a, 0x70,
+	0x38, 0x0a, 0xc4, 0xa2, 0x22, 0xbb, 0x5c, 0x84, 0xe4, 0x06, 0x63, 0x13, 0x08, 0xe0, 0xa4, 0xc6,
+	0x26, 0x5c, 0xaa, 0x56, 0xde, 0x91, 0x59, 0xb2, 0xbb, 0xa3, 0xcc, 0xcc, 0xda, 0xa8, 0x92, 0x54,
+	0xf9, 0x19, 0x52, 0x79, 0x82, 0x54, 0x25, 0x8f, 0x90, 0x8b, 0xbc, 0x45, 0xde, 0x28, 0x35, 0x3d,
+	0xb3, 0x5a, 0x59, 0x42, 0x95, 0x5c, 0x79, 0xbb, 0xfb, 0xeb, 0x4f, 0x33, 0xfd, 0xf5, 0x74, 0x1b,
+	0x88, 0x62, 0x52, 0xf5, 0xf9, 0xe0, 0x1d, 0x3b, 0x51, 0xb2, 0x3b, 0x12, 0x5c, 0x71, 0x52, 0x7d,
+	0x27, 0x79, 0x36, 0x1a, 0x6c, 0xde, 0x3c, 0xe5, 0xfc, 0x34, 0x61, 0x0f, 0xd0, 0x3b, 0xc8, 0x87,
+	0x0f, 0xc2, 0x6c, 0x6c, 0x20, 0x9b, 0xff, 0x99, 0x0d, 0x45, 0xb9, 0x08, 0x55, 0xcc, 0x33, 0x1b,
+	0xbf, 0x35, 0x1b, 0x97, 0x4a, 0xe4, 0x27, 0xca, 0x46, 0xff, 0x3b, 0x1b, 0x55, 0x71, 0xca, 0xa4,
+	0x0a, 0xd3, 0xd1, 0x22, 0xfa, 0x73, 0x11, 0x8e, 0x46, 0x4c, 0xd8, 0x13, 0xb6, 0x7f, 0x75, 0xa1,
+	0x7a, 0x14, 0xa7, 0xa3, 0x84, 0x91, 0x6b, 0x50, 0xe5, 0xfd, 0x01, 0xe7, 0x49, 0xe0, 0xb4, 0x9c,
+	0x4e, 0x9d, 0xfa, 0x7c, 0x8f, 0xf3, 0x84, 0xdc, 0x80, 0x1a, 0xef, 0xc7, 0x99, 0xda, 0xee, 0x05,
+	0x6e, 0xcb, 0xe9, 0xf8, 0xb4, 0xca, 0x9f, 0x6b, 0x6b, 0x12, 0xd8, 0xdd, 0x09, 0xbc, 0x96, 0xd3,
+	0xf1, 0x4c, 0x60, 0x77, 0x87, 0xdc, 0x84, 0x3a, 0xef, 0xe7, 0x26, 0xa5, 0xd2, 0x72, 0x3a, 0x2b,
+	0xb4, 0xc6, 0x5f, 0xa3, 0x59, 0x86, 0x76, 0x77, 0x02, 0xbf, 0xe5, 0x74, 0x2a, 0x36, 0x54, 0x64,
+	0x49, 0x93, 0x55, 0x6d, 0x39, 0x9d, 0x2b, 0xb4, 0xc6, 0x8f, 0xa6, 0xb2, 0xa4, 0xc9, 0xaa, 0xb5,
+	0x9c, 0x0e, 0xb1, 0xa1, 0xdd, 0x1d, 0x73, 0x88, 0x61, 0xc2, 0x43, 0x15, 0xd4, 0x5b, 0x4e, 0xc7,
+	0xa5, 0x55, 0xfe, 0x54, 0x5b, 0x26, 0x27, 0xe2, 0xf9, 0x20, 0x61, 0x41, 0xa3, 0xe5, 0x74, 0x1c,
+	0x5a, 0xe3, 0xfb, 0x68, 0x5a, 0x3a, 0x25, 0xe2, 0xec, 0x34, 0x80, 0x96, 0xd3, 0x69, 0x68, 0x3a,
+	0x34, 0x0d, 0xdd, 0x60, 0xac, 0x98, 0x0c, 0x9a, 0x2d, 0xa7, 0xb3, 0x4c, 0xab, 0x7c, 0x4f, 0x5b,
+	0xed, 0x9f, 0x1c, 0x80, 0x43, 0x9e, 0x3d, 0x8d, 0xb3, 0x58, 0x31, 0x49, 0xae, 0x82, 0x3f, 0xec,
+	0x67, 0x61, 0x86, 0xa5, 0x72, 0x69, 0x65, 0x78, 0x18, 0x66, 0xba, 0x80, 0xc3, 0xfe, 0x28, 0xce,
+	0x86, 0x58, 0x28, 0x97, 0xfa, 0xc3, 0xaf, 0xe3, 0x6c, 0x68, 0xdc, 0x99, 0x76, 0x7b, 0xd6, 0x7d,
+	0xa8, 0xdd, 0x57, 0xc1, 0x8f, 0x90, 0xa2, 0x82, 0xa7, 0xab, 0x44, 0x96, 0x22, 0x32, 0x14, 0x3e,
+	0x7a, 0xfd, 0xa8, 0xa0, 0x88, 0x0c, 0x45, 0xd5, 0xba, 0x35, 0x45, 0xfb, 0x37, 0x17, 0x6a, 0x94,
+	0x8d, 0x58, 0xa8, 0xa4, 0x86, 0x88, 0x42, 0x3d, 0x4f, 0xab, 0x27, 0x0a, 0xf5, 0xc4, 0x44, 0x3d,
+	0x4f, 0xab, 0x27, 0x26, 0xea, 0x89, 0x89, 0x7a, 0x9e, 0x56, 0x4f, 0x4c, 0xd4, 0x13, 0xa5, 0x7a,
+	0x9e, 0x56, 0x4f, 0x94, 0xea, 0x89, 0x52, 0x3d, 0x4f, 0xab, 0x27, 0x4a, 0xf5, 0x44, 0xa9, 0x9e,
+	0xa7, 0xd5, 0x13, 0x47, 0x53, 0x59, 0x13, 0xf5, 0x3c, 0xad, 0x9e, 0x28, 0xd5, 0x13, 0x13, 0xf5,
+	0x3c, 0xad, 0x9e, 0x98, 0xa8, 0x27, 0x4a, 0xf5, 0x3c, 0xad, 0x9e, 0x28, 0xd5, 0x13, 0xa5, 0x7a,
+	0x9e, 0x56, 0x4f, 0x94, 0xea, 0x89, 0x89, 0x7a, 0x9e, 0x56, 0x4f, 0x18, 0xf5, 0x7e, 0x77, 0xa1,
+	0xfa, 0x26, 0x8e, 0x4e, 0x99, 0x22, 0xf7, 0xc0, 0x3f, 0xe1, 0x09, 0x17, 0xa8, 0xdc, 0x6a, 0x6f,
+	0xa3, 0x6b, 0x9e, 0x68, 0xd7, 0x84, 0xbb, 0x4f, 0x74, 0x8c, 0x1a, 0x08, 0xd9, 0xd2, 0x7c, 0x06,
+	0xad, 0x8b, 0xb7, 0x08, 0x5d, 0x15, 0xf8, 0x97, 0xdc, 0x85, 0xaa, 0xc4, 0xa7, 0x84, 0x5d, 0xd5,
+	0xec, 0xad, 0x16, 0x68, 0xf3, 0xc0, 0xa8, 0x8d, 0x92, 0x8f, 0x4c, 0x41, 0x10, 0xa9, 0xcf, 0x39,
+	0x8f, 0xd4, 0x05, 0xb2, 0xd0, 0x9a, 0x30, 0x02, 0x07, 0x1b, 0xc8, 0xb9, 0x56, 0x20, 0xad, 0xee,
+	0xb4, 0x88, 0x93, 0x8f, 0xa1, 0x21, 0xfa, 0x05, 0xf8, 0x1a, 0xd2, 0xce, 0x81, 0xeb, 0xc2, 0x7e,
+	0xb5, 0xff, 0x07, 0xbe, 0x39, 0x74, 0x0d, 0x3c, 0x7a, 0xb0, 0xbf, 0xbe, 0x44, 0x1a, 0xe0, 0x7f,
+	0x41, 0x0f, 0x0e, 0x0e, 0xd7, 0x1d, 0x52, 0x87, 0xca, 0xde, 0xcb, 0xd7, 0x07, 0xeb, 0x6e, 0xfb,
+	0x67, 0x17, 0x2a, 0xaf, 0xc2, 0x91, 0x24, 0x9f, 0x41, 0x33, 0x35, 0xed, 0xa2, 0x6b, 0x8f, 0x3d,
+	0xd6, 0xec, 0xfd, 0xab, 0xe0, 0xd7, 0x90, 0xee, 0x2b, 0xec, 0x9f, 0x23, 0x25, 0x0e, 0x32, 0x25,
+	0xc6, 0xb4, 0x91, 0x16, 0x36, 0x79, 0x0c, 0x2b, 0x29, 0xf6, 0x66, 0x71, 0x6b, 0x17, 0xd3, 0xff,
+	0x7d, 0x39, 0x5d, 0xf7, 0xab, 0xb9, 0xb6, 0x21, 0x68, 0xa6, 0xa5, 0x67, 0xf3, 0x73, 0x58, 0xbd,
+	0xcc, 0x4f, 0xd6, 0xc1, 0xfb, 0x96, 0x8d, 0x51, 0x46, 0x8f, 0xea, 0x4f, 0xb2, 0x01, 0xfe, 0x59,
+	0x98, 0xe4, 0x0c, 0x9f, 0x5f, 0x83, 0x1a, 0xe3, 0x91, 0xfb, 0xd0, 0xd9, 0x3c, 0x84, 0xf5, 0x59,
+	0xfa, 0xe9, 0xfc, 0xba, 0xc9, 0xbf, 0x33, 0x9d, 0x3f, 0x2f, 0x4a, 0xc9, 0xd7, 0xfe, 0xd3, 0x81,
+	0xe5, 0x57, 0xf2, 0xf4, 0x4d, 0xac, 0xde, 0x7e, 0x95, 0x31, 0x3e, 0x24, 0xd7, 0xc1, 0x57, 0xb1,
+	0x4a, 0x18, 0xd2, 0x35, 0x9e, 0x2d, 0x51, 0x63, 0x92, 0x00, 0xaa, 0x32, 0x4c, 0x42, 0x31, 0x46,
+	0x4e, 0xef, 0xd9, 0x12, 0xb5, 0x36, 0xd9, 0x84, 0xda, 0x13, 0x9e, 0xeb, 0x93, 0xe0, 0x58, 0xd0,
+	0x39, 0x85, 0x83, 0xdc, 0x86, 0xe5, 0xb7, 0x3c, 0x65, 0xfd, 0x30, 0x8a, 0x04, 0x93, 0x12, 0x27,
+	0x84, 0x06, 0x34, 0xb5, 0xf7, 0xb1, 0x71, 0x92, 0x03, 0xb8, 0x92, 0xca, 0xd3, 0xfe, 0x79, 0xac,
+	0xde, 0xf6, 0x05, 0xfb, 0x2e, 0x8f, 0x05, 0x8b, 0x70, 0x6a, 0x34, 0x7b, 0x37, 0x26, 0x85, 0x35,
+	0x67, 0xa4, 0x36, 0xfc, 0x6c, 0x89, 0xae, 0xa5, 0x97, 0x5d, 0x7b, 0x35, 0xf0, 0xf3, 0x2c, 0xe6,
+	0x59, 0xfb, 0x2e, 0x54, 0x28, 0x0b, 0x93, 0xb2, 0x8a, 0x8e, 0x19, 0x35, 0x68, 0xdc, 0xab, 0xd7,
+	0xa3, 0xf5, 0x8b, 0x8b, 0x8b, 0x0b, 0xb7, 0x7d, 0xae, 0x0f, 0xae, 0x0b, 0xf2, 0x9e, 0xdc, 0x82,
+	0x46, 0x9c, 0x86, 0xa7, 0x71, 0xa6, 0x2f, 0x68, 0xe0, 0xa5, 0xa3, 0x4c, 0xe9, 0xed, 0xc3, 0xaa,
+	0x60, 0x61, 0xd2, 0x67, 0xef, 0x15, 0xcb, 0x64, 0xcc, 0x33, 0xb2, 0x5c, 0x76, 0x66, 0x98, 0x04,
+	0xdf, 0x5f, 0x6e, 0x6d, 0x4b, 0x4f, 0x57, 0x74, 0xd2, 0x41, 0x91, 0xd3, 0xfe, 0xc3, 0x07, 0x78,
+	0x91, 0xf1, 0xf3, 0xec, 0x78, 0x3c, 0x62, 0x92, 0xdc, 0x01, 0x37, 0xcc, 0x82, 0x55, 0x4c, 0xdd,
+	0xe8, 0x9a, 0x35, 0xd7, 0x2d, 0xd6, 0x5c, 0xf7, 0x71, 0x36, 0xa6, 0x6e, 0x98, 0x91, 0xfb, 0xe0,
+	0x45, 0xb9, 0x79, 0xec, 0xcd, 0xde, 0xcd, 0x39, 0xd8, 0xbe, 0x5d, 0xb6, 0x54, 0xa3, 0xc8, 0xff,
+	0xc1, 0x95, 0x2a, 0x58, 0xb6, 0x35, 0x9c, 0xc5, 0x1e, 0xe1, 0xe2, 0xa5, 0xae, 0xd4, 0x43, 0xc4,
+	0x55, 0xd2, 0xb6, 0xc9, 0xe6, 0x1c, 0xf0, 0xb8, 0xd8, 0xc1, 0xd4, 0x55, 0x52, 0x63, 0x93, 0xb3,
+	0x60, 0x6d, 0x01, 0xf6, 0x65, 0x2c, 0xd5, 0x37, 0xba, 0xc2, 0xd4, 0x4d, 0xce, 0x48, 0x07, 0xbc,
+	0xb3, 0x30, 0x09, 0xd6, 0x11, 0x7c, 0x7d, 0x0e, 0x6c, 0x80, 0x1a, 0x42, 0xba, 0xe0, 0x45, 0x83,
+	0x04, 0x5b, 0xa7, 0xd9, 0xbb, 0x35, 0x7f, 0x2f, 0x9c, 0x95, 0x16, 0x1f, 0x0d, 0x12, 0xb2, 0x05,
+	0xde, 0x30, 0x51, 0xd8, 0x49, 0xfa, 0xdd, 0xce, 0xe2, 0x71, 0xea, 0x5a, 0xf8, 0x30, 0x51, 0x1a,
+	0x1e, 0xdb, 0x15, 0xfd, 0x21, 0x38, 0xbe, 0x44, 0x0b, 0x8f, 0x77, 0x77, 0xf4, 0x69, 0xf2, 0xdd,
+	0x1d, 0x5c, 0x4e, 0x1f, 0x3a, 0xcd, 0xeb, 0x69, 0x7c, 0xbe, 0xbb, 0x83, 0xf4, 0xdb, 0x3d, 0xdc,
+	0xe5, 0x0b, 0xe8, 0xb7, 0x7b, 0x05, 0xfd, 0x76, 0x0f, 0xe9, 0xb7, 0x7b, 0xb8, 0xe0, 0x17, 0xd1,
+	0x4f, 0xf0, 0x39, 0xe2, 0x2b, 0xb8, 0x09, 0x1b, 0x0b, 0x8a, 0xae, 0x47, 0x81, 0x81, 0x23, 0x4e,
+	0xf3, 0xeb, 0xa1, 0x06, 0x0b, 0xf8, 0xcd, 0x76, 0xb1, 0xfc, 0x52, 0x09, 0xf2, 0x09, 0xf8, 0xe5,
+	0xff, 0x08, 0x1f, 0xba, 0x00, 0x6e, 0x1d, 0x93, 0x60, 0x90, 0xed, 0xdb, 0xb0, 0x36, 0xf3, 0x18,
+	0xf5, 0x00, 0x32, 0xa3, 0xd4, 0xed, 0x34, 0x90, 0xb7, 0xfd, 0x8b, 0x0b, 0x37, 0x2c, 0xea, 0x79,
+	0x16, 0xc5, 0x82, 0x9d, 0xa8, 0x09, 0xfa, 0x3e, 0x54, 0x64, 0x3e, 0x48, 0x6d, 0x27, 0x2f, 0x7a,
+	0xe1, 0x14, 0x41, 0xe4, 0x4b, 0x68, 0xa4, 0xe1, 0xa8, 0x3f, 0x8c, 0x59, 0x12, 0xd9, 0x61, 0xbb,
+	0x35, 0x93, 0x31, 0xfb, 0x03, 0x7a, 0x08, 0x3f, 0xd5, 0x78, 0x33, 0x7c, 0xeb, 0xa9, 0x35, 0xc9,
+	0x43, 0x68, 0xca, 0x24, 0x3e, 0x61, 0x96, 0xcd, 0x43, 0xb6, 0x85, 0xbf, 0x0f, 0x88, 0xc5, 0xcc,
+	0xcd, 0x63, 0x58, 0xb9, 0x44, 0x3a, 0x3d, 0x72, 0x1b, 0x66, 0xe4, 0x6e, 0x5d, 0x1e, 0xb9, 0x0b,
+	0x69, 0xa7, 0x66, 0xef, 0x3d, 0xd8, 0x98, 0x89, 0x62, 0xb5, 0x09, 0x81, 0xca, 0x60, 0xac, 0x24,
+	0xd6, 0x73, 0x99, 0xe2, 0x77, 0x7b, 0x1f, 0xc8, 0x0c, 0xf6, 0xcd, 0x8b, 0xe3, 0x42, 0x6e, 0x0d,
+	0xfc, 0x27, 0x72, 0x3f, 0x6a, 0x41, 0x25, 0x0b, 0x53, 0x36, 0x33, 0xb4, 0x7e, 0xc0, 0x5b, 0x60,
+	0xe4, 0xd1, 0xa7, 0x50, 0x61, 0xef, 0x55, 0x3a, 0x83, 0xf8, 0xf1, 0x6f, 0xa4, 0xd2, 0x29, 0x7f,
+	0x05, 0x00, 0x00, 0xff, 0xff, 0xea, 0x06, 0x1a, 0xa9, 0x37, 0x0c, 0x00, 0x00,
 }
diff --git a/jsonpb/jsonpb_test_proto/test_objects.proto b/jsonpb/jsonpb_test_proto/test_objects.proto
index 0d2fc1f..36eb6e8 100644
--- a/jsonpb/jsonpb_test_proto/test_objects.proto
+++ b/jsonpb/jsonpb_test_proto/test_objects.proto
@@ -107,6 +107,7 @@
     int64 salary = 2;
     string Country = 3;
     string home_address = 4;
+    MsgWithRequired msg_with_required = 5;
   }
 }
 
@@ -145,3 +146,26 @@
   optional google.protobuf.StringValue str = 10;
   optional google.protobuf.BytesValue bytes = 11;
 }
+
+// Test messages for marshaling/unmarshaling required fields.
+message MsgWithRequired {
+  required string str = 1;
+}
+
+message MsgWithIndirectRequired {
+  optional MsgWithRequired subm = 1;
+  map<string, MsgWithRequired> map_field = 2;
+  repeated MsgWithRequired slice_field = 3;
+}
+
+message MsgWithRequiredBytes {
+  required bytes byts = 1;
+}
+
+message MsgWithRequiredWKT {
+  required google.protobuf.StringValue str = 1;
+}
+
+extend Real {
+  optional MsgWithRequired extm = 125;
+}
diff --git a/proto/Makefile b/proto/Makefile
deleted file mode 100644
index e2e0651..0000000
--- a/proto/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-# Go support for Protocol Buffers - Google's data interchange format
-#
-# Copyright 2010 The Go Authors.  All rights reserved.
-# https://github.com/golang/protobuf
-#
-# 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.
-
-install:
-	go install
-
-test: install generate-test-pbs
-	go test
-
-
-generate-test-pbs:
-	make install
-	make -C testdata
-	protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata,Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. proto3_proto/proto3.proto
-	make
diff --git a/proto/all_test.go b/proto/all_test.go
index 41451a4..361f72f 100644
--- a/proto/all_test.go
+++ b/proto/all_test.go
@@ -41,11 +41,12 @@
 	"reflect"
 	"runtime/debug"
 	"strings"
+	"sync"
 	"testing"
 	"time"
 
 	. "github.com/golang/protobuf/proto"
-	. "github.com/golang/protobuf/proto/testdata"
+	. "github.com/golang/protobuf/proto/test_proto"
 )
 
 var globalO *Buffer
@@ -114,6 +115,8 @@
 		pb.F_BytesDefaulted = Default_GoTest_F_BytesDefaulted
 		pb.F_Sint32Defaulted = Int32(Default_GoTest_F_Sint32Defaulted)
 		pb.F_Sint64Defaulted = Int64(Default_GoTest_F_Sint64Defaulted)
+		pb.F_Sfixed32Defaulted = Int32(Default_GoTest_F_Sfixed32Defaulted)
+		pb.F_Sfixed64Defaulted = Int64(Default_GoTest_F_Sfixed64Defaulted)
 	}
 
 	pb.Kind = GoTest_TIME.Enum()
@@ -131,135 +134,13 @@
 	pb.F_BytesRequired = []byte("bytes")
 	pb.F_Sint32Required = Int32(-32)
 	pb.F_Sint64Required = Int64(-64)
+	pb.F_Sfixed32Required = Int32(-32)
+	pb.F_Sfixed64Required = Int64(-64)
 	pb.Requiredgroup = initGoTest_RequiredGroup()
 
 	return pb
 }
 
-func fail(msg string, b *bytes.Buffer, s string, t *testing.T) {
-	data := b.Bytes()
-	ld := len(data)
-	ls := len(s) / 2
-
-	fmt.Printf("fail %s ld=%d ls=%d\n", msg, ld, ls)
-
-	// find the interesting spot - n
-	n := ls
-	if ld < ls {
-		n = ld
-	}
-	j := 0
-	for i := 0; i < n; i++ {
-		bs := hex(s[j])*16 + hex(s[j+1])
-		j += 2
-		if data[i] == bs {
-			continue
-		}
-		n = i
-		break
-	}
-	l := n - 10
-	if l < 0 {
-		l = 0
-	}
-	h := n + 10
-
-	// find the interesting spot - n
-	fmt.Printf("is[%d]:", l)
-	for i := l; i < h; i++ {
-		if i >= ld {
-			fmt.Printf(" --")
-			continue
-		}
-		fmt.Printf(" %.2x", data[i])
-	}
-	fmt.Printf("\n")
-
-	fmt.Printf("sb[%d]:", l)
-	for i := l; i < h; i++ {
-		if i >= ls {
-			fmt.Printf(" --")
-			continue
-		}
-		bs := hex(s[j])*16 + hex(s[j+1])
-		j += 2
-		fmt.Printf(" %.2x", bs)
-	}
-	fmt.Printf("\n")
-
-	t.Fail()
-
-	//	t.Errorf("%s: \ngood: %s\nbad: %x", msg, s, b.Bytes())
-	// Print the output in a partially-decoded format; can
-	// be helpful when updating the test.  It produces the output
-	// that is pasted, with minor edits, into the argument to verify().
-	//	data := b.Bytes()
-	//	nesting := 0
-	//	for b.Len() > 0 {
-	//		start := len(data) - b.Len()
-	//		var u uint64
-	//		u, err := DecodeVarint(b)
-	//		if err != nil {
-	//			fmt.Printf("decode error on varint:", err)
-	//			return
-	//		}
-	//		wire := u & 0x7
-	//		tag := u >> 3
-	//		switch wire {
-	//		case WireVarint:
-	//			v, err := DecodeVarint(b)
-	//			if err != nil {
-	//				fmt.Printf("decode error on varint:", err)
-	//				return
-	//			}
-	//			fmt.Printf("\t\t\"%x\"  // field %d, encoding %d, value %d\n",
-	//				data[start:len(data)-b.Len()], tag, wire, v)
-	//		case WireFixed32:
-	//			v, err := DecodeFixed32(b)
-	//			if err != nil {
-	//				fmt.Printf("decode error on fixed32:", err)
-	//				return
-	//			}
-	//			fmt.Printf("\t\t\"%x\"  // field %d, encoding %d, value %d\n",
-	//				data[start:len(data)-b.Len()], tag, wire, v)
-	//		case WireFixed64:
-	//			v, err := DecodeFixed64(b)
-	//			if err != nil {
-	//				fmt.Printf("decode error on fixed64:", err)
-	//				return
-	//			}
-	//			fmt.Printf("\t\t\"%x\"  // field %d, encoding %d, value %d\n",
-	//				data[start:len(data)-b.Len()], tag, wire, v)
-	//		case WireBytes:
-	//			nb, err := DecodeVarint(b)
-	//			if err != nil {
-	//				fmt.Printf("decode error on bytes:", err)
-	//				return
-	//			}
-	//			after_tag := len(data) - b.Len()
-	//			str := make([]byte, nb)
-	//			_, err = b.Read(str)
-	//			if err != nil {
-	//				fmt.Printf("decode error on bytes:", err)
-	//				return
-	//			}
-	//			fmt.Printf("\t\t\"%x\" \"%x\"  // field %d, encoding %d (FIELD)\n",
-	//				data[start:after_tag], str, tag, wire)
-	//		case WireStartGroup:
-	//			nesting++
-	//			fmt.Printf("\t\t\"%x\"\t\t// start group field %d level %d\n",
-	//				data[start:len(data)-b.Len()], tag, nesting)
-	//		case WireEndGroup:
-	//			fmt.Printf("\t\t\"%x\"\t\t// end group field %d level %d\n",
-	//				data[start:len(data)-b.Len()], tag, nesting)
-	//			nesting--
-	//		default:
-	//			fmt.Printf("unrecognized wire type %d\n", wire)
-	//			return
-	//		}
-	//	}
-}
-
 func hex(c uint8) uint8 {
 	if '0' <= c && c <= '9' {
 		return c - '0'
@@ -482,6 +363,48 @@
 	}
 }
 
+// Ensure that Buffer.Marshal uses O(N) memory for N messages
+func TestBufferMarshalAllocs(t *testing.T) {
+	value := &OtherMessage{Key: Int64(1)}
+	msg := &MyMessage{Count: Int32(1), Others: []*OtherMessage{value}}
+
+	reallocSize := func(t *testing.T, items int, prealloc int) (int64, int64) {
+		var b Buffer
+		b.SetBuf(make([]byte, 0, prealloc))
+
+		var allocSpace int64
+		prevCap := cap(b.Bytes())
+		for i := 0; i < items; i++ {
+			err := b.Marshal(msg)
+			if err != nil {
+				t.Errorf("Marshal err = %q", err)
+				break
+			}
+			if c := cap(b.Bytes()); prevCap != c {
+				allocSpace += int64(c)
+				prevCap = c
+			}
+		}
+		needSpace := int64(len(b.Bytes()))
+		return allocSpace, needSpace
+	}
+
+	for _, prealloc := range []int{0, 100, 10000} {
+		for _, items := range []int{1, 2, 5, 10, 20, 50, 100, 200, 500, 1000} {
+			runtimeSpace, need := reallocSize(t, items, prealloc)
+			totalSpace := int64(prealloc) + runtimeSpace
+
+			runtimeRatio := float64(runtimeSpace) / float64(need)
+			totalRatio := float64(totalSpace) / float64(need)
+
+			if totalRatio < 1 || runtimeRatio > 4 {
+				t.Errorf("needed %dB, allocated %dB total (ratio %.1f), allocated %dB at runtime (ratio %.1f)",
+					need, totalSpace, totalRatio, runtimeSpace, runtimeRatio)
+			}
+		}
+	}
+}
+
 // Simple tests for bytes
 func TestBytesPrimitives(t *testing.T) {
 	o := old()
@@ -519,7 +442,7 @@
 	err := o.Marshal(pb)
 	if err == nil {
 		t.Error("did not catch missing required fields")
-	} else if strings.Index(err.Error(), "Kind") < 0 {
+	} else if !strings.Contains(err.Error(), "Kind") {
 		t.Error("wrong error type:", err)
 	}
 }
@@ -612,7 +535,9 @@
 			"b404"+ // field 70, encoding 4, end group
 			"aa0605"+"6279746573"+ // field 101, encoding 2, string "bytes"
 			"b0063f"+ // field 102, encoding 0, 0x3f zigzag32
-			"b8067f") // field 103, encoding 0, 0x7f zigzag64
+			"b8067f"+ // field 103, encoding 0, 0x7f zigzag64
+			"c506e0ffffff"+ // field 104, encoding 5, -32 fixed32
+			"c906c0ffffffffffffff") // field 105, encoding 1, -64 fixed64
 }
 
 // All required fields set, defaults provided.
@@ -647,9 +572,13 @@
 			"aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
 			"b0063f"+ // field 102, encoding 0, 0x3f zigzag32
 			"b8067f"+ // field 103, encoding 0, 0x7f zigzag64
+			"c506e0ffffff"+ // field 104, encoding 5, -32 fixed32
+			"c906c0ffffffffffffff"+ // field 105, encoding 1, -64 fixed64
 			"8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
 			"90193f"+ // field 402, encoding 0, value 63
-			"98197f") // field 403, encoding 0, value 127
+			"98197f"+ // field 403, encoding 0, value 127
+			"a519e0ffffff"+ // field 404, encoding 5, -32 fixed32
+			"a919c0ffffffffffffff") // field 405, encoding 1, -64 fixed64
 
 }
 
@@ -669,6 +598,8 @@
 	pb.F_BytesDefaulted = []byte("Bignose")
 	pb.F_Sint32Defaulted = Int32(-32)
 	pb.F_Sint64Defaulted = Int64(-64)
+	pb.F_Sfixed32Defaulted = Int32(-32)
+	pb.F_Sfixed64Defaulted = Int64(-64)
 
 	overify(t, pb,
 		"0807"+ // field 1, encoding 0, value 7
@@ -699,9 +630,13 @@
 			"aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
 			"b0063f"+ // field 102, encoding 0, 0x3f zigzag32
 			"b8067f"+ // field 103, encoding 0, 0x7f zigzag64
+			"c506e0ffffff"+ // field 104, encoding 5, -32 fixed32
+			"c906c0ffffffffffffff"+ // field 105, encoding 1, -64 fixed64
 			"8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
 			"90193f"+ // field 402, encoding 0, value 63
-			"98197f") // field 403, encoding 0, value 127
+			"98197f"+ // field 403, encoding 0, value 127
+			"a519e0ffffff"+ // field 404, encoding 5, -32 fixed32
+			"a919c0ffffffffffffff") // field 405, encoding 1, -64 fixed64
 
 }
 
@@ -724,6 +659,8 @@
 	pb.F_BytesOptional = []byte("Bignose")
 	pb.F_Sint32Optional = Int32(-32)
 	pb.F_Sint64Optional = Int64(-64)
+	pb.F_Sfixed32Optional = Int32(-32)
+	pb.F_Sfixed64Optional = Int64(-64)
 	pb.Optionalgroup = initGoTest_OptionalGroup()
 
 	overify(t, pb,
@@ -771,12 +708,18 @@
 			"aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
 			"b0063f"+ // field 102, encoding 0, 0x3f zigzag32
 			"b8067f"+ // field 103, encoding 0, 0x7f zigzag64
+			"c506e0ffffff"+ // field 104, encoding 5, -32 fixed32
+			"c906c0ffffffffffffff"+ // field 105, encoding 1, -64 fixed64
 			"ea1207"+"4269676e6f7365"+ // field 301, encoding 2, string "Bignose"
 			"f0123f"+ // field 302, encoding 0, value 63
 			"f8127f"+ // field 303, encoding 0, value 127
+			"8513e0ffffff"+ // field 304, encoding 5, -32 fixed32
+			"8913c0ffffffffffffff"+ // field 305, encoding 1, -64 fixed64
 			"8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
 			"90193f"+ // field 402, encoding 0, value 63
-			"98197f") // field 403, encoding 0, value 127
+			"98197f"+ // field 403, encoding 0, value 127
+			"a519e0ffffff"+ // field 404, encoding 5, -32 fixed32
+			"a919c0ffffffffffffff") // field 405, encoding 1, -64 fixed64
 
 }
 
@@ -797,6 +740,8 @@
 	pb.F_BytesRepeated = [][]byte{[]byte("big"), []byte("nose")}
 	pb.F_Sint32Repeated = []int32{32, -32}
 	pb.F_Sint64Repeated = []int64{64, -64}
+	pb.F_Sfixed32Repeated = []int32{32, -32}
+	pb.F_Sfixed64Repeated = []int64{64, -64}
 	pb.Repeatedgroup = []*GoTest_RepeatedGroup{initGoTest_RepeatedGroup(), initGoTest_RepeatedGroup()}
 
 	overify(t, pb,
@@ -856,15 +801,23 @@
 			"aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
 			"b0063f"+ // field 102, encoding 0, 0x3f zigzag32
 			"b8067f"+ // field 103, encoding 0, 0x7f zigzag64
+			"c506e0ffffff"+ // field 104, encoding 5, -32 fixed32
+			"c906c0ffffffffffffff"+ // field 105, encoding 1, -64 fixed64
 			"ca0c03"+"626967"+ // field 201, encoding 2, string "big"
 			"ca0c04"+"6e6f7365"+ // field 201, encoding 2, string "nose"
 			"d00c40"+ // field 202, encoding 0, value 32
 			"d00c3f"+ // field 202, encoding 0, value -32
 			"d80c8001"+ // field 203, encoding 0, value 64
 			"d80c7f"+ // field 203, encoding 0, value -64
+			"e50c20000000"+ // field 204, encoding 5, 32 fixed32
+			"e50ce0ffffff"+ // field 204, encoding 5, -32 fixed32
+			"e90c4000000000000000"+ // field 205, encoding 1, 64 fixed64
+			"e90cc0ffffffffffffff"+ // field 205, encoding 1, -64 fixed64
 			"8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
 			"90193f"+ // field 402, encoding 0, value 63
-			"98197f") // field 403, encoding 0, value 127
+			"98197f"+ // field 403, encoding 0, value 127
+			"a519e0ffffff"+ // field 404, encoding 5, -32 fixed32
+			"a919c0ffffffffffffff") // field 405, encoding 1, -64 fixed64
 
 }
 
@@ -882,6 +835,8 @@
 	pb.F_DoubleRepeatedPacked = []float64{64., 65.}
 	pb.F_Sint32RepeatedPacked = []int32{32, -32}
 	pb.F_Sint64RepeatedPacked = []int64{64, -64}
+	pb.F_Sfixed32RepeatedPacked = []int32{32, -32}
+	pb.F_Sfixed64RepeatedPacked = []int64{64, -64}
 
 	overify(t, pb,
 		"0807"+ // field 1, encoding 0, value 7
@@ -917,10 +872,17 @@
 			"aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
 			"b0063f"+ // field 102, encoding 0, 0x3f zigzag32
 			"b8067f"+ // field 103, encoding 0, 0x7f zigzag64
+			"c506e0ffffff"+ // field 104, encoding 5, -32 fixed32
+			"c906c0ffffffffffffff"+ // field 105, encoding 1, -64 fixed64
 			"b21f02"+ // field 502, encoding 2, 2 bytes
 			"403f"+ // value 32, value -32
 			"ba1f03"+ // field 503, encoding 2, 3 bytes
-			"80017f") // value 64, value -64
+			"80017f"+ // value 64, value -64
+			"c21f08"+ // field 504, encoding 2, 8 bytes
+			"20000000e0ffffff"+ // value 32, value -32
+			"ca1f10"+ // field 505, encoding 2, 16 bytes
+			"4000000000000000c0ffffffffffffff") // value 64, value -64
+
 }
 
 // Test that we can encode empty bytes fields.
@@ -1167,13 +1129,10 @@
 		if pbd.Repeatedgroup[i] == nil { // TODO: more checking?
 			t.Error("pbd.Repeatedgroup bad")
 		}
-		var x uint64
-		x = uint64(pbd.F_Sint64Repeated[i])
-		if x != i {
+		if x := uint64(pbd.F_Sint64Repeated[i]); x != i {
 			t.Error("pbd.F_Sint64Repeated bad", x, i)
 		}
-		x = uint64(pbd.F_Sint32Repeated[i])
-		if x != i {
+		if x := uint64(pbd.F_Sint32Repeated[i]); x != i {
 			t.Error("pbd.F_Sint32Repeated bad", x, i)
 		}
 		s := fmt.Sprint(i)
@@ -1181,39 +1140,31 @@
 		if pbd.F_StringRepeated[i] != s {
 			t.Error("pbd.F_Sint32Repeated bad", pbd.F_StringRepeated[i], i)
 		}
-		x = uint64(pbd.F_DoubleRepeated[i])
-		if x != i {
+		if x := uint64(pbd.F_DoubleRepeated[i]); x != i {
 			t.Error("pbd.F_DoubleRepeated bad", x, i)
 		}
-		x = uint64(pbd.F_FloatRepeated[i])
-		if x != i {
+		if x := uint64(pbd.F_FloatRepeated[i]); x != i {
 			t.Error("pbd.F_FloatRepeated bad", x, i)
 		}
-		x = pbd.F_Uint64Repeated[i]
-		if x != i {
+		if x := pbd.F_Uint64Repeated[i]; x != i {
 			t.Error("pbd.F_Uint64Repeated bad", x, i)
 		}
-		x = uint64(pbd.F_Uint32Repeated[i])
-		if x != i {
+		if x := uint64(pbd.F_Uint32Repeated[i]); x != i {
 			t.Error("pbd.F_Uint32Repeated bad", x, i)
 		}
-		x = pbd.F_Fixed64Repeated[i]
-		if x != i {
+		if x := pbd.F_Fixed64Repeated[i]; x != i {
 			t.Error("pbd.F_Fixed64Repeated bad", x, i)
 		}
-		x = uint64(pbd.F_Fixed32Repeated[i])
-		if x != i {
+		if x := uint64(pbd.F_Fixed32Repeated[i]); x != i {
 			t.Error("pbd.F_Fixed32Repeated bad", x, i)
 		}
-		x = uint64(pbd.F_Int64Repeated[i])
-		if x != i {
+		if x := uint64(pbd.F_Int64Repeated[i]); x != i {
 			t.Error("pbd.F_Int64Repeated bad", x, i)
 		}
-		x = uint64(pbd.F_Int32Repeated[i])
-		if x != i {
+		if x := uint64(pbd.F_Int32Repeated[i]); x != i {
 			t.Error("pbd.F_Int32Repeated bad", x, i)
 		}
-		if pbd.F_BoolRepeated[i] != (i%2 == 0) {
+		if x := pbd.F_BoolRepeated[i]; x != (i%2 == 0) {
 			t.Error("pbd.F_BoolRepeated bad", x, i)
 		}
 		if pbd.RepeatedField[i] == nil { // TODO: more checking?
@@ -1222,21 +1173,25 @@
 	}
 }
 
-// Verify we give a useful message when decoding to the wrong structure type.
-func TestTypeMismatch(t *testing.T) {
-	pb1 := initGoTest(true)
+func TestBadWireTypeUnknown(t *testing.T) {
+	var b []byte
+	fmt.Sscanf("0a01780d00000000080b101612036161611521000000202c220362626225370000002203636363214200000000000000584d5a036464645900000000000056405d63000000", "%x", &b)
 
-	// Marshal
-	o := old()
-	o.Marshal(pb1)
+	m := new(MyMessage)
+	if err := Unmarshal(b, m); err != nil {
+		t.Errorf("unexpected Unmarshal error: %v", err)
+	}
 
-	// Now Unmarshal it to the wrong type.
-	pb2 := initGoTestField()
-	err := o.Unmarshal(pb2)
-	if err == nil {
-		t.Error("expected error, got no error")
-	} else if !strings.Contains(err.Error(), "bad wiretype") {
-		t.Error("expected bad wiretype error, got", err)
+	var unknown []byte
+	fmt.Sscanf("0a01780d0000000010161521000000202c2537000000214200000000000000584d5a036464645d63000000", "%x", &unknown)
+	if !bytes.Equal(m.XXX_unrecognized, unknown) {
+		t.Errorf("unknown bytes mismatch:\ngot  %x\nwant %x", m.XXX_unrecognized, unknown)
+	}
+	DiscardUnknown(m)
+
+	want := &MyMessage{Count: Int32(11), Name: String("aaa"), Pet: []string{"bbb", "ccc"}, Bigfloat: Float64(88)}
+	if !Equal(m, want) {
+		t.Errorf("message mismatch:\ngot  %v\nwant %v", m, want)
 	}
 }
 
@@ -1331,7 +1286,8 @@
 	err = Unmarshal(buf, pb)
 	if err == nil {
 		t.Error("unmarshal: expected error, got nil")
-	} else if _, ok := err.(*RequiredNotSetError); !ok || !strings.Contains(err.Error(), "{Unknown}") {
+	} else if _, ok := err.(*RequiredNotSetError); !ok || !strings.Contains(err.Error(), "Type") && !strings.Contains(err.Error(), "{Unknown}") {
+		// TODO: remove unknown cases once we commit to the new unmarshaler.
 		t.Errorf("unmarshal: bad error type: %v", err)
 	}
 }
@@ -1348,7 +1304,7 @@
 	buf := []byte{11, 12}
 	if err := Unmarshal(buf, pb); err == nil {
 		t.Error("unmarshal: expected error, got nil")
-	} else if _, ok := err.(*RequiredNotSetError); !ok || !strings.Contains(err.Error(), "Group.{Unknown}") {
+	} else if _, ok := err.(*RequiredNotSetError); !ok || !strings.Contains(err.Error(), "Group.Field") && !strings.Contains(err.Error(), "Group.{Unknown}") {
 		t.Errorf("unmarshal: bad error type: %v", err)
 	}
 }
@@ -1385,18 +1341,7 @@
 func (*NNIMessage) String() string { return "" }
 func (*NNIMessage) ProtoMessage()  {}
 
-// A type that implements the Marshaler interface and is nillable.
-type nillableMessage struct {
-	x uint64
-}
-
-func (nm *nillableMessage) Marshal() ([]byte, error) {
-	return EncodeVarint(nm.x), nil
-}
-
-type NMMessage struct {
-	nm *nillableMessage
-}
+type NMMessage struct{}
 
 func (*NMMessage) Reset()         {}
 func (*NMMessage) String() string { return "" }
@@ -1595,6 +1540,14 @@
 	}
 }
 
+func TestBytesWithInvalidLengthInGroup(t *testing.T) {
+	// Overflowing a 64-bit length should not be allowed.
+	b := []byte{0xbb, 0x30, 0xb2, 0x30, 0xb0, 0xb2, 0x83, 0xf1, 0xb0, 0xb2, 0xef, 0xbf, 0xbd, 0x01}
+	if err := Unmarshal(b, new(MyMessage)); err == nil {
+		t.Fatalf("Overflowed uint64 length without error")
+	}
+}
+
 func TestUnmarshalFuzz(t *testing.T) {
 	const N = 1000
 	seed := time.Now().UnixNano()
@@ -1668,6 +1621,28 @@
 	}
 }
 
+func TestExtensionMapFieldMarshalDeterministic(t *testing.T) {
+	m := &MyMessage{Count: Int(123)}
+	if err := SetExtension(m, E_Ext_More, &Ext{MapField: map[int32]int32{1: 1, 2: 2, 3: 3, 4: 4}}); err != nil {
+		t.Fatalf("SetExtension: %v", err)
+	}
+	marshal := func(m Message) []byte {
+		var b Buffer
+		b.SetDeterministic(true)
+		if err := b.Marshal(m); err != nil {
+			t.Fatalf("Marshal failed: %v", err)
+		}
+		return b.Bytes()
+	}
+
+	want := marshal(m)
+	for i := 0; i < 100; i++ {
+		if got := marshal(m); !bytes.Equal(got, want) {
+			t.Errorf("Marshal produced inconsistent output with determinism enabled (pass %d).\n got %v\nwant %v", i, got, want)
+		}
+	}
+}
+
 // Many extensions, because small maps might not iterate differently on each iteration.
 var exts = []*ExtensionDesc{
 	E_X201,
@@ -1802,6 +1777,43 @@
 	}
 }
 
+func TestUnmarshalMergesGroups(t *testing.T) {
+	// If a nested group occurs twice in the input,
+	// the fields should be merged when decoding.
+	a := &GroupNew{
+		G: &GroupNew_G{
+			X: Int32(7),
+			Y: Int32(8),
+		},
+	}
+	aData, err := Marshal(a)
+	if err != nil {
+		t.Fatalf("Marshal(a): %v", err)
+	}
+	b := &GroupNew{
+		G: &GroupNew_G{
+			X: Int32(9),
+		},
+	}
+	bData, err := Marshal(b)
+	if err != nil {
+		t.Fatalf("Marshal(b): %v", err)
+	}
+	want := &GroupNew{
+		G: &GroupNew_G{
+			X: Int32(9),
+			Y: Int32(8),
+		},
+	}
+	got := new(GroupNew)
+	if err := Unmarshal(append(aData, bData...), got); err != nil {
+		t.Fatalf("Unmarshal: %v", err)
+	}
+	if !Equal(got, want) {
+		t.Errorf("\n got %v\nwant %v", got, want)
+	}
+}
+
 func TestEncodingSizes(t *testing.T) {
 	tests := []struct {
 		m Message
@@ -1845,7 +1857,9 @@
 		"b404" + // field 70, encoding 4, end group
 		"aa0605" + "6279746573" + // field 101, encoding 2, string "bytes"
 		"b0063f" + // field 102, encoding 0, 0x3f zigzag32
-		"b8067f" // field 103, encoding 0, 0x7f zigzag64
+		"b8067f" + // field 103, encoding 0, 0x7f zigzag64
+		"c506e0ffffff" + // field 104, encoding 5, -32 fixed32
+		"c906c0ffffffffffffff" // field 105, encoding 1, -64 fixed64
 
 	o := old()
 	bytes, err := Marshal(pb)
@@ -1854,7 +1868,7 @@
 		o.DebugPrint("", bytes)
 		t.Fatalf("expected = %s", expected)
 	}
-	if strings.Index(err.Error(), "RequiredField.Label") < 0 {
+	if !strings.Contains(err.Error(), "RequiredField.Label") {
 		t.Errorf("marshal-1 wrong err msg: %v", err)
 	}
 	if !equal(bytes, expected, t) {
@@ -1870,7 +1884,7 @@
 		o.DebugPrint("", bytes)
 		t.Fatalf("string = %s", expected)
 	}
-	if strings.Index(err.Error(), "RequiredField.{Unknown}") < 0 {
+	if !strings.Contains(err.Error(), "RequiredField.Label") && !strings.Contains(err.Error(), "RequiredField.{Unknown}") {
 		t.Errorf("unmarshal wrong err msg: %v", err)
 	}
 	bytes, err = Marshal(pbd)
@@ -1879,7 +1893,7 @@
 		o.DebugPrint("", bytes)
 		t.Fatalf("string = %s", expected)
 	}
-	if strings.Index(err.Error(), "RequiredField.Label") < 0 {
+	if !strings.Contains(err.Error(), "RequiredField.Label") {
 		t.Errorf("marshal-2 wrong err msg: %v", err)
 	}
 	if !equal(bytes, expected, t) {
@@ -1888,6 +1902,25 @@
 	}
 }
 
+func TestRequiredNotSetErrorWithBadWireTypes(t *testing.T) {
+	// Required field expects a varint, and properly found a varint.
+	if err := Unmarshal([]byte{0x08, 0x00}, new(GoEnum)); err != nil {
+		t.Errorf("Unmarshal = %v, want nil", err)
+	}
+	// Required field expects a varint, but found a fixed32 instead.
+	if err := Unmarshal([]byte{0x0d, 0x00, 0x00, 0x00, 0x00}, new(GoEnum)); err == nil {
+		t.Errorf("Unmarshal = nil, want RequiredNotSetError")
+	}
+	// Required field expects a varint, and found both a varint and fixed32 (ignored).
+	m := new(GoEnum)
+	if err := Unmarshal([]byte{0x08, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00}, m); err != nil {
+		t.Errorf("Unmarshal = %v, want nil", err)
+	}
+	if !bytes.Equal(m.XXX_unrecognized, []byte{0x0d, 0x00, 0x00, 0x00, 0x00}) {
+		t.Errorf("expected fixed32 to appear as unknown bytes: %x", m.XXX_unrecognized)
+	}
+}
+
 func fuzzUnmarshal(t *testing.T, data []byte) {
 	defer func() {
 		if e := recover(); e != nil {
@@ -1946,6 +1979,32 @@
 	(new(Buffer)).DebugPrint("Dump of b", b)
 }
 
+func TestMapFieldDeterministicMarshal(t *testing.T) {
+	m := &MessageWithMap{
+		NameMapping: map[int32]string{
+			1: "Rob",
+			4: "Ian",
+			8: "Dave",
+		},
+	}
+
+	marshal := func(m Message) []byte {
+		var b Buffer
+		b.SetDeterministic(true)
+		if err := b.Marshal(m); err != nil {
+			t.Fatalf("Marshal failed: %v", err)
+		}
+		return b.Bytes()
+	}
+
+	want := marshal(m)
+	for i := 0; i < 10; i++ {
+		if got := marshal(m); !bytes.Equal(got, want) {
+			t.Errorf("Marshal produced inconsistent output with determinism enabled (pass %d).\n got %v\nwant %v", i, got, want)
+		}
+	}
+}
+
 func TestMapFieldRoundTrips(t *testing.T) {
 	m := &MessageWithMap{
 		NameMapping: map[int32]string{
@@ -1954,7 +2013,7 @@
 			8: "Dave",
 		},
 		MsgMapping: map[int64]*FloatingPoint{
-			0x7001: &FloatingPoint{F: Float64(2.0)},
+			0x7001: {F: Float64(2.0)},
 		},
 		ByteMapping: map[bool][]byte{
 			false: []byte("that's not right!"),
@@ -1970,14 +2029,8 @@
 	if err := Unmarshal(b, m2); err != nil {
 		t.Fatalf("Unmarshal: %v", err)
 	}
-	for _, pair := range [][2]interface{}{
-		{m.NameMapping, m2.NameMapping},
-		{m.MsgMapping, m2.MsgMapping},
-		{m.ByteMapping, m2.ByteMapping},
-	} {
-		if !reflect.DeepEqual(pair[0], pair[1]) {
-			t.Errorf("Map did not survive a round trip.\ninitial: %v\n  final: %v", pair[0], pair[1])
-		}
+	if !Equal(m, m2) {
+		t.Errorf("Map did not survive a round trip.\ninitial: %v\n  final: %v", m, m2)
 	}
 }
 
@@ -2005,7 +2058,7 @@
 func TestMapFieldWithNilBytes(t *testing.T) {
 	m1 := &MessageWithMap{
 		ByteMapping: map[bool][]byte{
-			false: []byte{},
+			false: {},
 			true:  nil,
 		},
 	}
@@ -2119,6 +2172,22 @@
 	}
 }
 
+func TestOneofNilBytes(t *testing.T) {
+	// A oneof with nil byte slice should marshal to tag + 0 (size), with no error.
+	m := &Communique{Union: &Communique_Data{Data: nil}}
+	b, err := Marshal(m)
+	if err != nil {
+		t.Fatalf("Marshal failed: %v", err)
+	}
+	want := []byte{
+		7<<3 | 2, // tag 7, wire type 2
+		0,        // size
+	}
+	if !bytes.Equal(b, want) {
+		t.Errorf("Wrong result of Marshal: got %x, want %x", b, want)
+	}
+}
+
 func TestInefficientPackedBool(t *testing.T) {
 	// https://github.com/golang/protobuf/issues/76
 	inp := []byte{
@@ -2132,6 +2201,69 @@
 	}
 }
 
+// Make sure pure-reflect-based implementation handles
+// []int32-[]enum conversion correctly.
+func TestRepeatedEnum2(t *testing.T) {
+	pb := &RepeatedEnum{
+		Color: []RepeatedEnum_Color{RepeatedEnum_RED},
+	}
+	b, err := Marshal(pb)
+	if err != nil {
+		t.Fatalf("Marshal failed: %v", err)
+	}
+	x := new(RepeatedEnum)
+	err = Unmarshal(b, x)
+	if err != nil {
+		t.Fatalf("Unmarshal failed: %v", err)
+	}
+	if !Equal(pb, x) {
+		t.Errorf("Incorrect result: want: %v got: %v", pb, x)
+	}
+}
+
+// TestConcurrentMarshal makes sure that it is safe to marshal
+// same message in multiple goroutines concurrently.
+func TestConcurrentMarshal(t *testing.T) {
+	pb := initGoTest(true)
+	const N = 100
+	b := make([][]byte, N)
+
+	var wg sync.WaitGroup
+	for i := 0; i < N; i++ {
+		wg.Add(1)
+		go func(i int) {
+			defer wg.Done()
+			var err error
+			b[i], err = Marshal(pb)
+			if err != nil {
+				t.Errorf("marshal error: %v", err)
+			}
+		}(i)
+	}
+
+	wg.Wait()
+	for i := 1; i < N; i++ {
+		if !bytes.Equal(b[0], b[i]) {
+			t.Errorf("concurrent marshal result not same: b[0] = %v, b[%d] = %v", b[0], i, b[i])
+		}
+	}
+}
+
+func TestInvalidUTF8(t *testing.T) {
+	const wire = "\x12\x04\xde\xea\xca\xfe"
+
+	var m GoTest
+	if err := Unmarshal([]byte(wire), &m); err == nil {
+		t.Errorf("Unmarshal error: got nil, want non-nil")
+	}
+
+	m.Reset()
+	m.Table = String(wire[2:])
+	if _, err := Marshal(&m); err == nil {
+		t.Errorf("Marshal error: got nil, want non-nil")
+	}
+}
+
 // Benchmarks
 
 func testMsg() *GoTest {
diff --git a/proto/any_test.go b/proto/any_test.go
index 1a3c22e..56fc97c 100644
--- a/proto/any_test.go
+++ b/proto/any_test.go
@@ -38,7 +38,7 @@
 	"github.com/golang/protobuf/proto"
 
 	pb "github.com/golang/protobuf/proto/proto3_proto"
-	testpb "github.com/golang/protobuf/proto/testdata"
+	testpb "github.com/golang/protobuf/proto/test_proto"
 	anypb "github.com/golang/protobuf/ptypes/any"
 )
 
@@ -166,33 +166,33 @@
 name: "David"
 result_count: 47
 anything: <
-  [type.googleapis.com/testdata.MyMessage]: <
+  [type.googleapis.com/test_proto.MyMessage]: <
     count: 47
     name: "David"
-    [testdata.Ext.more]: <
+    [test_proto.Ext.more]: <
       data: "foo"
     >
-    [testdata.Ext.text]: "bar"
+    [test_proto.Ext.text]: "bar"
   >
 >
 many_things: <
-  [type.googleapis.com/testdata.MyMessage]: <
+  [type.googleapis.com/test_proto.MyMessage]: <
     count: 42
     bikeshed: GREEN
     rep_bytes: "roboto"
-    [testdata.Ext.more]: <
+    [test_proto.Ext.more]: <
       data: "baz"
     >
   >
 >
 many_things: <
-  [type.googleapis.com/testdata.MyMessage]: <
+  [type.googleapis.com/test_proto.MyMessage]: <
     count: 47
     name: "David"
-    [testdata.Ext.more]: <
+    [test_proto.Ext.more]: <
       data: "foo"
     >
-    [testdata.Ext.text]: "bar"
+    [test_proto.Ext.text]: "bar"
   >
 >
 `
diff --git a/proto/clone.go b/proto/clone.go
index e392575..3cd3249 100644
--- a/proto/clone.go
+++ b/proto/clone.go
@@ -35,22 +35,39 @@
 package proto
 
 import (
+	"fmt"
 	"log"
 	"reflect"
 	"strings"
 )
 
 // Clone returns a deep copy of a protocol buffer.
-func Clone(pb Message) Message {
-	in := reflect.ValueOf(pb)
+func Clone(src Message) Message {
+	in := reflect.ValueOf(src)
 	if in.IsNil() {
-		return pb
+		return src
 	}
-
 	out := reflect.New(in.Type().Elem())
-	// out is empty so a merge is a deep copy.
-	mergeStruct(out.Elem(), in.Elem())
-	return out.Interface().(Message)
+	dst := out.Interface().(Message)
+	Merge(dst, src)
+	return dst
+}
+
+// Merger is the interface representing objects that can merge messages of the same type.
+type Merger interface {
+	// Merge merges src into this message.
+	// Required and optional fields that are set in src will be set to that value in dst.
+	// Elements of repeated fields will be appended.
+	//
+	// Merge may panic if called with a different argument type than the receiver.
+	Merge(src Message)
+}
+
+// generatedMerger is the custom merge method that generated protos will have.
+// We must add this method since a generate Merge method will conflict with
+// many existing protos that have a Merge data field already defined.
+type generatedMerger interface {
+	XXX_Merge(src Message)
 }
 
 // Merge merges src into dst.
@@ -58,17 +75,24 @@
 // Elements of repeated fields will be appended.
 // Merge panics if src and dst are not the same type, or if dst is nil.
 func Merge(dst, src Message) {
+	if m, ok := dst.(Merger); ok {
+		m.Merge(src)
+		return
+	}
+
 	in := reflect.ValueOf(src)
 	out := reflect.ValueOf(dst)
 	if out.IsNil() {
 		panic("proto: nil destination")
 	}
 	if in.Type() != out.Type() {
-		// Explicit test prior to mergeStruct so that mistyped nils will fail
-		panic("proto: type mismatch")
+		panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src))
 	}
 	if in.IsNil() {
-		// Merging nil into non-nil is a quiet no-op
+		return // Merge from nil src is a noop
+	}
+	if m, ok := dst.(generatedMerger); ok {
+		m.XXX_Merge(src)
 		return
 	}
 	mergeStruct(out.Elem(), in.Elem())
@@ -84,7 +108,7 @@
 		mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
 	}
 
-	if emIn, ok := extendable(in.Addr().Interface()); ok {
+	if emIn, err := extendable(in.Addr().Interface()); err == nil {
 		emOut, _ := extendable(out.Addr().Interface())
 		mIn, muIn := emIn.extensionsRead()
 		if mIn != nil {
diff --git a/proto/clone_test.go b/proto/clone_test.go
index f607ff4..0d3b127 100644
--- a/proto/clone_test.go
+++ b/proto/clone_test.go
@@ -37,7 +37,7 @@
 	"github.com/golang/protobuf/proto"
 
 	proto3pb "github.com/golang/protobuf/proto/proto3_proto"
-	pb "github.com/golang/protobuf/proto/testdata"
+	pb "github.com/golang/protobuf/proto/test_proto"
 )
 
 var cloneTestMessage = &pb.MyMessage{
@@ -72,7 +72,7 @@
 func TestClone(t *testing.T) {
 	m := proto.Clone(cloneTestMessage).(*pb.MyMessage)
 	if !proto.Equal(m, cloneTestMessage) {
-		t.Errorf("Clone(%v) = %v", cloneTestMessage, m)
+		t.Fatalf("Clone(%v) = %v", cloneTestMessage, m)
 	}
 
 	// Verify it was a deep copy.
@@ -244,27 +244,45 @@
 			Data:       []byte("texas!"),
 		},
 	},
-	// Oneof fields should merge by assignment.
-	{
-		src: &pb.Communique{
-			Union: &pb.Communique_Number{41},
-		},
-		dst: &pb.Communique{
-			Union: &pb.Communique_Name{"Bobby Tables"},
-		},
-		want: &pb.Communique{
-			Union: &pb.Communique_Number{41},
-		},
+	{ // Oneof fields should merge by assignment.
+		src:  &pb.Communique{Union: &pb.Communique_Number{41}},
+		dst:  &pb.Communique{Union: &pb.Communique_Name{"Bobby Tables"}},
+		want: &pb.Communique{Union: &pb.Communique_Number{41}},
 	},
-	// Oneof nil is the same as not set.
+	{ // Oneof nil is the same as not set.
+		src:  &pb.Communique{},
+		dst:  &pb.Communique{Union: &pb.Communique_Name{"Bobby Tables"}},
+		want: &pb.Communique{Union: &pb.Communique_Name{"Bobby Tables"}},
+	},
 	{
-		src: &pb.Communique{},
-		dst: &pb.Communique{
-			Union: &pb.Communique_Name{"Bobby Tables"},
-		},
-		want: &pb.Communique{
-			Union: &pb.Communique_Name{"Bobby Tables"},
-		},
+		src:  &pb.Communique{Union: &pb.Communique_Number{1337}},
+		dst:  &pb.Communique{},
+		want: &pb.Communique{Union: &pb.Communique_Number{1337}},
+	},
+	{
+		src:  &pb.Communique{Union: &pb.Communique_Col{pb.MyMessage_RED}},
+		dst:  &pb.Communique{},
+		want: &pb.Communique{Union: &pb.Communique_Col{pb.MyMessage_RED}},
+	},
+	{
+		src:  &pb.Communique{Union: &pb.Communique_Data{[]byte("hello")}},
+		dst:  &pb.Communique{},
+		want: &pb.Communique{Union: &pb.Communique_Data{[]byte("hello")}},
+	},
+	{
+		src:  &pb.Communique{Union: &pb.Communique_Msg{&pb.Strings{BytesField: []byte{1, 2, 3}}}},
+		dst:  &pb.Communique{},
+		want: &pb.Communique{Union: &pb.Communique_Msg{&pb.Strings{BytesField: []byte{1, 2, 3}}}},
+	},
+	{
+		src:  &pb.Communique{Union: &pb.Communique_Msg{}},
+		dst:  &pb.Communique{},
+		want: &pb.Communique{Union: &pb.Communique_Msg{}},
+	},
+	{
+		src:  &pb.Communique{Union: &pb.Communique_Msg{&pb.Strings{StringField: proto.String("123")}}},
+		dst:  &pb.Communique{Union: &pb.Communique_Msg{&pb.Strings{BytesField: []byte{1, 2, 3}}}},
+		want: &pb.Communique{Union: &pb.Communique_Msg{&pb.Strings{StringField: proto.String("123"), BytesField: []byte{1, 2, 3}}}},
 	},
 	{
 		src: &proto3pb.Message{
@@ -287,14 +305,86 @@
 			},
 		},
 	},
+	{
+		src: &pb.GoTest{
+			F_BoolRepeated:   []bool{},
+			F_Int32Repeated:  []int32{},
+			F_Int64Repeated:  []int64{},
+			F_Uint32Repeated: []uint32{},
+			F_Uint64Repeated: []uint64{},
+			F_FloatRepeated:  []float32{},
+			F_DoubleRepeated: []float64{},
+			F_StringRepeated: []string{},
+			F_BytesRepeated:  [][]byte{},
+		},
+		dst: &pb.GoTest{},
+		want: &pb.GoTest{
+			F_BoolRepeated:   []bool{},
+			F_Int32Repeated:  []int32{},
+			F_Int64Repeated:  []int64{},
+			F_Uint32Repeated: []uint32{},
+			F_Uint64Repeated: []uint64{},
+			F_FloatRepeated:  []float32{},
+			F_DoubleRepeated: []float64{},
+			F_StringRepeated: []string{},
+			F_BytesRepeated:  [][]byte{},
+		},
+	},
+	{
+		src: &pb.GoTest{},
+		dst: &pb.GoTest{
+			F_BoolRepeated:   []bool{},
+			F_Int32Repeated:  []int32{},
+			F_Int64Repeated:  []int64{},
+			F_Uint32Repeated: []uint32{},
+			F_Uint64Repeated: []uint64{},
+			F_FloatRepeated:  []float32{},
+			F_DoubleRepeated: []float64{},
+			F_StringRepeated: []string{},
+			F_BytesRepeated:  [][]byte{},
+		},
+		want: &pb.GoTest{
+			F_BoolRepeated:   []bool{},
+			F_Int32Repeated:  []int32{},
+			F_Int64Repeated:  []int64{},
+			F_Uint32Repeated: []uint32{},
+			F_Uint64Repeated: []uint64{},
+			F_FloatRepeated:  []float32{},
+			F_DoubleRepeated: []float64{},
+			F_StringRepeated: []string{},
+			F_BytesRepeated:  [][]byte{},
+		},
+	},
+	{
+		src: &pb.GoTest{
+			F_BytesRepeated: [][]byte{nil, []byte{}, []byte{0}},
+		},
+		dst: &pb.GoTest{},
+		want: &pb.GoTest{
+			F_BytesRepeated: [][]byte{nil, []byte{}, []byte{0}},
+		},
+	},
+	{
+		src: &pb.MyMessage{
+			Others: []*pb.OtherMessage{},
+		},
+		dst: &pb.MyMessage{},
+		want: &pb.MyMessage{
+			Others: []*pb.OtherMessage{},
+		},
+	},
 }
 
 func TestMerge(t *testing.T) {
 	for _, m := range mergeTests {
 		got := proto.Clone(m.dst)
+		if !proto.Equal(got, m.dst) {
+			t.Errorf("Clone()\ngot  %v\nwant %v", got, m.dst)
+			continue
+		}
 		proto.Merge(got, m.src)
 		if !proto.Equal(got, m.want) {
-			t.Errorf("Merge(%v, %v)\n got %v\nwant %v\n", m.dst, m.src, got, m.want)
+			t.Errorf("Merge(%v, %v)\ngot  %v\nwant %v", m.dst, m.src, got, m.want)
 		}
 	}
 }
diff --git a/proto/decode.go b/proto/decode.go
index aa20729..d9aa3c4 100644
--- a/proto/decode.go
+++ b/proto/decode.go
@@ -39,8 +39,6 @@
 	"errors"
 	"fmt"
 	"io"
-	"os"
-	"reflect"
 )
 
 // errOverflow is returned when an integer is too large to be represented.
@@ -50,10 +48,6 @@
 // wire type is encountered. It does not get returned to user code.
 var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")
 
-// The fundamental decoders that interpret bytes on the wire.
-// Those that take integer types all return uint64 and are
-// therefore of type valueDecoder.
-
 // DecodeVarint reads a varint-encoded integer from the slice.
 // It returns the integer and the number of bytes consumed, or
 // zero if there is not enough.
@@ -267,9 +261,6 @@
 	return
 }
 
-// These are not ValueDecoders: they produce an array of bytes or a string.
-// bytes, embedded messages
-
 // DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
 // This is the format used for the bytes protocol buffer
 // type and for embedded messages.
@@ -311,81 +302,29 @@
 	return string(buf), nil
 }
 
-// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
-// If the protocol buffer has extensions, and the field matches, add it as an extension.
-// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
-func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error {
-	oi := o.index
-
-	err := o.skip(t, tag, wire)
-	if err != nil {
-		return err
-	}
-
-	if !unrecField.IsValid() {
-		return nil
-	}
-
-	ptr := structPointer_Bytes(base, unrecField)
-
-	// Add the skipped field to struct field
-	obuf := o.buf
-
-	o.buf = *ptr
-	o.EncodeVarint(uint64(tag<<3 | wire))
-	*ptr = append(o.buf, obuf[oi:o.index]...)
-
-	o.buf = obuf
-
-	return nil
-}
-
-// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
-func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
-
-	var u uint64
-	var err error
-
-	switch wire {
-	case WireVarint:
-		_, err = o.DecodeVarint()
-	case WireFixed64:
-		_, err = o.DecodeFixed64()
-	case WireBytes:
-		_, err = o.DecodeRawBytes(false)
-	case WireFixed32:
-		_, err = o.DecodeFixed32()
-	case WireStartGroup:
-		for {
-			u, err = o.DecodeVarint()
-			if err != nil {
-				break
-			}
-			fwire := int(u & 0x7)
-			if fwire == WireEndGroup {
-				break
-			}
-			ftag := int(u >> 3)
-			err = o.skip(t, ftag, fwire)
-			if err != nil {
-				break
-			}
-		}
-	default:
-		err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
-	}
-	return err
-}
-
 // Unmarshaler is the interface representing objects that can
-// unmarshal themselves.  The method should reset the receiver before
-// decoding starts.  The argument points to data that may be
+// unmarshal themselves.  The argument points to data that may be
 // overwritten, so implementations should not keep references to the
 // buffer.
+// Unmarshal implementations should not clear the receiver.
+// Any unmarshaled data should be merged into the receiver.
+// Callers of Unmarshal that do not want to retain existing data
+// should Reset the receiver before calling Unmarshal.
 type Unmarshaler interface {
 	Unmarshal([]byte) error
 }
 
+// newUnmarshaler is the interface representing objects that can
+// unmarshal themselves. The semantics are identical to Unmarshaler.
+//
+// This exists to support protoc-gen-go generated messages.
+// The proto package will stop type-asserting to this interface in the future.
+//
+// DO NOT DEPEND ON THIS.
+type newUnmarshaler interface {
+	XXX_Unmarshal([]byte) error
+}
+
 // Unmarshal parses the protocol buffer representation in buf and places the
 // decoded result in pb.  If the struct underlying pb does not match
 // the data in buf, the results can be unpredictable.
@@ -395,7 +334,13 @@
 // to preserve and append to existing data.
 func Unmarshal(buf []byte, pb Message) error {
 	pb.Reset()
-	return UnmarshalMerge(buf, pb)
+	if u, ok := pb.(newUnmarshaler); ok {
+		return u.XXX_Unmarshal(buf)
+	}
+	if u, ok := pb.(Unmarshaler); ok {
+		return u.Unmarshal(buf)
+	}
+	return NewBuffer(buf).Unmarshal(pb)
 }
 
 // UnmarshalMerge parses the protocol buffer representation in buf and
@@ -405,8 +350,16 @@
 // UnmarshalMerge merges into existing data in pb.
 // Most code should use Unmarshal instead.
 func UnmarshalMerge(buf []byte, pb Message) error {
-	// If the object can unmarshal itself, let it.
+	if u, ok := pb.(newUnmarshaler); ok {
+		return u.XXX_Unmarshal(buf)
+	}
 	if u, ok := pb.(Unmarshaler); ok {
+		// NOTE: The history of proto have unfortunately been inconsistent
+		// whether Unmarshaler should or should not implicitly clear itself.
+		// Some implementations do, most do not.
+		// Thus, calling this here may or may not do what people want.
+		//
+		// See https://github.com/golang/protobuf/issues/424
 		return u.Unmarshal(buf)
 	}
 	return NewBuffer(buf).Unmarshal(pb)
@@ -422,12 +375,17 @@
 }
 
 // DecodeGroup reads a tag-delimited group from the Buffer.
+// StartGroup tag is already consumed. This function consumes
+// EndGroup tag.
 func (p *Buffer) DecodeGroup(pb Message) error {
-	typ, base, err := getbase(pb)
-	if err != nil {
-		return err
+	b := p.buf[p.index:]
+	x, y := findEndGroup(b)
+	if x < 0 {
+		return io.ErrUnexpectedEOF
 	}
-	return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base)
+	err := Unmarshal(b[:x], pb)
+	p.index += y
+	return err
 }
 
 // Unmarshal parses the protocol buffer representation in the
@@ -438,533 +396,33 @@
 // Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal.
 func (p *Buffer) Unmarshal(pb Message) error {
 	// If the object can unmarshal itself, let it.
+	if u, ok := pb.(newUnmarshaler); ok {
+		err := u.XXX_Unmarshal(p.buf[p.index:])
+		p.index = len(p.buf)
+		return err
+	}
 	if u, ok := pb.(Unmarshaler); ok {
+		// NOTE: The history of proto have unfortunately been inconsistent
+		// whether Unmarshaler should or should not implicitly clear itself.
+		// Some implementations do, most do not.
+		// Thus, calling this here may or may not do what people want.
+		//
+		// See https://github.com/golang/protobuf/issues/424
 		err := u.Unmarshal(p.buf[p.index:])
 		p.index = len(p.buf)
 		return err
 	}
 
-	typ, base, err := getbase(pb)
-	if err != nil {
-		return err
-	}
-
-	err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
-
-	if collectStats {
-		stats.Decode++
-	}
-
-	return err
-}
-
-// unmarshalType does the work of unmarshaling a structure.
-func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error {
-	var state errorState
-	required, reqFields := prop.reqCount, uint64(0)
-
-	var err error
-	for err == nil && o.index < len(o.buf) {
-		oi := o.index
-		var u uint64
-		u, err = o.DecodeVarint()
-		if err != nil {
-			break
-		}
-		wire := int(u & 0x7)
-		if wire == WireEndGroup {
-			if is_group {
-				if required > 0 {
-					// Not enough information to determine the exact field.
-					// (See below.)
-					return &RequiredNotSetError{"{Unknown}"}
-				}
-				return nil // input is satisfied
-			}
-			return fmt.Errorf("proto: %s: wiretype end group for non-group", st)
-		}
-		tag := int(u >> 3)
-		if tag <= 0 {
-			return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire)
-		}
-		fieldnum, ok := prop.decoderTags.get(tag)
-		if !ok {
-			// Maybe it's an extension?
-			if prop.extendable {
-				if e, _ := extendable(structPointer_Interface(base, st)); isExtensionField(e, int32(tag)) {
-					if err = o.skip(st, tag, wire); err == nil {
-						extmap := e.extensionsWrite()
-						ext := extmap[int32(tag)] // may be missing
-						ext.enc = append(ext.enc, o.buf[oi:o.index]...)
-						extmap[int32(tag)] = ext
-					}
-					continue
-				}
-			}
-			// Maybe it's a oneof?
-			if prop.oneofUnmarshaler != nil {
-				m := structPointer_Interface(base, st).(Message)
-				// First return value indicates whether tag is a oneof field.
-				ok, err = prop.oneofUnmarshaler(m, tag, wire, o)
-				if err == ErrInternalBadWireType {
-					// Map the error to something more descriptive.
-					// Do the formatting here to save generated code space.
-					err = fmt.Errorf("bad wiretype for oneof field in %T", m)
-				}
-				if ok {
-					continue
-				}
-			}
-			err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
-			continue
-		}
-		p := prop.Prop[fieldnum]
-
-		if p.dec == nil {
-			fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
-			continue
-		}
-		dec := p.dec
-		if wire != WireStartGroup && wire != p.WireType {
-			if wire == WireBytes && p.packedDec != nil {
-				// a packable field
-				dec = p.packedDec
-			} else {
-				err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType)
-				continue
-			}
-		}
-		decErr := dec(o, p, base)
-		if decErr != nil && !state.shouldContinue(decErr, p) {
-			err = decErr
-		}
-		if err == nil && p.Required {
-			// Successfully decoded a required field.
-			if tag <= 64 {
-				// use bitmap for fields 1-64 to catch field reuse.
-				var mask uint64 = 1 << uint64(tag-1)
-				if reqFields&mask == 0 {
-					// new required field
-					reqFields |= mask
-					required--
-				}
-			} else {
-				// This is imprecise. It can be fooled by a required field
-				// with a tag > 64 that is encoded twice; that's very rare.
-				// A fully correct implementation would require allocating
-				// a data structure, which we would like to avoid.
-				required--
-			}
-		}
-	}
-	if err == nil {
-		if is_group {
-			return io.ErrUnexpectedEOF
-		}
-		if state.err != nil {
-			return state.err
-		}
-		if required > 0 {
-			// Not enough information to determine the exact field. If we use extra
-			// CPU, we could determine the field only if the missing required field
-			// has a tag <= 64 and we check reqFields.
-			return &RequiredNotSetError{"{Unknown}"}
-		}
-	}
-	return err
-}
-
-// Individual type decoders
-// For each,
-//	u is the decoded value,
-//	v is a pointer to the field (pointer) in the struct
-
-// Sizes of the pools to allocate inside the Buffer.
-// The goal is modest amortization and allocation
-// on at least 16-byte boundaries.
-const (
-	boolPoolSize   = 16
-	uint32PoolSize = 8
-	uint64PoolSize = 4
-)
-
-// Decode a bool.
-func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	if len(o.bools) == 0 {
-		o.bools = make([]bool, boolPoolSize)
-	}
-	o.bools[0] = u != 0
-	*structPointer_Bool(base, p.field) = &o.bools[0]
-	o.bools = o.bools[1:]
-	return nil
-}
-
-func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	*structPointer_BoolVal(base, p.field) = u != 0
-	return nil
-}
-
-// Decode an int32.
-func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	word32_Set(structPointer_Word32(base, p.field), o, uint32(u))
-	return nil
-}
-
-func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u))
-	return nil
-}
-
-// Decode an int64.
-func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	word64_Set(structPointer_Word64(base, p.field), o, u)
-	return nil
-}
-
-func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	word64Val_Set(structPointer_Word64Val(base, p.field), o, u)
-	return nil
-}
-
-// Decode a string.
-func (o *Buffer) dec_string(p *Properties, base structPointer) error {
-	s, err := o.DecodeStringBytes()
-	if err != nil {
-		return err
-	}
-	*structPointer_String(base, p.field) = &s
-	return nil
-}
-
-func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error {
-	s, err := o.DecodeStringBytes()
-	if err != nil {
-		return err
-	}
-	*structPointer_StringVal(base, p.field) = s
-	return nil
-}
-
-// Decode a slice of bytes ([]byte).
-func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error {
-	b, err := o.DecodeRawBytes(true)
-	if err != nil {
-		return err
-	}
-	*structPointer_Bytes(base, p.field) = b
-	return nil
-}
-
-// Decode a slice of bools ([]bool).
-func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	v := structPointer_BoolSlice(base, p.field)
-	*v = append(*v, u != 0)
-	return nil
-}
-
-// Decode a slice of bools ([]bool) in packed format.
-func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error {
-	v := structPointer_BoolSlice(base, p.field)
-
-	nn, err := o.DecodeVarint()
-	if err != nil {
-		return err
-	}
-	nb := int(nn) // number of bytes of encoded bools
-	fin := o.index + nb
-	if fin < o.index {
-		return errOverflow
-	}
-
-	y := *v
-	for o.index < fin {
-		u, err := p.valDec(o)
-		if err != nil {
-			return err
-		}
-		y = append(y, u != 0)
-	}
-
-	*v = y
-	return nil
-}
-
-// Decode a slice of int32s ([]int32).
-func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	structPointer_Word32Slice(base, p.field).Append(uint32(u))
-	return nil
-}
-
-// Decode a slice of int32s ([]int32) in packed format.
-func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error {
-	v := structPointer_Word32Slice(base, p.field)
-
-	nn, err := o.DecodeVarint()
-	if err != nil {
-		return err
-	}
-	nb := int(nn) // number of bytes of encoded int32s
-
-	fin := o.index + nb
-	if fin < o.index {
-		return errOverflow
-	}
-	for o.index < fin {
-		u, err := p.valDec(o)
-		if err != nil {
-			return err
-		}
-		v.Append(uint32(u))
-	}
-	return nil
-}
-
-// Decode a slice of int64s ([]int64).
-func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-
-	structPointer_Word64Slice(base, p.field).Append(u)
-	return nil
-}
-
-// Decode a slice of int64s ([]int64) in packed format.
-func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error {
-	v := structPointer_Word64Slice(base, p.field)
-
-	nn, err := o.DecodeVarint()
-	if err != nil {
-		return err
-	}
-	nb := int(nn) // number of bytes of encoded int64s
-
-	fin := o.index + nb
-	if fin < o.index {
-		return errOverflow
-	}
-	for o.index < fin {
-		u, err := p.valDec(o)
-		if err != nil {
-			return err
-		}
-		v.Append(u)
-	}
-	return nil
-}
-
-// Decode a slice of strings ([]string).
-func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error {
-	s, err := o.DecodeStringBytes()
-	if err != nil {
-		return err
-	}
-	v := structPointer_StringSlice(base, p.field)
-	*v = append(*v, s)
-	return nil
-}
-
-// Decode a slice of slice of bytes ([][]byte).
-func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
-	b, err := o.DecodeRawBytes(true)
-	if err != nil {
-		return err
-	}
-	v := structPointer_BytesSlice(base, p.field)
-	*v = append(*v, b)
-	return nil
-}
-
-// Decode a map field.
-func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
-	raw, err := o.DecodeRawBytes(false)
-	if err != nil {
-		return err
-	}
-	oi := o.index       // index at the end of this map entry
-	o.index -= len(raw) // move buffer back to start of map entry
-
-	mptr := structPointer_NewAt(base, p.field, p.mtype) // *map[K]V
-	if mptr.Elem().IsNil() {
-		mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
-	}
-	v := mptr.Elem() // map[K]V
-
-	// Prepare addressable doubly-indirect placeholders for the key and value types.
-	// See enc_new_map for why.
-	keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K
-	keybase := toStructPointer(keyptr.Addr())                  // **K
-
-	var valbase structPointer
-	var valptr reflect.Value
-	switch p.mtype.Elem().Kind() {
-	case reflect.Slice:
-		// []byte
-		var dummy []byte
-		valptr = reflect.ValueOf(&dummy)  // *[]byte
-		valbase = toStructPointer(valptr) // *[]byte
-	case reflect.Ptr:
-		// message; valptr is **Msg; need to allocate the intermediate pointer
-		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
-		valptr.Set(reflect.New(valptr.Type().Elem()))
-		valbase = toStructPointer(valptr)
-	default:
-		// everything else
-		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
-		valbase = toStructPointer(valptr.Addr())                   // **V
-	}
-
-	// Decode.
-	// This parses a restricted wire format, namely the encoding of a message
-	// with two fields. See enc_new_map for the format.
-	for o.index < oi {
-		// tagcode for key and value properties are always a single byte
-		// because they have tags 1 and 2.
-		tagcode := o.buf[o.index]
-		o.index++
-		switch tagcode {
-		case p.mkeyprop.tagcode[0]:
-			if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil {
-				return err
-			}
-		case p.mvalprop.tagcode[0]:
-			if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil {
-				return err
-			}
-		default:
-			// TODO: Should we silently skip this instead?
-			return fmt.Errorf("proto: bad map data tag %d", raw[0])
-		}
-	}
-	keyelem, valelem := keyptr.Elem(), valptr.Elem()
-	if !keyelem.IsValid() {
-		keyelem = reflect.Zero(p.mtype.Key())
-	}
-	if !valelem.IsValid() {
-		valelem = reflect.Zero(p.mtype.Elem())
-	}
-
-	v.SetMapIndex(keyelem, valelem)
-	return nil
-}
-
-// Decode a group.
-func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
-	bas := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(bas) {
-		// allocate new nested message
-		bas = toStructPointer(reflect.New(p.stype))
-		structPointer_SetStructPointer(base, p.field, bas)
-	}
-	return o.unmarshalType(p.stype, p.sprop, true, bas)
-}
-
-// Decode an embedded message.
-func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) {
-	raw, e := o.DecodeRawBytes(false)
-	if e != nil {
-		return e
-	}
-
-	bas := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(bas) {
-		// allocate new nested message
-		bas = toStructPointer(reflect.New(p.stype))
-		structPointer_SetStructPointer(base, p.field, bas)
-	}
-
-	// If the object can unmarshal itself, let it.
-	if p.isUnmarshaler {
-		iv := structPointer_Interface(bas, p.stype)
-		return iv.(Unmarshaler).Unmarshal(raw)
-	}
-
-	obuf := o.buf
-	oi := o.index
-	o.buf = raw
-	o.index = 0
-
-	err = o.unmarshalType(p.stype, p.sprop, false, bas)
-	o.buf = obuf
-	o.index = oi
-
-	return err
-}
-
-// Decode a slice of embedded messages.
-func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error {
-	return o.dec_slice_struct(p, false, base)
-}
-
-// Decode a slice of embedded groups.
-func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error {
-	return o.dec_slice_struct(p, true, base)
-}
-
-// Decode a slice of structs ([]*struct).
-func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error {
-	v := reflect.New(p.stype)
-	bas := toStructPointer(v)
-	structPointer_StructPointerSlice(base, p.field).Append(bas)
-
-	if is_group {
-		err := o.unmarshalType(p.stype, p.sprop, is_group, bas)
-		return err
-	}
-
-	raw, err := o.DecodeRawBytes(false)
-	if err != nil {
-		return err
-	}
-
-	// If the object can unmarshal itself, let it.
-	if p.isUnmarshaler {
-		iv := v.Interface()
-		return iv.(Unmarshaler).Unmarshal(raw)
-	}
-
-	obuf := o.buf
-	oi := o.index
-	o.buf = raw
-	o.index = 0
-
-	err = o.unmarshalType(p.stype, p.sprop, is_group, bas)
-
-	o.buf = obuf
-	o.index = oi
-
+	// Slow workaround for messages that aren't Unmarshalers.
+	// This includes some hand-coded .pb.go files and
+	// bootstrap protos.
+	// TODO: fix all of those and then add Unmarshal to
+	// the Message interface. Then:
+	// The cast above and code below can be deleted.
+	// The old unmarshaler can be deleted.
+	// Clients can call Unmarshal directly (can already do that, actually).
+	var info InternalMessageInfo
+	err := info.Unmarshal(pb, p.buf[p.index:])
+	p.index = len(p.buf)
 	return err
 }
diff --git a/proto/decode_test.go b/proto/decode_test.go
index 2c4c31d..949be3a 100644
--- a/proto/decode_test.go
+++ b/proto/decode_test.go
@@ -41,10 +41,7 @@
 	tpb "github.com/golang/protobuf/proto/proto3_proto"
 )
 
-var (
-	bytesBlackhole []byte
-	msgBlackhole   = new(tpb.Message)
-)
+var msgBlackhole = new(tpb.Message)
 
 // BenchmarkVarint32ArraySmall shows the performance on an array of small int32 fields (1 and
 // 2 bytes long).
diff --git a/proto/discard.go b/proto/discard.go
index bd0e3bb..dea2617 100644
--- a/proto/discard.go
+++ b/proto/discard.go
@@ -35,8 +35,14 @@
 	"fmt"
 	"reflect"
 	"strings"
+	"sync"
+	"sync/atomic"
 )
 
+type generatedDiscarder interface {
+	XXX_DiscardUnknown()
+}
+
 // DiscardUnknown recursively discards all unknown fields from this message
 // and all embedded messages.
 //
@@ -49,9 +55,202 @@
 // For proto2 messages, the unknown fields of message extensions are only
 // discarded from messages that have been accessed via GetExtension.
 func DiscardUnknown(m Message) {
+	if m, ok := m.(generatedDiscarder); ok {
+		m.XXX_DiscardUnknown()
+		return
+	}
+	// TODO: Dynamically populate a InternalMessageInfo for legacy messages,
+	// but the master branch has no implementation for InternalMessageInfo,
+	// so it would be more work to replicate that approach.
 	discardLegacy(m)
 }
 
+// DiscardUnknown recursively discards all unknown fields.
+func (a *InternalMessageInfo) DiscardUnknown(m Message) {
+	di := atomicLoadDiscardInfo(&a.discard)
+	if di == nil {
+		di = getDiscardInfo(reflect.TypeOf(m).Elem())
+		atomicStoreDiscardInfo(&a.discard, di)
+	}
+	di.discard(toPointer(&m))
+}
+
+type discardInfo struct {
+	typ reflect.Type
+
+	initialized int32 // 0: only typ is valid, 1: everything is valid
+	lock        sync.Mutex
+
+	fields       []discardFieldInfo
+	unrecognized field
+}
+
+type discardFieldInfo struct {
+	field   field // Offset of field, guaranteed to be valid
+	discard func(src pointer)
+}
+
+var (
+	discardInfoMap  = map[reflect.Type]*discardInfo{}
+	discardInfoLock sync.Mutex
+)
+
+func getDiscardInfo(t reflect.Type) *discardInfo {
+	discardInfoLock.Lock()
+	defer discardInfoLock.Unlock()
+	di := discardInfoMap[t]
+	if di == nil {
+		di = &discardInfo{typ: t}
+		discardInfoMap[t] = di
+	}
+	return di
+}
+
+func (di *discardInfo) discard(src pointer) {
+	if src.isNil() {
+		return // Nothing to do.
+	}
+
+	if atomic.LoadInt32(&di.initialized) == 0 {
+		di.computeDiscardInfo()
+	}
+
+	for _, fi := range di.fields {
+		sfp := src.offset(fi.field)
+		fi.discard(sfp)
+	}
+
+	// For proto2 messages, only discard unknown fields in message extensions
+	// that have been accessed via GetExtension.
+	if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil {
+		// Ignore lock since DiscardUnknown is not concurrency safe.
+		emm, _ := em.extensionsRead()
+		for _, mx := range emm {
+			if m, ok := mx.value.(Message); ok {
+				DiscardUnknown(m)
+			}
+		}
+	}
+
+	if di.unrecognized.IsValid() {
+		*src.offset(di.unrecognized).toBytes() = nil
+	}
+}
+
+func (di *discardInfo) computeDiscardInfo() {
+	di.lock.Lock()
+	defer di.lock.Unlock()
+	if di.initialized != 0 {
+		return
+	}
+	t := di.typ
+	n := t.NumField()
+
+	for i := 0; i < n; i++ {
+		f := t.Field(i)
+		if strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+
+		dfi := discardFieldInfo{field: toField(&f)}
+		tf := f.Type
+
+		// Unwrap tf to get its most basic type.
+		var isPointer, isSlice bool
+		if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
+			isSlice = true
+			tf = tf.Elem()
+		}
+		if tf.Kind() == reflect.Ptr {
+			isPointer = true
+			tf = tf.Elem()
+		}
+		if isPointer && isSlice && tf.Kind() != reflect.Struct {
+			panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name))
+		}
+
+		switch tf.Kind() {
+		case reflect.Struct:
+			switch {
+			case !isPointer:
+				panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name))
+			case isSlice: // E.g., []*pb.T
+				di := getDiscardInfo(tf)
+				dfi.discard = func(src pointer) {
+					sps := src.getPointerSlice()
+					for _, sp := range sps {
+						if !sp.isNil() {
+							di.discard(sp)
+						}
+					}
+				}
+			default: // E.g., *pb.T
+				di := getDiscardInfo(tf)
+				dfi.discard = func(src pointer) {
+					sp := src.getPointer()
+					if !sp.isNil() {
+						di.discard(sp)
+					}
+				}
+			}
+		case reflect.Map:
+			switch {
+			case isPointer || isSlice:
+				panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name))
+			default: // E.g., map[K]V
+				if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T)
+					dfi.discard = func(src pointer) {
+						sm := src.asPointerTo(tf).Elem()
+						if sm.Len() == 0 {
+							return
+						}
+						for _, key := range sm.MapKeys() {
+							val := sm.MapIndex(key)
+							DiscardUnknown(val.Interface().(Message))
+						}
+					}
+				} else {
+					dfi.discard = func(pointer) {} // Noop
+				}
+			}
+		case reflect.Interface:
+			// Must be oneof field.
+			switch {
+			case isPointer || isSlice:
+				panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name))
+			default: // E.g., interface{}
+				// TODO: Make this faster?
+				dfi.discard = func(src pointer) {
+					su := src.asPointerTo(tf).Elem()
+					if !su.IsNil() {
+						sv := su.Elem().Elem().Field(0)
+						if sv.Kind() == reflect.Ptr && sv.IsNil() {
+							return
+						}
+						switch sv.Type().Kind() {
+						case reflect.Ptr: // Proto struct (e.g., *T)
+							DiscardUnknown(sv.Interface().(Message))
+						}
+					}
+				}
+			}
+		default:
+			continue
+		}
+		di.fields = append(di.fields, dfi)
+	}
+
+	di.unrecognized = invalidField
+	if f, ok := t.FieldByName("XXX_unrecognized"); ok {
+		if f.Type != reflect.TypeOf([]byte{}) {
+			panic("expected XXX_unrecognized to be of type []byte")
+		}
+		di.unrecognized = toField(&f)
+	}
+
+	atomic.StoreInt32(&di.initialized, 1)
+}
+
 func discardLegacy(m Message) {
 	v := reflect.ValueOf(m)
 	if v.Kind() != reflect.Ptr || v.IsNil() {
@@ -139,7 +338,7 @@
 
 	// For proto2 messages, only discard unknown fields in message extensions
 	// that have been accessed via GetExtension.
-	if em, ok := extendable(m); ok {
+	if em, err := extendable(m); err == nil {
 		// Ignore lock since discardLegacy is not concurrency safe.
 		emm, _ := em.extensionsRead()
 		for _, mx := range emm {
diff --git a/proto/discard_test.go b/proto/discard_test.go
new file mode 100644
index 0000000..a2ff550
--- /dev/null
+++ b/proto/discard_test.go
@@ -0,0 +1,170 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2017 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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.
+
+package proto_test
+
+import (
+	"testing"
+
+	"github.com/golang/protobuf/proto"
+
+	proto3pb "github.com/golang/protobuf/proto/proto3_proto"
+	pb "github.com/golang/protobuf/proto/test_proto"
+)
+
+func TestDiscardUnknown(t *testing.T) {
+	tests := []struct {
+		desc     string
+		in, want proto.Message
+	}{{
+		desc: "Nil",
+		in:   nil, want: nil, // Should not panic
+	}, {
+		desc: "NilPtr",
+		in:   (*proto3pb.Message)(nil), want: (*proto3pb.Message)(nil), // Should not panic
+	}, {
+		desc: "Nested",
+		in: &proto3pb.Message{
+			Name:             "Aaron",
+			Nested:           &proto3pb.Nested{Cute: true, XXX_unrecognized: []byte("blah")},
+			XXX_unrecognized: []byte("blah"),
+		},
+		want: &proto3pb.Message{
+			Name:   "Aaron",
+			Nested: &proto3pb.Nested{Cute: true},
+		},
+	}, {
+		desc: "Slice",
+		in: &proto3pb.Message{
+			Name: "Aaron",
+			Children: []*proto3pb.Message{
+				{Name: "Sarah", XXX_unrecognized: []byte("blah")},
+				{Name: "Abraham", XXX_unrecognized: []byte("blah")},
+			},
+			XXX_unrecognized: []byte("blah"),
+		},
+		want: &proto3pb.Message{
+			Name: "Aaron",
+			Children: []*proto3pb.Message{
+				{Name: "Sarah"},
+				{Name: "Abraham"},
+			},
+		},
+	}, {
+		desc: "OneOf",
+		in: &pb.Communique{
+			Union: &pb.Communique_Msg{&pb.Strings{
+				StringField:      proto.String("123"),
+				XXX_unrecognized: []byte("blah"),
+			}},
+			XXX_unrecognized: []byte("blah"),
+		},
+		want: &pb.Communique{
+			Union: &pb.Communique_Msg{&pb.Strings{StringField: proto.String("123")}},
+		},
+	}, {
+		desc: "Map",
+		in: &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{
+			0x4002: &pb.FloatingPoint{
+				Exact:            proto.Bool(true),
+				XXX_unrecognized: []byte("blah"),
+			},
+		}},
+		want: &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{
+			0x4002: &pb.FloatingPoint{Exact: proto.Bool(true)},
+		}},
+	}, {
+		desc: "Extension",
+		in: func() proto.Message {
+			m := &pb.MyMessage{
+				Count: proto.Int32(42),
+				Somegroup: &pb.MyMessage_SomeGroup{
+					GroupField:       proto.Int32(6),
+					XXX_unrecognized: []byte("blah"),
+				},
+				XXX_unrecognized: []byte("blah"),
+			}
+			proto.SetExtension(m, pb.E_Ext_More, &pb.Ext{
+				Data:             proto.String("extension"),
+				XXX_unrecognized: []byte("blah"),
+			})
+			return m
+		}(),
+		want: func() proto.Message {
+			m := &pb.MyMessage{
+				Count:     proto.Int32(42),
+				Somegroup: &pb.MyMessage_SomeGroup{GroupField: proto.Int32(6)},
+			}
+			proto.SetExtension(m, pb.E_Ext_More, &pb.Ext{Data: proto.String("extension")})
+			return m
+		}(),
+	}}
+
+	// Test the legacy code path.
+	for _, tt := range tests {
+		// Clone the input so that we don't alter the original.
+		in := tt.in
+		if in != nil {
+			in = proto.Clone(tt.in)
+		}
+
+		var m LegacyMessage
+		m.Message, _ = in.(*proto3pb.Message)
+		m.Communique, _ = in.(*pb.Communique)
+		m.MessageWithMap, _ = in.(*pb.MessageWithMap)
+		m.MyMessage, _ = in.(*pb.MyMessage)
+		proto.DiscardUnknown(&m)
+		if !proto.Equal(in, tt.want) {
+			t.Errorf("test %s/Legacy, expected unknown fields to be discarded\ngot  %v\nwant %v", tt.desc, in, tt.want)
+		}
+	}
+
+	for _, tt := range tests {
+		proto.DiscardUnknown(tt.in)
+		if !proto.Equal(tt.in, tt.want) {
+			t.Errorf("test %s, expected unknown fields to be discarded\ngot  %v\nwant %v", tt.desc, tt.in, tt.want)
+		}
+	}
+}
+
+// LegacyMessage is a proto.Message that has several nested messages.
+// This does not have the XXX_DiscardUnknown method and so forces DiscardUnknown
+// to use the legacy fallback logic.
+type LegacyMessage struct {
+	Message        *proto3pb.Message
+	Communique     *pb.Communique
+	MessageWithMap *pb.MessageWithMap
+	MyMessage      *pb.MyMessage
+}
+
+func (m *LegacyMessage) Reset()         { *m = LegacyMessage{} }
+func (m *LegacyMessage) String() string { return proto.CompactTextString(m) }
+func (*LegacyMessage) ProtoMessage()    {}
diff --git a/proto/encode.go b/proto/encode.go
index 8b84d1b..c27d35f 100644
--- a/proto/encode.go
+++ b/proto/encode.go
@@ -39,7 +39,6 @@
 	"errors"
 	"fmt"
 	"reflect"
-	"sort"
 )
 
 // RequiredNotSetError is the error returned if Marshal is called with
@@ -82,10 +81,6 @@
 
 const maxVarintBytes = 10 // maximum length of a varint
 
-// maxMarshalSize is the largest allowed size of an encoded protobuf,
-// since C++ and Java use signed int32s for the size.
-const maxMarshalSize = 1<<31 - 1
-
 // EncodeVarint returns the varint encoding of x.
 // This is the format for the
 // int32, int64, uint32, uint64, bool, and enum
@@ -119,18 +114,27 @@
 
 // SizeVarint returns the varint encoding size of an integer.
 func SizeVarint(x uint64) int {
-	return sizeVarint(x)
-}
-
-func sizeVarint(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
+	switch {
+	case x < 1<<7:
+		return 1
+	case x < 1<<14:
+		return 2
+	case x < 1<<21:
+		return 3
+	case x < 1<<28:
+		return 4
+	case x < 1<<35:
+		return 5
+	case x < 1<<42:
+		return 6
+	case x < 1<<49:
+		return 7
+	case x < 1<<56:
+		return 8
+	case x < 1<<63:
+		return 9
 	}
-	return n
+	return 10
 }
 
 // EncodeFixed64 writes a 64-bit integer to the Buffer.
@@ -149,10 +153,6 @@
 	return nil
 }
 
-func sizeFixed64(x uint64) int {
-	return 8
-}
-
 // EncodeFixed32 writes a 32-bit integer to the Buffer.
 // This is the format for the
 // fixed32, sfixed32, and float protocol buffer types.
@@ -165,20 +165,12 @@
 	return nil
 }
 
-func sizeFixed32(x uint64) int {
-	return 4
-}
-
 // EncodeZigzag64 writes a zigzag-encoded 64-bit integer
 // to the Buffer.
 // This is the format used for the sint64 protocol buffer type.
 func (p *Buffer) EncodeZigzag64(x uint64) error {
 	// use signed number to get arithmetic right shift.
-	return p.EncodeVarint((x << 1) ^ uint64((int64(x) >> 63)))
-}
-
-func sizeZigzag64(x uint64) int {
-	return sizeVarint((x << 1) ^ uint64((int64(x) >> 63)))
+	return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
 }
 
 // EncodeZigzag32 writes a zigzag-encoded 32-bit integer
@@ -189,10 +181,6 @@
 	return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
 }
 
-func sizeZigzag32(x uint64) int {
-	return sizeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
-}
-
 // EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
 // This is the format used for the bytes protocol buffer
 // type and for embedded messages.
@@ -202,11 +190,6 @@
 	return nil
 }
 
-func sizeRawBytes(b []byte) int {
-	return sizeVarint(uint64(len(b))) +
-		len(b)
-}
-
 // EncodeStringBytes writes an encoded string to the Buffer.
 // This is the format used for the proto2 string type.
 func (p *Buffer) EncodeStringBytes(s string) error {
@@ -215,319 +198,17 @@
 	return nil
 }
 
-func sizeStringBytes(s string) int {
-	return sizeVarint(uint64(len(s))) +
-		len(s)
-}
-
 // Marshaler is the interface representing objects that can marshal themselves.
 type Marshaler interface {
 	Marshal() ([]byte, error)
 }
 
-// Marshal takes the protocol buffer
-// and encodes it into the wire format, returning the data.
-func Marshal(pb Message) ([]byte, error) {
-	// Can the object marshal itself?
-	if m, ok := pb.(Marshaler); ok {
-		return m.Marshal()
-	}
-	p := NewBuffer(nil)
-	err := p.Marshal(pb)
-	if p.buf == nil && err == nil {
-		// Return a non-nil slice on success.
-		return []byte{}, nil
-	}
-	return p.buf, err
-}
-
 // EncodeMessage writes the protocol buffer to the Buffer,
 // prefixed by a varint-encoded length.
 func (p *Buffer) EncodeMessage(pb Message) error {
-	t, base, err := getbase(pb)
-	if structPointer_IsNil(base) {
-		return ErrNil
-	}
-	if err == nil {
-		var state errorState
-		err = p.enc_len_struct(GetProperties(t.Elem()), base, &state)
-	}
-	return err
-}
-
-// Marshal takes the protocol buffer
-// and encodes it into the wire format, writing the result to the
-// Buffer.
-func (p *Buffer) Marshal(pb Message) error {
-	// Can the object marshal itself?
-	if m, ok := pb.(Marshaler); ok {
-		data, err := m.Marshal()
-		p.buf = append(p.buf, data...)
-		return err
-	}
-
-	t, base, err := getbase(pb)
-	if structPointer_IsNil(base) {
-		return ErrNil
-	}
-	if err == nil {
-		err = p.enc_struct(GetProperties(t.Elem()), base)
-	}
-
-	if collectStats {
-		(stats).Encode++ // Parens are to work around a goimports bug.
-	}
-
-	if len(p.buf) > maxMarshalSize {
-		return ErrTooLarge
-	}
-	return err
-}
-
-// Size returns the encoded size of a protocol buffer.
-func Size(pb Message) (n int) {
-	// Can the object marshal itself?  If so, Size is slow.
-	// TODO: add Size to Marshaler, or add a Sizer interface.
-	if m, ok := pb.(Marshaler); ok {
-		b, _ := m.Marshal()
-		return len(b)
-	}
-
-	t, base, err := getbase(pb)
-	if structPointer_IsNil(base) {
-		return 0
-	}
-	if err == nil {
-		n = size_struct(GetProperties(t.Elem()), base)
-	}
-
-	if collectStats {
-		(stats).Size++ // Parens are to work around a goimports bug.
-	}
-
-	return
-}
-
-// Individual type encoders.
-
-// Encode a bool.
-func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
-	v := *structPointer_Bool(base, p.field)
-	if v == nil {
-		return ErrNil
-	}
-	x := 0
-	if *v {
-		x = 1
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, uint64(x))
-	return nil
-}
-
-func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error {
-	v := *structPointer_BoolVal(base, p.field)
-	if !v {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, 1)
-	return nil
-}
-
-func size_bool(p *Properties, base structPointer) int {
-	v := *structPointer_Bool(base, p.field)
-	if v == nil {
-		return 0
-	}
-	return len(p.tagcode) + 1 // each bool takes exactly one byte
-}
-
-func size_proto3_bool(p *Properties, base structPointer) int {
-	v := *structPointer_BoolVal(base, p.field)
-	if !v && !p.oneof {
-		return 0
-	}
-	return len(p.tagcode) + 1 // each bool takes exactly one byte
-}
-
-// Encode an int32.
-func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
-	v := structPointer_Word32(base, p.field)
-	if word32_IsNil(v) {
-		return ErrNil
-	}
-	x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, uint64(x))
-	return nil
-}
-
-func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error {
-	v := structPointer_Word32Val(base, p.field)
-	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
-	if x == 0 {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, uint64(x))
-	return nil
-}
-
-func size_int32(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word32(base, p.field)
-	if word32_IsNil(v) {
-		return 0
-	}
-	x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
-	n += len(p.tagcode)
-	n += p.valSize(uint64(x))
-	return
-}
-
-func size_proto3_int32(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word32Val(base, p.field)
-	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
-	if x == 0 && !p.oneof {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += p.valSize(uint64(x))
-	return
-}
-
-// Encode a uint32.
-// Exactly the same as int32, except for no sign extension.
-func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
-	v := structPointer_Word32(base, p.field)
-	if word32_IsNil(v) {
-		return ErrNil
-	}
-	x := word32_Get(v)
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, uint64(x))
-	return nil
-}
-
-func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error {
-	v := structPointer_Word32Val(base, p.field)
-	x := word32Val_Get(v)
-	if x == 0 {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, uint64(x))
-	return nil
-}
-
-func size_uint32(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word32(base, p.field)
-	if word32_IsNil(v) {
-		return 0
-	}
-	x := word32_Get(v)
-	n += len(p.tagcode)
-	n += p.valSize(uint64(x))
-	return
-}
-
-func size_proto3_uint32(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word32Val(base, p.field)
-	x := word32Val_Get(v)
-	if x == 0 && !p.oneof {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += p.valSize(uint64(x))
-	return
-}
-
-// Encode an int64.
-func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
-	v := structPointer_Word64(base, p.field)
-	if word64_IsNil(v) {
-		return ErrNil
-	}
-	x := word64_Get(v)
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, x)
-	return nil
-}
-
-func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error {
-	v := structPointer_Word64Val(base, p.field)
-	x := word64Val_Get(v)
-	if x == 0 {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, x)
-	return nil
-}
-
-func size_int64(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word64(base, p.field)
-	if word64_IsNil(v) {
-		return 0
-	}
-	x := word64_Get(v)
-	n += len(p.tagcode)
-	n += p.valSize(x)
-	return
-}
-
-func size_proto3_int64(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word64Val(base, p.field)
-	x := word64Val_Get(v)
-	if x == 0 && !p.oneof {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += p.valSize(x)
-	return
-}
-
-// Encode a string.
-func (o *Buffer) enc_string(p *Properties, base structPointer) error {
-	v := *structPointer_String(base, p.field)
-	if v == nil {
-		return ErrNil
-	}
-	x := *v
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeStringBytes(x)
-	return nil
-}
-
-func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error {
-	v := *structPointer_StringVal(base, p.field)
-	if v == "" {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeStringBytes(v)
-	return nil
-}
-
-func size_string(p *Properties, base structPointer) (n int) {
-	v := *structPointer_String(base, p.field)
-	if v == nil {
-		return 0
-	}
-	x := *v
-	n += len(p.tagcode)
-	n += sizeStringBytes(x)
-	return
-}
-
-func size_proto3_string(p *Properties, base structPointer) (n int) {
-	v := *structPointer_StringVal(base, p.field)
-	if v == "" && !p.oneof {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += sizeStringBytes(v)
-	return
+	siz := Size(pb)
+	p.EncodeVarint(uint64(siz))
+	return p.Marshal(pb)
 }
 
 // All protocol buffer fields are nillable, but be careful.
@@ -538,825 +219,3 @@
 	}
 	return false
 }
-
-// Encode a message struct.
-func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
-	var state errorState
-	structp := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(structp) {
-		return ErrNil
-	}
-
-	// Can the object marshal itself?
-	if p.isMarshaler {
-		m := structPointer_Interface(structp, p.stype).(Marshaler)
-		data, err := m.Marshal()
-		if err != nil && !state.shouldContinue(err, nil) {
-			return err
-		}
-		o.buf = append(o.buf, p.tagcode...)
-		o.EncodeRawBytes(data)
-		return state.err
-	}
-
-	o.buf = append(o.buf, p.tagcode...)
-	return o.enc_len_struct(p.sprop, structp, &state)
-}
-
-func size_struct_message(p *Properties, base structPointer) int {
-	structp := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(structp) {
-		return 0
-	}
-
-	// Can the object marshal itself?
-	if p.isMarshaler {
-		m := structPointer_Interface(structp, p.stype).(Marshaler)
-		data, _ := m.Marshal()
-		n0 := len(p.tagcode)
-		n1 := sizeRawBytes(data)
-		return n0 + n1
-	}
-
-	n0 := len(p.tagcode)
-	n1 := size_struct(p.sprop, structp)
-	n2 := sizeVarint(uint64(n1)) // size of encoded length
-	return n0 + n1 + n2
-}
-
-// Encode a group struct.
-func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
-	var state errorState
-	b := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(b) {
-		return ErrNil
-	}
-
-	o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
-	err := o.enc_struct(p.sprop, b)
-	if err != nil && !state.shouldContinue(err, nil) {
-		return err
-	}
-	o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
-	return state.err
-}
-
-func size_struct_group(p *Properties, base structPointer) (n int) {
-	b := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(b) {
-		return 0
-	}
-
-	n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup))
-	n += size_struct(p.sprop, b)
-	n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup))
-	return
-}
-
-// Encode a slice of bools ([]bool).
-func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
-	s := *structPointer_BoolSlice(base, p.field)
-	l := len(s)
-	if l == 0 {
-		return ErrNil
-	}
-	for _, x := range s {
-		o.buf = append(o.buf, p.tagcode...)
-		v := uint64(0)
-		if x {
-			v = 1
-		}
-		p.valEnc(o, v)
-	}
-	return nil
-}
-
-func size_slice_bool(p *Properties, base structPointer) int {
-	s := *structPointer_BoolSlice(base, p.field)
-	l := len(s)
-	if l == 0 {
-		return 0
-	}
-	return l * (len(p.tagcode) + 1) // each bool takes exactly one byte
-}
-
-// Encode a slice of bools ([]bool) in packed format.
-func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
-	s := *structPointer_BoolSlice(base, p.field)
-	l := len(s)
-	if l == 0 {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
-	for _, x := range s {
-		v := uint64(0)
-		if x {
-			v = 1
-		}
-		p.valEnc(o, v)
-	}
-	return nil
-}
-
-func size_slice_packed_bool(p *Properties, base structPointer) (n int) {
-	s := *structPointer_BoolSlice(base, p.field)
-	l := len(s)
-	if l == 0 {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += sizeVarint(uint64(l))
-	n += l // each bool takes exactly one byte
-	return
-}
-
-// Encode a slice of bytes ([]byte).
-func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
-	s := *structPointer_Bytes(base, p.field)
-	if s == nil {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeRawBytes(s)
-	return nil
-}
-
-func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error {
-	s := *structPointer_Bytes(base, p.field)
-	if len(s) == 0 {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeRawBytes(s)
-	return nil
-}
-
-func size_slice_byte(p *Properties, base structPointer) (n int) {
-	s := *structPointer_Bytes(base, p.field)
-	if s == nil && !p.oneof {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += sizeRawBytes(s)
-	return
-}
-
-func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
-	s := *structPointer_Bytes(base, p.field)
-	if len(s) == 0 && !p.oneof {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += sizeRawBytes(s)
-	return
-}
-
-// Encode a slice of int32s ([]int32).
-func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return ErrNil
-	}
-	for i := 0; i < l; i++ {
-		o.buf = append(o.buf, p.tagcode...)
-		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
-		p.valEnc(o, uint64(x))
-	}
-	return nil
-}
-
-func size_slice_int32(p *Properties, base structPointer) (n int) {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return 0
-	}
-	for i := 0; i < l; i++ {
-		n += len(p.tagcode)
-		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
-		n += p.valSize(uint64(x))
-	}
-	return
-}
-
-// Encode a slice of int32s ([]int32) in packed format.
-func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return ErrNil
-	}
-	// TODO: Reuse a Buffer.
-	buf := NewBuffer(nil)
-	for i := 0; i < l; i++ {
-		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
-		p.valEnc(buf, uint64(x))
-	}
-
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeVarint(uint64(len(buf.buf)))
-	o.buf = append(o.buf, buf.buf...)
-	return nil
-}
-
-func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return 0
-	}
-	var bufSize int
-	for i := 0; i < l; i++ {
-		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
-		bufSize += p.valSize(uint64(x))
-	}
-
-	n += len(p.tagcode)
-	n += sizeVarint(uint64(bufSize))
-	n += bufSize
-	return
-}
-
-// Encode a slice of uint32s ([]uint32).
-// Exactly the same as int32, except for no sign extension.
-func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return ErrNil
-	}
-	for i := 0; i < l; i++ {
-		o.buf = append(o.buf, p.tagcode...)
-		x := s.Index(i)
-		p.valEnc(o, uint64(x))
-	}
-	return nil
-}
-
-func size_slice_uint32(p *Properties, base structPointer) (n int) {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return 0
-	}
-	for i := 0; i < l; i++ {
-		n += len(p.tagcode)
-		x := s.Index(i)
-		n += p.valSize(uint64(x))
-	}
-	return
-}
-
-// Encode a slice of uint32s ([]uint32) in packed format.
-// Exactly the same as int32, except for no sign extension.
-func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return ErrNil
-	}
-	// TODO: Reuse a Buffer.
-	buf := NewBuffer(nil)
-	for i := 0; i < l; i++ {
-		p.valEnc(buf, uint64(s.Index(i)))
-	}
-
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeVarint(uint64(len(buf.buf)))
-	o.buf = append(o.buf, buf.buf...)
-	return nil
-}
-
-func size_slice_packed_uint32(p *Properties, base structPointer) (n int) {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return 0
-	}
-	var bufSize int
-	for i := 0; i < l; i++ {
-		bufSize += p.valSize(uint64(s.Index(i)))
-	}
-
-	n += len(p.tagcode)
-	n += sizeVarint(uint64(bufSize))
-	n += bufSize
-	return
-}
-
-// Encode a slice of int64s ([]int64).
-func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
-	s := structPointer_Word64Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return ErrNil
-	}
-	for i := 0; i < l; i++ {
-		o.buf = append(o.buf, p.tagcode...)
-		p.valEnc(o, s.Index(i))
-	}
-	return nil
-}
-
-func size_slice_int64(p *Properties, base structPointer) (n int) {
-	s := structPointer_Word64Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return 0
-	}
-	for i := 0; i < l; i++ {
-		n += len(p.tagcode)
-		n += p.valSize(s.Index(i))
-	}
-	return
-}
-
-// Encode a slice of int64s ([]int64) in packed format.
-func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
-	s := structPointer_Word64Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return ErrNil
-	}
-	// TODO: Reuse a Buffer.
-	buf := NewBuffer(nil)
-	for i := 0; i < l; i++ {
-		p.valEnc(buf, s.Index(i))
-	}
-
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeVarint(uint64(len(buf.buf)))
-	o.buf = append(o.buf, buf.buf...)
-	return nil
-}
-
-func size_slice_packed_int64(p *Properties, base structPointer) (n int) {
-	s := structPointer_Word64Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return 0
-	}
-	var bufSize int
-	for i := 0; i < l; i++ {
-		bufSize += p.valSize(s.Index(i))
-	}
-
-	n += len(p.tagcode)
-	n += sizeVarint(uint64(bufSize))
-	n += bufSize
-	return
-}
-
-// Encode a slice of slice of bytes ([][]byte).
-func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
-	ss := *structPointer_BytesSlice(base, p.field)
-	l := len(ss)
-	if l == 0 {
-		return ErrNil
-	}
-	for i := 0; i < l; i++ {
-		o.buf = append(o.buf, p.tagcode...)
-		o.EncodeRawBytes(ss[i])
-	}
-	return nil
-}
-
-func size_slice_slice_byte(p *Properties, base structPointer) (n int) {
-	ss := *structPointer_BytesSlice(base, p.field)
-	l := len(ss)
-	if l == 0 {
-		return 0
-	}
-	n += l * len(p.tagcode)
-	for i := 0; i < l; i++ {
-		n += sizeRawBytes(ss[i])
-	}
-	return
-}
-
-// Encode a slice of strings ([]string).
-func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
-	ss := *structPointer_StringSlice(base, p.field)
-	l := len(ss)
-	for i := 0; i < l; i++ {
-		o.buf = append(o.buf, p.tagcode...)
-		o.EncodeStringBytes(ss[i])
-	}
-	return nil
-}
-
-func size_slice_string(p *Properties, base structPointer) (n int) {
-	ss := *structPointer_StringSlice(base, p.field)
-	l := len(ss)
-	n += l * len(p.tagcode)
-	for i := 0; i < l; i++ {
-		n += sizeStringBytes(ss[i])
-	}
-	return
-}
-
-// Encode a slice of message structs ([]*struct).
-func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
-	var state errorState
-	s := structPointer_StructPointerSlice(base, p.field)
-	l := s.Len()
-
-	for i := 0; i < l; i++ {
-		structp := s.Index(i)
-		if structPointer_IsNil(structp) {
-			return errRepeatedHasNil
-		}
-
-		// Can the object marshal itself?
-		if p.isMarshaler {
-			m := structPointer_Interface(structp, p.stype).(Marshaler)
-			data, err := m.Marshal()
-			if err != nil && !state.shouldContinue(err, nil) {
-				return err
-			}
-			o.buf = append(o.buf, p.tagcode...)
-			o.EncodeRawBytes(data)
-			continue
-		}
-
-		o.buf = append(o.buf, p.tagcode...)
-		err := o.enc_len_struct(p.sprop, structp, &state)
-		if err != nil && !state.shouldContinue(err, nil) {
-			if err == ErrNil {
-				return errRepeatedHasNil
-			}
-			return err
-		}
-	}
-	return state.err
-}
-
-func size_slice_struct_message(p *Properties, base structPointer) (n int) {
-	s := structPointer_StructPointerSlice(base, p.field)
-	l := s.Len()
-	n += l * len(p.tagcode)
-	for i := 0; i < l; i++ {
-		structp := s.Index(i)
-		if structPointer_IsNil(structp) {
-			return // return the size up to this point
-		}
-
-		// Can the object marshal itself?
-		if p.isMarshaler {
-			m := structPointer_Interface(structp, p.stype).(Marshaler)
-			data, _ := m.Marshal()
-			n += sizeRawBytes(data)
-			continue
-		}
-
-		n0 := size_struct(p.sprop, structp)
-		n1 := sizeVarint(uint64(n0)) // size of encoded length
-		n += n0 + n1
-	}
-	return
-}
-
-// Encode a slice of group structs ([]*struct).
-func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
-	var state errorState
-	s := structPointer_StructPointerSlice(base, p.field)
-	l := s.Len()
-
-	for i := 0; i < l; i++ {
-		b := s.Index(i)
-		if structPointer_IsNil(b) {
-			return errRepeatedHasNil
-		}
-
-		o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
-
-		err := o.enc_struct(p.sprop, b)
-
-		if err != nil && !state.shouldContinue(err, nil) {
-			if err == ErrNil {
-				return errRepeatedHasNil
-			}
-			return err
-		}
-
-		o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
-	}
-	return state.err
-}
-
-func size_slice_struct_group(p *Properties, base structPointer) (n int) {
-	s := structPointer_StructPointerSlice(base, p.field)
-	l := s.Len()
-
-	n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup))
-	n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup))
-	for i := 0; i < l; i++ {
-		b := s.Index(i)
-		if structPointer_IsNil(b) {
-			return // return size up to this point
-		}
-
-		n += size_struct(p.sprop, b)
-	}
-	return
-}
-
-// Encode an extension map.
-func (o *Buffer) enc_map(p *Properties, base structPointer) error {
-	exts := structPointer_ExtMap(base, p.field)
-	if err := encodeExtensionsMap(*exts); err != nil {
-		return err
-	}
-
-	return o.enc_map_body(*exts)
-}
-
-func (o *Buffer) enc_exts(p *Properties, base structPointer) error {
-	exts := structPointer_Extensions(base, p.field)
-
-	v, mu := exts.extensionsRead()
-	if v == nil {
-		return nil
-	}
-
-	mu.Lock()
-	defer mu.Unlock()
-	if err := encodeExtensionsMap(v); err != nil {
-		return err
-	}
-
-	return o.enc_map_body(v)
-}
-
-func (o *Buffer) enc_map_body(v map[int32]Extension) error {
-	// Fast-path for common cases: zero or one extensions.
-	if len(v) <= 1 {
-		for _, e := range v {
-			o.buf = append(o.buf, e.enc...)
-		}
-		return nil
-	}
-
-	// Sort keys to provide a deterministic encoding.
-	keys := make([]int, 0, len(v))
-	for k := range v {
-		keys = append(keys, int(k))
-	}
-	sort.Ints(keys)
-
-	for _, k := range keys {
-		o.buf = append(o.buf, v[int32(k)].enc...)
-	}
-	return nil
-}
-
-func size_map(p *Properties, base structPointer) int {
-	v := structPointer_ExtMap(base, p.field)
-	return extensionsMapSize(*v)
-}
-
-func size_exts(p *Properties, base structPointer) int {
-	v := structPointer_Extensions(base, p.field)
-	return extensionsSize(v)
-}
-
-// Encode a map field.
-func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
-	var state errorState // XXX: or do we need to plumb this through?
-
-	/*
-		A map defined as
-			map<key_type, value_type> map_field = N;
-		is encoded in the same way as
-			message MapFieldEntry {
-				key_type key = 1;
-				value_type value = 2;
-			}
-			repeated MapFieldEntry map_field = N;
-	*/
-
-	v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V
-	if v.Len() == 0 {
-		return nil
-	}
-
-	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
-
-	enc := func() error {
-		if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
-			return err
-		}
-		if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil && err != ErrNil {
-			return err
-		}
-		return nil
-	}
-
-	// Don't sort map keys. It is not required by the spec, and C++ doesn't do it.
-	for _, key := range v.MapKeys() {
-		val := v.MapIndex(key)
-
-		keycopy.Set(key)
-		valcopy.Set(val)
-
-		o.buf = append(o.buf, p.tagcode...)
-		if err := o.enc_len_thing(enc, &state); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func size_new_map(p *Properties, base structPointer) int {
-	v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V
-
-	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
-
-	n := 0
-	for _, key := range v.MapKeys() {
-		val := v.MapIndex(key)
-		keycopy.Set(key)
-		valcopy.Set(val)
-
-		// Tag codes for key and val are the responsibility of the sub-sizer.
-		keysize := p.mkeyprop.size(p.mkeyprop, keybase)
-		valsize := p.mvalprop.size(p.mvalprop, valbase)
-		entry := keysize + valsize
-		// Add on tag code and length of map entry itself.
-		n += len(p.tagcode) + sizeVarint(uint64(entry)) + entry
-	}
-	return n
-}
-
-// mapEncodeScratch returns a new reflect.Value matching the map's value type,
-// and a structPointer suitable for passing to an encoder or sizer.
-func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) {
-	// Prepare addressable doubly-indirect placeholders for the key and value types.
-	// This is needed because the element-type encoders expect **T, but the map iteration produces T.
-
-	keycopy = reflect.New(mapType.Key()).Elem()                 // addressable K
-	keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K
-	keyptr.Set(keycopy.Addr())                                  //
-	keybase = toStructPointer(keyptr.Addr())                    // **K
-
-	// Value types are more varied and require special handling.
-	switch mapType.Elem().Kind() {
-	case reflect.Slice:
-		// []byte
-		var dummy []byte
-		valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte
-		valbase = toStructPointer(valcopy.Addr())
-	case reflect.Ptr:
-		// message; the generated field type is map[K]*Msg (so V is *Msg),
-		// so we only need one level of indirection.
-		valcopy = reflect.New(mapType.Elem()).Elem() // addressable V
-		valbase = toStructPointer(valcopy.Addr())
-	default:
-		// everything else
-		valcopy = reflect.New(mapType.Elem()).Elem()                // addressable V
-		valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V
-		valptr.Set(valcopy.Addr())                                  //
-		valbase = toStructPointer(valptr.Addr())                    // **V
-	}
-	return
-}
-
-// Encode a struct.
-func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
-	var state errorState
-	// Encode fields in tag order so that decoders may use optimizations
-	// that depend on the ordering.
-	// https://developers.google.com/protocol-buffers/docs/encoding#order
-	for _, i := range prop.order {
-		p := prop.Prop[i]
-		if p.enc != nil {
-			err := p.enc(o, p, base)
-			if err != nil {
-				if err == ErrNil {
-					if p.Required && state.err == nil {
-						state.err = &RequiredNotSetError{p.Name}
-					}
-				} else if err == errRepeatedHasNil {
-					// Give more context to nil values in repeated fields.
-					return errors.New("repeated field " + p.OrigName + " has nil element")
-				} else if !state.shouldContinue(err, p) {
-					return err
-				}
-			}
-			if len(o.buf) > maxMarshalSize {
-				return ErrTooLarge
-			}
-		}
-	}
-
-	// Do oneof fields.
-	if prop.oneofMarshaler != nil {
-		m := structPointer_Interface(base, prop.stype).(Message)
-		if err := prop.oneofMarshaler(m, o); err == ErrNil {
-			return errOneofHasNil
-		} else if err != nil {
-			return err
-		}
-	}
-
-	// Add unrecognized fields at the end.
-	if prop.unrecField.IsValid() {
-		v := *structPointer_Bytes(base, prop.unrecField)
-		if len(o.buf)+len(v) > maxMarshalSize {
-			return ErrTooLarge
-		}
-		if len(v) > 0 {
-			o.buf = append(o.buf, v...)
-		}
-	}
-
-	return state.err
-}
-
-func size_struct(prop *StructProperties, base structPointer) (n int) {
-	for _, i := range prop.order {
-		p := prop.Prop[i]
-		if p.size != nil {
-			n += p.size(p, base)
-		}
-	}
-
-	// Add unrecognized fields at the end.
-	if prop.unrecField.IsValid() {
-		v := *structPointer_Bytes(base, prop.unrecField)
-		n += len(v)
-	}
-
-	// Factor in any oneof fields.
-	if prop.oneofSizer != nil {
-		m := structPointer_Interface(base, prop.stype).(Message)
-		n += prop.oneofSizer(m)
-	}
-
-	return
-}
-
-var zeroes [20]byte // longer than any conceivable sizeVarint
-
-// Encode a struct, preceded by its encoded length (as a varint).
-func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
-	return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state)
-}
-
-// Encode something, preceded by its encoded length (as a varint).
-func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error {
-	iLen := len(o.buf)
-	o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
-	iMsg := len(o.buf)
-	err := enc()
-	if err != nil && !state.shouldContinue(err, nil) {
-		return err
-	}
-	lMsg := len(o.buf) - iMsg
-	lLen := sizeVarint(uint64(lMsg))
-	switch x := lLen - (iMsg - iLen); {
-	case x > 0: // actual length is x bytes larger than the space we reserved
-		// Move msg x bytes right.
-		o.buf = append(o.buf, zeroes[:x]...)
-		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
-	case x < 0: // actual length is x bytes smaller than the space we reserved
-		// Move msg x bytes left.
-		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
-		o.buf = o.buf[:len(o.buf)+x] // x is negative
-	}
-	// Encode the length in the reserved space.
-	o.buf = o.buf[:iLen]
-	o.EncodeVarint(uint64(lMsg))
-	o.buf = o.buf[:len(o.buf)+lMsg]
-	return state.err
-}
-
-// errorState maintains the first error that occurs and updates that error
-// with additional context.
-type errorState struct {
-	err error
-}
-
-// shouldContinue reports whether encoding should continue upon encountering the
-// given error. If the error is RequiredNotSetError, shouldContinue returns true
-// and, if this is the first appearance of that error, remembers it for future
-// reporting.
-//
-// If prop is not nil, it may update any error with additional context about the
-// field with the error.
-func (s *errorState) shouldContinue(err error, prop *Properties) bool {
-	// Ignore unset required fields.
-	reqNotSet, ok := err.(*RequiredNotSetError)
-	if !ok {
-		return false
-	}
-	if s.err == nil {
-		if prop != nil {
-			err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field}
-		}
-		s.err = err
-	}
-	return true
-}
diff --git a/proto/equal.go b/proto/equal.go
index 2ed1cf5..d4db5a1 100644
--- a/proto/equal.go
+++ b/proto/equal.go
@@ -109,15 +109,6 @@
 				// set/unset mismatch
 				return false
 			}
-			b1, ok := f1.Interface().(raw)
-			if ok {
-				b2 := f2.Interface().(raw)
-				// RawMessage
-				if !bytes.Equal(b1.Bytes(), b2.Bytes()) {
-					return false
-				}
-				continue
-			}
 			f1, f2 = f1.Elem(), f2.Elem()
 		}
 		if !equalAny(f1, f2, sprop.Prop[i]) {
@@ -146,11 +137,7 @@
 
 	u1 := uf.Bytes()
 	u2 := v2.FieldByName("XXX_unrecognized").Bytes()
-	if !bytes.Equal(u1, u2) {
-		return false
-	}
-
-	return true
+	return bytes.Equal(u1, u2)
 }
 
 // v1 and v2 are known to have the same type.
@@ -261,6 +248,15 @@
 
 		m1, m2 := e1.value, e2.value
 
+		if m1 == nil && m2 == nil {
+			// Both have only encoded form.
+			if bytes.Equal(e1.enc, e2.enc) {
+				continue
+			}
+			// The bytes are different, but the extensions might still be
+			// equal. We need to decode them to compare.
+		}
+
 		if m1 != nil && m2 != nil {
 			// Both are unencoded.
 			if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
@@ -276,8 +272,12 @@
 			desc = m[extNum]
 		}
 		if desc == nil {
+			// If both have only encoded form and the bytes are the same,
+			// it is handled above. We get here when the bytes are different.
+			// We don't know how to decode it, so just compare them as byte
+			// slices.
 			log.Printf("proto: don't know how to compare extension %d of %v", extNum, base)
-			continue
+			return false
 		}
 		var err error
 		if m1 == nil {
diff --git a/proto/equal_test.go b/proto/equal_test.go
index a2febb3..93ff88f 100644
--- a/proto/equal_test.go
+++ b/proto/equal_test.go
@@ -36,7 +36,7 @@
 
 	. "github.com/golang/protobuf/proto"
 	proto3pb "github.com/golang/protobuf/proto/proto3_proto"
-	pb "github.com/golang/protobuf/proto/testdata"
+	pb "github.com/golang/protobuf/proto/test_proto"
 )
 
 // Four identical base messages.
@@ -45,6 +45,9 @@
 var messageWithExtension1a = &pb.MyMessage{Count: Int32(7)}
 var messageWithExtension1b = &pb.MyMessage{Count: Int32(7)}
 var messageWithExtension2 = &pb.MyMessage{Count: Int32(7)}
+var messageWithExtension3a = &pb.MyMessage{Count: Int32(7)}
+var messageWithExtension3b = &pb.MyMessage{Count: Int32(7)}
+var messageWithExtension3c = &pb.MyMessage{Count: Int32(7)}
 
 // Two messages with non-message extensions.
 var messageWithInt32Extension1 = &pb.MyMessage{Count: Int32(8)}
@@ -83,6 +86,20 @@
 	if err := SetExtension(messageWithInt32Extension1, pb.E_Ext_Number, Int32(24)); err != nil {
 		panic("SetExtension on Int32-2 failed: " + err.Error())
 	}
+
+	// messageWithExtension3{a,b,c} has unregistered extension.
+	if RegisteredExtensions(messageWithExtension3a)[200] != nil {
+		panic("expect extension 200 unregistered")
+	}
+	bytes := []byte{
+		0xc0, 0x0c, 0x01, // id=200, wiretype=0 (varint), data=1
+	}
+	bytes2 := []byte{
+		0xc0, 0x0c, 0x02, // id=200, wiretype=0 (varint), data=2
+	}
+	SetRawExtension(messageWithExtension3a, 200, bytes)
+	SetRawExtension(messageWithExtension3b, 200, bytes)
+	SetRawExtension(messageWithExtension3c, 200, bytes2)
 }
 
 var EqualTests = []struct {
@@ -142,6 +159,9 @@
 	{"int32 extension vs. itself", messageWithInt32Extension1, messageWithInt32Extension1, true},
 	{"int32 extension vs. a different int32", messageWithInt32Extension1, messageWithInt32Extension2, false},
 
+	{"unregistered extension same", messageWithExtension3a, messageWithExtension3b, true},
+	{"unregistered extension different", messageWithExtension3a, messageWithExtension3c, false},
+
 	{
 		"message with group",
 		&pb.MyMessage{
diff --git a/proto/extensions.go b/proto/extensions.go
index eaad218..816a3b9 100644
--- a/proto/extensions.go
+++ b/proto/extensions.go
@@ -38,6 +38,7 @@
 import (
 	"errors"
 	"fmt"
+	"io"
 	"reflect"
 	"strconv"
 	"sync"
@@ -91,14 +92,29 @@
 // extendable returns the extendableProto interface for the given generated proto message.
 // If the proto message has the old extension format, it returns a wrapper that implements
 // the extendableProto interface.
-func extendable(p interface{}) (extendableProto, bool) {
-	if ep, ok := p.(extendableProto); ok {
-		return ep, ok
+func extendable(p interface{}) (extendableProto, error) {
+	switch p := p.(type) {
+	case extendableProto:
+		if isNilPtr(p) {
+			return nil, fmt.Errorf("proto: nil %T is not extendable", p)
+		}
+		return p, nil
+	case extendableProtoV1:
+		if isNilPtr(p) {
+			return nil, fmt.Errorf("proto: nil %T is not extendable", p)
+		}
+		return extensionAdapter{p}, nil
 	}
-	if ep, ok := p.(extendableProtoV1); ok {
-		return extensionAdapter{ep}, ok
-	}
-	return nil, false
+	// Don't allocate a specific error containing %T:
+	// this is the hot path for Clone and MarshalText.
+	return nil, errNotExtendable
+}
+
+var errNotExtendable = errors.New("proto: not an extendable proto.Message")
+
+func isNilPtr(x interface{}) bool {
+	v := reflect.ValueOf(x)
+	return v.Kind() == reflect.Ptr && v.IsNil()
 }
 
 // XXX_InternalExtensions is an internal representation of proto extensions.
@@ -143,9 +159,6 @@
 	return e.p.extensionMap, &e.p.mu
 }
 
-var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
-var extendableProtoV1Type = reflect.TypeOf((*extendableProtoV1)(nil)).Elem()
-
 // ExtensionDesc represents an extension specification.
 // Used in generated code from the protocol compiler.
 type ExtensionDesc struct {
@@ -179,8 +192,8 @@
 
 // SetRawExtension is for testing only.
 func SetRawExtension(base Message, id int32, b []byte) {
-	epb, ok := extendable(base)
-	if !ok {
+	epb, err := extendable(base)
+	if err != nil {
 		return
 	}
 	extmap := epb.extensionsWrite()
@@ -205,7 +218,7 @@
 		pbi = ea.extendableProtoV1
 	}
 	if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
-		return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
+		return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a)
 	}
 	// Check the range.
 	if !isExtensionField(pb, extension.Field) {
@@ -250,85 +263,11 @@
 	return prop
 }
 
-// encode encodes any unmarshaled (unencoded) extensions in e.
-func encodeExtensions(e *XXX_InternalExtensions) error {
-	m, mu := e.extensionsRead()
-	if m == nil {
-		return nil // fast path
-	}
-	mu.Lock()
-	defer mu.Unlock()
-	return encodeExtensionsMap(m)
-}
-
-// encode encodes any unmarshaled (unencoded) extensions in e.
-func encodeExtensionsMap(m map[int32]Extension) error {
-	for k, e := range m {
-		if e.value == nil || e.desc == nil {
-			// Extension is only in its encoded form.
-			continue
-		}
-
-		// We don't skip extensions that have an encoded form set,
-		// because the extension value may have been mutated after
-		// the last time this function was called.
-
-		et := reflect.TypeOf(e.desc.ExtensionType)
-		props := extensionProperties(e.desc)
-
-		p := NewBuffer(nil)
-		// If e.value has type T, the encoder expects a *struct{ X T }.
-		// Pass a *T with a zero field and hope it all works out.
-		x := reflect.New(et)
-		x.Elem().Set(reflect.ValueOf(e.value))
-		if err := props.enc(p, props, toStructPointer(x)); err != nil {
-			return err
-		}
-		e.enc = p.buf
-		m[k] = e
-	}
-	return nil
-}
-
-func extensionsSize(e *XXX_InternalExtensions) (n int) {
-	m, mu := e.extensionsRead()
-	if m == nil {
-		return 0
-	}
-	mu.Lock()
-	defer mu.Unlock()
-	return extensionsMapSize(m)
-}
-
-func extensionsMapSize(m map[int32]Extension) (n int) {
-	for _, e := range m {
-		if e.value == nil || e.desc == nil {
-			// Extension is only in its encoded form.
-			n += len(e.enc)
-			continue
-		}
-
-		// We don't skip extensions that have an encoded form set,
-		// because the extension value may have been mutated after
-		// the last time this function was called.
-
-		et := reflect.TypeOf(e.desc.ExtensionType)
-		props := extensionProperties(e.desc)
-
-		// If e.value has type T, the encoder expects a *struct{ X T }.
-		// Pass a *T with a zero field and hope it all works out.
-		x := reflect.New(et)
-		x.Elem().Set(reflect.ValueOf(e.value))
-		n += props.size(props, toStructPointer(x))
-	}
-	return
-}
-
 // HasExtension returns whether the given extension is present in pb.
 func HasExtension(pb Message, extension *ExtensionDesc) bool {
 	// TODO: Check types, field numbers, etc.?
-	epb, ok := extendable(pb)
-	if !ok {
+	epb, err := extendable(pb)
+	if err != nil {
 		return false
 	}
 	extmap, mu := epb.extensionsRead()
@@ -336,15 +275,15 @@
 		return false
 	}
 	mu.Lock()
-	_, ok = extmap[extension.Field]
+	_, ok := extmap[extension.Field]
 	mu.Unlock()
 	return ok
 }
 
 // ClearExtension removes the given extension from pb.
 func ClearExtension(pb Message, extension *ExtensionDesc) {
-	epb, ok := extendable(pb)
-	if !ok {
+	epb, err := extendable(pb)
+	if err != nil {
 		return
 	}
 	// TODO: Check types, field numbers, etc.?
@@ -352,16 +291,26 @@
 	delete(extmap, extension.Field)
 }
 
-// GetExtension parses and returns the given extension of pb.
-// If the extension is not present and has no default value it returns ErrMissingExtension.
+// GetExtension retrieves a proto2 extended field from pb.
+//
+// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
+// then GetExtension parses the encoded field and returns a Go value of the specified type.
+// If the field is not present, then the default value is returned (if one is specified),
+// otherwise ErrMissingExtension is reported.
+//
+// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil),
+// then GetExtension returns the raw encoded bytes of the field extension.
 func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
-	epb, ok := extendable(pb)
-	if !ok {
-		return nil, errors.New("proto: not an extendable proto")
+	epb, err := extendable(pb)
+	if err != nil {
+		return nil, err
 	}
 
-	if err := checkExtensionTypes(epb, extension); err != nil {
-		return nil, err
+	if extension.ExtendedType != nil {
+		// can only check type if this is a complete descriptor
+		if err := checkExtensionTypes(epb, extension); err != nil {
+			return nil, err
+		}
 	}
 
 	emap, mu := epb.extensionsRead()
@@ -388,6 +337,11 @@
 		return e.value, nil
 	}
 
+	if extension.ExtensionType == nil {
+		// incomplete descriptor
+		return e.enc, nil
+	}
+
 	v, err := decodeExtension(e.enc, extension)
 	if err != nil {
 		return nil, err
@@ -405,6 +359,11 @@
 // defaultExtensionValue returns the default value for extension.
 // If no default for an extension is defined ErrMissingExtension is returned.
 func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
+	if extension.ExtensionType == nil {
+		// incomplete descriptor, so no default
+		return nil, ErrMissingExtension
+	}
+
 	t := reflect.TypeOf(extension.ExtensionType)
 	props := extensionProperties(extension)
 
@@ -439,31 +398,28 @@
 
 // decodeExtension decodes an extension encoded in b.
 func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
-	o := NewBuffer(b)
-
 	t := reflect.TypeOf(extension.ExtensionType)
-
-	props := extensionProperties(extension)
+	unmarshal := typeUnmarshaler(t, extension.Tag)
 
 	// t is a pointer to a struct, pointer to basic type or a slice.
-	// Allocate a "field" to store the pointer/slice itself; the
-	// pointer/slice will be stored here. We pass
-	// the address of this field to props.dec.
-	// This passes a zero field and a *t and lets props.dec
-	// interpret it as a *struct{ x t }.
+	// Allocate space to store the pointer/slice.
 	value := reflect.New(t).Elem()
 
+	var err error
 	for {
-		// Discard wire type and field number varint. It isn't needed.
-		if _, err := o.DecodeVarint(); err != nil {
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		wire := int(x) & 7
+
+		b, err = unmarshal(b, valToPointer(value.Addr()), wire)
+		if err != nil {
 			return nil, err
 		}
 
-		if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil {
-			return nil, err
-		}
-
-		if o.index >= len(o.buf) {
+		if len(b) == 0 {
 			break
 		}
 	}
@@ -473,9 +429,9 @@
 // GetExtensions returns a slice of the extensions present in pb that are also listed in es.
 // The returned slice has the same length as es; missing extensions will appear as nil elements.
 func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
-	epb, ok := extendable(pb)
-	if !ok {
-		return nil, errors.New("proto: not an extendable proto")
+	epb, err := extendable(pb)
+	if err != nil {
+		return nil, err
 	}
 	extensions = make([]interface{}, len(es))
 	for i, e := range es {
@@ -494,9 +450,9 @@
 // For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
 // just the Field field, which defines the extension's field number.
 func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
-	epb, ok := extendable(pb)
-	if !ok {
-		return nil, fmt.Errorf("proto: %T is not an extendable proto.Message", pb)
+	epb, err := extendable(pb)
+	if err != nil {
+		return nil, err
 	}
 	registeredExtensions := RegisteredExtensions(pb)
 
@@ -523,9 +479,9 @@
 
 // SetExtension sets the specified extension of pb to the specified value.
 func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
-	epb, ok := extendable(pb)
-	if !ok {
-		return errors.New("proto: not an extendable proto")
+	epb, err := extendable(pb)
+	if err != nil {
+		return err
 	}
 	if err := checkExtensionTypes(epb, extension); err != nil {
 		return err
@@ -550,8 +506,8 @@
 
 // ClearAllExtensions clears all extensions from pb.
 func ClearAllExtensions(pb Message) {
-	epb, ok := extendable(pb)
-	if !ok {
+	epb, err := extendable(pb)
+	if err != nil {
 		return
 	}
 	m := epb.extensionsWrite()
diff --git a/proto/extensions_test.go b/proto/extensions_test.go
index a255030..dc69fe9 100644
--- a/proto/extensions_test.go
+++ b/proto/extensions_test.go
@@ -34,12 +34,14 @@
 import (
 	"bytes"
 	"fmt"
+	"io"
 	"reflect"
 	"sort"
+	"strings"
 	"testing"
 
 	"github.com/golang/protobuf/proto"
-	pb "github.com/golang/protobuf/proto/testdata"
+	pb "github.com/golang/protobuf/proto/test_proto"
 	"golang.org/x/sync/errgroup"
 )
 
@@ -64,7 +66,107 @@
 	}
 }
 
-func TestExtensionDescsWithMissingExtensions(t *testing.T) {
+func TestGetExtensionWithEmptyBuffer(t *testing.T) {
+	// Make sure that GetExtension returns an error if its
+	// undecoded buffer is empty.
+	msg := &pb.MyMessage{}
+	proto.SetRawExtension(msg, pb.E_Ext_More.Field, []byte{})
+	_, err := proto.GetExtension(msg, pb.E_Ext_More)
+	if want := io.ErrUnexpectedEOF; err != want {
+		t.Errorf("unexpected error in GetExtension from empty buffer: got %v, want %v", err, want)
+	}
+}
+
+func TestGetExtensionForIncompleteDesc(t *testing.T) {
+	msg := &pb.MyMessage{Count: proto.Int32(0)}
+	extdesc1 := &proto.ExtensionDesc{
+		ExtendedType:  (*pb.MyMessage)(nil),
+		ExtensionType: (*bool)(nil),
+		Field:         123456789,
+		Name:          "a.b",
+		Tag:           "varint,123456789,opt",
+	}
+	ext1 := proto.Bool(true)
+	if err := proto.SetExtension(msg, extdesc1, ext1); err != nil {
+		t.Fatalf("Could not set ext1: %s", err)
+	}
+	extdesc2 := &proto.ExtensionDesc{
+		ExtendedType:  (*pb.MyMessage)(nil),
+		ExtensionType: ([]byte)(nil),
+		Field:         123456790,
+		Name:          "a.c",
+		Tag:           "bytes,123456790,opt",
+	}
+	ext2 := []byte{0, 1, 2, 3, 4, 5, 6, 7}
+	if err := proto.SetExtension(msg, extdesc2, ext2); err != nil {
+		t.Fatalf("Could not set ext2: %s", err)
+	}
+	extdesc3 := &proto.ExtensionDesc{
+		ExtendedType:  (*pb.MyMessage)(nil),
+		ExtensionType: (*pb.Ext)(nil),
+		Field:         123456791,
+		Name:          "a.d",
+		Tag:           "bytes,123456791,opt",
+	}
+	ext3 := &pb.Ext{Data: proto.String("foo")}
+	if err := proto.SetExtension(msg, extdesc3, ext3); err != nil {
+		t.Fatalf("Could not set ext3: %s", err)
+	}
+
+	b, err := proto.Marshal(msg)
+	if err != nil {
+		t.Fatalf("Could not marshal msg: %v", err)
+	}
+	if err := proto.Unmarshal(b, msg); err != nil {
+		t.Fatalf("Could not unmarshal into msg: %v", err)
+	}
+
+	var expected proto.Buffer
+	if err := expected.EncodeVarint(uint64((extdesc1.Field << 3) | proto.WireVarint)); err != nil {
+		t.Fatalf("failed to compute expected prefix for ext1: %s", err)
+	}
+	if err := expected.EncodeVarint(1 /* bool true */); err != nil {
+		t.Fatalf("failed to compute expected value for ext1: %s", err)
+	}
+
+	if b, err := proto.GetExtension(msg, &proto.ExtensionDesc{Field: extdesc1.Field}); err != nil {
+		t.Fatalf("Failed to get raw value for ext1: %s", err)
+	} else if !reflect.DeepEqual(b, expected.Bytes()) {
+		t.Fatalf("Raw value for ext1: got %v, want %v", b, expected.Bytes())
+	}
+
+	expected = proto.Buffer{} // reset
+	if err := expected.EncodeVarint(uint64((extdesc2.Field << 3) | proto.WireBytes)); err != nil {
+		t.Fatalf("failed to compute expected prefix for ext2: %s", err)
+	}
+	if err := expected.EncodeRawBytes(ext2); err != nil {
+		t.Fatalf("failed to compute expected value for ext2: %s", err)
+	}
+
+	if b, err := proto.GetExtension(msg, &proto.ExtensionDesc{Field: extdesc2.Field}); err != nil {
+		t.Fatalf("Failed to get raw value for ext2: %s", err)
+	} else if !reflect.DeepEqual(b, expected.Bytes()) {
+		t.Fatalf("Raw value for ext2: got %v, want %v", b, expected.Bytes())
+	}
+
+	expected = proto.Buffer{} // reset
+	if err := expected.EncodeVarint(uint64((extdesc3.Field << 3) | proto.WireBytes)); err != nil {
+		t.Fatalf("failed to compute expected prefix for ext3: %s", err)
+	}
+	if b, err := proto.Marshal(ext3); err != nil {
+		t.Fatalf("failed to compute expected value for ext3: %s", err)
+	} else if err := expected.EncodeRawBytes(b); err != nil {
+		t.Fatalf("failed to compute expected value for ext3: %s", err)
+	}
+
+	if b, err := proto.GetExtension(msg, &proto.ExtensionDesc{Field: extdesc3.Field}); err != nil {
+		t.Fatalf("Failed to get raw value for ext3: %s", err)
+	} else if !reflect.DeepEqual(b, expected.Bytes()) {
+		t.Fatalf("Raw value for ext3: got %v, want %v", b, expected.Bytes())
+	}
+}
+
+func TestExtensionDescsWithUnregisteredExtensions(t *testing.T) {
 	msg := &pb.MyMessage{Count: proto.Int32(0)}
 	extdesc1 := pb.E_Ext_More
 	if descs, err := proto.ExtensionDescs(msg); len(descs) != 0 || err != nil {
@@ -100,7 +202,7 @@
 		t.Fatalf("proto.ExtensionDescs: got error %v", err)
 	}
 	sortExtDescs(descs)
-	wantDescs := []*proto.ExtensionDesc{extdesc1, &proto.ExtensionDesc{Field: extdesc2.Field}}
+	wantDescs := []*proto.ExtensionDesc{extdesc1, {Field: extdesc2.Field}}
 	if !reflect.DeepEqual(descs, wantDescs) {
 		t.Errorf("proto.ExtensionDescs(msg) sorted extension ids: got %+v, want %+v", descs, wantDescs)
 	}
@@ -200,7 +302,7 @@
 		{pb.E_DefaultSfixed64, setInt64, int64(51)},
 		{pb.E_DefaultBool, setBool, true},
 		{pb.E_DefaultBool, setBool2, true},
-		{pb.E_DefaultString, setString, "Hello, string"},
+		{pb.E_DefaultString, setString, "Hello, string,def=foo"},
 		{pb.E_DefaultBytes, setBytes, []byte("Hello, bytes")},
 		{pb.E_DefaultEnum, setEnum, pb.DefaultsMessage_ONE},
 	}
@@ -287,6 +389,44 @@
 	}
 }
 
+func TestNilMessage(t *testing.T) {
+	name := "nil interface"
+	if got, err := proto.GetExtension(nil, pb.E_Ext_More); err == nil {
+		t.Errorf("%s: got %T %v, expected to fail", name, got, got)
+	} else if !strings.Contains(err.Error(), "extendable") {
+		t.Errorf("%s: got error %v, expected not-extendable error", name, err)
+	}
+
+	// Regression tests: all functions of the Extension API
+	// used to panic when passed (*M)(nil), where M is a concrete message
+	// type.  Now they handle this gracefully as a no-op or reported error.
+	var nilMsg *pb.MyMessage
+	desc := pb.E_Ext_More
+
+	isNotExtendable := func(err error) bool {
+		return strings.Contains(fmt.Sprint(err), "not extendable")
+	}
+
+	if proto.HasExtension(nilMsg, desc) {
+		t.Error("HasExtension(nil) = true")
+	}
+
+	if _, err := proto.GetExtensions(nilMsg, []*proto.ExtensionDesc{desc}); !isNotExtendable(err) {
+		t.Errorf("GetExtensions(nil) = %q (wrong error)", err)
+	}
+
+	if _, err := proto.ExtensionDescs(nilMsg); !isNotExtendable(err) {
+		t.Errorf("ExtensionDescs(nil) = %q (wrong error)", err)
+	}
+
+	if err := proto.SetExtension(nilMsg, desc, nil); !isNotExtendable(err) {
+		t.Errorf("SetExtension(nil) = %q (wrong error)", err)
+	}
+
+	proto.ClearExtension(nilMsg, desc) // no-op
+	proto.ClearAllExtensions(nilMsg)   // no-op
+}
+
 func TestExtensionsRoundTrip(t *testing.T) {
 	msg := &pb.MyMessage{}
 	ext1 := &pb.Ext{
@@ -311,7 +451,7 @@
 	}
 	x, ok := e.(*pb.Ext)
 	if !ok {
-		t.Errorf("e has type %T, expected testdata.Ext", e)
+		t.Errorf("e has type %T, expected test_proto.Ext", e)
 	} else if *x.Data != "there" {
 		t.Errorf("SetExtension failed to overwrite, got %+v, not 'there'", x)
 	}
@@ -339,7 +479,7 @@
 	}
 	if err := proto.SetExtension(msg, pb.E_Ext_More, (*pb.Ext)(nil)); err == nil {
 		t.Error("expected SetExtension to fail due to a nil extension")
-	} else if want := "proto: SetExtension called with nil value of type *testdata.Ext"; err.Error() != want {
+	} else if want := fmt.Sprintf("proto: SetExtension called with nil value of type %T", new(pb.Ext)); err.Error() != want {
 		t.Errorf("expected error %v, got %v", want, err)
 	}
 	// Note: if the behavior of Marshal is ever changed to ignore nil extensions, update
@@ -402,8 +542,13 @@
 		if ext == nil {
 			t.Fatalf("[%s] Invalid extension", test.name)
 		}
-		if !reflect.DeepEqual(ext, test.ext) {
-			t.Errorf("[%s] Wrong value for ComplexExtension: got: %v want: %v\n", test.name, ext, test.ext)
+		if len(ext) != len(test.ext) {
+			t.Errorf("[%s] Wrong length of ComplexExtension: got: %v want: %v\n", test.name, len(ext), len(test.ext))
+		}
+		for i := range test.ext {
+			if !proto.Equal(ext[i], test.ext[i]) {
+				t.Errorf("[%s] Wrong value for ComplexExtension[%d]: got: %v want: %v\n", test.name, i, ext[i], test.ext[i])
+			}
 		}
 	}
 }
@@ -477,7 +622,7 @@
 		if ext == nil {
 			t.Fatalf("[%s] Invalid extension", test.name)
 		}
-		if !reflect.DeepEqual(*ext, want) {
+		if !proto.Equal(ext, &want) {
 			t.Errorf("[%s] Wrong value for ComplexExtension: got: %s want: %s\n", test.name, ext, &want)
 		}
 	}
@@ -509,19 +654,22 @@
 }
 
 func TestMarshalRace(t *testing.T) {
-	// unregistered extension
-	desc := &proto.ExtensionDesc{
-		ExtendedType:  (*pb.MyMessage)(nil),
-		ExtensionType: (*bool)(nil),
-		Field:         101010100,
-		Name:          "emptyextension",
-		Tag:           "varint,0,opt",
+	ext := &pb.Ext{}
+	m := &pb.MyMessage{Count: proto.Int32(4)}
+	if err := proto.SetExtension(m, pb.E_Ext_More, ext); err != nil {
+		t.Fatalf("proto.SetExtension(m, desc, true): got error %q, want nil", err)
 	}
 
-	m := &pb.MyMessage{Count: proto.Int32(4)}
-	if err := proto.SetExtension(m, desc, proto.Bool(true)); err != nil {
-		t.Errorf("proto.SetExtension(m, desc, true): got error %q, want nil", err)
+	b, err := proto.Marshal(m)
+	if err != nil {
+		t.Fatalf("Could not marshal message: %v", err)
 	}
+	if err := proto.Unmarshal(b, m); err != nil {
+		t.Fatalf("Could not unmarshal message: %v", err)
+	}
+	// after Unmarshal, the extension is in undecoded form.
+	// GetExtension will decode it lazily. Make sure this does
+	// not race against Marshal.
 
 	var g errgroup.Group
 	for n := 3; n > 0; n-- {
@@ -529,6 +677,10 @@
 			_, err := proto.Marshal(m)
 			return err
 		})
+		g.Go(func() error {
+			_, err := proto.GetExtension(m, pb.E_Ext_More)
+			return err
+		})
 	}
 	if err := g.Wait(); err != nil {
 		t.Fatal(err)
diff --git a/proto/lib.go b/proto/lib.go
index 1c22550..0e2191b 100644
--- a/proto/lib.go
+++ b/proto/lib.go
@@ -265,6 +265,7 @@
 
 import (
 	"encoding/json"
+	"errors"
 	"fmt"
 	"log"
 	"reflect"
@@ -273,6 +274,8 @@
 	"sync"
 )
 
+var errInvalidUTF8 = errors.New("proto: invalid UTF-8 string")
+
 // Message is implemented by generated protocol buffer messages.
 type Message interface {
 	Reset()
@@ -309,16 +312,7 @@
 	buf   []byte // encode/decode byte stream
 	index int    // read point
 
-	// pools of basic types to amortize allocation.
-	bools   []bool
-	uint32s []uint32
-	uint64s []uint64
-
-	// extra pools, only used with pointer_reflect.go
-	int32s   []int32
-	int64s   []int64
-	float32s []float32
-	float64s []float64
+	deterministic bool
 }
 
 // NewBuffer allocates a new Buffer and initializes its internal data to
@@ -343,6 +337,30 @@
 // Bytes returns the contents of the Buffer.
 func (p *Buffer) Bytes() []byte { return p.buf }
 
+// SetDeterministic sets whether to use deterministic serialization.
+//
+// Deterministic serialization guarantees that for a given binary, equal
+// messages will always be serialized to the same bytes. This implies:
+//
+//   - Repeated serialization of a message will return the same bytes.
+//   - Different processes of the same binary (which may be executing on
+//     different machines) will serialize equal messages to the same bytes.
+//
+// Note that the deterministic serialization is NOT canonical across
+// languages. It is not guaranteed to remain stable over time. It is unstable
+// across different builds with schema changes due to unknown fields.
+// Users who need canonical serialization (e.g., persistent storage in a
+// canonical form, fingerprinting, etc.) should define their own
+// canonicalization specification and implement their own serializer rather
+// than relying on this API.
+//
+// If deterministic serialization is requested, map entries will be sorted
+// by keys in lexographical order. This is an implementation detail and
+// subject to change.
+func (p *Buffer) SetDeterministic(deterministic bool) {
+	p.deterministic = deterministic
+}
+
 /*
  * Helper routines for simplifying the creation of optional fields of basic type.
  */
@@ -831,22 +849,12 @@
 	return sf, false, nil
 }
 
+// mapKeys returns a sort.Interface to be used for sorting the map keys.
 // Map fields may have key types of non-float scalars, strings and enums.
-// The easiest way to sort them in some deterministic order is to use fmt.
-// If this turns out to be inefficient we can always consider other options,
-// such as doing a Schwartzian transform.
-
 func mapKeys(vs []reflect.Value) sort.Interface {
-	s := mapKeySorter{
-		vs: vs,
-		// default Less function: textual comparison
-		less: func(a, b reflect.Value) bool {
-			return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface())
-		},
-	}
+	s := mapKeySorter{vs: vs}
 
-	// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps;
-	// numeric keys are sorted numerically.
+	// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps.
 	if len(vs) == 0 {
 		return s
 	}
@@ -855,6 +863,12 @@
 		s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
 	case reflect.Uint32, reflect.Uint64:
 		s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
+	case reflect.Bool:
+		s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true
+	case reflect.String:
+		s.less = func(a, b reflect.Value) bool { return a.String() < b.String() }
+	default:
+		panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind()))
 	}
 
 	return s
@@ -895,3 +909,13 @@
 // ProtoPackageIsVersion1 is referenced from generated protocol buffer files
 // to assert that that code is compatible with this version of the proto package.
 const ProtoPackageIsVersion1 = true
+
+// InternalMessageInfo is a type used internally by generated .pb.go files.
+// This type is not intended to be used by non-generated code.
+// This type is not subject to any compatibility guarantee.
+type InternalMessageInfo struct {
+	marshal   *marshalInfo
+	unmarshal *unmarshalInfo
+	merge     *mergeInfo
+	discard   *discardInfo
+}
diff --git a/proto/map_test.go b/proto/map_test.go
index 313e879..b1e1529 100644
--- a/proto/map_test.go
+++ b/proto/map_test.go
@@ -2,12 +2,36 @@
 
 import (
 	"fmt"
+	"reflect"
 	"testing"
 
 	"github.com/golang/protobuf/proto"
 	ppb "github.com/golang/protobuf/proto/proto3_proto"
 )
 
+func TestMap(t *testing.T) {
+	var b []byte
+	fmt.Sscanf("a2010c0a044b657931120456616c31a201130a044b657932120556616c3261120456616c32a201240a044b6579330d05000000120556616c33621a0556616c3361120456616c331505000000a20100a201260a044b657934130a07536f6d6555524c1209536f6d655469746c651a08536e69707065743114", "%x", &b)
+
+	var m ppb.Message
+	if err := proto.Unmarshal(b, &m); err != nil {
+		t.Fatalf("proto.Unmarshal error: %v", err)
+	}
+
+	got := m.StringMap
+	want := map[string]string{
+		"":     "",
+		"Key1": "Val1",
+		"Key2": "Val2",
+		"Key3": "Val3",
+		"Key4": "",
+	}
+
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("maps differ:\ngot  %#v\nwant %#v", got, want)
+	}
+}
+
 func marshalled() []byte {
 	m := &ppb.IntMaps{}
 	for i := 0; i < 1000; i++ {
diff --git a/proto/message_set.go b/proto/message_set.go
index fd982de..3b6ca41 100644
--- a/proto/message_set.go
+++ b/proto/message_set.go
@@ -42,6 +42,7 @@
 	"fmt"
 	"reflect"
 	"sort"
+	"sync"
 )
 
 // errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
@@ -94,10 +95,7 @@
 }
 
 func (ms *messageSet) Has(pb Message) bool {
-	if ms.find(pb) != nil {
-		return true
-	}
-	return false
+	return ms.find(pb) != nil
 }
 
 func (ms *messageSet) Unmarshal(pb Message) error {
@@ -150,46 +148,42 @@
 // MarshalMessageSet encodes the extension map represented by m in the message set wire format.
 // It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
 func MarshalMessageSet(exts interface{}) ([]byte, error) {
-	var m map[int32]Extension
+	return marshalMessageSet(exts, false)
+}
+
+// marshaMessageSet implements above function, with the opt to turn on / off deterministic during Marshal.
+func marshalMessageSet(exts interface{}, deterministic bool) ([]byte, error) {
 	switch exts := exts.(type) {
 	case *XXX_InternalExtensions:
-		if err := encodeExtensions(exts); err != nil {
-			return nil, err
-		}
-		m, _ = exts.extensionsRead()
+		var u marshalInfo
+		siz := u.sizeMessageSet(exts)
+		b := make([]byte, 0, siz)
+		return u.appendMessageSet(b, exts, deterministic)
+
 	case map[int32]Extension:
-		if err := encodeExtensionsMap(exts); err != nil {
-			return nil, err
+		// This is an old-style extension map.
+		// Wrap it in a new-style XXX_InternalExtensions.
+		ie := XXX_InternalExtensions{
+			p: &struct {
+				mu           sync.Mutex
+				extensionMap map[int32]Extension
+			}{
+				extensionMap: exts,
+			},
 		}
-		m = exts
+
+		var u marshalInfo
+		siz := u.sizeMessageSet(&ie)
+		b := make([]byte, 0, siz)
+		return u.appendMessageSet(b, &ie, deterministic)
+
 	default:
 		return nil, errors.New("proto: not an extension map")
 	}
-
-	// Sort extension IDs to provide a deterministic encoding.
-	// See also enc_map in encode.go.
-	ids := make([]int, 0, len(m))
-	for id := range m {
-		ids = append(ids, int(id))
-	}
-	sort.Ints(ids)
-
-	ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
-	for _, id := range ids {
-		e := m[int32(id)]
-		// Remove the wire type and field number varint, as well as the length varint.
-		msg := skipVarint(skipVarint(e.enc))
-
-		ms.Item = append(ms.Item, &_MessageSet_Item{
-			TypeId:  Int32(int32(id)),
-			Message: msg,
-		})
-	}
-	return Marshal(ms)
 }
 
 // UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
-// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
+// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
 func UnmarshalMessageSet(buf []byte, exts interface{}) error {
 	var m map[int32]Extension
 	switch exts := exts.(type) {
@@ -235,7 +229,15 @@
 	var m map[int32]Extension
 	switch exts := exts.(type) {
 	case *XXX_InternalExtensions:
-		m, _ = exts.extensionsRead()
+		var mu sync.Locker
+		m, mu = exts.extensionsRead()
+		if m != nil {
+			// Keep the extensions map locked until we're done marshaling to prevent
+			// races between marshaling and unmarshaling the lazily-{en,de}coded
+			// values.
+			mu.Lock()
+			defer mu.Unlock()
+		}
 	case map[int32]Extension:
 		m = exts
 	default:
@@ -253,15 +255,16 @@
 
 	for i, id := range ids {
 		ext := m[id]
-		if i > 0 {
-			b.WriteByte(',')
-		}
-
 		msd, ok := messageSetMap[id]
 		if !ok {
 			// Unknown type; we can't render it, so skip it.
 			continue
 		}
+
+		if i > 0 && b.Len() > 1 {
+			b.WriteByte(',')
+		}
+
 		fmt.Fprintf(&b, `"[%s]":`, msd.name)
 
 		x := ext.value
diff --git a/proto/message_set_test.go b/proto/message_set_test.go
index 353a3ea..2c170c5 100644
--- a/proto/message_set_test.go
+++ b/proto/message_set_test.go
@@ -64,3 +64,14 @@
 		t.Errorf("Combined extension is %q, want %q", got, want)
 	}
 }
+
+func TestMarshalMessageSetJSON_UnknownType(t *testing.T) {
+	extMap := map[int32]Extension{12345: Extension{}}
+	got, err := MarshalMessageSetJSON(extMap)
+	if err != nil {
+		t.Fatalf("MarshalMessageSetJSON: %v", err)
+	}
+	if want := []byte("{}"); !bytes.Equal(got, want) {
+		t.Errorf("MarshalMessageSetJSON(%v) = %q, want %q", extMap, got, want)
+	}
+}
diff --git a/proto/pointer_reflect.go b/proto/pointer_reflect.go
index fb512e2..b6cad90 100644
--- a/proto/pointer_reflect.go
+++ b/proto/pointer_reflect.go
@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// +build appengine js
+// +build purego appengine js
 
 // This file contains an implementation of proto field accesses using package reflect.
 // It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
@@ -38,32 +38,13 @@
 package proto
 
 import (
-	"math"
 	"reflect"
+	"sync"
 )
 
-// A structPointer is a pointer to a struct.
-type structPointer struct {
-	v reflect.Value
-}
+const unsafeAllowed = false
 
-// toStructPointer returns a structPointer equivalent to the given reflect value.
-// The reflect value must itself be a pointer to a struct.
-func toStructPointer(v reflect.Value) structPointer {
-	return structPointer{v}
-}
-
-// IsNil reports whether p is nil.
-func structPointer_IsNil(p structPointer) bool {
-	return p.v.IsNil()
-}
-
-// Interface returns the struct pointer as an interface value.
-func structPointer_Interface(p structPointer, _ reflect.Type) interface{} {
-	return p.v.Interface()
-}
-
-// A field identifies a field in a struct, accessible from a structPointer.
+// A field identifies a field in a struct, accessible from a pointer.
 // In this implementation, a field is identified by the sequence of field indices
 // passed to reflect's FieldByIndex.
 type field []int
@@ -76,409 +57,301 @@
 // invalidField is an invalid field identifier.
 var invalidField = field(nil)
 
+// zeroField is a noop when calling pointer.offset.
+var zeroField = field([]int{})
+
 // IsValid reports whether the field identifier is valid.
 func (f field) IsValid() bool { return f != nil }
 
-// field returns the given field in the struct as a reflect value.
-func structPointer_field(p structPointer, f field) reflect.Value {
-	// Special case: an extension map entry with a value of type T
-	// passes a *T to the struct-handling code with a zero field,
-	// expecting that it will be treated as equivalent to *struct{ X T },
-	// which has the same memory layout. We have to handle that case
-	// specially, because reflect will panic if we call FieldByIndex on a
-	// non-struct.
-	if f == nil {
-		return p.v.Elem()
-	}
-
-	return p.v.Elem().FieldByIndex(f)
-}
-
-// ifield returns the given field in the struct as an interface value.
-func structPointer_ifield(p structPointer, f field) interface{} {
-	return structPointer_field(p, f).Addr().Interface()
-}
-
-// Bytes returns the address of a []byte field in the struct.
-func structPointer_Bytes(p structPointer, f field) *[]byte {
-	return structPointer_ifield(p, f).(*[]byte)
-}
-
-// BytesSlice returns the address of a [][]byte field in the struct.
-func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
-	return structPointer_ifield(p, f).(*[][]byte)
-}
-
-// Bool returns the address of a *bool field in the struct.
-func structPointer_Bool(p structPointer, f field) **bool {
-	return structPointer_ifield(p, f).(**bool)
-}
-
-// BoolVal returns the address of a bool field in the struct.
-func structPointer_BoolVal(p structPointer, f field) *bool {
-	return structPointer_ifield(p, f).(*bool)
-}
-
-// BoolSlice returns the address of a []bool field in the struct.
-func structPointer_BoolSlice(p structPointer, f field) *[]bool {
-	return structPointer_ifield(p, f).(*[]bool)
-}
-
-// String returns the address of a *string field in the struct.
-func structPointer_String(p structPointer, f field) **string {
-	return structPointer_ifield(p, f).(**string)
-}
-
-// StringVal returns the address of a string field in the struct.
-func structPointer_StringVal(p structPointer, f field) *string {
-	return structPointer_ifield(p, f).(*string)
-}
-
-// StringSlice returns the address of a []string field in the struct.
-func structPointer_StringSlice(p structPointer, f field) *[]string {
-	return structPointer_ifield(p, f).(*[]string)
-}
-
-// Extensions returns the address of an extension map field in the struct.
-func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
-	return structPointer_ifield(p, f).(*XXX_InternalExtensions)
-}
-
-// ExtMap returns the address of an extension map field in the struct.
-func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
-	return structPointer_ifield(p, f).(*map[int32]Extension)
-}
-
-// NewAt returns the reflect.Value for a pointer to a field in the struct.
-func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
-	return structPointer_field(p, f).Addr()
-}
-
-// SetStructPointer writes a *struct field in the struct.
-func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
-	structPointer_field(p, f).Set(q.v)
-}
-
-// GetStructPointer reads a *struct field in the struct.
-func structPointer_GetStructPointer(p structPointer, f field) structPointer {
-	return structPointer{structPointer_field(p, f)}
-}
-
-// StructPointerSlice the address of a []*struct field in the struct.
-func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice {
-	return structPointerSlice{structPointer_field(p, f)}
-}
-
-// A structPointerSlice represents the address of a slice of pointers to structs
-// (themselves messages or groups). That is, v.Type() is *[]*struct{...}.
-type structPointerSlice struct {
+// The pointer type is for the table-driven decoder.
+// The implementation here uses a reflect.Value of pointer type to
+// create a generic pointer. In pointer_unsafe.go we use unsafe
+// instead of reflect to implement the same (but faster) interface.
+type pointer struct {
 	v reflect.Value
 }
 
-func (p structPointerSlice) Len() int                  { return p.v.Len() }
-func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} }
-func (p structPointerSlice) Append(q structPointer) {
-	p.v.Set(reflect.Append(p.v, q.v))
+// toPointer converts an interface of pointer type to a pointer
+// that points to the same target.
+func toPointer(i *Message) pointer {
+	return pointer{v: reflect.ValueOf(*i)}
 }
 
-var (
-	int32Type   = reflect.TypeOf(int32(0))
-	uint32Type  = reflect.TypeOf(uint32(0))
-	float32Type = reflect.TypeOf(float32(0))
-	int64Type   = reflect.TypeOf(int64(0))
-	uint64Type  = reflect.TypeOf(uint64(0))
-	float64Type = reflect.TypeOf(float64(0))
-)
-
-// A word32 represents a field of type *int32, *uint32, *float32, or *enum.
-// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable.
-type word32 struct {
-	v reflect.Value
+// toAddrPointer converts an interface to a pointer that points to
+// the interface data.
+func toAddrPointer(i *interface{}, isptr bool) pointer {
+	v := reflect.ValueOf(*i)
+	u := reflect.New(v.Type())
+	u.Elem().Set(v)
+	return pointer{v: u}
 }
 
-// IsNil reports whether p is nil.
-func word32_IsNil(p word32) bool {
+// valToPointer converts v to a pointer.  v must be of pointer type.
+func valToPointer(v reflect.Value) pointer {
+	return pointer{v: v}
+}
+
+// offset converts from a pointer to a structure to a pointer to
+// one of its fields.
+func (p pointer) offset(f field) pointer {
+	return pointer{v: p.v.Elem().FieldByIndex(f).Addr()}
+}
+
+func (p pointer) isNil() bool {
 	return p.v.IsNil()
 }
 
-// Set sets p to point at a newly allocated word with bits set to x.
-func word32_Set(p word32, o *Buffer, x uint32) {
-	t := p.v.Type().Elem()
-	switch t {
-	case int32Type:
-		if len(o.int32s) == 0 {
-			o.int32s = make([]int32, uint32PoolSize)
-		}
-		o.int32s[0] = int32(x)
-		p.v.Set(reflect.ValueOf(&o.int32s[0]))
-		o.int32s = o.int32s[1:]
-		return
-	case uint32Type:
-		if len(o.uint32s) == 0 {
-			o.uint32s = make([]uint32, uint32PoolSize)
-		}
-		o.uint32s[0] = x
-		p.v.Set(reflect.ValueOf(&o.uint32s[0]))
-		o.uint32s = o.uint32s[1:]
-		return
-	case float32Type:
-		if len(o.float32s) == 0 {
-			o.float32s = make([]float32, uint32PoolSize)
-		}
-		o.float32s[0] = math.Float32frombits(x)
-		p.v.Set(reflect.ValueOf(&o.float32s[0]))
-		o.float32s = o.float32s[1:]
-		return
-	}
-
-	// must be enum
-	p.v.Set(reflect.New(t))
-	p.v.Elem().SetInt(int64(int32(x)))
-}
-
-// Get gets the bits pointed at by p, as a uint32.
-func word32_Get(p word32) uint32 {
-	elem := p.v.Elem()
-	switch elem.Kind() {
-	case reflect.Int32:
-		return uint32(elem.Int())
-	case reflect.Uint32:
-		return uint32(elem.Uint())
-	case reflect.Float32:
-		return math.Float32bits(float32(elem.Float()))
-	}
-	panic("unreachable")
-}
-
-// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct.
-func structPointer_Word32(p structPointer, f field) word32 {
-	return word32{structPointer_field(p, f)}
-}
-
-// A word32Val represents a field of type int32, uint32, float32, or enum.
-// That is, v.Type() is int32, uint32, float32, or enum and v is assignable.
-type word32Val struct {
-	v reflect.Value
-}
-
-// Set sets *p to x.
-func word32Val_Set(p word32Val, x uint32) {
-	switch p.v.Type() {
-	case int32Type:
-		p.v.SetInt(int64(x))
-		return
-	case uint32Type:
-		p.v.SetUint(uint64(x))
-		return
-	case float32Type:
-		p.v.SetFloat(float64(math.Float32frombits(x)))
-		return
-	}
-
-	// must be enum
-	p.v.SetInt(int64(int32(x)))
-}
-
-// Get gets the bits pointed at by p, as a uint32.
-func word32Val_Get(p word32Val) uint32 {
-	elem := p.v
-	switch elem.Kind() {
-	case reflect.Int32:
-		return uint32(elem.Int())
-	case reflect.Uint32:
-		return uint32(elem.Uint())
-	case reflect.Float32:
-		return math.Float32bits(float32(elem.Float()))
-	}
-	panic("unreachable")
-}
-
-// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
-func structPointer_Word32Val(p structPointer, f field) word32Val {
-	return word32Val{structPointer_field(p, f)}
-}
-
-// A word32Slice is a slice of 32-bit values.
-// That is, v.Type() is []int32, []uint32, []float32, or []enum.
-type word32Slice struct {
-	v reflect.Value
-}
-
-func (p word32Slice) Append(x uint32) {
-	n, m := p.v.Len(), p.v.Cap()
+// grow updates the slice s in place to make it one element longer.
+// s must be addressable.
+// Returns the (addressable) new element.
+func grow(s reflect.Value) reflect.Value {
+	n, m := s.Len(), s.Cap()
 	if n < m {
-		p.v.SetLen(n + 1)
+		s.SetLen(n + 1)
 	} else {
-		t := p.v.Type().Elem()
-		p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
+		s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem())))
 	}
-	elem := p.v.Index(n)
-	switch elem.Kind() {
-	case reflect.Int32:
-		elem.SetInt(int64(int32(x)))
-	case reflect.Uint32:
-		elem.SetUint(uint64(x))
-	case reflect.Float32:
-		elem.SetFloat(float64(math.Float32frombits(x)))
+	return s.Index(n)
+}
+
+func (p pointer) toInt64() *int64 {
+	return p.v.Interface().(*int64)
+}
+func (p pointer) toInt64Ptr() **int64 {
+	return p.v.Interface().(**int64)
+}
+func (p pointer) toInt64Slice() *[]int64 {
+	return p.v.Interface().(*[]int64)
+}
+
+var int32ptr = reflect.TypeOf((*int32)(nil))
+
+func (p pointer) toInt32() *int32 {
+	return p.v.Convert(int32ptr).Interface().(*int32)
+}
+
+// The toInt32Ptr/Slice methods don't work because of enums.
+// Instead, we must use set/get methods for the int32ptr/slice case.
+/*
+	func (p pointer) toInt32Ptr() **int32 {
+		return p.v.Interface().(**int32)
+}
+	func (p pointer) toInt32Slice() *[]int32 {
+		return p.v.Interface().(*[]int32)
+}
+*/
+func (p pointer) getInt32Ptr() *int32 {
+	if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
+		// raw int32 type
+		return p.v.Elem().Interface().(*int32)
 	}
+	// an enum
+	return p.v.Elem().Convert(int32PtrType).Interface().(*int32)
+}
+func (p pointer) setInt32Ptr(v int32) {
+	// Allocate value in a *int32. Possibly convert that to a *enum.
+	// Then assign it to a **int32 or **enum.
+	// Note: we can convert *int32 to *enum, but we can't convert
+	// **int32 to **enum!
+	p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem()))
 }
 
-func (p word32Slice) Len() int {
-	return p.v.Len()
-}
-
-func (p word32Slice) Index(i int) uint32 {
-	elem := p.v.Index(i)
-	switch elem.Kind() {
-	case reflect.Int32:
-		return uint32(elem.Int())
-	case reflect.Uint32:
-		return uint32(elem.Uint())
-	case reflect.Float32:
-		return math.Float32bits(float32(elem.Float()))
+// getInt32Slice copies []int32 from p as a new slice.
+// This behavior differs from the implementation in pointer_unsafe.go.
+func (p pointer) getInt32Slice() []int32 {
+	if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
+		// raw int32 type
+		return p.v.Elem().Interface().([]int32)
 	}
-	panic("unreachable")
+	// an enum
+	// Allocate a []int32, then assign []enum's values into it.
+	// Note: we can't convert []enum to []int32.
+	slice := p.v.Elem()
+	s := make([]int32, slice.Len())
+	for i := 0; i < slice.Len(); i++ {
+		s[i] = int32(slice.Index(i).Int())
+	}
+	return s
 }
 
-// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct.
-func structPointer_Word32Slice(p structPointer, f field) word32Slice {
-	return word32Slice{structPointer_field(p, f)}
-}
-
-// word64 is like word32 but for 64-bit values.
-type word64 struct {
-	v reflect.Value
-}
-
-func word64_Set(p word64, o *Buffer, x uint64) {
-	t := p.v.Type().Elem()
-	switch t {
-	case int64Type:
-		if len(o.int64s) == 0 {
-			o.int64s = make([]int64, uint64PoolSize)
-		}
-		o.int64s[0] = int64(x)
-		p.v.Set(reflect.ValueOf(&o.int64s[0]))
-		o.int64s = o.int64s[1:]
-		return
-	case uint64Type:
-		if len(o.uint64s) == 0 {
-			o.uint64s = make([]uint64, uint64PoolSize)
-		}
-		o.uint64s[0] = x
-		p.v.Set(reflect.ValueOf(&o.uint64s[0]))
-		o.uint64s = o.uint64s[1:]
-		return
-	case float64Type:
-		if len(o.float64s) == 0 {
-			o.float64s = make([]float64, uint64PoolSize)
-		}
-		o.float64s[0] = math.Float64frombits(x)
-		p.v.Set(reflect.ValueOf(&o.float64s[0]))
-		o.float64s = o.float64s[1:]
+// setInt32Slice copies []int32 into p as a new slice.
+// This behavior differs from the implementation in pointer_unsafe.go.
+func (p pointer) setInt32Slice(v []int32) {
+	if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
+		// raw int32 type
+		p.v.Elem().Set(reflect.ValueOf(v))
 		return
 	}
-	panic("unreachable")
-}
-
-func word64_IsNil(p word64) bool {
-	return p.v.IsNil()
-}
-
-func word64_Get(p word64) uint64 {
-	elem := p.v.Elem()
-	switch elem.Kind() {
-	case reflect.Int64:
-		return uint64(elem.Int())
-	case reflect.Uint64:
-		return elem.Uint()
-	case reflect.Float64:
-		return math.Float64bits(elem.Float())
+	// an enum
+	// Allocate a []enum, then assign []int32's values into it.
+	// Note: we can't convert []enum to []int32.
+	slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v))
+	for i, x := range v {
+		slice.Index(i).SetInt(int64(x))
 	}
-	panic("unreachable")
+	p.v.Elem().Set(slice)
+}
+func (p pointer) appendInt32Slice(v int32) {
+	grow(p.v.Elem()).SetInt(int64(v))
 }
 
-func structPointer_Word64(p structPointer, f field) word64 {
-	return word64{structPointer_field(p, f)}
+func (p pointer) toUint64() *uint64 {
+	return p.v.Interface().(*uint64)
+}
+func (p pointer) toUint64Ptr() **uint64 {
+	return p.v.Interface().(**uint64)
+}
+func (p pointer) toUint64Slice() *[]uint64 {
+	return p.v.Interface().(*[]uint64)
+}
+func (p pointer) toUint32() *uint32 {
+	return p.v.Interface().(*uint32)
+}
+func (p pointer) toUint32Ptr() **uint32 {
+	return p.v.Interface().(**uint32)
+}
+func (p pointer) toUint32Slice() *[]uint32 {
+	return p.v.Interface().(*[]uint32)
+}
+func (p pointer) toBool() *bool {
+	return p.v.Interface().(*bool)
+}
+func (p pointer) toBoolPtr() **bool {
+	return p.v.Interface().(**bool)
+}
+func (p pointer) toBoolSlice() *[]bool {
+	return p.v.Interface().(*[]bool)
+}
+func (p pointer) toFloat64() *float64 {
+	return p.v.Interface().(*float64)
+}
+func (p pointer) toFloat64Ptr() **float64 {
+	return p.v.Interface().(**float64)
+}
+func (p pointer) toFloat64Slice() *[]float64 {
+	return p.v.Interface().(*[]float64)
+}
+func (p pointer) toFloat32() *float32 {
+	return p.v.Interface().(*float32)
+}
+func (p pointer) toFloat32Ptr() **float32 {
+	return p.v.Interface().(**float32)
+}
+func (p pointer) toFloat32Slice() *[]float32 {
+	return p.v.Interface().(*[]float32)
+}
+func (p pointer) toString() *string {
+	return p.v.Interface().(*string)
+}
+func (p pointer) toStringPtr() **string {
+	return p.v.Interface().(**string)
+}
+func (p pointer) toStringSlice() *[]string {
+	return p.v.Interface().(*[]string)
+}
+func (p pointer) toBytes() *[]byte {
+	return p.v.Interface().(*[]byte)
+}
+func (p pointer) toBytesSlice() *[][]byte {
+	return p.v.Interface().(*[][]byte)
+}
+func (p pointer) toExtensions() *XXX_InternalExtensions {
+	return p.v.Interface().(*XXX_InternalExtensions)
+}
+func (p pointer) toOldExtensions() *map[int32]Extension {
+	return p.v.Interface().(*map[int32]Extension)
+}
+func (p pointer) getPointer() pointer {
+	return pointer{v: p.v.Elem()}
+}
+func (p pointer) setPointer(q pointer) {
+	p.v.Elem().Set(q.v)
+}
+func (p pointer) appendPointer(q pointer) {
+	grow(p.v.Elem()).Set(q.v)
 }
 
-// word64Val is like word32Val but for 64-bit values.
-type word64Val struct {
-	v reflect.Value
+// getPointerSlice copies []*T from p as a new []pointer.
+// This behavior differs from the implementation in pointer_unsafe.go.
+func (p pointer) getPointerSlice() []pointer {
+	if p.v.IsNil() {
+		return nil
+	}
+	n := p.v.Elem().Len()
+	s := make([]pointer, n)
+	for i := 0; i < n; i++ {
+		s[i] = pointer{v: p.v.Elem().Index(i)}
+	}
+	return s
 }
 
-func word64Val_Set(p word64Val, o *Buffer, x uint64) {
-	switch p.v.Type() {
-	case int64Type:
-		p.v.SetInt(int64(x))
-		return
-	case uint64Type:
-		p.v.SetUint(x)
-		return
-	case float64Type:
-		p.v.SetFloat(math.Float64frombits(x))
+// setPointerSlice copies []pointer into p as a new []*T.
+// This behavior differs from the implementation in pointer_unsafe.go.
+func (p pointer) setPointerSlice(v []pointer) {
+	if v == nil {
+		p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem())
 		return
 	}
-	panic("unreachable")
-}
-
-func word64Val_Get(p word64Val) uint64 {
-	elem := p.v
-	switch elem.Kind() {
-	case reflect.Int64:
-		return uint64(elem.Int())
-	case reflect.Uint64:
-		return elem.Uint()
-	case reflect.Float64:
-		return math.Float64bits(elem.Float())
+	s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v))
+	for _, p := range v {
+		s = reflect.Append(s, p.v)
 	}
-	panic("unreachable")
+	p.v.Elem().Set(s)
 }
 
-func structPointer_Word64Val(p structPointer, f field) word64Val {
-	return word64Val{structPointer_field(p, f)}
-}
-
-type word64Slice struct {
-	v reflect.Value
-}
-
-func (p word64Slice) Append(x uint64) {
-	n, m := p.v.Len(), p.v.Cap()
-	if n < m {
-		p.v.SetLen(n + 1)
-	} else {
-		t := p.v.Type().Elem()
-		p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
+// getInterfacePointer returns a pointer that points to the
+// interface data of the interface pointed by p.
+func (p pointer) getInterfacePointer() pointer {
+	if p.v.Elem().IsNil() {
+		return pointer{v: p.v.Elem()}
 	}
-	elem := p.v.Index(n)
-	switch elem.Kind() {
-	case reflect.Int64:
-		elem.SetInt(int64(int64(x)))
-	case reflect.Uint64:
-		elem.SetUint(uint64(x))
-	case reflect.Float64:
-		elem.SetFloat(float64(math.Float64frombits(x)))
-	}
+	return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct
 }
 
-func (p word64Slice) Len() int {
-	return p.v.Len()
+func (p pointer) asPointerTo(t reflect.Type) reflect.Value {
+	// TODO: check that p.v.Type().Elem() == t?
+	return p.v
 }
 
-func (p word64Slice) Index(i int) uint64 {
-	elem := p.v.Index(i)
-	switch elem.Kind() {
-	case reflect.Int64:
-		return uint64(elem.Int())
-	case reflect.Uint64:
-		return uint64(elem.Uint())
-	case reflect.Float64:
-		return math.Float64bits(float64(elem.Float()))
-	}
-	panic("unreachable")
+func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	return *p
+}
+func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	*p = v
+}
+func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	return *p
+}
+func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	*p = v
+}
+func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	return *p
+}
+func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	*p = v
+}
+func atomicLoadDiscardInfo(p **discardInfo) *discardInfo {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	return *p
+}
+func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	*p = v
 }
 
-func structPointer_Word64Slice(p structPointer, f field) word64Slice {
-	return word64Slice{structPointer_field(p, f)}
-}
+var atomicLock sync.Mutex
diff --git a/proto/pointer_unsafe.go b/proto/pointer_unsafe.go
index 6b5567d..d55a335 100644
--- a/proto/pointer_unsafe.go
+++ b/proto/pointer_unsafe.go
@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// +build !appengine,!js
+// +build !purego,!appengine,!js
 
 // This file contains the implementation of the proto field accesses using package unsafe.
 
@@ -37,38 +37,13 @@
 
 import (
 	"reflect"
+	"sync/atomic"
 	"unsafe"
 )
 
-// NOTE: These type_Foo functions would more idiomatically be methods,
-// but Go does not allow methods on pointer types, and we must preserve
-// some pointer type for the garbage collector. We use these
-// funcs with clunky names as our poor approximation to methods.
-//
-// An alternative would be
-//	type structPointer struct { p unsafe.Pointer }
-// but that does not registerize as well.
+const unsafeAllowed = true
 
-// A structPointer is a pointer to a struct.
-type structPointer unsafe.Pointer
-
-// toStructPointer returns a structPointer equivalent to the given reflect value.
-func toStructPointer(v reflect.Value) structPointer {
-	return structPointer(unsafe.Pointer(v.Pointer()))
-}
-
-// IsNil reports whether p is nil.
-func structPointer_IsNil(p structPointer) bool {
-	return p == nil
-}
-
-// Interface returns the struct pointer, assumed to have element type t,
-// as an interface value.
-func structPointer_Interface(p structPointer, t reflect.Type) interface{} {
-	return reflect.NewAt(t, unsafe.Pointer(p)).Interface()
-}
-
-// A field identifies a field in a struct, accessible from a structPointer.
+// A field identifies a field in a struct, accessible from a pointer.
 // In this implementation, a field is identified by its byte offset from the start of the struct.
 type field uintptr
 
@@ -80,191 +55,254 @@
 // invalidField is an invalid field identifier.
 const invalidField = ^field(0)
 
+// zeroField is a noop when calling pointer.offset.
+const zeroField = field(0)
+
 // IsValid reports whether the field identifier is valid.
 func (f field) IsValid() bool {
-	return f != ^field(0)
+	return f != invalidField
 }
 
-// Bytes returns the address of a []byte field in the struct.
-func structPointer_Bytes(p structPointer, f field) *[]byte {
-	return (*[]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+// The pointer type below is for the new table-driven encoder/decoder.
+// The implementation here uses unsafe.Pointer to create a generic pointer.
+// In pointer_reflect.go we use reflect instead of unsafe to implement
+// the same (but slower) interface.
+type pointer struct {
+	p unsafe.Pointer
 }
 
-// BytesSlice returns the address of a [][]byte field in the struct.
-func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
-	return (*[][]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+// size of pointer
+var ptrSize = unsafe.Sizeof(uintptr(0))
+
+// toPointer converts an interface of pointer type to a pointer
+// that points to the same target.
+func toPointer(i *Message) pointer {
+	// Super-tricky - read pointer out of data word of interface value.
+	// Saves ~25ns over the equivalent:
+	// return valToPointer(reflect.ValueOf(*i))
+	return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
 }
 
-// Bool returns the address of a *bool field in the struct.
-func structPointer_Bool(p structPointer, f field) **bool {
-	return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// BoolVal returns the address of a bool field in the struct.
-func structPointer_BoolVal(p structPointer, f field) *bool {
-	return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// BoolSlice returns the address of a []bool field in the struct.
-func structPointer_BoolSlice(p structPointer, f field) *[]bool {
-	return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// String returns the address of a *string field in the struct.
-func structPointer_String(p structPointer, f field) **string {
-	return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// StringVal returns the address of a string field in the struct.
-func structPointer_StringVal(p structPointer, f field) *string {
-	return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// StringSlice returns the address of a []string field in the struct.
-func structPointer_StringSlice(p structPointer, f field) *[]string {
-	return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// ExtMap returns the address of an extension map field in the struct.
-func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
-	return (*XXX_InternalExtensions)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
-	return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// NewAt returns the reflect.Value for a pointer to a field in the struct.
-func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
-	return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
-}
-
-// SetStructPointer writes a *struct field in the struct.
-func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
-	*(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q
-}
-
-// GetStructPointer reads a *struct field in the struct.
-func structPointer_GetStructPointer(p structPointer, f field) structPointer {
-	return *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// StructPointerSlice the address of a []*struct field in the struct.
-func structPointer_StructPointerSlice(p structPointer, f field) *structPointerSlice {
-	return (*structPointerSlice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups).
-type structPointerSlice []structPointer
-
-func (v *structPointerSlice) Len() int                  { return len(*v) }
-func (v *structPointerSlice) Index(i int) structPointer { return (*v)[i] }
-func (v *structPointerSlice) Append(p structPointer)    { *v = append(*v, p) }
-
-// A word32 is the address of a "pointer to 32-bit value" field.
-type word32 **uint32
-
-// IsNil reports whether *v is nil.
-func word32_IsNil(p word32) bool {
-	return *p == nil
-}
-
-// Set sets *v to point at a newly allocated word set to x.
-func word32_Set(p word32, o *Buffer, x uint32) {
-	if len(o.uint32s) == 0 {
-		o.uint32s = make([]uint32, uint32PoolSize)
+// toAddrPointer converts an interface to a pointer that points to
+// the interface data.
+func toAddrPointer(i *interface{}, isptr bool) pointer {
+	// Super-tricky - read or get the address of data word of interface value.
+	if isptr {
+		// The interface is of pointer type, thus it is a direct interface.
+		// The data word is the pointer data itself. We take its address.
+		return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)}
 	}
-	o.uint32s[0] = x
-	*p = &o.uint32s[0]
-	o.uint32s = o.uint32s[1:]
+	// The interface is not of pointer type. The data word is the pointer
+	// to the data.
+	return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
 }
 
-// Get gets the value pointed at by *v.
-func word32_Get(p word32) uint32 {
-	return **p
+// valToPointer converts v to a pointer. v must be of pointer type.
+func valToPointer(v reflect.Value) pointer {
+	return pointer{p: unsafe.Pointer(v.Pointer())}
 }
 
-// Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
-func structPointer_Word32(p structPointer, f field) word32 {
-	return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+// offset converts from a pointer to a structure to a pointer to
+// one of its fields.
+func (p pointer) offset(f field) pointer {
+	// For safety, we should panic if !f.IsValid, however calling panic causes
+	// this to no longer be inlineable, which is a serious performance cost.
+	/*
+		if !f.IsValid() {
+			panic("invalid field")
+		}
+	*/
+	return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))}
 }
 
-// A word32Val is the address of a 32-bit value field.
-type word32Val *uint32
-
-// Set sets *p to x.
-func word32Val_Set(p word32Val, x uint32) {
-	*p = x
+func (p pointer) isNil() bool {
+	return p.p == nil
 }
 
-// Get gets the value pointed at by p.
-func word32Val_Get(p word32Val) uint32 {
-	return *p
+func (p pointer) toInt64() *int64 {
+	return (*int64)(p.p)
+}
+func (p pointer) toInt64Ptr() **int64 {
+	return (**int64)(p.p)
+}
+func (p pointer) toInt64Slice() *[]int64 {
+	return (*[]int64)(p.p)
+}
+func (p pointer) toInt32() *int32 {
+	return (*int32)(p.p)
 }
 
-// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
-func structPointer_Word32Val(p structPointer, f field) word32Val {
-	return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
-}
-
-// A word32Slice is a slice of 32-bit values.
-type word32Slice []uint32
-
-func (v *word32Slice) Append(x uint32)    { *v = append(*v, x) }
-func (v *word32Slice) Len() int           { return len(*v) }
-func (v *word32Slice) Index(i int) uint32 { return (*v)[i] }
-
-// Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct.
-func structPointer_Word32Slice(p structPointer, f field) *word32Slice {
-	return (*word32Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-// word64 is like word32 but for 64-bit values.
-type word64 **uint64
-
-func word64_Set(p word64, o *Buffer, x uint64) {
-	if len(o.uint64s) == 0 {
-		o.uint64s = make([]uint64, uint64PoolSize)
+// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist.
+/*
+	func (p pointer) toInt32Ptr() **int32 {
+		return (**int32)(p.p)
 	}
-	o.uint64s[0] = x
-	*p = &o.uint64s[0]
-	o.uint64s = o.uint64s[1:]
+	func (p pointer) toInt32Slice() *[]int32 {
+		return (*[]int32)(p.p)
+	}
+*/
+func (p pointer) getInt32Ptr() *int32 {
+	return *(**int32)(p.p)
+}
+func (p pointer) setInt32Ptr(v int32) {
+	*(**int32)(p.p) = &v
 }
 
-func word64_IsNil(p word64) bool {
-	return *p == nil
+// getInt32Slice loads a []int32 from p.
+// The value returned is aliased with the original slice.
+// This behavior differs from the implementation in pointer_reflect.go.
+func (p pointer) getInt32Slice() []int32 {
+	return *(*[]int32)(p.p)
 }
 
-func word64_Get(p word64) uint64 {
-	return **p
+// setInt32Slice stores a []int32 to p.
+// The value set is aliased with the input slice.
+// This behavior differs from the implementation in pointer_reflect.go.
+func (p pointer) setInt32Slice(v []int32) {
+	*(*[]int32)(p.p) = v
 }
 
-func structPointer_Word64(p structPointer, f field) word64 {
-	return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead?
+func (p pointer) appendInt32Slice(v int32) {
+	s := (*[]int32)(p.p)
+	*s = append(*s, v)
 }
 
-// word64Val is like word32Val but for 64-bit values.
-type word64Val *uint64
-
-func word64Val_Set(p word64Val, o *Buffer, x uint64) {
-	*p = x
+func (p pointer) toUint64() *uint64 {
+	return (*uint64)(p.p)
+}
+func (p pointer) toUint64Ptr() **uint64 {
+	return (**uint64)(p.p)
+}
+func (p pointer) toUint64Slice() *[]uint64 {
+	return (*[]uint64)(p.p)
+}
+func (p pointer) toUint32() *uint32 {
+	return (*uint32)(p.p)
+}
+func (p pointer) toUint32Ptr() **uint32 {
+	return (**uint32)(p.p)
+}
+func (p pointer) toUint32Slice() *[]uint32 {
+	return (*[]uint32)(p.p)
+}
+func (p pointer) toBool() *bool {
+	return (*bool)(p.p)
+}
+func (p pointer) toBoolPtr() **bool {
+	return (**bool)(p.p)
+}
+func (p pointer) toBoolSlice() *[]bool {
+	return (*[]bool)(p.p)
+}
+func (p pointer) toFloat64() *float64 {
+	return (*float64)(p.p)
+}
+func (p pointer) toFloat64Ptr() **float64 {
+	return (**float64)(p.p)
+}
+func (p pointer) toFloat64Slice() *[]float64 {
+	return (*[]float64)(p.p)
+}
+func (p pointer) toFloat32() *float32 {
+	return (*float32)(p.p)
+}
+func (p pointer) toFloat32Ptr() **float32 {
+	return (**float32)(p.p)
+}
+func (p pointer) toFloat32Slice() *[]float32 {
+	return (*[]float32)(p.p)
+}
+func (p pointer) toString() *string {
+	return (*string)(p.p)
+}
+func (p pointer) toStringPtr() **string {
+	return (**string)(p.p)
+}
+func (p pointer) toStringSlice() *[]string {
+	return (*[]string)(p.p)
+}
+func (p pointer) toBytes() *[]byte {
+	return (*[]byte)(p.p)
+}
+func (p pointer) toBytesSlice() *[][]byte {
+	return (*[][]byte)(p.p)
+}
+func (p pointer) toExtensions() *XXX_InternalExtensions {
+	return (*XXX_InternalExtensions)(p.p)
+}
+func (p pointer) toOldExtensions() *map[int32]Extension {
+	return (*map[int32]Extension)(p.p)
 }
 
-func word64Val_Get(p word64Val) uint64 {
-	return *p
+// getPointerSlice loads []*T from p as a []pointer.
+// The value returned is aliased with the original slice.
+// This behavior differs from the implementation in pointer_reflect.go.
+func (p pointer) getPointerSlice() []pointer {
+	// Super-tricky - p should point to a []*T where T is a
+	// message type. We load it as []pointer.
+	return *(*[]pointer)(p.p)
 }
 
-func structPointer_Word64Val(p structPointer, f field) word64Val {
-	return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+// setPointerSlice stores []pointer into p as a []*T.
+// The value set is aliased with the input slice.
+// This behavior differs from the implementation in pointer_reflect.go.
+func (p pointer) setPointerSlice(v []pointer) {
+	// Super-tricky - p should point to a []*T where T is a
+	// message type. We store it as []pointer.
+	*(*[]pointer)(p.p) = v
 }
 
-// word64Slice is like word32Slice but for 64-bit values.
-type word64Slice []uint64
+// getPointer loads the pointer at p and returns it.
+func (p pointer) getPointer() pointer {
+	return pointer{p: *(*unsafe.Pointer)(p.p)}
+}
 
-func (v *word64Slice) Append(x uint64)    { *v = append(*v, x) }
-func (v *word64Slice) Len() int           { return len(*v) }
-func (v *word64Slice) Index(i int) uint64 { return (*v)[i] }
+// setPointer stores the pointer q at p.
+func (p pointer) setPointer(q pointer) {
+	*(*unsafe.Pointer)(p.p) = q.p
+}
 
-func structPointer_Word64Slice(p structPointer, f field) *word64Slice {
-	return (*word64Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+// append q to the slice pointed to by p.
+func (p pointer) appendPointer(q pointer) {
+	s := (*[]unsafe.Pointer)(p.p)
+	*s = append(*s, q.p)
+}
+
+// getInterfacePointer returns a pointer that points to the
+// interface data of the interface pointed by p.
+func (p pointer) getInterfacePointer() pointer {
+	// Super-tricky - read pointer out of data word of interface value.
+	return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]}
+}
+
+// asPointerTo returns a reflect.Value that is a pointer to an
+// object of type t stored at p.
+func (p pointer) asPointerTo(t reflect.Type) reflect.Value {
+	return reflect.NewAt(t, p.p)
+}
+
+func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {
+	return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+}
+func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {
+	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+}
+func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {
+	return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+}
+func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {
+	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+}
+func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {
+	return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+}
+func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {
+	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+}
+func atomicLoadDiscardInfo(p **discardInfo) *discardInfo {
+	return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+}
+func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {
+	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
 }
diff --git a/proto/properties.go b/proto/properties.go
index ec2289c..f710ada 100644
--- a/proto/properties.go
+++ b/proto/properties.go
@@ -58,42 +58,6 @@
 	WireFixed32    = 5
 )
 
-const startSize = 10 // initial slice/string sizes
-
-// Encoders are defined in encode.go
-// An encoder outputs the full representation of a field, including its
-// tag and encoder type.
-type encoder func(p *Buffer, prop *Properties, base structPointer) error
-
-// A valueEncoder encodes a single integer in a particular encoding.
-type valueEncoder func(o *Buffer, x uint64) error
-
-// Sizers are defined in encode.go
-// A sizer returns the encoded size of a field, including its tag and encoder
-// type.
-type sizer func(prop *Properties, base structPointer) int
-
-// A valueSizer returns the encoded size of a single integer in a particular
-// encoding.
-type valueSizer func(x uint64) int
-
-// Decoders are defined in decode.go
-// A decoder creates a value from its wire representation.
-// Unrecognized subelements are saved in unrec.
-type decoder func(p *Buffer, prop *Properties, base structPointer) error
-
-// A valueDecoder decodes a single integer in a particular encoding.
-type valueDecoder func(o *Buffer) (x uint64, err error)
-
-// A oneofMarshaler does the marshaling for all oneof fields in a message.
-type oneofMarshaler func(Message, *Buffer) error
-
-// A oneofUnmarshaler does the unmarshaling for a oneof field in a message.
-type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error)
-
-// A oneofSizer does the sizing for all oneof fields in a message.
-type oneofSizer func(Message) int
-
 // tagMap is an optimization over map[int]int for typical protocol buffer
 // use-cases. Encoded protocol buffers are often in tag order with small tag
 // numbers.
@@ -140,13 +104,6 @@
 	decoderTags      tagMap         // map from proto tag to struct field number
 	decoderOrigNames map[string]int // map from original name to struct field number
 	order            []int          // list of struct field numbers in tag order
-	unrecField       field          // field id of the XXX_unrecognized []byte field
-	extendable       bool           // is this an extendable proto
-
-	oneofMarshaler   oneofMarshaler
-	oneofUnmarshaler oneofUnmarshaler
-	oneofSizer       oneofSizer
-	stype            reflect.Type
 
 	// OneofTypes contains information about the oneof fields in this message.
 	// It is keyed by the original name of a field.
@@ -187,36 +144,19 @@
 
 	Default    string // default value
 	HasDefault bool   // whether an explicit default was provided
-	def_uint64 uint64
 
-	enc           encoder
-	valEnc        valueEncoder // set for bool and numeric types only
-	field         field
-	tagcode       []byte // encoding of EncodeVarint((Tag<<3)|WireType)
-	tagbuf        [8]byte
-	stype         reflect.Type      // set for struct types only
-	sprop         *StructProperties // set for struct types only
-	isMarshaler   bool
-	isUnmarshaler bool
+	stype reflect.Type      // set for struct types only
+	sprop *StructProperties // set for struct types only
 
 	mtype    reflect.Type // set for map types only
 	mkeyprop *Properties  // set for map types only
 	mvalprop *Properties  // set for map types only
-
-	size    sizer
-	valSize valueSizer // set for bool and numeric types only
-
-	dec    decoder
-	valDec valueDecoder // set for bool and numeric types only
-
-	// If this is a packable field, this will be the decoder for the packed version of the field.
-	packedDec decoder
 }
 
 // String formats the properties in the protobuf struct field tag style.
 func (p *Properties) String() string {
 	s := p.Wire
-	s = ","
+	s += ","
 	s += strconv.Itoa(p.Tag)
 	if p.Required {
 		s += ",req"
@@ -262,29 +202,14 @@
 	switch p.Wire {
 	case "varint":
 		p.WireType = WireVarint
-		p.valEnc = (*Buffer).EncodeVarint
-		p.valDec = (*Buffer).DecodeVarint
-		p.valSize = sizeVarint
 	case "fixed32":
 		p.WireType = WireFixed32
-		p.valEnc = (*Buffer).EncodeFixed32
-		p.valDec = (*Buffer).DecodeFixed32
-		p.valSize = sizeFixed32
 	case "fixed64":
 		p.WireType = WireFixed64
-		p.valEnc = (*Buffer).EncodeFixed64
-		p.valDec = (*Buffer).DecodeFixed64
-		p.valSize = sizeFixed64
 	case "zigzag32":
 		p.WireType = WireVarint
-		p.valEnc = (*Buffer).EncodeZigzag32
-		p.valDec = (*Buffer).DecodeZigzag32
-		p.valSize = sizeZigzag32
 	case "zigzag64":
 		p.WireType = WireVarint
-		p.valEnc = (*Buffer).EncodeZigzag64
-		p.valDec = (*Buffer).DecodeZigzag64
-		p.valSize = sizeZigzag64
 	case "bytes", "group":
 		p.WireType = WireBytes
 		// no numeric converter for non-numeric types
@@ -299,6 +224,7 @@
 		return
 	}
 
+outer:
 	for i := 2; i < len(fields); i++ {
 		f := fields[i]
 		switch {
@@ -326,229 +252,28 @@
 			if i+1 < len(fields) {
 				// Commas aren't escaped, and def is always last.
 				p.Default += "," + strings.Join(fields[i+1:], ",")
-				break
+				break outer
 			}
 		}
 	}
 }
 
-func logNoSliceEnc(t1, t2 reflect.Type) {
-	fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
-}
-
 var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
 
-// Initialize the fields for encoding and decoding.
-func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
-	p.enc = nil
-	p.dec = nil
-	p.size = nil
-
+// setFieldProps initializes the field properties for submessages and maps.
+func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
 	switch t1 := typ; t1.Kind() {
-	default:
-		fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
-
-	// proto3 scalar types
-
-	case reflect.Bool:
-		p.enc = (*Buffer).enc_proto3_bool
-		p.dec = (*Buffer).dec_proto3_bool
-		p.size = size_proto3_bool
-	case reflect.Int32:
-		p.enc = (*Buffer).enc_proto3_int32
-		p.dec = (*Buffer).dec_proto3_int32
-		p.size = size_proto3_int32
-	case reflect.Uint32:
-		p.enc = (*Buffer).enc_proto3_uint32
-		p.dec = (*Buffer).dec_proto3_int32 // can reuse
-		p.size = size_proto3_uint32
-	case reflect.Int64, reflect.Uint64:
-		p.enc = (*Buffer).enc_proto3_int64
-		p.dec = (*Buffer).dec_proto3_int64
-		p.size = size_proto3_int64
-	case reflect.Float32:
-		p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
-		p.dec = (*Buffer).dec_proto3_int32
-		p.size = size_proto3_uint32
-	case reflect.Float64:
-		p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
-		p.dec = (*Buffer).dec_proto3_int64
-		p.size = size_proto3_int64
-	case reflect.String:
-		p.enc = (*Buffer).enc_proto3_string
-		p.dec = (*Buffer).dec_proto3_string
-		p.size = size_proto3_string
-
 	case reflect.Ptr:
-		switch t2 := t1.Elem(); t2.Kind() {
-		default:
-			fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
-			break
-		case reflect.Bool:
-			p.enc = (*Buffer).enc_bool
-			p.dec = (*Buffer).dec_bool
-			p.size = size_bool
-		case reflect.Int32:
-			p.enc = (*Buffer).enc_int32
-			p.dec = (*Buffer).dec_int32
-			p.size = size_int32
-		case reflect.Uint32:
-			p.enc = (*Buffer).enc_uint32
-			p.dec = (*Buffer).dec_int32 // can reuse
-			p.size = size_uint32
-		case reflect.Int64, reflect.Uint64:
-			p.enc = (*Buffer).enc_int64
-			p.dec = (*Buffer).dec_int64
-			p.size = size_int64
-		case reflect.Float32:
-			p.enc = (*Buffer).enc_uint32 // can just treat them as bits
-			p.dec = (*Buffer).dec_int32
-			p.size = size_uint32
-		case reflect.Float64:
-			p.enc = (*Buffer).enc_int64 // can just treat them as bits
-			p.dec = (*Buffer).dec_int64
-			p.size = size_int64
-		case reflect.String:
-			p.enc = (*Buffer).enc_string
-			p.dec = (*Buffer).dec_string
-			p.size = size_string
-		case reflect.Struct:
+		if t1.Elem().Kind() == reflect.Struct {
 			p.stype = t1.Elem()
-			p.isMarshaler = isMarshaler(t1)
-			p.isUnmarshaler = isUnmarshaler(t1)
-			if p.Wire == "bytes" {
-				p.enc = (*Buffer).enc_struct_message
-				p.dec = (*Buffer).dec_struct_message
-				p.size = size_struct_message
-			} else {
-				p.enc = (*Buffer).enc_struct_group
-				p.dec = (*Buffer).dec_struct_group
-				p.size = size_struct_group
-			}
 		}
 
 	case reflect.Slice:
-		switch t2 := t1.Elem(); t2.Kind() {
-		default:
-			logNoSliceEnc(t1, t2)
-			break
-		case reflect.Bool:
-			if p.Packed {
-				p.enc = (*Buffer).enc_slice_packed_bool
-				p.size = size_slice_packed_bool
-			} else {
-				p.enc = (*Buffer).enc_slice_bool
-				p.size = size_slice_bool
-			}
-			p.dec = (*Buffer).dec_slice_bool
-			p.packedDec = (*Buffer).dec_slice_packed_bool
-		case reflect.Int32:
-			if p.Packed {
-				p.enc = (*Buffer).enc_slice_packed_int32
-				p.size = size_slice_packed_int32
-			} else {
-				p.enc = (*Buffer).enc_slice_int32
-				p.size = size_slice_int32
-			}
-			p.dec = (*Buffer).dec_slice_int32
-			p.packedDec = (*Buffer).dec_slice_packed_int32
-		case reflect.Uint32:
-			if p.Packed {
-				p.enc = (*Buffer).enc_slice_packed_uint32
-				p.size = size_slice_packed_uint32
-			} else {
-				p.enc = (*Buffer).enc_slice_uint32
-				p.size = size_slice_uint32
-			}
-			p.dec = (*Buffer).dec_slice_int32
-			p.packedDec = (*Buffer).dec_slice_packed_int32
-		case reflect.Int64, reflect.Uint64:
-			if p.Packed {
-				p.enc = (*Buffer).enc_slice_packed_int64
-				p.size = size_slice_packed_int64
-			} else {
-				p.enc = (*Buffer).enc_slice_int64
-				p.size = size_slice_int64
-			}
-			p.dec = (*Buffer).dec_slice_int64
-			p.packedDec = (*Buffer).dec_slice_packed_int64
-		case reflect.Uint8:
-			p.dec = (*Buffer).dec_slice_byte
-			if p.proto3 {
-				p.enc = (*Buffer).enc_proto3_slice_byte
-				p.size = size_proto3_slice_byte
-			} else {
-				p.enc = (*Buffer).enc_slice_byte
-				p.size = size_slice_byte
-			}
-		case reflect.Float32, reflect.Float64:
-			switch t2.Bits() {
-			case 32:
-				// can just treat them as bits
-				if p.Packed {
-					p.enc = (*Buffer).enc_slice_packed_uint32
-					p.size = size_slice_packed_uint32
-				} else {
-					p.enc = (*Buffer).enc_slice_uint32
-					p.size = size_slice_uint32
-				}
-				p.dec = (*Buffer).dec_slice_int32
-				p.packedDec = (*Buffer).dec_slice_packed_int32
-			case 64:
-				// can just treat them as bits
-				if p.Packed {
-					p.enc = (*Buffer).enc_slice_packed_int64
-					p.size = size_slice_packed_int64
-				} else {
-					p.enc = (*Buffer).enc_slice_int64
-					p.size = size_slice_int64
-				}
-				p.dec = (*Buffer).dec_slice_int64
-				p.packedDec = (*Buffer).dec_slice_packed_int64
-			default:
-				logNoSliceEnc(t1, t2)
-				break
-			}
-		case reflect.String:
-			p.enc = (*Buffer).enc_slice_string
-			p.dec = (*Buffer).dec_slice_string
-			p.size = size_slice_string
-		case reflect.Ptr:
-			switch t3 := t2.Elem(); t3.Kind() {
-			default:
-				fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
-				break
-			case reflect.Struct:
-				p.stype = t2.Elem()
-				p.isMarshaler = isMarshaler(t2)
-				p.isUnmarshaler = isUnmarshaler(t2)
-				if p.Wire == "bytes" {
-					p.enc = (*Buffer).enc_slice_struct_message
-					p.dec = (*Buffer).dec_slice_struct_message
-					p.size = size_slice_struct_message
-				} else {
-					p.enc = (*Buffer).enc_slice_struct_group
-					p.dec = (*Buffer).dec_slice_struct_group
-					p.size = size_slice_struct_group
-				}
-			}
-		case reflect.Slice:
-			switch t2.Elem().Kind() {
-			default:
-				fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
-				break
-			case reflect.Uint8:
-				p.enc = (*Buffer).enc_slice_slice_byte
-				p.dec = (*Buffer).dec_slice_slice_byte
-				p.size = size_slice_slice_byte
-			}
+		if t2 := t1.Elem(); t2.Kind() == reflect.Ptr && t2.Elem().Kind() == reflect.Struct {
+			p.stype = t2.Elem()
 		}
 
 	case reflect.Map:
-		p.enc = (*Buffer).enc_new_map
-		p.dec = (*Buffer).dec_new_map
-		p.size = size_new_map
-
 		p.mtype = t1
 		p.mkeyprop = &Properties{}
 		p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
@@ -562,20 +287,6 @@
 		p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
 	}
 
-	// precalculate tag code
-	wire := p.WireType
-	if p.Packed {
-		wire = WireBytes
-	}
-	x := uint32(p.Tag)<<3 | uint32(wire)
-	i := 0
-	for i = 0; x > 127; i++ {
-		p.tagbuf[i] = 0x80 | uint8(x&0x7F)
-		x >>= 7
-	}
-	p.tagbuf[i] = uint8(x)
-	p.tagcode = p.tagbuf[0 : i+1]
-
 	if p.stype != nil {
 		if lockGetProp {
 			p.sprop = GetProperties(p.stype)
@@ -586,32 +297,9 @@
 }
 
 var (
-	marshalerType   = reflect.TypeOf((*Marshaler)(nil)).Elem()
-	unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
+	marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
 )
 
-// isMarshaler reports whether type t implements Marshaler.
-func isMarshaler(t reflect.Type) bool {
-	// We're checking for (likely) pointer-receiver methods
-	// so if t is not a pointer, something is very wrong.
-	// The calls above only invoke isMarshaler on pointer types.
-	if t.Kind() != reflect.Ptr {
-		panic("proto: misuse of isMarshaler")
-	}
-	return t.Implements(marshalerType)
-}
-
-// isUnmarshaler reports whether type t implements Unmarshaler.
-func isUnmarshaler(t reflect.Type) bool {
-	// We're checking for (likely) pointer-receiver methods
-	// so if t is not a pointer, something is very wrong.
-	// The calls above only invoke isUnmarshaler on pointer types.
-	if t.Kind() != reflect.Ptr {
-		panic("proto: misuse of isUnmarshaler")
-	}
-	return t.Implements(unmarshalerType)
-}
-
 // Init populates the properties from a protocol buffer struct tag.
 func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
 	p.init(typ, name, tag, f, true)
@@ -621,14 +309,11 @@
 	// "bytes,49,opt,def=hello!"
 	p.Name = name
 	p.OrigName = name
-	if f != nil {
-		p.field = toField(f)
-	}
 	if tag == "" {
 		return
 	}
 	p.Parse(tag)
-	p.setEncAndDec(typ, f, lockGetProp)
+	p.setFieldProps(typ, f, lockGetProp)
 }
 
 var (
@@ -678,9 +363,6 @@
 	propertiesMap[t] = prop
 
 	// build properties
-	prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) ||
-		reflect.PtrTo(t).Implements(extendableProtoV1Type)
-	prop.unrecField = invalidField
 	prop.Prop = make([]*Properties, t.NumField())
 	prop.order = make([]int, t.NumField())
 
@@ -690,17 +372,6 @@
 		name := f.Name
 		p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
 
-		if f.Name == "XXX_InternalExtensions" { // special case
-			p.enc = (*Buffer).enc_exts
-			p.dec = nil // not needed
-			p.size = size_exts
-		} else if f.Name == "XXX_extensions" { // special case
-			p.enc = (*Buffer).enc_map
-			p.dec = nil // not needed
-			p.size = size_map
-		} else if f.Name == "XXX_unrecognized" { // special case
-			prop.unrecField = toField(&f)
-		}
 		oneof := f.Tag.Get("protobuf_oneof") // special case
 		if oneof != "" {
 			// Oneof fields don't use the traditional protobuf tag.
@@ -715,9 +386,6 @@
 			}
 			print("\n")
 		}
-		if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && oneof == "" {
-			fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
-		}
 	}
 
 	// Re-order prop.order.
@@ -728,8 +396,7 @@
 	}
 	if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
 		var oots []interface{}
-		prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs()
-		prop.stype = t
+		_, _, _, oots = om.XXX_OneofFuncs()
 
 		// Interpret oneof metadata.
 		prop.OneofTypes = make(map[string]*OneofProperties)
@@ -779,30 +446,6 @@
 	return prop
 }
 
-// Return the Properties object for the x[0]'th field of the structure.
-func propByIndex(t reflect.Type, x []int) *Properties {
-	if len(x) != 1 {
-		fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
-		return nil
-	}
-	prop := GetProperties(t)
-	return prop.Prop[x[0]]
-}
-
-// Get the address and type of a pointer to a struct from an interface.
-func getbase(pb Message) (t reflect.Type, b structPointer, err error) {
-	if pb == nil {
-		err = ErrNil
-		return
-	}
-	// get the reflect type of the pointer to the struct.
-	t = reflect.TypeOf(pb)
-	// get the address of the struct.
-	value := reflect.ValueOf(pb)
-	b = toStructPointer(value)
-	return
-}
-
 // A global registry of enum types.
 // The generated code will register the generated maps by calling RegisterEnum.
 
@@ -826,20 +469,42 @@
 // A registry of all linked message types.
 // The string is a fully-qualified proto name ("pkg.Message").
 var (
-	protoTypes    = make(map[string]reflect.Type)
-	revProtoTypes = make(map[reflect.Type]string)
+	protoTypedNils = make(map[string]Message)      // a map from proto names to typed nil pointers
+	protoMapTypes  = make(map[string]reflect.Type) // a map from proto names to map types
+	revProtoTypes  = make(map[reflect.Type]string)
 )
 
 // RegisterType is called from generated code and maps from the fully qualified
 // proto name to the type (pointer to struct) of the protocol buffer.
 func RegisterType(x Message, name string) {
-	if _, ok := protoTypes[name]; ok {
+	if _, ok := protoTypedNils[name]; ok {
 		// TODO: Some day, make this a panic.
 		log.Printf("proto: duplicate proto type registered: %s", name)
 		return
 	}
 	t := reflect.TypeOf(x)
-	protoTypes[name] = t
+	if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 {
+		// Generated code always calls RegisterType with nil x.
+		// This check is just for extra safety.
+		protoTypedNils[name] = x
+	} else {
+		protoTypedNils[name] = reflect.Zero(t).Interface().(Message)
+	}
+	revProtoTypes[t] = name
+}
+
+// RegisterMapType is called from generated code and maps from the fully qualified
+// proto name to the native map type of the proto map definition.
+func RegisterMapType(x interface{}, name string) {
+	if reflect.TypeOf(x).Kind() != reflect.Map {
+		panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name))
+	}
+	if _, ok := protoMapTypes[name]; ok {
+		log.Printf("proto: duplicate proto type registered: %s", name)
+		return
+	}
+	t := reflect.TypeOf(x)
+	protoMapTypes[name] = t
 	revProtoTypes[t] = name
 }
 
@@ -855,7 +520,14 @@
 }
 
 // MessageType returns the message type (pointer to struct) for a named message.
-func MessageType(name string) reflect.Type { return protoTypes[name] }
+// The type is not guaranteed to implement proto.Message if the name refers to a
+// map entry.
+func MessageType(name string) reflect.Type {
+	if t, ok := protoTypedNils[name]; ok {
+		return reflect.TypeOf(t)
+	}
+	return protoMapTypes[name]
+}
 
 // A registry of all linked proto files.
 var (
diff --git a/proto/proto3_proto/proto3.pb.go b/proto/proto3_proto/proto3.pb.go
index cc4d048..a80f089 100644
--- a/proto/proto3_proto/proto3.pb.go
+++ b/proto/proto3_proto/proto3.pb.go
@@ -1,27 +1,13 @@
-// Code generated by protoc-gen-go.
+// Code generated by protoc-gen-go. DO NOT EDIT.
 // source: proto3_proto/proto3.proto
-// DO NOT EDIT!
 
-/*
-Package proto3_proto is a generated protocol buffer package.
-
-It is generated from these files:
-	proto3_proto/proto3.proto
-
-It has these top-level messages:
-	Message
-	Nested
-	MessageWithMap
-	IntMap
-	IntMaps
-*/
 package proto3_proto
 
 import proto "github.com/golang/protobuf/proto"
 import fmt "fmt"
 import math "math"
-import google_protobuf "github.com/golang/protobuf/ptypes/any"
-import testdata "github.com/golang/protobuf/proto/testdata"
+import test_proto "github.com/golang/protobuf/proto/test_proto"
+import any "github.com/golang/protobuf/ptypes/any"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
@@ -59,33 +45,58 @@
 func (x Message_Humour) String() string {
 	return proto.EnumName(Message_Humour_name, int32(x))
 }
-func (Message_Humour) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} }
-
-type Message struct {
-	Name         string                           `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
-	Hilarity     Message_Humour                   `protobuf:"varint,2,opt,name=hilarity,enum=proto3_proto.Message_Humour" json:"hilarity,omitempty"`
-	HeightInCm   uint32                           `protobuf:"varint,3,opt,name=height_in_cm,json=heightInCm" json:"height_in_cm,omitempty"`
-	Data         []byte                           `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"`
-	ResultCount  int64                            `protobuf:"varint,7,opt,name=result_count,json=resultCount" json:"result_count,omitempty"`
-	TrueScotsman bool                             `protobuf:"varint,8,opt,name=true_scotsman,json=trueScotsman" json:"true_scotsman,omitempty"`
-	Score        float32                          `protobuf:"fixed32,9,opt,name=score" json:"score,omitempty"`
-	Key          []uint64                         `protobuf:"varint,5,rep,packed,name=key" json:"key,omitempty"`
-	ShortKey     []int32                          `protobuf:"varint,19,rep,packed,name=short_key,json=shortKey" json:"short_key,omitempty"`
-	Nested       *Nested                          `protobuf:"bytes,6,opt,name=nested" json:"nested,omitempty"`
-	RFunny       []Message_Humour                 `protobuf:"varint,16,rep,packed,name=r_funny,json=rFunny,enum=proto3_proto.Message_Humour" json:"r_funny,omitempty"`
-	Terrain      map[string]*Nested               `protobuf:"bytes,10,rep,name=terrain" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	Proto2Field  *testdata.SubDefaults            `protobuf:"bytes,11,opt,name=proto2_field,json=proto2Field" json:"proto2_field,omitempty"`
-	Proto2Value  map[string]*testdata.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value,json=proto2Value" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
-	Anything     *google_protobuf.Any             `protobuf:"bytes,14,opt,name=anything" json:"anything,omitempty"`
-	ManyThings   []*google_protobuf.Any           `protobuf:"bytes,15,rep,name=many_things,json=manyThings" json:"many_things,omitempty"`
-	Submessage   *Message                         `protobuf:"bytes,17,opt,name=submessage" json:"submessage,omitempty"`
-	Children     []*Message                       `protobuf:"bytes,18,rep,name=children" json:"children,omitempty"`
+func (Message_Humour) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_proto3_e706e4ff19a5dbea, []int{0, 0}
 }
 
-func (m *Message) Reset()                    { *m = Message{} }
-func (m *Message) String() string            { return proto.CompactTextString(m) }
-func (*Message) ProtoMessage()               {}
-func (*Message) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+type Message struct {
+	Name                 string                             `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	Hilarity             Message_Humour                     `protobuf:"varint,2,opt,name=hilarity,enum=proto3_proto.Message_Humour" json:"hilarity,omitempty"`
+	HeightInCm           uint32                             `protobuf:"varint,3,opt,name=height_in_cm,json=heightInCm" json:"height_in_cm,omitempty"`
+	Data                 []byte                             `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"`
+	ResultCount          int64                              `protobuf:"varint,7,opt,name=result_count,json=resultCount" json:"result_count,omitempty"`
+	TrueScotsman         bool                               `protobuf:"varint,8,opt,name=true_scotsman,json=trueScotsman" json:"true_scotsman,omitempty"`
+	Score                float32                            `protobuf:"fixed32,9,opt,name=score" json:"score,omitempty"`
+	Key                  []uint64                           `protobuf:"varint,5,rep,packed,name=key" json:"key,omitempty"`
+	ShortKey             []int32                            `protobuf:"varint,19,rep,packed,name=short_key,json=shortKey" json:"short_key,omitempty"`
+	Nested               *Nested                            `protobuf:"bytes,6,opt,name=nested" json:"nested,omitempty"`
+	RFunny               []Message_Humour                   `protobuf:"varint,16,rep,packed,name=r_funny,json=rFunny,enum=proto3_proto.Message_Humour" json:"r_funny,omitempty"`
+	Terrain              map[string]*Nested                 `protobuf:"bytes,10,rep,name=terrain" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	Proto2Field          *test_proto.SubDefaults            `protobuf:"bytes,11,opt,name=proto2_field,json=proto2Field" json:"proto2_field,omitempty"`
+	Proto2Value          map[string]*test_proto.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value,json=proto2Value" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	Anything             *any.Any                           `protobuf:"bytes,14,opt,name=anything" json:"anything,omitempty"`
+	ManyThings           []*any.Any                         `protobuf:"bytes,15,rep,name=many_things,json=manyThings" json:"many_things,omitempty"`
+	Submessage           *Message                           `protobuf:"bytes,17,opt,name=submessage" json:"submessage,omitempty"`
+	Children             []*Message                         `protobuf:"bytes,18,rep,name=children" json:"children,omitempty"`
+	StringMap            map[string]string                  `protobuf:"bytes,20,rep,name=string_map,json=stringMap" json:"string_map,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	XXX_NoUnkeyedLiteral struct{}                           `json:"-"`
+	XXX_unrecognized     []byte                             `json:"-"`
+	XXX_sizecache        int32                              `json:"-"`
+}
+
+func (m *Message) Reset()         { *m = Message{} }
+func (m *Message) String() string { return proto.CompactTextString(m) }
+func (*Message) ProtoMessage()    {}
+func (*Message) Descriptor() ([]byte, []int) {
+	return fileDescriptor_proto3_e706e4ff19a5dbea, []int{0}
+}
+func (m *Message) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Message.Unmarshal(m, b)
+}
+func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Message.Marshal(b, m, deterministic)
+}
+func (dst *Message) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Message.Merge(dst, src)
+}
+func (m *Message) XXX_Size() int {
+	return xxx_messageInfo_Message.Size(m)
+}
+func (m *Message) XXX_DiscardUnknown() {
+	xxx_messageInfo_Message.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Message proto.InternalMessageInfo
 
 func (m *Message) GetName() string {
 	if m != nil {
@@ -171,28 +182,28 @@
 	return nil
 }
 
-func (m *Message) GetProto2Field() *testdata.SubDefaults {
+func (m *Message) GetProto2Field() *test_proto.SubDefaults {
 	if m != nil {
 		return m.Proto2Field
 	}
 	return nil
 }
 
-func (m *Message) GetProto2Value() map[string]*testdata.SubDefaults {
+func (m *Message) GetProto2Value() map[string]*test_proto.SubDefaults {
 	if m != nil {
 		return m.Proto2Value
 	}
 	return nil
 }
 
-func (m *Message) GetAnything() *google_protobuf.Any {
+func (m *Message) GetAnything() *any.Any {
 	if m != nil {
 		return m.Anything
 	}
 	return nil
 }
 
-func (m *Message) GetManyThings() []*google_protobuf.Any {
+func (m *Message) GetManyThings() []*any.Any {
 	if m != nil {
 		return m.ManyThings
 	}
@@ -213,15 +224,44 @@
 	return nil
 }
 
-type Nested struct {
-	Bunny string `protobuf:"bytes,1,opt,name=bunny" json:"bunny,omitempty"`
-	Cute  bool   `protobuf:"varint,2,opt,name=cute" json:"cute,omitempty"`
+func (m *Message) GetStringMap() map[string]string {
+	if m != nil {
+		return m.StringMap
+	}
+	return nil
 }
 
-func (m *Nested) Reset()                    { *m = Nested{} }
-func (m *Nested) String() string            { return proto.CompactTextString(m) }
-func (*Nested) ProtoMessage()               {}
-func (*Nested) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
+type Nested struct {
+	Bunny                string   `protobuf:"bytes,1,opt,name=bunny" json:"bunny,omitempty"`
+	Cute                 bool     `protobuf:"varint,2,opt,name=cute" json:"cute,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Nested) Reset()         { *m = Nested{} }
+func (m *Nested) String() string { return proto.CompactTextString(m) }
+func (*Nested) ProtoMessage()    {}
+func (*Nested) Descriptor() ([]byte, []int) {
+	return fileDescriptor_proto3_e706e4ff19a5dbea, []int{1}
+}
+func (m *Nested) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Nested.Unmarshal(m, b)
+}
+func (m *Nested) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Nested.Marshal(b, m, deterministic)
+}
+func (dst *Nested) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Nested.Merge(dst, src)
+}
+func (m *Nested) XXX_Size() int {
+	return xxx_messageInfo_Nested.Size(m)
+}
+func (m *Nested) XXX_DiscardUnknown() {
+	xxx_messageInfo_Nested.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Nested proto.InternalMessageInfo
 
 func (m *Nested) GetBunny() string {
 	if m != nil {
@@ -238,13 +278,35 @@
 }
 
 type MessageWithMap struct {
-	ByteMapping map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping,json=byteMapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	ByteMapping          map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping,json=byteMapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
+	XXX_unrecognized     []byte          `json:"-"`
+	XXX_sizecache        int32           `json:"-"`
 }
 
-func (m *MessageWithMap) Reset()                    { *m = MessageWithMap{} }
-func (m *MessageWithMap) String() string            { return proto.CompactTextString(m) }
-func (*MessageWithMap) ProtoMessage()               {}
-func (*MessageWithMap) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
+func (m *MessageWithMap) Reset()         { *m = MessageWithMap{} }
+func (m *MessageWithMap) String() string { return proto.CompactTextString(m) }
+func (*MessageWithMap) ProtoMessage()    {}
+func (*MessageWithMap) Descriptor() ([]byte, []int) {
+	return fileDescriptor_proto3_e706e4ff19a5dbea, []int{2}
+}
+func (m *MessageWithMap) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_MessageWithMap.Unmarshal(m, b)
+}
+func (m *MessageWithMap) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_MessageWithMap.Marshal(b, m, deterministic)
+}
+func (dst *MessageWithMap) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_MessageWithMap.Merge(dst, src)
+}
+func (m *MessageWithMap) XXX_Size() int {
+	return xxx_messageInfo_MessageWithMap.Size(m)
+}
+func (m *MessageWithMap) XXX_DiscardUnknown() {
+	xxx_messageInfo_MessageWithMap.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MessageWithMap proto.InternalMessageInfo
 
 func (m *MessageWithMap) GetByteMapping() map[bool][]byte {
 	if m != nil {
@@ -254,13 +316,35 @@
 }
 
 type IntMap struct {
-	Rtt map[int32]int32 `protobuf:"bytes,1,rep,name=rtt" json:"rtt,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	Rtt                  map[int32]int32 `protobuf:"bytes,1,rep,name=rtt" json:"rtt,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
+	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
+	XXX_unrecognized     []byte          `json:"-"`
+	XXX_sizecache        int32           `json:"-"`
 }
 
-func (m *IntMap) Reset()                    { *m = IntMap{} }
-func (m *IntMap) String() string            { return proto.CompactTextString(m) }
-func (*IntMap) ProtoMessage()               {}
-func (*IntMap) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
+func (m *IntMap) Reset()         { *m = IntMap{} }
+func (m *IntMap) String() string { return proto.CompactTextString(m) }
+func (*IntMap) ProtoMessage()    {}
+func (*IntMap) Descriptor() ([]byte, []int) {
+	return fileDescriptor_proto3_e706e4ff19a5dbea, []int{3}
+}
+func (m *IntMap) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_IntMap.Unmarshal(m, b)
+}
+func (m *IntMap) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_IntMap.Marshal(b, m, deterministic)
+}
+func (dst *IntMap) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_IntMap.Merge(dst, src)
+}
+func (m *IntMap) XXX_Size() int {
+	return xxx_messageInfo_IntMap.Size(m)
+}
+func (m *IntMap) XXX_DiscardUnknown() {
+	xxx_messageInfo_IntMap.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_IntMap proto.InternalMessageInfo
 
 func (m *IntMap) GetRtt() map[int32]int32 {
 	if m != nil {
@@ -270,13 +354,35 @@
 }
 
 type IntMaps struct {
-	Maps []*IntMap `protobuf:"bytes,1,rep,name=maps" json:"maps,omitempty"`
+	Maps                 []*IntMap `protobuf:"bytes,1,rep,name=maps" json:"maps,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
+	XXX_unrecognized     []byte    `json:"-"`
+	XXX_sizecache        int32     `json:"-"`
 }
 
-func (m *IntMaps) Reset()                    { *m = IntMaps{} }
-func (m *IntMaps) String() string            { return proto.CompactTextString(m) }
-func (*IntMaps) ProtoMessage()               {}
-func (*IntMaps) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
+func (m *IntMaps) Reset()         { *m = IntMaps{} }
+func (m *IntMaps) String() string { return proto.CompactTextString(m) }
+func (*IntMaps) ProtoMessage()    {}
+func (*IntMaps) Descriptor() ([]byte, []int) {
+	return fileDescriptor_proto3_e706e4ff19a5dbea, []int{4}
+}
+func (m *IntMaps) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_IntMaps.Unmarshal(m, b)
+}
+func (m *IntMaps) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_IntMaps.Marshal(b, m, deterministic)
+}
+func (dst *IntMaps) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_IntMaps.Merge(dst, src)
+}
+func (m *IntMaps) XXX_Size() int {
+	return xxx_messageInfo_IntMaps.Size(m)
+}
+func (m *IntMaps) XXX_DiscardUnknown() {
+	xxx_messageInfo_IntMaps.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_IntMaps proto.InternalMessageInfo
 
 func (m *IntMaps) GetMaps() []*IntMap {
 	if m != nil {
@@ -287,61 +393,69 @@
 
 func init() {
 	proto.RegisterType((*Message)(nil), "proto3_proto.Message")
+	proto.RegisterMapType((map[string]*test_proto.SubDefaults)(nil), "proto3_proto.Message.Proto2ValueEntry")
+	proto.RegisterMapType((map[string]string)(nil), "proto3_proto.Message.StringMapEntry")
+	proto.RegisterMapType((map[string]*Nested)(nil), "proto3_proto.Message.TerrainEntry")
 	proto.RegisterType((*Nested)(nil), "proto3_proto.Nested")
 	proto.RegisterType((*MessageWithMap)(nil), "proto3_proto.MessageWithMap")
+	proto.RegisterMapType((map[bool][]byte)(nil), "proto3_proto.MessageWithMap.ByteMappingEntry")
 	proto.RegisterType((*IntMap)(nil), "proto3_proto.IntMap")
+	proto.RegisterMapType((map[int32]int32)(nil), "proto3_proto.IntMap.RttEntry")
 	proto.RegisterType((*IntMaps)(nil), "proto3_proto.IntMaps")
 	proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value)
 }
 
-func init() { proto.RegisterFile("proto3_proto/proto3.proto", fileDescriptor0) }
+func init() { proto.RegisterFile("proto3_proto/proto3.proto", fileDescriptor_proto3_e706e4ff19a5dbea) }
 
-var fileDescriptor0 = []byte{
-	// 733 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x53, 0x6d, 0x6f, 0xf3, 0x34,
-	0x14, 0x25, 0x4d, 0x5f, 0xd2, 0x9b, 0x74, 0x0b, 0x5e, 0x91, 0xbc, 0x02, 0x52, 0x28, 0x12, 0x8a,
-	0x78, 0x49, 0xa1, 0xd3, 0xd0, 0x84, 0x10, 0x68, 0x1b, 0x9b, 0xa8, 0xd6, 0x95, 0xca, 0xdd, 0x98,
-	0xf8, 0x14, 0xa5, 0xad, 0xdb, 0x46, 0x34, 0x4e, 0x49, 0x1c, 0xa4, 0xfc, 0x1d, 0xfe, 0x28, 0x8f,
-	0x6c, 0xa7, 0x5d, 0x36, 0x65, 0xcf, 0xf3, 0x29, 0xf6, 0xf1, 0xb9, 0xf7, 0x9c, 0x1c, 0x5f, 0xc3,
-	0xe9, 0x2e, 0x89, 0x79, 0x7c, 0xe6, 0xcb, 0xcf, 0x40, 0x6d, 0x3c, 0xf9, 0x41, 0x56, 0xf9, 0xa8,
-	0x77, 0xba, 0x8e, 0xe3, 0xf5, 0x96, 0x2a, 0xca, 0x3c, 0x5b, 0x0d, 0x02, 0x96, 0x2b, 0x62, 0xef,
-	0x84, 0xd3, 0x94, 0x2f, 0x03, 0x1e, 0x0c, 0xc4, 0x42, 0x81, 0xfd, 0xff, 0x5b, 0xd0, 0xba, 0xa7,
-	0x69, 0x1a, 0xac, 0x29, 0x42, 0x50, 0x67, 0x41, 0x44, 0xb1, 0xe6, 0x68, 0x6e, 0x9b, 0xc8, 0x35,
-	0xba, 0x00, 0x63, 0x13, 0x6e, 0x83, 0x24, 0xe4, 0x39, 0xae, 0x39, 0x9a, 0x7b, 0x34, 0xfc, 0xcc,
-	0x2b, 0x0b, 0x7a, 0x45, 0xb1, 0xf7, 0x7b, 0x16, 0xc5, 0x59, 0x42, 0x0e, 0x6c, 0xe4, 0x80, 0xb5,
-	0xa1, 0xe1, 0x7a, 0xc3, 0xfd, 0x90, 0xf9, 0x8b, 0x08, 0xeb, 0x8e, 0xe6, 0x76, 0x08, 0x28, 0x6c,
-	0xc4, 0xae, 0x23, 0xa1, 0x27, 0xec, 0xe0, 0xba, 0xa3, 0xb9, 0x16, 0x91, 0x6b, 0xf4, 0x05, 0x58,
-	0x09, 0x4d, 0xb3, 0x2d, 0xf7, 0x17, 0x71, 0xc6, 0x38, 0x6e, 0x39, 0x9a, 0xab, 0x13, 0x53, 0x61,
-	0xd7, 0x02, 0x42, 0x5f, 0x42, 0x87, 0x27, 0x19, 0xf5, 0xd3, 0x45, 0xcc, 0xd3, 0x28, 0x60, 0xd8,
-	0x70, 0x34, 0xd7, 0x20, 0x96, 0x00, 0x67, 0x05, 0x86, 0xba, 0xd0, 0x48, 0x17, 0x71, 0x42, 0x71,
-	0xdb, 0xd1, 0xdc, 0x1a, 0x51, 0x1b, 0x64, 0x83, 0xfe, 0x37, 0xcd, 0x71, 0xc3, 0xd1, 0xdd, 0x3a,
-	0x11, 0x4b, 0xf4, 0x29, 0xb4, 0xd3, 0x4d, 0x9c, 0x70, 0x5f, 0xe0, 0x27, 0x8e, 0xee, 0x36, 0x88,
-	0x21, 0x81, 0x3b, 0x9a, 0xa3, 0x6f, 0xa1, 0xc9, 0x68, 0xca, 0xe9, 0x12, 0x37, 0x1d, 0xcd, 0x35,
-	0x87, 0xdd, 0x97, 0xbf, 0x3e, 0x91, 0x67, 0xa4, 0xe0, 0xa0, 0x73, 0x68, 0x25, 0xfe, 0x2a, 0x63,
-	0x2c, 0xc7, 0xb6, 0xa3, 0x7f, 0x30, 0xa9, 0x66, 0x72, 0x2b, 0xb8, 0xe8, 0x67, 0x68, 0x71, 0x9a,
-	0x24, 0x41, 0xc8, 0x30, 0x38, 0xba, 0x6b, 0x0e, 0xfb, 0xd5, 0x65, 0x0f, 0x8a, 0x74, 0xc3, 0x78,
-	0x92, 0x93, 0x7d, 0x09, 0xba, 0x00, 0x75, 0xff, 0x43, 0x7f, 0x15, 0xd2, 0xed, 0x12, 0x9b, 0xd2,
-	0xe8, 0x27, 0xde, 0xfe, 0xae, 0xbd, 0x59, 0x36, 0xff, 0x8d, 0xae, 0x82, 0x6c, 0xcb, 0x53, 0x62,
-	0x2a, 0xea, 0xad, 0x60, 0xa2, 0xd1, 0xa1, 0xf2, 0xdf, 0x60, 0x9b, 0x51, 0xdc, 0x91, 0xe2, 0x5f,
-	0x55, 0x8b, 0x4f, 0x25, 0xf3, 0x4f, 0x41, 0x54, 0x06, 0x8a, 0x56, 0x12, 0x41, 0xdf, 0x83, 0x11,
-	0xb0, 0x9c, 0x6f, 0x42, 0xb6, 0xc6, 0x47, 0x45, 0x52, 0x6a, 0x0e, 0xbd, 0xfd, 0x1c, 0x7a, 0x97,
-	0x2c, 0x27, 0x07, 0x16, 0x3a, 0x07, 0x33, 0x0a, 0x58, 0xee, 0xcb, 0x5d, 0x8a, 0x8f, 0xa5, 0x76,
-	0x75, 0x11, 0x08, 0xe2, 0x83, 0xe4, 0xa1, 0x73, 0x80, 0x34, 0x9b, 0x47, 0xca, 0x14, 0xfe, 0xb8,
-	0xf8, 0xd7, 0x2a, 0xc7, 0xa4, 0x44, 0x44, 0x3f, 0x80, 0xb1, 0xd8, 0x84, 0xdb, 0x65, 0x42, 0x19,
-	0x46, 0x52, 0xea, 0x8d, 0xa2, 0x03, 0xad, 0x37, 0x05, 0xab, 0x1c, 0xf8, 0x7e, 0x72, 0xd4, 0xd3,
-	0x90, 0x93, 0xf3, 0x35, 0x34, 0x54, 0x70, 0xb5, 0xf7, 0xcc, 0x86, 0xa2, 0xfc, 0x54, 0xbb, 0xd0,
-	0x7a, 0x8f, 0x60, 0xbf, 0x4e, 0xb1, 0xa2, 0xeb, 0x37, 0x2f, 0xbb, 0xbe, 0x71, 0x91, 0xcf, 0x6d,
-	0xfb, 0xbf, 0x42, 0x53, 0x0d, 0x14, 0x32, 0xa1, 0xf5, 0x38, 0xb9, 0x9b, 0xfc, 0xf1, 0x34, 0xb1,
-	0x3f, 0x42, 0x06, 0xd4, 0xa7, 0x8f, 0x93, 0x99, 0xad, 0xa1, 0x0e, 0xb4, 0x67, 0xe3, 0xcb, 0xe9,
-	0xec, 0x61, 0x74, 0x7d, 0x67, 0xd7, 0xd0, 0x31, 0x98, 0x57, 0xa3, 0xf1, 0xd8, 0xbf, 0xba, 0x1c,
-	0x8d, 0x6f, 0xfe, 0xb2, 0xf5, 0xfe, 0x10, 0x9a, 0xca, 0xac, 0x78, 0x33, 0x73, 0x39, 0xbe, 0xca,
-	0x8f, 0xda, 0x88, 0x57, 0xba, 0xc8, 0xb8, 0x32, 0x64, 0x10, 0xb9, 0xee, 0xff, 0xa7, 0xc1, 0x51,
-	0x91, 0xd9, 0x53, 0xc8, 0x37, 0xf7, 0xc1, 0x0e, 0x4d, 0xc1, 0x9a, 0xe7, 0x9c, 0xfa, 0x51, 0xb0,
-	0xdb, 0x89, 0x39, 0xd0, 0x64, 0xce, 0xdf, 0x55, 0xe6, 0x5c, 0xd4, 0x78, 0x57, 0x39, 0xa7, 0xf7,
-	0x8a, 0x5f, 0x4c, 0xd5, 0xfc, 0x19, 0xe9, 0xfd, 0x02, 0xf6, 0x6b, 0x42, 0x39, 0x30, 0x43, 0x05,
-	0xd6, 0x2d, 0x07, 0x66, 0x95, 0x93, 0xf9, 0x07, 0x9a, 0x23, 0xc6, 0x85, 0xb7, 0x01, 0xe8, 0x09,
-	0xe7, 0x85, 0xa5, 0xcf, 0x5f, 0x5a, 0x52, 0x14, 0x8f, 0x70, 0xae, 0x2c, 0x08, 0x66, 0xef, 0x47,
-	0x30, 0xf6, 0x40, 0x59, 0xb2, 0x51, 0x21, 0xd9, 0x28, 0x4b, 0x9e, 0x41, 0x4b, 0xf5, 0x4b, 0x91,
-	0x0b, 0xf5, 0x28, 0xd8, 0xa5, 0x85, 0x68, 0xb7, 0x4a, 0x94, 0x48, 0xc6, 0xbc, 0xa9, 0x8e, 0xde,
-	0x05, 0x00, 0x00, 0xff, 0xff, 0x75, 0x38, 0xad, 0x84, 0xe4, 0x05, 0x00, 0x00,
+var fileDescriptor_proto3_e706e4ff19a5dbea = []byte{
+	// 774 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x94, 0x6f, 0x8f, 0xdb, 0x44,
+	0x10, 0xc6, 0x71, 0x9c, 0x3f, 0xce, 0xd8, 0x77, 0x35, 0x4b, 0x2a, 0xb6, 0x01, 0x24, 0x13, 0x10,
+	0xb2, 0x10, 0xf5, 0x41, 0xaa, 0x43, 0x55, 0x55, 0x81, 0xee, 0x8e, 0x56, 0x44, 0x77, 0x17, 0xa2,
+	0xcd, 0x95, 0x13, 0xaf, 0xac, 0x4d, 0x6e, 0x93, 0x58, 0xc4, 0xeb, 0xe0, 0x5d, 0x23, 0xf9, 0x0b,
+	0xf0, 0x41, 0xf8, 0xa4, 0x68, 0x77, 0x9d, 0xd4, 0xa9, 0x5c, 0xfa, 0x2a, 0xbb, 0x8f, 0x7f, 0x33,
+	0xcf, 0x78, 0x66, 0x1c, 0x78, 0xb2, 0xcb, 0x33, 0x99, 0x3d, 0x8b, 0xf5, 0xcf, 0x99, 0xb9, 0x44,
+	0xfa, 0x07, 0x79, 0xf5, 0x47, 0xc3, 0x27, 0xeb, 0x2c, 0x5b, 0x6f, 0x99, 0x41, 0x16, 0xc5, 0xea,
+	0x8c, 0xf2, 0xd2, 0x80, 0xc3, 0xc7, 0x92, 0x09, 0x59, 0x65, 0x50, 0x47, 0x23, 0x8f, 0xfe, 0xe9,
+	0x43, 0xef, 0x96, 0x09, 0x41, 0xd7, 0x0c, 0x21, 0x68, 0x73, 0x9a, 0x32, 0x6c, 0x05, 0x56, 0xd8,
+	0x27, 0xfa, 0x8c, 0x9e, 0x83, 0xb3, 0x49, 0xb6, 0x34, 0x4f, 0x64, 0x89, 0x5b, 0x81, 0x15, 0x9e,
+	0x8e, 0x3f, 0x8f, 0xea, 0x96, 0x51, 0x15, 0x1c, 0xfd, 0x5a, 0xa4, 0x59, 0x91, 0x93, 0x03, 0x8d,
+	0x02, 0xf0, 0x36, 0x2c, 0x59, 0x6f, 0x64, 0x9c, 0xf0, 0x78, 0x99, 0x62, 0x3b, 0xb0, 0xc2, 0x13,
+	0x02, 0x46, 0x9b, 0xf0, 0xab, 0x54, 0xf9, 0x3d, 0x50, 0x49, 0x71, 0x3b, 0xb0, 0x42, 0x8f, 0xe8,
+	0x33, 0xfa, 0x12, 0xbc, 0x9c, 0x89, 0x62, 0x2b, 0xe3, 0x65, 0x56, 0x70, 0x89, 0x7b, 0x81, 0x15,
+	0xda, 0xc4, 0x35, 0xda, 0x95, 0x92, 0xd0, 0x57, 0x70, 0x22, 0xf3, 0x82, 0xc5, 0x62, 0x99, 0x49,
+	0x91, 0x52, 0x8e, 0x9d, 0xc0, 0x0a, 0x1d, 0xe2, 0x29, 0x71, 0x5e, 0x69, 0x68, 0x00, 0x1d, 0xb1,
+	0xcc, 0x72, 0x86, 0xfb, 0x81, 0x15, 0xb6, 0x88, 0xb9, 0x20, 0x1f, 0xec, 0x3f, 0x59, 0x89, 0x3b,
+	0x81, 0x1d, 0xb6, 0x89, 0x3a, 0xa2, 0xcf, 0xa0, 0x2f, 0x36, 0x59, 0x2e, 0x63, 0xa5, 0x7f, 0x12,
+	0xd8, 0x61, 0x87, 0x38, 0x5a, 0xb8, 0x66, 0x25, 0xfa, 0x0e, 0xba, 0x9c, 0x09, 0xc9, 0x1e, 0x70,
+	0x37, 0xb0, 0x42, 0x77, 0x3c, 0x38, 0x7e, 0xf5, 0xa9, 0x7e, 0x46, 0x2a, 0x06, 0x9d, 0x43, 0x2f,
+	0x8f, 0x57, 0x05, 0xe7, 0x25, 0xf6, 0x03, 0xfb, 0x83, 0x9d, 0xea, 0xe6, 0xaf, 0x15, 0x8b, 0x5e,
+	0x42, 0x4f, 0xb2, 0x3c, 0xa7, 0x09, 0xc7, 0x10, 0xd8, 0xa1, 0x3b, 0x1e, 0x35, 0x87, 0xdd, 0x19,
+	0xe8, 0x15, 0x97, 0x79, 0x49, 0xf6, 0x21, 0xe8, 0x05, 0x98, 0x0d, 0x18, 0xc7, 0xab, 0x84, 0x6d,
+	0x1f, 0xb0, 0xab, 0x0b, 0xfd, 0x34, 0x7a, 0x3b, 0xed, 0x68, 0x5e, 0x2c, 0x7e, 0x61, 0x2b, 0x5a,
+	0x6c, 0xa5, 0x20, 0xae, 0x81, 0x5f, 0x2b, 0x16, 0x4d, 0x0e, 0xb1, 0x7f, 0xd3, 0x6d, 0xc1, 0xf0,
+	0x89, 0xb6, 0xff, 0xa6, 0xd9, 0x7e, 0xa6, 0xc9, 0xdf, 0x15, 0x68, 0x4a, 0xa8, 0x52, 0x69, 0x05,
+	0x7d, 0x0f, 0x0e, 0xe5, 0xa5, 0xdc, 0x24, 0x7c, 0x8d, 0x4f, 0xab, 0x5e, 0x99, 0x5d, 0x8c, 0xf6,
+	0xbb, 0x18, 0x5d, 0xf0, 0x92, 0x1c, 0x28, 0x74, 0x0e, 0x6e, 0x4a, 0x79, 0x19, 0xeb, 0x9b, 0xc0,
+	0x8f, 0xb4, 0x77, 0x73, 0x10, 0x28, 0xf0, 0x4e, 0x73, 0xe8, 0x1c, 0x40, 0x14, 0x8b, 0xd4, 0x14,
+	0x85, 0x3f, 0xd6, 0x56, 0x8f, 0x1b, 0x2b, 0x26, 0x35, 0x10, 0xfd, 0x00, 0xce, 0x72, 0x93, 0x6c,
+	0x1f, 0x72, 0xc6, 0x31, 0xd2, 0x56, 0xef, 0x09, 0x3a, 0x60, 0xe8, 0x0a, 0x40, 0xc8, 0x3c, 0xe1,
+	0xeb, 0x38, 0xa5, 0x3b, 0x3c, 0xd0, 0x41, 0x5f, 0x37, 0xf7, 0x66, 0xae, 0xb9, 0x5b, 0xba, 0x33,
+	0x9d, 0xe9, 0x8b, 0xfd, 0x7d, 0x38, 0x03, 0xaf, 0x3e, 0xb7, 0xfd, 0x02, 0x9a, 0x2f, 0x4c, 0x2f,
+	0xe0, 0xb7, 0xd0, 0x31, 0xdd, 0x6f, 0xfd, 0xcf, 0x8a, 0x19, 0xe4, 0x45, 0xeb, 0xb9, 0x35, 0xbc,
+	0x07, 0xff, 0xdd, 0x51, 0x34, 0x64, 0x7d, 0x7a, 0x9c, 0xf5, 0xbd, 0xfb, 0x50, 0x4b, 0xfc, 0x12,
+	0x4e, 0x8f, 0xdf, 0xa3, 0x21, 0xed, 0xa0, 0x9e, 0xb6, 0x5f, 0x8b, 0x1e, 0xfd, 0x0c, 0x5d, 0xb3,
+	0xd7, 0xc8, 0x85, 0xde, 0x9b, 0xe9, 0xf5, 0xf4, 0xb7, 0xfb, 0xa9, 0xff, 0x11, 0x72, 0xa0, 0x3d,
+	0x7b, 0x33, 0x9d, 0xfb, 0x16, 0x3a, 0x81, 0xfe, 0xfc, 0xe6, 0x62, 0x36, 0xbf, 0x9b, 0x5c, 0x5d,
+	0xfb, 0x2d, 0xf4, 0x08, 0xdc, 0xcb, 0xc9, 0xcd, 0x4d, 0x7c, 0x79, 0x31, 0xb9, 0x79, 0xf5, 0x87,
+	0x6f, 0x8f, 0xc6, 0xd0, 0x35, 0x2f, 0xab, 0x4c, 0x16, 0xfa, 0x2b, 0x32, 0xc6, 0xe6, 0xa2, 0xfe,
+	0x2c, 0x96, 0x85, 0x34, 0xce, 0x0e, 0xd1, 0xe7, 0xd1, 0xbf, 0x16, 0x9c, 0x56, 0x33, 0xb8, 0x4f,
+	0xe4, 0xe6, 0x96, 0xee, 0xd0, 0x0c, 0xbc, 0x45, 0x29, 0x99, 0x9a, 0xd9, 0x4e, 0x2d, 0xa3, 0xa5,
+	0xe7, 0xf6, 0xb4, 0x71, 0x6e, 0x55, 0x4c, 0x74, 0x59, 0x4a, 0x76, 0x6b, 0xf8, 0x6a, 0xb5, 0x17,
+	0x6f, 0x95, 0xe1, 0x4f, 0xe0, 0xbf, 0x0b, 0xd4, 0x3b, 0xe3, 0x34, 0x74, 0xc6, 0xab, 0x77, 0xe6,
+	0x2f, 0xe8, 0x4e, 0xb8, 0x54, 0xb5, 0x9d, 0x81, 0x9d, 0x4b, 0x59, 0x95, 0xf4, 0xc5, 0x71, 0x49,
+	0x06, 0x89, 0x88, 0x94, 0xa6, 0x04, 0x45, 0x0e, 0x7f, 0x04, 0x67, 0x2f, 0xd4, 0x2d, 0x3b, 0x0d,
+	0x96, 0x9d, 0xba, 0xe5, 0x33, 0xe8, 0x99, 0x7c, 0x02, 0x85, 0xd0, 0x4e, 0xe9, 0x4e, 0x54, 0xa6,
+	0x83, 0x26, 0x53, 0xa2, 0x89, 0x45, 0xd7, 0x3c, 0xfa, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x99, 0x24,
+	0x6b, 0x12, 0x6d, 0x06, 0x00, 0x00,
 }
diff --git a/proto/proto3_proto/proto3.proto b/proto/proto3_proto/proto3.proto
index 2048655..c81fe1e 100644
--- a/proto/proto3_proto/proto3.proto
+++ b/proto/proto3_proto/proto3.proto
@@ -32,7 +32,7 @@
 syntax = "proto3";
 
 import "google/protobuf/any.proto";
-import "testdata/test.proto";
+import "test_proto/test.proto";
 
 package proto3_proto;
 
@@ -58,14 +58,16 @@
   repeated Humour r_funny = 16;
 
   map<string, Nested> terrain = 10;
-  testdata.SubDefaults proto2_field = 11;
-  map<string, testdata.SubDefaults> proto2_value = 13;
+  test_proto.SubDefaults proto2_field = 11;
+  map<string, test_proto.SubDefaults> proto2_value = 13;
 
   google.protobuf.Any anything = 14;
   repeated google.protobuf.Any many_things = 15;
 
   Message submessage = 17;
   repeated Message children = 18;
+
+  map<string, string> string_map = 20;
 }
 
 message Nested {
diff --git a/proto/proto3_test.go b/proto/proto3_test.go
index 735837f..73eed6c 100644
--- a/proto/proto3_test.go
+++ b/proto/proto3_test.go
@@ -32,11 +32,12 @@
 package proto_test
 
 import (
+	"bytes"
 	"testing"
 
 	"github.com/golang/protobuf/proto"
 	pb "github.com/golang/protobuf/proto/proto3_proto"
-	tpb "github.com/golang/protobuf/proto/testdata"
+	tpb "github.com/golang/protobuf/proto/test_proto"
 )
 
 func TestProto3ZeroValues(t *testing.T) {
@@ -133,3 +134,18 @@
 		t.Errorf("with in = %v\nproto.SetDefaults(in) =>\ngot %v\nwant %v", in, got, want)
 	}
 }
+
+func TestUnknownFieldPreservation(t *testing.T) {
+	b1 := "\x0a\x05David"      // Known tag 1
+	b2 := "\xc2\x0c\x06Google" // Unknown tag 200
+	b := []byte(b1 + b2)
+
+	m := new(pb.Message)
+	if err := proto.Unmarshal(b, m); err != nil {
+		t.Fatalf("proto.Unmarshal: %v", err)
+	}
+
+	if !bytes.Equal(m.XXX_unrecognized, []byte(b2)) {
+		t.Fatalf("mismatching unknown fields:\ngot  %q\nwant %q", m.XXX_unrecognized, b2)
+	}
+}
diff --git a/proto/size2_test.go b/proto/size2_test.go
index a2729c3..7846b06 100644
--- a/proto/size2_test.go
+++ b/proto/size2_test.go
@@ -55,7 +55,7 @@
 		{1 << 63, 10},
 	}
 	for _, tc := range testCases {
-		size := sizeVarint(tc.n)
+		size := SizeVarint(tc.n)
 		if size != tc.size {
 			t.Errorf("sizeVarint(%d) = %d, want %d", tc.n, size, tc.size)
 		}
diff --git a/proto/size_test.go b/proto/size_test.go
index af1034d..3abac41 100644
--- a/proto/size_test.go
+++ b/proto/size_test.go
@@ -38,7 +38,7 @@
 
 	. "github.com/golang/protobuf/proto"
 	proto3pb "github.com/golang/protobuf/proto/proto3_proto"
-	pb "github.com/golang/protobuf/proto/testdata"
+	pb "github.com/golang/protobuf/proto/test_proto"
 )
 
 var messageWithExtension1 = &pb.MyMessage{Count: Int32(7)}
@@ -59,6 +59,30 @@
 
 }
 
+// non-pointer custom message
+type nonptrMessage struct{}
+
+func (m nonptrMessage) ProtoMessage()  {}
+func (m nonptrMessage) Reset()         {}
+func (m nonptrMessage) String() string { return "" }
+
+func (m nonptrMessage) Marshal() ([]byte, error) {
+	return []byte{42}, nil
+}
+
+// custom message embedding a proto.Message
+type messageWithEmbedding struct {
+	*pb.OtherMessage
+}
+
+func (m *messageWithEmbedding) ProtoMessage()  {}
+func (m *messageWithEmbedding) Reset()         {}
+func (m *messageWithEmbedding) String() string { return "" }
+
+func (m *messageWithEmbedding) Marshal() ([]byte, error) {
+	return []byte{42}, nil
+}
+
 var SizeTests = []struct {
 	desc string
 	pb   Message
@@ -146,6 +170,9 @@
 	{"oneof group", &pb.Oneof{Union: &pb.Oneof_FGroup{&pb.Oneof_F_Group{X: Int32(52)}}}},
 	{"oneof largest tag", &pb.Oneof{Union: &pb.Oneof_F_Largest_Tag{1}}},
 	{"multiple oneofs", &pb.Oneof{Union: &pb.Oneof_F_Int32{1}, Tormato: &pb.Oneof_Value{2}}},
+
+	{"non-pointer message", nonptrMessage{}},
+	{"custom message with embedding", &messageWithEmbedding{&pb.OtherMessage{}}},
 }
 
 func TestSize(t *testing.T) {
diff --git a/proto/table_marshal.go b/proto/table_marshal.go
new file mode 100644
index 0000000..0f212b3
--- /dev/null
+++ b/proto/table_marshal.go
@@ -0,0 +1,2681 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2016 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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.
+
+package proto
+
+import (
+	"errors"
+	"fmt"
+	"math"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"sync/atomic"
+	"unicode/utf8"
+)
+
+// a sizer takes a pointer to a field and the size of its tag, computes the size of
+// the encoded data.
+type sizer func(pointer, int) int
+
+// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format),
+// marshals the field to the end of the slice, returns the slice and error (if any).
+type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error)
+
+// marshalInfo is the information used for marshaling a message.
+type marshalInfo struct {
+	typ          reflect.Type
+	fields       []*marshalFieldInfo
+	unrecognized field                      // offset of XXX_unrecognized
+	extensions   field                      // offset of XXX_InternalExtensions
+	v1extensions field                      // offset of XXX_extensions
+	sizecache    field                      // offset of XXX_sizecache
+	initialized  int32                      // 0 -- only typ is set, 1 -- fully initialized
+	messageset   bool                       // uses message set wire format
+	hasmarshaler bool                       // has custom marshaler
+	sync.RWMutex                            // protect extElems map, also for initialization
+	extElems     map[int32]*marshalElemInfo // info of extension elements
+}
+
+// marshalFieldInfo is the information used for marshaling a field of a message.
+type marshalFieldInfo struct {
+	field      field
+	wiretag    uint64 // tag in wire format
+	tagsize    int    // size of tag in wire format
+	sizer      sizer
+	marshaler  marshaler
+	isPointer  bool
+	required   bool                              // field is required
+	name       string                            // name of the field, for error reporting
+	oneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements
+}
+
+// marshalElemInfo is the information used for marshaling an extension or oneof element.
+type marshalElemInfo struct {
+	wiretag   uint64 // tag in wire format
+	tagsize   int    // size of tag in wire format
+	sizer     sizer
+	marshaler marshaler
+	isptr     bool // elem is pointer typed, thus interface of this type is a direct interface (extension only)
+}
+
+var (
+	marshalInfoMap  = map[reflect.Type]*marshalInfo{}
+	marshalInfoLock sync.Mutex
+)
+
+// getMarshalInfo returns the information to marshal a given type of message.
+// The info it returns may not necessarily initialized.
+// t is the type of the message (NOT the pointer to it).
+func getMarshalInfo(t reflect.Type) *marshalInfo {
+	marshalInfoLock.Lock()
+	u, ok := marshalInfoMap[t]
+	if !ok {
+		u = &marshalInfo{typ: t}
+		marshalInfoMap[t] = u
+	}
+	marshalInfoLock.Unlock()
+	return u
+}
+
+// Size is the entry point from generated code,
+// and should be ONLY called by generated code.
+// It computes the size of encoded data of msg.
+// a is a pointer to a place to store cached marshal info.
+func (a *InternalMessageInfo) Size(msg Message) int {
+	u := getMessageMarshalInfo(msg, a)
+	ptr := toPointer(&msg)
+	if ptr.isNil() {
+		// We get here if msg is a typed nil ((*SomeMessage)(nil)),
+		// so it satisfies the interface, and msg == nil wouldn't
+		// catch it. We don't want crash in this case.
+		return 0
+	}
+	return u.size(ptr)
+}
+
+// Marshal is the entry point from generated code,
+// and should be ONLY called by generated code.
+// It marshals msg to the end of b.
+// a is a pointer to a place to store cached marshal info.
+func (a *InternalMessageInfo) Marshal(b []byte, msg Message, deterministic bool) ([]byte, error) {
+	u := getMessageMarshalInfo(msg, a)
+	ptr := toPointer(&msg)
+	if ptr.isNil() {
+		// We get here if msg is a typed nil ((*SomeMessage)(nil)),
+		// so it satisfies the interface, and msg == nil wouldn't
+		// catch it. We don't want crash in this case.
+		return b, ErrNil
+	}
+	return u.marshal(b, ptr, deterministic)
+}
+
+func getMessageMarshalInfo(msg interface{}, a *InternalMessageInfo) *marshalInfo {
+	// u := a.marshal, but atomically.
+	// We use an atomic here to ensure memory consistency.
+	u := atomicLoadMarshalInfo(&a.marshal)
+	if u == nil {
+		// Get marshal information from type of message.
+		t := reflect.ValueOf(msg).Type()
+		if t.Kind() != reflect.Ptr {
+			panic(fmt.Sprintf("cannot handle non-pointer message type %v", t))
+		}
+		u = getMarshalInfo(t.Elem())
+		// Store it in the cache for later users.
+		// a.marshal = u, but atomically.
+		atomicStoreMarshalInfo(&a.marshal, u)
+	}
+	return u
+}
+
+// size is the main function to compute the size of the encoded data of a message.
+// ptr is the pointer to the message.
+func (u *marshalInfo) size(ptr pointer) int {
+	if atomic.LoadInt32(&u.initialized) == 0 {
+		u.computeMarshalInfo()
+	}
+
+	// If the message can marshal itself, let it do it, for compatibility.
+	// NOTE: This is not efficient.
+	if u.hasmarshaler {
+		m := ptr.asPointerTo(u.typ).Interface().(Marshaler)
+		b, _ := m.Marshal()
+		return len(b)
+	}
+
+	n := 0
+	for _, f := range u.fields {
+		if f.isPointer && ptr.offset(f.field).getPointer().isNil() {
+			// nil pointer always marshals to nothing
+			continue
+		}
+		n += f.sizer(ptr.offset(f.field), f.tagsize)
+	}
+	if u.extensions.IsValid() {
+		e := ptr.offset(u.extensions).toExtensions()
+		if u.messageset {
+			n += u.sizeMessageSet(e)
+		} else {
+			n += u.sizeExtensions(e)
+		}
+	}
+	if u.v1extensions.IsValid() {
+		m := *ptr.offset(u.v1extensions).toOldExtensions()
+		n += u.sizeV1Extensions(m)
+	}
+	if u.unrecognized.IsValid() {
+		s := *ptr.offset(u.unrecognized).toBytes()
+		n += len(s)
+	}
+	// cache the result for use in marshal
+	if u.sizecache.IsValid() {
+		atomic.StoreInt32(ptr.offset(u.sizecache).toInt32(), int32(n))
+	}
+	return n
+}
+
+// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated),
+// fall back to compute the size.
+func (u *marshalInfo) cachedsize(ptr pointer) int {
+	if u.sizecache.IsValid() {
+		return int(atomic.LoadInt32(ptr.offset(u.sizecache).toInt32()))
+	}
+	return u.size(ptr)
+}
+
+// marshal is the main function to marshal a message. It takes a byte slice and appends
+// the encoded data to the end of the slice, returns the slice and error (if any).
+// ptr is the pointer to the message.
+// If deterministic is true, map is marshaled in deterministic order.
+func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte, error) {
+	if atomic.LoadInt32(&u.initialized) == 0 {
+		u.computeMarshalInfo()
+	}
+
+	// If the message can marshal itself, let it do it, for compatibility.
+	// NOTE: This is not efficient.
+	if u.hasmarshaler {
+		m := ptr.asPointerTo(u.typ).Interface().(Marshaler)
+		b1, err := m.Marshal()
+		b = append(b, b1...)
+		return b, err
+	}
+
+	var err, errreq error
+	// The old marshaler encodes extensions at beginning.
+	if u.extensions.IsValid() {
+		e := ptr.offset(u.extensions).toExtensions()
+		if u.messageset {
+			b, err = u.appendMessageSet(b, e, deterministic)
+		} else {
+			b, err = u.appendExtensions(b, e, deterministic)
+		}
+		if err != nil {
+			return b, err
+		}
+	}
+	if u.v1extensions.IsValid() {
+		m := *ptr.offset(u.v1extensions).toOldExtensions()
+		b, err = u.appendV1Extensions(b, m, deterministic)
+		if err != nil {
+			return b, err
+		}
+	}
+	for _, f := range u.fields {
+		if f.required && errreq == nil {
+			if ptr.offset(f.field).getPointer().isNil() {
+				// Required field is not set.
+				// We record the error but keep going, to give a complete marshaling.
+				errreq = &RequiredNotSetError{f.name}
+				continue
+			}
+		}
+		if f.isPointer && ptr.offset(f.field).getPointer().isNil() {
+			// nil pointer always marshals to nothing
+			continue
+		}
+		b, err = f.marshaler(b, ptr.offset(f.field), f.wiretag, deterministic)
+		if err != nil {
+			if err1, ok := err.(*RequiredNotSetError); ok {
+				// Required field in submessage is not set.
+				// We record the error but keep going, to give a complete marshaling.
+				if errreq == nil {
+					errreq = &RequiredNotSetError{f.name + "." + err1.field}
+				}
+				continue
+			}
+			if err == errRepeatedHasNil {
+				err = errors.New("proto: repeated field " + f.name + " has nil element")
+			}
+			return b, err
+		}
+	}
+	if u.unrecognized.IsValid() {
+		s := *ptr.offset(u.unrecognized).toBytes()
+		b = append(b, s...)
+	}
+	return b, errreq
+}
+
+// computeMarshalInfo initializes the marshal info.
+func (u *marshalInfo) computeMarshalInfo() {
+	u.Lock()
+	defer u.Unlock()
+	if u.initialized != 0 { // non-atomic read is ok as it is protected by the lock
+		return
+	}
+
+	t := u.typ
+	u.unrecognized = invalidField
+	u.extensions = invalidField
+	u.v1extensions = invalidField
+	u.sizecache = invalidField
+
+	// If the message can marshal itself, let it do it, for compatibility.
+	// NOTE: This is not efficient.
+	if reflect.PtrTo(t).Implements(marshalerType) {
+		u.hasmarshaler = true
+		atomic.StoreInt32(&u.initialized, 1)
+		return
+	}
+
+	// get oneof implementers
+	var oneofImplementers []interface{}
+	if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
+		_, _, _, oneofImplementers = m.XXX_OneofFuncs()
+	}
+
+	n := t.NumField()
+
+	// deal with XXX fields first
+	for i := 0; i < t.NumField(); i++ {
+		f := t.Field(i)
+		if !strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+		switch f.Name {
+		case "XXX_sizecache":
+			u.sizecache = toField(&f)
+		case "XXX_unrecognized":
+			u.unrecognized = toField(&f)
+		case "XXX_InternalExtensions":
+			u.extensions = toField(&f)
+			u.messageset = f.Tag.Get("protobuf_messageset") == "1"
+		case "XXX_extensions":
+			u.v1extensions = toField(&f)
+		case "XXX_NoUnkeyedLiteral":
+			// nothing to do
+		default:
+			panic("unknown XXX field: " + f.Name)
+		}
+		n--
+	}
+
+	// normal fields
+	fields := make([]marshalFieldInfo, n) // batch allocation
+	u.fields = make([]*marshalFieldInfo, 0, n)
+	for i, j := 0, 0; i < t.NumField(); i++ {
+		f := t.Field(i)
+
+		if strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+		field := &fields[j]
+		j++
+		field.name = f.Name
+		u.fields = append(u.fields, field)
+		if f.Tag.Get("protobuf_oneof") != "" {
+			field.computeOneofFieldInfo(&f, oneofImplementers)
+			continue
+		}
+		if f.Tag.Get("protobuf") == "" {
+			// field has no tag (not in generated message), ignore it
+			u.fields = u.fields[:len(u.fields)-1]
+			j--
+			continue
+		}
+		field.computeMarshalFieldInfo(&f)
+	}
+
+	// fields are marshaled in tag order on the wire.
+	sort.Sort(byTag(u.fields))
+
+	atomic.StoreInt32(&u.initialized, 1)
+}
+
+// helper for sorting fields by tag
+type byTag []*marshalFieldInfo
+
+func (a byTag) Len() int           { return len(a) }
+func (a byTag) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a byTag) Less(i, j int) bool { return a[i].wiretag < a[j].wiretag }
+
+// getExtElemInfo returns the information to marshal an extension element.
+// The info it returns is initialized.
+func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo {
+	// get from cache first
+	u.RLock()
+	e, ok := u.extElems[desc.Field]
+	u.RUnlock()
+	if ok {
+		return e
+	}
+
+	t := reflect.TypeOf(desc.ExtensionType) // pointer or slice to basic type or struct
+	tags := strings.Split(desc.Tag, ",")
+	tag, err := strconv.Atoi(tags[1])
+	if err != nil {
+		panic("tag is not an integer")
+	}
+	wt := wiretype(tags[0])
+	sizer, marshaler := typeMarshaler(t, tags, false, false)
+	e = &marshalElemInfo{
+		wiretag:   uint64(tag)<<3 | wt,
+		tagsize:   SizeVarint(uint64(tag) << 3),
+		sizer:     sizer,
+		marshaler: marshaler,
+		isptr:     t.Kind() == reflect.Ptr,
+	}
+
+	// update cache
+	u.Lock()
+	if u.extElems == nil {
+		u.extElems = make(map[int32]*marshalElemInfo)
+	}
+	u.extElems[desc.Field] = e
+	u.Unlock()
+	return e
+}
+
+// computeMarshalFieldInfo fills up the information to marshal a field.
+func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) {
+	// parse protobuf tag of the field.
+	// tag has format of "bytes,49,opt,name=foo,def=hello!"
+	tags := strings.Split(f.Tag.Get("protobuf"), ",")
+	if tags[0] == "" {
+		return
+	}
+	tag, err := strconv.Atoi(tags[1])
+	if err != nil {
+		panic("tag is not an integer")
+	}
+	wt := wiretype(tags[0])
+	if tags[2] == "req" {
+		fi.required = true
+	}
+	fi.setTag(f, tag, wt)
+	fi.setMarshaler(f, tags)
+}
+
+func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) {
+	fi.field = toField(f)
+	fi.wiretag = 1<<31 - 1 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire.
+	fi.isPointer = true
+	fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f)
+	fi.oneofElems = make(map[reflect.Type]*marshalElemInfo)
+
+	ityp := f.Type // interface type
+	for _, o := range oneofImplementers {
+		t := reflect.TypeOf(o)
+		if !t.Implements(ityp) {
+			continue
+		}
+		sf := t.Elem().Field(0) // oneof implementer is a struct with a single field
+		tags := strings.Split(sf.Tag.Get("protobuf"), ",")
+		tag, err := strconv.Atoi(tags[1])
+		if err != nil {
+			panic("tag is not an integer")
+		}
+		wt := wiretype(tags[0])
+		sizer, marshaler := typeMarshaler(sf.Type, tags, false, true) // oneof should not omit any zero value
+		fi.oneofElems[t.Elem()] = &marshalElemInfo{
+			wiretag:   uint64(tag)<<3 | wt,
+			tagsize:   SizeVarint(uint64(tag) << 3),
+			sizer:     sizer,
+			marshaler: marshaler,
+		}
+	}
+}
+
+type oneofMessage interface {
+	XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
+}
+
+// wiretype returns the wire encoding of the type.
+func wiretype(encoding string) uint64 {
+	switch encoding {
+	case "fixed32":
+		return WireFixed32
+	case "fixed64":
+		return WireFixed64
+	case "varint", "zigzag32", "zigzag64":
+		return WireVarint
+	case "bytes":
+		return WireBytes
+	case "group":
+		return WireStartGroup
+	}
+	panic("unknown wire type " + encoding)
+}
+
+// setTag fills up the tag (in wire format) and its size in the info of a field.
+func (fi *marshalFieldInfo) setTag(f *reflect.StructField, tag int, wt uint64) {
+	fi.field = toField(f)
+	fi.wiretag = uint64(tag)<<3 | wt
+	fi.tagsize = SizeVarint(uint64(tag) << 3)
+}
+
+// setMarshaler fills up the sizer and marshaler in the info of a field.
+func (fi *marshalFieldInfo) setMarshaler(f *reflect.StructField, tags []string) {
+	switch f.Type.Kind() {
+	case reflect.Map:
+		// map field
+		fi.isPointer = true
+		fi.sizer, fi.marshaler = makeMapMarshaler(f)
+		return
+	case reflect.Ptr, reflect.Slice:
+		fi.isPointer = true
+	}
+	fi.sizer, fi.marshaler = typeMarshaler(f.Type, tags, true, false)
+}
+
+// typeMarshaler returns the sizer and marshaler of a given field.
+// t is the type of the field.
+// tags is the generated "protobuf" tag of the field.
+// If nozero is true, zero value is not marshaled to the wire.
+// If oneof is true, it is a oneof field.
+func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, marshaler) {
+	encoding := tags[0]
+
+	pointer := false
+	slice := false
+	if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
+		slice = true
+		t = t.Elem()
+	}
+	if t.Kind() == reflect.Ptr {
+		pointer = true
+		t = t.Elem()
+	}
+
+	packed := false
+	proto3 := false
+	for i := 2; i < len(tags); i++ {
+		if tags[i] == "packed" {
+			packed = true
+		}
+		if tags[i] == "proto3" {
+			proto3 = true
+		}
+	}
+
+	switch t.Kind() {
+	case reflect.Bool:
+		if pointer {
+			return sizeBoolPtr, appendBoolPtr
+		}
+		if slice {
+			if packed {
+				return sizeBoolPackedSlice, appendBoolPackedSlice
+			}
+			return sizeBoolSlice, appendBoolSlice
+		}
+		if nozero {
+			return sizeBoolValueNoZero, appendBoolValueNoZero
+		}
+		return sizeBoolValue, appendBoolValue
+	case reflect.Uint32:
+		switch encoding {
+		case "fixed32":
+			if pointer {
+				return sizeFixed32Ptr, appendFixed32Ptr
+			}
+			if slice {
+				if packed {
+					return sizeFixed32PackedSlice, appendFixed32PackedSlice
+				}
+				return sizeFixed32Slice, appendFixed32Slice
+			}
+			if nozero {
+				return sizeFixed32ValueNoZero, appendFixed32ValueNoZero
+			}
+			return sizeFixed32Value, appendFixed32Value
+		case "varint":
+			if pointer {
+				return sizeVarint32Ptr, appendVarint32Ptr
+			}
+			if slice {
+				if packed {
+					return sizeVarint32PackedSlice, appendVarint32PackedSlice
+				}
+				return sizeVarint32Slice, appendVarint32Slice
+			}
+			if nozero {
+				return sizeVarint32ValueNoZero, appendVarint32ValueNoZero
+			}
+			return sizeVarint32Value, appendVarint32Value
+		}
+	case reflect.Int32:
+		switch encoding {
+		case "fixed32":
+			if pointer {
+				return sizeFixedS32Ptr, appendFixedS32Ptr
+			}
+			if slice {
+				if packed {
+					return sizeFixedS32PackedSlice, appendFixedS32PackedSlice
+				}
+				return sizeFixedS32Slice, appendFixedS32Slice
+			}
+			if nozero {
+				return sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero
+			}
+			return sizeFixedS32Value, appendFixedS32Value
+		case "varint":
+			if pointer {
+				return sizeVarintS32Ptr, appendVarintS32Ptr
+			}
+			if slice {
+				if packed {
+					return sizeVarintS32PackedSlice, appendVarintS32PackedSlice
+				}
+				return sizeVarintS32Slice, appendVarintS32Slice
+			}
+			if nozero {
+				return sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero
+			}
+			return sizeVarintS32Value, appendVarintS32Value
+		case "zigzag32":
+			if pointer {
+				return sizeZigzag32Ptr, appendZigzag32Ptr
+			}
+			if slice {
+				if packed {
+					return sizeZigzag32PackedSlice, appendZigzag32PackedSlice
+				}
+				return sizeZigzag32Slice, appendZigzag32Slice
+			}
+			if nozero {
+				return sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero
+			}
+			return sizeZigzag32Value, appendZigzag32Value
+		}
+	case reflect.Uint64:
+		switch encoding {
+		case "fixed64":
+			if pointer {
+				return sizeFixed64Ptr, appendFixed64Ptr
+			}
+			if slice {
+				if packed {
+					return sizeFixed64PackedSlice, appendFixed64PackedSlice
+				}
+				return sizeFixed64Slice, appendFixed64Slice
+			}
+			if nozero {
+				return sizeFixed64ValueNoZero, appendFixed64ValueNoZero
+			}
+			return sizeFixed64Value, appendFixed64Value
+		case "varint":
+			if pointer {
+				return sizeVarint64Ptr, appendVarint64Ptr
+			}
+			if slice {
+				if packed {
+					return sizeVarint64PackedSlice, appendVarint64PackedSlice
+				}
+				return sizeVarint64Slice, appendVarint64Slice
+			}
+			if nozero {
+				return sizeVarint64ValueNoZero, appendVarint64ValueNoZero
+			}
+			return sizeVarint64Value, appendVarint64Value
+		}
+	case reflect.Int64:
+		switch encoding {
+		case "fixed64":
+			if pointer {
+				return sizeFixedS64Ptr, appendFixedS64Ptr
+			}
+			if slice {
+				if packed {
+					return sizeFixedS64PackedSlice, appendFixedS64PackedSlice
+				}
+				return sizeFixedS64Slice, appendFixedS64Slice
+			}
+			if nozero {
+				return sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero
+			}
+			return sizeFixedS64Value, appendFixedS64Value
+		case "varint":
+			if pointer {
+				return sizeVarintS64Ptr, appendVarintS64Ptr
+			}
+			if slice {
+				if packed {
+					return sizeVarintS64PackedSlice, appendVarintS64PackedSlice
+				}
+				return sizeVarintS64Slice, appendVarintS64Slice
+			}
+			if nozero {
+				return sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero
+			}
+			return sizeVarintS64Value, appendVarintS64Value
+		case "zigzag64":
+			if pointer {
+				return sizeZigzag64Ptr, appendZigzag64Ptr
+			}
+			if slice {
+				if packed {
+					return sizeZigzag64PackedSlice, appendZigzag64PackedSlice
+				}
+				return sizeZigzag64Slice, appendZigzag64Slice
+			}
+			if nozero {
+				return sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero
+			}
+			return sizeZigzag64Value, appendZigzag64Value
+		}
+	case reflect.Float32:
+		if pointer {
+			return sizeFloat32Ptr, appendFloat32Ptr
+		}
+		if slice {
+			if packed {
+				return sizeFloat32PackedSlice, appendFloat32PackedSlice
+			}
+			return sizeFloat32Slice, appendFloat32Slice
+		}
+		if nozero {
+			return sizeFloat32ValueNoZero, appendFloat32ValueNoZero
+		}
+		return sizeFloat32Value, appendFloat32Value
+	case reflect.Float64:
+		if pointer {
+			return sizeFloat64Ptr, appendFloat64Ptr
+		}
+		if slice {
+			if packed {
+				return sizeFloat64PackedSlice, appendFloat64PackedSlice
+			}
+			return sizeFloat64Slice, appendFloat64Slice
+		}
+		if nozero {
+			return sizeFloat64ValueNoZero, appendFloat64ValueNoZero
+		}
+		return sizeFloat64Value, appendFloat64Value
+	case reflect.String:
+		if pointer {
+			return sizeStringPtr, appendStringPtr
+		}
+		if slice {
+			return sizeStringSlice, appendStringSlice
+		}
+		if nozero {
+			return sizeStringValueNoZero, appendStringValueNoZero
+		}
+		return sizeStringValue, appendStringValue
+	case reflect.Slice:
+		if slice {
+			return sizeBytesSlice, appendBytesSlice
+		}
+		if oneof {
+			// Oneof bytes field may also have "proto3" tag.
+			// We want to marshal it as a oneof field. Do this
+			// check before the proto3 check.
+			return sizeBytesOneof, appendBytesOneof
+		}
+		if proto3 {
+			return sizeBytes3, appendBytes3
+		}
+		return sizeBytes, appendBytes
+	case reflect.Struct:
+		switch encoding {
+		case "group":
+			if slice {
+				return makeGroupSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeGroupMarshaler(getMarshalInfo(t))
+		case "bytes":
+			if slice {
+				return makeMessageSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeMessageMarshaler(getMarshalInfo(t))
+		}
+	}
+	panic(fmt.Sprintf("unknown or mismatched type: type: %v, wire type: %v", t, encoding))
+}
+
+// Below are functions to size/marshal a specific type of a field.
+// They are stored in the field's info, and called by function pointers.
+// They have type sizer or marshaler.
+
+func sizeFixed32Value(_ pointer, tagsize int) int {
+	return 4 + tagsize
+}
+func sizeFixed32ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toUint32()
+	if v == 0 {
+		return 0
+	}
+	return 4 + tagsize
+}
+func sizeFixed32Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toUint32Ptr()
+	if p == nil {
+		return 0
+	}
+	return 4 + tagsize
+}
+func sizeFixed32Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint32Slice()
+	return (4 + tagsize) * len(s)
+}
+func sizeFixed32PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
+}
+func sizeFixedS32Value(_ pointer, tagsize int) int {
+	return 4 + tagsize
+}
+func sizeFixedS32ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toInt32()
+	if v == 0 {
+		return 0
+	}
+	return 4 + tagsize
+}
+func sizeFixedS32Ptr(ptr pointer, tagsize int) int {
+	p := ptr.getInt32Ptr()
+	if p == nil {
+		return 0
+	}
+	return 4 + tagsize
+}
+func sizeFixedS32Slice(ptr pointer, tagsize int) int {
+	s := ptr.getInt32Slice()
+	return (4 + tagsize) * len(s)
+}
+func sizeFixedS32PackedSlice(ptr pointer, tagsize int) int {
+	s := ptr.getInt32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
+}
+func sizeFloat32Value(_ pointer, tagsize int) int {
+	return 4 + tagsize
+}
+func sizeFloat32ValueNoZero(ptr pointer, tagsize int) int {
+	v := math.Float32bits(*ptr.toFloat32())
+	if v == 0 {
+		return 0
+	}
+	return 4 + tagsize
+}
+func sizeFloat32Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toFloat32Ptr()
+	if p == nil {
+		return 0
+	}
+	return 4 + tagsize
+}
+func sizeFloat32Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toFloat32Slice()
+	return (4 + tagsize) * len(s)
+}
+func sizeFloat32PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toFloat32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
+}
+func sizeFixed64Value(_ pointer, tagsize int) int {
+	return 8 + tagsize
+}
+func sizeFixed64ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toUint64()
+	if v == 0 {
+		return 0
+	}
+	return 8 + tagsize
+}
+func sizeFixed64Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toUint64Ptr()
+	if p == nil {
+		return 0
+	}
+	return 8 + tagsize
+}
+func sizeFixed64Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint64Slice()
+	return (8 + tagsize) * len(s)
+}
+func sizeFixed64PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
+}
+func sizeFixedS64Value(_ pointer, tagsize int) int {
+	return 8 + tagsize
+}
+func sizeFixedS64ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toInt64()
+	if v == 0 {
+		return 0
+	}
+	return 8 + tagsize
+}
+func sizeFixedS64Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toInt64Ptr()
+	if p == nil {
+		return 0
+	}
+	return 8 + tagsize
+}
+func sizeFixedS64Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toInt64Slice()
+	return (8 + tagsize) * len(s)
+}
+func sizeFixedS64PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toInt64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
+}
+func sizeFloat64Value(_ pointer, tagsize int) int {
+	return 8 + tagsize
+}
+func sizeFloat64ValueNoZero(ptr pointer, tagsize int) int {
+	v := math.Float64bits(*ptr.toFloat64())
+	if v == 0 {
+		return 0
+	}
+	return 8 + tagsize
+}
+func sizeFloat64Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toFloat64Ptr()
+	if p == nil {
+		return 0
+	}
+	return 8 + tagsize
+}
+func sizeFloat64Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toFloat64Slice()
+	return (8 + tagsize) * len(s)
+}
+func sizeFloat64PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toFloat64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
+}
+func sizeVarint32Value(ptr pointer, tagsize int) int {
+	v := *ptr.toUint32()
+	return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarint32ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toUint32()
+	if v == 0 {
+		return 0
+	}
+	return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarint32Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toUint32Ptr()
+	if p == nil {
+		return 0
+	}
+	return SizeVarint(uint64(*p)) + tagsize
+}
+func sizeVarint32Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint32Slice()
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v)) + tagsize
+	}
+	return n
+}
+func sizeVarint32PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v))
+	}
+	return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeVarintS32Value(ptr pointer, tagsize int) int {
+	v := *ptr.toInt32()
+	return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarintS32ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toInt32()
+	if v == 0 {
+		return 0
+	}
+	return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarintS32Ptr(ptr pointer, tagsize int) int {
+	p := ptr.getInt32Ptr()
+	if p == nil {
+		return 0
+	}
+	return SizeVarint(uint64(*p)) + tagsize
+}
+func sizeVarintS32Slice(ptr pointer, tagsize int) int {
+	s := ptr.getInt32Slice()
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v)) + tagsize
+	}
+	return n
+}
+func sizeVarintS32PackedSlice(ptr pointer, tagsize int) int {
+	s := ptr.getInt32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v))
+	}
+	return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeVarint64Value(ptr pointer, tagsize int) int {
+	v := *ptr.toUint64()
+	return SizeVarint(v) + tagsize
+}
+func sizeVarint64ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toUint64()
+	if v == 0 {
+		return 0
+	}
+	return SizeVarint(v) + tagsize
+}
+func sizeVarint64Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toUint64Ptr()
+	if p == nil {
+		return 0
+	}
+	return SizeVarint(*p) + tagsize
+}
+func sizeVarint64Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint64Slice()
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(v) + tagsize
+	}
+	return n
+}
+func sizeVarint64PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(v)
+	}
+	return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeVarintS64Value(ptr pointer, tagsize int) int {
+	v := *ptr.toInt64()
+	return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarintS64ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toInt64()
+	if v == 0 {
+		return 0
+	}
+	return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarintS64Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toInt64Ptr()
+	if p == nil {
+		return 0
+	}
+	return SizeVarint(uint64(*p)) + tagsize
+}
+func sizeVarintS64Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toInt64Slice()
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v)) + tagsize
+	}
+	return n
+}
+func sizeVarintS64PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toInt64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v))
+	}
+	return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeZigzag32Value(ptr pointer, tagsize int) int {
+	v := *ptr.toInt32()
+	return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
+}
+func sizeZigzag32ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toInt32()
+	if v == 0 {
+		return 0
+	}
+	return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
+}
+func sizeZigzag32Ptr(ptr pointer, tagsize int) int {
+	p := ptr.getInt32Ptr()
+	if p == nil {
+		return 0
+	}
+	v := *p
+	return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
+}
+func sizeZigzag32Slice(ptr pointer, tagsize int) int {
+	s := ptr.getInt32Slice()
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
+	}
+	return n
+}
+func sizeZigzag32PackedSlice(ptr pointer, tagsize int) int {
+	s := ptr.getInt32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))
+	}
+	return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeZigzag64Value(ptr pointer, tagsize int) int {
+	v := *ptr.toInt64()
+	return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
+}
+func sizeZigzag64ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toInt64()
+	if v == 0 {
+		return 0
+	}
+	return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
+}
+func sizeZigzag64Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toInt64Ptr()
+	if p == nil {
+		return 0
+	}
+	v := *p
+	return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
+}
+func sizeZigzag64Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toInt64Slice()
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
+	}
+	return n
+}
+func sizeZigzag64PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toInt64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63)))
+	}
+	return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeBoolValue(_ pointer, tagsize int) int {
+	return 1 + tagsize
+}
+func sizeBoolValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toBool()
+	if !v {
+		return 0
+	}
+	return 1 + tagsize
+}
+func sizeBoolPtr(ptr pointer, tagsize int) int {
+	p := *ptr.toBoolPtr()
+	if p == nil {
+		return 0
+	}
+	return 1 + tagsize
+}
+func sizeBoolSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toBoolSlice()
+	return (1 + tagsize) * len(s)
+}
+func sizeBoolPackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toBoolSlice()
+	if len(s) == 0 {
+		return 0
+	}
+	return len(s) + SizeVarint(uint64(len(s))) + tagsize
+}
+func sizeStringValue(ptr pointer, tagsize int) int {
+	v := *ptr.toString()
+	return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeStringValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toString()
+	if v == "" {
+		return 0
+	}
+	return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeStringPtr(ptr pointer, tagsize int) int {
+	p := *ptr.toStringPtr()
+	if p == nil {
+		return 0
+	}
+	v := *p
+	return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeStringSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toStringSlice()
+	n := 0
+	for _, v := range s {
+		n += len(v) + SizeVarint(uint64(len(v))) + tagsize
+	}
+	return n
+}
+func sizeBytes(ptr pointer, tagsize int) int {
+	v := *ptr.toBytes()
+	if v == nil {
+		return 0
+	}
+	return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeBytes3(ptr pointer, tagsize int) int {
+	v := *ptr.toBytes()
+	if len(v) == 0 {
+		return 0
+	}
+	return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeBytesOneof(ptr pointer, tagsize int) int {
+	v := *ptr.toBytes()
+	return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeBytesSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toBytesSlice()
+	n := 0
+	for _, v := range s {
+		n += len(v) + SizeVarint(uint64(len(v))) + tagsize
+	}
+	return n
+}
+
+// appendFixed32 appends an encoded fixed32 to b.
+func appendFixed32(b []byte, v uint32) []byte {
+	b = append(b,
+		byte(v),
+		byte(v>>8),
+		byte(v>>16),
+		byte(v>>24))
+	return b
+}
+
+// appendFixed64 appends an encoded fixed64 to b.
+func appendFixed64(b []byte, v uint64) []byte {
+	b = append(b,
+		byte(v),
+		byte(v>>8),
+		byte(v>>16),
+		byte(v>>24),
+		byte(v>>32),
+		byte(v>>40),
+		byte(v>>48),
+		byte(v>>56))
+	return b
+}
+
+// appendVarint appends an encoded varint to b.
+func appendVarint(b []byte, v uint64) []byte {
+	// TODO: make 1-byte (maybe 2-byte) case inline-able, once we
+	// have non-leaf inliner.
+	switch {
+	case v < 1<<7:
+		b = append(b, byte(v))
+	case v < 1<<14:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte(v>>7))
+	case v < 1<<21:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte(v>>14))
+	case v < 1<<28:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte(v>>21))
+	case v < 1<<35:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte(v>>28))
+	case v < 1<<42:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte(v>>35))
+	case v < 1<<49:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte((v>>35)&0x7f|0x80),
+			byte(v>>42))
+	case v < 1<<56:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte((v>>35)&0x7f|0x80),
+			byte((v>>42)&0x7f|0x80),
+			byte(v>>49))
+	case v < 1<<63:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte((v>>35)&0x7f|0x80),
+			byte((v>>42)&0x7f|0x80),
+			byte((v>>49)&0x7f|0x80),
+			byte(v>>56))
+	default:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte((v>>35)&0x7f|0x80),
+			byte((v>>42)&0x7f|0x80),
+			byte((v>>49)&0x7f|0x80),
+			byte((v>>56)&0x7f|0x80),
+			1)
+	}
+	return b
+}
+
+func appendFixed32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toUint32()
+	b =