ExtensionDescs returns a list of extension descriptors found in m, containing descriptors for both populated extension fields in m and also unknown fields of m that are in the extension range. For the later case, an type incomplete descriptor is provided where only the ExtensionDesc.Field field is p
(m Message)
| 277 | // the ExtensionDesc.Field field is populated. |
| 278 | // The order of the extension descriptors is undefined. |
| 279 | func ExtensionDescs(m Message) ([]*ExtensionDesc, error) { |
| 280 | mr := MessageReflect(m) |
| 281 | if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { |
| 282 | return nil, errNotExtendable |
| 283 | } |
| 284 | |
| 285 | // Collect a set of known extension descriptors. |
| 286 | extDescs := make(map[protoreflect.FieldNumber]*ExtensionDesc) |
| 287 | mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { |
| 288 | if fd.IsExtension() { |
| 289 | xt := fd.(protoreflect.ExtensionTypeDescriptor) |
| 290 | if xd, ok := xt.Type().(*ExtensionDesc); ok { |
| 291 | extDescs[fd.Number()] = xd |
| 292 | } |
| 293 | } |
| 294 | return true |
| 295 | }) |
| 296 | |
| 297 | // Collect a set of unknown extension descriptors. |
| 298 | extRanges := mr.Descriptor().ExtensionRanges() |
| 299 | for b := mr.GetUnknown(); len(b) > 0; { |
| 300 | num, _, n := protowire.ConsumeField(b) |
| 301 | if extRanges.Has(num) && extDescs[num] == nil { |
| 302 | extDescs[num] = nil |
| 303 | } |
| 304 | b = b[n:] |
| 305 | } |
| 306 | |
| 307 | // Transpose the set of descriptors into a list. |
| 308 | var xts []*ExtensionDesc |
| 309 | for num, xt := range extDescs { |
| 310 | if xt == nil { |
| 311 | xt = &ExtensionDesc{Field: int32(num)} |
| 312 | } |
| 313 | xts = append(xts, xt) |
| 314 | } |
| 315 | return xts, nil |
| 316 | } |
| 317 | |
| 318 | // isValidExtension reports whether xtd is a valid extension descriptor for md. |
| 319 | func isValidExtension(md protoreflect.MessageDescriptor, xtd protoreflect.ExtensionTypeDescriptor) bool { |