From a4371358766ec8f356d09e36984c69572ad48515 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 8 Aug 2016 17:24:03 -0700 Subject: [PATCH] Only instantiate nil struct pointers that are used unpackProperties was instantiating all nil struct pointers in any struct that had a property set. Check if the property is set first, and only instantiate the struct if it was set. This has a slight behavioral change, as now structures that only exist through nil pointers and are never set into will not be type-checked. This should be fixed in a later patch set that moves the type checking to be done across all property structs once per factory before blueprint files are loaded. Change-Id: I0dea34d7fff76bb4fc907516a2d996e4ea2408d6 --- unpack.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/unpack.go b/unpack.go index 3580eff..0c4ca61 100644 --- a/unpack.go +++ b/unpack.go @@ -139,10 +139,15 @@ func unpackStructValue(namePrefix string, structValue reflect.Value, panic(fmt.Errorf("field %s is not settable", propertyName)) } + // Get the property value if it was specified. + packedProperty, propertyIsSet := propertyMap[propertyName] + origFieldValue := fieldValue // To make testing easier we validate the struct field's type regardless // of whether or not the property was specified in the parsed string. + // TODO(ccross): we don't validate types inside nil struct pointers + // Move type validation to a function that runs on each factory once switch kind := fieldValue.Kind(); kind { case reflect.Bool, reflect.String, reflect.Struct: // Do nothing @@ -164,7 +169,10 @@ func unpackStructValue(namePrefix string, structValue reflect.Value, case reflect.Ptr: switch ptrKind := fieldValue.Type().Elem().Kind(); ptrKind { case reflect.Struct: - if fieldValue.IsNil() { + if fieldValue.IsNil() && (propertyIsSet || field.Anonymous) { + // Instantiate nil struct pointers + // Set into origFieldValue in case it was an interface, in which case + // fieldValue points to the unsettable pointer inside the interface fieldValue = reflect.New(fieldValue.Type().Elem()) origFieldValue.Set(fieldValue) } @@ -190,9 +198,7 @@ func unpackStructValue(namePrefix string, structValue reflect.Value, continue } - // Get the property value if it was specified. - packedProperty, ok := propertyMap[propertyName] - if !ok { + if !propertyIsSet { // This property wasn't specified. continue } -- GitLab