func parseElem()

in cli/azd/pkg/yamlnode/yamlnode.go [291:407]


func parseElem(s string) ([]pathElem, error) {
	result := []pathElem{}
	elem := pathElem{kind: keyElem}
	key := strings.Builder{}

	inKey := true // whether we are currently parsing a key part of the element
	for i := 0; i < len(s); i++ {
		c := s[i]

		switch c {
		case '[':
			inKey = false

			// find the closing bracket
			j := i + 1
			for j < len(s) {
				if s[j] == ']' {
					break
				}
				j++
			}

			if j == len(s) {
				return nil, fmt.Errorf("missing closing bracket ']' after '[': %s", s[i:])
			}

			// contents is the string between the brackets
			contents := s[i+1 : j]
			if contents == "" && j+1 < len(s) && s[j+1] == '?' { // empty brackets followed by '?'
				elem.optionalKind = yaml.SequenceNode
				i = j + 1
				continue
			}
			idx, err := strconv.Atoi(contents)
			if err != nil || idx < 0 {
				return nil, fmt.Errorf("invalid sequence index: %s in %s", contents, s[i:j+1])
			}

			switch elem.kind {
			case keyElem:
				elem.key = key.String()
				key.Reset()

				if elem.key == "" {
					return nil, fmt.Errorf("empty key in %s", s)
				}
			case indexElem:
				// do nothing
			}

			result = append(result, elem)
			elem = pathElem{kind: indexElem, idx: idx}

			i = j
		case ']':
			return nil, fmt.Errorf("unexpected closing bracket '[' before ']': %s", s[i:])
		case '?':
			elem.optionalKind = yaml.MappingNode
			if i != len(s)-1 {
				return nil, fmt.Errorf(
					"unexpected characters after optional qualifier `?`: %s: "+
						"'?' is a special character; to escape using double quotes, try \"%s\"",
					s[i+1:],
					s[:i])
			}
		case '\\':
			if i+1 < len(s) && s[i+1] == '"' {
				key.WriteByte('"')
				i++
			}
		case '"':
			// find the closing quote
			j := i + 1
			for j < len(s) {
				if s[j] == '\\' && j+1 < len(s) && s[j+1] == '"' {
					key.WriteByte('"')
					j += 2
					continue
				}

				if s[j] == '"' {
					break
				}
				key.WriteByte(s[j])
				j++
			}

			if j == len(s) {
				return nil, fmt.Errorf(
					"missing closing quote '\"' near %s; to escape double quotes, try adding a preceding backslash", s[i:])
			}
			i = j
		default:
			if !inKey {
				return nil, fmt.Errorf(
					"unexpected characters after character `%s`: %s: "+
						"'[', ']' are special characters; to escape using double quotes, try \"%s\"",
					string(s[i-1]),
					s[i:],
					s[:i-1])
			}
			key.WriteByte(c)
		}
	}

	if key.Len() > 0 {
		elem.key = key.String()
		elem.kind = keyElem
	}

	if len(result) == 0 && elem.key == "" {
		return nil, fmt.Errorf("empty")
	}

	result = append(result, elem)
	return result, nil
}