183 // |
183 // |
184 // When a message is unmarshaled and contains extensions, each |
184 // When a message is unmarshaled and contains extensions, each |
185 // extension will have only enc set. When such an extension is |
185 // extension will have only enc set. When such an extension is |
186 // accessed using GetExtension (or GetExtensions) desc and value |
186 // accessed using GetExtension (or GetExtensions) desc and value |
187 // will be set. |
187 // will be set. |
188 desc *ExtensionDesc |
188 desc *ExtensionDesc |
|
189 |
|
190 // value is a concrete value for the extension field. Let the type of |
|
191 // desc.ExtensionType be the "API type" and the type of Extension.value |
|
192 // be the "storage type". The API type and storage type are the same except: |
|
193 // * For scalars (except []byte), the API type uses *T, |
|
194 // while the storage type uses T. |
|
195 // * For repeated fields, the API type uses []T, while the storage type |
|
196 // uses *[]T. |
|
197 // |
|
198 // The reason for the divergence is so that the storage type more naturally |
|
199 // matches what is expected of when retrieving the values through the |
|
200 // protobuf reflection APIs. |
|
201 // |
|
202 // The value may only be populated if desc is also populated. |
189 value interface{} |
203 value interface{} |
190 enc []byte |
204 |
|
205 // enc is the raw bytes for the extension field. |
|
206 enc []byte |
191 } |
207 } |
192 |
208 |
193 // SetRawExtension is for testing only. |
209 // SetRawExtension is for testing only. |
194 func SetRawExtension(base Message, id int32, b []byte) { |
210 func SetRawExtension(base Message, id int32, b []byte) { |
195 epb, err := extendable(base) |
211 epb, err := extendable(base) |
332 // This shouldn't happen. If it does, it means that |
348 // This shouldn't happen. If it does, it means that |
333 // GetExtension was called twice with two different |
349 // GetExtension was called twice with two different |
334 // descriptors with the same field number. |
350 // descriptors with the same field number. |
335 return nil, errors.New("proto: descriptor conflict") |
351 return nil, errors.New("proto: descriptor conflict") |
336 } |
352 } |
337 return e.value, nil |
353 return extensionAsLegacyType(e.value), nil |
338 } |
354 } |
339 |
355 |
340 if extension.ExtensionType == nil { |
356 if extension.ExtensionType == nil { |
341 // incomplete descriptor |
357 // incomplete descriptor |
342 return e.enc, nil |
358 return e.enc, nil |
347 return nil, err |
363 return nil, err |
348 } |
364 } |
349 |
365 |
350 // Remember the decoded version and drop the encoded version. |
366 // Remember the decoded version and drop the encoded version. |
351 // That way it is safe to mutate what we return. |
367 // That way it is safe to mutate what we return. |
352 e.value = v |
368 e.value = extensionAsStorageType(v) |
353 e.desc = extension |
369 e.desc = extension |
354 e.enc = nil |
370 e.enc = nil |
355 emap[extension.Field] = e |
371 emap[extension.Field] = e |
356 return e.value, nil |
372 return extensionAsLegacyType(e.value), nil |
357 } |
373 } |
358 |
374 |
359 // defaultExtensionValue returns the default value for extension. |
375 // defaultExtensionValue returns the default value for extension. |
360 // If no default for an extension is defined ErrMissingExtension is returned. |
376 // If no default for an extension is defined ErrMissingExtension is returned. |
361 func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { |
377 func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { |
486 if err := checkExtensionTypes(epb, extension); err != nil { |
502 if err := checkExtensionTypes(epb, extension); err != nil { |
487 return err |
503 return err |
488 } |
504 } |
489 typ := reflect.TypeOf(extension.ExtensionType) |
505 typ := reflect.TypeOf(extension.ExtensionType) |
490 if typ != reflect.TypeOf(value) { |
506 if typ != reflect.TypeOf(value) { |
491 return errors.New("proto: bad extension value type") |
507 return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType) |
492 } |
508 } |
493 // nil extension values need to be caught early, because the |
509 // nil extension values need to be caught early, because the |
494 // encoder can't distinguish an ErrNil due to a nil extension |
510 // encoder can't distinguish an ErrNil due to a nil extension |
495 // from an ErrNil due to a missing field. Extensions are |
511 // from an ErrNil due to a missing field. Extensions are |
496 // always optional, so the encoder would just swallow the error |
512 // always optional, so the encoder would just swallow the error |
498 if reflect.ValueOf(value).IsNil() { |
514 if reflect.ValueOf(value).IsNil() { |
499 return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) |
515 return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) |
500 } |
516 } |
501 |
517 |
502 extmap := epb.extensionsWrite() |
518 extmap := epb.extensionsWrite() |
503 extmap[extension.Field] = Extension{desc: extension, value: value} |
519 extmap[extension.Field] = Extension{desc: extension, value: extensionAsStorageType(value)} |
504 return nil |
520 return nil |
505 } |
521 } |
506 |
522 |
507 // ClearAllExtensions clears all extensions from pb. |
523 // ClearAllExtensions clears all extensions from pb. |
508 func ClearAllExtensions(pb Message) { |
524 func ClearAllExtensions(pb Message) { |
539 // protocol buffer struct, indexed by the extension number. |
555 // protocol buffer struct, indexed by the extension number. |
540 // The argument pb should be a nil pointer to the struct type. |
556 // The argument pb should be a nil pointer to the struct type. |
541 func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { |
557 func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { |
542 return extensionMaps[reflect.TypeOf(pb).Elem()] |
558 return extensionMaps[reflect.TypeOf(pb).Elem()] |
543 } |
559 } |
|
560 |
|
561 // extensionAsLegacyType converts an value in the storage type as the API type. |
|
562 // See Extension.value. |
|
563 func extensionAsLegacyType(v interface{}) interface{} { |
|
564 switch rv := reflect.ValueOf(v); rv.Kind() { |
|
565 case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: |
|
566 // Represent primitive types as a pointer to the value. |
|
567 rv2 := reflect.New(rv.Type()) |
|
568 rv2.Elem().Set(rv) |
|
569 v = rv2.Interface() |
|
570 case reflect.Ptr: |
|
571 // Represent slice types as the value itself. |
|
572 switch rv.Type().Elem().Kind() { |
|
573 case reflect.Slice: |
|
574 if rv.IsNil() { |
|
575 v = reflect.Zero(rv.Type().Elem()).Interface() |
|
576 } else { |
|
577 v = rv.Elem().Interface() |
|
578 } |
|
579 } |
|
580 } |
|
581 return v |
|
582 } |
|
583 |
|
584 // extensionAsStorageType converts an value in the API type as the storage type. |
|
585 // See Extension.value. |
|
586 func extensionAsStorageType(v interface{}) interface{} { |
|
587 switch rv := reflect.ValueOf(v); rv.Kind() { |
|
588 case reflect.Ptr: |
|
589 // Represent slice types as the value itself. |
|
590 switch rv.Type().Elem().Kind() { |
|
591 case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: |
|
592 if rv.IsNil() { |
|
593 v = reflect.Zero(rv.Type().Elem()).Interface() |
|
594 } else { |
|
595 v = rv.Elem().Interface() |
|
596 } |
|
597 } |
|
598 case reflect.Slice: |
|
599 // Represent slice types as a pointer to the value. |
|
600 if rv.Type().Elem().Kind() != reflect.Uint8 { |
|
601 rv2 := reflect.New(rv.Type()) |
|
602 rv2.Elem().Set(rv) |
|
603 v = rv2.Interface() |
|
604 } |
|
605 } |
|
606 return v |
|
607 } |