vendor/github.com/golang/protobuf/proto/extensions.go
changeset 251 1c52a0eeb952
parent 242 2a9ec03fe5a1
child 256 6d9efbef00a9
equal deleted inserted replaced
250:c040f992052f 251:1c52a0eeb952
   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 }