Import of https://github.com/ciena/voltctl at commit 40d61fbf3f910ed4017cf67c9c79e8e1f82a33a5
Change-Id: I8464c59e60d76cb8612891db3303878975b5416c
diff --git a/vendor/github.com/fullstorydev/grpcurl/desc_source.go b/vendor/github.com/fullstorydev/grpcurl/desc_source.go
new file mode 100644
index 0000000..c23ae3d
--- /dev/null
+++ b/vendor/github.com/fullstorydev/grpcurl/desc_source.go
@@ -0,0 +1,253 @@
+package grpcurl
+
+import (
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "sync"
+
+ "github.com/golang/protobuf/proto"
+ descpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
+ "github.com/jhump/protoreflect/desc"
+ "github.com/jhump/protoreflect/desc/protoparse"
+ "github.com/jhump/protoreflect/dynamic"
+ "github.com/jhump/protoreflect/grpcreflect"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+// ErrReflectionNotSupported is returned by DescriptorSource operations that
+// rely on interacting with the reflection service when the source does not
+// actually expose the reflection service. When this occurs, an alternate source
+// (like file descriptor sets) must be used.
+var ErrReflectionNotSupported = errors.New("server does not support the reflection API")
+
+// DescriptorSource is a source of protobuf descriptor information. It can be backed by a FileDescriptorSet
+// proto (like a file generated by protoc) or a remote server that supports the reflection API.
+type DescriptorSource interface {
+ // ListServices returns a list of fully-qualified service names. It will be all services in a set of
+ // descriptor files or the set of all services exposed by a gRPC server.
+ ListServices() ([]string, error)
+ // FindSymbol returns a descriptor for the given fully-qualified symbol name.
+ FindSymbol(fullyQualifiedName string) (desc.Descriptor, error)
+ // AllExtensionsForType returns all known extension fields that extend the given message type name.
+ AllExtensionsForType(typeName string) ([]*desc.FieldDescriptor, error)
+}
+
+// DescriptorSourceFromProtoSets creates a DescriptorSource that is backed by the named files, whose contents
+// are encoded FileDescriptorSet protos.
+func DescriptorSourceFromProtoSets(fileNames ...string) (DescriptorSource, error) {
+ files := &descpb.FileDescriptorSet{}
+ for _, fileName := range fileNames {
+ b, err := ioutil.ReadFile(fileName)
+ if err != nil {
+ return nil, fmt.Errorf("could not load protoset file %q: %v", fileName, err)
+ }
+ var fs descpb.FileDescriptorSet
+ err = proto.Unmarshal(b, &fs)
+ if err != nil {
+ return nil, fmt.Errorf("could not parse contents of protoset file %q: %v", fileName, err)
+ }
+ files.File = append(files.File, fs.File...)
+ }
+ return DescriptorSourceFromFileDescriptorSet(files)
+}
+
+// DescriptorSourceFromProtoFiles creates a DescriptorSource that is backed by the named files,
+// whose contents are Protocol Buffer source files. The given importPaths are used to locate
+// any imported files.
+func DescriptorSourceFromProtoFiles(importPaths []string, fileNames ...string) (DescriptorSource, error) {
+ fileNames, err := protoparse.ResolveFilenames(importPaths, fileNames...)
+ if err != nil {
+ return nil, err
+ }
+ p := protoparse.Parser{
+ ImportPaths: importPaths,
+ InferImportPaths: len(importPaths) == 0,
+ IncludeSourceCodeInfo: true,
+ }
+ fds, err := p.ParseFiles(fileNames...)
+ if err != nil {
+ return nil, fmt.Errorf("could not parse given files: %v", err)
+ }
+ return DescriptorSourceFromFileDescriptors(fds...)
+}
+
+// DescriptorSourceFromFileDescriptorSet creates a DescriptorSource that is backed by the FileDescriptorSet.
+func DescriptorSourceFromFileDescriptorSet(files *descpb.FileDescriptorSet) (DescriptorSource, error) {
+ unresolved := map[string]*descpb.FileDescriptorProto{}
+ for _, fd := range files.File {
+ unresolved[fd.GetName()] = fd
+ }
+ resolved := map[string]*desc.FileDescriptor{}
+ for _, fd := range files.File {
+ _, err := resolveFileDescriptor(unresolved, resolved, fd.GetName())
+ if err != nil {
+ return nil, err
+ }
+ }
+ return &fileSource{files: resolved}, nil
+}
+
+func resolveFileDescriptor(unresolved map[string]*descpb.FileDescriptorProto, resolved map[string]*desc.FileDescriptor, filename string) (*desc.FileDescriptor, error) {
+ if r, ok := resolved[filename]; ok {
+ return r, nil
+ }
+ fd, ok := unresolved[filename]
+ if !ok {
+ return nil, fmt.Errorf("no descriptor found for %q", filename)
+ }
+ deps := make([]*desc.FileDescriptor, 0, len(fd.GetDependency()))
+ for _, dep := range fd.GetDependency() {
+ depFd, err := resolveFileDescriptor(unresolved, resolved, dep)
+ if err != nil {
+ return nil, err
+ }
+ deps = append(deps, depFd)
+ }
+ result, err := desc.CreateFileDescriptor(fd, deps...)
+ if err != nil {
+ return nil, err
+ }
+ resolved[filename] = result
+ return result, nil
+}
+
+// DescriptorSourceFromFileDescriptors creates a DescriptorSource that is backed by the given
+// file descriptors
+func DescriptorSourceFromFileDescriptors(files ...*desc.FileDescriptor) (DescriptorSource, error) {
+ fds := map[string]*desc.FileDescriptor{}
+ for _, fd := range files {
+ if err := addFile(fd, fds); err != nil {
+ return nil, err
+ }
+ }
+ return &fileSource{files: fds}, nil
+}
+
+func addFile(fd *desc.FileDescriptor, fds map[string]*desc.FileDescriptor) error {
+ name := fd.GetName()
+ if existing, ok := fds[name]; ok {
+ // already added this file
+ if existing != fd {
+ // doh! duplicate files provided
+ return fmt.Errorf("given files include multiple copies of %q", name)
+ }
+ return nil
+ }
+ fds[name] = fd
+ for _, dep := range fd.GetDependencies() {
+ if err := addFile(dep, fds); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+type fileSource struct {
+ files map[string]*desc.FileDescriptor
+ er *dynamic.ExtensionRegistry
+ erInit sync.Once
+}
+
+func (fs *fileSource) ListServices() ([]string, error) {
+ set := map[string]bool{}
+ for _, fd := range fs.files {
+ for _, svc := range fd.GetServices() {
+ set[svc.GetFullyQualifiedName()] = true
+ }
+ }
+ sl := make([]string, 0, len(set))
+ for svc := range set {
+ sl = append(sl, svc)
+ }
+ return sl, nil
+}
+
+// GetAllFiles returns all of the underlying file descriptors. This is
+// more thorough and more efficient than the fallback strategy used by
+// the GetAllFiles package method, for enumerating all files from a
+// descriptor source.
+func (fs *fileSource) GetAllFiles() ([]*desc.FileDescriptor, error) {
+ files := make([]*desc.FileDescriptor, len(fs.files))
+ i := 0
+ for _, fd := range fs.files {
+ files[i] = fd
+ i++
+ }
+ return files, nil
+}
+
+func (fs *fileSource) FindSymbol(fullyQualifiedName string) (desc.Descriptor, error) {
+ for _, fd := range fs.files {
+ if dsc := fd.FindSymbol(fullyQualifiedName); dsc != nil {
+ return dsc, nil
+ }
+ }
+ return nil, notFound("Symbol", fullyQualifiedName)
+}
+
+func (fs *fileSource) AllExtensionsForType(typeName string) ([]*desc.FieldDescriptor, error) {
+ fs.erInit.Do(func() {
+ fs.er = &dynamic.ExtensionRegistry{}
+ for _, fd := range fs.files {
+ fs.er.AddExtensionsFromFile(fd)
+ }
+ })
+ return fs.er.AllExtensionsForType(typeName), nil
+}
+
+// DescriptorSourceFromServer creates a DescriptorSource that uses the given gRPC reflection client
+// to interrogate a server for descriptor information. If the server does not support the reflection
+// API then the various DescriptorSource methods will return ErrReflectionNotSupported
+func DescriptorSourceFromServer(_ context.Context, refClient *grpcreflect.Client) DescriptorSource {
+ return serverSource{client: refClient}
+}
+
+type serverSource struct {
+ client *grpcreflect.Client
+}
+
+func (ss serverSource) ListServices() ([]string, error) {
+ svcs, err := ss.client.ListServices()
+ return svcs, reflectionSupport(err)
+}
+
+func (ss serverSource) FindSymbol(fullyQualifiedName string) (desc.Descriptor, error) {
+ file, err := ss.client.FileContainingSymbol(fullyQualifiedName)
+ if err != nil {
+ return nil, reflectionSupport(err)
+ }
+ d := file.FindSymbol(fullyQualifiedName)
+ if d == nil {
+ return nil, notFound("Symbol", fullyQualifiedName)
+ }
+ return d, nil
+}
+
+func (ss serverSource) AllExtensionsForType(typeName string) ([]*desc.FieldDescriptor, error) {
+ var exts []*desc.FieldDescriptor
+ nums, err := ss.client.AllExtensionNumbersForType(typeName)
+ if err != nil {
+ return nil, reflectionSupport(err)
+ }
+ for _, fieldNum := range nums {
+ ext, err := ss.client.ResolveExtension(typeName, fieldNum)
+ if err != nil {
+ return nil, reflectionSupport(err)
+ }
+ exts = append(exts, ext)
+ }
+ return exts, nil
+}
+
+func reflectionSupport(err error) error {
+ if err == nil {
+ return nil
+ }
+ if stat, ok := status.FromError(err); ok && stat.Code() == codes.Unimplemented {
+ return ErrReflectionNotSupported
+ }
+ return err
+}