Cleaning around Dex parsing

Mostly renaming. Contains also a few minor changes.

Change-Id: Iad497f22130191f3731819b7972cc28458b70bf8
diff --git a/src/main/java/com/android/tools/r8/DexSegments.java b/src/main/java/com/android/tools/r8/DexSegments.java
index 72ac766..aa17b82 100644
--- a/src/main/java/com/android/tools/r8/DexSegments.java
+++ b/src/main/java/com/android/tools/r8/DexSegments.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8;
 
 import com.android.tools.r8.ProgramResource.Kind;
-import com.android.tools.r8.dex.DexFileReader;
-import com.android.tools.r8.dex.Segment;
+import com.android.tools.r8.dex.DexParser;
+import com.android.tools.r8.dex.DexSection;
 import com.android.tools.r8.origin.CommandLineOrigin;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
@@ -98,11 +98,11 @@
     try (Closer closer = Closer.create()) {
       for (ProgramResource resource : app.computeAllProgramResources()) {
         if (resource.getKind() == Kind.DEX) {
-          for (Segment segment :
-              DexFileReader.parseMapFrom(
+          for (DexSection dexSection :
+              DexParser.parseMapFrom(
                   closer.register(resource.getByteStream()), resource.getOrigin())) {
-            int value = result.computeIfAbsent(segment.typeName(), (key) -> 0);
-            result.put(segment.typeName(), value + segment.size());
+            int value = result.computeIfAbsent(dexSection.typeName(), (key) -> 0);
+            result.put(dexSection.typeName(), value + dexSection.size());
           }
         }
       }
diff --git a/src/main/java/com/android/tools/r8/ExtractMarker.java b/src/main/java/com/android/tools/r8/ExtractMarker.java
index 272d2e5..ced0b4c 100644
--- a/src/main/java/com/android/tools/r8/ExtractMarker.java
+++ b/src/main/java/com/android/tools/r8/ExtractMarker.java
@@ -6,8 +6,8 @@
 import com.android.tools.r8.ProgramResource.Kind;
 import com.android.tools.r8.dex.ApplicationReader;
 import com.android.tools.r8.dex.Marker;
-import com.android.tools.r8.dex.VDexFile;
-import com.android.tools.r8.dex.VDexFileReader;
+import com.android.tools.r8.dex.VDexReader;
+import com.android.tools.r8.dex.VDexParser;
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.origin.Origin;
@@ -72,10 +72,10 @@
       throws IOException, ResourceException {
     if (FileUtils.isVDexFile(file)) {
       PathOrigin vdexOrigin = new PathOrigin(file);
-      VDexFile vdexFile = new VDexFile(vdexOrigin, Files.newInputStream(file));
-      VDexFileReader reader = new VDexFileReader(vdexFile);
+      VDexReader vdexReader = new VDexReader(vdexOrigin, Files.newInputStream(file));
+      VDexParser vDexParser = new VDexParser(vdexReader);
       int index = 0;
-      for (byte[] bytes : reader.getDexFiles()) {
+      for (byte[] bytes : vDexParser.getDexFiles()) {
         appBuilder.addDexProgramData(bytes, new VdexOrigin(vdexOrigin, index));
         index++;
       }
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
index b6a3ef6..28a7fbb 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
@@ -52,9 +52,9 @@
 
 public class ApplicationReader {
 
-  final InternalOptions options;
-  final DexItemFactory itemFactory;
-  final Timing timing;
+  private final InternalOptions options;
+  private final DexItemFactory itemFactory;
+  private final Timing timing;
   private final AndroidApp inputApp;
 
   public interface ProgramClassConflictResolver {
@@ -122,8 +122,8 @@
     return builder.build();
   }
 
-  private int verifyOrComputeMinApiLevel(int computedMinApiLevel, DexFile file) {
-    DexVersion version = DexVersion.getDexVersion(file.getDexVersion());
+  private int verifyOrComputeMinApiLevel(int computedMinApiLevel, DexReader dexReader) {
+    DexVersion version = DexVersion.getDexVersion(dexReader.getDexVersion());
     if (options.minApiLevel == AndroidApiLevel.getDefault().getLevel()) {
       computedMinApiLevel = Math
           .max(computedMinApiLevel, AndroidApiLevel.getMinAndroidApiLevel(version).getLevel());
@@ -194,23 +194,22 @@
         List<ProgramResource> dexSources, ClassKind classKind, Queue<T> classes)
         throws IOException, ResourceException {
       if (dexSources.size() > 0) {
-        List<DexFileReader> fileReaders = new ArrayList<>(dexSources.size());
+        List<DexParser> dexParsers = new ArrayList<>(dexSources.size());
         int computedMinApiLevel = options.minApiLevel;
         for (ProgramResource input : dexSources) {
-          DexFile file = new DexFile(input);
-          computedMinApiLevel = verifyOrComputeMinApiLevel(computedMinApiLevel, file);
-          fileReaders.add(new DexFileReader(file, classKind, itemFactory));
+          DexReader dexReader = new DexReader(input);
+          computedMinApiLevel = verifyOrComputeMinApiLevel(computedMinApiLevel, dexReader);
+          dexParsers.add(new DexParser(dexReader, classKind, itemFactory));
         }
         options.minApiLevel = computedMinApiLevel;
-        for (DexFileReader reader : fileReaders) {
-          DexFileReader.populateIndexTables(reader);
+        for (DexParser dexParser : dexParsers) {
+          dexParser.populateIndexTables();
         }
         // Read the DexCode items and DexProgramClass items in parallel.
         if (!options.skipReadingDexCode) {
-          for (DexFileReader reader : fileReaders) {
+          for (DexParser dexParser : dexParsers) {
             futures.add(executorService.submit(() -> {
-              reader.addCodeItemsTo();  // Depends on Everything for parsing.
-              reader.addClassDefsTo(
+              dexParser.addClassDefsTo(
                   classKind.bridgeConsumer(classes::add)); // Depends on Methods, Code items etc.
             }));
           }
diff --git a/src/main/java/com/android/tools/r8/dex/BaseFile.java b/src/main/java/com/android/tools/r8/dex/BinaryReader.java
similarity index 90%
rename from src/main/java/com/android/tools/r8/dex/BaseFile.java
rename to src/main/java/com/android/tools/r8/dex/BinaryReader.java
index 2f54fba..127e1d5 100644
--- a/src/main/java/com/android/tools/r8/dex/BaseFile.java
+++ b/src/main/java/com/android/tools/r8/dex/BinaryReader.java
@@ -12,15 +12,18 @@
 import java.io.IOException;
 import java.nio.ByteBuffer;
 
-public abstract class BaseFile {
+/**
+ * Base class for reading binary content.
+ */
+public abstract class BinaryReader {
   protected final Origin origin;
   protected final ByteBuffer buffer;
 
-  protected BaseFile(ProgramResource resource) throws ResourceException, IOException {
+  protected BinaryReader(ProgramResource resource) throws ResourceException, IOException {
     this(resource.getOrigin(), ByteStreams.toByteArray(resource.getByteStream()));
   }
 
-  protected BaseFile(Origin origin, byte[] bytes) {
+  protected BinaryReader(Origin origin, byte[] bytes) {
     assert origin != null;
     this.origin = origin;
     buffer = ByteBuffer.wrap(bytes);
diff --git a/src/main/java/com/android/tools/r8/dex/DexFileReader.java b/src/main/java/com/android/tools/r8/dex/DexParser.java
similarity index 73%
rename from src/main/java/com/android/tools/r8/dex/DexFileReader.java
rename to src/main/java/com/android/tools/r8/dex/DexParser.java
index a17a8ce..9aa7eed 100644
--- a/src/main/java/com/android/tools/r8/dex/DexFileReader.java
+++ b/src/main/java/com/android/tools/r8/dex/DexParser.java
@@ -76,26 +76,26 @@
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 
-public class DexFileReader {
+public class DexParser {
 
-  final int NO_INDEX = -1;
+  private final int NO_INDEX = -1;
   private final Origin origin;
-  private DexFile file;
-  private final Segment[] segments;
+  private DexReader dexReader;
+  private final DexSection[] dexSections;
   private int[] stringIDs;
   private final ClassKind classKind;
 
-  public static Segment[] parseMapFrom(Path file) throws IOException {
+  public static DexSection[] parseMapFrom(Path file) throws IOException {
     return parseMapFrom(Files.newInputStream(file), new PathOrigin(file));
   }
 
-  public static Segment[] parseMapFrom(InputStream stream, Origin origin) throws IOException {
-    return parseMapFrom(new DexFile(origin, ByteStreams.toByteArray(stream)));
+  public static DexSection[] parseMapFrom(InputStream stream, Origin origin) throws IOException {
+    return parseMapFrom(new DexReader(origin, ByteStreams.toByteArray(stream)));
   }
 
-  private static Segment[] parseMapFrom(DexFile dex) {
-    DexFileReader reader = new DexFileReader(dex, ClassKind.PROGRAM, new DexItemFactory());
-    return reader.segments;
+  private static DexSection[] parseMapFrom(DexReader dexReader) {
+    DexParser dexParser = new DexParser(dexReader, ClassKind.PROGRAM, new DexItemFactory());
+    return dexParser.dexSections;
   }
 
   public void close() {
@@ -103,7 +103,7 @@
     indexedItems = null;
     codes = null;
     offsetMap = null;
-    file = null;
+    dexReader = null;
     stringIDs = null;
   }
 
@@ -119,43 +119,43 @@
   // Factory to canonicalize certain dexitems.
   private final DexItemFactory dexItemFactory;
 
-  public DexFileReader(DexFile file, ClassKind classKind, DexItemFactory dexItemFactory) {
-    assert file.getOrigin() != null;
-    this.origin = file.getOrigin();
-    this.file = file;
+  public DexParser(DexReader dexReader, ClassKind classKind, DexItemFactory dexItemFactory) {
+    assert dexReader.getOrigin() != null;
+    this.origin = dexReader.getOrigin();
+    this.dexReader = dexReader;
     this.dexItemFactory = dexItemFactory;
-    file.setByteOrder();
-    segments = parseMap();
+    dexReader.setByteOrder();
+    dexSections = parseMap();
     parseStringIDs();
     this.classKind = classKind;
   }
 
-  public OffsetToObjectMapping getIndexedItemsMap() {
-    return indexedItems;
-  }
+  private void ensureCodesInited() {
+    if (codes == null) {
+      codes = new Int2ObjectOpenHashMap<>();
+    }
 
-  void addCodeItemsTo() {
     if (classKind == ClassKind.LIBRARY) {
       // Ignore contents of library files.
       return;
     }
-    Segment segment = lookupSegment(Constants.TYPE_CODE_ITEM);
-    if (segment.length == 0) {
+    DexSection dexSection = lookupSection(Constants.TYPE_CODE_ITEM);
+    if (dexSection.length == 0) {
       return;
     }
-    file.position(segment.offset);
-    for (int i = 0; i < segment.length; i++) {
-      file.align(4);  // code items are 4 byte aligned.
-      int offset = file.position();
+    dexReader.position(dexSection.offset);
+    for (int i = 0; i < dexSection.length; i++) {
+      dexReader.align(4);  // code items are 4 byte aligned.
+      int offset = dexReader.position();
       DexCode code = parseCodeItem();
       codes.put(offset, code);  // Update the file local offset to code mapping.
     }
   }
 
   private DexTypeList parseTypeList() {
-    DexType[] result = new DexType[file.getUint()];
+    DexType[] result = new DexType[dexReader.getUint()];
     for (int j = 0; j < result.length; j++) {
-      result[j] = indexedItems.getType(file.getUshort());
+      result[j] = indexedItems.getType(dexReader.getUshort());
     }
     return new DexTypeList(result);
   }
@@ -167,68 +167,68 @@
     return (DexTypeList) cacheAt(offset, this::parseTypeList);
   }
 
-  public DexValue parseEncodedValue() {
-    int header = file.get() & 0xff;
+  private DexValue parseEncodedValue() {
+    int header = dexReader.get() & 0xff;
     int valueArg = header >> 5;
     int valueType = header & 0x1f;
     switch (valueType) {
       case DexValue.VALUE_BYTE: {
         assert valueArg == 0;
-        byte value = (byte) parseSigned(file, 1);
+        byte value = (byte) parseSigned(dexReader, 1);
         return DexValue.DexValueByte.create(value);
       }
       case DexValue.VALUE_SHORT: {
         int size = valueArg + 1;
-        short value = (short) parseSigned(file, size);
+        short value = (short) parseSigned(dexReader, size);
         return DexValue.DexValueShort.create(value);
       }
       case DexValue.VALUE_CHAR: {
         int size = valueArg + 1;
-        char value = (char) parseUnsigned(file, size);
+        char value = (char) parseUnsigned(dexReader, size);
         return DexValue.DexValueChar.create(value);
       }
       case DexValue.VALUE_INT: {
         int size = valueArg + 1;
-        int value = (int) parseSigned(file, size);
+        int value = (int) parseSigned(dexReader, size);
         return DexValue.DexValueInt.create(value);
       }
       case DexValue.VALUE_LONG: {
         int size = valueArg + 1;
-        long value = parseSigned(file, size);
+        long value = parseSigned(dexReader, size);
         return DexValue.DexValueLong.create(value);
       }
       case DexValue.VALUE_FLOAT: {
         int size = valueArg + 1;
-        return DexValue.DexValueFloat.create(parseFloat(file, size));
+        return DexValue.DexValueFloat.create(parseFloat(dexReader, size));
       }
       case DexValue.VALUE_DOUBLE: {
         int size = valueArg + 1;
-        return DexValue.DexValueDouble.create(parseDouble(file, size));
+        return DexValue.DexValueDouble.create(parseDouble(dexReader, size));
       }
       case DexValue.VALUE_STRING: {
         int size = valueArg + 1;
-        int index = (int) parseUnsigned(file, size);
+        int index = (int) parseUnsigned(dexReader, size);
         DexString value = indexedItems.getString(index);
         return new DexValue.DexValueString(value);
       }
       case DexValue.VALUE_TYPE: {
         int size = valueArg + 1;
-        DexType value = indexedItems.getType((int) parseUnsigned(file, size));
+        DexType value = indexedItems.getType((int) parseUnsigned(dexReader, size));
         return new DexValue.DexValueType(value);
       }
       case DexValue.VALUE_FIELD: {
         int size = valueArg + 1;
-        DexField value = indexedItems.getField((int) parseUnsigned(file, size));
+        DexField value = indexedItems.getField((int) parseUnsigned(dexReader, size));
         return new DexValue.DexValueField(value);
       }
       case DexValue.VALUE_METHOD: {
         int size = valueArg + 1;
-        DexMethod value = indexedItems.getMethod((int) parseUnsigned(file, size));
+        DexMethod value = indexedItems.getMethod((int) parseUnsigned(dexReader, size));
         return new DexValue.DexValueMethod(value);
       }
       case DexValue.VALUE_ENUM: {
         int size = valueArg + 1;
-        DexField value = indexedItems.getField((int) parseUnsigned(file, size));
+        DexField value = indexedItems.getField((int) parseUnsigned(dexReader, size));
         return new DexValue.DexValueEnum(value);
       }
       case DexValue.VALUE_ARRAY: {
@@ -249,12 +249,12 @@
       }
       case DexValue.VALUE_METHOD_TYPE: {
         int size = valueArg + 1;
-        DexProto value = indexedItems.getProto((int) parseUnsigned(file, size));
+        DexProto value = indexedItems.getProto((int) parseUnsigned(dexReader, size));
         return new DexValue.DexValueMethodType(value);
       }
       case DexValue.VALUE_METHOD_HANDLE: {
         int size = valueArg + 1;
-        DexMethodHandle value = indexedItems.getMethodHandle((int) parseUnsigned(file, size));
+        DexMethodHandle value = indexedItems.getMethodHandle((int) parseUnsigned(dexReader, size));
         return new DexValue.DexValueMethodHandle(value);
       }
       default:
@@ -263,11 +263,11 @@
   }
 
   private DexEncodedAnnotation parseEncodedAnnotation() {
-    int typeIdx = file.getUleb128();
-    int size = file.getUleb128();
+    int typeIdx = dexReader.getUleb128();
+    int size = dexReader.getUleb128();
     DexAnnotationElement[] elements = new DexAnnotationElement[size];
     for (int i = 0; i < size; i++) {
-      int nameIdx = file.getUleb128();
+      int nameIdx = dexReader.getUleb128();
       DexValue value = parseEncodedValue();
       elements[i] = new DexAnnotationElement(indexedItems.getString(nameIdx), value);
     }
@@ -275,7 +275,7 @@
   }
 
   private DexValue[] parseEncodedArrayValues() {
-    int size = file.getUleb128();
+    int size = dexReader.getUleb128();
     DexValue[] values = new DexValue[size];
     for (int i = 0; i < size; i++) {
       values[i] = parseEncodedValue();
@@ -299,17 +299,17 @@
     int[] fieldIndices = new int[size];
     int[] annotationOffsets = new int[size];
     for (int i = 0; i < size; i++) {
-      fieldIndices[i] = file.getUint();
-      annotationOffsets[i] = file.getUint();
+      fieldIndices[i] = dexReader.getUint();
+      annotationOffsets[i] = dexReader.getUint();
     }
-    int saved = file.position();
+    int saved = dexReader.position();
     DexFieldAnnotation[] result = new DexFieldAnnotation[size];
     for (int i = 0; i < size; i++) {
       DexField field = indexedItems.getField(fieldIndices[i]);
       DexAnnotationSet annotation = annotationSetAt(annotationOffsets[i]);
       result[i] = new DexFieldAnnotation(field, annotation);
     }
-    file.position(saved);
+    dexReader.position(saved);
     return result;
   }
 
@@ -320,17 +320,17 @@
     int[] methodIndices = new int[size];
     int[] annotationOffsets = new int[size];
     for (int i = 0; i < size; i++) {
-      methodIndices[i] = file.getUint();
-      annotationOffsets[i] = file.getUint();
+      methodIndices[i] = dexReader.getUint();
+      annotationOffsets[i] = dexReader.getUint();
     }
-    int saved = file.position();
+    int saved = dexReader.position();
     DexMethodAnnotation[] result = new DexMethodAnnotation[size];
     for (int i = 0; i < size; i++) {
       DexMethod method = indexedItems.getMethod(methodIndices[i]);
       DexAnnotationSet annotation = annotationSetAt(annotationOffsets[i]);
       result[i] = new DexMethodAnnotation(method, annotation);
     }
-    file.position(saved);
+    dexReader.position(saved);
     return result;
   }
 
@@ -339,10 +339,10 @@
   }
 
   private DexAnnotationSetRefList parseAnnotationSetRefList() {
-    int size = file.getUint();
+    int size = dexReader.getUint();
     int[] annotationOffsets = new int[size];
     for (int i = 0; i < size; i++) {
-      annotationOffsets[i] = file.getUint();
+      annotationOffsets[i] = dexReader.getUint();
     }
     DexAnnotationSet[] values = new DexAnnotationSet[size];
     for (int i = 0; i < size; i++) {
@@ -358,10 +358,10 @@
     int[] methodIndices = new int[size];
     int[] annotationOffsets = new int[size];
     for (int i = 0; i < size; i++) {
-      methodIndices[i] = file.getUint();
-      annotationOffsets[i] = file.getUint();
+      methodIndices[i] = dexReader.getUint();
+      annotationOffsets[i] = dexReader.getUint();
     }
-    int saved = file.position();
+    int saved = dexReader.position();
     DexParameterAnnotation[] result = new DexParameterAnnotation[size];
     for (int i = 0; i < size; i++) {
       DexMethod method = indexedItems.getMethod(methodIndices[i]);
@@ -369,7 +369,7 @@
           method,
           annotationSetRefListAt(annotationOffsets[i]));
     }
-    file.position(saved);
+    dexReader.position(saved);
     return result;
   }
 
@@ -389,7 +389,7 @@
       return result;  // return the cached result.
     }
     // Cache is empty so parse the structure.
-    file.position(offset);
+    dexReader.position(offset);
     result = function.get();
     // Update the map.
     offsetMap.put(offset, result);
@@ -399,9 +399,9 @@
 
   private DexAnnotation parseAnnotation() {
     if (Log.ENABLED) {
-      Log.verbose(getClass(), "Reading Annotation @ 0x%08x.", file.position());
+      Log.verbose(getClass(), "Reading Annotation @ 0x%08x.", dexReader.position());
     }
-    int visibility = file.get();
+    int visibility = dexReader.get();
     return new DexAnnotation(visibility, parseEncodedAnnotation());
   }
 
@@ -411,12 +411,12 @@
 
   private DexAnnotationSet parseAnnotationSet() {
     if (Log.ENABLED) {
-      Log.verbose(getClass(), "Reading AnnotationSet @ 0x%08x.", file.position());
+      Log.verbose(getClass(), "Reading AnnotationSet @ 0x%08x.", dexReader.position());
     }
-    int size = file.getUint();
+    int size = dexReader.getUint();
     int[] annotationOffsets = new int[size];
     for (int i = 0; i < size; i++) {
-      annotationOffsets[i] = file.getUint();
+      annotationOffsets[i] = dexReader.getUint();
     }
     DexAnnotation[] result = new DexAnnotation[size];
     for (int i = 0; i < size; i++) {
@@ -435,10 +435,10 @@
   }
 
   private AnnotationsDirectory parseAnnotationsDirectory() {
-    int classAnnotationsOff = file.getUint();
-    int fieldsSize = file.getUint();
-    int methodsSize = file.getUint();
-    int parametersSize = file.getUint();
+    int classAnnotationsOff = dexReader.getUint();
+    int fieldsSize = dexReader.getUint();
+    int methodsSize = dexReader.getUint();
+    int parametersSize = dexReader.getUint();
     final DexFieldAnnotation[] fields = parseFieldAnnotations(fieldsSize);
     final DexMethodAnnotation[] methods = parseMethodAnnotations(methodsSize);
     final DexParameterAnnotation[] parameters = parseParameterAnnotations(parametersSize);
@@ -454,28 +454,28 @@
   }
 
   private DexDebugInfo parseDebugInfo() {
-    int start = file.getUleb128();
-    int parametersSize = file.getUleb128();
+    int start = dexReader.getUleb128();
+    int parametersSize = dexReader.getUleb128();
     DexString[] parameters = new DexString[parametersSize];
     for (int i = 0; i < parametersSize; i++) {
-      int index = file.getUleb128p1();
+      int index = dexReader.getUleb128p1();
       if (index != NO_INDEX) {
         parameters[i] = indexedItems.getString(index);
       }
     }
     List<DexDebugEvent> events = new ArrayList<>();
-    for (int head = file.getUbyte(); head != Constants.DBG_END_SEQUENCE; head = file.getUbyte()) {
+    for (int head = dexReader.getUbyte(); head != Constants.DBG_END_SEQUENCE; head = dexReader.getUbyte()) {
       switch (head) {
         case Constants.DBG_ADVANCE_PC:
-          events.add(dexItemFactory.createAdvancePC(file.getUleb128()));
+          events.add(dexItemFactory.createAdvancePC(dexReader.getUleb128()));
           break;
         case Constants.DBG_ADVANCE_LINE:
-          events.add(dexItemFactory.createAdvanceLine(file.getSleb128()));
+          events.add(dexItemFactory.createAdvanceLine(dexReader.getSleb128()));
           break;
         case Constants.DBG_START_LOCAL: {
-          int registerNum = file.getUleb128();
-          int nameIdx = file.getUleb128p1();
-          int typeIdx = file.getUleb128p1();
+          int registerNum = dexReader.getUleb128();
+          int nameIdx = dexReader.getUleb128p1();
+          int typeIdx = dexReader.getUleb128p1();
           events.add(new DexDebugEvent.StartLocal(
               registerNum,
               nameIdx == NO_INDEX ? null : indexedItems.getString(nameIdx),
@@ -484,10 +484,10 @@
           break;
         }
         case Constants.DBG_START_LOCAL_EXTENDED: {
-          int registerNum = file.getUleb128();
-          int nameIdx = file.getUleb128p1();
-          int typeIdx = file.getUleb128p1();
-          int sigIdx = file.getUleb128p1();
+          int registerNum = dexReader.getUleb128();
+          int nameIdx = dexReader.getUleb128p1();
+          int typeIdx = dexReader.getUleb128p1();
+          int sigIdx = dexReader.getUleb128p1();
           events.add(new DexDebugEvent.StartLocal(
               registerNum,
               nameIdx == NO_INDEX ? null : indexedItems.getString(nameIdx),
@@ -496,11 +496,11 @@
           break;
         }
         case Constants.DBG_END_LOCAL: {
-          events.add(dexItemFactory.createEndLocal(file.getUleb128()));
+          events.add(dexItemFactory.createEndLocal(dexReader.getUleb128()));
           break;
         }
         case Constants.DBG_RESTART_LOCAL: {
-          events.add(dexItemFactory.createRestartLocal(file.getUleb128()));
+          events.add(dexItemFactory.createRestartLocal(dexReader.getUleb128()));
           break;
         }
         case Constants.DBG_SET_PROLOGUE_END: {
@@ -512,7 +512,7 @@
           break;
         }
         case Constants.DBG_SET_FILE: {
-          int nameIdx = file.getUleb128p1();
+          int nameIdx = dexReader.getUleb128p1();
           DexString sourceFile = nameIdx == NO_INDEX ? null : indexedItems.getString(nameIdx);
           events.add(dexItemFactory.createSetFile(sourceFile));
           break;
@@ -562,9 +562,9 @@
     MemberAnnotationIterator<DexField, DexAnnotationSet> annotationIterator =
         new MemberAnnotationIterator<>(annotations, DexAnnotationSet::empty);
     for (int i = 0; i < size; i++) {
-      fieldIndex += file.getUleb128();
+      fieldIndex += dexReader.getUleb128();
       DexField field = indexedItems.getField(fieldIndex);
-      FieldAccessFlags accessFlags = FieldAccessFlags.fromDexAccessFlags(file.getUleb128());
+      FieldAccessFlags accessFlags = FieldAccessFlags.fromDexAccessFlags(dexReader.getUleb128());
       DexAnnotationSet fieldAnnotations = annotationIterator.getNextFor(field);
       DexValue staticValue = null;
       if (accessFlags.isStatic()) {
@@ -588,9 +588,9 @@
     MemberAnnotationIterator<DexMethod, DexAnnotationSetRefList> parameterAnnotationsIterator =
         new MemberAnnotationIterator<>(parameters, DexAnnotationSetRefList::empty);
     for (int i = 0; i < size; i++) {
-      methodIndex += file.getUleb128();
-      MethodAccessFlags accessFlags = MethodAccessFlags.fromDexAccessFlags(file.getUleb128());
-      int codeOff = file.getUleb128();
+      methodIndex += dexReader.getUleb128();
+      MethodAccessFlags accessFlags = MethodAccessFlags.fromDexAccessFlags(dexReader.getUleb128());
+      int codeOff = dexReader.getUleb128();
       DexCode code = null;
       if (!skipCodes) {
         assert codeOff == 0 || codes.get(codeOff) != null;
@@ -604,13 +604,14 @@
   }
 
   void addClassDefsTo(Consumer<DexClass> classCollection) {
-    final Segment segment = lookupSegment(Constants.TYPE_CLASS_DEF_ITEM);
-    final int length = segment.length;
+    ensureCodesInited();
+    final DexSection dexSection = lookupSection(Constants.TYPE_CLASS_DEF_ITEM);
+    final int length = dexSection.length;
     indexedItems.initializeClasses(length);
     if (length == 0) {
       return;
     }
-    file.position(segment.offset);
+    dexReader.position(dexSection.offset);
 
     int[] classIndices = new int[length];
     int[] accessFlags = new int[length];
@@ -623,16 +624,16 @@
 
     for (int i = 0; i < length; i++) {
       if (Log.ENABLED) {
-        Log.verbose(getClass(), "Reading ClassDef @ 0x%08x.", file.position());
+        Log.verbose(getClass(), "Reading ClassDef @ 0x%08x.", dexReader.position());
       }
-      classIndices[i] = file.getUint();
-      accessFlags[i] = file.getUint();
-      superclassIndices[i] = file.getInt();
-      interfacesOffsets[i] = file.getUint();
-      sourceFileIndices[i] = file.getInt();
-      annotationsOffsets[i] = file.getUint();
-      classDataOffsets[i] = file.getUint();
-      staticValuesOffsets[i] = file.getUint();
+      classIndices[i] = dexReader.getUint();
+      accessFlags[i] = dexReader.getUint();
+      superclassIndices[i] = dexReader.getInt();
+      interfacesOffsets[i] = dexReader.getUint();
+      sourceFileIndices[i] = dexReader.getInt();
+      annotationsOffsets[i] = dexReader.getUint();
+      classDataOffsets[i] = dexReader.getUint();
+      staticValuesOffsets[i] = dexReader.getUint();
     }
 
     for (int i = 0; i < length; i++) {
@@ -656,11 +657,11 @@
       if (classDataOffsets[i] != 0) {
         DexEncodedArray staticValues = encodedArrayAt(staticValuesOffsets[i]);
 
-        file.position(classDataOffsets[i]);
-        int staticFieldsSize = file.getUleb128();
-        int instanceFieldsSize = file.getUleb128();
-        int directMethodsSize = file.getUleb128();
-        int virtualMethodsSize = file.getUleb128();
+        dexReader.position(classDataOffsets[i]);
+        int staticFieldsSize = dexReader.getUleb128();
+        int instanceFieldsSize = dexReader.getUleb128();
+        int directMethodsSize = dexReader.getUleb128();
+        int virtualMethodsSize = dexReader.getUleb128();
 
         staticFields = readFields(staticFieldsSize, annotationsDirectory.fields,
             staticValues != null ? staticValues.values : null);
@@ -702,105 +703,105 @@
   }
 
   private void parseStringIDs() {
-    Segment segment = lookupSegment(Constants.TYPE_STRING_ID_ITEM);
-    stringIDs = new int[segment.length];
-    if (segment.length == 0) {
+    DexSection dexSection = lookupSection(Constants.TYPE_STRING_ID_ITEM);
+    stringIDs = new int[dexSection.length];
+    if (dexSection.length == 0) {
       return;
     }
-    file.position(segment.offset);
-    for (int i = 0; i < segment.length; i++) {
-      stringIDs[i] = file.getUint();
+    dexReader.position(dexSection.offset);
+    for (int i = 0; i < dexSection.length; i++) {
+      stringIDs[i] = dexReader.getUint();
     }
   }
 
-  private Segment lookupSegment(int type) {
-    for (Segment s : segments) {
+  private DexSection lookupSection(int type) {
+    for (DexSection s : dexSections) {
       if (s.type == type) {
         return s;
       }
     }
-    // If the segment doesn't exist, return an empty segment of this type.
-    return new Segment(type, 0, 0, 0);
+    // If the section doesn't exist, return an empty section of this type.
+    return new DexSection(type, 0, 0, 0);
   }
 
-  private Segment[] parseMap() {
-    // Read the segments information from the MAP.
-    int mapOffset = file.getUint(Constants.MAP_OFF_OFFSET);
-    file.position(mapOffset);
-    int mapSize = file.getUint();
-    final Segment[] result = new Segment[mapSize];
+  private DexSection[] parseMap() {
+    // Read the dexSections information from the MAP.
+    int mapOffset = dexReader.getUint(Constants.MAP_OFF_OFFSET);
+    dexReader.position(mapOffset);
+    int mapSize = dexReader.getUint();
+    final DexSection[] result = new DexSection[mapSize];
     for (int i = 0; i < mapSize; i++) {
-      int type = file.getUshort();
-      int unused = file.getUshort();
-      int size = file.getUint();
-      int offset = file.getUint();
-      result[i] = new Segment(type, unused, size, offset);
+      int type = dexReader.getUshort();
+      int unused = dexReader.getUshort();
+      int size = dexReader.getUint();
+      int offset = dexReader.getUint();
+      result[i] = new DexSection(type, unused, size, offset);
     }
     if (Log.ENABLED) {
       for (int i = 0; i < result.length; i++) {
-        Segment segment = result[i];
-        int nextOffset = i < result.length - 1 ? result[i + 1].offset : segment.offset;
-        Log.debug(this.getClass(), "Read segment 0x%04x @ 0x%08x #items %08d size 0x%08x.",
-            segment.type, segment.offset, segment.length, nextOffset - segment.offset);
+        DexSection dexSection = result[i];
+        int nextOffset = i < result.length - 1 ? result[i + 1].offset : dexSection.offset;
+        Log.debug(this.getClass(), "Read section 0x%04x @ 0x%08x #items %08d size 0x%08x.",
+            dexSection.type, dexSection.offset, dexSection.length, nextOffset - dexSection.offset);
       }
     }
     for (int i = 0; i < mapSize - 1; i++) {
       result[i].setEnd(result[i + 1].offset);
     }
-    result[mapSize - 1].setEnd(file.end());
+    result[mapSize - 1].setEnd(dexReader.end());
     return result;
   }
 
   private DexCode parseCodeItem() {
-    int registerSize = file.getUshort();
-    int insSize = file.getUshort();
-    int outsSize = file.getUshort();
-    int triesSize = file.getUshort();
-    int debugInfoOff = file.getUint();
-    int insnsSize = file.getUint();
+    int registerSize = dexReader.getUshort();
+    int insSize = dexReader.getUshort();
+    int outsSize = dexReader.getUshort();
+    int triesSize = dexReader.getUshort();
+    int debugInfoOff = dexReader.getUint();
+    int insnsSize = dexReader.getUint();
     short[] code = new short[insnsSize];
     Try[] tries = new Try[triesSize];
     DexCode.TryHandler[] handlers = null;
 
     if (insnsSize != 0) {
       for (int i = 0; i < insnsSize; i++) {
-        code[i] = file.getShort();
+        code[i] = dexReader.getShort();
       }
       if (insnsSize % 2 != 0) {
-        file.getUshort();  // Skip padding ushort
+        dexReader.getUshort();  // Skip padding ushort
       }
       if (triesSize > 0) {
         Int2IntArrayMap handlerMap = new Int2IntArrayMap();
         // tries: try_item[tries_size].
         for (int i = 0; i < triesSize; i++) {
-          int startAddr = file.getUint();
-          int insnCount = file.getUshort();
-          int handlerOff = file.getUshort();
+          int startAddr = dexReader.getUint();
+          int insnCount = dexReader.getUshort();
+          int handlerOff = dexReader.getUshort();
           tries[i] = new Try(startAddr, insnCount, handlerOff);
         }
         // handlers: encoded_catch_handler_list
-        int encodedCatchHandlerListPosition = file.position();
+        int encodedCatchHandlerListPosition = dexReader.position();
         // - size: uleb128
-        int size = file.getUleb128();
+        int size = dexReader.getUleb128();
         handlers = new TryHandler[size];
         // - list: encoded_catch_handler[handlers_size]
         for (int i = 0; i < size; i++) {
           // encoded_catch_handler
-          int encodedCatchHandlerOffset = file.position() - encodedCatchHandlerListPosition;
+          int encodedCatchHandlerOffset = dexReader.position() - encodedCatchHandlerListPosition;
           handlerMap.put(encodedCatchHandlerOffset, i);
           // - size:	sleb128
-          int hsize = file.getSleb128();
+          int hsize = dexReader.getSleb128();
           int realHsize = Math.abs(hsize);
           // - handlers	encoded_type_addr_pair[abs(size)]
           TryHandler.TypeAddrPair pairs[] = new TryHandler.TypeAddrPair[realHsize];
           for (int j = 0; j < realHsize; j++) {
-            int typeIdx = file.getUleb128();
-            int addr = file.getUleb128();
+            int typeIdx = dexReader.getUleb128();
+            int addr = dexReader.getUleb128();
             pairs[j] = new TypeAddrPair(indexedItems.getType(typeIdx), addr);
           }
           int catchAllAddr = -1;
           if (hsize <= 0) {
-            catchAllAddr = file.getUleb128();
+            catchAllAddr = dexReader.getUleb128();
           }
           handlers[i] = new TryHandler(pairs, catchAllAddr);
         }
@@ -811,9 +812,9 @@
       }
     }
     // Store and restore offset information around reading debug info.
-    int saved = file.position();
+    int saved = dexReader.position();
     DexDebugInfo debugInfo = debugInfoAt(debugInfoOff);
-    file.position(saved);
+    dexReader.position(saved);
     InstructionFactory factory = new InstructionFactory();
     Instruction[] instructions =
         factory.readSequenceFrom(ShortBuffer.wrap(code), 0, code.length, indexedItems);
@@ -828,105 +829,105 @@
         factory.getHighestSortingString());
   }
 
-  static void populateIndexTables(DexFileReader fileReader) {
+  void populateIndexTables() {
     // Populate structures that are already sorted upon read.
-    DexFileReader.populateStrings(fileReader);  // Depends on nothing.
-    DexFileReader.populateTypes(fileReader);  // Depends on Strings.
-    DexFileReader.populateFields(fileReader);  // Depends on Types, and Strings.
-    DexFileReader.populateProtos(fileReader);  // Depends on Types and Strings.
-    DexFileReader.populateMethods(fileReader);  // Depends on Protos, Types, and Strings.
-    DexFileReader.populateMethodHandles(fileReader); // Depends on Methods and Fields
-    DexFileReader.populateCallSites(fileReader); // Depends on MethodHandles
+    populateStrings();  // Depends on nothing.
+    populateTypes();  // Depends on Strings.
+    populateFields();  // Depends on Types, and Strings.
+    populateProtos();  // Depends on Types and Strings.
+    populateMethods();  // Depends on Protos, Types, and Strings.
+    populateMethodHandles(); // Depends on Methods and Fields
+    populateCallSites(); // Depends on MethodHandles
   }
 
-  private static void populateStrings(DexFileReader reader) {
-    reader.indexedItems.initializeStrings(reader.stringIDs.length);
-    for (int i = 0; i < reader.stringIDs.length; i++) {
-      reader.indexedItems.setString(i, reader.stringAt(i));
+  private void populateStrings() {
+    indexedItems.initializeStrings(stringIDs.length);
+    for (int i = 0; i < stringIDs.length; i++) {
+      indexedItems.setString(i, stringAt(i));
     }
   }
 
-  private static void populateMethodHandles(DexFileReader reader) {
-    Segment segment = reader.lookupSegment(Constants.TYPE_METHOD_HANDLE_ITEM);
-    reader.indexedItems.initializeMethodHandles(segment.length);
-    for (int i = 0; i < segment.length; i++) {
-      reader.indexedItems.setMethodHandle(i, reader.methodHandleAt(i));
+  private void populateMethodHandles() {
+    DexSection dexSection = lookupSection(Constants.TYPE_METHOD_HANDLE_ITEM);
+    indexedItems.initializeMethodHandles(dexSection.length);
+    for (int i = 0; i < dexSection.length; i++) {
+      indexedItems.setMethodHandle(i, methodHandleAt(i));
     }
   }
 
-  private static void populateCallSites(DexFileReader reader) {
-    Segment segment = reader.lookupSegment(Constants.TYPE_CALL_SITE_ID_ITEM);
-    reader.indexedItems.initializeCallSites(segment.length);
-    for (int i = 0; i < segment.length; i++) {
-      reader.indexedItems.setCallSites(i, reader.callSiteAt(i));
+  private void populateCallSites() {
+    DexSection dexSection = lookupSection(Constants.TYPE_CALL_SITE_ID_ITEM);
+    indexedItems.initializeCallSites(dexSection.length);
+    for (int i = 0; i < dexSection.length; i++) {
+      indexedItems.setCallSites(i, callSiteAt(i));
     }
   }
 
-  private static void populateTypes(DexFileReader reader) {
-    Segment segment = reader.lookupSegment(Constants.TYPE_TYPE_ID_ITEM);
-    reader.indexedItems.initializeTypes(segment.length);
-    for (int i = 0; i < segment.length; i++) {
-      reader.indexedItems.setType(i, reader.typeAt(i));
+  private void populateTypes() {
+    DexSection dexSection = lookupSection(Constants.TYPE_TYPE_ID_ITEM);
+    indexedItems.initializeTypes(dexSection.length);
+    for (int i = 0; i < dexSection.length; i++) {
+      indexedItems.setType(i, typeAt(i));
     }
   }
 
-  private static void populateFields(DexFileReader reader) {
-    Segment segment = reader.lookupSegment(Constants.TYPE_FIELD_ID_ITEM);
-    reader.indexedItems.initializeFields(segment.length);
-    for (int i = 0; i < segment.length; i++) {
-      reader.indexedItems.setField(i, reader.fieldAt(i));
+  private void populateFields() {
+    DexSection dexSection = lookupSection(Constants.TYPE_FIELD_ID_ITEM);
+    indexedItems.initializeFields(dexSection.length);
+    for (int i = 0; i < dexSection.length; i++) {
+      indexedItems.setField(i, fieldAt(i));
     }
   }
 
-  private static void populateProtos(DexFileReader reader) {
-    Segment segment = reader.lookupSegment(Constants.TYPE_PROTO_ID_ITEM);
-    reader.indexedItems.initializeProtos(segment.length);
-    for (int i = 0; i < segment.length; i++) {
-      reader.indexedItems.setProto(i, reader.protoAt(i));
+  private void populateProtos() {
+    DexSection dexSection = lookupSection(Constants.TYPE_PROTO_ID_ITEM);
+    indexedItems.initializeProtos(dexSection.length);
+    for (int i = 0; i < dexSection.length; i++) {
+      indexedItems.setProto(i, protoAt(i));
     }
   }
 
-  private static void populateMethods(DexFileReader reader) {
-    Segment segment = reader.lookupSegment(Constants.TYPE_METHOD_ID_ITEM);
-    reader.indexedItems.initializeMethods(segment.length);
-    for (int i = 0; i < segment.length; i++) {
-      reader.indexedItems.setMethod(i, reader.methodAt(i));
+  private void populateMethods() {
+    DexSection dexSection = lookupSection(Constants.TYPE_METHOD_ID_ITEM);
+    indexedItems.initializeMethods(dexSection.length);
+    for (int i = 0; i < dexSection.length; i++) {
+      indexedItems.setMethod(i, methodAt(i));
     }
   }
 
   private DexString stringAt(int index) {
     final int offset = stringIDs[index];
-    file.position(offset);
-    int size = file.getUleb128();
+    dexReader.position(offset);
+    int size = dexReader.getUleb128();
     ByteArrayOutputStream os = new ByteArrayOutputStream();
     byte read;
     do {
-      read = file.get();
+      read = dexReader.get();
       os.write(read);
     } while (read != 0);
     return dexItemFactory.createString(size, os.toByteArray());
   }
 
   private DexType typeAt(int index) {
-    Segment segment = lookupSegment(Constants.TYPE_TYPE_ID_ITEM);
-    if (index >= segment.length) {
+    DexSection dexSection = lookupSection(Constants.TYPE_TYPE_ID_ITEM);
+    if (index >= dexSection.length) {
       return null;
     }
-    int offset = segment.offset + (Constants.TYPE_TYPE_ID_ITEM_SIZE * index);
-    int stringIndex = file.getUint(offset);
+    int offset = dexSection.offset + (Constants.TYPE_TYPE_ID_ITEM_SIZE * index);
+    int stringIndex = dexReader.getUint(offset);
     return dexItemFactory.createType(indexedItems.getString(stringIndex));
   }
 
   private DexField fieldAt(int index) {
-    Segment segment = lookupSegment(Constants.TYPE_FIELD_ID_ITEM);
-    if (index >= segment.length) {
+    DexSection dexSection = lookupSection(Constants.TYPE_FIELD_ID_ITEM);
+    if (index >= dexSection.length) {
       return null;
     }
-    int offset = segment.offset + (Constants.TYPE_FIELD_ID_ITEM_SIZE * index);
-    file.position(offset);
-    int classIndex = file.getUshort();
-    int typeIndex = file.getUshort();
-    int nameIndex = file.getUint();
+    int offset = dexSection.offset + (Constants.TYPE_FIELD_ID_ITEM_SIZE * index);
+    dexReader.position(offset);
+    int classIndex = dexReader.getUshort();
+    int typeIndex = dexReader.getUshort();
+    int nameIndex = dexReader.getUint();
     DexType clazz = indexedItems.getType(classIndex);
     DexType type = indexedItems.getType(typeIndex);
     DexString name = indexedItems.getString(nameIndex);
@@ -934,15 +935,15 @@
   }
 
   private DexMethodHandle methodHandleAt(int index) {
-    Segment segment = lookupSegment(Constants.TYPE_METHOD_HANDLE_ITEM);
-    if (index >= segment.length) {
+    DexSection dexSection = lookupSection(Constants.TYPE_METHOD_HANDLE_ITEM);
+    if (index >= dexSection.length) {
       return null;
     }
-    int offset = segment.offset + (Constants.TYPE_METHOD_HANDLE_ITEM_SIZE * index);
-    file.position(offset);
-    MethodHandleType type = MethodHandleType.getKind(file.getUshort());
-    file.getUshort(); // unused
-    int indexFieldOrMethod = file.getUshort();
+    int offset = dexSection.offset + (Constants.TYPE_METHOD_HANDLE_ITEM_SIZE * index);
+    dexReader.position(offset);
+    MethodHandleType type = MethodHandleType.getKind(dexReader.getUshort());
+    dexReader.getUshort(); // unused
+    int indexFieldOrMethod = dexReader.getUshort();
     Descriptor<? extends DexItem, ? extends Descriptor<?, ?>> fieldOrMethod;
     switch (type) {
       case INSTANCE_GET:
@@ -963,18 +964,18 @@
       default:
         throw new AssertionError("Method handle type unsupported in a dex file.");
     }
-    file.getUshort(); // unused
+    dexReader.getUshort(); // unused
 
     return dexItemFactory.createMethodHandle(type, fieldOrMethod);
   }
 
   private DexCallSite callSiteAt(int index) {
-    Segment segment = lookupSegment(Constants.TYPE_CALL_SITE_ID_ITEM);
-    if (index >= segment.length) {
+    DexSection dexSection = lookupSection(Constants.TYPE_CALL_SITE_ID_ITEM);
+    if (index >= dexSection.length) {
       return null;
     }
     int callSiteOffset =
-        file.getUint(segment.offset + (Constants.TYPE_CALL_SITE_ID_ITEM_SIZE * index));
+        dexReader.getUint(dexSection.offset + (Constants.TYPE_CALL_SITE_ID_ITEM_SIZE * index));
     DexEncodedArray callSiteEncodedArray = encodedArrayAt(callSiteOffset);
     DexValue[] values = callSiteEncodedArray.values;
     assert values[0] instanceof DexValueMethodHandle;
@@ -990,15 +991,15 @@
   }
 
   private DexProto protoAt(int index) {
-    Segment segment = lookupSegment(Constants.TYPE_PROTO_ID_ITEM);
-    if (index >= segment.length) {
+    DexSection dexSection = lookupSection(Constants.TYPE_PROTO_ID_ITEM);
+    if (index >= dexSection.length) {
       return null;
     }
-    int offset = segment.offset + (Constants.TYPE_PROTO_ID_ITEM_SIZE * index);
-    file.position(offset);
-    int shortyIndex = file.getUint();
-    int returnTypeIndex = file.getUint();
-    int parametersOffsetIndex = file.getUint();
+    int offset = dexSection.offset + (Constants.TYPE_PROTO_ID_ITEM_SIZE * index);
+    dexReader.position(offset);
+    int shortyIndex = dexReader.getUint();
+    int returnTypeIndex = dexReader.getUint();
+    int parametersOffsetIndex = dexReader.getUint();
     DexString shorty = indexedItems.getString(shortyIndex);
     DexType returnType = indexedItems.getType(returnTypeIndex);
     DexTypeList parameters = typeListAt(parametersOffsetIndex);
@@ -1006,15 +1007,15 @@
   }
 
   private DexMethod methodAt(int index) {
-    Segment segment = lookupSegment(Constants.TYPE_METHOD_ID_ITEM);
-    if (index >= segment.length) {
+    DexSection dexSection = lookupSection(Constants.TYPE_METHOD_ID_ITEM);
+    if (index >= dexSection.length) {
       return null;
     }
-    int offset = segment.offset + (Constants.TYPE_METHOD_ID_ITEM_SIZE * index);
-    file.position(offset);
-    int classIndex = file.getUshort();
-    int protoIndex = file.getUshort();
-    int nameIndex = file.getUint();
+    int offset = dexSection.offset + (Constants.TYPE_METHOD_ID_ITEM_SIZE * index);
+    dexReader.position(offset);
+    int classIndex = dexReader.getUshort();
+    int protoIndex = dexReader.getUshort();
+    int nameIndex = dexReader.getUint();
     return dexItemFactory.createMethod(
         indexedItems.getType(classIndex),
         indexedItems.getProto(protoIndex),
diff --git a/src/main/java/com/android/tools/r8/dex/DexFile.java b/src/main/java/com/android/tools/r8/dex/DexReader.java
similarity index 91%
rename from src/main/java/com/android/tools/r8/dex/DexFile.java
rename to src/main/java/com/android/tools/r8/dex/DexReader.java
index cc85fd9..44bacc6 100644
--- a/src/main/java/com/android/tools/r8/dex/DexFile.java
+++ b/src/main/java/com/android/tools/r8/dex/DexReader.java
@@ -14,11 +14,14 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
-public class DexFile extends BaseFile {
+/**
+ * {@link BinaryReader} for Dex content.
+ */
+public class DexReader extends BinaryReader {
 
   private final int version;
 
-  public DexFile(ProgramResource resource) throws ResourceException, IOException {
+  public DexReader(ProgramResource resource) throws ResourceException, IOException {
     super(resource);
     version = parseMagic(buffer);
   }
@@ -28,7 +31,7 @@
    *
    * @param bytes contents of the file
    */
-  DexFile(Origin origin, byte[] bytes) {
+  DexReader(Origin origin, byte[] bytes) {
     super(origin, bytes);
     version = parseMagic(buffer);
   }
diff --git a/src/main/java/com/android/tools/r8/dex/Segment.java b/src/main/java/com/android/tools/r8/dex/DexSection.java
similarity index 91%
rename from src/main/java/com/android/tools/r8/dex/Segment.java
rename to src/main/java/com/android/tools/r8/dex/DexSection.java
index 7836438..3013f7a 100644
--- a/src/main/java/com/android/tools/r8/dex/Segment.java
+++ b/src/main/java/com/android/tools/r8/dex/DexSection.java
@@ -3,13 +3,16 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.dex;
 
-public class Segment {
+/**
+ * A section as defined by the Dex file format.
+ */
+public class DexSection {
   public final int type;
   public final int length;
   public final int offset;
   private int end;
 
-  public Segment(int type, int unused, int length, int offset) {
+  public DexSection(int type, int unused, int length, int offset) {
     this.type = type;
     assert unused == 0;
     this.length = length;
@@ -21,7 +24,7 @@
     this.end = end;
   }
 
-  // Returns the byte size of this segment.
+  // Returns the byte size of this section.
   public int size() {
     return end - offset;
   }
diff --git a/src/main/java/com/android/tools/r8/dex/VDexFileReader.java b/src/main/java/com/android/tools/r8/dex/VDexFileReader.java
deleted file mode 100644
index 4865061..0000000
--- a/src/main/java/com/android/tools/r8/dex/VDexFileReader.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8.dex;
-
-import static com.android.tools.r8.dex.Constants.VDEX_NUMBER_OF_DEX_FILES_OFFSET;
-
-import com.android.tools.r8.errors.CompilationError;
-import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
-import java.util.List;
-
-public class VDexFileReader {
-
-  private VDexFile file;
-  private List<byte[]> dexFiles = new ArrayList<>();
-
-  public void close() {
-    file = null;
-    dexFiles = ImmutableList.of();
-  }
-
-  public VDexFileReader(VDexFile file) {
-    this.file = file;
-    file.setByteOrder();
-    parseDexFiles();
-  }
-
-  public List<byte[]> getDexFiles() {
-    return dexFiles;
-  }
-
-  private void parseDexFiles() {
-    file.position(VDEX_NUMBER_OF_DEX_FILES_OFFSET);
-    int numberOfDexFiles = file.getUint();
-    int dexSize = file.getUint();
-    int verifierDepsSize = file.getUint();
-    int quickeningInfoSize = file.getUint();
-
-    int offset = VDexFile.firstDexOffset(numberOfDexFiles);
-    int totalDexSize = 0;
-    for (int i = 0; i < numberOfDexFiles; i++) {
-      int size = file.getUint(offset + Constants.FILE_SIZE_OFFSET);
-      file.position(offset);
-      dexFiles.add(file.getByteArray(size));
-      totalDexSize += size;
-      offset += size;
-    }
-    if (totalDexSize != dexSize) {
-      throw new CompilationError("Invalid vdex file. Mismatch in total dex files size");
-    }
-  }
-}
diff --git a/src/main/java/com/android/tools/r8/dex/VDexParser.java b/src/main/java/com/android/tools/r8/dex/VDexParser.java
new file mode 100644
index 0000000..c75667a
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/dex/VDexParser.java
@@ -0,0 +1,56 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.dex;
+
+import static com.android.tools.r8.dex.Constants.VDEX_NUMBER_OF_DEX_FILES_OFFSET;
+
+import com.android.tools.r8.errors.CompilationError;
+import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Parse a VDEX and isolate the different dex files it contains.
+ */
+public class VDexParser {
+
+  private VDexReader vDexReader;
+  private List<byte[]> dexFiles = new ArrayList<>();
+
+  public void close() {
+    vDexReader = null;
+    dexFiles = ImmutableList.of();
+  }
+
+  public VDexParser(VDexReader vDexReader) {
+    this.vDexReader = vDexReader;
+    vDexReader.setByteOrder();
+    parseDexFiles();
+  }
+
+  public List<byte[]> getDexFiles() {
+    return dexFiles;
+  }
+
+  private void parseDexFiles() {
+    vDexReader.position(VDEX_NUMBER_OF_DEX_FILES_OFFSET);
+    int numberOfDexFiles = vDexReader.getUint();
+    int dexSize = vDexReader.getUint();
+    int verifierDepsSize = vDexReader.getUint();
+    int quickeningInfoSize = vDexReader.getUint();
+
+    int offset = VDexReader.firstDexOffset(numberOfDexFiles);
+    int totalDexSize = 0;
+    for (int i = 0; i < numberOfDexFiles; i++) {
+      int size = vDexReader.getUint(offset + Constants.FILE_SIZE_OFFSET);
+      vDexReader.position(offset);
+      dexFiles.add(vDexReader.getByteArray(size));
+      totalDexSize += size;
+      offset += size;
+    }
+    if (totalDexSize != dexSize) {
+      throw new CompilationError("Invalid vdex file. Mismatch in total dex files size");
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/dex/VDexFile.java b/src/main/java/com/android/tools/r8/dex/VDexReader.java
similarity index 96%
rename from src/main/java/com/android/tools/r8/dex/VDexFile.java
rename to src/main/java/com/android/tools/r8/dex/VDexReader.java
index 6d13020..a3a5a2f 100644
--- a/src/main/java/com/android/tools/r8/dex/VDexFile.java
+++ b/src/main/java/com/android/tools/r8/dex/VDexReader.java
@@ -20,11 +20,11 @@
 /**
  * See runtime/vdex_file.h and runtime/vdex_file.cc in the Art code for the vdex file format.
  */
-public class VDexFile extends BaseFile {
+public class VDexReader extends BinaryReader {
 
   private final int version;
 
-  public VDexFile(Origin origin, InputStream stream) throws IOException {
+  public VDexReader(Origin origin, InputStream stream) throws IOException {
     super(origin, ByteStreams.toByteArray(stream));
     version = parseMagic(buffer);
     if (!supportedVersion(version)) {
diff --git a/src/main/java/com/android/tools/r8/utils/EncodedValueUtils.java b/src/main/java/com/android/tools/r8/utils/EncodedValueUtils.java
index d6848a4..e94f30d 100644
--- a/src/main/java/com/android/tools/r8/utils/EncodedValueUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/EncodedValueUtils.java
@@ -3,21 +3,21 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.utils;
 
-import com.android.tools.r8.dex.DexFile;
+import com.android.tools.r8.dex.DexReader;
 import com.android.tools.r8.dex.DexOutputBuffer;
 
 public class EncodedValueUtils {
 
-  public static long parseSigned(DexFile file, int numberOfBytes) {
+  public static long parseSigned(DexReader dexReader, int numberOfBytes) {
     assert numberOfBytes > 0;
     long result = 0;
     int shift = 0;
     for (int i = 1; i < numberOfBytes; i++) {
-      result |= ((long) (file.get() & 0xFF)) << shift;
+      result |= ((long) (dexReader.get() & 0xFF)) << shift;
       shift += 8;
     }
     // Let the last byte sign-extend into any remaining bytes.
-    return result | (((long) file.get()) << shift);
+    return result | (((long) dexReader.get()) << shift);
   }
 
   // Inspired by com.android.dex.EncodedValueCodec
@@ -44,12 +44,12 @@
     return result;
   }
 
-  public static long parseUnsigned(DexFile file, int numberOfBytes) {
+  public static long parseUnsigned(DexReader dexReader, int numberOfBytes) {
     assert numberOfBytes > 0;
     long result = 0;
     int shift = 0;
     for (int i = 0; i < numberOfBytes; i++) {
-      result |= ((long) (file.get() & 0xFF)) << shift;
+      result |= ((long) (dexReader.get() & 0xFF)) << shift;
       shift += 8;
     }
     return result;
@@ -104,8 +104,9 @@
     return result;
   }
 
-  public static float parseFloat(DexFile file, int numberOfBytes) {
-    long bits = parseUnsigned(file, numberOfBytes) << ((Float.BYTES - numberOfBytes) * Byte.SIZE);
+  public static float parseFloat(DexReader dexReader, int numberOfBytes) {
+    long bits =
+        parseUnsigned(dexReader, numberOfBytes) << ((Float.BYTES - numberOfBytes) * Byte.SIZE);
     return Float.intBitsToFloat((int) bits);
   }
 
@@ -121,8 +122,9 @@
     return result;
   }
 
-  public static double parseDouble(DexFile file, int numberOfBytes) {
-    long bits = parseUnsigned(file, numberOfBytes) << ((Double.BYTES - numberOfBytes) * Byte.SIZE);
+  public static double parseDouble(DexReader dexReader, int numberOfBytes) {
+    long bits =
+        parseUnsigned(dexReader, numberOfBytes) << ((Double.BYTES - numberOfBytes) * Byte.SIZE);
     return Double.longBitsToDouble(bits);
   }
 
diff --git a/src/main/java/com/android/tools/r8/utils/LebUtils.java b/src/main/java/com/android/tools/r8/utils/LebUtils.java
index 90c1c10..437a261 100644
--- a/src/main/java/com/android/tools/r8/utils/LebUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/LebUtils.java
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.utils;
 
-import com.android.tools.r8.dex.BaseFile;
+import com.android.tools.r8.dex.BinaryReader;
 import com.android.tools.r8.dex.DexOutputBuffer;
 import java.util.Arrays;
 
@@ -13,12 +13,12 @@
   private static final int MORE_DATA_TAG_BIT = 0x80;
   private static final int MAX_BYTES_PER_VALUE = 5;
 
-  public static int parseUleb128(BaseFile file) {
+  public static int parseUleb128(BinaryReader reader) {
     int result = 0;
     byte b;
     int shift = 0;
     do {
-      b = file.get();
+      b = reader.get();
       result |= (b & (byte) PAYLOAD_MASK) << shift;
       shift += BITS_PER_ENCODED_BYTE;
     } while ((b & ~(byte) PAYLOAD_MASK) == ~(byte) PAYLOAD_MASK);
@@ -57,12 +57,12 @@
         .max(1, (Integer.SIZE - Integer.numberOfLeadingZeros(value) + 6) / BITS_PER_ENCODED_BYTE);
   }
 
-  public static int parseSleb128(BaseFile file) {
+  public static int parseSleb128(BinaryReader reader) {
     int result = 0;
     byte b;
     int shift = 0;
     do {
-      b = file.get();
+      b = reader.get();
       result |= (b & (byte) PAYLOAD_MASK) << shift;
       shift += BITS_PER_ENCODED_BYTE;
     } while ((b & ~(byte) PAYLOAD_MASK) == ~(byte) PAYLOAD_MASK);
diff --git a/src/test/java/com/android/tools/r8/R8CodeCanonicalizationTest.java b/src/test/java/com/android/tools/r8/R8CodeCanonicalizationTest.java
index 2f60037..405994c 100644
--- a/src/test/java/com/android/tools/r8/R8CodeCanonicalizationTest.java
+++ b/src/test/java/com/android/tools/r8/R8CodeCanonicalizationTest.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8;
 
 import com.android.tools.r8.dex.Constants;
-import com.android.tools.r8.dex.DexFileReader;
-import com.android.tools.r8.dex.Segment;
+import com.android.tools.r8.dex.DexParser;
+import com.android.tools.r8.dex.DexSection;
 import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -20,10 +20,10 @@
       ToolHelper.EXAMPLES_BUILD_DIR, "invokeempty", "classes.dex");
 
   private int readNumberOfCodes(Path file) throws IOException {
-    Segment[] segments = DexFileReader.parseMapFrom(file);
-    for (Segment segment : segments) {
-      if (segment.type == Constants.TYPE_CODE_ITEM) {
-        return segment.length;
+    DexSection[] dexSections = DexParser.parseMapFrom(file);
+    for (DexSection dexSection : dexSections) {
+      if (dexSection.type == Constants.TYPE_CODE_ITEM) {
+        return dexSection.length;
       }
     }
     return 0;
diff --git a/src/test/java/com/android/tools/r8/dex/EncodedFloatingValueTest.java b/src/test/java/com/android/tools/r8/dex/EncodedFloatingValueTest.java
index f1967e5..b61ea58 100644
--- a/src/test/java/com/android/tools/r8/dex/EncodedFloatingValueTest.java
+++ b/src/test/java/com/android/tools/r8/dex/EncodedFloatingValueTest.java
@@ -42,33 +42,33 @@
     );
   }
 
-  // Create a DexFile with correct file magic followed by the argument bytes. Positions the
-  // DexFile after the file magic.
-  private DexFile createDexFileWithContent(byte[] bytes) {
+  // Create a DexReader with correct file magic followed by the argument bytes. Positions the
+  // DexReader after the file magic.
+  private DexReader createDexFileWithContent(byte[] bytes) {
     DexOutputBuffer buffer = new DexOutputBuffer();
     buffer.putBytes(Constants.DEX_FILE_MAGIC_PREFIX);
     buffer.putBytes(AndroidApiLevel.B.getDexVersion().getBytes());
     buffer.putByte(Constants.DEX_FILE_MAGIC_SUFFIX);
     buffer.putBytes(bytes);
-    DexFile dexFile = new DexFile(Origin.unknown(), buffer.asArray());
-    dexFile.position(DEX_MAGIC_SIZE);
-    return dexFile;
+    DexReader dexReader = new DexReader(Origin.unknown(), buffer.asArray());
+    dexReader.position(DEX_MAGIC_SIZE);
+    return dexReader;
   }
 
   @Test
   public void testEncodeDecodeDouble() {
     byte[] bytes = EncodedValueUtils.encodeDouble(value);
     assertTrue(bytes.length <= Double.BYTES);
-    DexFile dexFile = createDexFileWithContent(bytes);
-    Assert.assertEquals(value, EncodedValueUtils.parseDouble(dexFile, bytes.length), 0.0);
+    DexReader dexReader = createDexFileWithContent(bytes);
+    Assert.assertEquals(value, EncodedValueUtils.parseDouble(dexReader, bytes.length), 0.0);
   }
 
   @Test
   public void testEncodeDecodeFloat() {
     byte[] bytes = EncodedValueUtils.encodeFloat((float) value);
     assertTrue(bytes.length <= Float.BYTES);
-    DexFile dexFile = createDexFileWithContent(bytes);
-    Assert.assertEquals((float) value, EncodedValueUtils.parseFloat(dexFile, bytes.length), 0.0f);
+    DexReader dexReader = createDexFileWithContent(bytes);
+    Assert.assertEquals((float) value, EncodedValueUtils.parseFloat(dexReader, bytes.length), 0.0f);
   }
 
   @Test
@@ -77,8 +77,8 @@
     int length = EncodedValueUtils.putDouble(buffer, value);
     assertTrue(length <= Double.BYTES);
     byte[] bytes = buffer.asArray();
-    DexFile dexFile = createDexFileWithContent(bytes);
-    assertEquals(value, EncodedValueUtils.parseDouble(dexFile, length), 0.0);
+    DexReader dexReader = createDexFileWithContent(bytes);
+    assertEquals(value, EncodedValueUtils.parseDouble(dexReader, length), 0.0);
   }
 
   @Test
@@ -87,7 +87,7 @@
     int length = EncodedValueUtils.putFloat(buffer, (float) value);
     assertTrue(length <= Float.BYTES);
     byte[] bytes = buffer.asArray();
-    DexFile dexFile = createDexFileWithContent(bytes);
-    assertEquals((float) value, EncodedValueUtils.parseFloat(dexFile, length), 0.0f);
+    DexReader dexReader = createDexFileWithContent(bytes);
+    assertEquals((float) value, EncodedValueUtils.parseFloat(dexReader, length), 0.0f);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/dex/Leb128Test.java b/src/test/java/com/android/tools/r8/dex/Leb128Test.java
index 609c652..e722984 100644
--- a/src/test/java/com/android/tools/r8/dex/Leb128Test.java
+++ b/src/test/java/com/android/tools/r8/dex/Leb128Test.java
@@ -45,17 +45,17 @@
     );
   }
 
-  // Create a DexFile with correct file magic followed by the argument bytes. Positions the
-  // DexFile after the file magic.
-  private DexFile createDexFileWithContent(byte[] bytes) {
+  // Create a DexReader with correct file magic followed by the argument bytes. Positions the
+  // DexReader after the file magic.
+  private DexReader createDexFileWithContent(byte[] bytes) {
     DexOutputBuffer buffer = new DexOutputBuffer();
     buffer.putBytes(Constants.DEX_FILE_MAGIC_PREFIX);
     buffer.putBytes(AndroidApiLevel.B.getDexVersion().getBytes());
     buffer.putByte(Constants.DEX_FILE_MAGIC_SUFFIX);
     buffer.putBytes(bytes);
-    DexFile dexFile = new DexFile(Origin.unknown(), buffer.asArray());
-    dexFile.position(DEX_MAGIC_SIZE);
-    return dexFile;
+    DexReader dexReader = new DexReader(Origin.unknown(), buffer.asArray());
+    dexReader.position(DEX_MAGIC_SIZE);
+    return dexReader;
   }
 
   @Test
@@ -66,8 +66,8 @@
     DexOutputBuffer buffer = new DexOutputBuffer();
     LebUtils.putUleb128(buffer, value);
     Assert.assertEquals(buffer.position(), LebUtils.sizeAsUleb128(value));
-    DexFile file = createDexFileWithContent(buffer.asArray());
-    Assert.assertEquals(value, LebUtils.parseUleb128(file));
+    DexReader reader = createDexFileWithContent(buffer.asArray());
+    Assert.assertEquals(value, LebUtils.parseUleb128(reader));
   }
 
   @Test
@@ -77,8 +77,8 @@
     }
     byte[] encoded = LebUtils.encodeUleb128(value);
     Assert.assertEquals(encoded.length, LebUtils.sizeAsUleb128(value));
-    DexFile file = createDexFileWithContent(encoded);
-    Assert.assertEquals(value, LebUtils.parseUleb128(file));
+    DexReader reader = createDexFileWithContent(encoded);
+    Assert.assertEquals(value, LebUtils.parseUleb128(reader));
   }
 
   @Test
@@ -86,8 +86,8 @@
     DexOutputBuffer buffer = new DexOutputBuffer();
     LebUtils.putSleb128(buffer, value);
     Assert.assertEquals(buffer.position(), LebUtils.sizeAsSleb128(value));
-    DexFile file = createDexFileWithContent(buffer.asArray());
-    Assert.assertEquals(value, LebUtils.parseSleb128(file));
+    DexReader reader = createDexFileWithContent(buffer.asArray());
+    Assert.assertEquals(value, LebUtils.parseSleb128(reader));
   }
 
 
@@ -95,7 +95,7 @@
   public void encodeDecodeSLeb128Test() {
     byte[] encoded = LebUtils.encodeSleb128(value);
     Assert.assertEquals(encoded.length, LebUtils.sizeAsSleb128(value));
-    DexFile file = createDexFileWithContent(encoded);
-    Assert.assertEquals(value, LebUtils.parseSleb128(file));
+    DexReader reader = createDexFileWithContent(encoded);
+    Assert.assertEquals(value, LebUtils.parseSleb128(reader));
   }
 }