internal/fuzz: refactor fuzzer

Add a new Fuzz message containing all the message types we want to make
available to fuzzers. Previously, testing (for example) required fields
would require modifying the fuzzer; now, it's just a matter of adding a
message with required fields as a field of the top-level Fuzz message.

Add internal/cmd/generate-corpus to codify where the fuzz seed corpus
comes from. This will simplify adding text and json fuzzers.

Rename internal/fuzz/wire to internal/fuzz/wirefuzz to minimize package
name ambiguity. Also, the addition of the Fuzz container message
invalidates the existing corpus, so using a new name seems like a good
idea.

Change-Id: I94f8f64ba93596c8e8cecb4d42bcc5b98c17d838
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/212218
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/internal/cmd/generate-corpus/main.go b/internal/cmd/generate-corpus/main.go
new file mode 100644
index 0000000..f566166
--- /dev/null
+++ b/internal/cmd/generate-corpus/main.go
@@ -0,0 +1,119 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Program generate-corpus generates a seed corpus for the fuzzers.
+//
+// This command is not run automatically because its output is not stable.
+// It's present in source control mainly as documentation of where the seed
+// corpus came from.
+package main
+
+import (
+	"crypto/sha1"
+	"fmt"
+	"io/ioutil"
+	"log"
+
+	"google.golang.org/protobuf/proto"
+
+	fuzzpb "google.golang.org/protobuf/internal/testprotos/fuzz"
+	testpb "google.golang.org/protobuf/internal/testprotos/test"
+)
+
+var messages = []proto.Message{
+	&fuzzpb.Fuzz{
+		TestAllTypes: &testpb.TestAllTypes{
+			OptionalInt32:      proto.Int32(1001),
+			OptionalInt64:      proto.Int64(1002),
+			OptionalUint32:     proto.Uint32(1003),
+			OptionalUint64:     proto.Uint64(1004),
+			OptionalSint32:     proto.Int32(1005),
+			OptionalSint64:     proto.Int64(1006),
+			OptionalFixed32:    proto.Uint32(1007),
+			OptionalFixed64:    proto.Uint64(1008),
+			OptionalSfixed32:   proto.Int32(1009),
+			OptionalSfixed64:   proto.Int64(1010),
+			OptionalFloat:      proto.Float32(1011.5),
+			OptionalDouble:     proto.Float64(1012.5),
+			OptionalBool:       proto.Bool(true),
+			OptionalString:     proto.String("string"),
+			OptionalBytes:      []byte("bytes"),
+			OptionalNestedEnum: testpb.TestAllTypes_BAR.Enum(),
+			Optionalgroup: &testpb.TestAllTypes_OptionalGroup{
+				A: proto.Int32(1017),
+			},
+			OptionalNestedMessage: &testpb.TestAllTypes_NestedMessage{
+				A: proto.Int32(42),
+				Corecursive: &testpb.TestAllTypes{
+					OptionalInt32: proto.Int32(43),
+				},
+			},
+			RepeatedInt32:    []int32{1001, 2001},
+			RepeatedInt64:    []int64{1002, 2002},
+			RepeatedUint32:   []uint32{1003, 2003},
+			RepeatedUint64:   []uint64{1004, 2004},
+			RepeatedSint32:   []int32{1005, 2005},
+			RepeatedSint64:   []int64{1006, 2006},
+			RepeatedFixed32:  []uint32{1007, 2007},
+			RepeatedFixed64:  []uint64{1008, 2008},
+			RepeatedSfixed32: []int32{1009, 2009},
+			RepeatedSfixed64: []int64{1010, 2010},
+			RepeatedFloat:    []float32{1011.5, 2011.5},
+			RepeatedDouble:   []float64{1012.5, 2012.5},
+			RepeatedBool:     []bool{true, false},
+			RepeatedString:   []string{"foo", "bar"},
+			RepeatedBytes:    [][]byte{[]byte("FOO"), []byte("BAR")},
+			RepeatedNestedEnum: []testpb.TestAllTypes_NestedEnum{
+				testpb.TestAllTypes_FOO,
+				testpb.TestAllTypes_BAR,
+			},
+			RepeatedNestedMessage: []*testpb.TestAllTypes_NestedMessage{
+				{A: proto.Int32(1)},
+				nil,
+				{A: proto.Int32(2)},
+			},
+			Repeatedgroup: []*testpb.TestAllTypes_RepeatedGroup{
+				{A: proto.Int32(1017)},
+				nil,
+				{A: proto.Int32(2017)},
+			},
+			MapInt32Int32:       map[int32]int32{1056: 1156, 2056: 2156},
+			MapInt64Int64:       map[int64]int64{1057: 1157, 2057: 2157},
+			MapUint32Uint32:     map[uint32]uint32{1058: 1158, 2058: 2158},
+			MapUint64Uint64:     map[uint64]uint64{1059: 1159, 2059: 2159},
+			MapSint32Sint32:     map[int32]int32{1060: 1160, 2060: 2160},
+			MapSint64Sint64:     map[int64]int64{1061: 1161, 2061: 2161},
+			MapFixed32Fixed32:   map[uint32]uint32{1062: 1162, 2062: 2162},
+			MapFixed64Fixed64:   map[uint64]uint64{1063: 1163, 2063: 2163},
+			MapSfixed32Sfixed32: map[int32]int32{1064: 1164, 2064: 2164},
+			MapSfixed64Sfixed64: map[int64]int64{1065: 1165, 2065: 2165},
+			MapInt32Float:       map[int32]float32{1066: 1166.5, 2066: 2166.5},
+			MapInt32Double:      map[int32]float64{1067: 1167.5, 2067: 2167.5},
+			MapBoolBool:         map[bool]bool{true: false, false: true},
+			MapStringString:     map[string]string{"69.1.key": "69.1.val", "69.2.key": "69.2.val"},
+			MapStringBytes:      map[string][]byte{"70.1.key": []byte("70.1.val"), "70.2.key": []byte("70.2.val")},
+			MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{
+				"71.1.key": {A: proto.Int32(1171)},
+				"71.2.key": {A: proto.Int32(2171)},
+			},
+			MapStringNestedEnum: map[string]testpb.TestAllTypes_NestedEnum{
+				"73.1.key": testpb.TestAllTypes_FOO,
+				"73.2.key": testpb.TestAllTypes_BAR,
+			},
+			OneofField: &testpb.TestAllTypes_OneofUint32{1111},
+		},
+	},
+}
+
+func main() {
+	for _, m := range messages {
+		wire, err := proto.Marshal(m)
+		if err != nil {
+			log.Fatal(err)
+		}
+		if err := ioutil.WriteFile(fmt.Sprintf("internal/fuzz/wirefuzz/corpus/%x", sha1.Sum(wire)), wire, 0777); err != nil {
+			log.Fatal(err)
+		}
+	}
+}
diff --git a/internal/fuzz/wire/corpus/093039684b75b1f06f7a5aeb81b61fb9b6821c8a b/internal/fuzz/wire/corpus/093039684b75b1f06f7a5aeb81b61fb9b6821c8a
deleted file mode 100644
index cf599f2..0000000
--- a/internal/fuzz/wire/corpus/093039684b75b1f06f7a5aeb81b61fb9b6821c8a
+++ /dev/null
Binary files differ
diff --git a/internal/fuzz/wire/corpus/26ff72cf93341dd2ec7f4f3e4138f1158d554916 b/internal/fuzz/wire/corpus/26ff72cf93341dd2ec7f4f3e4138f1158d554916
deleted file mode 100644
index 560240f..0000000
--- a/internal/fuzz/wire/corpus/26ff72cf93341dd2ec7f4f3e4138f1158d554916
+++ /dev/null
Binary files differ
diff --git a/internal/fuzz/wire/fuzz.go b/internal/fuzz/wire/fuzz.go
deleted file mode 100644
index 1d0ae51..0000000
--- a/internal/fuzz/wire/fuzz.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package wire includes a fuzzer for the wire marshaler and unmarshaler.
-package wire
-
-import (
-	"google.golang.org/protobuf/proto"
-
-	testpb "google.golang.org/protobuf/internal/testprotos/test"
-	test3pb "google.golang.org/protobuf/internal/testprotos/test3"
-)
-
-// Fuzz is a fuzzer for proto.Marshal and proto.Unmarshal.
-func Fuzz(data []byte) int {
-	score := 0
-	for _, newf := range []func() proto.Message{
-		func() proto.Message { return &testpb.TestAllTypes{} },
-		func() proto.Message { return &testpb.TestAllExtensions{} },
-		func() proto.Message { return &test3pb.TestAllTypes{} },
-	} {
-		m1 := newf()
-		if err := proto.Unmarshal(data, m1); err != nil {
-			continue
-		}
-		score = 1
-		data1, err := proto.Marshal(m1)
-		if err != nil {
-			panic(err)
-		}
-		if proto.Size(m1) != len(data1) {
-			panic("size does not match output")
-		}
-		m2 := newf()
-		if err := proto.Unmarshal(data1, m2); err != nil {
-			panic(err)
-		}
-		if !proto.Equal(m1, m2) {
-			panic("not equal")
-		}
-	}
-	return score
-}
diff --git a/internal/fuzz/wirefuzz/corpus/20019c4ef10ebf8031c8d204bdd0ae1ec214bf90 b/internal/fuzz/wirefuzz/corpus/20019c4ef10ebf8031c8d204bdd0ae1ec214bf90
new file mode 100755
index 0000000..59e5662
--- /dev/null
+++ b/internal/fuzz/wirefuzz/corpus/20019c4ef10ebf8031c8d204bdd0ae1ec214bf90
Binary files differ
diff --git a/internal/fuzz/wirefuzz/fuzz.go b/internal/fuzz/wirefuzz/fuzz.go
new file mode 100644
index 0000000..79b5f01
--- /dev/null
+++ b/internal/fuzz/wirefuzz/fuzz.go
@@ -0,0 +1,41 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package wirefuzz includes a fuzzer for the wire marshaler and unmarshaler.
+package wirefuzz
+
+import (
+	"google.golang.org/protobuf/proto"
+
+	fuzzpb "google.golang.org/protobuf/internal/testprotos/fuzz"
+)
+
+// Fuzz is a fuzzer for proto.Marshal and proto.Unmarshal.
+func Fuzz(data []byte) (score int) {
+	m1 := &fuzzpb.Fuzz{}
+	if err := (proto.UnmarshalOptions{
+		AllowPartial: true,
+	}).Unmarshal(data, m1); err != nil {
+		return 0
+	}
+	data1, err := proto.MarshalOptions{
+		AllowPartial: true,
+	}.Marshal(m1)
+	if err != nil {
+		panic(err)
+	}
+	if proto.Size(m1) != len(data1) {
+		panic("size does not match output")
+	}
+	m2 := &fuzzpb.Fuzz{}
+	if err := (proto.UnmarshalOptions{
+		AllowPartial: true,
+	}).Unmarshal(data1, m2); err != nil {
+		panic(err)
+	}
+	if !proto.Equal(m1, m2) {
+		panic("not equal")
+	}
+	return 1
+}
diff --git a/internal/fuzz/wire/fuzz_test.go b/internal/fuzz/wirefuzz/fuzz_test.go
similarity index 70%
rename from internal/fuzz/wire/fuzz_test.go
rename to internal/fuzz/wirefuzz/fuzz_test.go
index 40a510a..3351ae9 100644
--- a/internal/fuzz/wire/fuzz_test.go
+++ b/internal/fuzz/wirefuzz/fuzz_test.go
@@ -1,4 +1,8 @@
-package wire
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package wirefuzz
 
 import (
 	"io/ioutil"
diff --git a/internal/testprotos/fuzz/fuzz.pb.go b/internal/testprotos/fuzz/fuzz.pb.go
new file mode 100644
index 0000000..b017f39
--- /dev/null
+++ b/internal/testprotos/fuzz/fuzz.pb.go
@@ -0,0 +1,253 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: fuzz/fuzz.proto
+
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package goproto_proto_fuzz
+
+import (
+	test "google.golang.org/protobuf/internal/testprotos/test"
+	test3 "google.golang.org/protobuf/internal/testprotos/test3"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+// Fuzz is a container for every message we want to make available to the fuzzer.
+type Fuzz struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	TestAllTypes            *test.TestAllTypes            `protobuf:"bytes,1,opt,name=test_all_types,json=testAllTypes" json:"test_all_types,omitempty"`
+	TestAllExtensions       *test.TestAllExtensions       `protobuf:"bytes,2,opt,name=test_all_extensions,json=testAllExtensions" json:"test_all_extensions,omitempty"`
+	TestRequired            *test.TestRequired            `protobuf:"bytes,3,opt,name=test_required,json=testRequired" json:"test_required,omitempty"`
+	TestRequiredForeign     *test.TestRequiredForeign     `protobuf:"bytes,4,opt,name=test_required_foreign,json=testRequiredForeign" json:"test_required_foreign,omitempty"`
+	TestRequiredGroupFields *test.TestRequiredGroupFields `protobuf:"bytes,5,opt,name=test_required_group_fields,json=testRequiredGroupFields" json:"test_required_group_fields,omitempty"`
+	TestPackedTypes         *test.TestPackedTypes         `protobuf:"bytes,6,opt,name=test_packed_types,json=testPackedTypes" json:"test_packed_types,omitempty"`
+	TestPackedExtensions    *test.TestPackedExtensions    `protobuf:"bytes,7,opt,name=test_packed_extensions,json=testPackedExtensions" json:"test_packed_extensions,omitempty"`
+	TestAllTypes3           *test3.TestAllTypes           `protobuf:"bytes,8,opt,name=test_all_types3,json=testAllTypes3" json:"test_all_types3,omitempty"`
+}
+
+func (x *Fuzz) Reset() {
+	*x = Fuzz{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_fuzz_fuzz_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Fuzz) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Fuzz) ProtoMessage() {}
+
+func (x *Fuzz) ProtoReflect() protoreflect.Message {
+	mi := &file_fuzz_fuzz_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Fuzz.ProtoReflect.Descriptor instead.
+func (*Fuzz) Descriptor() ([]byte, []int) {
+	return file_fuzz_fuzz_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Fuzz) GetTestAllTypes() *test.TestAllTypes {
+	if x != nil {
+		return x.TestAllTypes
+	}
+	return nil
+}
+
+func (x *Fuzz) GetTestAllExtensions() *test.TestAllExtensions {
+	if x != nil {
+		return x.TestAllExtensions
+	}
+	return nil
+}
+
+func (x *Fuzz) GetTestRequired() *test.TestRequired {
+	if x != nil {
+		return x.TestRequired
+	}
+	return nil
+}
+
+func (x *Fuzz) GetTestRequiredForeign() *test.TestRequiredForeign {
+	if x != nil {
+		return x.TestRequiredForeign
+	}
+	return nil
+}
+
+func (x *Fuzz) GetTestRequiredGroupFields() *test.TestRequiredGroupFields {
+	if x != nil {
+		return x.TestRequiredGroupFields
+	}
+	return nil
+}
+
+func (x *Fuzz) GetTestPackedTypes() *test.TestPackedTypes {
+	if x != nil {
+		return x.TestPackedTypes
+	}
+	return nil
+}
+
+func (x *Fuzz) GetTestPackedExtensions() *test.TestPackedExtensions {
+	if x != nil {
+		return x.TestPackedExtensions
+	}
+	return nil
+}
+
+func (x *Fuzz) GetTestAllTypes3() *test3.TestAllTypes {
+	if x != nil {
+		return x.TestAllTypes3
+	}
+	return nil
+}
+
+var File_fuzz_fuzz_proto protoreflect.FileDescriptor
+
+var file_fuzz_fuzz_proto_rawDesc = []byte{
+	0x0a, 0x0f, 0x66, 0x75, 0x7a, 0x7a, 0x2f, 0x66, 0x75, 0x7a, 0x7a, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x12, 0x12, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2e, 0x66, 0x75, 0x7a, 0x7a, 0x1a, 0x0f, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x74, 0x65, 0x73, 0x74,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x10, 0x74, 0x65, 0x73, 0x74, 0x33, 0x2f, 0x74, 0x65,
+	0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xaf, 0x05, 0x0a, 0x04, 0x46, 0x75, 0x7a,
+	0x7a, 0x12, 0x46, 0x0a, 0x0e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x79,
+	0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54,
+	0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x0c, 0x74, 0x65, 0x73,
+	0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x55, 0x0a, 0x13, 0x74, 0x65, 0x73,
+	0x74, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74,
+	0x41, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x11, 0x74,
+	0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73,
+	0x12, 0x45, 0x0a, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65,
+	0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73,
+	0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x52, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x52,
+	0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x5b, 0x0a, 0x15, 0x74, 0x65, 0x73, 0x74, 0x5f,
+	0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74,
+	0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x65, 0x69, 0x67, 0x6e, 0x52,
+	0x13, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x46, 0x6f, 0x72,
+	0x65, 0x69, 0x67, 0x6e, 0x12, 0x68, 0x0a, 0x1a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x71,
+	0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x66, 0x69, 0x65, 0x6c,
+	0x64, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x67, 0x6f, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65,
+	0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x46,
+	0x69, 0x65, 0x6c, 0x64, 0x73, 0x52, 0x17, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69,
+	0x72, 0x65, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x4f,
+	0x0a, 0x11, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x74, 0x79,
+	0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54,
+	0x65, 0x73, 0x74, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x0f,
+	0x74, 0x65, 0x73, 0x74, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12,
+	0x5e, 0x0a, 0x16, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x65,
+	0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x28, 0x2e, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+	0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x45,
+	0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x14, 0x74, 0x65, 0x73, 0x74, 0x50,
+	0x61, 0x63, 0x6b, 0x65, 0x64, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12,
+	0x49, 0x0a, 0x0f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65,
+	0x73, 0x33, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x33, 0x2e, 0x54,
+	0x65, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x0d, 0x74, 0x65, 0x73,
+	0x74, 0x41, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x33,
+}
+
+var (
+	file_fuzz_fuzz_proto_rawDescOnce sync.Once
+	file_fuzz_fuzz_proto_rawDescData = file_fuzz_fuzz_proto_rawDesc
+)
+
+func file_fuzz_fuzz_proto_rawDescGZIP() []byte {
+	file_fuzz_fuzz_proto_rawDescOnce.Do(func() {
+		file_fuzz_fuzz_proto_rawDescData = protoimpl.X.CompressGZIP(file_fuzz_fuzz_proto_rawDescData)
+	})
+	return file_fuzz_fuzz_proto_rawDescData
+}
+
+var file_fuzz_fuzz_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_fuzz_fuzz_proto_goTypes = []interface{}{
+	(*Fuzz)(nil),                         // 0: goproto.proto.fuzz.Fuzz
+	(*test.TestAllTypes)(nil),            // 1: goproto.proto.test.TestAllTypes
+	(*test.TestAllExtensions)(nil),       // 2: goproto.proto.test.TestAllExtensions
+	(*test.TestRequired)(nil),            // 3: goproto.proto.test.TestRequired
+	(*test.TestRequiredForeign)(nil),     // 4: goproto.proto.test.TestRequiredForeign
+	(*test.TestRequiredGroupFields)(nil), // 5: goproto.proto.test.TestRequiredGroupFields
+	(*test.TestPackedTypes)(nil),         // 6: goproto.proto.test.TestPackedTypes
+	(*test.TestPackedExtensions)(nil),    // 7: goproto.proto.test.TestPackedExtensions
+	(*test3.TestAllTypes)(nil),           // 8: goproto.proto.test3.TestAllTypes
+}
+var file_fuzz_fuzz_proto_depIdxs = []int32{
+	1, // 0: goproto.proto.fuzz.Fuzz.test_all_types:type_name -> goproto.proto.test.TestAllTypes
+	2, // 1: goproto.proto.fuzz.Fuzz.test_all_extensions:type_name -> goproto.proto.test.TestAllExtensions
+	3, // 2: goproto.proto.fuzz.Fuzz.test_required:type_name -> goproto.proto.test.TestRequired
+	4, // 3: goproto.proto.fuzz.Fuzz.test_required_foreign:type_name -> goproto.proto.test.TestRequiredForeign
+	5, // 4: goproto.proto.fuzz.Fuzz.test_required_group_fields:type_name -> goproto.proto.test.TestRequiredGroupFields
+	6, // 5: goproto.proto.fuzz.Fuzz.test_packed_types:type_name -> goproto.proto.test.TestPackedTypes
+	7, // 6: goproto.proto.fuzz.Fuzz.test_packed_extensions:type_name -> goproto.proto.test.TestPackedExtensions
+	8, // 7: goproto.proto.fuzz.Fuzz.test_all_types3:type_name -> goproto.proto.test3.TestAllTypes
+	8, // [8:8] is the sub-list for method output_type
+	8, // [8:8] is the sub-list for method input_type
+	8, // [8:8] is the sub-list for extension type_name
+	8, // [8:8] is the sub-list for extension extendee
+	0, // [0:8] is the sub-list for field type_name
+}
+
+func init() { file_fuzz_fuzz_proto_init() }
+func file_fuzz_fuzz_proto_init() {
+	if File_fuzz_fuzz_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_fuzz_fuzz_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Fuzz); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_fuzz_fuzz_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   1,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_fuzz_fuzz_proto_goTypes,
+		DependencyIndexes: file_fuzz_fuzz_proto_depIdxs,
+		MessageInfos:      file_fuzz_fuzz_proto_msgTypes,
+	}.Build()
+	File_fuzz_fuzz_proto = out.File
+	file_fuzz_fuzz_proto_rawDesc = nil
+	file_fuzz_fuzz_proto_goTypes = nil
+	file_fuzz_fuzz_proto_depIdxs = nil
+}
diff --git a/internal/testprotos/fuzz/fuzz.proto b/internal/testprotos/fuzz/fuzz.proto
new file mode 100644
index 0000000..917e1e9
--- /dev/null
+++ b/internal/testprotos/fuzz/fuzz.proto
@@ -0,0 +1,20 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package goproto.proto.fuzz;
+
+import "test/test.proto";
+import "test3/test.proto";
+
+// Fuzz is a container for every message we want to make available to the fuzzer.
+message Fuzz {
+  optional goproto.proto.test.TestAllTypes test_all_types = 1;
+  optional goproto.proto.test.TestAllExtensions test_all_extensions = 2;
+  optional goproto.proto.test.TestRequired test_required = 3;
+  optional goproto.proto.test.TestRequiredForeign test_required_foreign = 4;
+  optional goproto.proto.test.TestRequiredGroupFields test_required_group_fields = 5;
+  optional goproto.proto.test.TestPackedTypes test_packed_types = 6;
+  optional goproto.proto.test.TestPackedExtensions test_packed_extensions = 7;
+  optional goproto.proto.test3.TestAllTypes test_all_types3 = 8;
+}