28 func formatListOpt(vs list, isRoot, allowMulti bool) string { |
28 func formatListOpt(vs list, isRoot, allowMulti bool) string { |
29 start, end := "[", "]" |
29 start, end := "[", "]" |
30 if isRoot { |
30 if isRoot { |
31 var name string |
31 var name string |
32 switch vs.(type) { |
32 switch vs.(type) { |
33 case pref.Names: |
33 case protoreflect.Names: |
34 name = "Names" |
34 name = "Names" |
35 case pref.FieldNumbers: |
35 case protoreflect.FieldNumbers: |
36 name = "FieldNumbers" |
36 name = "FieldNumbers" |
37 case pref.FieldRanges: |
37 case protoreflect.FieldRanges: |
38 name = "FieldRanges" |
38 name = "FieldRanges" |
39 case pref.EnumRanges: |
39 case protoreflect.EnumRanges: |
40 name = "EnumRanges" |
40 name = "EnumRanges" |
41 case pref.FileImports: |
41 case protoreflect.FileImports: |
42 name = "FileImports" |
42 name = "FileImports" |
43 case pref.Descriptor: |
43 case protoreflect.Descriptor: |
44 name = reflect.ValueOf(vs).MethodByName("Get").Type().Out(0).Name() + "s" |
44 name = reflect.ValueOf(vs).MethodByName("Get").Type().Out(0).Name() + "s" |
45 default: |
45 default: |
46 name = reflect.ValueOf(vs).Elem().Type().Name() |
46 name = reflect.ValueOf(vs).Elem().Type().Name() |
47 } |
47 } |
48 start, end = name+"{", "}" |
48 start, end = name+"{", "}" |
49 } |
49 } |
50 |
50 |
51 var ss []string |
51 var ss []string |
52 switch vs := vs.(type) { |
52 switch vs := vs.(type) { |
53 case pref.Names: |
53 case protoreflect.Names: |
54 for i := 0; i < vs.Len(); i++ { |
54 for i := 0; i < vs.Len(); i++ { |
55 ss = append(ss, fmt.Sprint(vs.Get(i))) |
55 ss = append(ss, fmt.Sprint(vs.Get(i))) |
56 } |
56 } |
57 return start + joinStrings(ss, false) + end |
57 return start + joinStrings(ss, false) + end |
58 case pref.FieldNumbers: |
58 case protoreflect.FieldNumbers: |
59 for i := 0; i < vs.Len(); i++ { |
59 for i := 0; i < vs.Len(); i++ { |
60 ss = append(ss, fmt.Sprint(vs.Get(i))) |
60 ss = append(ss, fmt.Sprint(vs.Get(i))) |
61 } |
61 } |
62 return start + joinStrings(ss, false) + end |
62 return start + joinStrings(ss, false) + end |
63 case pref.FieldRanges: |
63 case protoreflect.FieldRanges: |
64 for i := 0; i < vs.Len(); i++ { |
64 for i := 0; i < vs.Len(); i++ { |
65 r := vs.Get(i) |
65 r := vs.Get(i) |
66 if r[0]+1 == r[1] { |
66 if r[0]+1 == r[1] { |
67 ss = append(ss, fmt.Sprintf("%d", r[0])) |
67 ss = append(ss, fmt.Sprintf("%d", r[0])) |
68 } else { |
68 } else { |
69 ss = append(ss, fmt.Sprintf("%d:%d", r[0], r[1])) // enum ranges are end exclusive |
69 ss = append(ss, fmt.Sprintf("%d:%d", r[0], r[1])) // enum ranges are end exclusive |
70 } |
70 } |
71 } |
71 } |
72 return start + joinStrings(ss, false) + end |
72 return start + joinStrings(ss, false) + end |
73 case pref.EnumRanges: |
73 case protoreflect.EnumRanges: |
74 for i := 0; i < vs.Len(); i++ { |
74 for i := 0; i < vs.Len(); i++ { |
75 r := vs.Get(i) |
75 r := vs.Get(i) |
76 if r[0] == r[1] { |
76 if r[0] == r[1] { |
77 ss = append(ss, fmt.Sprintf("%d", r[0])) |
77 ss = append(ss, fmt.Sprintf("%d", r[0])) |
78 } else { |
78 } else { |
79 ss = append(ss, fmt.Sprintf("%d:%d", r[0], int64(r[1])+1)) // enum ranges are end inclusive |
79 ss = append(ss, fmt.Sprintf("%d:%d", r[0], int64(r[1])+1)) // enum ranges are end inclusive |
80 } |
80 } |
81 } |
81 } |
82 return start + joinStrings(ss, false) + end |
82 return start + joinStrings(ss, false) + end |
83 case pref.FileImports: |
83 case protoreflect.FileImports: |
84 for i := 0; i < vs.Len(); i++ { |
84 for i := 0; i < vs.Len(); i++ { |
85 var rs records |
85 var rs records |
86 rs.Append(reflect.ValueOf(vs.Get(i)), "Path", "Package", "IsPublic", "IsWeak") |
86 rs.Append(reflect.ValueOf(vs.Get(i)), "Path", "Package", "IsPublic", "IsWeak") |
87 ss = append(ss, "{"+rs.Join()+"}") |
87 ss = append(ss, "{"+rs.Join()+"}") |
88 } |
88 } |
89 return start + joinStrings(ss, allowMulti) + end |
89 return start + joinStrings(ss, allowMulti) + end |
90 default: |
90 default: |
91 _, isEnumValue := vs.(pref.EnumValueDescriptors) |
91 _, isEnumValue := vs.(protoreflect.EnumValueDescriptors) |
92 for i := 0; i < vs.Len(); i++ { |
92 for i := 0; i < vs.Len(); i++ { |
93 m := reflect.ValueOf(vs).MethodByName("Get") |
93 m := reflect.ValueOf(vs).MethodByName("Get") |
94 v := m.Call([]reflect.Value{reflect.ValueOf(i)})[0].Interface() |
94 v := m.Call([]reflect.Value{reflect.ValueOf(i)})[0].Interface() |
95 ss = append(ss, formatDescOpt(v.(pref.Descriptor), false, allowMulti && !isEnumValue)) |
95 ss = append(ss, formatDescOpt(v.(protoreflect.Descriptor), false, allowMulti && !isEnumValue)) |
96 } |
96 } |
97 return start + joinStrings(ss, allowMulti && isEnumValue) + end |
97 return start + joinStrings(ss, allowMulti && isEnumValue) + end |
98 } |
98 } |
99 } |
99 } |
100 |
100 |
104 // while others are pointers that we do not want to follow since the descriptor |
104 // while others are pointers that we do not want to follow since the descriptor |
105 // is actually a cyclic graph. |
105 // is actually a cyclic graph. |
106 // |
106 // |
107 // Using a list allows us to print the accessors in a sensible order. |
107 // Using a list allows us to print the accessors in a sensible order. |
108 var descriptorAccessors = map[reflect.Type][]string{ |
108 var descriptorAccessors = map[reflect.Type][]string{ |
109 reflect.TypeOf((*pref.FileDescriptor)(nil)).Elem(): {"Path", "Package", "Imports", "Messages", "Enums", "Extensions", "Services"}, |
109 reflect.TypeOf((*protoreflect.FileDescriptor)(nil)).Elem(): {"Path", "Package", "Imports", "Messages", "Enums", "Extensions", "Services"}, |
110 reflect.TypeOf((*pref.MessageDescriptor)(nil)).Elem(): {"IsMapEntry", "Fields", "Oneofs", "ReservedNames", "ReservedRanges", "RequiredNumbers", "ExtensionRanges", "Messages", "Enums", "Extensions"}, |
110 reflect.TypeOf((*protoreflect.MessageDescriptor)(nil)).Elem(): {"IsMapEntry", "Fields", "Oneofs", "ReservedNames", "ReservedRanges", "RequiredNumbers", "ExtensionRanges", "Messages", "Enums", "Extensions"}, |
111 reflect.TypeOf((*pref.FieldDescriptor)(nil)).Elem(): {"Number", "Cardinality", "Kind", "HasJSONName", "JSONName", "HasPresence", "IsExtension", "IsPacked", "IsWeak", "IsList", "IsMap", "MapKey", "MapValue", "HasDefault", "Default", "ContainingOneof", "ContainingMessage", "Message", "Enum"}, |
111 reflect.TypeOf((*protoreflect.FieldDescriptor)(nil)).Elem(): {"Number", "Cardinality", "Kind", "HasJSONName", "JSONName", "HasPresence", "IsExtension", "IsPacked", "IsWeak", "IsList", "IsMap", "MapKey", "MapValue", "HasDefault", "Default", "ContainingOneof", "ContainingMessage", "Message", "Enum"}, |
112 reflect.TypeOf((*pref.OneofDescriptor)(nil)).Elem(): {"Fields"}, // not directly used; must keep in sync with formatDescOpt |
112 reflect.TypeOf((*protoreflect.OneofDescriptor)(nil)).Elem(): {"Fields"}, // not directly used; must keep in sync with formatDescOpt |
113 reflect.TypeOf((*pref.EnumDescriptor)(nil)).Elem(): {"Values", "ReservedNames", "ReservedRanges"}, |
113 reflect.TypeOf((*protoreflect.EnumDescriptor)(nil)).Elem(): {"Values", "ReservedNames", "ReservedRanges"}, |
114 reflect.TypeOf((*pref.EnumValueDescriptor)(nil)).Elem(): {"Number"}, |
114 reflect.TypeOf((*protoreflect.EnumValueDescriptor)(nil)).Elem(): {"Number"}, |
115 reflect.TypeOf((*pref.ServiceDescriptor)(nil)).Elem(): {"Methods"}, |
115 reflect.TypeOf((*protoreflect.ServiceDescriptor)(nil)).Elem(): {"Methods"}, |
116 reflect.TypeOf((*pref.MethodDescriptor)(nil)).Elem(): {"Input", "Output", "IsStreamingClient", "IsStreamingServer"}, |
116 reflect.TypeOf((*protoreflect.MethodDescriptor)(nil)).Elem(): {"Input", "Output", "IsStreamingClient", "IsStreamingServer"}, |
117 } |
117 } |
118 |
118 |
119 func FormatDesc(s fmt.State, r rune, t pref.Descriptor) { |
119 func FormatDesc(s fmt.State, r rune, t protoreflect.Descriptor) { |
120 io.WriteString(s, formatDescOpt(t, true, r == 'v' && (s.Flag('+') || s.Flag('#')))) |
120 io.WriteString(s, formatDescOpt(t, true, r == 'v' && (s.Flag('+') || s.Flag('#')))) |
121 } |
121 } |
122 func formatDescOpt(t pref.Descriptor, isRoot, allowMulti bool) string { |
122 func formatDescOpt(t protoreflect.Descriptor, isRoot, allowMulti bool) string { |
123 rv := reflect.ValueOf(t) |
123 rv := reflect.ValueOf(t) |
124 rt := rv.MethodByName("ProtoType").Type().In(0) |
124 rt := rv.MethodByName("ProtoType").Type().In(0) |
125 |
125 |
126 start, end := "{", "}" |
126 start, end := "{", "}" |
127 if isRoot { |
127 if isRoot { |
128 start = rt.Name() + "{" |
128 start = rt.Name() + "{" |
129 } |
129 } |
130 |
130 |
131 _, isFile := t.(pref.FileDescriptor) |
131 _, isFile := t.(protoreflect.FileDescriptor) |
132 rs := records{allowMulti: allowMulti} |
132 rs := records{allowMulti: allowMulti} |
133 if t.IsPlaceholder() { |
133 if t.IsPlaceholder() { |
134 if isFile { |
134 if isFile { |
135 rs.Append(rv, "Path", "Package", "IsPlaceholder") |
135 rs.Append(rv, "Path", "Package", "IsPlaceholder") |
136 } else { |
136 } else { |
144 rs.Append(rv, "Syntax", "FullName") |
144 rs.Append(rv, "Syntax", "FullName") |
145 default: |
145 default: |
146 rs.Append(rv, "Name") |
146 rs.Append(rv, "Name") |
147 } |
147 } |
148 switch t := t.(type) { |
148 switch t := t.(type) { |
149 case pref.FieldDescriptor: |
149 case protoreflect.FieldDescriptor: |
150 for _, s := range descriptorAccessors[rt] { |
150 for _, s := range descriptorAccessors[rt] { |
151 switch s { |
151 switch s { |
152 case "MapKey": |
152 case "MapKey": |
153 if k := t.MapKey(); k != nil { |
153 if k := t.MapKey(); k != nil { |
154 rs.recs = append(rs.recs, [2]string{"MapKey", k.Kind().String()}) |
154 rs.recs = append(rs.recs, [2]string{"MapKey", k.Kind().String()}) |
155 } |
155 } |
156 case "MapValue": |
156 case "MapValue": |
157 if v := t.MapValue(); v != nil { |
157 if v := t.MapValue(); v != nil { |
158 switch v.Kind() { |
158 switch v.Kind() { |
159 case pref.EnumKind: |
159 case protoreflect.EnumKind: |
160 rs.recs = append(rs.recs, [2]string{"MapValue", string(v.Enum().FullName())}) |
160 rs.recs = append(rs.recs, [2]string{"MapValue", string(v.Enum().FullName())}) |
161 case pref.MessageKind, pref.GroupKind: |
161 case protoreflect.MessageKind, protoreflect.GroupKind: |
162 rs.recs = append(rs.recs, [2]string{"MapValue", string(v.Message().FullName())}) |
162 rs.recs = append(rs.recs, [2]string{"MapValue", string(v.Message().FullName())}) |
163 default: |
163 default: |
164 rs.recs = append(rs.recs, [2]string{"MapValue", v.Kind().String()}) |
164 rs.recs = append(rs.recs, [2]string{"MapValue", v.Kind().String()}) |
165 } |
165 } |
166 } |
166 } |