label/label.go
func Parse(s string) (Label, error) {
	origStr := s

	relative := true
	var repo string
	if strings.HasPrefix(s, "@") {
		relative = false
		endRepo := strings.Index(s, "//")
		if endRepo < 0 {
			return NoLabel, fmt.Errorf("label parse error: repository does not end with '//': %q", origStr)
		}
		repo = s[len("@"):endRepo]
		if !labelRepoRegexp.MatchString(repo) {
			return NoLabel, fmt.Errorf("label parse error: repository has invalid characters: %q", origStr)
		}
		s = s[endRepo:]
	}

	var pkg string
	if strings.HasPrefix(s, "//") {
		relative = false
		endPkg := strings.Index(s, ":")
		if endPkg < 0 {
			pkg = s[len("//"):]
			s = ""
		} else {
			pkg = s[len("//"):endPkg]
			s = s[endPkg:]
		}
		if !labelPkgRegexp.MatchString(pkg) {
			return NoLabel, fmt.Errorf("label parse error: package has invalid characters: %q", origStr)
		}
	}

	if s == ":" {
		return NoLabel, fmt.Errorf("label parse error: empty name: %q", origStr)
	}
	name := strings.TrimPrefix(s, ":")
	if !labelNameRegexp.MatchString(name) {
		return NoLabel, fmt.Errorf("label parse error: name has invalid characters: %q", origStr)
	}

	if pkg == "" && name == "" {
		return NoLabel, fmt.Errorf("label parse error: empty package and name: %q", origStr)
	}
	if name == "" {
		name = path.Base(pkg)
	}

	return Label{
		Repo:     repo,
		Pkg:      pkg,
		Name:     name,
		Relative: relative,
	}, nil
}
func Parse(s string) (Label, error) {
	origStr := s

	relative := true
	var repo string
	if strings.HasPrefix(s, "@") {
		relative = false
		endRepo := strings.Index(s, "//")
		if endRepo < 0 {
			return NoLabel, fmt.Errorf("label parse error: repository does not end with '//': %q", origStr)
		}
		repo = s[len("@"):endRepo]
		if !labelRepoRegexp.MatchString(repo) {
			return NoLabel, fmt.Errorf("label parse error: repository has invalid characters: %q", origStr)
		}
		s = s[endRepo:]
	}

	var pkg string
	if strings.HasPrefix(s, "//") {
		relative = false
		endPkg := strings.Index(s, ":")
		if endPkg < 0 {
			pkg = s[len("//"):]
			s = ""
		} else {
			pkg = s[len("//"):endPkg]
			s = s[endPkg:]
		}
		if !labelPkgRegexp.MatchString(pkg) {
			return NoLabel, fmt.Errorf("label parse error: package has invalid characters: %q", origStr)
		}
	}

	if s == ":" {
		return NoLabel, fmt.Errorf("label parse error: empty name: %q", origStr)
	}
	name := strings.TrimPrefix(s, ":")
	if !labelNameRegexp.MatchString(name) {
		return NoLabel, fmt.Errorf("label parse error: name has invalid characters: %q", origStr)
	}

	if pkg == "" && name == "" {
		return NoLabel, fmt.Errorf("label parse error: empty package and name: %q", origStr)
	}
	if name == "" {
		name = path.Base(pkg)
	}

	return Label{
		Repo:     repo,
		Pkg:      pkg,
		Name:     name,
		Relative: relative,
	}, nil
}
// Parse reads a label from a string.
// See https://docs.bazel.build/versions/master/build-ref.html#lexi.