Merge pull request #749 from menghanl/streams_in_serviceinfo

Split methods and streams in service info
diff --git a/reflection/serverreflection.go b/reflection/serverreflection.go
index b044a3a..0daa096 100644
--- a/reflection/serverreflection.go
+++ b/reflection/serverreflection.go
@@ -214,19 +214,19 @@
 		return nil, fmt.Errorf("unknown symbol: %v", name)
 	}
 
-	// Search for method in info.
+	// Search for method name in info.Methods.
 	var found bool
 	for _, m := range info.Methods {
-		if m == name[pos+1:] {
+		if m.Name == name[pos+1:] {
 			found = true
 			break
 		}
 	}
-	if !found {
-		return nil, fmt.Errorf("unknown symbol: %v", name)
+	if found {
+		return info.Metadata, nil
 	}
 
-	return info.Metadata, nil
+	return nil, fmt.Errorf("unknown symbol: %v", name)
 }
 
 // fileDescEncodingContainingSymbol finds the file descriptor containing the given symbol,
diff --git a/reflection/serverreflection_test.go b/reflection/serverreflection_test.go
index aeb31e1..ca9610e 100644
--- a/reflection/serverreflection_test.go
+++ b/reflection/serverreflection_test.go
@@ -273,6 +273,7 @@
 	}{
 		{"grpc.testing.SearchService", fdTestByte},
 		{"grpc.testing.SearchService.Search", fdTestByte},
+		{"grpc.testing.SearchService.StreamingSearch", fdTestByte},
 		{"grpc.testing.SearchResponse", fdTestByte},
 		{"grpc.testing.ToBeExtened", fdProto2Byte},
 	} {
diff --git a/server.go b/server.go
index 7dabfc6..f7b8319 100644
--- a/server.go
+++ b/server.go
@@ -245,10 +245,19 @@
 	s.m[sd.ServiceName] = srv
 }
 
-// ServiceInfo contains method names and metadata for a service.
+// MethodInfo contains information about an RPC.
+type MethodInfo struct {
+	// Name is the method name only, without the service name or package name.
+	Name string
+	// IsClientStream indicates whether the RPC is a client streaming RPC.
+	IsClientStream bool
+	// IsServerStream indicates whether the RPC is a server streaming RPC.
+	IsServerStream bool
+}
+
+// ServiceInfo contains unary RPC method info, streaming RPC methid info and metadata for a service.
 type ServiceInfo struct {
-	// Methods are method names only, without the service name or package name.
-	Methods []string
+	Methods []MethodInfo
 	// Metadata is the metadata specified in ServiceDesc when registering service.
 	Metadata interface{}
 }
@@ -258,12 +267,20 @@
 func (s *Server) GetServiceInfo() map[string]*ServiceInfo {
 	ret := make(map[string]*ServiceInfo)
 	for n, srv := range s.m {
-		methods := make([]string, 0, len(srv.md)+len(srv.sd))
+		methods := make([]MethodInfo, 0, len(srv.md)+len(srv.sd))
 		for m := range srv.md {
-			methods = append(methods, m)
+			methods = append(methods, MethodInfo{
+				Name:           m,
+				IsClientStream: false,
+				IsServerStream: false,
+			})
 		}
-		for m := range srv.sd {
-			methods = append(methods, m)
+		for m, d := range srv.sd {
+			methods = append(methods, MethodInfo{
+				Name:           m,
+				IsClientStream: d.ClientStreams,
+				IsServerStream: d.ServerStreams,
+			})
 		}
 
 		ret[n] = &ServiceInfo{
diff --git a/server_test.go b/server_test.go
index 7c1e54d..eb598a5 100644
--- a/server_test.go
+++ b/server_test.go
@@ -79,7 +79,7 @@
 			{
 				StreamName:    "EmptyStream",
 				Handler:       nil,
-				ServerStreams: true,
+				ServerStreams: false,
 				ClientStreams: true,
 			},
 		},
@@ -92,10 +92,17 @@
 	info := server.GetServiceInfo()
 	want := map[string]*ServiceInfo{
 		"grpc.testing.EmptyService": &ServiceInfo{
-			Methods: []string{
-				"EmptyCall",
-				"EmptyStream",
-			},
+			Methods: []MethodInfo{
+				MethodInfo{
+					Name:           "EmptyCall",
+					IsClientStream: false,
+					IsServerStream: false,
+				},
+				MethodInfo{
+					Name:           "EmptyStream",
+					IsClientStream: true,
+					IsServerStream: false,
+				}},
 			Metadata: []int{0, 2, 1, 3},
 		},
 	}