func()

in codegen/type_converter.go [440:641]


func (c *TypeConverter) genConverterForMap(
	toField toFieldParam,
	fromField fromFieldParam,
	overriddenField overriddenFieldParam,
	indent string,
) error {
	toFieldType := toField.Type.(*compile.MapSpec)

	typeName, err := c.getGoTypeName(toFieldType.ValueSpec)
	if err != nil {
		return err
	}

	valueStruct, isStruct := compile.RootTypeSpec(toFieldType.ValueSpec).(*compile.StructSpec)
	valueList, isList := compile.RootTypeSpec(toFieldType.ValueSpec).(*compile.ListSpec)
	valueMap, isMap := compile.RootTypeSpec(toFieldType.ValueSpec).(*compile.MapSpec)
	sourceIdentifier := fromField.ValueIdentifier
	_, isStringKey := toFieldType.KeySpec.(*compile.StringSpec)
	keyType := "string"

	if !isStringKey {
		realType := compile.RootTypeSpec(toFieldType.KeySpec)
		switch realType.(type) {
		case *compile.StringSpec:
			keyType, _ = c.getGoTypeName(toFieldType.KeySpec)
		default:
			return errors.Errorf(
				"could not convert key (%s), map is not string-keyed.", toField.Name)
		}
	}

	checkOverride := false
	sourceListID := ""
	isOverriddenID := ""
	if overriddenField.Identifier != "" {
		sourceListID = c.makeUniqIdentifier("sourceList")
		isOverriddenID = c.makeUniqIdentifier("isOverridden")

		// Determine which map (from or overrride) to use
		c.appendf("%s := %s", sourceListID, overriddenField.Identifier)

		if isStruct {
			c.appendf("%s := false", isOverriddenID)
		}
		// TODO(sindelar): Verify how optional thrift map are defined.
		c.appendf("if %s != nil {", fromField.Identifier)

		c.appendf("\t%s = %s", sourceListID, fromField.Identifier)
		if isStruct {
			c.appendf("\t%s = true", isOverriddenID)
		}
		c.append("}")

		sourceIdentifier = sourceListID
		checkOverride = true
	}
	if isStruct {
		c.appendf(
			"%s = make(map[%s]*%s, len(%s))",
			toField.Identifier, keyType, typeName, sourceIdentifier,
		)
	} else {
		c.appendf(
			"%s = make(map[%s]%s, len(%s))",
			toField.Identifier, keyType, typeName, sourceIdentifier,
		)
	}

	keyID := c.makeUniqIdentifier("key")
	valID := c.makeUniqIdentifier("value")
	c.appendf(
		"for %s, %s := range %s {",
		keyID, valID, sourceIdentifier,
	)

	if isStruct || isList || isMap {
		nestedIndent := "\t" + indent

		fromFieldMapType, ok := compile.RootTypeSpec(fromField.Type).(*compile.MapSpec)
		if !ok {
			return errors.Errorf(
				"Could not convert field (%s): type is not map",
				fromField.Name,
			)
		}

		toFieldKeyID := keyID

		toTypeKeyName := keyType
		fromTypeKeyName, _ := c.getGoTypeName(fromFieldMapType.KeySpec)

		if fromTypeKeyName != toTypeKeyName {
			toFieldKeyID = toTypeKeyName + "(" + keyID + ")"
		}

		if isStruct {
			if checkOverride {
				nestedIndent = "\t" + nestedIndent
				c.appendf("\tif %s {", isOverriddenID)
			}

			err = c.genConverterForStruct(
				toField.Name,
				valueStruct,
				toField.Required,
				fromFieldMapType.ValueSpec,
				valID,
				trimAnyPrefix(toField.Identifier, "out.", "outOriginal.")+"["+toFieldKeyID+"]",
				trimAnyPrefix(fromField.Identifier, "in.", "inOriginal.")+"["+keyID+"]",
				nestedIndent,
				nil,
				nil,
			)
			if err != nil {
				return err
			}

			if checkOverride {
				c.append("\t", "} else {")

				overriddenFieldMapType, ok := overriddenField.Type.(*compile.MapSpec)
				if !ok {
					return errors.Errorf(
						"Could not convert field (%s): type is not map",
						overriddenField.Name,
					)
				}

				err = c.genConverterForStruct(
					toField.Name,
					valueStruct,
					toField.Required,
					overriddenFieldMapType.ValueSpec,
					valID,
					trimAnyPrefix(toField.Identifier, "out.", "outOriginal.")+"["+toFieldKeyID+"]",
					trimAnyPrefix(overriddenField.Identifier, "in.", "inOriginal.")+"["+keyID+"]",
					nestedIndent,
					nil,
					nil,
				)
				if err != nil {
					return err
				}
				c.append("\t", "}")
			}
		} else if isList {
			err = c.genConverterForList(
				toFieldParam{
					valueList,
					toField.Name,
					toField.Required,
					toField.Identifier + "[" + toFieldKeyID + "]",
				},
				fromFieldParam{
					fromFieldMapType.ValueSpec,
					fromField.Name,
					fromField.Identifier + "[" + keyID + "]",
					valID,
				},
				overriddenField,
				nestedIndent)
			if err != nil {
				return err
			}
		} else if isMap {
			err = c.genConverterForMap(
				toFieldParam{
					valueMap,
					toField.Name,
					toField.Required,
					toField.Identifier + "[" + toFieldKeyID + "]",
				},
				fromFieldParam{
					fromFieldMapType.ValueSpec,
					fromField.Name,
					fromField.Identifier + "[" + keyID + "]",
					valID,
				},
				overriddenField,
				nestedIndent)
			if err != nil {
				return err
			}
		}
	} else {
		if keyType == "string" {
			c.appendf(
				"\t%s[%s] = %s(%s)",
				toField.Identifier, keyID, typeName, valID,
			)

		} else {
			c.appendf(
				"\t %s[%s(%s)] = %s(%s)",
				toField.Identifier, keyType, keyID, typeName, valID,
			)
		}
	}

	c.append("}")
	return nil
}