in codegen/type_converter.go [163:265]
func (c *TypeConverter) genConverterForStruct(
toFieldName string,
toFieldType *compile.StructSpec,
toRequired bool,
fromFieldType compile.TypeSpec,
fromIdentifier string,
keyPrefix string,
fromPrefix string,
indent string,
fieldMap map[string]FieldMapperEntry,
prevKeyPrefixes []string,
) error {
toIdentifier := "out"
if keyPrefix != "" {
toIdentifier += "." + keyPrefix
}
typeName, _ := c.getIdentifierName(toFieldType)
subToFields := toFieldType.Fields
// if no fromFieldType assume we're constructing from transform fieldMap TODO: make this less subtle
if fromFieldType == nil {
// in the direct assignment we do a nil check on fromField here. its hard for unknown number of transforms
// initialize the toField with an empty struct only if it's required, otherwise send to uninitialized map
if toRequired {
c.append(indent, toIdentifier, " = &", typeName, "{}")
} else {
id := "out"
if c.useRecurGen {
id = "outOriginal"
}
if keyPrefix != "" {
id += "." + keyPrefix
}
c.uninitialized[id] = &fieldStruct{
Identifier: id,
TypeName: typeName,
}
}
if keyPrefix != "" {
keyPrefix += "."
}
// if fromPrefix != "" {
// fromPrefix += "."
// }
// recursive call
err := c.genStructConverter(
keyPrefix,
fromPrefix,
indent,
nil,
subToFields,
fieldMap,
prevKeyPrefixes,
)
if err != nil {
return err
}
return nil
}
fromFieldStruct, ok := fromFieldType.(*compile.StructSpec)
if !ok {
return errors.Errorf(
"could not convert struct fields, "+
"incompatible type for %s :",
toFieldName,
)
}
c.append(indent, "if ", fromIdentifier, " != nil {")
c.append(indent, "\t", toIdentifier, " = &", typeName, "{}")
if keyPrefix != "" {
keyPrefix += "."
}
if fromPrefix != "" {
fromPrefix += "."
}
subFromFields := fromFieldStruct.Fields
err := c.genStructConverter(
keyPrefix,
fromPrefix,
indent+"\t",
subFromFields,
subToFields,
fieldMap,
prevKeyPrefixes,
)
if err != nil {
return err
}
c.append(indent, "} else {")
c.append(indent, "\t", toIdentifier, " = nil")
c.append(indent, "}")
return nil
}