in internal/objectstore/objectstore.go [65:118]
func (o *ObjectStore) Register(value reflect.Value, objectRef api.ObjectRef) error {
var err error
if value, err = canonicalValue(value); err != nil {
return err
}
ptr := value.Pointer()
if existing, found := o.objectToID[ptr]; found {
if existing == objectRef.InstanceID {
o.mergeInterfaces(objectRef)
return nil
}
return fmt.Errorf("attempting to register %v as %v, but it was already registered as %v", value, objectRef.InstanceID, existing)
}
aliases := findAliases(value)
if existing, found := o.idToObjects[objectRef.InstanceID]; found {
if _, found := existing[value]; found {
o.mergeInterfaces(objectRef)
return nil
}
// Value already exists (e.g: a constructor made a callback with "this"
// passed as an argument). We make the current value(s) an alias of the new
// one.
for existing := range existing {
aliases = append(aliases, existing)
}
}
for _, alias := range aliases {
ptr := alias.Pointer()
if existing, found := o.objectToID[ptr]; found && existing != objectRef.InstanceID {
return fmt.Errorf("value %v is embedded in %v which has ID %v, but was already assigned %v", alias.String(), value.String(), objectRef.InstanceID, existing)
}
}
o.objectToID[ptr] = objectRef.InstanceID
// Only add to idToObject if this is the first time this InstanceID is registered
if _, found := o.idToObject[objectRef.InstanceID]; !found {
o.idToObject[objectRef.InstanceID] = value
}
if _, found := o.idToObjects[objectRef.InstanceID]; !found {
o.idToObjects[objectRef.InstanceID] = make(map[reflect.Value]struct{})
}
o.idToObjects[objectRef.InstanceID][value] = struct{}{}
for _, alias := range aliases {
o.objectToID[alias.Pointer()] = objectRef.InstanceID
}
o.mergeInterfaces(objectRef)
return nil
}