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 13 import com.google.protobuf.testing.Proto2Testing; 14 import com.google.protobuf.testing.Proto2Testing.Proto2Message; 15 import com.google.protobuf.testing.Proto2Testing.Proto2Message.TestEnum; 16 import com.google.protobuf.testing.Proto2Testing.Proto2MessageWithExtensions; 17 import java.util.List; 18 import org.junit.Before; 19 import org.junit.Test; 20 import org.junit.runner.RunWith; 21 import org.junit.runners.JUnit4; 22 23 @RunWith(JUnit4.class) 24 public class Proto2ExtensionLookupSchemaTest { 25 private byte[] data; 26 private ExtensionRegistry extensionRegistry; 27 28 @Before setup()29 public void setup() { 30 TestSchemas.registerGenericProto2Schemas(); 31 32 data = new Proto2MessageFactory(10, 20, 1, 1).newMessage().toByteArray(); 33 extensionRegistry = ExtensionRegistry.newInstance(); 34 Proto2Testing.registerAllExtensions(extensionRegistry); 35 } 36 37 @Test testExtensions()38 public void testExtensions() throws Exception { 39 Proto2MessageWithExtensions base = 40 Proto2MessageWithExtensions.parseFrom(data, extensionRegistry); 41 42 Proto2MessageWithExtensions message = 43 ExperimentalSerializationUtil.fromByteArray( 44 data, Proto2MessageWithExtensions.class, extensionRegistry); 45 assertThat(message).isEqualTo(base); 46 47 Proto2MessageWithExtensions roundtripMessage = 48 ExperimentalSerializationUtil.fromByteArray( 49 ExperimentalSerializationUtil.toByteArray(message), 50 Proto2MessageWithExtensions.class, 51 extensionRegistry); 52 assertThat(roundtripMessage).isEqualTo(base); 53 } 54 55 @Test testUnknownEnum()56 public void testUnknownEnum() throws Exception { 57 // Use unknown fields to hold invalid enum values. 58 UnknownFieldSetLite unknowns = UnknownFieldSetLite.newInstance(); 59 final int outOfRange = 1000; 60 assertThat(TestEnum.forNumber(outOfRange)).isNull(); 61 unknowns.storeField( 62 WireFormat.makeTag(Proto2Message.FIELD_ENUM_13_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT), 63 (long) outOfRange); 64 unknowns.storeField( 65 WireFormat.makeTag( 66 Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT), 67 (long) TestEnum.ONE_VALUE); 68 unknowns.storeField( 69 WireFormat.makeTag( 70 Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT), 71 (long) outOfRange); 72 unknowns.storeField( 73 WireFormat.makeTag( 74 Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT), 75 (long) TestEnum.TWO_VALUE); 76 77 { 78 // Construct a packed enum list. 79 int packedSize = 80 CodedOutputStream.computeUInt32SizeNoTag(TestEnum.ONE_VALUE) 81 + CodedOutputStream.computeUInt32SizeNoTag(outOfRange) 82 + CodedOutputStream.computeUInt32SizeNoTag(TestEnum.ONE_VALUE); 83 ByteString.CodedBuilder packedBuilder = ByteString.newCodedBuilder(packedSize); 84 CodedOutputStream packedOut = packedBuilder.getCodedOutput(); 85 packedOut.writeEnumNoTag(TestEnum.ONE_VALUE); 86 packedOut.writeEnumNoTag(outOfRange); 87 packedOut.writeEnumNoTag(TestEnum.TWO_VALUE); 88 unknowns.storeField( 89 WireFormat.makeTag( 90 Proto2Message.FIELD_ENUM_LIST_PACKED_44_FIELD_NUMBER, 91 WireFormat.WIRETYPE_LENGTH_DELIMITED), 92 packedBuilder.build()); 93 } 94 int size = unknowns.getSerializedSize(); 95 byte[] output = new byte[size]; 96 CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); 97 unknowns.writeTo(codedOutput); 98 codedOutput.flush(); 99 100 Proto2MessageWithExtensions parsed = 101 ExperimentalSerializationUtil.fromByteArray( 102 output, Proto2MessageWithExtensions.class, extensionRegistry); 103 assertWithMessage("out-of-range singular enum should not be in message") 104 .that(parsed.hasExtension(Proto2Testing.fieldEnum13)) 105 .isFalse(); 106 { 107 List<Long> singularEnum = 108 parsed 109 .getUnknownFields() 110 .getField(Proto2Message.FIELD_ENUM_13_FIELD_NUMBER) 111 .getVarintList(); 112 assertThat(singularEnum).hasSize(1); 113 assertThat(singularEnum.get(0)).isEqualTo((Long) (long) outOfRange); 114 } 115 { 116 List<Long> repeatedEnum = 117 parsed 118 .getUnknownFields() 119 .getField(Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER) 120 .getVarintList(); 121 assertThat(repeatedEnum).hasSize(1); 122 assertThat(repeatedEnum.get(0)).isEqualTo((Long) (long) outOfRange); 123 } 124 { 125 List<Long> packedRepeatedEnum = 126 parsed 127 .getUnknownFields() 128 .getField(Proto2Message.FIELD_ENUM_LIST_PACKED_44_FIELD_NUMBER) 129 .getVarintList(); 130 assertThat(packedRepeatedEnum).hasSize(1); 131 assertThat(packedRepeatedEnum.get(0)).isEqualTo((Long) (long) outOfRange); 132 } 133 assertWithMessage("out-of-range repeated enum should not be in message") 134 .that(parsed.getExtension(Proto2Testing.fieldEnumList30).size()) 135 .isEqualTo(2); 136 assertThat(parsed.getExtension(Proto2Testing.fieldEnumList30, 0)).isEqualTo(TestEnum.ONE); 137 assertThat(parsed.getExtension(Proto2Testing.fieldEnumList30, 1)).isEqualTo(TestEnum.TWO); 138 assertWithMessage("out-of-range packed repeated enum should not be in message") 139 .that(parsed.getExtension(Proto2Testing.fieldEnumListPacked44).size()) 140 .isEqualTo(2); 141 assertThat(parsed.getExtension(Proto2Testing.fieldEnumListPacked44, 0)).isEqualTo(TestEnum.ONE); 142 assertThat(parsed.getExtension(Proto2Testing.fieldEnumListPacked44, 1)).isEqualTo(TestEnum.TWO); 143 } 144 } 145