MCPcopy
hub / github.com/golang/protobuf / GetExtension

Function GetExtension

proto/extensions.go:120–179  ·  view source on GitHub ↗

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)

Source from the content-addressed store, hash-verified

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.
120func 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 }

Callers 9

TestGetExtensionDefaultsFunction · 0.92
TestNilMessageFunction · 0.92
TestExtensionsRoundTripFunction · 0.92
TestCloneFunction · 0.92
GetExtensionsFunction · 0.85

Calls 12

MessageReflectFunction · 0.85
isValidExtensionFunction · 0.85
clearUnknownFunction · 0.85
fieldNumTypeAlias · 0.85
isScalarKindFunction · 0.85
HasMethod · 0.80
InterfaceMethod · 0.80
TypeMethod · 0.80
DescriptorMethod · 0.65
UnmarshalMethod · 0.65
LenMethod · 0.45
NewMethod · 0.45

Tested by 8

TestGetExtensionDefaultsFunction · 0.74
TestNilMessageFunction · 0.74
TestExtensionsRoundTripFunction · 0.74
TestCloneFunction · 0.74