func goModelName()

in codegen/templates/templates.go [288:377]


func goModelName(primaryToGoFunc func(string) string, parts []string) string {
	modelNamesMu.Lock()
	defer modelNamesMu.Unlock()

	var (
		goNameKey string
		partLen   int

		nameExists = func(n string) bool {
			for _, v := range modelNames {
				if n == v {
					return true
				}
			}
			return false
		}

		applyToGoFunc = func(parts []string) string {
			var out string
			switch len(parts) {
			case 0:
				return ""
			case 1:
				return primaryToGoFunc(parts[0])
			default:
				out = primaryToGoFunc(parts[0])
			}
			for _, p := range parts[1:] {
				out = fmt.Sprintf("%s%s", out, ToGo(p))
			}
			return out
		}

		applyValidGoName = func(parts []string) string {
			var out string
			for _, p := range parts {
				out = fmt.Sprintf("%s%s", out, replaceInvalidCharacters(p))
			}
			return out
		}
	)

	// build key for this entity
	goNameKey = buildGoModelNameKey(parts)

	// determine if we've seen this entity before, and reuse if so
	if goName, ok := modelNames[goNameKey]; ok {
		return goName
	}

	// attempt first pass
	if goName := applyToGoFunc(parts); !nameExists(goName) {
		modelNames[goNameKey] = goName
		return goName
	}

	// determine number of parts
	partLen = len(parts)

	// if there is only 1 part, append incrementing number until no conflict
	if partLen == 1 {
		base := applyToGoFunc(parts)
		for i := 0; ; i++ {
			tmp := fmt.Sprintf("%s%d", base, i)
			if !nameExists(tmp) {
				modelNames[goNameKey] = tmp
				return tmp
			}
		}
	}

	// best effort "pretty" name
	for i := partLen - 1; i >= 1; i-- {
		tmp := fmt.Sprintf("%s%s", applyToGoFunc(parts[0:i]), applyValidGoName(parts[i:]))
		if !nameExists(tmp) {
			modelNames[goNameKey] = tmp
			return tmp
		}
	}

	// finally, fallback to just adding an incrementing number
	base := applyToGoFunc(parts)
	for i := 0; ; i++ {
		tmp := fmt.Sprintf("%s%d", base, i)
		if !nameExists(tmp) {
			modelNames[goNameKey] = tmp
			return tmp
		}
	}
}