// Check if the unquoted string is a variable reference, starting with $.
170639
func (lx *lexer) isVariable() bool {
	if lx.input[lx.start] == '$' {
		lx.start += 1
		return true
	}
	return false
}
1162172
func (f stringNotLikeFunc) evaluate(values map[string][]string) bool {
	return !f.stringLikeFunc.evaluate(values)
}
1224506
func (n *LiteralNode) IsUnknown() bool {
	return IsUnknown(Variable{
		Type:  n.Typex,
		Value: n.Value,
	})
}
1211807
func isStringUppercase(s string) bool {
	if strings.ToUpper(s) != s {
		return false
	}
	for _, c := range []rune(s) {
		if unicode.IsUpper(c) {
			return true
		}
	}
	return false
}
847383
func (s *Scanner) scanString() {
	braces := 0
	for {
		// '"' opening already consumed
		// read character after quote
		ch := s.next()

		if (ch == '\n' && braces == 0) || ch < 0 || ch == eof {
			s.err("literal not terminated")
			return
		}

		if ch == '"' && braces == 0 {
			break
		}

		// If we're going into a ${} then we can ignore quotes for awhile
		if braces == 0 && ch == '$' && s.peek() == '{' {
			braces++
			s.next()
		} else if braces > 0 && ch == '{' {
			braces++
		}
		if braces > 0 && ch == '}' {
			braces--
		}

		if ch == '\\' {
			s.scanEscape()
		}
	}

	return
}
174926
func variableNV(ln *line) (string, string, error) {
	s := strings.TrimSpace(ln.s)

	if !strings.HasPrefix(s, dollarMark) {
		return "", "", fmt.Errorf("variable must start with %q [line: %d]", dollarMark, ln.no)
	}

	nv := strings.SplitN(s, space, 2)

	if len(nv) < 2 {
		return "", "", fmt.Errorf("variable's name and value should be divided by a space [line: %d]", ln.no)
	}

	if !strings.HasSuffix(nv[0], colon) {
		return "", "", fmt.Errorf("variable's name should end with a colon [line: %d]", ln.no)
	}

	return strings.TrimSuffix(strings.TrimPrefix(nv[0], dollarMark), colon), nv[1], nil
}
305635
func unquote(s string) string {
	u, q, esc := make([]rune, 0, len(s)), false, false
	for _, c := range s {
		if esc {
			uc, ok := unescape[c]
			switch {
			case ok:
				u = append(u, uc)
				fallthrough
			case !q && c == '\n':
				esc = false
				continue
			}
			panic("invalid escape sequence")
		}
		switch c {
		case '"':
			q = !q
		case '\\':
			esc = true
		default:
			u = append(u, c)
		}
	}
	if q {
		panic("missing end quote")
	}
	if esc {
		panic("invalid escape sequence")
	}
	return string(u)
}
432964
func (v *variable) stringValue() string {
	switch v.kind {
	case boolKind:
		return fmt.Sprint(v.boolValue())
	case intKind:
		return fmt.Sprint(v.intValue())
	case floatKind:
		return fmt.Sprint(v.floatValue())
	}
	return v.value
}
804902
func (scope *Scope) Quote(str string) string {
	if strings.Contains(str, ".") {
		newStrs := []string{}
		for _, str := range strings.Split(str, ".") {
			newStrs = append(newStrs, scope.Dialect().Quote(str))
		}
		return strings.Join(newStrs, ".")
	}

	return scope.Dialect().Quote(str)
}
1264074
func (a VarRefs) Strings() []string {
	s := make([]string, len(a))
	for i, ref := range a {
		s[i] = ref.Val
	}
	return s
}
1333930
func quote(unquoted string, triple bool) string {
	q := `"`
	if triple {
		q = `"""`
	}

	var buf bytes.Buffer
	buf.WriteString(q)

	for i := 0; i < len(unquoted); i++ {
		c := unquoted[i]
		if c == '"' && triple && (i+1 < len(unquoted) && unquoted[i+1] != '"' || i+2 < len(unquoted) && unquoted[i+2] != '"') {
			// Can pass up to two quotes through, because they are followed by a non-quote byte.
			buf.WriteByte(c)
			if i+1 < len(unquoted) && unquoted[i+1] == '"' {
				buf.WriteByte(c)
				i++
			}
			continue
		}
		if triple && c == '\n' {
			// Can allow newline in triple-quoted string.
			buf.WriteByte(c)
			continue
		}
		if c == '\'' {
			// Can allow ' since we always use ".
			buf.WriteByte(c)
			continue
		}
		if c == '\\' {
			if i+1 < len(unquoted) && indexByte(notEsc, unquoted[i+1]) >= 0 {
				// Can pass \ through when followed by a byte that
				// known not to be a valid escape sequence and also
				// that does not trigger an escape sequence of its own.
				// Use this, because various BUILD files do.
				buf.WriteByte('\\')
				buf.WriteByte(unquoted[i+1])
				i++
				continue
			}
		}
		if esc[c] != 0 {
			buf.WriteByte('\\')
			buf.WriteByte(esc[c])
			continue
		}
		if c < 0x20 || c >= 0x80 {
			// BUILD files are supposed to be Latin-1, so escape all control and high bytes.
			// I'd prefer to use \x here, but Blaze does not implement
			// \x in quoted strings (b/7272572).
			buf.WriteByte('\\')
			buf.WriteByte(hex[c>>6]) // actually octal but reusing hex digits 0-7.
			buf.WriteByte(hex[(c>>3)&7])
			buf.WriteByte(hex[c&7])
			/*
				buf.WriteByte('\\')
				buf.WriteByte('x')
				buf.WriteByte(hex[c>>4])
				buf.WriteByte(hex[c&0xF])
			*/
			continue
		}
		buf.WriteByte(c)
		continue
	}

	buf.WriteString(q)
	return buf.String()
}
1374715
func needsQuoting(text string) bool {
	for _, r := range text {
		if !strconv.IsPrint(r) {
			return true
		}
	}
	return false
}
1361099
func (v *TypeReference) String() string {
	if v == nil {
		return "<nil>"
	}

	var fields [3]string
	i := 0
	fields[i] = fmt.Sprintf("Name: %v", v.Name)
	i++
	fields[i] = fmt.Sprintf("ImportPath: %v", v.ImportPath)
	i++
	if v.Annotations != nil {
		fields[i] = fmt.Sprintf("Annotations: %v", v.Annotations)
		i++
	}

	return fmt.Sprintf("TypeReference{%v}", strings.Join(fields[:i], ", "))
}
900095
func unquoteString(s string) (string, error) {
	ret := new(bytes.Buffer)
	for i := 0; i < len(s); i++ {
		if s[i] == '\\' {
			i++
			if i == len(s) {
				return "", errors.New("Missing a closing quotation mark in string")
			}
			switch s[i] {
			case '"':
				ret.WriteByte('"')
			case 'b':
				ret.WriteByte('\b')
			case 'f':
				ret.WriteByte('\f')
			case 'n':
				ret.WriteByte('\n')
			case 'r':
				ret.WriteByte('\r')
			case 't':
				ret.WriteByte('\t')
			case '\\':
				ret.WriteByte('\\')
			case 'u':
				if i+4 > len(s) {
					return "", errors.Errorf("Invalid unicode: %s", s[i+1:])
				}
				char, size, err := decodeEscapedUnicode(hack.Slice(s[i+1 : i+5]))
				if err != nil {
					return "", errors.Trace(err)
				}
				ret.Write(char[0:size])
				i += 4
			default:
				// For all other escape sequences, backslash is ignored.
				ret.WriteByte(s[i])
			}
		} else {
			ret.WriteByte(s[i])
		}
	}
	return ret.String(), nil
}
458096
func IsJSONString(s string) bool {
	s = strings.TrimSpace(s)
	return strings.HasPrefix(s, "{") && strings.HasSuffix(s, "}")
}
1295435
func (p *Parser) parseQuote(cur *ListNode) error {
Loop:
	for {
		switch p.next() {
		case eof, '\n':
			return fmt.Errorf("unterminated quoted string")
		case '"':
			break Loop
		}
	}
	value := p.consumeText()
	s, err := strconv.Unquote(value)
	if err != nil {
		return fmt.Errorf("unquote string %s error %v", value, err)
	}
	cur.append(newText(s))
	return p.parseInsideAction(cur)
}
716657
func (v Value) StringValue() string {
	switch v.Type {
	case StringType:
		return strings.TrimFunc(string(v.raw), isTrimmable)
	case QuotedStringType:
		// preserve all characters in the quotes
		return string(removeEscapedCharacters(v.raw[1 : len(v.raw)-1]))
	default:
		return strings.TrimFunc(string(v.raw), isTrimmable)
	}
}