internal/proto: implement v1 registration with v2 registration

This CL implements v1 registration in terms of v2 registration,
unifying the two global states.

Change-Id: I1c28e5f3392dcfa7cd7b2933f2c0974456a182a9
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/168350
Reviewed-by: Herbie Ong <herbie@google.com>
diff --git a/go.mod b/go.mod
index 22c8753..dbcf032 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,3 @@
 module github.com/golang/protobuf
 
-require github.com/golang/protobuf/v2 v2.0.0-20190312230405-4989810018b7
+require github.com/golang/protobuf/v2 v2.0.0-20190320041633-559d47f1da45
diff --git a/go.sum b/go.sum
index 9dd4c5b..d0211f0 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,5 @@
 github.com/golang/protobuf v1.2.1-0.20190311233832-968e039ade03/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf/v2 v2.0.0-20190312230405-4989810018b7 h1:aQENkYDAn/68ZfghmurTBhR18Q7/XWx1JpMaqFtP1GM=
-github.com/golang/protobuf/v2 v2.0.0-20190312230405-4989810018b7/go.mod h1:euNorOscCho6jibQUfcx8TAp5HZXU5/+1xMsdtkc8lo=
-github.com/google/go-cmp v0.2.1-0.20190228024137-c81281657ad9 h1:GDk30QdVXDf6i734280OeWAO9UCCjXLeWkLLyHQGUkI=
-github.com/google/go-cmp v0.2.1-0.20190228024137-c81281657ad9/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/golang/protobuf/v2 v2.0.0-20190320041633-559d47f1da45 h1:UpSQcE2BQjlwjgUj1o+22OMRLUpeeTZNH1fuZN5lEv4=
+github.com/golang/protobuf/v2 v2.0.0-20190320041633-559d47f1da45/go.mod h1:memx26heJzlbv0kkl0yZyY1iCWPnh53PDfstsy8HCEg=
+github.com/google/go-cmp v0.2.1-0.20190312032427-6f77996f0c42 h1:q3pnF5JFBNRz8sRD+IRj7Y6DMyYGTNqnZ9axTbSfoNI=
+github.com/google/go-cmp v0.2.1-0.20190312032427-6f77996f0c42/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
diff --git a/internal/proto/common.go b/internal/proto/common.go
index f8ec496..d49c17c 100644
--- a/internal/proto/common.go
+++ b/internal/proto/common.go
@@ -14,4 +14,7 @@
 	_ "github.com/golang/protobuf/v2/runtime/protolegacy"
 )
 
-type Message = protoapi.Message
+type (
+	Message       = protoapi.Message
+	ExtensionDesc = protoapi.ExtensionDesc
+)
diff --git a/internal/proto/properties.go b/internal/proto/properties.go
index 3df9e3d..2d0ace6 100644
--- a/internal/proto/properties.go
+++ b/internal/proto/properties.go
@@ -301,7 +301,7 @@
 	if !foundField {
 		// Check with protobuf reflection to make sure this isn't
 		// an empty protobuf message.
-		mt := protoimpl.X.MessageOf(reflect.New(t).Interface()).Type()
+		mt := protoimpl.X.MessageTypeOf(reflect.New(t).Interface())
 		if mt.Fields().Len() > 0 {
 			panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t))
 		}
diff --git a/internal/proto/registry.go b/internal/proto/registry.go
new file mode 100644
index 0000000..d63283b
--- /dev/null
+++ b/internal/proto/registry.go
@@ -0,0 +1,373 @@
+// 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 proto
+
+import (
+	"bytes"
+	"compress/gzip"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"reflect"
+	"runtime"
+	"strings"
+	"sync"
+
+	protoV2 "github.com/golang/protobuf/v2/proto"
+	"github.com/golang/protobuf/v2/reflect/protodesc"
+	"github.com/golang/protobuf/v2/reflect/protoreflect"
+	pref "github.com/golang/protobuf/v2/reflect/protoreflect"
+	"github.com/golang/protobuf/v2/reflect/protoregistry"
+	"github.com/golang/protobuf/v2/runtime/protoimpl"
+	"github.com/golang/protobuf/v2/runtime/protolegacy"
+
+	descriptorpb "github.com/golang/protobuf/v2/types/descriptor"
+)
+
+// filePath is the path to the proto source file.
+type filePath = string // e.g., "google/protobuf/descriptor.proto"
+
+// fileDescGZIP is the compressed contents of the encoded FileDescriptorProto.
+type fileDescGZIP = []byte
+
+var fileCache sync.Map // map[filePath]fileDescGZIP
+
+// RegisterFile is called from generated code and registers the compressed
+// FileDescriptorProto with the file path for a proto source file.
+//
+// Deprecated: Use protoregistry.GlobalFiles.Register instead.
+func RegisterFile(s filePath, d fileDescGZIP) {
+	// Decompress the descriptor.
+	zr, err := gzip.NewReader(bytes.NewReader(d))
+	if err != nil {
+		panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err))
+	}
+	b, err := ioutil.ReadAll(zr)
+	if err != nil {
+		panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err))
+	}
+
+	// Parse the raw descriptor proto.
+	var pb descriptorpb.FileDescriptorProto
+	if err := protoV2.Unmarshal(b, &pb); err != nil {
+		panic(fmt.Sprintf("proto: unmarshal failure: %v", err))
+	}
+
+	// Convert the raw descriptor to a structured file descriptor.
+	fd, err := protodesc.NewFile(&pb, nil)
+	if err != nil {
+		// TODO: Ignore errors due to placeholders.
+		panic(fmt.Sprintf("proto: descriptor parsing failure: %v", err))
+	}
+
+	// Register the descriptor in the v2 registry and cache the result locally.
+	if err := protoregistry.GlobalFiles.Register(fd); err != nil {
+		printWarning(err)
+		return
+	}
+	fileCache.Store(s, b)
+}
+
+// FileDescriptor returns the compressed FileDescriptorProto given the file path
+// for a proto source file. It returns nil if not found.
+//
+// Deprecated: Use protoregistry.GlobalFiles.RangeFilesByPath instead.
+func FileDescriptor(s filePath) (d fileDescGZIP) {
+	if d, ok := fileCache.Load(s); ok {
+		return d.(fileDescGZIP)
+	}
+
+	// Find the descriptor in the v2 registry.
+	var n int
+	protoregistry.GlobalFiles.RangeFilesByPath(s, func(fd protoreflect.FileDescriptor) bool {
+		n++
+
+		// Convert the structured file descriptor to the raw descriptor proto.
+		pb := protodesc.ToFileDescriptorProto(fd)
+		b, err := protoV2.Marshal(pb)
+		if err != nil {
+			panic(fmt.Sprintf("proto: marshal failure: %v", err))
+		}
+		bb := new(bytes.Buffer)
+		zw := gzip.NewWriter(bb)
+		if _, err := zw.Write(b); err != nil {
+			panic(fmt.Sprintf("proto: compression failure: %v", err))
+		}
+		if err := zw.Close(); err != nil {
+			panic(fmt.Sprintf("proto: compression failure: %v", err))
+		}
+		d = bb.Bytes()
+		return true
+	})
+	if n > 1 {
+		return d // best-effort; may be non-deterministic
+	}
+
+	// Locally cache the raw descriptor form for the file.
+	if len(d) > 0 {
+		fileCache.Store(s, d)
+	}
+	return d
+}
+
+// enumName is the name of an enum. For historical reasons, the enum name is
+// neither the full Go name nor the full protobuf name of the enum.
+// The name is the dot-separated combination of just the proto package that the
+// enum is declared within followed by the Go type name of the generated enum.
+type enumName = string // e.g., "my.proto.package.GoMessage_GoEnum"
+
+// enumsByName maps enum values by name to their numeric counterpart.
+type enumsByName = map[string]int32
+
+// enumsByNumber maps enum values by number to their name counterpart.
+type enumsByNumber = map[int32]string
+
+var enumCache sync.Map // map[enumName]enumsByName
+
+// RegisterEnum is called from the generated code and registers the mapping of
+// enum value names to enum numbers for the enum identified by s.
+//
+// Deprecated: Use protoregistry.GlobalTypes.Register instead.
+func RegisterEnum(s enumName, _ enumsByNumber, m enumsByName) {
+	if _, ok := enumCache.Load(s); ok {
+		panic("proto: duplicate enum registered: " + s)
+	}
+	enumCache.Store(s, m)
+
+	// This does not forward registration to the v2 registry since this API
+	// lacks sufficient information to construct a complete v2 enum descriptor.
+}
+
+// EnumValueMap returns the mapping from enum value names to enum numbers for
+// the enum of the given name. It returns nil if not found.
+//
+// Deprecated: Use protoregistry.GlobalTypes.FindEnumByName instead.
+func EnumValueMap(s enumName) (m enumsByName) {
+	v, ok := enumCache.Load(s)
+	if ok {
+		return v.(enumsByName)
+	}
+
+	// Construct the mapping from a v2 enum descriptor.
+	var protoPkg protoreflect.FullName
+	if i := strings.LastIndexByte(s, '.'); i >= 0 {
+		protoPkg = protoreflect.FullName(s[:i])
+	}
+	protoregistry.GlobalFiles.RangeFilesByPackage(protoreflect.FullName(protoPkg), func(fd protoreflect.FileDescriptor) bool {
+		return walkEnums(fd, func(ed protoreflect.EnumDescriptor) bool {
+			if s == hybridEnumName(ed) {
+				m = make(enumsByName)
+				evs := ed.Values()
+				for i := evs.Len() - 1; i >= 0; i-- {
+					ev := evs.Get(i)
+					m[string(ev.Name())] = int32(ev.Number())
+				}
+				return false
+			}
+			return true
+		})
+	})
+
+	if m != nil {
+		enumCache.Store(s, m)
+	}
+	return m
+}
+
+// walkEnums recursively walks all enums declared in d.
+func walkEnums(d interface {
+	Enums() protoreflect.EnumDescriptors
+	Messages() protoreflect.MessageDescriptors
+}, f func(protoreflect.EnumDescriptor) bool) bool {
+	cont := true
+	eds := d.Enums()
+	for i := eds.Len() - 1; cont && i >= 0; i-- {
+		cont = cont && f(eds.Get(i))
+	}
+	mds := d.Messages()
+	for i := mds.Len() - 1; cont && i >= 0; i-- {
+		cont = cont && walkEnums(mds.Get(i), f)
+	}
+	return cont
+}
+
+// hybridEnumName returns the legacy enum identifier.
+func hybridEnumName(ed pref.EnumDescriptor) enumName {
+	var protoPkg string
+	for parent, _ := ed.Parent(); parent != nil; parent, _ = parent.Parent() {
+		if fd, ok := parent.(pref.FileDescriptor); ok {
+			protoPkg = string(fd.Package())
+			break
+		}
+	}
+	if protoPkg == "" {
+		return camelCase(string(ed.FullName()))
+	}
+	return protoPkg + "." + camelCase(strings.TrimPrefix(string(ed.FullName()), protoPkg+"."))
+}
+
+// camelCase is a copy of the v2 protogen.camelCase function.
+func camelCase(s string) string {
+	isASCIILower := func(c byte) bool {
+		return 'a' <= c && c <= 'z'
+	}
+	isASCIIDigit := func(c byte) bool {
+		return '0' <= c && c <= '9'
+	}
+
+	var b []byte
+	for i := 0; i < len(s); i++ {
+		c := s[i]
+		switch {
+		case c == '.' && i+1 < len(s) && isASCIILower(s[i+1]):
+			continue
+		case c == '.':
+			b = append(b, '_')
+		case c == '_' && (i == 0 || s[i-1] == '.'):
+			b = append(b, 'X')
+		case c == '_' && i+1 < len(s) && isASCIILower(s[i+1]):
+			continue
+		case isASCIIDigit(c):
+			b = append(b, c)
+		default:
+			if isASCIILower(c) {
+				c -= 'a' - 'A'
+			}
+			b = append(b, c)
+			for ; i+1 < len(s) && isASCIILower(s[i+1]); i++ {
+				b = append(b, s[i+1])
+			}
+		}
+	}
+	return string(b)
+}
+
+// messageName is the full name of protobuf message.
+type messageName = string
+
+var messageTypeCache sync.Map // map[messageName]reflect.Type
+
+// RegisterType is called from generated code and register the message Go type
+// for a message of the given name.
+//
+// Deprecated: Use protoregistry.GlobalTypes.Register instead.
+func RegisterType(m Message, s messageName) {
+	mt := protoimpl.X.MessageTypeOf(m)
+	if s != messageName(mt.FullName()) {
+		panic(fmt.Sprintf("proto: inconsistent message name: got %v, want %v", s, mt.FullName()))
+	}
+	if err := protoregistry.GlobalTypes.Register(mt); err != nil {
+		printWarning(err)
+		return
+	}
+	messageTypeCache.Store(s, reflect.TypeOf(m))
+}
+
+// RegisterMapType is called from generated code and registers the Go map type
+// for a protobuf message representing a map entry.
+//
+// Deprecated: Do not use.
+func RegisterMapType(m interface{}, s messageName) {
+	t := reflect.TypeOf(m)
+	if t.Kind() != reflect.Map {
+		panic(fmt.Sprintf("invalid map kind: %v", t))
+	}
+	if _, ok := messageTypeCache.Load(s); ok {
+		printWarning(fmt.Errorf("proto: duplicate proto message registered: %s", s))
+		return
+	}
+	messageTypeCache.Store(s, t)
+}
+
+// MessageType returns the message type for a named message.
+// It returns nil if not found.
+//
+// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead.
+func MessageType(s messageName) reflect.Type {
+	if t, ok := messageTypeCache.Load(s); ok {
+		return t.(reflect.Type)
+	}
+
+	// Derive the message type from the v2 registry.
+	var t reflect.Type
+	mt, _ := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(s))
+	if mt != nil {
+		t = mt.GoType()
+	}
+	// TODO: Support retrieving Go map types for map entry messages?
+
+	if t != nil {
+		messageTypeCache.Store(s, t)
+	}
+	return t
+}
+
+// MessageName returns the full protobuf name for the given message type.
+//
+// Deprecated: Use protoreflect.MessageDescriptor.FullName instead.
+func MessageName(m Message) messageName {
+	if m, ok := m.(interface {
+		XXX_MessageName() messageName
+	}); ok {
+		return m.XXX_MessageName()
+	}
+	return messageName(protoimpl.X.MessageTypeOf(m).FullName())
+}
+
+// RegisterExtension is called from the generated code and registers
+// the extension descriptor.
+//
+// Deprecated: Use protoregistry.GlobalTypes.Register instead.
+func RegisterExtension(d *ExtensionDesc) {
+	xt := protolegacy.X.ExtensionTypeFromDesc(d)
+	if err := protoregistry.GlobalTypes.Register(xt); err != nil {
+		panic(err)
+	}
+}
+
+type extensionsByNumber = map[int32]*ExtensionDesc
+
+var extensionCache sync.Map // map[messageName]extensionsByNumber
+
+// RegisteredExtensions returns a map of the registered extensions for the
+// provided protobuf message, indexed by the extension field number.
+//
+// Deprecated: Use protoregistry.GlobalTypes.RangeExtensionsByMessage instead.
+func RegisteredExtensions(m Message) extensionsByNumber {
+	s := MessageName(m)
+	if xs, ok := extensionCache.Load(s); ok {
+		return xs.(extensionsByNumber)
+	}
+
+	var xs extensionsByNumber
+	protoregistry.GlobalTypes.RangeExtensionsByMessage(protoreflect.FullName(s), func(xt protoreflect.ExtensionType) bool {
+		if xs == nil {
+			xs = make(extensionsByNumber)
+		}
+		xs[int32(xt.Number())] = protolegacy.X.ExtensionDescFromType(xt)
+		return true
+	})
+
+	if xs == nil {
+		return nil
+	}
+	if xs, ok := extensionCache.LoadOrStore(s, xs); ok {
+		return xs.(extensionsByNumber)
+	}
+	return xs
+}
+
+// printWarning prints a warning to os.Stderr regarding a registration conflict.
+func printWarning(err error) {
+	// TODO: Provide a link in the warning to a page that explains
+	// what the user should do instead?
+	b := make([]byte, 0, 1<<12)
+	b = append(b, "==================\n"...)
+	b = append(b, "WARNING: "+err.Error()+"\n"...)
+	b = append(b, "A future release of proto will panic on registration conflicts.\n\n"...)
+	b = b[:len(b)+runtime.Stack(b[len(b):cap(b)], false)]
+	b = append(b, "==================\n"...)
+	os.Stderr.Write(b)
+}
diff --git a/jsonpb/jsonpb_test.go b/jsonpb/jsonpb_test.go
index 607a57a..a8000c9 100644
--- a/jsonpb/jsonpb_test.go
+++ b/jsonpb/jsonpb_test.go
@@ -1024,7 +1024,7 @@
 }
 
 const (
-	dynamicMessageName = "google.protobuf.jsonpb.testing.dynamicMessage"
+	dynamicMessageName = "github_com.golang.protobuf.jsonpb.dynamicMessage"
 )
 
 func init() {
diff --git a/proto/discard.go b/proto/discard.go
index fe5a140..7c376c2 100644
--- a/proto/discard.go
+++ b/proto/discard.go
@@ -18,8 +18,6 @@
 	XXX_DiscardUnknown()
 }
 
-var discardUnknownAlt func(Message) // populated by hooks.go
-
 // DiscardUnknown recursively discards all unknown fields from this message
 // and all embedded messages.
 //
@@ -33,7 +31,7 @@
 // discarded from messages that have been accessed via GetExtension.
 func DiscardUnknown(m Message) {
 	if discardUnknownAlt != nil {
-		discardUnknownAlt(m)
+		discardUnknownAlt(m) // populated by hooks_enabled.go
 		return
 	}
 
diff --git a/proto/equal.go b/proto/equal.go
index 88e094e..29ae49b 100644
--- a/proto/equal.go
+++ b/proto/equal.go
@@ -245,7 +245,7 @@
 		// we need to unmarshal them first.
 		var desc *ExtensionDesc
 		mz := reflect.Zero(reflect.PtrTo(base)).Interface().(Message)
-		if m := protoapi.RegisteredExtensions(mz); m != nil {
+		if m := RegisteredExtensions(mz); m != nil {
 			desc = m[int32(extNum)]
 		}
 		if desc == nil {
diff --git a/proto/hooks.go b/proto/hooks.go
deleted file mode 100644
index cd4da7d..0000000
--- a/proto/hooks.go
+++ /dev/null
@@ -1,14 +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.
-
-// +build proto_reimpl
-
-package proto
-
-import "github.com/golang/protobuf/internal/proto"
-
-func init() {
-	setDefaultsAlt = proto.SetDefaults
-	discardUnknownAlt = proto.DiscardUnknown
-}
diff --git a/proto/hooks_disabled.go b/proto/hooks_disabled.go
new file mode 100644
index 0000000..fe9aaa0
--- /dev/null
+++ b/proto/hooks_disabled.go
@@ -0,0 +1,76 @@
+// 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.
+
+// +build !proto_reimpl
+
+package proto
+
+import (
+	"reflect"
+
+	descriptorpb "github.com/golang/protobuf/v2/types/descriptor"
+)
+
+var (
+	// Hooks for lib.go.
+	setDefaultsAlt func(Message)
+
+	// Hooks for discard.go.
+	discardUnknownAlt func(Message)
+
+	// Hooks for registry.go.
+	registerEnumAlt         func(string, map[int32]string, map[string]int32)
+	enumValueMapAlt         func(string) map[string]int32
+	registerTypeAlt         func(Message, string)
+	registerMapTypeAlt      func(interface{}, string)
+	messageNameAlt          func(Message) string
+	messageTypeAlt          func(string) reflect.Type
+	registerFileAlt         func(string, []byte)
+	fileDescriptorAlt       func(string) []byte
+	registerExtensionAlt    func(*ExtensionDesc)
+	registeredExtensionsAlt func(Message) map[int32]*ExtensionDesc
+)
+
+// The v2 descriptor no longer registers with v1.
+// If we're only relying on the v1 registry, we need to manually register the
+// types in descriptor.
+func init() {
+	// TODO: This should be eventually deleted once the v1 repository is fully
+	// switched over to wrap the v2 repository.
+	rawDesc, _ := (*descriptorpb.DescriptorProto)(nil).Descriptor()
+	RegisterFile("google/protobuf/descriptor.proto", rawDesc)
+	RegisterEnum("google.protobuf.FieldDescriptorProto_Type", descriptorpb.FieldDescriptorProto_Type_name, descriptorpb.FieldDescriptorProto_Type_value)
+	RegisterEnum("google.protobuf.FieldDescriptorProto_Label", descriptorpb.FieldDescriptorProto_Label_name, descriptorpb.FieldDescriptorProto_Label_value)
+	RegisterEnum("google.protobuf.FileOptions_OptimizeMode", descriptorpb.FileOptions_OptimizeMode_name, descriptorpb.FileOptions_OptimizeMode_value)
+	RegisterEnum("google.protobuf.FieldOptions_CType", descriptorpb.FieldOptions_CType_name, descriptorpb.FieldOptions_CType_value)
+	RegisterEnum("google.protobuf.FieldOptions_JSType", descriptorpb.FieldOptions_JSType_name, descriptorpb.FieldOptions_JSType_value)
+	RegisterEnum("google.protobuf.MethodOptions_IdempotencyLevel", descriptorpb.MethodOptions_IdempotencyLevel_name, descriptorpb.MethodOptions_IdempotencyLevel_value)
+	RegisterType((*descriptorpb.FileDescriptorSet)(nil), "google.protobuf.FileDescriptorSet")
+	RegisterType((*descriptorpb.FileDescriptorProto)(nil), "google.protobuf.FileDescriptorProto")
+	RegisterType((*descriptorpb.DescriptorProto)(nil), "google.protobuf.DescriptorProto")
+	RegisterType((*descriptorpb.ExtensionRangeOptions)(nil), "google.protobuf.ExtensionRangeOptions")
+	RegisterType((*descriptorpb.FieldDescriptorProto)(nil), "google.protobuf.FieldDescriptorProto")
+	RegisterType((*descriptorpb.OneofDescriptorProto)(nil), "google.protobuf.OneofDescriptorProto")
+	RegisterType((*descriptorpb.EnumDescriptorProto)(nil), "google.protobuf.EnumDescriptorProto")
+	RegisterType((*descriptorpb.EnumValueDescriptorProto)(nil), "google.protobuf.EnumValueDescriptorProto")
+	RegisterType((*descriptorpb.ServiceDescriptorProto)(nil), "google.protobuf.ServiceDescriptorProto")
+	RegisterType((*descriptorpb.MethodDescriptorProto)(nil), "google.protobuf.MethodDescriptorProto")
+	RegisterType((*descriptorpb.FileOptions)(nil), "google.protobuf.FileOptions")
+	RegisterType((*descriptorpb.MessageOptions)(nil), "google.protobuf.MessageOptions")
+	RegisterType((*descriptorpb.FieldOptions)(nil), "google.protobuf.FieldOptions")
+	RegisterType((*descriptorpb.OneofOptions)(nil), "google.protobuf.OneofOptions")
+	RegisterType((*descriptorpb.EnumOptions)(nil), "google.protobuf.EnumOptions")
+	RegisterType((*descriptorpb.EnumValueOptions)(nil), "google.protobuf.EnumValueOptions")
+	RegisterType((*descriptorpb.ServiceOptions)(nil), "google.protobuf.ServiceOptions")
+	RegisterType((*descriptorpb.MethodOptions)(nil), "google.protobuf.MethodOptions")
+	RegisterType((*descriptorpb.UninterpretedOption)(nil), "google.protobuf.UninterpretedOption")
+	RegisterType((*descriptorpb.SourceCodeInfo)(nil), "google.protobuf.SourceCodeInfo")
+	RegisterType((*descriptorpb.GeneratedCodeInfo)(nil), "google.protobuf.GeneratedCodeInfo")
+	RegisterType((*descriptorpb.DescriptorProto_ExtensionRange)(nil), "google.protobuf.DescriptorProto.ExtensionRange")
+	RegisterType((*descriptorpb.DescriptorProto_ReservedRange)(nil), "google.protobuf.DescriptorProto.ReservedRange")
+	RegisterType((*descriptorpb.EnumDescriptorProto_EnumReservedRange)(nil), "google.protobuf.EnumDescriptorProto.EnumReservedRange")
+	RegisterType((*descriptorpb.UninterpretedOption_NamePart)(nil), "google.protobuf.UninterpretedOption.NamePart")
+	RegisterType((*descriptorpb.SourceCodeInfo_Location)(nil), "google.protobuf.SourceCodeInfo.Location")
+	RegisterType((*descriptorpb.GeneratedCodeInfo_Annotation)(nil), "google.protobuf.GeneratedCodeInfo.Annotation")
+}
diff --git a/proto/hooks_enabled.go b/proto/hooks_enabled.go
new file mode 100644
index 0000000..c117ba4
--- /dev/null
+++ b/proto/hooks_enabled.go
@@ -0,0 +1,31 @@
+// 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.
+
+// +build proto_reimpl
+
+package proto
+
+import (
+	"github.com/golang/protobuf/internal/proto"
+)
+
+var (
+	// Hooks for lib.go.
+	setDefaultsAlt = proto.SetDefaults
+
+	// Hooks for discard.go.
+	discardUnknownAlt = proto.DiscardUnknown
+
+	// Hooks for registry.go.
+	registerEnumAlt         = proto.RegisterEnum
+	enumValueMapAlt         = proto.EnumValueMap
+	registerTypeAlt         = proto.RegisterType
+	registerMapTypeAlt      = proto.RegisterMapType
+	messageNameAlt          = proto.MessageName
+	messageTypeAlt          = proto.MessageType
+	registerFileAlt         = proto.RegisterFile
+	fileDescriptorAlt       = proto.FileDescriptor
+	registerExtensionAlt    = proto.RegisterExtension
+	registeredExtensionsAlt = proto.RegisteredExtensions
+)
diff --git a/proto/lib.go b/proto/lib.go
index 8887b7a..1906a2a 100644
--- a/proto/lib.go
+++ b/proto/lib.go
@@ -261,14 +261,12 @@
 	p.index = index
 }
 
-var setDefaultsAlt func(Message) // populated by hooks.go
-
 // SetDefaults sets unset protocol buffer fields to their default values.
 // It only modifies fields that are both unset and have defined defaults.
 // It recursively sets default values in any non-nil sub-messages.
 func SetDefaults(pb Message) {
 	if setDefaultsAlt != nil {
-		setDefaultsAlt(pb)
+		setDefaultsAlt(pb) // populated by hooks_enabled.go
 		return
 	}
 	setDefaults(reflect.ValueOf(pb), true, false)
diff --git a/proto/registry.go b/proto/registry.go
index b2c0265..49732ce 100644
--- a/proto/registry.go
+++ b/proto/registry.go
@@ -1,72 +1,166 @@
-// Copyright 2016 The Go Authors. All rights reserved.
+// 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 proto
 
 import (
+	"fmt"
+	"log"
 	"reflect"
-
-	"github.com/golang/protobuf/protoapi"
+	"strconv"
 )
 
-// TODO: Registration should be written in terms of v2 registries.
+var enumValueMaps = make(map[string]map[string]int32)
 
 // RegisterEnum is called from the generated code to install the enum descriptor
 // maps into the global table to aid parsing text format protocol buffers.
 func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
-	protoapi.RegisterEnum(typeName, unusedNameMap, valueMap)
+	if registerEnumAlt != nil {
+		registerEnumAlt(typeName, unusedNameMap, valueMap) // populated by hooks_enabled.go
+		return
+	}
+	if _, ok := enumValueMaps[typeName]; ok {
+		panic("proto: duplicate enum registered: " + typeName)
+	}
+	enumValueMaps[typeName] = valueMap
 }
 
 // EnumValueMap returns the mapping from names to integers of the
 // enum type enumType, or a nil if not found.
 func EnumValueMap(enumType string) map[string]int32 {
-	return protoapi.EnumValueMap(enumType)
+	if enumValueMapAlt != nil {
+		return enumValueMapAlt(enumType) // populated by hooks_enabled.go
+	}
+	return enumValueMaps[enumType]
 }
 
+// A registry of all linked message types.
+// The string is a fully-qualified proto name ("pkg.Message").
+var (
+	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) {
-	protoapi.RegisterType(x, name)
+	if registerTypeAlt != nil {
+		registerTypeAlt(x, name) // populated by hooks_enabled.go
+		return
+	}
+	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)
+	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) {
-	protoapi.RegisterMapType(x, name)
+	if registerMapTypeAlt != nil {
+		registerMapTypeAlt(x, name) // populated by hooks_enabled.go
+		return
+	}
+	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
+
+	// Avoid registering into revProtoTypes since map types are not unique.
+	// revProtoTypes[t] = name
 }
 
 // MessageName returns the fully-qualified proto name for the given message type.
 func MessageName(x Message) string {
-	return protoapi.MessageName(x)
+	if messageNameAlt != nil {
+		return messageNameAlt(x) // populated by hooks_enabled.go
+	}
+	type xname interface {
+		XXX_MessageName() string
+	}
+	if m, ok := x.(xname); ok {
+		return m.XXX_MessageName()
+	}
+	return revProtoTypes[reflect.TypeOf(x)]
 }
 
 // MessageType returns the message type (pointer to struct) for a named message.
 // The type is not guaranteed to implement proto.Message if the name refers to a
 // map entry.
 func MessageType(name string) reflect.Type {
-	return protoapi.MessageType(name)
+	if messageTypeAlt != nil {
+		return messageTypeAlt(name) // populated by hooks_enabled.go
+	}
+	if t, ok := protoTypedNils[name]; ok {
+		return reflect.TypeOf(t)
+	}
+	return protoMapTypes[name]
 }
 
+// A registry of all linked proto files.
+var protoFiles = make(map[string][]byte) // file name => fileDescriptor
+
 // RegisterFile is called from generated code and maps from the
 // full file name of a .proto file to its compressed FileDescriptorProto.
 func RegisterFile(filename string, fileDescriptor []byte) {
-	protoapi.RegisterFile(filename, fileDescriptor)
+	if registerFileAlt != nil {
+		registerFileAlt(filename, fileDescriptor) // populated by hooks_enabled.go
+		return
+	}
+	protoFiles[filename] = fileDescriptor
 }
 
 // FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
 func FileDescriptor(filename string) []byte {
-	return protoapi.FileDescriptor(filename)
+	if fileDescriptorAlt != nil {
+		return fileDescriptorAlt(filename) // populated by hooks_enabled.go
+	}
+	return protoFiles[filename]
 }
 
+var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
+
 // RegisterExtension is called from the generated code.
 func RegisterExtension(desc *ExtensionDesc) {
-	protoapi.RegisterExtension(desc)
+	if registerExtensionAlt != nil {
+		registerExtensionAlt(desc) // populated by hooks_enabled.go
+		return
+	}
+	st := reflect.TypeOf(desc.ExtendedType).Elem()
+	m := extensionMaps[st]
+	if m == nil {
+		m = make(map[int32]*ExtensionDesc)
+		extensionMaps[st] = m
+	}
+	if _, ok := m[desc.Field]; ok {
+		panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
+	}
+	m[desc.Field] = desc
 }
 
 // RegisteredExtensions returns a map of the registered extensions of a
 // protocol buffer struct, indexed by the extension number.
 // The argument pb should be a nil pointer to the struct type.
 func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
-	return protoapi.RegisteredExtensions(pb)
+	if registeredExtensionsAlt != nil {
+		return registeredExtensionsAlt(pb) // populated by hooks_enabled.go
+	}
+	return extensionMaps[reflect.TypeOf(pb).Elem()]
 }
diff --git a/proto/registry_test.go b/proto/registry_test.go
new file mode 100644
index 0000000..ca3f971
--- /dev/null
+++ b/proto/registry_test.go
@@ -0,0 +1,28 @@
+// 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 proto_test
+
+import (
+	"reflect"
+	"testing"
+
+	"github.com/golang/protobuf/proto"
+
+	descriptorpb "github.com/golang/protobuf/v2/types/descriptor"
+)
+
+func TestRegistry(t *testing.T) {
+	if got := proto.FileDescriptor("google/protobuf/descriptor.proto"); len(got) == 0 {
+		t.Errorf(`FileDescriptor("google/protobuf/descriptor.proto") = empty, want non-empty`)
+	}
+	if got := proto.EnumValueMap("google.protobuf.FieldDescriptorProto_Label"); len(got) == 0 {
+		t.Errorf(`EnumValueMap("google.protobuf.FieldDescriptorProto_Label") = empty, want non-empty`)
+	}
+	wantType := reflect.TypeOf(new(descriptorpb.EnumDescriptorProto_EnumReservedRange))
+	gotType := proto.MessageType("google.protobuf.EnumDescriptorProto.EnumReservedRange")
+	if gotType != wantType {
+		t.Errorf(`MessageType("google.protobuf.EnumDescriptorProto.EnumReservedRange") = %v, want %v`, gotType, wantType)
+	}
+}
diff --git a/proto/table_marshal.go b/proto/table_marshal.go
index 008d07d..aefee64 100644
--- a/proto/table_marshal.go
+++ b/proto/table_marshal.go
@@ -259,7 +259,7 @@
 			if err == errInvalidUTF8 {
 				if errLater == nil {
 					mz := reflect.Zero(reflect.PtrTo(u.typ)).Interface().(Message)
-					fullName := protoapi.MessageName(mz) + "." + f.name
+					fullName := MessageName(mz) + "." + f.name
 					errLater = &invalidUTF8Error{fullName}
 				}
 				continue
diff --git a/proto/table_unmarshal.go b/proto/table_unmarshal.go
index aed2af8..104f375 100644
--- a/proto/table_unmarshal.go
+++ b/proto/table_unmarshal.go
@@ -164,7 +164,7 @@
 				if err == errInvalidUTF8 {
 					if errLater == nil {
 						mz := reflect.Zero(reflect.PtrTo(u.typ)).Interface().(Message)
-						fullName := protoapi.MessageName(mz) + "." + f.name
+						fullName := MessageName(mz) + "." + f.name
 						errLater = &invalidUTF8Error{fullName}
 					}
 					continue
diff --git a/proto/text.go b/proto/text.go
index 439bb76..ad0652b 100644
--- a/proto/text.go
+++ b/proto/text.go
@@ -653,7 +653,7 @@
 // writeExtensions writes all the extensions in pv.
 // pv is assumed to be a pointer to a protocol message struct that is extendable.
 func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {
-	emap := protoapi.RegisteredExtensions(pv.Interface().(Message))
+	emap := RegisteredExtensions(pv.Interface().(Message))
 	ep, _ := extendable(pv.Interface())
 
 	// Order the extensions by ID.
diff --git a/proto/text_parser.go b/proto/text_parser.go
index 543176e..96a7833 100644
--- a/proto/text_parser.go
+++ b/proto/text_parser.go
@@ -16,8 +16,6 @@
 	"strings"
 	"sync"
 	"unicode/utf8"
-
-	"github.com/golang/protobuf/protoapi"
 )
 
 // Error string emitted when deserializing Any and fields are already set
@@ -823,7 +821,7 @@
 		if len(props.Enum) == 0 {
 			break
 		}
-		m := protoapi.EnumValueMap(props.Enum)
+		m := EnumValueMap(props.Enum)
 		if m == nil {
 			break
 		}
diff --git a/protoapi/registry.go b/protoapi/registry.go
deleted file mode 100644
index 0383d4f..0000000
--- a/protoapi/registry.go
+++ /dev/null
@@ -1,132 +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 protoapi
-
-import (
-	"fmt"
-	"log"
-	"reflect"
-	"strconv"
-)
-
-// TODO: This entire file should not exist and will eventually be deleted.
-// This is added for bootstrapping purposes so that a descriptor proto can be
-// generated that supports v2 reflection, but still registers into the
-// v1 registries for the time being.
-
-var enumValueMaps = make(map[string]map[string]int32)
-
-// RegisterEnum is called from the generated code to install the enum descriptor
-// maps into the global table to aid parsing text format protocol buffers.
-func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
-	if _, ok := enumValueMaps[typeName]; ok {
-		panic("proto: duplicate enum registered: " + typeName)
-	}
-	enumValueMaps[typeName] = valueMap
-}
-
-// EnumValueMap returns the mapping from names to integers of the
-// enum type enumType, or a nil if not found.
-func EnumValueMap(enumType string) map[string]int32 {
-	return enumValueMaps[enumType]
-}
-
-// A registry of all linked message types.
-// The string is a fully-qualified proto name ("pkg.Message").
-var (
-	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 := protoTypedNils[name]; ok {
-		// TODO: Some day, make this a panic.
-		log.Printf("proto: duplicate proto type registered: %s", name)
-		return
-	}
-	t := reflect.TypeOf(x)
-	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
-}
-
-// MessageName returns the fully-qualified proto name for the given message type.
-func MessageName(x Message) string {
-	type xname interface {
-		XXX_MessageName() string
-	}
-	if m, ok := x.(xname); ok {
-		return m.XXX_MessageName()
-	}
-	return revProtoTypes[reflect.TypeOf(x)]
-}
-
-// MessageType returns the message type (pointer to struct) for a named message.
-// 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 protoFiles = make(map[string][]byte) // file name => fileDescriptor
-
-// RegisterFile is called from generated code and maps from the
-// full file name of a .proto file to its compressed FileDescriptorProto.
-func RegisterFile(filename string, fileDescriptor []byte) {
-	protoFiles[filename] = fileDescriptor
-}
-
-// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
-func FileDescriptor(filename string) []byte { return protoFiles[filename] }
-
-var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
-
-// RegisterExtension is called from the generated code.
-func RegisterExtension(desc *ExtensionDesc) {
-	st := reflect.TypeOf(desc.ExtendedType).Elem()
-	m := extensionMaps[st]
-	if m == nil {
-		m = make(map[int32]*ExtensionDesc)
-		extensionMaps[st] = m
-	}
-	if _, ok := m[desc.Field]; ok {
-		panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
-	}
-	m[desc.Field] = desc
-}
-
-// RegisteredExtensions returns a map of the registered extensions of a
-// protocol buffer struct, indexed by the extension number.
-// The argument pb should be a nil pointer to the struct type.
-func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
-	return extensionMaps[reflect.TypeOf(pb).Elem()]
-}
diff --git a/protoc-gen-go/descriptor/descriptor.pb.go b/protoc-gen-go/descriptor/descriptor.pb.go
index a27d857..6fc98ed 100644
--- a/protoc-gen-go/descriptor/descriptor.pb.go
+++ b/protoc-gen-go/descriptor/descriptor.pb.go
@@ -5,18 +5,11 @@
 
 import (
 	proto "github.com/golang/protobuf/proto"
-	protoapi "github.com/golang/protobuf/protoapi"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	descriptor "github.com/golang/protobuf/v2/types/descriptor"
 )
 
-// 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.ProtoPackageIsVersion3 // please upgrade the proto package
-
 // Symbols defined in public import of google/protobuf/descriptor.proto
 
 type FieldDescriptorProto_Type = descriptor.FieldDescriptorProto_Type
@@ -156,10 +149,6 @@
 type SourceCodeInfo_Location = descriptor.SourceCodeInfo_Location
 type GeneratedCodeInfo_Annotation = descriptor.GeneratedCodeInfo_Annotation
 
-func init() {
-	proto.RegisterFile("github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto", xxx_File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawdesc_gzipped)
-}
-
 var xxx_File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawdesc = []byte{
 	// 180 bytes of the wire-encoded FileDescriptorProto
 	0x0a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
@@ -176,7 +165,7 @@
 	0x6f, 0x74, 0x6f, 0x32,
 }
 
-var xxx_File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawdesc_gzipped = protoapi.CompressGZIP(xxx_File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawdesc)
+var xxx_File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawdesc_gzipped = protoimpl.X.CompressGZIP(xxx_File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawdesc)
 
 const _ = protoimpl.EnforceVersion(protoimpl.Version - 0)
 
@@ -195,6 +184,7 @@
 		GoTypes:           xxx_File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes,
 		DependencyIndexes: xxx_File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs,
 	}.Init()
+	proto.RegisterFile("github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto", xxx_File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawdesc_gzipped)
 	xxx_File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes = nil
 	xxx_File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs = nil
 }
diff --git a/protoc-gen-go/plugin/plugin.pb.go b/protoc-gen-go/plugin/plugin.pb.go
index 6314cb7..7d13e68 100644
--- a/protoc-gen-go/plugin/plugin.pb.go
+++ b/protoc-gen-go/plugin/plugin.pb.go
@@ -5,18 +5,11 @@
 
 import (
 	proto "github.com/golang/protobuf/proto"
-	protoapi "github.com/golang/protobuf/protoapi"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	plugin "github.com/golang/protobuf/v2/types/plugin"
 )
 
-// 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.ProtoPackageIsVersion3 // please upgrade the proto package
-
 // Symbols defined in public import of google/protobuf/compiler/plugin.proto
 
 type Version = plugin.Version
@@ -24,10 +17,6 @@
 type CodeGeneratorResponse = plugin.CodeGeneratorResponse
 type CodeGeneratorResponse_File = plugin.CodeGeneratorResponse_File
 
-func init() {
-	proto.RegisterFile("github.com/golang/protobuf/protoc-gen-go/plugin/plugin.proto", xxx_File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_rawdesc_gzipped)
-}
-
 var xxx_File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_rawdesc = []byte{
 	// 172 bytes of the wire-encoded FileDescriptorProto
 	0x0a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
@@ -43,7 +32,7 @@
 	0x67, 0x6f, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32,
 }
 
-var xxx_File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_rawdesc_gzipped = protoapi.CompressGZIP(xxx_File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_rawdesc)
+var xxx_File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_rawdesc_gzipped = protoimpl.X.CompressGZIP(xxx_File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_rawdesc)
 
 const _ = protoimpl.EnforceVersion(protoimpl.Version - 0)
 
@@ -62,6 +51,7 @@
 		GoTypes:           xxx_File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_goTypes,
 		DependencyIndexes: xxx_File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_depIdxs,
 	}.Init()
+	proto.RegisterFile("github.com/golang/protobuf/protoc-gen-go/plugin/plugin.proto", xxx_File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_rawdesc_gzipped)
 	xxx_File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_goTypes = nil
 	xxx_File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_depIdxs = nil
 }
diff --git a/ptypes/any/any.pb.go b/ptypes/any/any.pb.go
index 42078b5..1857c74 100644
--- a/ptypes/any/any.pb.go
+++ b/ptypes/any/any.pb.go
@@ -5,26 +5,15 @@
 
 import (
 	proto "github.com/golang/protobuf/proto"
-	protoapi "github.com/golang/protobuf/protoapi"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	known "github.com/golang/protobuf/v2/types/known"
 )
 
-// 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.ProtoPackageIsVersion3 // please upgrade the proto package
-
 // Symbols defined in public import of google/protobuf/any.proto
 
 type Any = known.Any
 
-func init() {
-	proto.RegisterFile("github.com/golang/protobuf/ptypes/any/any.proto", xxx_File_github_com_golang_protobuf_ptypes_any_any_proto_rawdesc_gzipped)
-}
-
 var xxx_File_github_com_golang_protobuf_ptypes_any_any_proto_rawdesc = []byte{
 	// 131 bytes of the wire-encoded FileDescriptorProto
 	0x0a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
@@ -38,7 +27,7 @@
 	0x74, 0x6f, 0x33,
 }
 
-var xxx_File_github_com_golang_protobuf_ptypes_any_any_proto_rawdesc_gzipped = protoapi.CompressGZIP(xxx_File_github_com_golang_protobuf_ptypes_any_any_proto_rawdesc)
+var xxx_File_github_com_golang_protobuf_ptypes_any_any_proto_rawdesc_gzipped = protoimpl.X.CompressGZIP(xxx_File_github_com_golang_protobuf_ptypes_any_any_proto_rawdesc)
 
 const _ = protoimpl.EnforceVersion(protoimpl.Version - 0)
 
@@ -57,6 +46,7 @@
 		GoTypes:           xxx_File_github_com_golang_protobuf_ptypes_any_any_proto_goTypes,
 		DependencyIndexes: xxx_File_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs,
 	}.Init()
+	proto.RegisterFile("github.com/golang/protobuf/ptypes/any/any.proto", xxx_File_github_com_golang_protobuf_ptypes_any_any_proto_rawdesc_gzipped)
 	xxx_File_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = nil
 	xxx_File_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = nil
 }
diff --git a/ptypes/duration/duration.pb.go b/ptypes/duration/duration.pb.go
index d667a5e..af0e70b 100644
--- a/ptypes/duration/duration.pb.go
+++ b/ptypes/duration/duration.pb.go
@@ -5,26 +5,15 @@
 
 import (
 	proto "github.com/golang/protobuf/proto"
-	protoapi "github.com/golang/protobuf/protoapi"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	known "github.com/golang/protobuf/v2/types/known"
 )
 
-// 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.ProtoPackageIsVersion3 // please upgrade the proto package
-
 // Symbols defined in public import of google/protobuf/duration.proto
 
 type Duration = known.Duration
 
-func init() {
-	proto.RegisterFile("github.com/golang/protobuf/ptypes/duration/duration.proto", xxx_File_github_com_golang_protobuf_ptypes_duration_duration_proto_rawdesc_gzipped)
-}
-
 var xxx_File_github_com_golang_protobuf_ptypes_duration_duration_proto_rawdesc = []byte{
 	// 156 bytes of the wire-encoded FileDescriptorProto
 	0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
@@ -39,7 +28,7 @@
 	0x6f, 0x6e, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
-var xxx_File_github_com_golang_protobuf_ptypes_duration_duration_proto_rawdesc_gzipped = protoapi.CompressGZIP(xxx_File_github_com_golang_protobuf_ptypes_duration_duration_proto_rawdesc)
+var xxx_File_github_com_golang_protobuf_ptypes_duration_duration_proto_rawdesc_gzipped = protoimpl.X.CompressGZIP(xxx_File_github_com_golang_protobuf_ptypes_duration_duration_proto_rawdesc)
 
 const _ = protoimpl.EnforceVersion(protoimpl.Version - 0)
 
@@ -58,6 +47,7 @@
 		GoTypes:           xxx_File_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes,
 		DependencyIndexes: xxx_File_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs,
 	}.Init()
+	proto.RegisterFile("github.com/golang/protobuf/ptypes/duration/duration.proto", xxx_File_github_com_golang_protobuf_ptypes_duration_duration_proto_rawdesc_gzipped)
 	xxx_File_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = nil
 	xxx_File_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = nil
 }
diff --git a/ptypes/empty/empty.pb.go b/ptypes/empty/empty.pb.go
index c94aa08..726c360 100644
--- a/ptypes/empty/empty.pb.go
+++ b/ptypes/empty/empty.pb.go
@@ -5,26 +5,15 @@
 
 import (
 	proto "github.com/golang/protobuf/proto"
-	protoapi "github.com/golang/protobuf/protoapi"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	known "github.com/golang/protobuf/v2/types/known"
 )
 
-// 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.ProtoPackageIsVersion3 // please upgrade the proto package
-
 // Symbols defined in public import of google/protobuf/empty.proto
 
 type Empty = known.Empty
 
-func init() {
-	proto.RegisterFile("github.com/golang/protobuf/ptypes/empty/empty.proto", xxx_File_github_com_golang_protobuf_ptypes_empty_empty_proto_rawdesc_gzipped)
-}
-
 var xxx_File_github_com_golang_protobuf_ptypes_empty_empty_proto_rawdesc = []byte{
 	// 141 bytes of the wire-encoded FileDescriptorProto
 	0x0a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
@@ -38,7 +27,7 @@
 	0x70, 0x74, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
-var xxx_File_github_com_golang_protobuf_ptypes_empty_empty_proto_rawdesc_gzipped = protoapi.CompressGZIP(xxx_File_github_com_golang_protobuf_ptypes_empty_empty_proto_rawdesc)
+var xxx_File_github_com_golang_protobuf_ptypes_empty_empty_proto_rawdesc_gzipped = protoimpl.X.CompressGZIP(xxx_File_github_com_golang_protobuf_ptypes_empty_empty_proto_rawdesc)
 
 const _ = protoimpl.EnforceVersion(protoimpl.Version - 0)
 
@@ -57,6 +46,7 @@
 		GoTypes:           xxx_File_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes,
 		DependencyIndexes: xxx_File_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs,
 	}.Init()
+	proto.RegisterFile("github.com/golang/protobuf/ptypes/empty/empty.proto", xxx_File_github_com_golang_protobuf_ptypes_empty_empty_proto_rawdesc_gzipped)
 	xxx_File_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = nil
 	xxx_File_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = nil
 }
diff --git a/ptypes/struct/struct.pb.go b/ptypes/struct/struct.pb.go
index 0d71b8d..543a925 100644
--- a/ptypes/struct/struct.pb.go
+++ b/ptypes/struct/struct.pb.go
@@ -5,18 +5,11 @@
 
 import (
 	proto "github.com/golang/protobuf/proto"
-	protoapi "github.com/golang/protobuf/protoapi"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	known "github.com/golang/protobuf/v2/types/known"
 )
 
-// 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.ProtoPackageIsVersion3 // please upgrade the proto package
-
 // Symbols defined in public import of google/protobuf/struct.proto
 
 type NullValue = known.NullValue
@@ -36,10 +29,6 @@
 type Value_ListValue = known.Value_ListValue
 type ListValue = known.ListValue
 
-func init() {
-	proto.RegisterFile("github.com/golang/protobuf/ptypes/struct/struct.proto", xxx_File_github_com_golang_protobuf_ptypes_struct_struct_proto_rawdesc_gzipped)
-}
-
 var xxx_File_github_com_golang_protobuf_ptypes_struct_struct_proto_rawdesc = []byte{
 	// 148 bytes of the wire-encoded FileDescriptorProto
 	0x0a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
@@ -54,7 +43,7 @@
 	0x6f, 0x74, 0x6f, 0x33,
 }
 
-var xxx_File_github_com_golang_protobuf_ptypes_struct_struct_proto_rawdesc_gzipped = protoapi.CompressGZIP(xxx_File_github_com_golang_protobuf_ptypes_struct_struct_proto_rawdesc)
+var xxx_File_github_com_golang_protobuf_ptypes_struct_struct_proto_rawdesc_gzipped = protoimpl.X.CompressGZIP(xxx_File_github_com_golang_protobuf_ptypes_struct_struct_proto_rawdesc)
 
 const _ = protoimpl.EnforceVersion(protoimpl.Version - 0)
 
@@ -73,6 +62,7 @@
 		GoTypes:           xxx_File_github_com_golang_protobuf_ptypes_struct_struct_proto_goTypes,
 		DependencyIndexes: xxx_File_github_com_golang_protobuf_ptypes_struct_struct_proto_depIdxs,
 	}.Init()
+	proto.RegisterFile("github.com/golang/protobuf/ptypes/struct/struct.proto", xxx_File_github_com_golang_protobuf_ptypes_struct_struct_proto_rawdesc_gzipped)
 	xxx_File_github_com_golang_protobuf_ptypes_struct_struct_proto_goTypes = nil
 	xxx_File_github_com_golang_protobuf_ptypes_struct_struct_proto_depIdxs = nil
 }
diff --git a/ptypes/timestamp/timestamp.pb.go b/ptypes/timestamp/timestamp.pb.go
index c4246dc..c993c58 100644
--- a/ptypes/timestamp/timestamp.pb.go
+++ b/ptypes/timestamp/timestamp.pb.go
@@ -5,26 +5,15 @@
 
 import (
 	proto "github.com/golang/protobuf/proto"
-	protoapi "github.com/golang/protobuf/protoapi"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	known "github.com/golang/protobuf/v2/types/known"
 )
 
-// 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.ProtoPackageIsVersion3 // please upgrade the proto package
-
 // Symbols defined in public import of google/protobuf/timestamp.proto
 
 type Timestamp = known.Timestamp
 
-func init() {
-	proto.RegisterFile("github.com/golang/protobuf/ptypes/timestamp/timestamp.proto", xxx_File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawdesc_gzipped)
-}
-
 var xxx_File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawdesc = []byte{
 	// 161 bytes of the wire-encoded FileDescriptorProto
 	0x0a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
@@ -40,7 +29,7 @@
 	0x33,
 }
 
-var xxx_File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawdesc_gzipped = protoapi.CompressGZIP(xxx_File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawdesc)
+var xxx_File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawdesc_gzipped = protoimpl.X.CompressGZIP(xxx_File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawdesc)
 
 const _ = protoimpl.EnforceVersion(protoimpl.Version - 0)
 
@@ -59,6 +48,7 @@
 		GoTypes:           xxx_File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes,
 		DependencyIndexes: xxx_File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs,
 	}.Init()
+	proto.RegisterFile("github.com/golang/protobuf/ptypes/timestamp/timestamp.proto", xxx_File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawdesc_gzipped)
 	xxx_File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = nil
 	xxx_File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = nil
 }
diff --git a/ptypes/wrappers/wrappers.pb.go b/ptypes/wrappers/wrappers.pb.go
index d3499ac..7e47bc6 100644
--- a/ptypes/wrappers/wrappers.pb.go
+++ b/ptypes/wrappers/wrappers.pb.go
@@ -5,18 +5,11 @@
 
 import (
 	proto "github.com/golang/protobuf/proto"
-	protoapi "github.com/golang/protobuf/protoapi"
 	protoreflect "github.com/golang/protobuf/v2/reflect/protoreflect"
 	protoimpl "github.com/golang/protobuf/v2/runtime/protoimpl"
 	known "github.com/golang/protobuf/v2/types/known"
 )
 
-// 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.ProtoPackageIsVersion3 // please upgrade the proto package
-
 // Symbols defined in public import of google/protobuf/wrappers.proto
 
 type DoubleValue = known.DoubleValue
@@ -29,10 +22,6 @@
 type StringValue = known.StringValue
 type BytesValue = known.BytesValue
 
-func init() {
-	proto.RegisterFile("github.com/golang/protobuf/ptypes/wrappers/wrappers.proto", xxx_File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawdesc_gzipped)
-}
-
 var xxx_File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawdesc = []byte{
 	// 156 bytes of the wire-encoded FileDescriptorProto
 	0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,
@@ -47,7 +36,7 @@
 	0x72, 0x73, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
-var xxx_File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawdesc_gzipped = protoapi.CompressGZIP(xxx_File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawdesc)
+var xxx_File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawdesc_gzipped = protoimpl.X.CompressGZIP(xxx_File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawdesc)
 
 const _ = protoimpl.EnforceVersion(protoimpl.Version - 0)
 
@@ -66,6 +55,7 @@
 		GoTypes:           xxx_File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes,
 		DependencyIndexes: xxx_File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs,
 	}.Init()
+	proto.RegisterFile("github.com/golang/protobuf/ptypes/wrappers/wrappers.proto", xxx_File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawdesc_gzipped)
 	xxx_File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes = nil
 	xxx_File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs = nil
 }