gen/data_types.go
func (d *APIDescriptor) FinalizeTypeNames(rawTypes map[string][]*ObjectDataType) {

	// 1. Make sure data type names don't clash with resource names
	rawTypeNames := make([]string, len(rawTypes))
	idx := 0
	for n := range rawTypes {
		rawTypeNames[idx] = n
		idx++
	}
	sort.Strings(rawTypeNames)
	for _, tn := range rawTypeNames {
		types := rawTypes[tn]
		for rn := range d.Resources {
			if tn == rn {
				oldTn := tn
				if strings.HasSuffix(tn, "Param") {
					tn = fmt.Sprintf("%s2", tn)
				} else {
					tn = fmt.Sprintf("%sParam", tn)
				}
				for _, ty := range types {
					ty.TypeName = tn
				}
				rawTypes[tn] = types
				delete(rawTypes, oldTn)
			}
		}
	}

	// 2. Make data type names unique
	idx = 0
	for n := range rawTypes {
		rawTypeNames[idx] = n
		idx++
	}
	sort.Strings(rawTypeNames)
	for _, tn := range rawTypeNames {
		types := rawTypes[tn]
		first := types[0]
		d.Types[tn] = first
		if len(types) > 1 {
			for i, ty := range types[1:] {
				found := false
				for j := 0; j < i+1; j++ {
					if ty.IsEquivalent(types[j]) {
						found = true
						break
					}
				}
				if !found {
					newName := d.uniqueTypeName(tn)
					ty.TypeName = newName
					d.Types[newName] = ty
					d.TypeNames = append(d.TypeNames, newName)
				}
			}
		}
	}

	// 3. Finally initialize .ResourceNames and .TypeNames
	idx = 0
	resourceNames := make([]string, len(d.Resources))
	for n := range d.Resources {
		resourceNames[idx] = n
		idx++
	}
	sort.Strings(resourceNames)
	d.ResourceNames = resourceNames

	typeNames := make([]string, len(d.Types))
	idx = 0
	for tn := range d.Types {
		typeNames[idx] = tn
		idx++
	}
	sort.Strings(typeNames)
	d.TypeNames = typeNames
}
func (d *APIDescriptor) FinalizeTypeNames(rawTypes map[string][]*ObjectDataType) {

	// 1. Make sure data type names don't clash with resource names
	rawTypeNames := make([]string, len(rawTypes))
	idx := 0
	for n := range rawTypes {
		rawTypeNames[idx] = n
		idx++
	}
	sort.Strings(rawTypeNames)
	for _, tn := range rawTypeNames {
		types := rawTypes[tn]
		for rn := range d.Resources {
			if tn == rn {
				oldTn := tn
				if strings.HasSuffix(tn, "Param") {
					tn = fmt.Sprintf("%s2", tn)
				} else {
					tn = fmt.Sprintf("%sParam", tn)
				}
				for _, ty := range types {
					ty.TypeName = tn
				}
				rawTypes[tn] = types
				delete(rawTypes, oldTn)
			}
		}
	}

	// 2. Make data type names unique
	idx = 0
	for n := range rawTypes {
		rawTypeNames[idx] = n
		idx++
	}
	sort.Strings(rawTypeNames)
	for _, tn := range rawTypeNames {
		types := rawTypes[tn]
		first := types[0]
		d.Types[tn] = first
		if len(types) > 1 {
			for i, ty := range types[1:] {
				found := false
				for j := 0; j < i+1; j++ {
					if ty.IsEquivalent(types[j]) {
						found = true
						break
					}
				}
				if !found {
					newName := d.uniqueTypeName(tn)
					ty.TypeName = newName
					d.Types[newName] = ty
					d.TypeNames = append(d.TypeNames, newName)
				}
			}
		}
	}

	// 3. Finally initialize .ResourceNames and .TypeNames
	idx = 0
	resourceNames := make([]string, len(d.Resources))
	for n := range d.Resources {
		resourceNames[idx] = n
		idx++
	}
	sort.Strings(resourceNames)
	d.ResourceNames = resourceNames

	typeNames := make([]string, len(d.Types))
	idx = 0
	for tn := range d.Types {
		typeNames[idx] = tn
		idx++
	}
	sort.Strings(typeNames)
	d.TypeNames = typeNames
}
// FinalizeTypeNames goes through all the types generated by the analyzer and generate unique names.