func (v *versionComparer) isPreviewVersionLabel(identifier string) (int, bool) {
	for rank, id := range previewVersionLabels {
		if identifier == id {
			return rank, true
		}
	}
	return -1, false
}
isPreviewVersionLabel checks the passed identifier to see if it is one of our special set, and
if so returns its rank and true. If the passed identifier is not special, returns -1 and false.
package astmodel
import (
	"sort"
	"strings"
	"unicode"
	"github.com/pkg/errors"
)
const (
	genRuntimePathPrefix  = "github.com/Azure/k8s-infra/hack/generated/pkg/genruntime"
	GenRuntimePackageName = "genruntime"
	GroupSuffix           = ".infra.azure.com"
)
var MetaV1PackageReference = MakeExternalPackageReference("k8s.io/apimachinery/pkg/apis/meta/v1")
type PackageReference interface {
	AsLocalPackage() (LocalPackageReference, bool)
	PackageName() string
	PackagePath() string
	Equals(ref PackageReference) bool
	String() string
	IsPreview() bool
}
func PackageAsLocalPackage(pkg PackageReference) (LocalPackageReference, error) {
	if localPkg, ok := pkg.AsLocalPackage(); ok {
		return localPkg, nil
	}
	return LocalPackageReference{}, errors.Errorf("%q is not a local package", pkg.PackagePath())
}
func SortPackageReferencesByPathAndVersion(packages []PackageReference) {
	sort.Slice(packages, func(i, j int) bool {
		comparer := versionComparer{
			left:  []rune(packages[i].PackagePath()),
			right: []rune(packages[j].PackagePath()),
		}
		compare := comparer.Compare()
		return compare < 0
	})
}
type versionComparer struct {
	left       []rune
	leftIndex  int
	right      []rune
	rightIndex int
}
func (v *versionComparer) Compare() int {
	for {
		if v.leftIndex >= len(v.left) && v.rightIndex >= len(v.right) {
			break
		}
		if v.leftIndex >= len(v.left) {
			if unicode.IsLetter(v.right[v.rightIndex]) {
				return 1
			}
			return -1
		}
		if v.rightIndex >= len(v.right) {
			if unicode.IsLetter(v.left[v.leftIndex]) {
				return -1
			}
			return 1
		}
		leftRune := v.left[v.leftIndex]
		rightRune := v.right[v.rightIndex]
		if unicode.IsDigit(leftRune) && unicode.IsDigit(rightRune) {
			compare := v.compareNumeric()
			if compare != 0 {
				return compare
			}
			continue
		}
		if unicode.IsLetter(leftRune) && unicode.IsLetter(rightRune) {
			compare := v.compareIdentifier()
			if compare != 0 {
				return compare
			}
			continue
		}
		if leftRune == rightRune {
			v.leftIndex++
			v.rightIndex++
			continue
		}
		if leftRune < rightRune {
			return -1
		} else {
			return 1
		}
	}
	return 0
}
func (v *versionComparer) compareNumeric() int {
	v.leftIndex = v.endOfSpan(v.left, v.leftIndex, v.IsZero)
	v.rightIndex = v.endOfSpan(v.right, v.rightIndex, v.IsZero)
	leftLength := v.endOfSpan(v.left, v.leftIndex, unicode.IsDigit) - v.leftIndex
	rightLength := v.endOfSpan(v.right, v.rightIndex, unicode.IsDigit) - v.rightIndex
	if leftLength > rightLength {
		return 1
	} else if leftLength < rightLength {
		return -1
	}
	length := leftLength
	for length > 0 {
		if v.left[v.leftIndex] != v.right[v.rightIndex] {
			break
		}
		v.leftIndex++
		v.rightIndex++
		length--
	}
	if length == 0 {
		return 0
	}
	if v.left[v.leftIndex] < v.right[v.rightIndex] {
		return -1
	}
	return 1
}
func (v *versionComparer) compareIdentifier() int {
	leftEnd := v.endOfSpan(v.left, v.leftIndex, unicode.IsLetter)
	rightEnd := v.endOfSpan(v.right, v.rightIndex, unicode.IsLetter)
	left := string(v.left[v.leftIndex:leftEnd])
	right := string(v.right[v.rightIndex:rightEnd])
	if left == right {
		v.leftIndex = leftEnd
		v.rightIndex = rightEnd
		return 0
	}
	leftRank, leftIsSpecial := v.isPreviewVersionLabel(left)
	rightRank, rightIsSpecial := v.isPreviewVersionLabel(right)
	if leftIsSpecial && rightIsSpecial {
		if leftRank < rightRank {
			return -1
		}
		return 1
	}
	if leftIsSpecial {
		return -1
	}
	if rightIsSpecial {
		return 1
	}
	if left < right {
		return -1
	}
	return 1
}
func (v *versionComparer) endOfSpan(runes []rune, start int, predicate func(rune) bool) int {
	index := start
	for index < len(runes) {
		if !predicate(runes[index]) {
			break
		}
		index++
	}
	return index
}
func (v *versionComparer) IsZero(r rune) bool {
	return r == '0'
}
var previewVersionLabels []string = []string{
	"alpha",
	"beta",
	"preview",
}