gRPC migration

Change-Id: Ib390f6dde0d5a8d6db12ccd7da41135570ad1354
diff --git a/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go b/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go
index 43f16c6..59f024c 100644
--- a/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go
+++ b/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go
@@ -17,24 +17,49 @@
 
 import (
 	"fmt"
-	"log"
+	"os"
 	"strings"
 	"sync"
 
+	"google.golang.org/protobuf/internal/encoding/messageset"
 	"google.golang.org/protobuf/internal/errors"
+	"google.golang.org/protobuf/internal/flags"
 	"google.golang.org/protobuf/reflect/protoreflect"
 )
 
+// conflictPolicy configures the policy for handling registration conflicts.
+//
+// It can be over-written at compile time with a linker-initialized variable:
+//	go build -ldflags "-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn"
+//
+// It can be over-written at program execution with an environment variable:
+//	GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn ./main
+//
+// Neither of the above are covered by the compatibility promise and
+// may be removed in a future release of this module.
+var conflictPolicy = "panic" // "panic" | "warn" | "ignore"
+
 // ignoreConflict reports whether to ignore a registration conflict
 // given the descriptor being registered and the error.
 // It is a variable so that the behavior is easily overridden in another file.
 var ignoreConflict = func(d protoreflect.Descriptor, err error) bool {
-	log.Printf(""+
-		"WARNING: %v\n"+
-		"A future release will panic on registration conflicts. See:\n"+
-		"https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict\n"+
-		"\n", err)
-	return true
+	const env = "GOLANG_PROTOBUF_REGISTRATION_CONFLICT"
+	const faq = "https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict"
+	policy := conflictPolicy
+	if v := os.Getenv(env); v != "" {
+		policy = v
+	}
+	switch policy {
+	case "panic":
+		panic(fmt.Sprintf("%v\nSee %v\n", err, faq))
+	case "warn":
+		fmt.Fprintf(os.Stderr, "WARNING: %v\nSee %v\n\n", err, faq)
+		return true
+	case "ignore":
+		return true
+	default:
+		panic("invalid " + env + " value: " + os.Getenv(env))
+	}
 }
 
 var globalMutex sync.RWMutex
@@ -69,7 +94,8 @@
 	// Note that enum values are in the top-level since that are in the same
 	// scope as the parent enum.
 	descsByName map[protoreflect.FullName]interface{}
-	filesByPath map[string]protoreflect.FileDescriptor
+	filesByPath map[string][]protoreflect.FileDescriptor
+	numFiles    int
 }
 
 type packageDescriptor struct {
@@ -92,16 +118,16 @@
 		r.descsByName = map[protoreflect.FullName]interface{}{
 			"": &packageDescriptor{},
 		}
-		r.filesByPath = make(map[string]protoreflect.FileDescriptor)
+		r.filesByPath = make(map[string][]protoreflect.FileDescriptor)
 	}
 	path := file.Path()
-	if prev := r.filesByPath[path]; prev != nil {
+	if prev := r.filesByPath[path]; len(prev) > 0 {
+		r.checkGenProtoConflict(path)
 		err := errors.New("file %q is already registered", file.Path())
-		err = amendErrorWithCaller(err, prev, file)
-		if r == GlobalFiles && ignoreConflict(file, err) {
-			err = nil
+		err = amendErrorWithCaller(err, prev[0], file)
+		if !(r == GlobalFiles && ignoreConflict(file, err)) {
+			return err
 		}
-		return err
 	}
 
 	for name := file.Package(); name != ""; name = name.Parent() {
@@ -142,10 +168,52 @@
 	rangeTopLevelDescriptors(file, func(d protoreflect.Descriptor) {
 		r.descsByName[d.FullName()] = d
 	})
-	r.filesByPath[path] = file
+	r.filesByPath[path] = append(r.filesByPath[path], file)
+	r.numFiles++
 	return nil
 }
 
+// Several well-known types were hosted in the google.golang.org/genproto module
+// but were later moved to this module. To avoid a weak dependency on the
+// genproto module (and its relatively large set of transitive dependencies),
+// we rely on a registration conflict to determine whether the genproto version
+// is too old (i.e., does not contain aliases to the new type declarations).
+func (r *Files) checkGenProtoConflict(path string) {
+	if r != GlobalFiles {
+		return
+	}
+	var prevPath string
+	const prevModule = "google.golang.org/genproto"
+	const prevVersion = "cb27e3aa (May 26th, 2020)"
+	switch path {
+	case "google/protobuf/field_mask.proto":
+		prevPath = prevModule + "/protobuf/field_mask"
+	case "google/protobuf/api.proto":
+		prevPath = prevModule + "/protobuf/api"
+	case "google/protobuf/type.proto":
+		prevPath = prevModule + "/protobuf/ptype"
+	case "google/protobuf/source_context.proto":
+		prevPath = prevModule + "/protobuf/source_context"
+	default:
+		return
+	}
+	pkgName := strings.TrimSuffix(strings.TrimPrefix(path, "google/protobuf/"), ".proto")
+	pkgName = strings.Replace(pkgName, "_", "", -1) + "pb" // e.g., "field_mask" => "fieldmaskpb"
+	currPath := "google.golang.org/protobuf/types/known/" + pkgName
+	panic(fmt.Sprintf(""+
+		"duplicate registration of %q\n"+
+		"\n"+
+		"The generated definition for this file has moved:\n"+
+		"\tfrom: %q\n"+
+		"\tto:   %q\n"+
+		"A dependency on the %q module must\n"+
+		"be at version %v or higher.\n"+
+		"\n"+
+		"Upgrade the dependency by running:\n"+
+		"\tgo get -u %v\n",
+		path, prevPath, currPath, prevModule, prevVersion, prevPath))
+}
+
 // FindDescriptorByName looks up a descriptor by the full name.
 //
 // This returns (nil, NotFound) if not found.
@@ -241,6 +309,7 @@
 // FindFileByPath looks up a file by the path.
 //
 // This returns (nil, NotFound) if not found.
+// This returns an error if multiple files have the same path.
 func (r *Files) FindFileByPath(path string) (protoreflect.FileDescriptor, error) {
 	if r == nil {
 		return nil, NotFound
@@ -249,13 +318,19 @@
 		globalMutex.RLock()
 		defer globalMutex.RUnlock()
 	}
-	if fd, ok := r.filesByPath[path]; ok {
-		return fd, nil
+	fds := r.filesByPath[path]
+	switch len(fds) {
+	case 0:
+		return nil, NotFound
+	case 1:
+		return fds[0], nil
+	default:
+		return nil, errors.New("multiple files named %q", path)
 	}
-	return nil, NotFound
 }
 
-// NumFiles reports the number of registered files.
+// NumFiles reports the number of registered files,
+// including duplicate files with the same name.
 func (r *Files) NumFiles() int {
 	if r == nil {
 		return 0
@@ -264,10 +339,11 @@
 		globalMutex.RLock()
 		defer globalMutex.RUnlock()
 	}
-	return len(r.filesByPath)
+	return r.numFiles
 }
 
 // RangeFiles iterates over all registered files while f returns true.
+// If multiple files have the same name, RangeFiles iterates over all of them.
 // The iteration order is undefined.
 func (r *Files) RangeFiles(f func(protoreflect.FileDescriptor) bool) {
 	if r == nil {
@@ -277,9 +353,11 @@
 		globalMutex.RLock()
 		defer globalMutex.RUnlock()
 	}
-	for _, file := range r.filesByPath {
-		if !f(file) {
-			return
+	for _, files := range r.filesByPath {
+		for _, file := range files {
+			if !f(file) {
+				return
+			}
 		}
 	}
 }
@@ -528,13 +606,25 @@
 	return nil, NotFound
 }
 
-// FindMessageByName looks up a message by its full name.
-// E.g., "google.protobuf.Any"
+// FindMessageByName looks up a message by its full name,
+// e.g. "google.protobuf.Any".
 //
-// This return (nil, NotFound) if not found.
+// This returns (nil, NotFound) if not found.
 func (r *Types) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) {
-	// The full name by itself is a valid URL.
-	return r.FindMessageByURL(string(message))
+	if r == nil {
+		return nil, NotFound
+	}
+	if r == GlobalTypes {
+		globalMutex.RLock()
+		defer globalMutex.RUnlock()
+	}
+	if v := r.typesByName[message]; v != nil {
+		if mt, _ := v.(protoreflect.MessageType); mt != nil {
+			return mt, nil
+		}
+		return nil, errors.New("found wrong type: got %v, want message", typeName(v))
+	}
+	return nil, NotFound
 }
 
 // FindMessageByURL looks up a message by a URL identifier.
@@ -542,6 +632,8 @@
 //
 // This returns (nil, NotFound) if not found.
 func (r *Types) FindMessageByURL(url string) (protoreflect.MessageType, error) {
+	// This function is similar to FindMessageByName but
+	// truncates anything before and including '/' in the URL.
 	if r == nil {
 		return nil, NotFound
 	}
@@ -581,6 +673,26 @@
 		if xt, _ := v.(protoreflect.ExtensionType); xt != nil {
 			return xt, nil
 		}
+
+		// MessageSet extensions are special in that the name of the extension
+		// is the name of the message type used to extend the MessageSet.
+		// This naming scheme is used by text and JSON serialization.
+		//
+		// This feature is protected by the ProtoLegacy flag since MessageSets
+		// are a proto1 feature that is long deprecated.
+		if flags.ProtoLegacy {
+			if _, ok := v.(protoreflect.MessageType); ok {
+				field := field.Append(messageset.ExtensionName)
+				if v := r.typesByName[field]; v != nil {
+					if xt, _ := v.(protoreflect.ExtensionType); xt != nil {
+						if messageset.IsMessageSetExtension(xt.TypeDescriptor()) {
+							return xt, nil
+						}
+					}
+				}
+			}
+		}
+
 		return nil, errors.New("found wrong type: got %v, want extension", typeName(v))
 	}
 	return nil, NotFound