cmd/protoc-gen-go: remove generation of XXX_OneofWrappers

Associate the oneof wrapper types with a message by conveying that
information to the associated MessageInfo.

Change-Id: Iabfca593850e1d6a89498a37eacbf22dbb73bd20
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/185239
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 9f77d59..3cd0c38 100644
--- a/cmd/protoc-gen-go/internal_gengo/main.go
+++ b/cmd/protoc-gen-go/internal_gengo/main.go
@@ -35,6 +35,10 @@
 	// GZIP'd contents of the raw file descriptor and the path from the root
 	// to the given enum or message descriptor.
 	generateRawDescMethods = true
+
+	// generateOneofWrapperMethods specifies whether to generate
+	// XXX_OneofWrappers methods on messages with oneofs.
+	generateOneofWrapperMethods = false
 )
 
 const (
@@ -523,15 +527,10 @@
 		g.P()
 	}
 
-	// XXX_OneofWrappers method.
+	// Oneof wrapper types.
 	if len(message.Oneofs) > 0 {
 		genOneofWrappers(gen, g, f, message)
 	}
-
-	// Oneof wrapper types.
-	for _, oneof := range message.Oneofs {
-		genOneofTypes(gen, g, f, message, oneof)
-	}
 }
 
 // fieldGoType returns the Go type used for a field.
@@ -771,19 +770,25 @@
 	g.P()
 }
 
-// genOneofWrappers generates the XXX_OneofWrappers method for a message.
+// genOneofWrappers generates the oneof wrapper types and associates the types
+// with the parent message type.
 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),")
-		}
+	idx := f.allMessagesByPtr[message]
+	typesVar := messageTypesVarName(f)
+
+	// Associate the wrapper types through a XXX_OneofWrappers method.
+	if generateOneofWrapperMethods {
+		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 ", typesVar, "[", idx, "].OneofWrappers")
+		g.P("}")
+		g.P()
 	}
-	g.P("}")
-	g.P("}")
-	g.P()
+
+	// Generate the oneof wrapper types.
+	for _, oneof := range message.Oneofs {
+		genOneofTypes(gen, g, f, message, oneof)
+	}
 }
 
 // genOneofTypes generates the interface type used for a oneof field,