github.com/jhump/protoreflect@v1.16.0/desc/protoprint/sort.go (about) 1 package protoprint 2 3 import ( 4 "fmt" 5 "strings" 6 7 "google.golang.org/protobuf/types/descriptorpb" 8 9 "github.com/jhump/protoreflect/desc" 10 ) 11 12 // ElementKind is an enumeration of the types of elements in a protobuf 13 // file descriptor. This can be used by custom sort functions, for 14 // printing a file using a custom ordering of elements. 15 type ElementKind int 16 17 const ( 18 KindPackage = ElementKind(iota) + 1 19 KindImport 20 KindOption 21 KindField 22 KindMessage 23 KindEnum 24 KindService 25 KindExtensionRange 26 KindExtension 27 KindReservedRange 28 KindReservedName 29 KindEnumValue 30 KindMethod 31 ) 32 33 // Element represents an element in a proto descriptor that can be 34 // printed. This interface is primarily used to allow users of this package to 35 // define custom sort orders for the printed output. The methods of this 36 // interface represent the values that can be used for ordering elements. 37 type Element interface { 38 // Kind returns the kind of the element. The kind determines which other 39 // methods are applicable. 40 Kind() ElementKind 41 // Name returns the element name. This is NOT applicable to syntax, 42 // extension range, and reserved range kinds and will return the empty 43 // string for these kinds. For custom options, this will be the 44 // fully-qualified name of the corresponding extension. 45 Name() string 46 // Number returns the element number. This is only applicable to field, 47 // extension, and enum value kinds and will return zero for all other kinds. 48 Number() int32 49 // NumberRange returns the range of numbers/tags for the element. This is 50 // only applicable to extension ranges and reserved ranges and will return 51 // (0, 0) for all other kinds. 52 NumberRange() (int32, int32) 53 // Extendee is the extended message for the extension element. Elements 54 // other than extensions will return the empty string. 55 Extendee() string 56 // IsCustomOption returns true if the element is a custom option. If it is 57 // not (including if the element kind is not option) then this method will 58 // return false. 59 IsCustomOption() bool 60 } 61 62 func asElement(v interface{}) Element { 63 switch v := v.(type) { 64 case pkg: 65 return pkgElement(v) 66 case imp: 67 return impElement(v) 68 case []option: 69 return (*optionElement)(&v[0]) 70 case reservedRange: 71 return resvdRangeElement(v) 72 case string: 73 return resvdNameElement(v) 74 case *desc.FieldDescriptor: 75 return (*fieldElement)(v) 76 case *desc.MessageDescriptor: 77 return (*msgElement)(v) 78 case *desc.EnumDescriptor: 79 return (*enumElement)(v) 80 case *desc.EnumValueDescriptor: 81 return (*enumValElement)(v) 82 case *desc.ServiceDescriptor: 83 return (*svcElement)(v) 84 case *desc.MethodDescriptor: 85 return (*methodElement)(v) 86 case *descriptorpb.DescriptorProto_ExtensionRange: 87 return (*extRangeElement)(v) 88 default: 89 panic(fmt.Sprintf("unexpected type of element: %T", v)) 90 } 91 } 92 93 type pkgElement pkg 94 95 var _ Element = pkgElement("") 96 97 func (p pkgElement) Kind() ElementKind { 98 return KindPackage 99 } 100 101 func (p pkgElement) Name() string { 102 return string(p) 103 } 104 105 func (p pkgElement) Number() int32 { 106 return 0 107 } 108 109 func (p pkgElement) NumberRange() (int32, int32) { 110 return 0, 0 111 } 112 113 func (p pkgElement) Extendee() string { 114 return "" 115 } 116 117 func (p pkgElement) IsCustomOption() bool { 118 return false 119 } 120 121 type impElement imp 122 123 var _ Element = impElement("") 124 125 func (i impElement) Kind() ElementKind { 126 return KindImport 127 } 128 129 func (i impElement) Name() string { 130 return string(i) 131 } 132 133 func (i impElement) Number() int32 { 134 return 0 135 } 136 137 func (i impElement) NumberRange() (int32, int32) { 138 return 0, 0 139 } 140 141 func (i impElement) Extendee() string { 142 return "" 143 } 144 145 func (i impElement) IsCustomOption() bool { 146 return false 147 } 148 149 type optionElement option 150 151 var _ Element = (*optionElement)(nil) 152 153 func (o *optionElement) Kind() ElementKind { 154 return KindOption 155 } 156 157 func (o *optionElement) Name() string { 158 if strings.HasPrefix(o.name, "(") { 159 // remove parentheses 160 return o.name[1 : len(o.name)-1] 161 } 162 return o.name 163 } 164 165 func (o *optionElement) Number() int32 { 166 return 0 167 } 168 169 func (o *optionElement) NumberRange() (int32, int32) { 170 return 0, 0 171 } 172 173 func (o *optionElement) Extendee() string { 174 return "" 175 } 176 177 func (o *optionElement) IsCustomOption() bool { 178 return strings.HasPrefix(o.name, "(") 179 } 180 181 type resvdRangeElement reservedRange 182 183 var _ Element = resvdRangeElement{} 184 185 func (r resvdRangeElement) Kind() ElementKind { 186 return KindReservedRange 187 } 188 189 func (r resvdRangeElement) Name() string { 190 return "" 191 } 192 193 func (r resvdRangeElement) Number() int32 { 194 return 0 195 } 196 197 func (r resvdRangeElement) NumberRange() (int32, int32) { 198 return r.start, r.end 199 } 200 201 func (r resvdRangeElement) Extendee() string { 202 return "" 203 } 204 205 func (r resvdRangeElement) IsCustomOption() bool { 206 return false 207 } 208 209 type resvdNameElement string 210 211 var _ Element = resvdNameElement("") 212 213 func (r resvdNameElement) Kind() ElementKind { 214 return KindReservedName 215 } 216 217 func (r resvdNameElement) Name() string { 218 return string(r) 219 } 220 221 func (r resvdNameElement) Number() int32 { 222 return 0 223 } 224 225 func (r resvdNameElement) NumberRange() (int32, int32) { 226 return 0, 0 227 } 228 229 func (r resvdNameElement) Extendee() string { 230 return "" 231 } 232 233 func (r resvdNameElement) IsCustomOption() bool { 234 return false 235 } 236 237 type fieldElement desc.FieldDescriptor 238 239 var _ Element = (*fieldElement)(nil) 240 241 func (f *fieldElement) Kind() ElementKind { 242 if (*desc.FieldDescriptor)(f).IsExtension() { 243 return KindExtension 244 } 245 return KindField 246 } 247 248 func (f *fieldElement) Name() string { 249 return (*desc.FieldDescriptor)(f).GetName() 250 } 251 252 func (f *fieldElement) Number() int32 { 253 return (*desc.FieldDescriptor)(f).GetNumber() 254 } 255 256 func (f *fieldElement) NumberRange() (int32, int32) { 257 return 0, 0 258 } 259 260 func (f *fieldElement) Extendee() string { 261 fd := (*desc.FieldDescriptor)(f) 262 if fd.IsExtension() { 263 fd.GetOwner().GetFullyQualifiedName() 264 } 265 return "" 266 } 267 268 func (f *fieldElement) IsCustomOption() bool { 269 return false 270 } 271 272 type msgElement desc.MessageDescriptor 273 274 var _ Element = (*msgElement)(nil) 275 276 func (m *msgElement) Kind() ElementKind { 277 return KindMessage 278 } 279 280 func (m *msgElement) Name() string { 281 return (*desc.MessageDescriptor)(m).GetName() 282 } 283 284 func (m *msgElement) Number() int32 { 285 return 0 286 } 287 288 func (m *msgElement) NumberRange() (int32, int32) { 289 return 0, 0 290 } 291 292 func (m *msgElement) Extendee() string { 293 return "" 294 } 295 296 func (m *msgElement) IsCustomOption() bool { 297 return false 298 } 299 300 type enumElement desc.EnumDescriptor 301 302 var _ Element = (*enumElement)(nil) 303 304 func (e *enumElement) Kind() ElementKind { 305 return KindEnum 306 } 307 308 func (e *enumElement) Name() string { 309 return (*desc.EnumDescriptor)(e).GetName() 310 } 311 312 func (e *enumElement) Number() int32 { 313 return 0 314 } 315 316 func (e *enumElement) NumberRange() (int32, int32) { 317 return 0, 0 318 } 319 320 func (e *enumElement) Extendee() string { 321 return "" 322 } 323 324 func (e *enumElement) IsCustomOption() bool { 325 return false 326 } 327 328 type enumValElement desc.EnumValueDescriptor 329 330 var _ Element = (*enumValElement)(nil) 331 332 func (e *enumValElement) Kind() ElementKind { 333 return KindEnumValue 334 } 335 336 func (e *enumValElement) Name() string { 337 return (*desc.EnumValueDescriptor)(e).GetName() 338 } 339 340 func (e *enumValElement) Number() int32 { 341 return (*desc.EnumValueDescriptor)(e).GetNumber() 342 } 343 344 func (e *enumValElement) NumberRange() (int32, int32) { 345 return 0, 0 346 } 347 348 func (e *enumValElement) Extendee() string { 349 return "" 350 } 351 352 func (e *enumValElement) IsCustomOption() bool { 353 return false 354 } 355 356 type svcElement desc.ServiceDescriptor 357 358 var _ Element = (*svcElement)(nil) 359 360 func (s *svcElement) Kind() ElementKind { 361 return KindService 362 } 363 364 func (s *svcElement) Name() string { 365 return (*desc.ServiceDescriptor)(s).GetName() 366 } 367 368 func (s *svcElement) Number() int32 { 369 return 0 370 } 371 372 func (s *svcElement) NumberRange() (int32, int32) { 373 return 0, 0 374 } 375 376 func (s *svcElement) Extendee() string { 377 return "" 378 } 379 380 func (s *svcElement) IsCustomOption() bool { 381 return false 382 } 383 384 type methodElement desc.MethodDescriptor 385 386 var _ Element = (*methodElement)(nil) 387 388 func (m *methodElement) Kind() ElementKind { 389 return KindMethod 390 } 391 392 func (m *methodElement) Name() string { 393 return (*desc.MethodDescriptor)(m).GetName() 394 } 395 396 func (m *methodElement) Number() int32 { 397 return 0 398 } 399 400 func (m *methodElement) NumberRange() (int32, int32) { 401 return 0, 0 402 } 403 404 func (m *methodElement) Extendee() string { 405 return "" 406 } 407 408 func (m *methodElement) IsCustomOption() bool { 409 return false 410 } 411 412 type extRangeElement descriptorpb.DescriptorProto_ExtensionRange 413 414 var _ Element = (*extRangeElement)(nil) 415 416 func (e *extRangeElement) Kind() ElementKind { 417 return KindExtensionRange 418 } 419 420 func (e *extRangeElement) Name() string { 421 return "" 422 } 423 424 func (e *extRangeElement) Number() int32 { 425 return 0 426 } 427 428 func (e *extRangeElement) NumberRange() (int32, int32) { 429 ext := (*descriptorpb.DescriptorProto_ExtensionRange)(e) 430 return ext.GetStart(), ext.GetEnd() 431 } 432 433 func (e *extRangeElement) Extendee() string { 434 return "" 435 } 436 437 func (e *extRangeElement) IsCustomOption() bool { 438 return false 439 }