cmd/protoc-gen-go: generate XXX_OneofWrappers instead of XXX_OneofFuncs

The marshaler, unmarshaler, and sizer functions are unused ever since
the underlying implementation was switched to be table-driven.
Change the function to only return the wrapper structs.

This change:
* enables generated protos to drop dependencies on certain proto types
* reduces the size of generated protos
* simplifies the implementation of oneofs in protoc-gen-go

Updates #708

Change-Id: I845c9009bc0236d1b51d34b014dc3e184303c0f2
Reviewed-on: https://go-review.googlesource.com/c/151357
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/cmd/protoc-gen-go/internal_gengo/main.go b/cmd/protoc-gen-go/internal_gengo/main.go
index 3dcf7c9..6fd1fca 100644
--- a/cmd/protoc-gen-go/internal_gengo/main.go
+++ b/cmd/protoc-gen-go/internal_gengo/main.go
@@ -27,7 +27,7 @@
 // It is incremented whenever an incompatibility between the generated code and
 // proto package is introduced; the generated code references
 // a constant, proto.ProtoPackageIsVersionN (where N is generatedCodeVersion).
-const generatedCodeVersion = 2
+const generatedCodeVersion = 3
 
 const (
 	fmtPackage   = protogen.GoImportPath("fmt")
@@ -563,7 +563,7 @@
 	}
 
 	if len(message.Oneofs) > 0 {
-		genOneofFuncs(gen, g, f, message)
+		genOneofWrappers(gen, g, f, message)
 	}
 	for _, extension := range message.Extensions {
 		genExtension(gen, g, f, extension)
@@ -832,3 +832,116 @@
 	"google.protobuf.UInt64Value": true,
 	"google.protobuf.Value":       true,
 }
+
+// genOneofField generates the struct field for a oneof.
+func genOneofField(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, message *protogen.Message, oneof *protogen.Oneof) {
+	if g.PrintLeadingComments(oneof.Location) {
+		g.P("//")
+	}
+	g.P("// Types that are valid to be assigned to ", oneofFieldName(oneof), ":")
+	for _, field := range oneof.Fields {
+		g.PrintLeadingComments(field.Location)
+		g.P("//\t*", fieldOneofType(field))
+	}
+	g.Annotate(message.GoIdent.GoName+"."+oneofFieldName(oneof), oneof.Location)
+	g.P(oneofFieldName(oneof), " ", oneofInterfaceName(oneof), " `protobuf_oneof:\"", oneof.Desc.Name(), "\"`")
+}
+
+// genOneofTypes generates the interface type used for a oneof field,
+// and the wrapper types that satisfy that interface.
+//
+// It also generates the getter method for the parent oneof field
+// (but not the member fields).
+func genOneofTypes(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, message *protogen.Message, oneof *protogen.Oneof) {
+	ifName := oneofInterfaceName(oneof)
+	g.P("type ", ifName, " interface {")
+	g.P(ifName, "()")
+	g.P("}")
+	g.P()
+	for _, field := range oneof.Fields {
+		name := fieldOneofType(field)
+		g.Annotate(name.GoName, field.Location)
+		g.Annotate(name.GoName+"."+field.GoName, field.Location)
+		g.P("type ", name, " struct {")
+		goType, _ := fieldGoType(g, field)
+		tags := []string{
+			fmt.Sprintf("protobuf:%q", fieldProtobufTag(field)),
+		}
+		g.P(field.GoName, " ", goType, " `", strings.Join(tags, " "), "`")
+		g.P("}")
+		g.P()
+	}
+	for _, field := range oneof.Fields {
+		g.P("func (*", fieldOneofType(field), ") ", ifName, "() {}")
+		g.P()
+	}
+	g.Annotate(message.GoIdent.GoName+".Get"+oneof.GoName, oneof.Location)
+	g.P("func (m *", message.GoIdent.GoName, ") Get", oneof.GoName, "() ", ifName, " {")
+	g.P("if m != nil {")
+	g.P("return m.", oneofFieldName(oneof))
+	g.P("}")
+	g.P("return nil")
+	g.P("}")
+	g.P()
+}
+
+// oneofFieldName returns the name of the struct field holding the oneof value.
+//
+// This function is trivial, but pulling out the name like this makes it easier
+// to experiment with alternative oneof implementations.
+func oneofFieldName(oneof *protogen.Oneof) string {
+	return oneof.GoName
+}
+
+// oneofInterfaceName returns the name of the interface type implemented by
+// the oneof field value types.
+func oneofInterfaceName(oneof *protogen.Oneof) string {
+	return fmt.Sprintf("is%s_%s", oneof.ParentMessage.GoIdent.GoName, oneof.GoName)
+}
+
+// genOneofWrappers generates the XXX_OneofWrappers method for a message.
+func genOneofWrappers(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, message *protogen.Message) {
+	g.P("// XXX_OneofWrappers is for the internal use of the proto package.")
+	g.P("func (*", message.GoIdent.GoName, ") XXX_OneofWrappers() []interface{} {")
+	g.P("return []interface{}{")
+	for _, oneof := range message.Oneofs {
+		for _, field := range oneof.Fields {
+			g.P("(*", fieldOneofType(field), ")(nil),")
+		}
+	}
+	g.P("}")
+	g.P("}")
+	g.P()
+}
+
+// fieldOneofType returns the wrapper type used to represent a field in a oneof.
+func fieldOneofType(field *protogen.Field) protogen.GoIdent {
+	ident := protogen.GoIdent{
+		GoImportPath: field.ParentMessage.GoIdent.GoImportPath,
+		GoName:       field.ParentMessage.GoIdent.GoName + "_" + field.GoName,
+	}
+	// Check for collisions with nested messages or enums.
+	//
+	// This conflict resolution is incomplete: Among other things, it
+	// does not consider collisions with other oneof field types.
+	//
+	// TODO: Consider dropping this entirely. Detecting conflicts and
+	// producing an error is almost certainly better than permuting
+	// field and type names in mostly unpredictable ways.
+Loop:
+	for {
+		for _, message := range field.ParentMessage.Messages {
+			if message.GoIdent == ident {
+				ident.GoName += "_"
+				continue Loop
+			}
+		}
+		for _, enum := range field.ParentMessage.Enums {
+			if enum.GoIdent == ident {
+				ident.GoName += "_"
+				continue Loop
+			}
+		}
+		return ident
+	}
+}
diff --git a/cmd/protoc-gen-go/internal_gengo/oneof.go b/cmd/protoc-gen-go/internal_gengo/oneof.go
deleted file mode 100644
index 8f84b2d..0000000
--- a/cmd/protoc-gen-go/internal_gengo/oneof.go
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright 2018 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 internal_gengo
-
-import (
-	"fmt"
-	"strings"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/v2/protogen"
-	"github.com/golang/protobuf/v2/reflect/protoreflect"
-)
-
-// genOneofField generates the struct field for a oneof.
-func genOneofField(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, message *protogen.Message, oneof *protogen.Oneof) {
-	if g.PrintLeadingComments(oneof.Location) {
-		g.P("//")
-	}
-	g.P("// Types that are valid to be assigned to ", oneofFieldName(oneof), ":")
-	for _, field := range oneof.Fields {
-		g.PrintLeadingComments(field.Location)
-		g.P("//\t*", fieldOneofType(field))
-	}
-	g.Annotate(message.GoIdent.GoName+"."+oneofFieldName(oneof), oneof.Location)
-	g.P(oneofFieldName(oneof), " ", oneofInterfaceName(oneof), " `protobuf_oneof:\"", oneof.Desc.Name(), "\"`")
-}
-
-// genOneofTypes generates the interface type used for a oneof field,
-// and the wrapper types that satisfy that interface.
-//
-// It also generates the getter method for the parent oneof field
-// (but not the member fields).
-func genOneofTypes(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, message *protogen.Message, oneof *protogen.Oneof) {
-	ifName := oneofInterfaceName(oneof)
-	g.P("type ", ifName, " interface {")
-	g.P(ifName, "()")
-	g.P("}")
-	g.P()
-	for _, field := range oneof.Fields {
-		name := fieldOneofType(field)
-		g.Annotate(name.GoName, field.Location)
-		g.Annotate(name.GoName+"."+field.GoName, field.Location)
-		g.P("type ", name, " struct {")
-		goType, _ := fieldGoType(g, field)
-		tags := []string{
-			fmt.Sprintf("protobuf:%q", fieldProtobufTag(field)),
-		}
-		g.P(field.GoName, " ", goType, " `", strings.Join(tags, " "), "`")
-		g.P("}")
-		g.P()
-	}
-	for _, field := range oneof.Fields {
-		g.P("func (*", fieldOneofType(field), ") ", ifName, "() {}")
-		g.P()
-	}
-	g.Annotate(message.GoIdent.GoName+".Get"+oneof.GoName, oneof.Location)
-	g.P("func (m *", message.GoIdent.GoName, ") Get", oneof.GoName, "() ", ifName, " {")
-	g.P("if m != nil {")
-	g.P("return m.", oneofFieldName(oneof))
-	g.P("}")
-	g.P("return nil")
-	g.P("}")
-	g.P()
-}
-
-// oneofFieldName returns the name of the struct field holding the oneof value.
-//
-// This function is trivial, but pulling out the name like this makes it easier
-// to experiment with alternative oneof implementations.
-func oneofFieldName(oneof *protogen.Oneof) string {
-	return oneof.GoName
-}
-
-// oneofInterfaceName returns the name of the interface type implemented by
-// the oneof field value types.
-func oneofInterfaceName(oneof *protogen.Oneof) string {
-	return fmt.Sprintf("is%s_%s", oneof.ParentMessage.GoIdent.GoName, oneof.GoName)
-}
-
-// genOneofFuncs generates the XXX_OneofFuncs method for a message.
-func genOneofFuncs(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, message *protogen.Message) {
-	protoMessage := g.QualifiedGoIdent(protoPackage.Ident("Message"))
-	protoBuffer := g.QualifiedGoIdent(protoPackage.Ident("Buffer"))
-	encFunc := "_" + message.GoIdent.GoName + "_OneofMarshaler"
-	decFunc := "_" + message.GoIdent.GoName + "_OneofUnmarshaler"
-	sizeFunc := "_" + message.GoIdent.GoName + "_OneofSizer"
-	encSig := "(msg " + protoMessage + ", b *" + protoBuffer + ") error"
-	decSig := "(msg " + protoMessage + ", tag, wire int, b *" + protoBuffer + ") (bool, error)"
-	sizeSig := "(msg " + protoMessage + ") (n int)"
-
-	// XXX_OneofFuncs
-	g.P("// XXX_OneofFuncs is for the internal use of the proto package.")
-	g.P("func (*", message.GoIdent.GoName, ") XXX_OneofFuncs() (func ", encSig, ", func ", decSig, ", func ", sizeSig, ", []interface{}) {")
-	g.P("return ", encFunc, ", ", decFunc, ", ", sizeFunc, ", []interface{}{")
-	for _, oneof := range message.Oneofs {
-		for _, field := range oneof.Fields {
-			g.P("(*", fieldOneofType(field), ")(nil),")
-		}
-	}
-	g.P("}")
-	g.P("}")
-	g.P()
-
-	// Marshaler
-	g.P("func ", encFunc, encSig, " {")
-	g.P("m := msg.(*", message.GoIdent, ")")
-	for _, oneof := range message.Oneofs {
-		g.P("// ", oneof.Desc.Name())
-		g.P("switch x := m.", oneofFieldName(oneof), ".(type) {")
-		for _, field := range oneof.Fields {
-			genOneofFieldMarshal(g, field)
-		}
-		g.P("case nil:")
-		g.P("default:")
-		g.P("return ", fmtPackage.Ident("Errorf"), `("`, message.GoIdent.GoName, ".", oneofFieldName(oneof), ` has unexpected type %T", x)`)
-		g.P("}")
-	}
-	g.P("return nil")
-	g.P("}")
-	g.P()
-
-	// Unmarshaler
-	g.P("func ", decFunc, decSig, " {")
-	g.P("m := msg.(*", message.GoIdent, ")")
-	g.P("switch tag {")
-	for _, oneof := range message.Oneofs {
-		for _, field := range oneof.Fields {
-			genOneofFieldUnmarshal(g, field)
-		}
-	}
-	g.P("default:")
-	g.P("return false, nil")
-	g.P("}")
-	g.P("}")
-	g.P()
-
-	// Sizer
-	g.P("func ", sizeFunc, sizeSig, " {")
-	g.P("m := msg.(*", message.GoIdent, ")")
-	for _, oneof := range message.Oneofs {
-		g.P("// ", oneof.Desc.Name())
-		g.P("switch x := m.", oneofFieldName(oneof), ".(type) {")
-		for _, field := range oneof.Fields {
-			genOneofFieldSizer(g, field)
-		}
-		g.P("case nil:")
-		g.P("default:")
-		g.P("panic(", fmtPackage.Ident("Sprintf"), `("proto: unexpected type %T in oneof", x))`)
-		g.P("}")
-	}
-	g.P("return n")
-	g.P("}")
-	g.P()
-}
-
-// genOneofFieldMarshal generates the marshal case for a oneof subfield.
-func genOneofFieldMarshal(g *protogen.GeneratedFile, field *protogen.Field) {
-	g.P("case *", fieldOneofType(field), ":")
-	encodeTag := func(wireType string) {
-		g.P("b.EncodeVarint(", field.Desc.Number(), "<<3|", protoPackage.Ident(wireType), ")")
-	}
-	switch field.Desc.Kind() {
-	case protoreflect.BoolKind:
-		g.P("t := uint64(0)")
-		g.P("if x.", field.GoName, " { t = 1 }")
-		encodeTag("WireVarint")
-		g.P("b.EncodeVarint(t)")
-	case protoreflect.EnumKind, protoreflect.Int32Kind, protoreflect.Uint32Kind, protoreflect.Int64Kind, protoreflect.Uint64Kind:
-		encodeTag("WireVarint")
-		g.P("b.EncodeVarint(uint64(x.", field.GoName, "))")
-	case protoreflect.Sint32Kind:
-		encodeTag("WireVarint")
-		g.P("b.EncodeZigzag32(uint64(x.", field.GoName, "))")
-	case protoreflect.Sint64Kind:
-		encodeTag("WireVarint")
-		g.P("b.EncodeZigzag64(uint64(x.", field.GoName, "))")
-	case protoreflect.Sfixed32Kind, protoreflect.Fixed32Kind:
-		encodeTag("WireFixed32")
-		g.P("b.EncodeFixed32(uint64(x.", field.GoName, "))")
-	case protoreflect.FloatKind:
-		encodeTag("WireFixed32")
-		g.P("b.EncodeFixed32(uint64(", mathPackage.Ident("Float32bits"), "(x.", field.GoName, ")))")
-	case protoreflect.Sfixed64Kind, protoreflect.Fixed64Kind:
-		encodeTag("WireFixed64")
-		g.P("b.EncodeFixed64(uint64(x.", field.GoName, "))")
-	case protoreflect.DoubleKind:
-		encodeTag("WireFixed64")
-		g.P("b.EncodeFixed64(", mathPackage.Ident("Float64bits"), "(x.", field.GoName, "))")
-	case protoreflect.StringKind:
-		encodeTag("WireBytes")
-		g.P("b.EncodeStringBytes(x.", field.GoName, ")")
-	case protoreflect.BytesKind:
-		encodeTag("WireBytes")
-		g.P("b.EncodeRawBytes(x.", field.GoName, ")")
-	case protoreflect.MessageKind:
-		encodeTag("WireBytes")
-		g.P("if err := b.EncodeMessage(x.", field.GoName, "); err != nil {")
-		g.P("return err")
-		g.P("}")
-	case protoreflect.GroupKind:
-		encodeTag("WireStartGroup")
-		g.P("if err := b.Marshal(x.", field.GoName, "); err != nil {")
-		g.P("return err")
-		g.P("}")
-		encodeTag("WireEndGroup")
-	}
-}
-
-// genOneofFieldUnmarshal generates the unmarshal case for a oneof subfield.
-func genOneofFieldUnmarshal(g *protogen.GeneratedFile, field *protogen.Field) {
-	oneof := field.OneofType
-	g.P("case ", field.Desc.Number(), ": // ", oneof.Desc.Name(), ".", field.Desc.Name())
-	checkTag := func(wireType string) {
-		g.P("if wire != ", protoPackage.Ident(wireType), " {")
-		g.P("return true, ", protoPackage.Ident("ErrInternalBadWireType"))
-		g.P("}")
-	}
-	switch field.Desc.Kind() {
-	case protoreflect.BoolKind:
-		checkTag("WireVarint")
-		g.P("x, err := b.DecodeVarint()")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{x != 0}")
-	case protoreflect.EnumKind:
-		checkTag("WireVarint")
-		g.P("x, err := b.DecodeVarint()")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{", field.EnumType.GoIdent, "(x)}")
-	case protoreflect.Int32Kind, protoreflect.Uint32Kind, protoreflect.Int64Kind, protoreflect.Uint64Kind:
-		checkTag("WireVarint")
-		g.P("x, err := b.DecodeVarint()")
-		x := "x"
-		if goType, _ := fieldGoType(g, field); goType != "uint64" {
-			x = goType + "(x)"
-		}
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{", x, "}")
-	case protoreflect.Sint32Kind:
-		checkTag("WireVarint")
-		g.P("x, err := b.DecodeZigzag32()")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{int32(x)}")
-	case protoreflect.Sint64Kind:
-		checkTag("WireVarint")
-		g.P("x, err := b.DecodeZigzag64()")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{int64(x)}")
-	case protoreflect.Sfixed32Kind:
-		checkTag("WireFixed32")
-		g.P("x, err := b.DecodeFixed32()")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{int32(x)}")
-	case protoreflect.Fixed32Kind:
-		checkTag("WireFixed32")
-		g.P("x, err := b.DecodeFixed32()")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{uint32(x)}")
-	case protoreflect.FloatKind:
-		checkTag("WireFixed32")
-		g.P("x, err := b.DecodeFixed32()")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{", mathPackage.Ident("Float32frombits"), "(uint32(x))}")
-	case protoreflect.Sfixed64Kind:
-		checkTag("WireFixed64")
-		g.P("x, err := b.DecodeFixed64()")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{int64(x)}")
-	case protoreflect.Fixed64Kind:
-		checkTag("WireFixed64")
-		g.P("x, err := b.DecodeFixed64()")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{x}")
-	case protoreflect.DoubleKind:
-		checkTag("WireFixed64")
-		g.P("x, err := b.DecodeFixed64()")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{", mathPackage.Ident("Float64frombits"), "(x)}")
-	case protoreflect.StringKind:
-		checkTag("WireBytes")
-		g.P("x, err := b.DecodeStringBytes()")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{x}")
-	case protoreflect.BytesKind:
-		checkTag("WireBytes")
-		g.P("x, err := b.DecodeRawBytes(true)")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{x}")
-	case protoreflect.MessageKind:
-		checkTag("WireBytes")
-		g.P("msg := new(", field.MessageType.GoIdent, ")")
-		g.P("err := b.DecodeMessage(msg)")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{msg}")
-	case protoreflect.GroupKind:
-		checkTag("WireStartGroup")
-		g.P("msg := new(", field.MessageType.GoIdent, ")")
-		g.P("err := b.DecodeGroup(msg)")
-		g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{msg}")
-	}
-	g.P("return true, err")
-}
-
-// genOneofFieldSizer  generates the sizer case for a oneof subfield.
-func genOneofFieldSizer(g *protogen.GeneratedFile, field *protogen.Field) {
-	sizeProto := protoPackage.Ident("Size")
-	sizeVarint := protoPackage.Ident("SizeVarint")
-	g.P("case *", fieldOneofType(field), ":")
-	if field.Desc.Kind() == protoreflect.MessageKind {
-		g.P("s := ", sizeProto, "(x.", field.GoName, ")")
-	}
-	// Tag and wire varint is known statically.
-	tagAndWireSize := proto.SizeVarint(uint64(field.Desc.Number()) << 3) // wire doesn't affect varint size
-	g.P("n += ", tagAndWireSize, " // tag and wire")
-	switch field.Desc.Kind() {
-	case protoreflect.BoolKind:
-		g.P("n += 1")
-	case protoreflect.EnumKind, protoreflect.Int32Kind, protoreflect.Uint32Kind, protoreflect.Int64Kind, protoreflect.Uint64Kind:
-		g.P("n += ", sizeVarint, "(uint64(x.", field.GoName, "))")
-	case protoreflect.Sint32Kind:
-		g.P("n += ", sizeVarint, "(uint64((uint32(x.", field.GoName, ") << 1) ^ uint32((int32(x.", field.GoName, ") >> 31))))")
-	case protoreflect.Sint64Kind:
-		g.P("n += ", sizeVarint, "(uint64(uint64(x.", field.GoName, "<<1) ^ uint64((int64(x.", field.GoName, ") >> 63))))")
-	case protoreflect.Sfixed32Kind, protoreflect.Fixed32Kind, protoreflect.FloatKind:
-		g.P("n += 4")
-	case protoreflect.Sfixed64Kind, protoreflect.Fixed64Kind, protoreflect.DoubleKind:
-		g.P("n += 8")
-	case protoreflect.StringKind, protoreflect.BytesKind:
-		g.P("n += ", sizeVarint, "(uint64(len(x.", field.GoName, ")))")
-		g.P("n += len(x.", field.GoName, ")")
-	case protoreflect.MessageKind:
-		g.P("n += ", sizeVarint, "(uint64(s))")
-		g.P("n += s")
-	case protoreflect.GroupKind:
-		g.P("n += ", sizeProto, "(x.", field.GoName, ")")
-		g.P("n += ", tagAndWireSize, " // tag and wire")
-	}
-}
-
-// fieldOneofType returns the wrapper type used to represent a field in a oneof.
-func fieldOneofType(field *protogen.Field) protogen.GoIdent {
-	ident := protogen.GoIdent{
-		GoImportPath: field.ParentMessage.GoIdent.GoImportPath,
-		GoName:       field.ParentMessage.GoIdent.GoName + "_" + field.GoName,
-	}
-	// Check for collisions with nested messages or enums.
-	//
-	// This conflict resolution is incomplete: Among other things, it
-	// does not consider collisions with other oneof field types.
-	//
-	// TODO: Consider dropping this entirely. Detecting conflicts and
-	// producing an error is almost certainly better than permuting
-	// field and type names in mostly unpredictable ways.
-Loop:
-	for {
-		for _, message := range field.ParentMessage.Messages {
-			if message.GoIdent == ident {
-				ident.GoName += "_"
-				continue Loop
-			}
-		}
-		for _, enum := range field.ParentMessage.Enums {
-			if enum.GoIdent == ident {
-				ident.GoName += "_"
-				continue Loop
-			}
-		}
-		return ident
-	}
-}
diff --git a/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go b/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go
index 7f6e574..71a8e5d 100644
--- a/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go
+++ b/cmd/protoc-gen-go/testdata/annotations/annotations.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type AnnotationsTestEnum int32
 
diff --git a/cmd/protoc-gen-go/testdata/comments/comments.pb.go b/cmd/protoc-gen-go/testdata/comments/comments.pb.go
index 4a6cd3f..62bfafd 100644
--- a/cmd/protoc-gen-go/testdata/comments/comments.pb.go
+++ b/cmd/protoc-gen-go/testdata/comments/comments.pb.go
@@ -20,7 +20,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 // COMMENT: Message1
 type Message1 struct {
@@ -93,57 +93,13 @@
 	return ""
 }
 
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*Message1) 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 _Message1_OneofMarshaler, _Message1_OneofUnmarshaler, _Message1_OneofSizer, []interface{}{
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*Message1) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
 		(*Message1_Oneof1AField1)(nil),
 	}
 }
 
-func _Message1_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*Message1)
-	// Oneof1a
-	switch x := m.Oneof1A.(type) {
-	case *Message1_Oneof1AField1:
-		b.EncodeVarint(2<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.Oneof1AField1)
-	case nil:
-	default:
-		return fmt.Errorf("Message1.Oneof1A has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _Message1_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*Message1)
-	switch tag {
-	case 2: // Oneof1a.Oneof1AField1
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.Oneof1A = &Message1_Oneof1AField1{x}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _Message1_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*Message1)
-	// Oneof1a
-	switch x := m.Oneof1A.(type) {
-	case *Message1_Oneof1AField1:
-		n += 1 // tag and wire
-		n += proto.SizeVarint(uint64(len(x.Oneof1AField1)))
-		n += len(x.Oneof1AField1)
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
 // COMMENT: Message1A
 type Message1_Message1A struct {
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
diff --git a/cmd/protoc-gen-go/testdata/comments/deprecated.pb.go b/cmd/protoc-gen-go/testdata/comments/deprecated.pb.go
index fb87120..02cb7af 100644
--- a/cmd/protoc-gen-go/testdata/comments/deprecated.pb.go
+++ b/cmd/protoc-gen-go/testdata/comments/deprecated.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type DeprecatedEnum int32 // Deprecated: Do not use.
 const (
diff --git a/cmd/protoc-gen-go/testdata/extensions/base/base.pb.go b/cmd/protoc-gen-go/testdata/extensions/base/base.pb.go
index 64b5383..76f04e0 100644
--- a/cmd/protoc-gen-go/testdata/extensions/base/base.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/base/base.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type BaseMessage struct {
 	Field                        *string  `protobuf:"bytes,1,opt,name=field" json:"field,omitempty"`
diff --git a/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go b/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
index 4170822..908eaba 100644
--- a/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/ext/ext.pb.go
@@ -20,7 +20,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type Enum int32
 
diff --git a/cmd/protoc-gen-go/testdata/extensions/extra/extra.pb.go b/cmd/protoc-gen-go/testdata/extensions/extra/extra.pb.go
index 043edce..ad3b3f2 100644
--- a/cmd/protoc-gen-go/testdata/extensions/extra/extra.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/extra/extra.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type ExtraMessage struct {
 	Data                 []byte   `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"`
diff --git a/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go b/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
index d1f1380..f2ae2e2 100644
--- a/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
+++ b/cmd/protoc-gen-go/testdata/extensions/proto3/ext3.pb.go
@@ -19,7 +19,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type Enum int32
 
diff --git a/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go b/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
index eb97be1..96676ef 100644
--- a/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
+++ b/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 // Assorted edge cases in field name conflict resolution.
 //
@@ -273,9 +273,9 @@
 	return ""
 }
 
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*Message) 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 _Message_OneofMarshaler, _Message_OneofUnmarshaler, _Message_OneofSizer, []interface{}{
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*Message) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
 		(*Message_OneofConflictA)(nil),
 		(*Message_OneofNoConflict)(nil),
 		(*Message_OneofConflictB_)(nil),
@@ -283,116 +283,6 @@
 	}
 }
 
-func _Message_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*Message)
-	// oneof_conflict_a
-	switch x := m.OneofConflictA_.(type) {
-	case *Message_OneofConflictA:
-		b.EncodeVarint(40<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.OneofConflictA)
-	case nil:
-	default:
-		return fmt.Errorf("Message.OneofConflictA_ has unexpected type %T", x)
-	}
-	// oneof_conflict_b
-	switch x := m.OneofConflictB.(type) {
-	case *Message_OneofNoConflict:
-		b.EncodeVarint(50<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.OneofNoConflict)
-	case *Message_OneofConflictB_:
-		b.EncodeVarint(51<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.OneofConflictB_)
-	case nil:
-	default:
-		return fmt.Errorf("Message.OneofConflictB has unexpected type %T", x)
-	}
-	// oneof_conflict_c
-	switch x := m.OneofConflictC.(type) {
-	case *Message_OneofMessageConflict_:
-		b.EncodeVarint(60<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.OneofMessageConflict)
-	case nil:
-	default:
-		return fmt.Errorf("Message.OneofConflictC has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _Message_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*Message)
-	switch tag {
-	case 40: // oneof_conflict_a.OneofConflictA
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.OneofConflictA_ = &Message_OneofConflictA{x}
-		return true, err
-	case 50: // oneof_conflict_b.oneof_no_conflict
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.OneofConflictB = &Message_OneofNoConflict{x}
-		return true, err
-	case 51: // oneof_conflict_b.OneofConflictB
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.OneofConflictB = &Message_OneofConflictB_{x}
-		return true, err
-	case 60: // oneof_conflict_c.oneof_message_conflict
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.OneofConflictC = &Message_OneofMessageConflict_{x}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _Message_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*Message)
-	// oneof_conflict_a
-	switch x := m.OneofConflictA_.(type) {
-	case *Message_OneofConflictA:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(len(x.OneofConflictA)))
-		n += len(x.OneofConflictA)
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	// oneof_conflict_b
-	switch x := m.OneofConflictB.(type) {
-	case *Message_OneofNoConflict:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(len(x.OneofNoConflict)))
-		n += len(x.OneofNoConflict)
-	case *Message_OneofConflictB_:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(len(x.OneofConflictB_)))
-		n += len(x.OneofConflictB_)
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	// oneof_conflict_c
-	switch x := m.OneofConflictC.(type) {
-	case *Message_OneofMessageConflict_:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(len(x.OneofMessageConflict)))
-		n += len(x.OneofMessageConflict)
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
 type Message_OneofMessageConflict struct {
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
diff --git a/cmd/protoc-gen-go/testdata/import_public/a.pb.go b/cmd/protoc-gen-go/testdata/import_public/a.pb.go
index 9b18dc0..3870ac0 100644
--- a/cmd/protoc-gen-go/testdata/import_public/a.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/a.pb.go
@@ -19,7 +19,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 const Default_M_S = sub.Default_M_S
 
diff --git a/cmd/protoc-gen-go/testdata/import_public/b.pb.go b/cmd/protoc-gen-go/testdata/import_public/b.pb.go
index 62ff437..0b1ce40 100644
--- a/cmd/protoc-gen-go/testdata/import_public/b.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/b.pb.go
@@ -19,7 +19,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type Local struct {
 	M                    *sub.M   `protobuf:"bytes,1,opt,name=m" json:"m,omitempty"`
diff --git a/cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go b/cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go
index b9218c2..35b37f2 100644
--- a/cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/sub/a.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type E int32
 
@@ -231,70 +231,14 @@
 	return 0
 }
 
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*M) 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 _M_OneofMarshaler, _M_OneofUnmarshaler, _M_OneofSizer, []interface{}{
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*M) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
 		(*M_OneofInt32)(nil),
 		(*M_OneofInt64)(nil),
 	}
 }
 
-func _M_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*M)
-	// oneof_field
-	switch x := m.OneofField.(type) {
-	case *M_OneofInt32:
-		b.EncodeVarint(2<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.OneofInt32))
-	case *M_OneofInt64:
-		b.EncodeVarint(3<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.OneofInt64))
-	case nil:
-	default:
-		return fmt.Errorf("M.OneofField has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _M_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*M)
-	switch tag {
-	case 2: // oneof_field.oneof_int32
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofField = &M_OneofInt32{int32(x)}
-		return true, err
-	case 3: // oneof_field.oneof_int64
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofField = &M_OneofInt64{int64(x)}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _M_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*M)
-	// oneof_field
-	switch x := m.OneofField.(type) {
-	case *M_OneofInt32:
-		n += 1 // tag and wire
-		n += proto.SizeVarint(uint64(x.OneofInt32))
-	case *M_OneofInt64:
-		n += 1 // tag and wire
-		n += proto.SizeVarint(uint64(x.OneofInt64))
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
 type M_Submessage struct {
 	// Types that are valid to be assigned to SubmessageOneofField:
 	//	*M_Submessage_SubmessageOneofInt32
@@ -367,70 +311,14 @@
 	return 0
 }
 
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*M_Submessage) 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 _M_Submessage_OneofMarshaler, _M_Submessage_OneofUnmarshaler, _M_Submessage_OneofSizer, []interface{}{
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*M_Submessage) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
 		(*M_Submessage_SubmessageOneofInt32)(nil),
 		(*M_Submessage_SubmessageOneofInt64)(nil),
 	}
 }
 
-func _M_Submessage_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*M_Submessage)
-	// submessage_oneof_field
-	switch x := m.SubmessageOneofField.(type) {
-	case *M_Submessage_SubmessageOneofInt32:
-		b.EncodeVarint(1<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.SubmessageOneofInt32))
-	case *M_Submessage_SubmessageOneofInt64:
-		b.EncodeVarint(2<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.SubmessageOneofInt64))
-	case nil:
-	default:
-		return fmt.Errorf("M_Submessage.SubmessageOneofField has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _M_Submessage_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*M_Submessage)
-	switch tag {
-	case 1: // submessage_oneof_field.submessage_oneof_int32
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.SubmessageOneofField = &M_Submessage_SubmessageOneofInt32{int32(x)}
-		return true, err
-	case 2: // submessage_oneof_field.submessage_oneof_int64
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.SubmessageOneofField = &M_Submessage_SubmessageOneofInt64{int64(x)}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _M_Submessage_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*M_Submessage)
-	// submessage_oneof_field
-	switch x := m.SubmessageOneofField.(type) {
-	case *M_Submessage_SubmessageOneofInt32:
-		n += 1 // tag and wire
-		n += proto.SizeVarint(uint64(x.SubmessageOneofInt32))
-	case *M_Submessage_SubmessageOneofInt64:
-		n += 1 // tag and wire
-		n += proto.SizeVarint(uint64(x.SubmessageOneofInt64))
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
 var E_ExtensionField = &proto.ExtensionDesc{
 	ExtendedType:  (*M)(nil),
 	ExtensionType: (*string)(nil),
diff --git a/cmd/protoc-gen-go/testdata/import_public/sub/b.pb.go b/cmd/protoc-gen-go/testdata/import_public/sub/b.pb.go
index 0baad37..d0d43b4 100644
--- a/cmd/protoc-gen-go/testdata/import_public/sub/b.pb.go
+++ b/cmd/protoc-gen-go/testdata/import_public/sub/b.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type M2 struct {
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
diff --git a/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go b/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go
index ec263db..9f774fe 100644
--- a/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/fmt/m.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type M struct {
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go b/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go
index 174854b..1cec006 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type E1 int32
 
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go b/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go
index 9b6cd05..0563d58 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type M2 struct {
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go b/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go
index 61b5155..cbc8430 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type M3 struct {
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
diff --git a/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go b/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go
index 19b0bd8..2771b83 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type M4 struct {
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
diff --git a/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go b/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go
index d15f4c9..51592e7 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type M1 struct {
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
diff --git a/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go b/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go
index 66e66de..f31fb0d 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type M2 struct {
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
diff --git a/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go b/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go
index 6713a20..1fef9ea 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go
@@ -19,7 +19,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type A1M1 struct {
 	F                    *test_a_1.M1 `protobuf:"bytes,1,opt,name=f,proto3" json:"f,omitempty"`
diff --git a/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go b/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go
index a0a1588..13d5dd6 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go
@@ -19,7 +19,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type A1M2 struct {
 	F                    *test_a_1.M2 `protobuf:"bytes,1,opt,name=f,proto3" json:"f,omitempty"`
diff --git a/cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go b/cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go
index 61699b2..60d613d 100644
--- a/cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go
+++ b/cmd/protoc-gen-go/testdata/imports/test_import_all.pb.go
@@ -22,7 +22,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type All struct {
 	Am1                  *test_a_1.M1 `protobuf:"bytes,1,opt,name=am1,proto3" json:"am1,omitempty"`
diff --git a/cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go b/cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go
index fbb7da3..bad4bff 100644
--- a/cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go
+++ b/cmd/protoc-gen-go/testdata/nopackage/nopackage.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type Enum int32
 
diff --git a/cmd/protoc-gen-go/testdata/proto2/enum.pb.go b/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
index 5172108..a4f394b 100644
--- a/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 // EnumType1 comment.
 type EnumType1 int32
diff --git a/cmd/protoc-gen-go/testdata/proto2/fields.pb.go b/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
index 775de73..268dfb5 100644
--- a/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type FieldTestMessage_Enum int32
 
@@ -1083,9 +1083,9 @@
 	return 0
 }
 
-// XXX_OneofFuncs is for the internal use of the proto package.
-func (*FieldTestMessage) 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 _FieldTestMessage_OneofMarshaler, _FieldTestMessage_OneofUnmarshaler, _FieldTestMessage_OneofSizer, []interface{}{
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*FieldTestMessage) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
 		(*FieldTestMessage_OneofBool)(nil),
 		(*FieldTestMessage_OneofEnum)(nil),
 		(*FieldTestMessage_OneofInt32)(nil),
@@ -1110,337 +1110,6 @@
 	}
 }
 
-func _FieldTestMessage_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
-	m := msg.(*FieldTestMessage)
-	// oneof_field
-	switch x := m.OneofField.(type) {
-	case *FieldTestMessage_OneofBool:
-		t := uint64(0)
-		if x.OneofBool {
-			t = 1
-		}
-		b.EncodeVarint(601<<3 | proto.WireVarint)
-		b.EncodeVarint(t)
-	case *FieldTestMessage_OneofEnum:
-		b.EncodeVarint(602<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.OneofEnum))
-	case *FieldTestMessage_OneofInt32:
-		b.EncodeVarint(603<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.OneofInt32))
-	case *FieldTestMessage_OneofSint32:
-		b.EncodeVarint(604<<3 | proto.WireVarint)
-		b.EncodeZigzag32(uint64(x.OneofSint32))
-	case *FieldTestMessage_OneofUint32:
-		b.EncodeVarint(605<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.OneofUint32))
-	case *FieldTestMessage_OneofInt64:
-		b.EncodeVarint(606<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.OneofInt64))
-	case *FieldTestMessage_OneofSint64:
-		b.EncodeVarint(607<<3 | proto.WireVarint)
-		b.EncodeZigzag64(uint64(x.OneofSint64))
-	case *FieldTestMessage_OneofUint64:
-		b.EncodeVarint(608<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.OneofUint64))
-	case *FieldTestMessage_OneofSfixed32:
-		b.EncodeVarint(609<<3 | proto.WireFixed32)
-		b.EncodeFixed32(uint64(x.OneofSfixed32))
-	case *FieldTestMessage_OneofFixed32:
-		b.EncodeVarint(610<<3 | proto.WireFixed32)
-		b.EncodeFixed32(uint64(x.OneofFixed32))
-	case *FieldTestMessage_OneofFloat:
-		b.EncodeVarint(611<<3 | proto.WireFixed32)
-		b.EncodeFixed32(uint64(math.Float32bits(x.OneofFloat)))
-	case *FieldTestMessage_OneofSfixed64:
-		b.EncodeVarint(612<<3 | proto.WireFixed64)
-		b.EncodeFixed64(uint64(x.OneofSfixed64))
-	case *FieldTestMessage_OneofFixed64:
-		b.EncodeVarint(613<<3 | proto.WireFixed64)
-		b.EncodeFixed64(uint64(x.OneofFixed64))
-	case *FieldTestMessage_OneofDouble:
-		b.EncodeVarint(614<<3 | proto.WireFixed64)
-		b.EncodeFixed64(math.Float64bits(x.OneofDouble))
-	case *FieldTestMessage_OneofString:
-		b.EncodeVarint(615<<3 | proto.WireBytes)
-		b.EncodeStringBytes(x.OneofString)
-	case *FieldTestMessage_OneofBytes:
-		b.EncodeVarint(616<<3 | proto.WireBytes)
-		b.EncodeRawBytes(x.OneofBytes)
-	case *FieldTestMessage_Oneof_Message:
-		b.EncodeVarint(617<<3 | proto.WireBytes)
-		if err := b.EncodeMessage(x.Oneof_Message); err != nil {
-			return err
-		}
-	case *FieldTestMessage_Oneofgroup:
-		b.EncodeVarint(618<<3 | proto.WireStartGroup)
-		if err := b.Marshal(x.Oneofgroup); err != nil {
-			return err
-		}
-		b.EncodeVarint(618<<3 | proto.WireEndGroup)
-	case *FieldTestMessage_OneofLargestTag:
-		b.EncodeVarint(536870911<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.OneofLargestTag))
-	case nil:
-	default:
-		return fmt.Errorf("FieldTestMessage.OneofField has unexpected type %T", x)
-	}
-	// oneof_two
-	switch x := m.OneofTwo.(type) {
-	case *FieldTestMessage_OneofTwo_1:
-		b.EncodeVarint(700<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.OneofTwo_1))
-	case *FieldTestMessage_OneofTwo_2:
-		b.EncodeVarint(701<<3 | proto.WireVarint)
-		b.EncodeVarint(uint64(x.OneofTwo_2))
-	case nil:
-	default:
-		return fmt.Errorf("FieldTestMessage.OneofTwo has unexpected type %T", x)
-	}
-	return nil
-}
-
-func _FieldTestMessage_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
-	m := msg.(*FieldTestMessage)
-	switch tag {
-	case 601: // oneof_field.oneof_bool
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofField = &FieldTestMessage_OneofBool{x != 0}
-		return true, err
-	case 602: // oneof_field.oneof_enum
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofField = &FieldTestMessage_OneofEnum{FieldTestMessage_Enum(x)}
-		return true, err
-	case 603: // oneof_field.oneof_int32
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofField = &FieldTestMessage_OneofInt32{int32(x)}
-		return true, err
-	case 604: // oneof_field.oneof_sint32
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeZigzag32()
-		m.OneofField = &FieldTestMessage_OneofSint32{int32(x)}
-		return true, err
-	case 605: // oneof_field.oneof_uint32
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofField = &FieldTestMessage_OneofUint32{uint32(x)}
-		return true, err
-	case 606: // oneof_field.oneof_int64
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofField = &FieldTestMessage_OneofInt64{int64(x)}
-		return true, err
-	case 607: // oneof_field.oneof_sint64
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeZigzag64()
-		m.OneofField = &FieldTestMessage_OneofSint64{int64(x)}
-		return true, err
-	case 608: // oneof_field.oneof_uint64
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofField = &FieldTestMessage_OneofUint64{x}
-		return true, err
-	case 609: // oneof_field.oneof_sfixed32
-		if wire != proto.WireFixed32 {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeFixed32()
-		m.OneofField = &FieldTestMessage_OneofSfixed32{int32(x)}
-		return true, err
-	case 610: // oneof_field.oneof_fixed32
-		if wire != proto.WireFixed32 {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeFixed32()
-		m.OneofField = &FieldTestMessage_OneofFixed32{uint32(x)}
-		return true, err
-	case 611: // oneof_field.oneof_float
-		if wire != proto.WireFixed32 {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeFixed32()
-		m.OneofField = &FieldTestMessage_OneofFloat{math.Float32frombits(uint32(x))}
-		return true, err
-	case 612: // oneof_field.oneof_sfixed64
-		if wire != proto.WireFixed64 {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeFixed64()
-		m.OneofField = &FieldTestMessage_OneofSfixed64{int64(x)}
-		return true, err
-	case 613: // oneof_field.oneof_fixed64
-		if wire != proto.WireFixed64 {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeFixed64()
-		m.OneofField = &FieldTestMessage_OneofFixed64{x}
-		return true, err
-	case 614: // oneof_field.oneof_double
-		if wire != proto.WireFixed64 {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeFixed64()
-		m.OneofField = &FieldTestMessage_OneofDouble{math.Float64frombits(x)}
-		return true, err
-	case 615: // oneof_field.oneof_string
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeStringBytes()
-		m.OneofField = &FieldTestMessage_OneofString{x}
-		return true, err
-	case 616: // oneof_field.oneof_bytes
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeRawBytes(true)
-		m.OneofField = &FieldTestMessage_OneofBytes{x}
-		return true, err
-	case 617: // oneof_field.oneof_Message
-		if wire != proto.WireBytes {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(FieldTestMessage_Message)
-		err := b.DecodeMessage(msg)
-		m.OneofField = &FieldTestMessage_Oneof_Message{msg}
-		return true, err
-	case 618: // oneof_field.oneofgroup
-		if wire != proto.WireStartGroup {
-			return true, proto.ErrInternalBadWireType
-		}
-		msg := new(FieldTestMessage_OneofGroup)
-		err := b.DecodeGroup(msg)
-		m.OneofField = &FieldTestMessage_Oneofgroup{msg}
-		return true, err
-	case 536870911: // oneof_field.oneof_largest_tag
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofField = &FieldTestMessage_OneofLargestTag{int32(x)}
-		return true, err
-	case 700: // oneof_two.oneof_two_1
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofTwo = &FieldTestMessage_OneofTwo_1{int32(x)}
-		return true, err
-	case 701: // oneof_two.oneof_two_2
-		if wire != proto.WireVarint {
-			return true, proto.ErrInternalBadWireType
-		}
-		x, err := b.DecodeVarint()
-		m.OneofTwo = &FieldTestMessage_OneofTwo_2{int64(x)}
-		return true, err
-	default:
-		return false, nil
-	}
-}
-
-func _FieldTestMessage_OneofSizer(msg proto.Message) (n int) {
-	m := msg.(*FieldTestMessage)
-	// oneof_field
-	switch x := m.OneofField.(type) {
-	case *FieldTestMessage_OneofBool:
-		n += 2 // tag and wire
-		n += 1
-	case *FieldTestMessage_OneofEnum:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(x.OneofEnum))
-	case *FieldTestMessage_OneofInt32:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(x.OneofInt32))
-	case *FieldTestMessage_OneofSint32:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64((uint32(x.OneofSint32) << 1) ^ uint32((int32(x.OneofSint32) >> 31))))
-	case *FieldTestMessage_OneofUint32:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(x.OneofUint32))
-	case *FieldTestMessage_OneofInt64:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(x.OneofInt64))
-	case *FieldTestMessage_OneofSint64:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(uint64(x.OneofSint64<<1) ^ uint64((int64(x.OneofSint64) >> 63))))
-	case *FieldTestMessage_OneofUint64:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(x.OneofUint64))
-	case *FieldTestMessage_OneofSfixed32:
-		n += 2 // tag and wire
-		n += 4
-	case *FieldTestMessage_OneofFixed32:
-		n += 2 // tag and wire
-		n += 4
-	case *FieldTestMessage_OneofFloat:
-		n += 2 // tag and wire
-		n += 4
-	case *FieldTestMessage_OneofSfixed64:
-		n += 2 // tag and wire
-		n += 8
-	case *FieldTestMessage_OneofFixed64:
-		n += 2 // tag and wire
-		n += 8
-	case *FieldTestMessage_OneofDouble:
-		n += 2 // tag and wire
-		n += 8
-	case *FieldTestMessage_OneofString:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(len(x.OneofString)))
-		n += len(x.OneofString)
-	case *FieldTestMessage_OneofBytes:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(len(x.OneofBytes)))
-		n += len(x.OneofBytes)
-	case *FieldTestMessage_Oneof_Message:
-		s := proto.Size(x.Oneof_Message)
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(s))
-		n += s
-	case *FieldTestMessage_Oneofgroup:
-		n += 2 // tag and wire
-		n += proto.Size(x.Oneofgroup)
-		n += 2 // tag and wire
-	case *FieldTestMessage_OneofLargestTag:
-		n += 5 // tag and wire
-		n += proto.SizeVarint(uint64(x.OneofLargestTag))
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	// oneof_two
-	switch x := m.OneofTwo.(type) {
-	case *FieldTestMessage_OneofTwo_1:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(x.OneofTwo_1))
-	case *FieldTestMessage_OneofTwo_2:
-		n += 2 // tag and wire
-		n += proto.SizeVarint(uint64(x.OneofTwo_2))
-	case nil:
-	default:
-		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
-	}
-	return n
-}
-
 type FieldTestMessage_OptionalGroup struct {
 	OptionalGroup        *string  `protobuf:"bytes,19,opt,name=optional_group,json=optionalGroup" json:"optional_group,omitempty"`
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
diff --git a/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go b/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
index 0f8b3ee..7f6f395 100644
--- a/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type Layer1 struct {
 	L2                   *Layer1_Layer2        `protobuf:"bytes,1,opt,name=l2" json:"l2,omitempty"`
diff --git a/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go b/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
index 1cb5191..869707d 100644
--- a/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type Message struct {
 	I32                  *int32   `protobuf:"varint,1,opt,name=i32" json:"i32,omitempty"`
diff --git a/cmd/protoc-gen-go/testdata/proto3/enum.pb.go b/cmd/protoc-gen-go/testdata/proto3/enum.pb.go
index 511e8e0..cce047c 100644
--- a/cmd/protoc-gen-go/testdata/proto3/enum.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto3/enum.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type Enum int32
 
diff --git a/cmd/protoc-gen-go/testdata/proto3/fields.pb.go b/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
index 1e45d9f..62b0d42 100644
--- a/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
@@ -18,7 +18,7 @@
 // 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
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 
 type FieldTestMessage_Enum int32