write dex archives uncompressed
RELNOTES: none

PiperOrigin-RevId: 164620306
diff --git a/src/test/java/com/google/devtools/build/android/dexer/DexConversionEnqueuerTest.java b/src/test/java/com/google/devtools/build/android/dexer/DexConversionEnqueuerTest.java
index 2c27f4b..5f1bb82 100644
--- a/src/test/java/com/google/devtools/build/android/dexer/DexConversionEnqueuerTest.java
+++ b/src/test/java/com/google/devtools/build/android/dexer/DexConversionEnqueuerTest.java
@@ -141,11 +141,12 @@
     stuffer.call();
     Future<ZipEntryContent> f = stuffer.getFiles().remove();
     assertThat(f.isDone()).isTrue();
+    byte[] dexcode = f.get().getContent();
     assertThat(f.get().getEntry().getName()).isEqualTo(filename + ".dex");
     assertThat(f.get().getEntry().getTime()).isEqualTo(FILE_TIME);
-    assertThat(f.get().getEntry().getSize()).isEqualTo(-1);
-    assertThat(f.get().getEntry().getCompressedSize()).isEqualTo(-1);
-    byte[] dexcode = f.get().getContent();
+    assertThat(f.get().getEntry().getSize()).isEqualTo(dexcode.length);
+    assertThat(f.get().getEntry().getCompressedSize()).isEqualTo(dexcode.length);
+
     Dex dex = new Dex(dexcode);
     assertThat(dex.classDefs()).hasSize(1);
     assertThat(cache.getIfPresent(DexingKey.create(false, false, bytecode))).isSameAs(dexcode);
diff --git a/src/tools/android/java/com/google/devtools/build/android/dexer/DexConversionEnqueuer.java b/src/tools/android/java/com/google/devtools/build/android/dexer/DexConversionEnqueuer.java
index b66e725..9e94b47 100644
--- a/src/tools/android/java/com/google/devtools/build/android/dexer/DexConversionEnqueuer.java
+++ b/src/tools/android/java/com/google/devtools/build/android/dexer/DexConversionEnqueuer.java
@@ -28,6 +28,7 @@
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
+import java.util.zip.CRC32;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import javax.annotation.Nullable;
@@ -108,7 +109,7 @@
   private Future<ZipEntryContent> toDex(ZipEntry entry, byte[] content) {
     byte[] cached = dexCache != null ? dexCache.getIfPresent(dexer.getDexingKey(content)) : null;
     return cached != null
-        ? immediateFuture(newDexEntry(entry, cached))
+        ? immediateFuture(storedDexEntry(entry, cached))
         : executor.submit(new ClassToDex(entry, content, dexer, dexCache));
   }
 
@@ -126,13 +127,25 @@
     return files;
   }
 
-  private static ZipEntryContent newDexEntry(ZipEntry classfile, byte[] dexed) {
-    return new ZipEntryContent(withFileName(classfile, classfile.getName() + ".dex"), dexed);
+  private static ZipEntryContent storedDexEntry(ZipEntry classfile, byte[] dexed) {
+    return new ZipEntryContent(
+        storedEntry(classfile.getName() + ".dex", classfile.getTime(), dexed),
+        dexed);
   }
 
-  private static ZipEntry withFileName(ZipEntry orig, String filename) {
+  private static ZipEntry storedEntry(String filename, long time, byte[] content) {
+    // Need to pre-compute checksum for STORED (uncompressed) entries)
+    CRC32 checksum = new CRC32();
+    checksum.update(content);
+
     ZipEntry result = new ZipEntry(filename);
-    result.setTime(orig.getTime());
+    result.setTime(time);
+    result.setCrc(checksum.getValue());
+    result.setSize(content.length);
+    result.setCompressedSize(content.length);
+    // Write uncompressed, since this is just an intermediary artifact that
+    // we will convert to .dex
+    result.setMethod(ZipEntry.STORED);
     return result;
   }
 
@@ -162,7 +175,7 @@
         dexCache.put(dexer.getDexingKey(content), dexed);
       }
       // Use .class.dex suffix expected by SplitZip
-      return newDexEntry(entry, dexed);
+      return storedDexEntry(entry, dexed);
     }
   }
 }