vendor/google.golang.org/protobuf/internal/descfmt/stringer.go
changeset 260 445e01aede7e
parent 256 6d9efbef00a9
equal deleted inserted replaced
259:db4911b0c721 260:445e01aede7e
    12 	"strconv"
    12 	"strconv"
    13 	"strings"
    13 	"strings"
    14 
    14 
    15 	"google.golang.org/protobuf/internal/detrand"
    15 	"google.golang.org/protobuf/internal/detrand"
    16 	"google.golang.org/protobuf/internal/pragma"
    16 	"google.golang.org/protobuf/internal/pragma"
    17 	pref "google.golang.org/protobuf/reflect/protoreflect"
    17 	"google.golang.org/protobuf/reflect/protoreflect"
    18 )
    18 )
    19 
    19 
    20 type list interface {
    20 type list interface {
    21 	Len() int
    21 	Len() int
    22 	pragma.DoNotImplement
    22 	pragma.DoNotImplement
    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 					}
   178 					}
   178 					}
   179 				default:
   179 				default:
   180 					rs.Append(rv, s)
   180 					rs.Append(rv, s)
   181 				}
   181 				}
   182 			}
   182 			}
   183 		case pref.OneofDescriptor:
   183 		case protoreflect.OneofDescriptor:
   184 			var ss []string
   184 			var ss []string
   185 			fs := t.Fields()
   185 			fs := t.Fields()
   186 			for i := 0; i < fs.Len(); i++ {
   186 			for i := 0; i < fs.Len(); i++ {
   187 				ss = append(ss, string(fs.Get(i).Name()))
   187 				ss = append(ss, string(fs.Get(i).Name()))
   188 			}
   188 			}
   214 			rv = v.FieldByName(a)
   214 			rv = v.FieldByName(a)
   215 		}
   215 		}
   216 		if !rv.IsValid() {
   216 		if !rv.IsValid() {
   217 			panic(fmt.Sprintf("unknown accessor: %v.%s", v.Type(), a))
   217 			panic(fmt.Sprintf("unknown accessor: %v.%s", v.Type(), a))
   218 		}
   218 		}
   219 		if _, ok := rv.Interface().(pref.Value); ok {
   219 		if _, ok := rv.Interface().(protoreflect.Value); ok {
   220 			rv = rv.MethodByName("Interface").Call(nil)[0]
   220 			rv = rv.MethodByName("Interface").Call(nil)[0]
   221 			if !rv.IsNil() {
   221 			if !rv.IsNil() {
   222 				rv = rv.Elem()
   222 				rv = rv.Elem()
   223 			}
   223 			}
   224 		}
   224 		}
   248 		var s string
   248 		var s string
   249 		v := rv.Interface()
   249 		v := rv.Interface()
   250 		switch v := v.(type) {
   250 		switch v := v.(type) {
   251 		case list:
   251 		case list:
   252 			s = formatListOpt(v, false, rs.allowMulti)
   252 			s = formatListOpt(v, false, rs.allowMulti)
   253 		case pref.FieldDescriptor, pref.OneofDescriptor, pref.EnumValueDescriptor, pref.MethodDescriptor:
   253 		case protoreflect.FieldDescriptor, protoreflect.OneofDescriptor, protoreflect.EnumValueDescriptor, protoreflect.MethodDescriptor:
   254 			s = string(v.(pref.Descriptor).Name())
   254 			s = string(v.(protoreflect.Descriptor).Name())
   255 		case pref.Descriptor:
   255 		case protoreflect.Descriptor:
   256 			s = string(v.FullName())
   256 			s = string(v.FullName())
   257 		case string:
   257 		case string:
   258 			s = strconv.Quote(v)
   258 			s = strconv.Quote(v)
   259 		case []byte:
   259 		case []byte:
   260 			s = fmt.Sprintf("%q", v)
   260 			s = fmt.Sprintf("%q", v)