Home | History | Annotate | Download | only in protoinputstream
      1 /*
      2  * Copyright (C) 2019 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.test.protoinputstream;
     18 
     19 import android.util.proto.ProtoInputStream;
     20 import android.util.proto.ProtoStream;
     21 import android.util.proto.WireTypeMismatchException;
     22 
     23 import com.android.test.protoinputstream.nano.Test;
     24 
     25 import com.google.protobuf.nano.MessageNano;
     26 
     27 import junit.framework.TestCase;
     28 
     29 import java.io.ByteArrayInputStream;
     30 import java.io.IOException;
     31 import java.io.InputStream;
     32 
     33 public class ProtoInputStreamUInt32Test extends TestCase {
     34 
     35     public void testRead() throws IOException {
     36         testRead(0);
     37         testRead(1);
     38         testRead(5);
     39     }
     40 
     41     private void testRead(int chunkSize) throws IOException {
     42         final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT32;
     43 
     44         final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
     45         final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
     46         final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
     47         final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
     48         final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
     49         final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
     50 
     51         final byte[] protobuf = new byte[]{
     52                 // 1 -> 0 - default value, not written
     53                 // 2 -> 1
     54                 (byte) 0x10,
     55                 (byte) 0x01,
     56                 // 6 -> MAX_VALUE
     57                 (byte) 0x30,
     58                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
     59                 // 3 -> -1
     60                 (byte) 0x18,
     61                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
     62                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
     63                 // 4 -> MIN_VALUE
     64                 (byte) 0x20,
     65                 (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
     66                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
     67                 // 5 -> MAX_VALUE
     68                 (byte) 0x28,
     69                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
     70         };
     71 
     72         InputStream stream = new ByteArrayInputStream(protobuf);
     73         final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
     74         int[] results = new int[5];
     75         while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
     76             switch (pi.getFieldNumber()) {
     77                 case (int) fieldId1:
     78                     fail("Should never reach this");
     79                     break;
     80                 case (int) fieldId2:
     81                     results[1] = pi.readInt(fieldId2);
     82                     break;
     83                 case (int) fieldId3:
     84                     results[2] = pi.readInt(fieldId3);
     85                     break;
     86                 case (int) fieldId4:
     87                     results[3] = pi.readInt(fieldId4);
     88                     break;
     89                 case (int) fieldId5:
     90                     results[4] = pi.readInt(fieldId5);
     91                     break;
     92                 case (int) fieldId6:
     93                     // Intentionally don't read the data. Parse should continue normally
     94                     break;
     95                 default:
     96                     fail("Unexpected field id " + pi.getFieldNumber());
     97             }
     98         }
     99         stream.close();
    100 
    101         assertEquals(0, results[0]);
    102         assertEquals(1, results[1]);
    103         assertEquals(-1, results[2]);
    104         assertEquals(Integer.MIN_VALUE, results[3]);
    105         assertEquals(Integer.MAX_VALUE, results[4]);
    106     }
    107 
    108     /**
    109      * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
    110      */
    111     public void testReadCompat() throws Exception {
    112         testReadCompat(0);
    113         testReadCompat(1);
    114         testReadCompat(-1);
    115         testReadCompat(Integer.MIN_VALUE);
    116         testReadCompat(Integer.MAX_VALUE);
    117     }
    118 
    119     /**
    120      * Implementation of testReadCompat with a given value.
    121      */
    122     private void testReadCompat(int val) throws Exception {
    123         final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT32;
    124         final long fieldId = fieldFlags | ((long) 50 & 0x0ffffffffL);
    125 
    126         final Test.All all = new Test.All();
    127         all.uint32Field = val;
    128 
    129         final byte[] proto = MessageNano.toByteArray(all);
    130 
    131         final ProtoInputStream pi = new ProtoInputStream(proto);
    132         final Test.All readback = Test.All.parseFrom(proto);
    133 
    134         int result = 0; // start off with default value
    135         while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
    136             switch (pi.getFieldNumber()) {
    137                 case (int) fieldId:
    138                     result = pi.readInt(fieldId);
    139                     break;
    140                 default:
    141                     fail("Unexpected field id " + pi.getFieldNumber());
    142             }
    143         }
    144 
    145         assertEquals(readback.uint32Field, result);
    146     }
    147 
    148     public void testRepeated() throws IOException {
    149         testRepeated(0);
    150         testRepeated(1);
    151         testRepeated(5);
    152     }
    153 
    154     private void testRepeated(int chunkSize) throws IOException {
    155         final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_UINT32;
    156 
    157         final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
    158         final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
    159         final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
    160         final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
    161         final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
    162         final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
    163 
    164         final byte[] protobuf = new byte[]{
    165                 // 1 -> 0 - default value, written when repeated
    166                 (byte) 0x08,
    167                 (byte) 0x00,
    168                 // 2 -> 1
    169                 (byte) 0x10,
    170                 (byte) 0x01,
    171                 // 6 -> MAX_VALUE
    172                 (byte) 0x30,
    173                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
    174                 // 3 -> -1
    175                 (byte) 0x18,
    176                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
    177                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
    178                 // 4 -> MIN_VALUE
    179                 (byte) 0x20,
    180                 (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
    181                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
    182                 // 5 -> MAX_VALUE
    183                 (byte) 0x28,
    184                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
    185 
    186                 // 1 -> 0 - default value, written when repeated
    187                 (byte) 0x08,
    188                 (byte) 0x00,
    189                 // 2 -> 1
    190                 (byte) 0x10,
    191                 (byte) 0x01,
    192                 // 3 -> -1
    193                 (byte) 0x18,
    194                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
    195                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
    196                 // 4 -> MIN_VALUE
    197                 (byte) 0x20,
    198                 (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
    199                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
    200                 // 5 -> MAX_VALUE
    201                 (byte) 0x28,
    202                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
    203         };
    204 
    205         InputStream stream = new ByteArrayInputStream(protobuf);
    206         final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
    207         int[][] results = new int[5][2];
    208         int[] indices = new int[5];
    209         while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
    210 
    211             switch (pi.getFieldNumber()) {
    212                 case (int) fieldId1:
    213                     results[0][indices[0]++] = pi.readInt(fieldId1);
    214                     break;
    215                 case (int) fieldId2:
    216                     results[1][indices[1]++] = pi.readInt(fieldId2);
    217                     break;
    218                 case (int) fieldId3:
    219                     results[2][indices[2]++] = pi.readInt(fieldId3);
    220                     break;
    221                 case (int) fieldId4:
    222                     results[3][indices[3]++] = pi.readInt(fieldId4);
    223                     break;
    224                 case (int) fieldId5:
    225                     results[4][indices[4]++] = pi.readInt(fieldId5);
    226                     break;
    227                 case (int) fieldId6:
    228                     // Intentionally don't read the data. Parse should continue normally
    229                     break;
    230                 default:
    231                     fail("Unexpected field id " + pi.getFieldNumber());
    232             }
    233         }
    234         stream.close();
    235 
    236 
    237         assertEquals(0, results[0][0]);
    238         assertEquals(0, results[0][1]);
    239         assertEquals(1, results[1][0]);
    240         assertEquals(1, results[1][1]);
    241         assertEquals(-1, results[2][0]);
    242         assertEquals(-1, results[2][1]);
    243         assertEquals(Integer.MIN_VALUE, results[3][0]);
    244         assertEquals(Integer.MIN_VALUE, results[3][1]);
    245         assertEquals(Integer.MAX_VALUE, results[4][0]);
    246         assertEquals(Integer.MAX_VALUE, results[4][1]);
    247     }
    248 
    249     /**
    250      * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
    251      */
    252     public void testRepeatedCompat() throws Exception {
    253         testRepeatedCompat(new int[0]);
    254         testRepeatedCompat(new int[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
    255     }
    256 
    257     /**
    258      * Implementation of testRepeatedCompat with a given value.
    259      */
    260     private void testRepeatedCompat(int[] val) throws Exception {
    261         final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_UINT32;
    262         final long fieldId = fieldFlags | ((long) 51 & 0x0ffffffffL);
    263 
    264         final Test.All all = new Test.All();
    265         all.uint32FieldRepeated = val;
    266 
    267         final byte[] proto = MessageNano.toByteArray(all);
    268 
    269         final ProtoInputStream pi = new ProtoInputStream(proto);
    270         final Test.All readback = Test.All.parseFrom(proto);
    271 
    272         int[] result = new int[val.length];
    273         int index = 0;
    274         while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
    275             switch (pi.getFieldNumber()) {
    276                 case (int) fieldId:
    277                     result[index++] = pi.readInt(fieldId);
    278                     break;
    279                 default:
    280                     fail("Unexpected field id " + pi.getFieldNumber());
    281             }
    282         }
    283 
    284         assertEquals(readback.uint32FieldRepeated.length, result.length);
    285         for (int i = 0; i < result.length; i++) {
    286             assertEquals(readback.uint32FieldRepeated[i], result[i]);
    287         }
    288     }
    289 
    290     public void testPacked() throws IOException {
    291         testPacked(0);
    292         testPacked(1);
    293         testPacked(5);
    294     }
    295 
    296     private void testPacked(int chunkSize) throws IOException {
    297         final long fieldFlags = ProtoStream.FIELD_COUNT_PACKED | ProtoStream.FIELD_TYPE_UINT32;
    298 
    299         final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
    300         final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
    301         final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
    302         final long fieldId4 = fieldFlags | ((long) 4 & 0x0ffffffffL);
    303         final long fieldId5 = fieldFlags | ((long) 5 & 0x0ffffffffL);
    304         final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
    305 
    306         final byte[] protobuf = new byte[]{
    307                 // 1 -> 0 - default value, written when repeated
    308                 (byte) 0x0a,
    309                 (byte) 0x02,
    310                 (byte) 0x00,
    311                 (byte) 0x00,
    312                 // 2 -> 1
    313                 (byte) 0x12,
    314                 (byte) 0x02,
    315                 (byte) 0x01,
    316                 (byte) 0x01,
    317 
    318                 // 6 -> MAX_VALUE
    319                 (byte) 0x32,
    320                 (byte) 0x0a,
    321                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
    322 
    323                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
    324 
    325                 // 3 -> -1
    326                 (byte) 0x1a,
    327                 (byte) 0x14,
    328                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
    329                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
    330 
    331                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
    332                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
    333 
    334                 // 4 -> MIN_VALUE
    335                 (byte) 0x22,
    336                 (byte) 0x14,
    337                 (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
    338                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
    339 
    340                 (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0xf8,
    341                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x01,
    342 
    343                 // 5 -> MAX_VALUE
    344                 (byte) 0x2a,
    345                 (byte) 0x0a,
    346                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
    347 
    348                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x07,
    349         };
    350 
    351         InputStream stream = new ByteArrayInputStream(protobuf);
    352         final ProtoInputStream pi = new ProtoInputStream(stream, chunkSize);
    353         int[][] results = new int[5][2];
    354         int[] indices = new int[5];
    355         while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
    356 
    357             switch (pi.getFieldNumber()) {
    358                 case (int) fieldId1:
    359                     results[0][indices[0]++] = pi.readInt(fieldId1);
    360                     break;
    361                 case (int) fieldId2:
    362                     results[1][indices[1]++] = pi.readInt(fieldId2);
    363                     break;
    364                 case (int) fieldId3:
    365                     results[2][indices[2]++] = pi.readInt(fieldId3);
    366                     break;
    367                 case (int) fieldId4:
    368                     results[3][indices[3]++] = pi.readInt(fieldId4);
    369                     break;
    370                 case (int) fieldId5:
    371                     results[4][indices[4]++] = pi.readInt(fieldId5);
    372                     break;
    373                 case (int) fieldId6:
    374                     // Intentionally don't read the data. Parse should continue normally
    375                     break;
    376                 default:
    377                     fail("Unexpected field id " + pi.getFieldNumber());
    378             }
    379         }
    380         stream.close();
    381 
    382 
    383         assertEquals(0, results[0][0]);
    384         assertEquals(0, results[0][1]);
    385         assertEquals(1, results[1][0]);
    386         assertEquals(1, results[1][1]);
    387         assertEquals(-1, results[2][0]);
    388         assertEquals(-1, results[2][1]);
    389         assertEquals(Integer.MIN_VALUE, results[3][0]);
    390         assertEquals(Integer.MIN_VALUE, results[3][1]);
    391         assertEquals(Integer.MAX_VALUE, results[4][0]);
    392         assertEquals(Integer.MAX_VALUE, results[4][1]);
    393     }
    394 
    395     /**
    396      * Test that reading with ProtoInputStream matches, and can read the output of standard proto.
    397      */
    398     public void testPackedCompat() throws Exception {
    399         testPackedCompat(new int[0]);
    400         testPackedCompat(new int[]{0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE});
    401     }
    402 
    403     /**
    404      * Implementation of testRepeatedCompat with a given value.
    405      */
    406     private void testPackedCompat(int[] val) throws Exception {
    407         final long fieldFlags = ProtoStream.FIELD_COUNT_REPEATED | ProtoStream.FIELD_TYPE_UINT32;
    408         final long fieldId = fieldFlags | ((long) 52 & 0x0ffffffffL);
    409 
    410         final Test.All all = new Test.All();
    411         all.uint32FieldPacked = val;
    412 
    413         final byte[] proto = MessageNano.toByteArray(all);
    414 
    415         final ProtoInputStream pi = new ProtoInputStream(proto);
    416         final Test.All readback = Test.All.parseFrom(proto);
    417 
    418         int[] result = new int[val.length];
    419         int index = 0;
    420         while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
    421             switch (pi.getFieldNumber()) {
    422                 case (int) fieldId:
    423                     result[index++] = pi.readInt(fieldId);
    424                     break;
    425                 default:
    426                     fail("Unexpected field id " + pi.getFieldNumber());
    427             }
    428         }
    429 
    430         assertEquals(readback.uint32FieldPacked.length, result.length);
    431         for (int i = 0; i < result.length; i++) {
    432             assertEquals(readback.uint32FieldPacked[i], result[i]);
    433         }
    434     }
    435 
    436     /**
    437      * Test that using the wrong read method throws an exception
    438      */
    439     public void testBadReadType() throws IOException {
    440         final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT32;
    441 
    442         final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
    443 
    444         final byte[] protobuf = new byte[]{
    445                 // 1 -> 1
    446                 (byte) 0x08,
    447                 (byte) 0x01,
    448         };
    449 
    450         ProtoInputStream pi = new ProtoInputStream(protobuf);
    451         pi.isNextField(fieldId1);
    452         try {
    453             pi.readFloat(fieldId1);
    454             fail("Should have throw IllegalArgumentException");
    455         } catch (IllegalArgumentException iae) {
    456             // good
    457         }
    458 
    459         pi = new ProtoInputStream(protobuf);
    460         pi.isNextField(fieldId1);
    461         try {
    462             pi.readDouble(fieldId1);
    463             fail("Should have throw IllegalArgumentException");
    464         } catch (IllegalArgumentException iae) {
    465             // good
    466         }
    467 
    468         pi = new ProtoInputStream(protobuf);
    469         pi.isNextField(fieldId1);
    470         try {
    471             pi.readBoolean(fieldId1);
    472             fail("Should have throw IllegalArgumentException");
    473         } catch (IllegalArgumentException iae) {
    474             // good
    475         }
    476 
    477         pi = new ProtoInputStream(protobuf);
    478         pi.isNextField(fieldId1);
    479         try {
    480             pi.readLong(fieldId1);
    481             fail("Should have throw IllegalArgumentException");
    482         } catch (IllegalArgumentException iae) {
    483             // good
    484         }
    485 
    486         pi = new ProtoInputStream(protobuf);
    487         pi.isNextField(fieldId1);
    488         try {
    489             pi.readBytes(fieldId1);
    490             fail("Should have throw IllegalArgumentException");
    491         } catch (IllegalArgumentException iae) {
    492             // good
    493         }
    494 
    495         pi = new ProtoInputStream(protobuf);
    496         pi.isNextField(fieldId1);
    497         try {
    498             pi.readString(fieldId1);
    499             fail("Should have throw IllegalArgumentException");
    500         } catch (IllegalArgumentException iae) {
    501             // good
    502         }
    503     }
    504 
    505     /**
    506      * Test that unexpected wrong wire types will throw an exception
    507      */
    508     public void testBadWireType() throws IOException {
    509         final long fieldFlags = ProtoStream.FIELD_COUNT_SINGLE | ProtoStream.FIELD_TYPE_UINT32;
    510 
    511         final long fieldId1 = fieldFlags | ((long) 1 & 0x0ffffffffL);
    512         final long fieldId2 = fieldFlags | ((long) 2 & 0x0ffffffffL);
    513         final long fieldId3 = fieldFlags | ((long) 3 & 0x0ffffffffL);
    514         final long fieldId6 = fieldFlags | ((long) 6 & 0x0ffffffffL);
    515 
    516         final byte[] protobuf = new byte[]{
    517                 // 1 : varint -> 1
    518                 (byte) 0x08,
    519                 (byte) 0x01,
    520                 // 2 : fixed64 -> 0x1
    521                 (byte) 0x11,
    522                 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
    523                 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
    524                 // 3 : length delimited -> { 1 }
    525                 (byte) 0x1a,
    526                 (byte) 0x01,
    527                 (byte) 0x01,
    528                 // 6 : fixed32
    529                 (byte) 0x35,
    530                 (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
    531         };
    532 
    533         InputStream stream = new ByteArrayInputStream(protobuf);
    534         final ProtoInputStream pi = new ProtoInputStream(stream);
    535 
    536         while (pi.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
    537             try {
    538                 switch (pi.getFieldNumber()) {
    539                     case (int) fieldId1:
    540                         pi.readInt(fieldId1);
    541                         // don't fail, varint is ok
    542                         break;
    543                     case (int) fieldId2:
    544                         pi.readInt(fieldId2);
    545                         fail("Should have thrown a WireTypeMismatchException");
    546                         break;
    547                     case (int) fieldId3:
    548                         pi.readInt(fieldId3);
    549                         // don't fail, length delimited is ok (represents packed uint32)
    550                         break;
    551                     case (int) fieldId6:
    552                         pi.readInt(fieldId6);
    553                         fail("Should have thrown a WireTypeMismatchException");
    554                         break;
    555                     default:
    556                         fail("Unexpected field id " + pi.getFieldNumber());
    557                 }
    558             } catch (WireTypeMismatchException wtme) {
    559                 // good
    560             }
    561         }
    562         stream.close();
    563     }
    564 }
    565