You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: scan.go
    path of file: ./repos/delve/vendor/go.starlark.net/syntax
    
    the code of the file until where you have to start completion: // Copyright 2017 The Bazel Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package syntax

// A lexical scanner for Starlark.

import (
	"fmt"
	"io"
	"log"
	"math/big"
	"os"
	"strconv"
	"strings"
	"unicode"
	"unicode/utf8"
)

// A Token represents a Starlark lexical token.
type Token int8

const (
	ILLEGAL Token = iota
	EOF

	NEWLINE
	INDENT
	OUTDENT

	// Tokens with values
	IDENT  // x
	INT    // 123
	FLOAT  // 1.23e45
	STRING // "foo" or 'foo' or '''foo''' or r'foo' or r"foo"
	BYTES  // b"foo", etc

	// Punctuation
	PLUS          // +
	MINUS         // -
	STAR          // *
	SLASH         // /
	SLASHSLASH    // //
	PERCENT       // %
	AMP           // &
	PIPE          // |
	CIRCUMFLEX    // ^
	LTLT          // <<
	GTGT          // >>
	TILDE      
    
func (sc *scanner) scanString(val *tokenValue, quote rune) Token {
	start := sc.pos
	triple := len(sc.rest) >= 3 && sc.rest[0] == byte(quote) && sc.rest[1] == byte(quote) && sc.rest[2] == byte(quote)
	sc.readRune()

	// String literals may contain escaped or unescaped newlines,
	// causing them to span multiple lines (gulps) of REPL input;
	// they are the only such token. Thus we cannot call endToken,
	// as it assumes sc.rest is unchanged since startToken.
	// Instead, buffer the token here.
	// TODO(adonovan): opt: buffer only if we encounter a newline.
	raw := new(strings.Builder)

	// Copy the prefix, e.g. r' or " (see startToken).
	raw.Write(sc.token[:len(sc.token)-len(sc.rest)])

	if !triple {
		// single-quoted string literal
		for {
			if sc.eof() {
				sc.error(val.pos, "unexpected EOF in string")
			}
			c := sc.readRune()
			raw.WriteRune(c)
			if c == quote {
				break
			}
			if c == '\n' {
				sc.error(val.pos, "unexpected newline in string")
			}
			if c == '\\' {
				if sc.eof() {
					sc.error(val.pos, "unexpected EOF in string")
				}
				c = sc.readRune()
				raw.WriteRune(c)
			}
		}
	} else {
		// triple-quoted string literal
		sc.readRune()
		raw.WriteRune(quote)
		sc.readRune()
		raw.WriteRune(quote)

		quoteCount := 0
		for {
			if sc.eof() {
				sc.error(val.pos, "unexpected EOF in string")
			}
			c := sc.readRune()
			raw.WriteRune(c)
			if c == quote {
				quoteCount++
				if quoteCount == 3 {
					break
				}
			} else {
				quoteCount = 0
			}
			if c == '\\' {
				if sc.eof() {
					sc.error(val.pos, "unexpected EOF in string")
				}
				c = sc.readRune()
				raw.WriteRune(c)
			}
		}
	}
	val.raw = raw.String()

	s, _, isByte, err := unquote(val.raw)
	if err != nil {
		sc.error(start, err.Error())
	}
	val.string = s
	if isByte {
		return BYTES
	} else {
		return STRING
	}
}