Add typeForName nameForType nameForPointer

This commit is contained in:
Menghan Li 2016-05-16 16:31:42 -07:00
Родитель 15469fce29
Коммит 36cbb03cfe
2 изменённых файлов: 101 добавлений и 1 удалений

Просмотреть файл

@ -87,3 +87,45 @@ func decompress(b []byte) []byte {
}
return out
}
func (s *serverReflectionServer) typeForName(name string) (reflect.Type, error) {
// TODO cache
pt := proto.MessageType(name)
if pt == nil {
return nil, fmt.Errorf("unknown type: %q", name)
}
st := pt.Elem()
// TODO cache
// s.typeToNameMap[st] = name
// s.nameToTypeMap[name] = st
// fd, _, ok := s.fileDescForType(st)
// if ok {
// s.typeToFilenameMap[st] = fd.GetName()
// }
return st, nil
}
func (s *serverReflectionServer) nameForType(st reflect.Type) (string, error) {
// TODO cache
var name string
fd, idxs, err := s.fileDescForType(st)
if err != nil {
return "", err
}
mt := fd.MessageType[idxs[0]]
name = mt.GetName()
for i := 1; i < len(idxs); i++ {
mt = mt.NestedType[idxs[i]]
name += "_" + mt.GetName()
}
if fd.Package != nil {
name = *fd.Package + "." + name
}
return name, nil
}
func (s *serverReflectionServer) nameForPointer(i interface{}) (string, error) {
return s.nameForType(reflect.TypeOf(i).Elem())
}

Просмотреть файл

@ -2,7 +2,6 @@ package main
import (
"reflect"
"sort"
"testing"
pb "google.golang.org/grpc/reflection/grpc_testing"
@ -13,3 +12,62 @@ var (
)
// TODO TestFileDescForType(t *testing.T)
func TestTypeForName(t *testing.T) {
for _, test := range []struct {
name string
want reflect.Type
}{
{"grpc.testing.SearchResponse", reflect.TypeOf(pb.SearchResponse{})},
} {
r, err := s.typeForName(test.name)
// TODO remove all Logf
t.Logf("typeForName(%q) = %q, %v", test.name, r, err)
if err != nil || r != test.want {
t.Fatalf("typeForName(%q) = %q, %v, want %q, <nil>", test.name, r, err, test.want)
}
}
}
func TestTypeForNameNotFound(t *testing.T) {
for _, test := range []string{
"grpc.testing.not_exiting",
} {
_, err := s.typeForName(test)
if err == nil {
t.Fatalf("typeForName(%q) = _, %v, want _, <non-nil>", test, err)
}
}
}
func TestNameForType(t *testing.T) {
for _, test := range []struct {
st reflect.Type
want string
}{
{reflect.TypeOf(pb.SearchResponse{}), "grpc.testing.SearchResponse"},
{reflect.TypeOf(pb.SearchResponse_Result{}), "grpc.testing.SearchResponse_Result"},
} {
r, err := s.nameForType(test.st)
t.Logf("nameForType(%q) = %q, %v", test.st, r, err)
if err != nil || r != test.want {
t.Fatalf("nameForType(%q) = %q, %v, want %q, <nil>", test.st, r, err, test.want)
}
}
}
func TestNameForPointer(t *testing.T) {
for _, test := range []struct {
pt interface{}
want string
}{
{&pb.SearchResponse{}, "grpc.testing.SearchResponse"},
{&pb.SearchResponse_Result{}, "grpc.testing.SearchResponse_Result"},
} {
r, err := s.nameForPointer(test.pt)
t.Logf("nameForPointer(%T) = %q, %v", test.pt, r, err)
if err != nil || r != test.want {
t.Fatalf("nameForPointer(%T) = %q, %v, want %q, <nil>", test.pt, r, err, test.want)
}
}
}