reduced number of string copies in SkSL parser

Bug: skia:
Change-Id: Iab823b01b6f5f85bbb47c4ac69c6ce396dabf497
Reviewed-on: https://skia-review.googlesource.com/34000
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp
index 2a88d30..d3e1d57 100644
--- a/src/sksl/SkSLParser.cpp
+++ b/src/sksl/SkSLParser.cpp
@@ -148,29 +148,42 @@
     }
 }
 
-Token Parser::nextRawToken() {
+Token Parser::nextRawToken(bool needText) {
     if (fPushback.fKind != Token::INVALID_TOKEN) {
         Token result = fPushback;
         fPushback.fKind = Token::INVALID_TOKEN;
         fPushback.fText = "";
         return result;
     }
-    int token = sksllex(fScanner);
-    return Token(Position(skslget_lineno(fScanner), -1), (Token::Kind) token,
-                 String(skslget_text(fScanner)));
+    Token::Kind kind = (Token::Kind) sksllex(fScanner);
+    if (!needText) {
+        switch (kind) {
+            case Token::Kind::DIRECTIVE:     // fall through
+            case Token::Kind::IDENTIFIER:    // fall through
+            case Token::Kind::INT_LITERAL:   // fall through
+            case Token::Kind::FLOAT_LITERAL: // fall through
+            case Token::Kind::SECTION:
+                needText = true;
+            default:
+                break;
+        }
+    }
+    static String unavailable("<unavailable>");
+    return Token(Position(skslget_lineno(fScanner), -1), kind,
+                 needText ? String(skslget_text(fScanner)) : unavailable);
 }
 
 Token Parser::nextToken() {
     Token token;
     do {
-        token = this->nextRawToken();
+        token = this->nextRawToken(false);
     } while (token.fKind == Token::WHITESPACE);
     return token;
 }
 
 void Parser::pushback(Token t) {
     ASSERT(fPushback.fKind == Token::INVALID_TOKEN);
-    fPushback = t;
+    fPushback = std::move(t);
 }
 
 Token Parser::peek() {
@@ -186,7 +199,7 @@
         }
         return true;
     }
-    this->pushback(next);
+    this->pushback(std::move(next));
     return false;
 }
 
@@ -315,7 +328,7 @@
     String text;
     int level = 1;
     for (;;) {
-        Token next = this->nextRawToken();
+        Token next = this->nextRawToken(true);
         switch (next.fKind) {
             case Token::LBRACE:
                 ++level;
@@ -593,12 +606,13 @@
     if (!this->expect(Token::EQ, "'='")) {
         return "";
     }
-    Token start = this->peek();
+    Token start = this->nextRawToken(true);
+    this->pushback(start);
     String code;
     int level = 1;
     bool done = false;
     while (!done) {
-        Token next = this->peek();
+        Token next = this->nextRawToken(true);
         switch (next.fKind) {
             case Token::LPAREN:
                 ++level;
@@ -620,8 +634,11 @@
         if (!level) {
             done = true;
         }
-        if (!done) {
-            code += this->nextRawToken().fText;
+        if (done) {
+            this->pushback(std::move(next));
+        }
+        else {
+            code += next.fText;
         }
     }
     return code;