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