Revert "Use json encoding for cquery ParseResult"

This reverts commit fcc53f992b40786b216d38844ab61945fe5c9071.

Reason for revert: Broke mixed_droid

Change-Id: I0f7b864a93624a6be94f8faf55cd9e5175de7f14
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index 28240c8..cf8e9f7 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -158,28 +158,63 @@
   # NOTE: It's OK if there's no ToC, as Soong just uses it for optimization
   pass
 
-return json_encode({
-	"OutputFiles": outputFiles,
-	"CcObjectFiles": ccObjectFiles,
-	"CcSharedLibraryFiles": sharedLibraries,
-	"CcStaticLibraryFiles": staticLibraries,
-	"Includes": includes,
-	"SystemIncludes": system_includes,
-	"Headers": headers,
-	"RootStaticArchives": rootStaticArchives,
-	"RootDynamicLibraries": rootSharedLibraries,
-	"toc_file": toc_file
-})`
+returns = [
+  outputFiles,
+  ccObjectFiles,
+  sharedLibraries,
+  staticLibraries,
+  includes,
+  system_includes,
+  headers,
+  rootStaticArchives,
+  rootSharedLibraries,
+  [toc_file]
+]
+
+return "|".join([", ".join(r) for r in returns])`
 }
 
 // ParseResult returns a value obtained by parsing the result of the request's Starlark function.
 // The given rawString must correspond to the string output which was created by evaluating the
 // Starlark given in StarlarkFunctionBody.
 func (g getCcInfoType) ParseResult(rawString string) (CcInfo, error) {
-	var ccInfo CcInfo
-	decoder := json.NewDecoder(strings.NewReader(rawString))
-	err := decoder.Decode(&ccInfo)
-	return ccInfo, err
+	const expectedLen = 10
+	splitString := strings.Split(rawString, "|")
+	if len(splitString) != expectedLen {
+		return CcInfo{}, fmt.Errorf("expected %d items, got %q", expectedLen, splitString)
+	}
+	outputFilesString := splitString[0]
+	ccObjectsString := splitString[1]
+	ccSharedLibrariesString := splitString[2]
+	ccStaticLibrariesString := splitString[3]
+	includesString := splitString[4]
+	systemIncludesString := splitString[5]
+	headersString := splitString[6]
+	rootStaticArchivesString := splitString[7]
+	rootDynamicLibrariesString := splitString[8]
+	tocFile := splitString[9] // NOTE: Will be the empty string if there wasn't
+
+	outputFiles := splitOrEmpty(outputFilesString, ", ")
+	ccObjects := splitOrEmpty(ccObjectsString, ", ")
+	ccSharedLibraries := splitOrEmpty(ccSharedLibrariesString, ", ")
+	ccStaticLibraries := splitOrEmpty(ccStaticLibrariesString, ", ")
+	includes := splitOrEmpty(includesString, ", ")
+	systemIncludes := splitOrEmpty(systemIncludesString, ", ")
+	headers := splitOrEmpty(headersString, ", ")
+	rootStaticArchives := splitOrEmpty(rootStaticArchivesString, ", ")
+	rootDynamicLibraries := splitOrEmpty(rootDynamicLibrariesString, ", ")
+	return CcInfo{
+		OutputFiles:          outputFiles,
+		CcObjectFiles:        ccObjects,
+		CcSharedLibraryFiles: ccSharedLibraries,
+		CcStaticLibraryFiles: ccStaticLibraries,
+		Includes:             includes,
+		SystemIncludes:       systemIncludes,
+		Headers:              headers,
+		RootStaticArchives:   rootStaticArchives,
+		RootDynamicLibraries: rootDynamicLibraries,
+		TocFile:              tocFile,
+	}, nil
 }
 
 // Query Bazel for the artifacts generated by the apex modules.
diff --git a/bazel/cquery/request_type_test.go b/bazel/cquery/request_type_test.go
index dd95fbf..46eb0b6 100644
--- a/bazel/cquery/request_type_test.go
+++ b/bazel/cquery/request_type_test.go
@@ -1,8 +1,9 @@
 package cquery
 
 import (
-	"encoding/json"
+	"fmt"
 	"reflect"
+	"strings"
 	"testing"
 )
 
@@ -62,49 +63,74 @@
 }
 
 func TestGetCcInfoParseResults(t *testing.T) {
+	const expectedSplits = 10
+	noResult := strings.Repeat("|", expectedSplits-1)
 	testCases := []struct {
 		description          string
-		inputCcInfo          CcInfo
+		input                string
 		expectedOutput       CcInfo
 		expectedErrorMessage string
 	}{
 		{
-			description:    "no result",
-			inputCcInfo:    CcInfo{},
-			expectedOutput: CcInfo{},
+			description: "no result",
+			input:       noResult,
+			expectedOutput: CcInfo{
+				OutputFiles:          []string{},
+				CcObjectFiles:        []string{},
+				CcSharedLibraryFiles: []string{},
+				CcStaticLibraryFiles: []string{},
+				Includes:             []string{},
+				SystemIncludes:       []string{},
+				Headers:              []string{},
+				RootStaticArchives:   []string{},
+				RootDynamicLibraries: []string{},
+				TocFile:              "",
+			},
 		},
 		{
 			description: "only output",
-			inputCcInfo: CcInfo{
-				OutputFiles: []string{"test", "test3"},
-			},
+			input:       "test" + noResult,
 			expectedOutput: CcInfo{
-				OutputFiles: []string{"test", "test3"},
+				OutputFiles:          []string{"test"},
+				CcObjectFiles:        []string{},
+				CcSharedLibraryFiles: []string{},
+				CcStaticLibraryFiles: []string{},
+				Includes:             []string{},
+				SystemIncludes:       []string{},
+				Headers:              []string{},
+				RootStaticArchives:   []string{},
+				RootDynamicLibraries: []string{},
+				TocFile:              "",
 			},
 		},
 		{
 			description: "only ToC",
-			inputCcInfo: CcInfo{
-				TocFile: "test",
-			},
+			input:       noResult + "test",
 			expectedOutput: CcInfo{
-				TocFile: "test",
+				OutputFiles:          []string{},
+				CcObjectFiles:        []string{},
+				CcSharedLibraryFiles: []string{},
+				CcStaticLibraryFiles: []string{},
+				Includes:             []string{},
+				SystemIncludes:       []string{},
+				Headers:              []string{},
+				RootStaticArchives:   []string{},
+				RootDynamicLibraries: []string{},
+				TocFile:              "test",
 			},
 		},
 		{
 			description: "all items set",
-			inputCcInfo: CcInfo{
-				OutputFiles:          []string{"out1", "out2"},
-				CcObjectFiles:        []string{"object1", "object2"},
-				CcSharedLibraryFiles: []string{"shared_lib1", "shared_lib2"},
-				CcStaticLibraryFiles: []string{"static_lib1", "static_lib2"},
-				Includes:             []string{".", "dir/subdir"},
-				SystemIncludes:       []string{"system/dir", "system/other/dir"},
-				Headers:              []string{"dir/subdir/hdr.h"},
-				RootStaticArchives:   []string{"rootstaticarchive1"},
-				RootDynamicLibraries: []string{"rootdynamiclibrary1"},
-				TocFile:              "lib.so.toc",
-			},
+			input: "out1, out2" +
+				"|object1, object2" +
+				"|shared_lib1, shared_lib2" +
+				"|static_lib1, static_lib2" +
+				"|., dir/subdir" +
+				"|system/dir, system/other/dir" +
+				"|dir/subdir/hdr.h" +
+				"|rootstaticarchive1" +
+				"|rootdynamiclibrary1" +
+				"|lib.so.toc",
 			expectedOutput: CcInfo{
 				OutputFiles:          []string{"out1", "out2"},
 				CcObjectFiles:        []string{"object1", "object2"},
@@ -118,10 +144,21 @@
 				TocFile:              "lib.so.toc",
 			},
 		},
+		{
+			description:          "too few result splits",
+			input:                "|",
+			expectedOutput:       CcInfo{},
+			expectedErrorMessage: fmt.Sprintf("expected %d items, got %q", expectedSplits, []string{"", ""}),
+		},
+		{
+			description:          "too many result splits",
+			input:                strings.Repeat("|", expectedSplits+1), // 2 too many
+			expectedOutput:       CcInfo{},
+			expectedErrorMessage: fmt.Sprintf("expected %d items, got %q", expectedSplits, make([]string, expectedSplits+2)),
+		},
 	}
 	for _, tc := range testCases {
-		jsonInput, err := json.Marshal(tc.inputCcInfo)
-		actualOutput, err := GetCcInfo.ParseResult(string(jsonInput))
+		actualOutput, err := GetCcInfo.ParseResult(tc.input)
 		if (err == nil && tc.expectedErrorMessage != "") ||
 			(err != nil && err.Error() != tc.expectedErrorMessage) {
 			t.Errorf("%q:\n%12s: %q\n%12s: %q", tc.description, "expect Error", tc.expectedErrorMessage, "but got", err)