• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 package com.google.protobuf;
32 
33 import static com.google.protobuf.TestUtil.TEST_REQUIRED_INITIALIZED;
34 import static com.google.protobuf.TestUtil.TEST_REQUIRED_UNINITIALIZED;
35 
36 import com.google.protobuf.Descriptors.FieldDescriptor;
37 import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
38 import protobuf_unittest.UnittestProto;
39 import protobuf_unittest.UnittestProto.ForeignMessage;
40 import protobuf_unittest.UnittestProto.TestAllExtensions;
41 import protobuf_unittest.UnittestProto.TestAllTypes;
42 import protobuf_unittest.UnittestProto.TestPackedTypes;
43 import protobuf_unittest.UnittestProto.TestRequired;
44 import protobuf_unittest.UnittestProto.TestRequiredForeign;
45 import protobuf_unittest.UnittestProto.TestUnpackedTypes;
46 import java.util.Map;
47 import junit.framework.TestCase;
48 
49 /**
50  * Unit test for {@link AbstractMessage}.
51  *
52  * @author kenton@google.com Kenton Varda
53  */
54 public class AbstractMessageTest extends TestCase {
55   /**
56    * Extends AbstractMessage and wraps some other message object. The methods of the Message
57    * interface which aren't explicitly implemented by AbstractMessage are forwarded to the wrapped
58    * object. This allows us to test that AbstractMessage's implementations work even if the wrapped
59    * object does not use them.
60    */
61   private static class AbstractMessageWrapper extends AbstractMessage {
62     private final Message wrappedMessage;
63 
AbstractMessageWrapper(Message wrappedMessage)64     public AbstractMessageWrapper(Message wrappedMessage) {
65       this.wrappedMessage = wrappedMessage;
66     }
67 
68     @Override
getDescriptorForType()69     public Descriptors.Descriptor getDescriptorForType() {
70       return wrappedMessage.getDescriptorForType();
71     }
72 
73     @Override
getDefaultInstanceForType()74     public AbstractMessageWrapper getDefaultInstanceForType() {
75       return new AbstractMessageWrapper(wrappedMessage.getDefaultInstanceForType());
76     }
77 
78     @Override
getAllFields()79     public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
80       return wrappedMessage.getAllFields();
81     }
82 
83     @Override
hasField(Descriptors.FieldDescriptor field)84     public boolean hasField(Descriptors.FieldDescriptor field) {
85       return wrappedMessage.hasField(field);
86     }
87 
88     @Override
getField(Descriptors.FieldDescriptor field)89     public Object getField(Descriptors.FieldDescriptor field) {
90       return wrappedMessage.getField(field);
91     }
92 
93     @Override
getRepeatedFieldCount(Descriptors.FieldDescriptor field)94     public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
95       return wrappedMessage.getRepeatedFieldCount(field);
96     }
97 
98     @Override
getRepeatedField(Descriptors.FieldDescriptor field, int index)99     public Object getRepeatedField(Descriptors.FieldDescriptor field, int index) {
100       return wrappedMessage.getRepeatedField(field, index);
101     }
102 
103     @Override
getUnknownFields()104     public UnknownFieldSet getUnknownFields() {
105       return wrappedMessage.getUnknownFields();
106     }
107 
108     @Override
newBuilderForType()109     public Builder newBuilderForType() {
110       return new Builder(wrappedMessage.newBuilderForType());
111     }
112 
113     @Override
toBuilder()114     public Builder toBuilder() {
115       return new Builder(wrappedMessage.toBuilder());
116     }
117 
118     static class Builder extends AbstractMessage.Builder<Builder> {
119       private final Message.Builder wrappedBuilder;
120 
Builder(Message.Builder wrappedBuilder)121       public Builder(Message.Builder wrappedBuilder) {
122         this.wrappedBuilder = wrappedBuilder;
123       }
124 
125       @Override
build()126       public AbstractMessageWrapper build() {
127         return new AbstractMessageWrapper(wrappedBuilder.build());
128       }
129 
130       @Override
buildPartial()131       public AbstractMessageWrapper buildPartial() {
132         return new AbstractMessageWrapper(wrappedBuilder.buildPartial());
133       }
134 
135       @Override
clone()136       public Builder clone() {
137         return new Builder(wrappedBuilder.clone());
138       }
139 
140       @Override
isInitialized()141       public boolean isInitialized() {
142         return clone().buildPartial().isInitialized();
143       }
144 
145       @Override
getDescriptorForType()146       public Descriptors.Descriptor getDescriptorForType() {
147         return wrappedBuilder.getDescriptorForType();
148       }
149 
150       @Override
getDefaultInstanceForType()151       public AbstractMessageWrapper getDefaultInstanceForType() {
152         return new AbstractMessageWrapper(wrappedBuilder.getDefaultInstanceForType());
153       }
154 
155       @Override
getAllFields()156       public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
157         return wrappedBuilder.getAllFields();
158       }
159 
160       @Override
newBuilderForField(Descriptors.FieldDescriptor field)161       public Builder newBuilderForField(Descriptors.FieldDescriptor field) {
162         return new Builder(wrappedBuilder.newBuilderForField(field));
163       }
164 
165       @Override
hasField(Descriptors.FieldDescriptor field)166       public boolean hasField(Descriptors.FieldDescriptor field) {
167         return wrappedBuilder.hasField(field);
168       }
169 
170       @Override
getField(Descriptors.FieldDescriptor field)171       public Object getField(Descriptors.FieldDescriptor field) {
172         return wrappedBuilder.getField(field);
173       }
174 
175       @Override
setField(Descriptors.FieldDescriptor field, Object value)176       public Builder setField(Descriptors.FieldDescriptor field, Object value) {
177         wrappedBuilder.setField(field, value);
178         return this;
179       }
180 
181       @Override
clearField(Descriptors.FieldDescriptor field)182       public Builder clearField(Descriptors.FieldDescriptor field) {
183         wrappedBuilder.clearField(field);
184         return this;
185       }
186 
187       @Override
getRepeatedFieldCount(Descriptors.FieldDescriptor field)188       public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
189         return wrappedBuilder.getRepeatedFieldCount(field);
190       }
191 
192       @Override
getRepeatedField(Descriptors.FieldDescriptor field, int index)193       public Object getRepeatedField(Descriptors.FieldDescriptor field, int index) {
194         return wrappedBuilder.getRepeatedField(field, index);
195       }
196 
197       @Override
setRepeatedField(Descriptors.FieldDescriptor field, int index, Object value)198       public Builder setRepeatedField(Descriptors.FieldDescriptor field, int index, Object value) {
199         wrappedBuilder.setRepeatedField(field, index, value);
200         return this;
201       }
202 
203       @Override
addRepeatedField(Descriptors.FieldDescriptor field, Object value)204       public Builder addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
205         wrappedBuilder.addRepeatedField(field, value);
206         return this;
207       }
208 
209       @Override
getUnknownFields()210       public UnknownFieldSet getUnknownFields() {
211         return wrappedBuilder.getUnknownFields();
212       }
213 
214       @Override
setUnknownFields(UnknownFieldSet unknownFields)215       public Builder setUnknownFields(UnknownFieldSet unknownFields) {
216         wrappedBuilder.setUnknownFields(unknownFields);
217         return this;
218       }
219 
220       @Override
getFieldBuilder(FieldDescriptor field)221       public Message.Builder getFieldBuilder(FieldDescriptor field) {
222         return wrappedBuilder.getFieldBuilder(field);
223       }
224     }
225 
226     @Override
getParserForType()227     public Parser<? extends Message> getParserForType() {
228       return wrappedMessage.getParserForType();
229     }
230   }
231 
232   // =================================================================
233 
234   TestUtil.ReflectionTester reflectionTester =
235       new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
236 
237   TestUtil.ReflectionTester extensionsReflectionTester =
238       new TestUtil.ReflectionTester(
239           TestAllExtensions.getDescriptor(), TestUtil.getFullExtensionRegistry());
240 
testClear()241   public void testClear() throws Exception {
242     AbstractMessageWrapper message =
243         new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder(TestUtil.getAllSet()))
244             .clear()
245             .build();
246     TestUtil.assertClear((TestAllTypes) message.wrappedMessage);
247   }
248 
testCopy()249   public void testCopy() throws Exception {
250     AbstractMessageWrapper message =
251         new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder())
252             .mergeFrom(TestUtil.getAllSet())
253             .build();
254     TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage);
255   }
256 
testSerializedSize()257   public void testSerializedSize() throws Exception {
258     TestAllTypes message = TestUtil.getAllSet();
259     Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet());
260 
261     assertEquals(message.getSerializedSize(), abstractMessage.getSerializedSize());
262   }
263 
testSerialization()264   public void testSerialization() throws Exception {
265     Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet());
266 
267     TestUtil.assertAllFieldsSet(TestAllTypes.parseFrom(abstractMessage.toByteString()));
268 
269     assertEquals(TestUtil.getAllSet().toByteString(), abstractMessage.toByteString());
270   }
271 
testParsing()272   public void testParsing() throws Exception {
273     AbstractMessageWrapper.Builder builder =
274         new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder());
275     AbstractMessageWrapper message = builder.mergeFrom(TestUtil.getAllSet().toByteString()).build();
276     TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage);
277   }
278 
testParsingUninitialized()279   public void testParsingUninitialized() throws Exception {
280     TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
281     builder.getOptionalMessageBuilder().setDummy2(10);
282     ByteString bytes = builder.buildPartial().toByteString();
283     Message.Builder abstractMessageBuilder =
284         new AbstractMessageWrapper.Builder(TestRequiredForeign.newBuilder());
285     // mergeFrom() should not throw initialization error.
286     abstractMessageBuilder.mergeFrom(bytes).buildPartial();
287     try {
288       abstractMessageBuilder.mergeFrom(bytes).build();
289       fail();
290     } catch (UninitializedMessageException ex) {
291       // pass
292     }
293 
294     // test DynamicMessage directly.
295     Message.Builder dynamicMessageBuilder =
296         DynamicMessage.newBuilder(TestRequiredForeign.getDescriptor());
297     // mergeFrom() should not throw initialization error.
298     dynamicMessageBuilder.mergeFrom(bytes).buildPartial();
299     try {
300       dynamicMessageBuilder.mergeFrom(bytes).build();
301       fail();
302     } catch (UninitializedMessageException ex) {
303       // pass
304     }
305   }
306 
testPackedSerialization()307   public void testPackedSerialization() throws Exception {
308     Message abstractMessage = new AbstractMessageWrapper(TestUtil.getPackedSet());
309 
310     TestUtil.assertPackedFieldsSet(TestPackedTypes.parseFrom(abstractMessage.toByteString()));
311 
312     assertEquals(TestUtil.getPackedSet().toByteString(), abstractMessage.toByteString());
313   }
314 
testPackedParsing()315   public void testPackedParsing() throws Exception {
316     AbstractMessageWrapper.Builder builder =
317         new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder());
318     AbstractMessageWrapper message =
319         builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
320     TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage);
321   }
322 
testUnpackedSerialization()323   public void testUnpackedSerialization() throws Exception {
324     Message abstractMessage = new AbstractMessageWrapper(TestUtil.getUnpackedSet());
325 
326     TestUtil.assertUnpackedFieldsSet(TestUnpackedTypes.parseFrom(abstractMessage.toByteString()));
327 
328     assertEquals(TestUtil.getUnpackedSet().toByteString(), abstractMessage.toByteString());
329   }
330 
testParsePackedToUnpacked()331   public void testParsePackedToUnpacked() throws Exception {
332     AbstractMessageWrapper.Builder builder =
333         new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder());
334     AbstractMessageWrapper message =
335         builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
336     TestUtil.assertUnpackedFieldsSet((TestUnpackedTypes) message.wrappedMessage);
337   }
338 
testParseUnpackedToPacked()339   public void testParseUnpackedToPacked() throws Exception {
340     AbstractMessageWrapper.Builder builder =
341         new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder());
342     AbstractMessageWrapper message =
343         builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
344     TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage);
345   }
346 
testUnpackedParsing()347   public void testUnpackedParsing() throws Exception {
348     AbstractMessageWrapper.Builder builder =
349         new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder());
350     AbstractMessageWrapper message =
351         builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
352     TestUtil.assertUnpackedFieldsSet((TestUnpackedTypes) message.wrappedMessage);
353   }
354 
testOptimizedForSize()355   public void testOptimizedForSize() throws Exception {
356     // We're mostly only checking that this class was compiled successfully.
357     TestOptimizedForSize message = TestOptimizedForSize.newBuilder().setI(1).build();
358     message = TestOptimizedForSize.parseFrom(message.toByteString());
359     assertEquals(2, message.getSerializedSize());
360   }
361 
362   // -----------------------------------------------------------------
363   // Tests for isInitialized().
364 
testIsInitialized()365   public void testIsInitialized() throws Exception {
366     TestRequired.Builder builder = TestRequired.newBuilder();
367     AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder);
368 
369     assertFalse(abstractBuilder.isInitialized());
370     assertEquals("a, b, c", abstractBuilder.getInitializationErrorString());
371     builder.setA(1);
372     assertFalse(abstractBuilder.isInitialized());
373     assertEquals("b, c", abstractBuilder.getInitializationErrorString());
374     builder.setB(1);
375     assertFalse(abstractBuilder.isInitialized());
376     assertEquals("c", abstractBuilder.getInitializationErrorString());
377     builder.setC(1);
378     assertTrue(abstractBuilder.isInitialized());
379     assertEquals("", abstractBuilder.getInitializationErrorString());
380   }
381 
testForeignIsInitialized()382   public void testForeignIsInitialized() throws Exception {
383     TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
384     AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder);
385 
386     assertTrue(abstractBuilder.isInitialized());
387     assertEquals("", abstractBuilder.getInitializationErrorString());
388 
389     builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
390     assertFalse(abstractBuilder.isInitialized());
391     assertEquals(
392         "optional_message.b, optional_message.c", abstractBuilder.getInitializationErrorString());
393 
394     builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
395     assertTrue(abstractBuilder.isInitialized());
396     assertEquals("", abstractBuilder.getInitializationErrorString());
397 
398     builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
399     assertFalse(abstractBuilder.isInitialized());
400     assertEquals(
401         "repeated_message[0].b, repeated_message[0].c",
402         abstractBuilder.getInitializationErrorString());
403 
404     builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
405     assertTrue(abstractBuilder.isInitialized());
406     assertEquals("", abstractBuilder.getInitializationErrorString());
407   }
408 
409   // -----------------------------------------------------------------
410   // Tests for mergeFrom
411 
412   static final TestAllTypes MERGE_SOURCE =
413       TestAllTypes.newBuilder()
414           .setOptionalInt32(1)
415           .setOptionalString("foo")
416           .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
417           .addRepeatedString("bar")
418           .build();
419 
420   static final TestAllTypes MERGE_DEST =
421       TestAllTypes.newBuilder()
422           .setOptionalInt64(2)
423           .setOptionalString("baz")
424           .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build())
425           .addRepeatedString("qux")
426           .build();
427 
428   static final String MERGE_RESULT_TEXT =
429       ""
430           + "optional_int32: 1\n"
431           + "optional_int64: 2\n"
432           + "optional_string: \"foo\"\n"
433           + "optional_foreign_message {\n"
434           + "  c: 3\n"
435           + "}\n"
436           + "repeated_string: \"qux\"\n"
437           + "repeated_string: \"bar\"\n";
438 
testMergeFrom()439   public void testMergeFrom() throws Exception {
440     AbstractMessageWrapper result =
441         new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder(MERGE_DEST))
442             .mergeFrom(MERGE_SOURCE)
443             .build();
444 
445     assertEquals(MERGE_RESULT_TEXT, result.toString());
446   }
447 
448   // -----------------------------------------------------------------
449   // Tests for equals and hashCode
450 
testEqualsAndHashCode()451   public void testEqualsAndHashCode() throws Exception {
452     TestAllTypes a = TestUtil.getAllSet();
453     TestAllTypes b = TestAllTypes.newBuilder().build();
454     TestAllTypes c = TestAllTypes.newBuilder(b).addRepeatedString("x").build();
455     TestAllTypes d = TestAllTypes.newBuilder(c).addRepeatedString("y").build();
456     TestAllExtensions e = TestUtil.getAllExtensionsSet();
457     TestAllExtensions f =
458         TestAllExtensions.newBuilder(e)
459             .addExtension(UnittestProto.repeatedInt32Extension, 999)
460             .build();
461 
462     checkEqualsIsConsistent(a);
463     checkEqualsIsConsistent(b);
464     checkEqualsIsConsistent(c);
465     checkEqualsIsConsistent(d);
466     checkEqualsIsConsistent(e);
467     checkEqualsIsConsistent(f);
468 
469     checkNotEqual(a, b);
470     checkNotEqual(a, c);
471     checkNotEqual(a, d);
472     checkNotEqual(a, e);
473     checkNotEqual(a, f);
474 
475     checkNotEqual(b, c);
476     checkNotEqual(b, d);
477     checkNotEqual(b, e);
478     checkNotEqual(b, f);
479 
480     checkNotEqual(c, d);
481     checkNotEqual(c, e);
482     checkNotEqual(c, f);
483 
484     checkNotEqual(d, e);
485     checkNotEqual(d, f);
486 
487     checkNotEqual(e, f);
488 
489     // Deserializing into the TestEmptyMessage such that every field
490     // is an {@link UnknownFieldSet.Field}.
491     UnittestProto.TestEmptyMessage eUnknownFields =
492         UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray());
493     UnittestProto.TestEmptyMessage fUnknownFields =
494         UnittestProto.TestEmptyMessage.parseFrom(f.toByteArray());
495     checkNotEqual(eUnknownFields, fUnknownFields);
496     checkEqualsIsConsistent(eUnknownFields);
497     checkEqualsIsConsistent(fUnknownFields);
498 
499     // Subsequent reconstitutions should be identical
500     UnittestProto.TestEmptyMessage eUnknownFields2 =
501         UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray());
502     checkEqualsIsConsistent(eUnknownFields, eUnknownFields2);
503   }
504 
505   /** Asserts that the given proto has symmetric equals and hashCode methods. */
checkEqualsIsConsistent(Message message)506   private void checkEqualsIsConsistent(Message message) {
507     // Object should be equal to itself.
508     assertEquals(message, message);
509 
510     // Object should be equal to a dynamic copy of itself.
511     DynamicMessage dynamic = DynamicMessage.newBuilder(message).build();
512     checkEqualsIsConsistent(message, dynamic);
513   }
514 
515   /** Asserts that the given protos are equal and have the same hash code. */
checkEqualsIsConsistent(Message message1, Message message2)516   private void checkEqualsIsConsistent(Message message1, Message message2) {
517     assertEquals(message1, message2);
518     assertEquals(message2, message1);
519     assertEquals(message2.hashCode(), message1.hashCode());
520   }
521 
522   /**
523    * Asserts that the given protos are not equal and have different hash codes.
524    *
525    * <p><b>Note:</b> It's valid for non-equal objects to have the same hash code, so this test is
526    * stricter than it needs to be. However, this should happen relatively rarely.
527    */
checkNotEqual(Message m1, Message m2)528   private void checkNotEqual(Message m1, Message m2) {
529     String equalsError = String.format("%s should not be equal to %s", m1, m2);
530     assertFalse(equalsError, m1.equals(m2));
531     assertFalse(equalsError, m2.equals(m1));
532 
533     assertFalse(
534         String.format("%s should have a different hash code from %s", m1, m2),
535         m1.hashCode() == m2.hashCode());
536   }
537 
testCheckByteStringIsUtf8OnUtf8()538   public void testCheckByteStringIsUtf8OnUtf8() {
539     ByteString byteString = ByteString.copyFromUtf8("some text");
540     AbstractMessageLite.checkByteStringIsUtf8(byteString);
541     // No exception thrown.
542   }
543 
testCheckByteStringIsUtf8OnNonUtf8()544   public void testCheckByteStringIsUtf8OnNonUtf8() {
545     ByteString byteString =
546         ByteString.copyFrom(new byte[] {(byte) 0x80}); // A lone continuation byte.
547     try {
548       AbstractMessageLite.checkByteStringIsUtf8(byteString);
549       fail("Expected AbstractMessageLite.checkByteStringIsUtf8 to throw IllegalArgumentException");
550     } catch (IllegalArgumentException exception) {
551       assertEquals("Byte string is not UTF-8.", exception.getMessage());
552     }
553   }
554 }
555