fix: support saving custom types that implements PropertyLoadSaver (#2794)



Co-authored-by: Chris Cotter <cjcotter@google.com>
diff --git a/datastore/save.go b/datastore/save.go
index 7b9e24c..08874ad 100644
--- a/datastore/save.go
+++ b/datastore/save.go
@@ -138,6 +138,17 @@
 		}
 	}
 
+	if v.CanAddr() {
+		vi := v.Addr().Interface()
+		if pSaver, ok := vi.(PropertyLoadSaver); ok {
+			val, err := pSaver.Save()
+			if err != nil {
+				return fmt.Errorf("field save error: %v", err)
+			}
+			p.Value = val
+		}
+	}
+
 	if p.Value == nil {
 		return fmt.Errorf("datastore: unsupported struct field type: %v", v.Type())
 	}
diff --git a/datastore/save_test.go b/datastore/save_test.go
index ca16036..ac52f7c 100644
--- a/datastore/save_test.go
+++ b/datastore/save_test.go
@@ -288,6 +288,24 @@
 	}
 }
 
+// Map is used by TestSaveFieldsWithInterface
+// to test a custom type property save.
+type Map map[int]int
+
+func (*Map) Load(_ []Property) error {
+	return nil
+}
+
+func (*Map) Save() ([]Property, error) {
+	return []Property{}, nil
+}
+
+// Struct is used by TestSaveFieldsWithInterface
+// to test a custom type property save.
+type Struct struct {
+	Map Map
+}
+
 func TestSaveFieldsWithInterface(t *testing.T) {
 	// We should be able to extract the underlying value behind an interface.
 	// See issue https://github.com/googleapis/google-cloud-go/issues/1474.
@@ -347,6 +365,13 @@
 			},
 		},
 		{
+			name: "Nil map",
+			in:   &Struct{},
+			want: []Property{
+				{Name: "Map", Value: []Property{}},
+			},
+		},
+		{
 			name: "Nested",
 			in: &n3{
 				N2: &n2{