Reland "[Retrace] Account for non-ascii std-in input"

This reverts commit 084c8fde16d8527a57f0477f92a6f5864b13f211.

Change-Id: Iafab425a274be6fc8a9b506887dead58ba40ddbe
diff --git a/src/main/java/com/android/tools/r8/retrace/Retrace.java b/src/main/java/com/android/tools/r8/retrace/Retrace.java
index af2b520..3d59b8b 100644
--- a/src/main/java/com/android/tools/r8/retrace/Retrace.java
+++ b/src/main/java/com/android/tools/r8/retrace/Retrace.java
@@ -17,7 +17,11 @@
 import com.android.tools.r8.utils.StringDiagnostic;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.Timing;
+import com.google.common.base.Charsets;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -117,7 +121,7 @@
   private static List<String> getStackTraceFromFile(
       String stackTracePath, DiagnosticsHandler diagnostics) {
     try {
-      return Files.readAllLines(Paths.get(stackTracePath));
+      return Files.readAllLines(Paths.get(stackTracePath), Charsets.UTF_8);
     } catch (IOException e) {
       diagnostics.error(new StringDiagnostic("Could not find stack trace file: " + stackTracePath));
       throw new RetraceAbortException();
@@ -196,7 +200,15 @@
       return;
     }
     builder.setRetracedStackTraceConsumer(
-        retraced -> System.out.print(StringUtils.lines(retraced)));
+        retraced -> {
+          try (PrintStream printStream = new PrintStream(System.out, true, Charsets.UTF_8.name())) {
+            for (String line : retraced) {
+              printStream.println(line);
+            }
+          } catch (UnsupportedEncodingException e) {
+            retraceDiagnosticsHandler.error(new StringDiagnostic(e.getMessage()));
+          }
+        });
     run(builder.build());
   }
 
@@ -210,7 +222,7 @@
   }
 
   private static List<String> getStackTraceFromStandardInput() {
-    Scanner sc = new Scanner(System.in);
+    Scanner sc = new Scanner(new InputStreamReader(System.in, Charsets.UTF_8));
     List<String> readLines = new ArrayList<>();
     while (sc.hasNext()) {
       readLines.add(sc.nextLine());
diff --git a/src/test/java/com/android/tools/r8/internal/retrace/RetraceTests.java b/src/test/java/com/android/tools/r8/internal/retrace/RetraceTests.java
index ee1d8f8..c8b98d7 100644
--- a/src/test/java/com/android/tools/r8/internal/retrace/RetraceTests.java
+++ b/src/test/java/com/android/tools/r8/internal/retrace/RetraceTests.java
@@ -38,6 +38,7 @@
           + "|(?:(?:.*?[:\"]\\s+)?%c(?::.*)?)"
           + "|(?:.*?%t\\s+%c\\.%m\\s*\\(%a\\)\\s*)";
   private static String FINSKY_REGEX = "(?:.*Finsky\\s+:\\s+\\[\\d+\\]\\s+%c\\.%m\\(%l\\):.*)";
+  private static String SMILEY_EMOJI = "\uD83D\uDE00";
 
   public RetraceTests(TestParameters parameters) {}
 
@@ -131,6 +132,39 @@
     runRetraceTest(new VelvetStackTrace());
   }
 
+  @Test
+  public void testNonAscii() {
+    CronetStackTrace cronetStackTrace = new CronetStackTrace();
+    runRetraceTest(
+        new StackTraceForTest() {
+          @Override
+          public List<String> obfuscatedStackTrace() {
+            ArrayList<String> smileyObf = new ArrayList<>();
+            smileyObf.add(SMILEY_EMOJI);
+            smileyObf.addAll(cronetStackTrace.obfuscatedStackTrace());
+            return smileyObf;
+          }
+
+          @Override
+          public String mapping() {
+            return cronetStackTrace.mapping();
+          }
+
+          @Override
+          public List<String> retracedStackTrace() {
+            ArrayList<String> smileyObf = new ArrayList<>();
+            smileyObf.add(SMILEY_EMOJI);
+            smileyObf.addAll(cronetStackTrace.retracedStackTrace());
+            return smileyObf;
+          }
+
+          @Override
+          public int expectedWarnings() {
+            return 0;
+          }
+        });
+  }
+
   private TestDiagnosticMessagesImpl runRetraceTest(StackTraceForTest stackTraceForTest) {
     return runRetraceTest(stackTraceForTest, DEFAULT_REGULAR_EXPRESSION);
   }
diff --git a/src/test/java/com/android/tools/r8/retrace/RetraceCommandLineTests.java b/src/test/java/com/android/tools/r8/retrace/RetraceCommandLineTests.java
index e8494d6..ec3fcc1 100644
--- a/src/test/java/com/android/tools/r8/retrace/RetraceCommandLineTests.java
+++ b/src/test/java/com/android/tools/r8/retrace/RetraceCommandLineTests.java
@@ -15,12 +15,14 @@
 import com.android.tools.r8.retrace.stacktraces.ActualRetraceBotStackTraceWithInfo;
 import com.android.tools.r8.retrace.stacktraces.FoundMethodVerboseStackTrace;
 import com.android.tools.r8.utils.StringUtils;
+import com.google.common.base.Charsets;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
@@ -38,6 +40,8 @@
 
   @Rule public TemporaryFolder folder = new TemporaryFolder();
 
+  private static String SMILEY_EMOJI = "\uD83D\uDE00";
+
   @Test
   public void testPrintIdentityStackTraceFile() throws IOException {
     runTest("", nonMappableStackTrace, false, nonMappableStackTrace);
@@ -125,6 +129,16 @@
     assertEquals(Retrace.USAGE_MESSAGE, processResult.stdout);
   }
 
+  @Test
+  public void testNonAscii() throws IOException {
+    runTest("", SMILEY_EMOJI, false, SMILEY_EMOJI + StringUtils.LINE_SEPARATOR);
+  }
+
+  @Test
+  public void testNonAsciiStdIn() throws IOException {
+    runTest("", SMILEY_EMOJI, true, SMILEY_EMOJI + StringUtils.LINE_SEPARATOR);
+  }
+
   private final String nonMappableStackTrace =
       StringUtils.lines(
           "com.android.r8.R8Exception: Problem when compiling program",
@@ -164,7 +178,7 @@
     Path mappingFile = folder.newFile("mapping.txt").toPath();
     Files.write(mappingFile, mapping.getBytes());
     File stackTraceFile = folder.newFile("stacktrace.txt");
-    Files.write(stackTraceFile.toPath(), stackTrace.getBytes());
+    Files.write(stackTraceFile.toPath(), stackTrace.getBytes(StandardCharsets.UTF_8));
 
     Collection<String> args = new ArrayList<>();
     args.add(mappingFile.toString());
@@ -216,8 +230,8 @@
       System.setErr(originalErr);
       return new ProcessResult(
           exitCode,
-          outputByteStream.toString(),
-          errorByteStream.toString(),
+          outputByteStream.toString(Charsets.UTF_8.name()),
+          errorByteStream.toString(Charsets.UTF_8.name()),
           StringUtils.joinLines(args));
     }
   }