GetExtension retrieves a proto2 extended field from m. If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil), then GetExtension parses the encoded field and returns a Go value of the specified type. If the field is not present, then the default value is returned (if one
(m Message, xt *ExtensionDesc)
| 118 | // If the descriptor is type incomplete (i.e., ExtensionDesc.ExtensionType is nil), |
| 119 | // then GetExtension returns the raw encoded bytes for the extension field. |
| 120 | func GetExtension(m Message, xt *ExtensionDesc) (interface{}, error) { |
| 121 | mr := MessageReflect(m) |
| 122 | if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { |
| 123 | return nil, errNotExtendable |
| 124 | } |
| 125 | |
| 126 | // Retrieve the unknown fields for this extension field. |
| 127 | var bo protoreflect.RawFields |
| 128 | for bi := mr.GetUnknown(); len(bi) > 0; { |
| 129 | num, _, n := protowire.ConsumeField(bi) |
| 130 | if int32(num) == xt.Field { |
| 131 | bo = append(bo, bi[:n]...) |
| 132 | } |
| 133 | bi = bi[n:] |
| 134 | } |
| 135 | |
| 136 | // For type incomplete descriptors, only retrieve the unknown fields. |
| 137 | if xt.ExtensionType == nil { |
| 138 | return []byte(bo), nil |
| 139 | } |
| 140 | |
| 141 | // If the extension field only exists as unknown fields, unmarshal it. |
| 142 | // This is rarely done since proto.Unmarshal eagerly unmarshals extensions. |
| 143 | xtd := xt.TypeDescriptor() |
| 144 | if !isValidExtension(mr.Descriptor(), xtd) { |
| 145 | return nil, fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m) |
| 146 | } |
| 147 | if !mr.Has(xtd) && len(bo) > 0 { |
| 148 | m2 := mr.New() |
| 149 | if err := (proto.UnmarshalOptions{ |
| 150 | Resolver: extensionResolver{xt}, |
| 151 | }.Unmarshal(bo, m2.Interface())); err != nil { |
| 152 | return nil, err |
| 153 | } |
| 154 | if m2.Has(xtd) { |
| 155 | mr.Set(xtd, m2.Get(xtd)) |
| 156 | clearUnknown(mr, fieldNum(xt.Field)) |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | // Check whether the message has the extension field set or a default. |
| 161 | var pv protoreflect.Value |
| 162 | switch { |
| 163 | case mr.Has(xtd): |
| 164 | pv = mr.Get(xtd) |
| 165 | case xtd.HasDefault(): |
| 166 | pv = xtd.Default() |
| 167 | default: |
| 168 | return nil, ErrMissingExtension |
| 169 | } |
| 170 | |
| 171 | v := xt.InterfaceOf(pv) |
| 172 | rv := reflect.ValueOf(v) |
| 173 | if isScalarKind(rv.Kind()) { |
| 174 | rv2 := reflect.New(rv.Type()) |
| 175 | rv2.Elem().Set(rv) |
| 176 | v = rv2.Interface() |
| 177 | } |