diff --git a/api/test-current.txt b/api/test-current.txt
index 67a26f3..2bf3900 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2840,31 +2840,6 @@
     method public void writeRawZigZag64(long);
   }
 
-  public final class ProtoInputStream extends android.util.proto.ProtoStream {
-    ctor public ProtoInputStream(java.io.InputStream, int);
-    ctor public ProtoInputStream(java.io.InputStream);
-    ctor public ProtoInputStream(byte[]);
-    method public int decodeZigZag32(int);
-    method public long decodeZigZag64(long);
-    method public String dumpDebugData();
-    method public void end(long);
-    method public int getFieldNumber();
-    method public int getOffset();
-    method public int getWireType();
-    method public boolean isNextField(long) throws java.io.IOException;
-    method public int nextField() throws java.io.IOException;
-    method public boolean readBoolean(long) throws java.io.IOException;
-    method public byte[] readBytes(long) throws java.io.IOException;
-    method public double readDouble(long) throws java.io.IOException;
-    method public float readFloat(long) throws java.io.IOException;
-    method public int readInt(long) throws java.io.IOException;
-    method public long readLong(long) throws java.io.IOException;
-    method public String readString(long) throws java.io.IOException;
-    method public void skip() throws java.io.IOException;
-    method public long start(long) throws java.io.IOException;
-    field public static final int NO_MORE_FIELDS = -1; // 0xffffffff
-  }
-
   public final class ProtoOutputStream extends android.util.proto.ProtoStream {
     ctor public ProtoOutputStream();
     ctor public ProtoOutputStream(int);
diff --git a/core/java/android/util/proto/ProtoInputStream.java b/core/java/android/util/proto/ProtoInputStream.java
index cd2b6ce..c290dff 100644
--- a/core/java/android/util/proto/ProtoInputStream.java
+++ b/core/java/android/util/proto/ProtoInputStream.java
@@ -16,8 +16,6 @@
 
 package android.util.proto;
 
-import android.annotation.TestApi;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
@@ -64,7 +62,6 @@
  *
  * @hide
  */
-@TestApi
 public final class ProtoInputStream extends ProtoStream {
 
     public static final int NO_MORE_FIELDS = -1;
diff --git a/core/java/android/util/proto/TEST_MAPPING b/core/java/android/util/proto/TEST_MAPPING
new file mode 100644
index 0000000..cf9f077
--- /dev/null
+++ b/core/java/android/util/proto/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "ProtoInputStreamTests"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/tests/ProtoInputStreamTests/Android.mk b/tests/ProtoInputStreamTests/Android.mk
new file mode 100644
index 0000000..eb747cc
--- /dev/null
+++ b/tests/ProtoInputStreamTests/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := ProtoInputStreamTests
+LOCAL_PROTOC_OPTIMIZE_TYPE := nano
+LOCAL_MODULE_TAGS := tests optional
+LOCAL_SRC_FILES := \
+    $(call all-java-files-under, src) \
+    $(call all-proto-files-under, src)
+LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_CERTIFICATE := platform
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    androidx.test.rules \
+    frameworks-base-testutils \
+    mockito-target-minus-junit4
+
+include $(BUILD_PACKAGE)
\ No newline at end of file
diff --git a/tests/ProtoInputStreamTests/AndroidManifest.xml b/tests/ProtoInputStreamTests/AndroidManifest.xml
new file mode 100644
index 0000000..c11aa73
--- /dev/null
+++ b/tests/ProtoInputStreamTests/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.test.protoinputstream">
+    <application>
+        <uses-library android:name="android.test.runner"/>
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.test.protoinputstream"
+                     android:label="ProtoInputStream Tests">
+    </instrumentation>
+</manifest>
\ No newline at end of file
diff --git a/tests/ProtoInputStreamTests/AndroidTest.xml b/tests/ProtoInputStreamTests/AndroidTest.xml
new file mode 100644
index 0000000..51ab88e
--- /dev/null
+++ b/tests/ProtoInputStreamTests/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Configuration for ProtoInputStream Tests">
+    <option name="test-suite-tag" value="ProtoInputStreamTests" />
+    <option name="config-descriptor:metadata" key="component" value="metrics" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="ProtoInputStreamTests.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.test.protoinputstream" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/tests/ProtoInputStreamTests/TEST_MAPPING b/tests/ProtoInputStreamTests/TEST_MAPPING
new file mode 100644
index 0000000..cf9f077
--- /dev/null
+++ b/tests/ProtoInputStreamTests/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "ProtoInputStreamTests"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBoolTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBoolTest.java
new file mode 100644
index 0000000..c21c403
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBoolTest.java
@@ -0,0 +1,500 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamBoolTest extends TestCase {
+
+    /**
+     * Test reading single bool field
+     */
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    /**
+     * Implementation of testRead with a given chunkSize.
+     */
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_BOOL;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 3 -> 1
+                (byte) 0x18,
+                (byte) 0x01,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        boolean[] results = new boolean[2];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readBoolean(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(false, results[0]);
+        assertEquals(true, results[1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(false);
+        testReadCompat(true);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(boolean val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_BOOL;
+        final long fieldId = fieldFlags | ((long) 130 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.boolField = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        boolean result = false; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readBoolean(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.boolField, result);
+    }
+
+
+    /**
+     * Test reading repeated bool field
+     */
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    /**
+     * Implementation of testRepeated with a given chunkSize.
+     */
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_BOOL;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+
+                // 4 -> 0
+                (byte) 0x20,
+                (byte) 0x00,
+                // 4 -> 1
+                (byte) 0x20,
+                (byte) 0x01,
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+
+                // 3 -> 0
+                (byte) 0x18,
+                (byte) 0x00,
+                // 3 -> 1
+                (byte) 0x18,
+                (byte) 0x01,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        boolean[][] results = new boolean[3][2];
+        int[] indices = new int[3];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readBoolean(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readBoolean(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readBoolean(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(false, results[0][0]);
+        assertEquals(false, results[0][1]);
+        assertEquals(true, results[1][0]);
+        assertEquals(true, results[1][1]);
+        assertEquals(false, results[2][0]);
+        assertEquals(true, results[2][1]);
+    }
+
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new boolean[0]);
+        testRepeatedCompat(new boolean[]{false, true});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(boolean[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_BOOL;
+        final long fieldId = fieldFlags | ((long) 131 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.boolFieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        boolean[] result = new boolean[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readBoolean(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.boolFieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.boolFieldRepeated[i], result[i]);
+        }
+    }
+
+    /**
+     * Test reading packed bool field
+     */
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    /**
+     * Implementation of testPacked with a given chunkSize.
+     */
+    public void testPacked(int chunkSize) throws IOException {
+
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_BOOL;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x02,
+                (byte) 0x00,
+                (byte) 0x00,
+                // 4 -> 0,1
+                (byte) 0x22,
+                (byte) 0x02,
+                (byte) 0x00,
+                (byte) 0x01,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x02,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 3 -> 0,1
+                (byte) 0x1a,
+                (byte) 0x02,
+                (byte) 0x00,
+                (byte) 0x01,
+        };
+
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        boolean[][] results = new boolean[3][2];
+        int[] indices = new int[3];
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readBoolean(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readBoolean(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readBoolean(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(false, results[0][0]);
+        assertEquals(false, results[0][1]);
+        assertEquals(true, results[1][0]);
+        assertEquals(true, results[1][1]);
+        assertEquals(false, results[2][0]);
+        assertEquals(true, results[2][1]);
+    }
+
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new boolean[0]);
+        testPackedCompat(new boolean[]{false, true});
+    }
+
+    /**
+     * Implementation of testPackedCompat with a given value.
+     */
+    private void testPackedCompat(boolean[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_BOOL;
+        final long fieldId = fieldFlags | ((long) 132 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.boolFieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        boolean[] result = new boolean[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readBoolean(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.boolFieldPacked.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.boolFieldPacked[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_BOOL;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readInt(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readLong(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_BOOL;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readBoolean(fieldId1);
+                        // don't fail, varint is ok
+                        break;
+                    case (int) fieldId2:
+                        pi.readBoolean(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readBoolean(fieldId3);
+                        // don't fail, length delimited is ok (represents packed booleans)
+                        break;
+                    case (int) fieldId6:
+                        pi.readBoolean(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBytesTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBytesTest.java
new file mode 100644
index 0000000..09fe40e
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBytesTest.java
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+public class ProtoInputStreamBytesTest extends TestCase {
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_BYTES;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> null - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x00,
+                // 2 -> { } - default value, written when repeated
+                (byte) 0x12,
+                (byte) 0x00,
+                // 5 -> { 0, 1, 2, 3, 4 }
+                (byte) 0x2a,
+                (byte) 0x05,
+                (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
+                // 3 -> { 0, 1, 2, 3, 4, 5 }
+                (byte) 0x1a,
+                (byte) 0x06,
+                (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05,
+                // 4 -> { (byte)0xff, (byte)0xfe, (byte)0xfd, (byte)0xfc }
+                (byte) 0x22,
+                (byte) 0x04,
+                (byte) 0xff, (byte) 0xfe, (byte) 0xfd, (byte) 0xfc,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        byte[][] results = new byte[4][];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0] = pi.readBytes(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readBytes(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readBytes(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readBytes(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertTrue("Expected: []  Actual: " + Arrays.toString(results[0]),
+                Arrays.equals(new byte[]{}, results[0]));
+        assertTrue("Expected: []  Actual: " + Arrays.toString(results[1]),
+                Arrays.equals(new byte[]{}, results[1]));
+        assertTrue("Expected: [0, 1, 2, 3, 4, 5]  Actual: " + Arrays.toString(results[2]),
+                Arrays.equals(new byte[]{0, 1, 2, 3, 4, 5}, results[2]));
+        assertTrue("Expected: [-1, -2, -3, -4]  Actual: " + Arrays.toString(results[3]),
+                Arrays.equals(new byte[]{(byte) 0xff, (byte) 0xfe, (byte) 0xfd, (byte) 0xfc},
+                        results[3]));
+    }
+
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(new byte[0]);
+        testReadCompat(new byte[]{1, 2, 3, 4});
+        testReadCompat(new byte[]{(byte) 0xff, (byte) 0xfe, (byte) 0xfd, (byte) 0xfc});
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(byte[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_BYTES;
+        final long fieldId = fieldFlags | ((long) 150 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.bytesField = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        byte[] result = new byte[val.length];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readBytes(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.bytesField.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.bytesField[i], result[i]);
+        }
+    }
+
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_BYTES;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> null - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x00,
+                // 2 -> { } - default value, written when repeated
+                (byte) 0x12,
+                (byte) 0x00,
+                // 3 -> { 0, 1, 2, 3, 4, 5 }
+                (byte) 0x1a,
+                (byte) 0x06,
+                (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05,
+                // 4 -> { (byte)0xff, (byte)0xfe, (byte)0xfd, (byte)0xfc }
+                (byte) 0x22,
+                (byte) 0x04,
+                (byte) 0xff, (byte) 0xfe, (byte) 0xfd, (byte) 0xfc,
+
+                // 5 -> { 0, 1, 2, 3, 4}
+                (byte) 0x2a,
+                (byte) 0x05,
+                (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
+
+                // 1 -> null - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x00,
+                // 2 -> { } - default value, written when repeated
+                (byte) 0x12,
+                (byte) 0x00,
+                // 3 -> { 0, 1, 2, 3, 4, 5 }
+                (byte) 0x1a,
+                (byte) 0x06,
+                (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05,
+                // 4 -> { (byte)0xff, (byte)0xfe, (byte)0xfd, (byte)0xfc }
+                (byte) 0x22,
+                (byte) 0x04,
+                (byte) 0xff, (byte) 0xfe, (byte) 0xfd, (byte) 0xfc,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        byte[][][] results = new byte[4][2][];
+        int[] indices = new int[4];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readBytes(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readBytes(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readBytes(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readBytes(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assert (Arrays.equals(new byte[]{}, results[0][0]));
+        assert (Arrays.equals(new byte[]{}, results[0][1]));
+        assert (Arrays.equals(new byte[]{}, results[1][0]));
+        assert (Arrays.equals(new byte[]{}, results[1][1]));
+        assert (Arrays.equals(new byte[]{1, 2, 3, 4}, results[2][0]));
+        assert (Arrays.equals(new byte[]{1, 2, 3, 4}, results[2][1]));
+        assert (Arrays.equals(new byte[]{(byte) 0xff, (byte) 0xfe, (byte) 0xfd, (byte) 0xfc},
+                results[3][0]));
+        assert (Arrays.equals(new byte[]{(byte) 0xff, (byte) 0xfe, (byte) 0xfd, (byte) 0xfc},
+                results[3][1]));
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new byte[0][]);
+        testRepeatedCompat(new byte[][]{
+                new byte[0],
+                new byte[]{1, 2, 3, 4},
+                new byte[]{(byte) 0xff, (byte) 0xfe, (byte) 0xfd, (byte) 0xfc}
+        });
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(byte[][] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_BYTES;
+        final long fieldId = fieldFlags | ((long) 151 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.bytesFieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        byte[][] result = new byte[val.length][]; // start off with default value
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readBytes(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.bytesFieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.bytesFieldRepeated[i].length, result[i].length);
+            for (int j = 0; j < result[i].length; j++) {
+                assertEquals(readback.bytesFieldRepeated[i][j], result[i][j]);
+            }
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_BYTES;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> {1}
+                (byte) 0x0a,
+                (byte) 0x01,
+                (byte) 0x01,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readInt(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readLong(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_BYTES;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readBytes(fieldId1);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId2:
+                        pi.readBytes(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readBytes(fieldId3);
+                        // don't fail, length delimited is ok
+                        break;
+                    case (int) fieldId6:
+                        pi.readBytes(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamDoubleTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamDoubleTest.java
new file mode 100644
index 0000000..118fe34
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamDoubleTest.java
@@ -0,0 +1,728 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamDoubleTest extends TestCase {
+
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_DOUBLE;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+        final long fieldId9 = fieldFlags | ((long) 9 & 0x0ffffffffL);
+        final long fieldId10 = fieldFlags | ((long) 10 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 2 -> 1
+                (byte) 0x11,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x3f,
+                // 10 -> 1
+                (byte) 0x51,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x3f,
+                // 3 -> -1234.432
+                (byte) 0x19,
+                (byte) 0x7d, (byte) 0x3f, (byte) 0x35, (byte) 0x5e,
+                (byte) 0xba, (byte) 0x49, (byte) 0x93, (byte) 0xc0,
+                // 4 -> 42.42
+                (byte) 0x21,
+                (byte) 0xf6, (byte) 0x28, (byte) 0x5c, (byte) 0x8f,
+                (byte) 0xc2, (byte) 0x35, (byte) 0x45, (byte) 0x40,
+                // 5 -> Double.MIN_NORMAL
+                (byte) 0x29,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x10, (byte) 0x00,
+                // 6 -> DOUBLE.MIN_VALUE
+                (byte) 0x31,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 7 -> Double.NEGATIVE_INFINITY
+                (byte) 0x39,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0xff,
+                // 8 -> Double.NaN
+                (byte) 0x41,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf8, (byte) 0x7f,
+                // 9 -> Double.POSITIVE_INFINITY
+                (byte) 0x49,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        double[] results = new double[9];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readDouble(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readDouble(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readDouble(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4] = pi.readDouble(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5] = pi.readDouble(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6] = pi.readDouble(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    results[7] = pi.readDouble(fieldId8);
+                    break;
+                case (int) fieldId9:
+                    results[8] = pi.readDouble(fieldId9);
+                    break;
+                case (int) fieldId10:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+        assertEquals(0.0, results[0]);
+        assertEquals(1.0, results[1]);
+        assertEquals(-1234.432, results[2]);
+        assertEquals(42.42, results[3]);
+        assertEquals(Double.MIN_NORMAL, results[4]);
+        assertEquals(Double.MIN_VALUE, results[5]);
+        assertEquals(Double.NEGATIVE_INFINITY, results[6]);
+        assertEquals(Double.NaN, results[7]);
+        assertEquals(Double.POSITIVE_INFINITY, results[8]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(0);
+        testReadCompat(1);
+        testReadCompat(-1234.432);
+        testReadCompat(42.42);
+        testReadCompat(Double.MIN_NORMAL);
+        testReadCompat(Double.MIN_VALUE);
+        testReadCompat(Double.NEGATIVE_INFINITY);
+        testReadCompat(Double.NaN);
+        testReadCompat(Double.POSITIVE_INFINITY);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(double val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_DOUBLE;
+        final long fieldId = fieldFlags | ((long) 10 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.doubleField = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        double result = 0.0; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readDouble(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.doubleField, result);
+    }
+
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_DOUBLE;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+        final long fieldId9 = fieldFlags | ((long) 9 & 0x0ffffffffL);
+        final long fieldId10 = fieldFlags | ((long) 10 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x09,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x11,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x3f,
+                // 3 -> -1234.432
+                (byte) 0x19,
+                (byte) 0x7d, (byte) 0x3f, (byte) 0x35, (byte) 0x5e,
+                (byte) 0xba, (byte) 0x49, (byte) 0x93, (byte) 0xc0,
+                // 4 -> 42.42
+                (byte) 0x21,
+                (byte) 0xf6, (byte) 0x28, (byte) 0x5c, (byte) 0x8f,
+                (byte) 0xc2, (byte) 0x35, (byte) 0x45, (byte) 0x40,
+                // 5 -> Double.MIN_NORMAL
+                (byte) 0x29,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x10, (byte) 0x00,
+                // 6 -> DOUBLE.MIN_VALUE
+                (byte) 0x31,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 7 -> Double.NEGATIVE_INFINITY
+                (byte) 0x39,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0xff,
+                // 8 -> Double.NaN
+                (byte) 0x41,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf8, (byte) 0x7f,
+                // 9 -> Double.POSITIVE_INFINITY
+                (byte) 0x49,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x7f,
+                // 10 -> 1
+                (byte) 0x51,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x3f,
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x09,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x11,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x3f,
+                // 3 -> -1234.432
+                (byte) 0x19,
+                (byte) 0x7d, (byte) 0x3f, (byte) 0x35, (byte) 0x5e,
+                (byte) 0xba, (byte) 0x49, (byte) 0x93, (byte) 0xc0,
+                // 4 -> 42.42
+                (byte) 0x21,
+                (byte) 0xf6, (byte) 0x28, (byte) 0x5c, (byte) 0x8f,
+                (byte) 0xc2, (byte) 0x35, (byte) 0x45, (byte) 0x40,
+                // 5 -> Double.MIN_NORMAL
+                (byte) 0x29,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x10, (byte) 0x00,
+                // 6 -> DOUBLE.MIN_VALUE
+                (byte) 0x31,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 7 -> Double.NEGATIVE_INFINITY
+                (byte) 0x39,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0xff,
+                // 8 -> Double.NaN
+                (byte) 0x41,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf8, (byte) 0x7f,
+                // 9 -> Double.POSITIVE_INFINITY
+                (byte) 0x49,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        double[][] results = new double[9][2];
+        int[] indices = new int[9];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readDouble(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readDouble(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readDouble(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readDouble(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readDouble(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readDouble(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readDouble(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    results[7][indices[7]++] = pi.readDouble(fieldId8);
+                    break;
+                case (int) fieldId9:
+                    results[8][indices[8]++] = pi.readDouble(fieldId9);
+                    break;
+                case (int) fieldId10:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+        assertEquals(0.0, results[0][0]);
+        assertEquals(0.0, results[0][1]);
+        assertEquals(1.0, results[1][0]);
+        assertEquals(1.0, results[1][1]);
+        assertEquals(-1234.432, results[2][0]);
+        assertEquals(-1234.432, results[2][1]);
+        assertEquals(42.42, results[3][0]);
+        assertEquals(42.42, results[3][1]);
+        assertEquals(Double.MIN_NORMAL, results[4][0]);
+        assertEquals(Double.MIN_NORMAL, results[4][1]);
+        assertEquals(Double.MIN_VALUE, results[5][0]);
+        assertEquals(Double.MIN_VALUE, results[5][1]);
+        assertEquals(Double.NEGATIVE_INFINITY, results[6][0]);
+        assertEquals(Double.NEGATIVE_INFINITY, results[6][1]);
+        assertEquals(Double.NaN, results[7][0]);
+        assertEquals(Double.NaN, results[7][1]);
+        assertEquals(Double.POSITIVE_INFINITY, results[8][0]);
+        assertEquals(Double.POSITIVE_INFINITY, results[8][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new double[0]);
+        testRepeatedCompat(new double[]{0, 1, -1234.432, 42.42,
+                Double.MIN_NORMAL, Double.MIN_VALUE, Double.NEGATIVE_INFINITY, Double.NaN,
+                Double.POSITIVE_INFINITY,
+        });
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(double[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_DOUBLE;
+        final long fieldId = fieldFlags | ((long) 11 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.doubleFieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        double[] result = new double[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readDouble(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.doubleFieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.doubleFieldRepeated[i], result[i]);
+        }
+    }
+
+
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    private void testPacked(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_DOUBLE;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+        final long fieldId9 = fieldFlags | ((long) 9 & 0x0ffffffffL);
+        final long fieldId10 = fieldFlags | ((long) 10 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x10,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x10,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x3f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x3f,
+                // 10 -> 1
+                (byte) 0x52,
+                (byte) 0x10,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x3f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x3f,
+                // 3 -> -1234.432
+                (byte) 0x1a,
+                (byte) 0x10,
+                (byte) 0x7d, (byte) 0x3f, (byte) 0x35, (byte) 0x5e,
+                (byte) 0xba, (byte) 0x49, (byte) 0x93, (byte) 0xc0,
+                (byte) 0x7d, (byte) 0x3f, (byte) 0x35, (byte) 0x5e,
+                (byte) 0xba, (byte) 0x49, (byte) 0x93, (byte) 0xc0,
+                // 4 -> 42.42
+                (byte) 0x22,
+                (byte) 0x10,
+                (byte) 0xf6, (byte) 0x28, (byte) 0x5c, (byte) 0x8f,
+                (byte) 0xc2, (byte) 0x35, (byte) 0x45, (byte) 0x40,
+                (byte) 0xf6, (byte) 0x28, (byte) 0x5c, (byte) 0x8f,
+                (byte) 0xc2, (byte) 0x35, (byte) 0x45, (byte) 0x40,
+                // 5 -> Double.MIN_NORMAL
+                (byte) 0x2a,
+                (byte) 0x10,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x10, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x10, (byte) 0x00,
+                // 6 -> DOUBLE.MIN_VALUE
+                (byte) 0x32,
+                (byte) 0x10,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 7 -> Double.NEGATIVE_INFINITY
+                (byte) 0x3a,
+                (byte) 0x10,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0xff,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0xff,
+                // 8 -> Double.NaN
+                (byte) 0x42,
+                (byte) 0x10,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf8, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf8, (byte) 0x7f,
+                // 9 -> Double.POSITIVE_INFINITY
+                (byte) 0x4a,
+                (byte) 0x10,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        double[][] results = new double[9][2];
+        int[] indices = new int[9];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readDouble(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readDouble(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readDouble(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readDouble(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readDouble(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readDouble(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readDouble(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    results[7][indices[7]++] = pi.readDouble(fieldId8);
+                    break;
+                case (int) fieldId9:
+                    results[8][indices[8]++] = pi.readDouble(fieldId9);
+                    break;
+                case (int) fieldId10:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+        assertEquals(0.0, results[0][0]);
+        assertEquals(0.0, results[0][1]);
+        assertEquals(1.0, results[1][0]);
+        assertEquals(1.0, results[1][1]);
+        assertEquals(-1234.432, results[2][0]);
+        assertEquals(-1234.432, results[2][1]);
+        assertEquals(42.42, results[3][0]);
+        assertEquals(42.42, results[3][1]);
+        assertEquals(Double.MIN_NORMAL, results[4][0]);
+        assertEquals(Double.MIN_NORMAL, results[4][1]);
+        assertEquals(Double.MIN_VALUE, results[5][0]);
+        assertEquals(Double.MIN_VALUE, results[5][1]);
+        assertEquals(Double.NEGATIVE_INFINITY, results[6][0]);
+        assertEquals(Double.NEGATIVE_INFINITY, results[6][1]);
+        assertEquals(Double.NaN, results[7][0]);
+        assertEquals(Double.NaN, results[7][1]);
+        assertEquals(Double.POSITIVE_INFINITY, results[8][0]);
+        assertEquals(Double.POSITIVE_INFINITY, results[8][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new double[0]);
+        testPackedCompat(new double[]{0, 1, -1234.432, 42.42,
+                Double.MIN_NORMAL, Double.MIN_VALUE, Double.NEGATIVE_INFINITY, Double.NaN,
+                Double.POSITIVE_INFINITY,
+        });
+    }
+
+    /**
+     * Implementation of testPackedCompat with a given value.
+     */
+    private void testPackedCompat(double[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_DOUBLE;
+        final long fieldId = fieldFlags | ((long) 12 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.doubleFieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        double[] result = new double[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readDouble(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.doubleFieldPacked.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.doubleFieldPacked[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_DOUBLE;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x09,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readInt(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readLong(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_DOUBLE;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x08,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readDouble(fieldId1);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId2:
+                        pi.readDouble(fieldId2);
+                        // don't fail, fixed64 is ok
+                        break;
+                    case (int) fieldId3:
+                        pi.readDouble(fieldId3);
+                        // don't fail, length delimited is ok (represents packed doubles)
+                        break;
+                    case (int) fieldId6:
+                        pi.readDouble(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamEnumTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamEnumTest.java
new file mode 100644
index 0000000..f55d951
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamEnumTest.java
@@ -0,0 +1,570 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamEnumTest extends TestCase {
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_ENUM;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 6 -> MAX_VALUE
+                (byte) 0x30,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[] results = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0]);
+        assertEquals(1, results[1]);
+        assertEquals(-1, results[2]);
+        assertEquals(Integer.MIN_VALUE, results[3]);
+        assertEquals(Integer.MAX_VALUE, results[4]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(0);
+        testReadCompat(1);
+        testReadCompat(-1);
+        testReadCompat(Integer.MIN_VALUE);
+        testReadCompat(Integer.MAX_VALUE);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(int val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_ENUM;
+        final long fieldId = fieldFlags | ((long) 160 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.outsideField = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+
+        int result = 0; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        // Nano proto drops values that are outside the range, so compare against val
+        assertEquals(val, result);
+    }
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_ENUM;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                // 6 -> MAX_VALUE
+                (byte) 0x30,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[][] results = new int[5][2];
+        int[] indices = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readInt(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+    }
+
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new int[]{});
+        testRepeatedCompat(new int[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(int[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_ENUM;
+        final long fieldId = fieldFlags | ((long) 161 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.outsideFieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+
+        int[] result = new int[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        // Nano proto drops values that are outside the range, so compare against val
+        assertEquals(val.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(val[i], result[i]);
+        }
+    }
+
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    private void testPacked(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_ENUM;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x02,
+                (byte) 0x00,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x02,
+                (byte) 0x01,
+                (byte) 0x01,
+
+                // 6 -> MAX_VALUE
+                (byte) 0x32,
+                (byte) 0x0a,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                // 3 -> -1
+                (byte) 0x1a,
+                (byte) 0x14,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                // 4 -> MIN_VALUE
+                (byte) 0x22,
+                (byte) 0x14,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                // 5 -> MAX_VALUE
+                (byte) 0x2a,
+                (byte) 0x0a,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[][] results = new int[5][2];
+        int[] indices = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readInt(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new int[]{});
+        testPackedCompat(new int[]{0, 1});
+
+        // Nano proto has a bug.  It gets the size with computeInt32SizeNoTag (correctly)
+        // but incorrectly uses writeRawVarint32 to write the value for negative numbers.
+        //testPackedCompat(new int[] { 0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE });
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testPackedCompat(int[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_ENUM;
+        final long fieldId = fieldFlags | ((long) 162 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.outsideFieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+
+        int[] result = new int[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        // Nano proto drops values that are outside the range, so compare against val
+        assertEquals(val.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(val[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_ENUM;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readLong(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_ENUM;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readInt(fieldId1);
+                        // don't fail, varint is ok
+                        break;
+                    case (int) fieldId2:
+                        pi.readInt(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readInt(fieldId3);
+                        // don't fail, length delimited is ok (represents packed enums)
+                        break;
+                    case (int) fieldId6:
+                        pi.readInt(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed32Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed32Test.java
new file mode 100644
index 0000000..df68476
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed32Test.java
@@ -0,0 +1,547 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamFixed32Test extends TestCase {
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FIXED32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 2 -> 1
+                (byte) 0x15,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 -> 1
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x1d,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x25,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x2d,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[] results = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0]);
+        assertEquals(1, results[1]);
+        assertEquals(-1, results[2]);
+        assertEquals(Integer.MIN_VALUE, results[3]);
+        assertEquals(Integer.MAX_VALUE, results[4]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(0);
+        testReadCompat(1);
+        testReadCompat(-1);
+        testReadCompat(Integer.MIN_VALUE);
+        testReadCompat(Integer.MAX_VALUE);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(int val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FIXED32;
+        final long fieldId = fieldFlags | ((long) 90 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.fixed32Field = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int result = 0; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.fixed32Field, result);
+    }
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_FIXED32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x15,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x1d,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x25,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x2d,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+
+                // 6 -> 1
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x15,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x1d,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x25,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x2d,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[][] results = new int[5][2];
+        int[] indices = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readInt(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new int[0]);
+        testRepeatedCompat(new int[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(int[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_FIXED32;
+        final long fieldId = fieldFlags | ((long) 91 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.fixed32FieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int[] result = new int[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.fixed32FieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.fixed32FieldRepeated[i], result[i]);
+        }
+    }
+
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    private void testPacked(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_FIXED32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x08,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 -> 1
+                (byte) 0x32,
+                (byte) 0x08,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x08,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x1a,
+                (byte) 0x08,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x22,
+                (byte) 0x08,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x2a,
+                (byte) 0x08,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[][] results = new int[5][2];
+        int[] indices = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readInt(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new int[0]);
+        testPackedCompat(new int[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testPackedCompat(int[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_FIXED32;
+        final long fieldId = fieldFlags | ((long) 92 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.fixed32FieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int[] result = new int[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.fixed32FieldPacked.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.fixed32FieldPacked[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FIXED32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x0d,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readLong(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FIXED32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x04,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readInt(fieldId1);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId2:
+                        pi.readInt(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readInt(fieldId3);
+                        // don't fail, length delimited is ok (represents packed fixed32)
+                        break;
+                    case (int) fieldId6:
+                        pi.readInt(fieldId6);
+                        // don't fail, fixed32 is ok
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed64Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed64Test.java
new file mode 100644
index 0000000..af4130b
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed64Test.java
@@ -0,0 +1,649 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamFixed64Test extends TestCase {
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FIXED64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 2 -> 1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 -> 1
+                (byte) 0x41,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x19,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x21,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x29,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x31,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x39,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[] results = new long[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0]);
+        assertEquals(1, results[1]);
+        assertEquals(-1, results[2]);
+        assertEquals(Integer.MIN_VALUE, results[3]);
+        assertEquals(Integer.MAX_VALUE, results[4]);
+        assertEquals(Long.MIN_VALUE, results[5]);
+        assertEquals(Long.MAX_VALUE, results[6]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(0);
+        testReadCompat(1);
+        testReadCompat(-1);
+        testReadCompat(Integer.MIN_VALUE);
+        testReadCompat(Integer.MAX_VALUE);
+        testReadCompat(Long.MIN_VALUE);
+        testReadCompat(Long.MAX_VALUE);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(long val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FIXED64;
+        final long fieldId = fieldFlags | ((long) 100 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.fixed64Field = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long result = 0; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.fixed64Field, result);
+    }
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_FIXED64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x09,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x19,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x21,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x29,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x31,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x39,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+
+                // 8 -> 1
+                (byte) 0x41,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x09,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x19,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x21,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x29,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x31,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x39,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[][] results = new long[7][2];
+        int[] indices = new int[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readLong(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+        assertEquals(Long.MIN_VALUE, results[5][0]);
+        assertEquals(Long.MIN_VALUE, results[5][1]);
+        assertEquals(Long.MAX_VALUE, results[6][0]);
+        assertEquals(Long.MAX_VALUE, results[6][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new long[0]);
+        testRepeatedCompat(new long[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(long[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_FIXED64;
+        final long fieldId = fieldFlags | ((long) 101 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.fixed64FieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long[] result = new long[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.fixed64FieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.fixed64FieldRepeated[i], result[i]);
+        }
+    }
+
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    private void testPacked(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_FIXED64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x10,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x10,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 8 -> 1
+                (byte) 0x42,
+                (byte) 0x10,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x1a,
+                (byte) 0x10,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x22,
+                (byte) 0x10,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x2a,
+                (byte) 0x10,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x32,
+                (byte) 0x10,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x3a,
+                (byte) 0x10,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[][] results = new long[7][2];
+        int[] indices = new int[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readLong(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+        assertEquals(Long.MIN_VALUE, results[5][0]);
+        assertEquals(Long.MIN_VALUE, results[5][1]);
+        assertEquals(Long.MAX_VALUE, results[6][0]);
+        assertEquals(Long.MAX_VALUE, results[6][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new long[0]);
+        testPackedCompat(new long[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testPackedCompat(long[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_FIXED64;
+        final long fieldId = fieldFlags | ((long) 102 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.fixed64FieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long[] result = new long[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.fixed64FieldPacked.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.fixed64FieldPacked[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FIXED64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x09,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readInt(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FIXED64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x08,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readLong(fieldId1);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId2:
+                        pi.readLong(fieldId2);
+                        // don't fail, fixed64 is ok
+                        break;
+                    case (int) fieldId3:
+                        pi.readLong(fieldId3);
+                        // don't fail, length delimited is ok (represents packed fixed64)
+                        break;
+                    case (int) fieldId6:
+                        pi.readLong(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFloatTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFloatTest.java
new file mode 100644
index 0000000..9bc07dc
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFloatTest.java
@@ -0,0 +1,679 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamFloatTest extends TestCase {
+
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FLOAT;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+        final long fieldId9 = fieldFlags | ((long) 9 & 0x0ffffffffL);
+        final long fieldId10 = fieldFlags | ((long) 10 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 2 -> 1
+                (byte) 0x15,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x3f,
+                // 10 -> 1
+                (byte) 0x55,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x3f,
+                // 3 -> -1234.432
+                (byte) 0x1d,
+                (byte) 0xd3, (byte) 0x4d, (byte) 0x9a, (byte) 0xc4,
+                // 4 -> 42.42
+                (byte) 0x25,
+                (byte) 0x14, (byte) 0xae, (byte) 0x29, (byte) 0x42,
+                // 5 -> Float.MIN_NORMAL
+                (byte) 0x2d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x00,
+                // 6 -> DOUBLE.MIN_VALUE
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 7 -> Float.NEGATIVE_INFINITY
+                (byte) 0x3d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0xff,
+                // 8 -> Float.NaN
+                (byte) 0x45,
+                (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x7f,
+                // 9 -> Float.POSITIVE_INFINITY
+                (byte) 0x4d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        float[] results = new float[9];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readFloat(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readFloat(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readFloat(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4] = pi.readFloat(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5] = pi.readFloat(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6] = pi.readFloat(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    results[7] = pi.readFloat(fieldId8);
+                    break;
+                case (int) fieldId9:
+                    results[8] = pi.readFloat(fieldId9);
+                    break;
+                case (int) fieldId10:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+        assertEquals(0.0f, results[0]);
+        assertEquals(1.0f, results[1]);
+        assertEquals(-1234.432f, results[2]);
+        assertEquals(42.42f, results[3]);
+        assertEquals(Float.MIN_NORMAL, results[4]);
+        assertEquals(Float.MIN_VALUE, results[5]);
+        assertEquals(Float.NEGATIVE_INFINITY, results[6]);
+        assertEquals(Float.NaN, results[7]);
+        assertEquals(Float.POSITIVE_INFINITY, results[8]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(0);
+        testReadCompat(1);
+        testReadCompat(-1234.432f);
+        testReadCompat(42.42f);
+        testReadCompat(Float.MIN_NORMAL);
+        testReadCompat(Float.MIN_VALUE);
+        testReadCompat(Float.NEGATIVE_INFINITY);
+        testReadCompat(Float.NaN);
+        testReadCompat(Float.POSITIVE_INFINITY);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(float val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FLOAT;
+        final long fieldId = fieldFlags | ((long) 20 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.floatField = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        float result = 0.0f; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readFloat(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.floatField, result);
+    }
+
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_FLOAT;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+        final long fieldId9 = fieldFlags | ((long) 9 & 0x0ffffffffL);
+        final long fieldId10 = fieldFlags | ((long) 10 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x15,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x3f,
+                // 3 -> -1234.432
+                (byte) 0x1d,
+                (byte) 0xd3, (byte) 0x4d, (byte) 0x9a, (byte) 0xc4,
+                // 4 -> 42.42
+                (byte) 0x25,
+                (byte) 0x14, (byte) 0xae, (byte) 0x29, (byte) 0x42,
+                // 5 -> Float.MIN_NORMAL
+                (byte) 0x2d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x00,
+                // 6 -> DOUBLE.MIN_VALUE
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 7 -> Float.NEGATIVE_INFINITY
+                (byte) 0x3d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0xff,
+                // 8 -> Float.NaN
+                (byte) 0x45,
+                (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x7f,
+                // 9 -> Float.POSITIVE_INFINITY
+                (byte) 0x4d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x7f,
+
+                // 10 -> 1
+                (byte) 0x55,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x3f,
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x15,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x3f,
+                // 3 -> -1234.432
+                (byte) 0x1d,
+                (byte) 0xd3, (byte) 0x4d, (byte) 0x9a, (byte) 0xc4,
+                // 4 -> 42.42
+                (byte) 0x25,
+                (byte) 0x14, (byte) 0xae, (byte) 0x29, (byte) 0x42,
+                // 5 -> Float.MIN_NORMAL
+                (byte) 0x2d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x00,
+                // 6 -> DOUBLE.MIN_VALUE
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 7 -> Float.NEGATIVE_INFINITY
+                (byte) 0x3d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0xff,
+                // 8 -> Float.NaN
+                (byte) 0x45,
+                (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x7f,
+                // 9 -> Float.POSITIVE_INFINITY
+                (byte) 0x4d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        float[][] results = new float[9][2];
+        int[] indices = new int[9];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readFloat(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readFloat(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readFloat(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readFloat(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readFloat(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readFloat(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readFloat(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    results[7][indices[7]++] = pi.readFloat(fieldId8);
+                    break;
+                case (int) fieldId9:
+                    results[8][indices[8]++] = pi.readFloat(fieldId9);
+                    break;
+                case (int) fieldId10:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+        assertEquals(0.0f, results[0][0]);
+        assertEquals(0.0f, results[0][1]);
+        assertEquals(1.0f, results[1][0]);
+        assertEquals(1.0f, results[1][1]);
+        assertEquals(-1234.432f, results[2][0]);
+        assertEquals(-1234.432f, results[2][1]);
+        assertEquals(42.42f, results[3][0]);
+        assertEquals(42.42f, results[3][1]);
+        assertEquals(Float.MIN_NORMAL, results[4][0]);
+        assertEquals(Float.MIN_NORMAL, results[4][1]);
+        assertEquals(Float.MIN_VALUE, results[5][0]);
+        assertEquals(Float.MIN_VALUE, results[5][1]);
+        assertEquals(Float.NEGATIVE_INFINITY, results[6][0]);
+        assertEquals(Float.NEGATIVE_INFINITY, results[6][1]);
+        assertEquals(Float.NaN, results[7][0]);
+        assertEquals(Float.NaN, results[7][1]);
+        assertEquals(Float.POSITIVE_INFINITY, results[8][0]);
+        assertEquals(Float.POSITIVE_INFINITY, results[8][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new float[0]);
+        testRepeatedCompat(new float[]{0, 1, -1234.432f, 42.42f,
+                Float.MIN_NORMAL, Float.MIN_VALUE, Float.NEGATIVE_INFINITY, Float.NaN,
+                Float.POSITIVE_INFINITY,
+        });
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(float[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_FLOAT;
+        final long fieldId = fieldFlags | ((long) 21 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.floatFieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        float[] result = new float[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readFloat(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.floatFieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.floatFieldRepeated[i], result[i]);
+        }
+    }
+
+
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    private void testPacked(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_FLOAT;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+        final long fieldId9 = fieldFlags | ((long) 9 & 0x0ffffffffL);
+        final long fieldId10 = fieldFlags | ((long) 10 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x08,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x08,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x3f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x3f,
+                // 10 -> 1
+                (byte) 0x52,
+                (byte) 0x08,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x3f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x3f,
+                // 3 -> -1234.432
+                (byte) 0x1a,
+                (byte) 0x08,
+                (byte) 0xd3, (byte) 0x4d, (byte) 0x9a, (byte) 0xc4,
+                (byte) 0xd3, (byte) 0x4d, (byte) 0x9a, (byte) 0xc4,
+                // 4 -> 42.42
+                (byte) 0x22,
+                (byte) 0x08,
+                (byte) 0x14, (byte) 0xae, (byte) 0x29, (byte) 0x42,
+                (byte) 0x14, (byte) 0xae, (byte) 0x29, (byte) 0x42,
+                // 5 -> Float.MIN_NORMAL
+                (byte) 0x2a,
+                (byte) 0x08,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x00,
+                // 6 -> DOUBLE.MIN_VALUE
+                (byte) 0x32,
+                (byte) 0x08,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 7 -> Float.NEGATIVE_INFINITY
+                (byte) 0x3a,
+                (byte) 0x08,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0xff,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0xff,
+                // 8 -> Float.NaN
+                (byte) 0x42,
+                (byte) 0x08,
+                (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x7f,
+                // 9 -> Float.POSITIVE_INFINITY
+                (byte) 0x4a,
+                (byte) 0x08,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        float[][] results = new float[9][2];
+        int[] indices = new int[9];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readFloat(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readFloat(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readFloat(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readFloat(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readFloat(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readFloat(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readFloat(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    results[7][indices[7]++] = pi.readFloat(fieldId8);
+                    break;
+                case (int) fieldId9:
+                    results[8][indices[8]++] = pi.readFloat(fieldId9);
+                    break;
+                case (int) fieldId10:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+        assertEquals(0.0f, results[0][0]);
+        assertEquals(0.0f, results[0][1]);
+        assertEquals(1.0f, results[1][0]);
+        assertEquals(1.0f, results[1][1]);
+        assertEquals(-1234.432f, results[2][0]);
+        assertEquals(-1234.432f, results[2][1]);
+        assertEquals(42.42f, results[3][0]);
+        assertEquals(42.42f, results[3][1]);
+        assertEquals(Float.MIN_NORMAL, results[4][0]);
+        assertEquals(Float.MIN_NORMAL, results[4][1]);
+        assertEquals(Float.MIN_VALUE, results[5][0]);
+        assertEquals(Float.MIN_VALUE, results[5][1]);
+        assertEquals(Float.NEGATIVE_INFINITY, results[6][0]);
+        assertEquals(Float.NEGATIVE_INFINITY, results[6][1]);
+        assertEquals(Float.NaN, results[7][0]);
+        assertEquals(Float.NaN, results[7][1]);
+        assertEquals(Float.POSITIVE_INFINITY, results[8][0]);
+        assertEquals(Float.POSITIVE_INFINITY, results[8][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new float[0]);
+        testPackedCompat(new float[]{0, 1, -1234.432f, 42.42f,
+                Float.MIN_NORMAL, Float.MIN_VALUE, Float.NEGATIVE_INFINITY, Float.NaN,
+                Float.POSITIVE_INFINITY,
+        });
+    }
+
+    /**
+     * Implementation of testPackedCompat with a given value.
+     */
+    private void testPackedCompat(float[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_FLOAT;
+        final long fieldId = fieldFlags | ((long) 22 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.floatFieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        float[] result = new float[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readFloat(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.floatFieldPacked.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.floatFieldPacked[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FLOAT;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x0d,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readInt(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readLong(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_FLOAT;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x04,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readFloat(fieldId1);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId2:
+                        pi.readFloat(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readFloat(fieldId3);
+                        // don't fail, length delimited is ok (represents packed floats)
+                        break;
+                    case (int) fieldId6:
+                        pi.readFloat(fieldId6);
+                        // don't fail, fixed32 is ok
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt32Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt32Test.java
new file mode 100644
index 0000000..0065870
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt32Test.java
@@ -0,0 +1,565 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamInt32Test extends TestCase {
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_INT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 6 -> MAX_VALUE
+                (byte) 0x30,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[] results = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0]);
+        assertEquals(1, results[1]);
+        assertEquals(-1, results[2]);
+        assertEquals(Integer.MIN_VALUE, results[3]);
+        assertEquals(Integer.MAX_VALUE, results[4]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(0);
+        testReadCompat(1);
+        testReadCompat(-1);
+        testReadCompat(Integer.MIN_VALUE);
+        testReadCompat(Integer.MAX_VALUE);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(int val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_INT32;
+        final long fieldId = fieldFlags | ((long) 30 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.int32Field = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int result = 0; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.int32Field, result);
+    }
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_INT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                // 6 -> MAX_VALUE
+                (byte) 0x30,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[][] results = new int[5][2];
+        int[] indices = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readInt(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new int[0]);
+        testRepeatedCompat(new int[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(int[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_INT32;
+        final long fieldId = fieldFlags | ((long) 31 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.int32FieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int[] result = new int[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.int32FieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.int32FieldRepeated[i], result[i]);
+        }
+    }
+
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    private void testPacked(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_INT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x02,
+                (byte) 0x00,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x02,
+                (byte) 0x01,
+                (byte) 0x01,
+
+                // 6 -> MAX_VALUE
+                (byte) 0x32,
+                (byte) 0x0a,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                // 3 -> -1
+                (byte) 0x1a,
+                (byte) 0x14,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                // 4 -> MIN_VALUE
+                (byte) 0x22,
+                (byte) 0x14,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                // 5 -> MAX_VALUE
+                (byte) 0x2a,
+                (byte) 0x0a,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[][] results = new int[5][2];
+        int[] indices = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readInt(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new int[0]);
+        testPackedCompat(new int[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testPackedCompat(int[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_INT32;
+        final long fieldId = fieldFlags | ((long) 32 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.int32FieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int[] result = new int[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.int32FieldPacked.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.int32FieldPacked[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_INT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readLong(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_INT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readInt(fieldId1);
+                        // don't fail, varint is ok
+                        break;
+                    case (int) fieldId2:
+                        pi.readInt(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readInt(fieldId3);
+                        // don't fail, length delimited is ok (represents packed int32)
+                        break;
+                    case (int) fieldId6:
+                        pi.readInt(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt64Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt64Test.java
new file mode 100644
index 0000000..4d6d105
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt64Test.java
@@ -0,0 +1,645 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamInt64Test extends TestCase {
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_INT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 8 -> Long.MAX_VALUE
+                (byte) 0x40,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x30,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x01,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x38,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[] results = new long[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0]);
+        assertEquals(1, results[1]);
+        assertEquals(-1, results[2]);
+        assertEquals(Integer.MIN_VALUE, results[3]);
+        assertEquals(Integer.MAX_VALUE, results[4]);
+        assertEquals(Long.MIN_VALUE, results[5]);
+        assertEquals(Long.MAX_VALUE, results[6]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(0);
+        testReadCompat(1);
+        testReadCompat(-1);
+        testReadCompat(Integer.MIN_VALUE);
+        testReadCompat(Integer.MAX_VALUE);
+        testReadCompat(Long.MIN_VALUE);
+        testReadCompat(Long.MAX_VALUE);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(long val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_INT64;
+        final long fieldId = fieldFlags | ((long) 40 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.int64Field = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long result = 0; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.int64Field, result);
+    }
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_INT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x30,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x01,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x38,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+
+                // 8 -> Long.MAX_VALUE
+                (byte) 0x40,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x30,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x01,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x38,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[][] results = new long[7][2];
+        int[] indices = new int[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readLong(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+        assertEquals(Long.MIN_VALUE, results[5][0]);
+        assertEquals(Long.MIN_VALUE, results[5][1]);
+        assertEquals(Long.MAX_VALUE, results[6][0]);
+        assertEquals(Long.MAX_VALUE, results[6][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new long[0]);
+        testRepeatedCompat(new long[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(long[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_INT64;
+        final long fieldId = fieldFlags | ((long) 41 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.int64FieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long[] result = new long[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.int64FieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.int64FieldRepeated[i], result[i]);
+        }
+    }
+
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    private void testPacked(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_INT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x02,
+                (byte) 0x00,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x02,
+                (byte) 0x01,
+                (byte) 0x01,
+
+                // 8 -> Long.MAX_VALUE
+                (byte) 0x42,
+                (byte) 0x12,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+
+                // 3 -> -1
+                (byte) 0x1a,
+                (byte) 0x14,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x22,
+                (byte) 0x14,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x2a,
+                (byte) 0x0a,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x32,
+                (byte) 0x14,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x01,
+
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x01,
+
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x3a,
+                (byte) 0x12,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[][] results = new long[7][2];
+        int[] indices = new int[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readLong(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+        assertEquals(Long.MIN_VALUE, results[5][0]);
+        assertEquals(Long.MIN_VALUE, results[5][1]);
+        assertEquals(Long.MAX_VALUE, results[6][0]);
+        assertEquals(Long.MAX_VALUE, results[6][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new long[0]);
+        testPackedCompat(new long[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testPackedCompat(long[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_INT64;
+        final long fieldId = fieldFlags | ((long) 42 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.int64FieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long[] result = new long[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.int64FieldPacked.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.int64FieldPacked[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_INT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readInt(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_INT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readLong(fieldId1);
+                        // don't fail, varint is ok
+                        break;
+                    case (int) fieldId2:
+                        pi.readLong(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readLong(fieldId3);
+                        // don't fail, length delimited is ok (represents packed int64)
+                        break;
+                    case (int) fieldId6:
+                        pi.readLong(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamObjectTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamObjectTest.java
new file mode 100644
index 0000000..5e49eea
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamObjectTest.java
@@ -0,0 +1,507 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamObjectTest extends TestCase {
+
+
+    class SimpleObject {
+        public char mChar;
+        public char mLargeChar;
+        public String mString;
+        public SimpleObject mNested;
+
+        void parseProto(ProtoInputStream pi) throws IOException {
+            final long uintFieldFlags =
+                    ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT32;
+            final long stringFieldFlags =
+                    ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_STRING;
+            final long messageFieldFlags =
+                    ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_MESSAGE;
+            final long charId = uintFieldFlags | ((long) 2 & 0x0ffffffffL);
+            final long largeCharId = uintFieldFlags | ((long) 5000 & 0x0ffffffffL);
+            final long stringId = stringFieldFlags | ((long) 4 & 0x0ffffffffL);
+            final long nestedId = messageFieldFlags | ((long) 5 & 0x0ffffffffL);
+
+            while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                switch (pi.getFieldNumber()) {
+                    case (int) charId:
+                        mChar = (char) pi.readInt(charId);
+                        break;
+                    case (int) largeCharId:
+                        mLargeChar = (char) pi.readInt(largeCharId);
+                        break;
+                    case (int) stringId:
+                        mString = pi.readString(stringId);
+                        break;
+                    case (int) nestedId:
+                        long token = pi.start(nestedId);
+                        mNested = new SimpleObject();
+                        mNested.parseProto(pi);
+                        pi.end(token);
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Test reading an object with one char in it.
+     */
+    public void testObjectOneChar() throws IOException {
+        testObjectOneChar(0);
+        testObjectOneChar(1);
+        testObjectOneChar(5);
+    }
+
+    /**
+     * Implementation of testObjectOneChar for a given chunkSize.
+     */
+    private void testObjectOneChar(int chunkSize) throws IOException {
+        final long messageFieldFlags =
+                ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_MESSAGE;
+
+        final long messageId1 = messageFieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long messageId2 = messageFieldFlags | ((long) 2 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // Message 2 : { char 2 : 'c' }
+                (byte) 0x12, (byte) 0x02, (byte) 0x10, (byte) 0x63,
+                // Message 1 : { char 2 : 'b' }
+                (byte) 0x0a, (byte) 0x02, (byte) 0x10, (byte) 0x62,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+
+        SimpleObject result = null;
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) messageId1:
+                    final long token = pi.start(messageId1);
+                    result = new SimpleObject();
+                    result.parseProto(pi);
+                    pi.end(token);
+                    break;
+                case (int) messageId2:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertNotNull(result);
+        assertEquals('b', result.mChar);
+    }
+
+    /**
+     * Test reading an object with one multibyte unicode char in it.
+     */
+    public void testObjectOneLargeChar() throws IOException {
+        testObjectOneLargeChar(0);
+        testObjectOneLargeChar(1);
+        testObjectOneLargeChar(5);
+    }
+
+    /**
+     * Implementation of testObjectOneLargeChar for a given chunkSize.
+     */
+    private void testObjectOneLargeChar(int chunkSize) throws IOException {
+        final long messageFieldFlags =
+                ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_MESSAGE;
+
+        final long messageId1 = messageFieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long messageId2 = messageFieldFlags | ((long) 2 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // Message 2 : { char 5000 : '\u3110' }
+                (byte) 0x12, (byte) 0x05, (byte) 0xc0, (byte) 0xb8,
+                (byte) 0x02, (byte) 0x90, (byte) 0x62,
+                // Message 1 : { char 5000 : '\u3110' }
+                (byte) 0x0a, (byte) 0x05, (byte) 0xc0, (byte) 0xb8,
+                (byte) 0x02, (byte) 0x90, (byte) 0x62,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+
+        SimpleObject result = null;
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) messageId1:
+                    final long token = pi.start(messageId1);
+                    result = new SimpleObject();
+                    result.parseProto(pi);
+                    pi.end(token);
+                    break;
+                case (int) messageId2:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertNotNull(result);
+        assertEquals('\u3110', result.mLargeChar);
+    }
+
+    /**
+     * Test reading a char, then an object, then a char.
+     */
+    public void testObjectAndTwoChars() throws IOException {
+        testObjectAndTwoChars(0);
+        testObjectAndTwoChars(1);
+        testObjectAndTwoChars(5);
+    }
+
+    /**
+     * Implementation of testObjectAndTwoChars for a given chunkSize.
+     */
+    private void testObjectAndTwoChars(int chunkSize) throws IOException  {
+        final long uintFieldFlags =
+                ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT32;
+        final long messageFieldFlags =
+                ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_MESSAGE;
+
+        final long charId1 = uintFieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long messageId2 = messageFieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long charId4 = uintFieldFlags | ((long) 4 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 'a'
+                (byte) 0x08, (byte) 0x61,
+                // Message 1 : { char 2 : 'b' }
+                (byte) 0x12, (byte) 0x02, (byte) 0x10, (byte) 0x62,
+                // 4 -> 'c'
+                (byte) 0x20, (byte) 0x63,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+
+        SimpleObject obj = null;
+        char char1 = '\0';
+        char char4 = '\0';
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) charId1:
+                    char1 = (char) pi.readInt(charId1);
+                    break;
+                case (int) messageId2:
+                    final long token = pi.start(messageId2);
+                    obj = new SimpleObject();
+                    obj.parseProto(pi);
+                    pi.end(token);
+                    break;
+                case (int) charId4:
+                    char4 = (char) pi.readInt(charId4);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals('a', char1);
+        assertNotNull(obj);
+        assertEquals('b', obj.mChar);
+        assertEquals('c', char4);
+    }
+
+    /**
+     * Test reading a char, then an object with an int and a string in it, then a char.
+     */
+    public void testComplexObject() throws IOException {
+        testComplexObject(0);
+        testComplexObject(1);
+        testComplexObject(5);
+    }
+
+    /**
+     * Implementation of testComplexObject for a given chunkSize.
+     */
+    private void testComplexObject(int chunkSize) throws IOException  {
+        final long uintFieldFlags =
+                ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT32;
+        final long messageFieldFlags =
+                ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_MESSAGE;
+
+        final long charId1 = uintFieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long messageId2 = messageFieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long charId4 = uintFieldFlags | ((long) 4 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 'x'
+                (byte) 0x08, (byte) 0x78,
+                // begin object 2
+                (byte) 0x12, (byte) 0x10,
+                // 2 -> 'y'
+                (byte) 0x10, (byte) 0x79,
+                // 4 -> "abcdefghijkl"
+                (byte) 0x22, (byte) 0x0c,
+                (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66,
+                (byte) 0x67, (byte) 0x68, (byte) 0x69, (byte) 0x6a, (byte) 0x6b, (byte) 0x6c,
+                // 4 -> 'z'
+                (byte) 0x20, (byte) 0x7a,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+
+        SimpleObject obj = null;
+        char char1 = '\0';
+        char char4 = '\0';
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) charId1:
+                    char1 = (char) pi.readInt(charId1);
+                    break;
+                case (int) messageId2:
+                    final long token = pi.start(messageId2);
+                    obj = new SimpleObject();
+                    obj.parseProto(pi);
+                    pi.end(token);
+                    break;
+                case (int) charId4:
+                    char4 = (char) pi.readInt(charId4);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals('x', char1);
+        assertNotNull(obj);
+        assertEquals('y', obj.mChar);
+        assertEquals("abcdefghijkl", obj.mString);
+        assertEquals('z', char4);
+    }
+
+    /**
+     * Test reading 3 levels deep of objects.
+     */
+    public void testDeepObjects() throws IOException {
+        testDeepObjects(0);
+        testDeepObjects(1);
+        testDeepObjects(5);
+    }
+
+    /**
+     * Implementation of testDeepObjects for a given chunkSize.
+     */
+    private void testDeepObjects(int chunkSize) throws IOException  {
+        final long messageFieldFlags =
+                ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_MESSAGE;
+        final long messageId2 = messageFieldFlags | ((long) 2 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // begin object id 2
+                (byte) 0x12, (byte) 0x1a,
+                // 2 -> 'a'
+                (byte) 0x10, (byte) 0x61,
+                // begin nested object id 5
+                (byte) 0x2a, (byte) 0x15,
+                // 5000 -> '\u3110'
+                (byte) 0xc0, (byte) 0xb8,
+                (byte) 0x02, (byte) 0x90, (byte) 0x62,
+                // begin nested object id 5
+                (byte) 0x2a, (byte) 0x0e,
+                // 4 -> "abcdefghijkl"
+                (byte) 0x22, (byte) 0x0c,
+                (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66,
+                (byte) 0x67, (byte) 0x68, (byte) 0x69, (byte) 0x6a, (byte) 0x6b, (byte) 0x6c,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+
+        SimpleObject obj = null;
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) messageId2:
+                    final long token = pi.start(messageId2);
+                    obj = new SimpleObject();
+                    obj.parseProto(pi);
+                    pi.end(token);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertNotNull(obj);
+        assertEquals('a', obj.mChar);
+        assertNotNull(obj.mNested);
+        assertEquals('\u3110', obj.mNested.mLargeChar);
+        assertNotNull(obj.mNested.mNested);
+        assertEquals("abcdefghijkl", obj.mNested.mNested.mString);
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_MESSAGE;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> {1}
+                (byte) 0x0a,
+                (byte) 0x01,
+                (byte) 0x01,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readInt(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readLong(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_MESSAGE;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readBytes(fieldId1);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId2:
+                        pi.readBytes(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readBytes(fieldId3);
+                        // don't fail, length delimited is ok
+                        break;
+                    case (int) fieldId6:
+                        pi.readBytes(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed32Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed32Test.java
new file mode 100644
index 0000000..75c88a4
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed32Test.java
@@ -0,0 +1,547 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamSFixed32Test extends TestCase {
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SFIXED32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 2 -> 1
+                (byte) 0x15,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 -> 1
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x1d,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x25,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x2d,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[] results = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0]);
+        assertEquals(1, results[1]);
+        assertEquals(-1, results[2]);
+        assertEquals(Integer.MIN_VALUE, results[3]);
+        assertEquals(Integer.MAX_VALUE, results[4]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(0);
+        testReadCompat(1);
+        testReadCompat(-1);
+        testReadCompat(Integer.MIN_VALUE);
+        testReadCompat(Integer.MAX_VALUE);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(int val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SFIXED32;
+        final long fieldId = fieldFlags | ((long) 110 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.sfixed32Field = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int result = 0; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.sfixed32Field, result);
+    }
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_SFIXED32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x15,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x1d,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x25,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x2d,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+
+                // 6 -> 1
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0d,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x15,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x1d,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x25,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x2d,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[][] results = new int[5][2];
+        int[] indices = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readInt(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new int[0]);
+        testRepeatedCompat(new int[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(int[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_SFIXED32;
+        final long fieldId = fieldFlags | ((long) 111 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.sfixed32FieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int[] result = new int[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.sfixed32FieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.sfixed32FieldRepeated[i], result[i]);
+        }
+    }
+
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    private void testPacked(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_SFIXED32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x08,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x08,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 -> 1
+                (byte) 0x32,
+                (byte) 0x08,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x1a,
+                (byte) 0x08,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x22,
+                (byte) 0x08,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x2a,
+                (byte) 0x08,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[][] results = new int[5][2];
+        int[] indices = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readInt(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new int[0]);
+        testPackedCompat(new int[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testPackedCompat(int[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_SFIXED32;
+        final long fieldId = fieldFlags | ((long) 112 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.sfixed32FieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int[] result = new int[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.sfixed32FieldPacked.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.sfixed32FieldPacked[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SFIXED32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readLong(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SFIXED32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x04,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readInt(fieldId1);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId2:
+                        pi.readInt(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readInt(fieldId3);
+                        // don't fail, length delimited is ok (represents packed sfixed32)
+                        break;
+                    case (int) fieldId6:
+                        pi.readInt(fieldId6);
+                        // don't fail, fixed32 is ok
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed64Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed64Test.java
new file mode 100644
index 0000000..4c65cf4
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed64Test.java
@@ -0,0 +1,648 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamSFixed64Test extends TestCase {
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SFIXED64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 2 -> 1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 8 -> 1
+                (byte) 0x41,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x19,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x21,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x29,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x31,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x39,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[] results = new long[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0]);
+        assertEquals(1, results[1]);
+        assertEquals(-1, results[2]);
+        assertEquals(Integer.MIN_VALUE, results[3]);
+        assertEquals(Integer.MAX_VALUE, results[4]);
+        assertEquals(Long.MIN_VALUE, results[5]);
+        assertEquals(Long.MAX_VALUE, results[6]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(0);
+        testReadCompat(1);
+        testReadCompat(-1);
+        testReadCompat(Integer.MIN_VALUE);
+        testReadCompat(Integer.MAX_VALUE);
+        testReadCompat(Long.MIN_VALUE);
+        testReadCompat(Long.MAX_VALUE);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(long val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SFIXED64;
+        final long fieldId = fieldFlags | ((long) 120 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.sfixed64Field = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long result = 0; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.sfixed64Field, result);
+    }
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_SFIXED64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x09,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x19,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x21,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x29,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x31,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x39,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+
+                // 8 -> 1
+                (byte) 0x41,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x09,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x19,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x21,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x29,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x31,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x39,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[][] results = new long[7][2];
+        int[] indices = new int[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readLong(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+        assertEquals(Long.MIN_VALUE, results[5][0]);
+        assertEquals(Long.MIN_VALUE, results[5][1]);
+        assertEquals(Long.MAX_VALUE, results[6][0]);
+        assertEquals(Long.MAX_VALUE, results[6][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new long[0]);
+        testRepeatedCompat(new long[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(long[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_SFIXED64;
+        final long fieldId = fieldFlags | ((long) 121 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.sfixed64FieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long[] result = new long[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.sfixed64FieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.sfixed64FieldRepeated[i], result[i]);
+        }
+    }
+
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    private void testPacked(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_SFIXED64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x10,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x10,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 8 -> 1
+                (byte) 0x42,
+                (byte) 0x10,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 -> -1
+                (byte) 0x1a,
+                (byte) 0x10,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x22,
+                (byte) 0x10,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x2a,
+                (byte) 0x10,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x32,
+                (byte) 0x10,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x3a,
+                (byte) 0x10,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[][] results = new long[7][2];
+        int[] indices = new int[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readLong(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+        assertEquals(Long.MIN_VALUE, results[5][0]);
+        assertEquals(Long.MIN_VALUE, results[5][1]);
+        assertEquals(Long.MAX_VALUE, results[6][0]);
+        assertEquals(Long.MAX_VALUE, results[6][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new long[0]);
+        testPackedCompat(new long[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testPackedCompat(long[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_SFIXED64;
+        final long fieldId = fieldFlags | ((long) 122 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.sfixed64FieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long[] result = new long[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.sfixed64FieldPacked.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.sfixed64FieldPacked[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SFIXED64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readInt(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SFIXED64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x08,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readLong(fieldId1);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId2:
+                        pi.readLong(fieldId2);
+                        // don't fail, fixed32 is ok
+                        break;
+                    case (int) fieldId3:
+                        pi.readLong(fieldId3);
+                        // don't fail, length delimited is ok (represents packed sfixed64)
+                        break;
+                    case (int) fieldId6:
+                        pi.readLong(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt32Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt32Test.java
new file mode 100644
index 0000000..6854cd8
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt32Test.java
@@ -0,0 +1,547 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamSInt32Test extends TestCase {
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SINT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x02,
+                // 6 -> MAX_VALUE
+                (byte) 0x30,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0x01,
+                // 4 -> MIN_VALUE
+                (byte) 0x20,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 5 -> MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[] results = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0]);
+        assertEquals(1, results[1]);
+        assertEquals(-1, results[2]);
+        assertEquals(Integer.MIN_VALUE, results[3]);
+        assertEquals(Integer.MAX_VALUE, results[4]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(0);
+        testReadCompat(1);
+        testReadCompat(-1);
+        testReadCompat(Integer.MIN_VALUE);
+        testReadCompat(Integer.MAX_VALUE);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(int val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SINT32;
+        final long fieldId = fieldFlags | ((long) 70 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.sint32Field = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int result = 0; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.sint32Field, result);
+    }
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_SINT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x02,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0x01,
+                // 4 -> MIN_VALUE
+                (byte) 0x20,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 5 -> MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+
+                // 6 -> MAX_VALUE
+                (byte) 0x30,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x02,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0x01,
+                // 4 -> MIN_VALUE
+                (byte) 0x20,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 5 -> MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[][] results = new int[5][2];
+        int[] indices = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readInt(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new int[0]);
+        testRepeatedCompat(new int[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(int[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_SINT32;
+        final long fieldId = fieldFlags | ((long) 71 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.sint32FieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int[] result = new int[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.sint32FieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.sint32FieldRepeated[i], result[i]);
+        }
+    }
+
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    private void testPacked(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_SINT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x02,
+                (byte) 0x00,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x02,
+                (byte) 0x02,
+                (byte) 0x02,
+                // 6 -> MAX_VALUE
+                (byte) 0x32,
+                (byte) 0x0a,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 3 -> -1
+                (byte) 0x1a,
+                (byte) 0x02,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 4 -> MIN_VALUE
+                (byte) 0x22,
+                (byte) 0x0a,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 5 -> MAX_VALUE
+                (byte) 0x2a,
+                (byte) 0x0a,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[][] results = new int[5][2];
+        int[] indices = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readInt(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new int[0]);
+        testPackedCompat(new int[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testPackedCompat(int[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_SINT32;
+        final long fieldId = fieldFlags | ((long) 72 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.sint32FieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int[] result = new int[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.sint32FieldPacked.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.sint32FieldPacked[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SINT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readLong(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SINT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readInt(fieldId1);
+                        // don't fail, varint is ok
+                        break;
+                    case (int) fieldId2:
+                        pi.readInt(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readInt(fieldId3);
+                        // don't fail, length delimited is ok (represents packed sint32)
+                        break;
+                    case (int) fieldId6:
+                        pi.readInt(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt64Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt64Test.java
new file mode 100644
index 0000000..c53e9d7
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt64Test.java
@@ -0,0 +1,622 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamSInt64Test extends TestCase {
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SINT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x02,
+                // 8 -> Integer.MAX_VALUE
+                (byte) 0x40,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0x01,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x20,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x30,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x38,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[] results = new long[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0]);
+        assertEquals(1, results[1]);
+        assertEquals(-1, results[2]);
+        assertEquals(Integer.MIN_VALUE, results[3]);
+        assertEquals(Integer.MAX_VALUE, results[4]);
+        assertEquals(Long.MIN_VALUE, results[5]);
+        assertEquals(Long.MAX_VALUE, results[6]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(0);
+        testReadCompat(1);
+        testReadCompat(-1);
+        testReadCompat(Integer.MIN_VALUE);
+        testReadCompat(Integer.MAX_VALUE);
+        testReadCompat(Long.MIN_VALUE);
+        testReadCompat(Long.MAX_VALUE);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(long val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SINT64;
+        final long fieldId = fieldFlags | ((long) 80 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.sint64Field = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long result = 0; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.sint64Field, result);
+    }
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_SINT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x02,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0x01,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x20,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x30,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x38,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                // 8 -> Integer.MAX_VALUE
+                (byte) 0x40,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x02,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0x01,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x20,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x30,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x38,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[][] results = new long[7][2];
+        int[] indices = new int[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readLong(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+        assertEquals(Long.MIN_VALUE, results[5][0]);
+        assertEquals(Long.MIN_VALUE, results[5][1]);
+        assertEquals(Long.MAX_VALUE, results[6][0]);
+        assertEquals(Long.MAX_VALUE, results[6][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new long[0]);
+        testRepeatedCompat(new long[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(long[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_SINT64;
+        final long fieldId = fieldFlags | ((long) 81 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.sint64FieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long[] result = new long[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.sint64FieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.sint64FieldRepeated[i], result[i]);
+        }
+    }
+
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    private void testPacked(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_SINT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x02,
+                (byte) 0x00,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x02,
+                (byte) 0x02,
+                (byte) 0x02,
+                // 8 -> Integer.MAX_VALUE
+                (byte) 0x42,
+                (byte) 0x0a,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 3 -> -1
+                (byte) 0x1a,
+                (byte) 0x02,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x22,
+                (byte) 0x0a,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x2a,
+                (byte) 0x0a,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0f,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x32,
+                (byte) 0x14,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x3a,
+                (byte) 0x14,
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[][] results = new long[7][2];
+        int[] indices = new int[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readLong(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+        assertEquals(Long.MIN_VALUE, results[5][0]);
+        assertEquals(Long.MIN_VALUE, results[5][1]);
+        assertEquals(Long.MAX_VALUE, results[6][0]);
+        assertEquals(Long.MAX_VALUE, results[6][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new long[0]);
+        testPackedCompat(new long[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testPackedCompat(long[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_SINT64;
+        final long fieldId = fieldFlags | ((long) 82 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.sint64FieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long[] result = new long[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.sint64FieldPacked.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.sint64FieldPacked[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SINT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readInt(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_SINT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readLong(fieldId1);
+                        // don't fail, varint is ok
+                        break;
+                    case (int) fieldId2:
+                        pi.readLong(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readLong(fieldId3);
+                        // don't fail, length delimited is ok (represents packed sint64)
+                        break;
+                    case (int) fieldId6:
+                        pi.readLong(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamStringTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamStringTest.java
new file mode 100644
index 0000000..816d5f9
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamStringTest.java
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamStringTest extends TestCase {
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_STRING;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> null - default value, not written
+                // 2 -> "" - default value, not written
+                // 3 -> "abcd\u3110!"
+                (byte) 0x1a,
+                (byte) 0x08,
+                (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64,
+                (byte) 0xe3, (byte) 0x84, (byte) 0x90, (byte) 0x21,
+                // 5 -> "Hi"
+                (byte) 0x2a,
+                (byte) 0x02,
+                (byte) 0x48, (byte) 0x69,
+                // 4 -> "Hi"
+                (byte) 0x22,
+                (byte) 0x02,
+                (byte) 0x48, (byte) 0x69,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        String[] results = new String[4];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0] = pi.readString(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readString(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readString(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readString(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertNull(results[0]);
+        assertNull(results[1]);
+        assertEquals("abcd\u3110!", results[2]);
+        assertEquals("Hi", results[3]);
+    }
+
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat("");
+        testReadCompat("abcd\u3110!");
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(String val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_STRING;
+        final long fieldId = fieldFlags | ((long) 140 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.stringField = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        String result = "";
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readString(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.stringField, result);
+    }
+
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_STRING;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> null - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x00,
+                // 2 -> "" - default value, written when repeated
+                (byte) 0x12,
+                (byte) 0x00,
+                // 3 -> "abcd\u3110!"
+                (byte) 0x1a,
+                (byte) 0x08,
+                (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64,
+                (byte) 0xe3, (byte) 0x84, (byte) 0x90, (byte) 0x21,
+                // 4 -> "Hi"
+                (byte) 0x22,
+                (byte) 0x02,
+                (byte) 0x48, (byte) 0x69,
+
+                // 5 -> "Hi"
+                (byte) 0x2a,
+                (byte) 0x02,
+                (byte) 0x48, (byte) 0x69,
+
+                // 1 -> null - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x00,
+                // 2 -> "" - default value, written when repeated
+                (byte) 0x12,
+                (byte) 0x00,
+                // 3 -> "abcd\u3110!"
+                (byte) 0x1a,
+                (byte) 0x08,
+                (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64,
+                (byte) 0xe3, (byte) 0x84, (byte) 0x90, (byte) 0x21,
+                // 4 -> "Hi"
+                (byte) 0x22,
+                (byte) 0x02,
+                (byte) 0x48, (byte) 0x69,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        String[][] results = new String[4][2];
+        int[] indices = new int[4];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readString(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readString(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readString(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readString(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+
+        assertEquals("", results[0][0]);
+        assertEquals("", results[0][1]);
+        assertEquals("", results[1][0]);
+        assertEquals("", results[1][1]);
+        assertEquals("abcd\u3110!", results[2][0]);
+        assertEquals("abcd\u3110!", results[2][1]);
+        assertEquals("Hi", results[3][0]);
+        assertEquals("Hi", results[3][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new String[0]);
+        testRepeatedCompat(new String[]{"", "abcd\u3110!", "Hi"});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(String[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_STRING;
+        final long fieldId = fieldFlags | ((long) 141 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.stringFieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        String[] result = new String[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readString(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.stringFieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.stringFieldRepeated[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_STRING;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> {1}
+                (byte) 0x0a,
+                (byte) 0x01,
+                (byte) 0x01,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readInt(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readLong(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_STRING;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readString(fieldId1);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId2:
+                        pi.readString(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readString(fieldId3);
+                        // don't fail, length delimited is ok (represents packed booleans)
+                        break;
+                    case (int) fieldId6:
+                        pi.readString(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt32Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt32Test.java
new file mode 100644
index 0000000..50fc537
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt32Test.java
@@ -0,0 +1,564 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamUInt32Test extends TestCase {
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 6 -> MAX_VALUE
+                (byte) 0x30,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[] results = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0]);
+        assertEquals(1, results[1]);
+        assertEquals(-1, results[2]);
+        assertEquals(Integer.MIN_VALUE, results[3]);
+        assertEquals(Integer.MAX_VALUE, results[4]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(0);
+        testReadCompat(1);
+        testReadCompat(-1);
+        testReadCompat(Integer.MIN_VALUE);
+        testReadCompat(Integer.MAX_VALUE);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(int val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT32;
+        final long fieldId = fieldFlags | ((long) 50 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.uint32Field = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int result = 0; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.uint32Field, result);
+    }
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_UINT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 6 -> MAX_VALUE
+                (byte) 0x30,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[][] results = new int[5][2];
+        int[] indices = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readInt(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new int[0]);
+        testRepeatedCompat(new int[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(int[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_UINT32;
+        final long fieldId = fieldFlags | ((long) 51 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.uint32FieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int[] result = new int[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.uint32FieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.uint32FieldRepeated[i], result[i]);
+        }
+    }
+
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    private void testPacked(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_UINT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x02,
+                (byte) 0x00,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x02,
+                (byte) 0x01,
+                (byte) 0x01,
+
+                // 6 -> MAX_VALUE
+                (byte) 0x32,
+                (byte) 0x0a,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                // 3 -> -1
+                (byte) 0x1a,
+                (byte) 0x14,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                // 4 -> MIN_VALUE
+                (byte) 0x22,
+                (byte) 0x14,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                // 5 -> MAX_VALUE
+                (byte) 0x2a,
+                (byte) 0x0a,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        int[][] results = new int[5][2];
+        int[] indices = new int[5];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readInt(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readInt(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readInt(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readInt(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readInt(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new int[0]);
+        testPackedCompat(new int[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testPackedCompat(int[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_UINT32;
+        final long fieldId = fieldFlags | ((long) 52 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.uint32FieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        int[] result = new int[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readInt(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.uint32FieldPacked.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.uint32FieldPacked[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readLong(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT32;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readInt(fieldId1);
+                        // don't fail, varint is ok
+                        break;
+                    case (int) fieldId2:
+                        pi.readInt(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readInt(fieldId3);
+                        // don't fail, length delimited is ok (represents packed uint32)
+                        break;
+                    case (int) fieldId6:
+                        pi.readInt(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt64Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt64Test.java
new file mode 100644
index 0000000..20969e9
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt64Test.java
@@ -0,0 +1,641 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.WireTypeMismatchException;
+
+import com.android.test.protoinputstream.nano.Test;
+
+import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ProtoInputStreamUInt64Test extends TestCase {
+
+    public void testRead() throws IOException {
+        testRead(0);
+        testRead(1);
+        testRead(5);
+    }
+
+    private void testRead(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, not written
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 8 -> Integer.MAX_VALUE
+                (byte) 0x40,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x30,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x01,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x38,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[] results = new long[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    fail("Should never reach this");
+                    break;
+                case (int) fieldId2:
+                    results[1] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0]);
+        assertEquals(1, results[1]);
+        assertEquals(-1, results[2]);
+        assertEquals(Integer.MIN_VALUE, results[3]);
+        assertEquals(Integer.MAX_VALUE, results[4]);
+        assertEquals(Long.MIN_VALUE, results[5]);
+        assertEquals(Long.MAX_VALUE, results[6]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testReadCompat() throws Exception {
+        testReadCompat(0);
+        testReadCompat(1);
+        testReadCompat(-1);
+        testReadCompat(Integer.MIN_VALUE);
+        testReadCompat(Integer.MAX_VALUE);
+        testReadCompat(Long.MIN_VALUE);
+        testReadCompat(Long.MAX_VALUE);
+    }
+
+    /**
+     * Implementation of testReadCompat with a given value.
+     */
+    private void testReadCompat(long val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT64;
+        final long fieldId = fieldFlags | ((long) 60 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.uint64Field = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long result = 0; // start off with default value
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.uint64Field, result);
+    }
+
+    public void testRepeated() throws IOException {
+        testRepeated(0);
+        testRepeated(1);
+        testRepeated(5);
+    }
+
+    private void testRepeated(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_UINT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x30,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x01,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x38,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+
+                // 8 -> Integer.MAX_VALUE
+                (byte) 0x40,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x08,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x10,
+                (byte) 0x01,
+                // 3 -> -1
+                (byte) 0x18,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x20,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x28,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x30,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x01,
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x38,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[][] results = new long[7][2];
+        int[] indices = new int[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readLong(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+        assertEquals(Long.MIN_VALUE, results[5][0]);
+        assertEquals(Long.MIN_VALUE, results[5][1]);
+        assertEquals(Long.MAX_VALUE, results[6][0]);
+        assertEquals(Long.MAX_VALUE, results[6][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testRepeatedCompat() throws Exception {
+        testRepeatedCompat(new long[0]);
+        testRepeatedCompat(new long[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testRepeatedCompat(long[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_UINT64;
+        final long fieldId = fieldFlags | ((long) 61 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.uint64FieldRepeated = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long[] result = new long[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.uint64FieldRepeated.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.uint64FieldRepeated[i], result[i]);
+        }
+    }
+
+    public void testPacked() throws IOException {
+        testPacked(0);
+        testPacked(1);
+        testPacked(5);
+    }
+
+    private void testPacked(int chunkSize) throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_UINT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
+        final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+        final long fieldId7 = fieldFlags | ((long) 7 & 0x0ffffffffL);
+        final long fieldId8 = fieldFlags | ((long) 8 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 0 - default value, written when repeated
+                (byte) 0x0a,
+                (byte) 0x02,
+                (byte) 0x00,
+                (byte) 0x00,
+                // 2 -> 1
+                (byte) 0x12,
+                (byte) 0x02,
+                (byte) 0x01,
+                (byte) 0x01,
+
+                // 8 -> Integer.MAX_VALUE
+                (byte) 0x42,
+                (byte) 0x0a,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                // 3 -> -1
+                (byte) 0x1a,
+                (byte) 0x14,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                // 4 -> Integer.MIN_VALUE
+                (byte) 0x22,
+                (byte) 0x14,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
+
+                // 5 -> Integer.MAX_VALUE
+                (byte) 0x2a,
+                (byte) 0x0a,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
+
+                // 6 -> Long.MIN_VALUE
+                (byte) 0x32,
+                (byte) 0x14,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x01,
+
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80,
+                (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x01,
+
+                // 7 -> Long.MAX_VALUE
+                (byte) 0x3a,
+                (byte) 0x12,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x7f,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
+        long[][] results = new long[7][2];
+        int[] indices = new int[7];
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId1:
+                    results[0][indices[0]++] = pi.readLong(fieldId1);
+                    break;
+                case (int) fieldId2:
+                    results[1][indices[1]++] = pi.readLong(fieldId2);
+                    break;
+                case (int) fieldId3:
+                    results[2][indices[2]++] = pi.readLong(fieldId3);
+                    break;
+                case (int) fieldId4:
+                    results[3][indices[3]++] = pi.readLong(fieldId4);
+                    break;
+                case (int) fieldId5:
+                    results[4][indices[4]++] = pi.readLong(fieldId5);
+                    break;
+                case (int) fieldId6:
+                    results[5][indices[5]++] = pi.readLong(fieldId6);
+                    break;
+                case (int) fieldId7:
+                    results[6][indices[6]++] = pi.readLong(fieldId7);
+                    break;
+                case (int) fieldId8:
+                    // Intentionally don't read the data. Parse should continue normally
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+        stream.close();
+
+        assertEquals(0, results[0][0]);
+        assertEquals(0, results[0][1]);
+        assertEquals(1, results[1][0]);
+        assertEquals(1, results[1][1]);
+        assertEquals(-1, results[2][0]);
+        assertEquals(-1, results[2][1]);
+        assertEquals(Integer.MIN_VALUE, results[3][0]);
+        assertEquals(Integer.MIN_VALUE, results[3][1]);
+        assertEquals(Integer.MAX_VALUE, results[4][0]);
+        assertEquals(Integer.MAX_VALUE, results[4][1]);
+        assertEquals(Long.MIN_VALUE, results[5][0]);
+        assertEquals(Long.MIN_VALUE, results[5][1]);
+        assertEquals(Long.MAX_VALUE, results[6][0]);
+        assertEquals(Long.MAX_VALUE, results[6][1]);
+    }
+
+    /**
+     * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
+     */
+    public void testPackedCompat() throws Exception {
+        testPackedCompat(new long[0]);
+        testPackedCompat(new long[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
+    }
+
+    /**
+     * Implementation of testRepeatedCompat with a given value.
+     */
+    private void testPackedCompat(long[] val) throws Exception {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_UINT64;
+        final long fieldId = fieldFlags | ((long) 62 & 0x0ffffffffL);
+
+        final Test.All all = new Test.All();
+        all.uint64FieldPacked = val;
+
+        final byte[] proto = MessageNano.toByteArray(all);
+
+        final ProtoInputStream pi = new ProtoInputStream(proto);
+        final Test.All readback = Test.All.parseFrom(proto);
+
+        long[] result = new long[val.length];
+        int index = 0;
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (pi.getFieldNumber()) {
+                case (int) fieldId:
+                    result[index++] = pi.readLong(fieldId);
+                    break;
+                default:
+                    fail("Unexpected field id " + pi.getFieldNumber());
+            }
+        }
+
+        assertEquals(readback.uint64FieldPacked.length, result.length);
+        for (int i = 0; i < result.length; i++) {
+            assertEquals(readback.uint64FieldPacked[i], result[i]);
+        }
+    }
+
+    /**
+     * Test that using the wrong read method throws an exception
+     */
+    public void testBadReadType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+        };
+
+        ProtoInputStream pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readFloat(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readDouble(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readInt(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBoolean(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readBytes(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+
+        pi = new ProtoInputStream(protobuf);
+        pi.isNextField(fieldId1);
+        try {
+            pi.readString(fieldId1);
+            fail("Should have throw IllegalArgumentException");
+        } catch (IllegalArgumentException iae) {
+            // good
+        }
+    }
+
+    /**
+     * Test that unexpected wrong wire types will throw an exception
+     */
+    public void testBadWireType() throws IOException {
+        final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT64;
+
+        final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
+        final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
+        final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
+        final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
+
+        final byte[] protobuf = new byte[]{
+                // 1 : varint -> 1
+                (byte) 0x08,
+                (byte) 0x01,
+                // 2 : fixed64 -> 0x1
+                (byte) 0x11,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                // 3 : length delimited -> { 1 }
+                (byte) 0x1a,
+                (byte) 0x01,
+                (byte) 0x01,
+                // 6 : fixed32
+                (byte) 0x35,
+                (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        };
+
+        InputStream stream = new ByteArrayInputStream(protobuf);
+        final ProtoInputStream pi = new ProtoInputStream(stream);
+
+        while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            try {
+                switch (pi.getFieldNumber()) {
+                    case (int) fieldId1:
+                        pi.readLong(fieldId1);
+                        // don't fail, varint is ok
+                        break;
+                    case (int) fieldId2:
+                        pi.readLong(fieldId2);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    case (int) fieldId3:
+                        pi.readLong(fieldId3);
+                        // don't fail, length delimited is ok (represents packed uint64)
+                        break;
+                    case (int) fieldId6:
+                        pi.readLong(fieldId6);
+                        fail("Should have thrown a WireTypeMismatchException");
+                        break;
+                    default:
+                        fail("Unexpected field id " + pi.getFieldNumber());
+                }
+            } catch (WireTypeMismatchException wtme) {
+                // good
+            }
+        }
+        stream.close();
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoTests.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoTests.java
new file mode 100644
index 0000000..cdf6ae2
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoTests.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.protoinputstream;
+
+import junit.framework.TestSuite;
+
+public class ProtoTests {
+    public static TestSuite suite() {
+        TestSuite suite = new TestSuite(ProtoTests.class.getName());
+
+        suite.addTestSuite(ProtoInputStreamDoubleTest.class);
+        suite.addTestSuite(ProtoInputStreamFloatTest.class);
+        suite.addTestSuite(ProtoInputStreamInt32Test.class);
+        suite.addTestSuite(ProtoInputStreamInt64Test.class);
+        suite.addTestSuite(ProtoInputStreamUInt32Test.class);
+        suite.addTestSuite(ProtoInputStreamUInt64Test.class);
+        suite.addTestSuite(ProtoInputStreamSInt32Test.class);
+        suite.addTestSuite(ProtoInputStreamSInt64Test.class);
+        suite.addTestSuite(ProtoInputStreamFixed32Test.class);
+        suite.addTestSuite(ProtoInputStreamFixed64Test.class);
+        suite.addTestSuite(ProtoInputStreamSFixed32Test.class);
+        suite.addTestSuite(ProtoInputStreamSFixed64Test.class);
+        suite.addTestSuite(ProtoInputStreamBoolTest.class);
+        suite.addTestSuite(ProtoInputStreamStringTest.class);
+        suite.addTestSuite(ProtoInputStreamBytesTest.class);
+        suite.addTestSuite(ProtoInputStreamEnumTest.class);
+        suite.addTestSuite(ProtoInputStreamObjectTest.class);
+
+        return suite;
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/test.proto b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/test.proto
new file mode 100644
index 0000000..9ff1d7e
--- /dev/null
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/test.proto
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package com.android.test.protoinputstream;
+
+/**
+ * Enum that outside the scope of any classes.
+ */
+enum Outside {
+    OUTSIDE_0 = 0;
+    OUTSIDE_1 = 1;
+};
+
+/**
+ * Message that is recursive.
+ */
+message Nested {
+    optional int32 data = 10001;
+    optional Nested nested = 10002;
+};
+
+/**
+ * Message with all of the field types.
+ */
+message All {
+    /**
+     * Enum that is inside the scope of a class.
+     */
+    enum Inside {
+        option allow_alias = true;
+        INSIDE_0 = 0;
+        INSIDE_1 = 1;
+        INSIDE_1A = 1;
+    };
+
+    optional double double_field = 10;
+    repeated double double_field_repeated = 11;
+    repeated double double_field_packed = 12 [packed=true];
+
+    optional float float_field = 20;
+    repeated float float_field_repeated = 21;
+    repeated float float_field_packed = 22 [packed=true];
+
+    optional int32 int32_field = 30;
+    repeated int32 int32_field_repeated = 31;
+    repeated int32 int32_field_packed = 32 [packed=true];
+
+    optional int64 int64_field = 40;
+    repeated int64 int64_field_repeated = 41;
+    repeated int64 int64_field_packed = 42 [packed=true];
+
+    optional uint32 uint32_field = 50;
+    repeated uint32 uint32_field_repeated = 51;
+    repeated uint32 uint32_field_packed = 52 [packed=true];
+
+    optional uint64 uint64_field = 60;
+    repeated uint64 uint64_field_repeated = 61;
+    repeated uint64 uint64_field_packed = 62 [packed=true];
+
+    optional sint32 sint32_field = 70;
+    repeated sint32 sint32_field_repeated = 71;
+    repeated sint32 sint32_field_packed = 72 [packed=true];
+
+    optional sint64 sint64_field = 80;
+    repeated sint64 sint64_field_repeated = 81;
+    repeated sint64 sint64_field_packed = 82 [packed=true];
+
+    optional fixed32 fixed32_field = 90;
+    repeated fixed32 fixed32_field_repeated = 91;
+    repeated fixed32 fixed32_field_packed = 92 [packed=true];
+
+    optional fixed64 fixed64_field = 100;
+    repeated fixed64 fixed64_field_repeated = 101;
+    repeated fixed64 fixed64_field_packed = 102 [packed=true];
+
+    optional sfixed32 sfixed32_field = 110;
+    repeated sfixed32 sfixed32_field_repeated = 111;
+    repeated sfixed32 sfixed32_field_packed = 112 [packed=true];
+
+    optional sfixed64 sfixed64_field = 120;
+    repeated sfixed64 sfixed64_field_repeated = 121;
+    repeated sfixed64 sfixed64_field_packed = 122 [packed=true];
+
+    optional bool bool_field = 130;
+    repeated bool bool_field_repeated = 131;
+    repeated bool bool_field_packed = 132 [packed=true];
+
+    optional string string_field = 140;
+    repeated string string_field_repeated = 141;
+
+    optional bytes bytes_field = 150;
+    repeated bytes bytes_field_repeated = 151;
+
+    optional Outside outside_field = 160;
+    repeated Outside outside_field_repeated = 161;
+    repeated Outside outside_field_packed = 162 [packed=true];
+
+    optional Nested nested_field = 170;
+    repeated Nested nested_field_repeated = 171;
+};
