go-micro.dev/v5@v5.12.0/server/grpc/extractor.go (about) 1 package grpc 2 3 import ( 4 "fmt" 5 "reflect" 6 "strings" 7 8 "go-micro.dev/v5/registry" 9 ) 10 11 func extractValue(v reflect.Type, d int) *registry.Value { 12 if d == 3 { 13 return nil 14 } 15 if v == nil { 16 return nil 17 } 18 19 if v.Kind() == reflect.Ptr { 20 v = v.Elem() 21 } 22 23 arg := ®istry.Value{ 24 Name: v.Name(), 25 Type: v.Name(), 26 } 27 28 switch v.Kind() { 29 case reflect.Struct: 30 for i := 0; i < v.NumField(); i++ { 31 f := v.Field(i) 32 if f.PkgPath != "" { 33 continue 34 } 35 val := extractValue(f.Type, d+1) 36 if val == nil { 37 continue 38 } 39 40 // if we can find a json tag use it 41 if tags := f.Tag.Get("json"); len(tags) > 0 { 42 parts := strings.Split(tags, ",") 43 if parts[0] == "-" || parts[0] == "omitempty" { 44 continue 45 } 46 val.Name = parts[0] 47 } 48 49 // if there's no name default it 50 if len(val.Name) == 0 { 51 val.Name = v.Field(i).Name 52 } 53 54 arg.Values = append(arg.Values, val) 55 } 56 case reflect.Slice: 57 p := v.Elem() 58 if p.Kind() == reflect.Ptr { 59 p = p.Elem() 60 } 61 arg.Type = "[]" + p.Name() 62 } 63 64 return arg 65 } 66 67 func extractEndpoint(method reflect.Method) *registry.Endpoint { 68 if method.PkgPath != "" { 69 return nil 70 } 71 72 var rspType, reqType reflect.Type 73 var stream bool 74 mt := method.Type 75 76 switch mt.NumIn() { 77 case 3: 78 reqType = mt.In(1) 79 rspType = mt.In(2) 80 case 4: 81 reqType = mt.In(2) 82 rspType = mt.In(3) 83 default: 84 return nil 85 } 86 87 // are we dealing with a stream? 88 switch rspType.Kind() { 89 case reflect.Func, reflect.Interface: 90 stream = true 91 } 92 93 request := extractValue(reqType, 0) 94 response := extractValue(rspType, 0) 95 96 ep := ®istry.Endpoint{ 97 Name: method.Name, 98 Request: request, 99 Response: response, 100 Metadata: make(map[string]string), 101 } 102 103 if stream { 104 ep.Metadata = map[string]string{ 105 "stream": fmt.Sprintf("%v", stream), 106 } 107 } 108 109 return ep 110 } 111 112 func extractSubValue(typ reflect.Type) *registry.Value { 113 var reqType reflect.Type 114 switch typ.NumIn() { 115 case 1: 116 reqType = typ.In(0) 117 case 2: 118 reqType = typ.In(1) 119 case 3: 120 reqType = typ.In(2) 121 default: 122 return nil 123 } 124 return extractValue(reqType, 0) 125 }