Skip to content

Commit eb0b788

Browse files
authored
Make reflect resource utility friendly with Go SDK (#2051)
* Add reflect from struct * disable omitempty check for Go SDK types
1 parent 696061f commit eb0b788

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

common/reflect_resource.go

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,25 @@ func typeToSchema(v reflect.Value, t reflect.Type, path []string) map[string]*sc
254254
scm[fieldName].Type = schema.TypeList
255255
elem := typeField.Type.Elem()
256256
sv := reflect.New(elem).Elem()
257+
nestedSchema := typeToSchema(sv, elem, append(path, fieldName, "0"))
258+
if strings.Contains(tfTag, "suppress_diff") {
259+
blockCount := strings.Join(append(path, fieldName, "#"), ".")
260+
scm[fieldName].DiffSuppressFunc = makeEmptyBlockSuppressFunc(blockCount)
261+
for _, v := range nestedSchema {
262+
// to those relatively new to GoLang: we must explicitly pass down v by copy
263+
v.DiffSuppressFunc = diffSuppressor(fmt.Sprintf("%v", v.Type.Zero()))
264+
}
265+
}
266+
scm[fieldName].Elem = &schema.Resource{
267+
Schema: nestedSchema,
268+
}
269+
case reflect.Struct:
270+
scm[fieldName].MaxItems = 1
271+
scm[fieldName].Type = schema.TypeList
272+
273+
elem := typeField.Type // changed from ptr
274+
sv := reflect.New(elem) // changed from ptr
275+
257276
nestedSchema := typeToSchema(sv, elem, append(path, fieldName, "0"))
258277
if strings.Contains(tfTag, "suppress_diff") {
259278
blockCount := strings.Join(append(path, fieldName, "#"), ".")
@@ -304,6 +323,7 @@ func iterFields(rv reflect.Value, path []string, s map[string]*schema.Schema,
304323
if !rv.IsValid() {
305324
return fmt.Errorf("%s: got invalid reflect value %#v", path, rv)
306325
}
326+
isGoSDK := strings.Contains(rv.Type().PkgPath(), "databricks-sdk-go")
307327
for i := 0; i < rv.NumField(); i++ {
308328
typeField := rv.Type().Field(i)
309329
fieldName := chooseFieldName(typeField)
@@ -315,7 +335,8 @@ func iterFields(rv reflect.Value, path []string, s map[string]*schema.Schema,
315335
continue
316336
}
317337
omitEmpty := isOptional(typeField)
318-
if omitEmpty && !fieldSchema.Optional {
338+
// TODO: fix in https://github.com/databricks/databricks-sdk-go/issues/268
339+
if !isGoSDK && omitEmpty && !fieldSchema.Optional {
319340
return fmt.Errorf("inconsistency: %s has omitempty, but is not optional", fieldName)
320341
}
321342
defaultEmpty := reflect.ValueOf(fieldSchema.Default).Kind() == reflect.Invalid
@@ -610,6 +631,20 @@ func readListFromData(path []string, d attributeGetter,
610631
nestedResource := fieldSchema.Elem.(*schema.Resource)
611632
nestedPath := append(path, offsetConverter(0))
612633
return readReflectValueFromData(nestedPath, d, ve, nestedResource.Schema)
634+
case reflect.Struct:
635+
// code path for setting the struct value is different from pointer value
636+
// in a single way: we set the field only after readReflectValueFromData
637+
// traversed the graph.
638+
vstruct := reflect.New(valueField.Type())
639+
ve := vstruct.Elem()
640+
nestedResource := fieldSchema.Elem.(*schema.Resource)
641+
nestedPath := append(path, offsetConverter(0))
642+
err := readReflectValueFromData(nestedPath, d, ve, nestedResource.Schema)
643+
if err != nil {
644+
return err
645+
}
646+
valueField.Set(ve)
647+
return nil
613648
case reflect.Slice:
614649
k := valueField.Type().Elem().Kind()
615650
newSlice := reflect.MakeSlice(valueField.Type(), len(rawList), len(rawList))

0 commit comments

Comments
 (0)