Make ninjaString an interface

There are 8935901 *ninjaString objects generated in an AOSP
aosp_blueline-userdebug build, and 7865180 of those are a literal
string with no ninja variables.
Each of those *ninjaString objects takes a minimum of 48 bytes for
2 slices, plus 8 bytes for the pointer to the ninjaString.  For
the literal string case, one of those slices has a single element,
(costing another 16 bytes for the backing array), and the other
slice is empty, for a total of 72 bytes.

Replace *ninjaString with a ninjaString interface.  This increases
the size of the reference from 8 bytes to 16 bytes, but using
a type alias of a string for the literal string implementation uses
only 16 bytes, saving 40 bytes per literal string or 314 MB.

Test: ninja_strings_test
Change-Id: Ic5fe16ed1f2a244fe6a8ccdf762919634d825cbe
diff --git a/ninja_defs.go b/ninja_defs.go
index 61846fe..c5d0e4b 100644
--- a/ninja_defs.go
+++ b/ninja_defs.go
@@ -128,11 +128,11 @@
 // A ruleDef describes a rule definition.  It does not include the name of the
 // rule.
 type ruleDef struct {
-	CommandDeps      []*ninjaString
-	CommandOrderOnly []*ninjaString
+	CommandDeps      []ninjaString
+	CommandOrderOnly []ninjaString
 	Comment          string
 	Pool             Pool
-	Variables        map[string]*ninjaString
+	Variables        map[string]ninjaString
 }
 
 func parseRuleParams(scope scope, params *RuleParams) (*ruleDef,
@@ -141,7 +141,7 @@
 	r := &ruleDef{
 		Comment:   params.Comment,
 		Pool:      params.Pool,
-		Variables: make(map[string]*ninjaString),
+		Variables: make(map[string]ninjaString),
 	}
 
 	if params.Command == "" {
@@ -252,13 +252,13 @@
 	Comment         string
 	Rule            Rule
 	RuleDef         *ruleDef
-	Outputs         []*ninjaString
-	ImplicitOutputs []*ninjaString
-	Inputs          []*ninjaString
-	Implicits       []*ninjaString
-	OrderOnly       []*ninjaString
-	Args            map[Variable]*ninjaString
-	Variables       map[string]*ninjaString
+	Outputs         []ninjaString
+	ImplicitOutputs []ninjaString
+	Inputs          []ninjaString
+	Implicits       []ninjaString
+	OrderOnly       []ninjaString
+	Args            map[Variable]ninjaString
+	Variables       map[string]ninjaString
 	Optional        bool
 }
 
@@ -273,9 +273,9 @@
 		Rule:    rule,
 	}
 
-	setVariable := func(name string, value *ninjaString) {
+	setVariable := func(name string, value ninjaString) {
 		if b.Variables == nil {
-			b.Variables = make(map[string]*ninjaString)
+			b.Variables = make(map[string]ninjaString)
 		}
 		b.Variables[name] = value
 	}
@@ -339,7 +339,7 @@
 	argNameScope := rule.scope()
 
 	if len(params.Args) > 0 {
-		b.Args = make(map[Variable]*ninjaString)
+		b.Args = make(map[Variable]ninjaString)
 		for name, value := range params.Args {
 			if !rule.isArg(name) {
 				return nil, fmt.Errorf("unknown argument %q", name)
@@ -419,7 +419,7 @@
 	return nw.BlankLine()
 }
 
-func valueList(list []*ninjaString, pkgNames map[*packageContext]string,
+func valueList(list []ninjaString, pkgNames map[*packageContext]string,
 	escaper *strings.Replacer) []string {
 
 	result := make([]string, len(list))
@@ -429,7 +429,7 @@
 	return result
 }
 
-func writeVariables(nw *ninjaWriter, variables map[string]*ninjaString,
+func writeVariables(nw *ninjaWriter, variables map[string]ninjaString,
 	pkgNames map[*packageContext]string) error {
 	var keys []string
 	for k := range variables {