/*
* 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.
*/
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.ExtensionRegistry;
import protos.GroupFe;
import protos.GroupRe;
import protos.MessageData;
import protos.MessageData.GroupF;
import protos.MessageData.GroupR;
import protos.MessageData.SubMsg;
import protos.MessageData.SubMsg.InnerMsg;
import protos.MessageDataOrBuilder;
import protos.MessageFields;
import protos.MessageSet;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
/**
* Tests for correct behavior of message and group fields.
*/
public class MessagesTest extends ProtobufTest {
public void testParseFromByteArray() throws Exception {
ExtensionRegistry registry = ExtensionRegistry.newInstance();
MessageFields.registerAllExtensions(registry);
MessageData msg = MessageData.parseFrom(ALL_MESSAGES_BYTES, registry);
checkFields(msg);
}
public void testParseReversedMessageSets() throws Exception {
ExtensionRegistry registry = ExtensionRegistry.newInstance();
MessageFields.registerAllExtensions(registry);
MessageData msg = MessageData.parseFrom(
ALL_MESSAGES_WITH_MESSAGE_SETS_REVERSED_BYTES, registry);
checkFields(msg);
}
public void testMergeFromInputStream() throws Exception {
ExtensionRegistry registry = ExtensionRegistry.newInstance();
MessageFields.registerAllExtensions(registry);
ByteArrayInputStream in = new ByteArrayInputStream(ALL_MESSAGES_BYTES);
MessageData.Builder builder = MessageData.newBuilder().mergeFrom(in, registry);
MessageData msg = builder.build();
checkFields(builder);
checkFields(msg);
}
public void testMergeFromOtherMessage() throws Exception {
MessageData filledMsg = getFilledMessage();
MessageData.Builder builder = MessageData.newBuilder();
builder.setExtension(MessageFields.msgFe, SubMsg.newBuilder().setIntF(1).build());
builder.mergeFrom(filledMsg);
MessageData msg = builder.build();
checkFields(builder);
checkFields(msg);
}
public void testSerialization() throws Exception {
MessageData msg = getFilledMessage();
assertEquals(168, msg.getSerializedSize());
byte[] bytes1 = msg.toByteArray();
checkBytes(ALL_MESSAGES_BYTES, bytes1);
ByteArrayOutputStream out = new ByteArrayOutputStream();
msg.writeTo(out);
byte[] bytes2 = out.toByteArray();
checkBytes(ALL_MESSAGES_BYTES, bytes2);
}
// TODO(kstanger): Correct field names is not supported in the wrappers.
/*public void testGroupName() throws Exception {
FieldDescriptor groupField = MessageData.getDescriptor().findFieldByNumber(4);
assertEquals("groupf", groupField.getName());
}*/
public void testGroupSerialization() throws Exception {
GroupF group = GroupF.newBuilder().setIntF(1).build();
assertEquals(2, group.getSerializedSize());
byte[] bytes = group.toByteArray();
byte[] expected = asBytes(new int[] { 0x08, 0x01 });
checkBytes(expected, bytes);
}
public void testMergeExistingMessageFields() throws Exception {
ExtensionRegistry registry = ExtensionRegistry.newInstance();
MessageFields.registerAllExtensions(registry);
MessageData toMerge = MessageData.newBuilder()
.setMsgF(SubMsg.newBuilder().setUintF(123).build())
.setGroupF(GroupF.newBuilder().setUintF(234).build())
.addMsgR(SubMsg.newBuilder().setUintF(345).build())
.addGroupR(GroupR.newBuilder().setUintF(456).build())
.setExtension(MessageFields.msgFe, SubMsg.newBuilder().setUintF(567).build())
.setExtension(MessageFields.groupFe, GroupFe.newBuilder().setUintF(678).build())
.addExtension(MessageFields.msgRe, SubMsg.newBuilder().setUintF(789).build())
.addExtension(MessageFields.groupRe, GroupRe.newBuilder().setUintF(890).build())
.build();
byte[] toMergeBytes = toMerge.toByteArray();
// Save the singular fields so we can verify that they aren't modified by merging.
SubMsg field1 = SubMsg.newBuilder().setIntF(321).build();
GroupF field2 = GroupF.newBuilder().setIntF(432).build();
SubMsg field3 = SubMsg.newBuilder().setIntF(765).build();
GroupFe field4 = GroupFe.newBuilder().setIntF(876).build();
MessageData.Builder builder = MessageData.newBuilder()
.setMsgF(field1)
.setGroupF(field2)
.addMsgR(SubMsg.newBuilder().setIntF(543).build())
.addGroupR(GroupR.newBuilder().setIntF(654).build())
.setExtension(MessageFields.msgFe, field3)
.setExtension(MessageFields.groupFe, field4)
.addExtension(MessageFields.msgRe, SubMsg.newBuilder().setIntF(987).build())
.addExtension(MessageFields.groupRe, GroupRe.newBuilder().setIntF(98).build());
MessageData.Builder builder1 = builder.build().toBuilder();
builder1.mergeFrom(toMerge);
checkMergedFields(builder1);
MessageData.Builder builder2 = builder.build().toBuilder();
builder2.mergeFrom(toMergeBytes, registry);
// TODO(kstanger): This is a bug in the native ObjC runtime. It fails to
// merge message type extension fields when reading from data. Instead it
// just overwrites the existing message field.
//checkMergedFields(builder2);
assertFalse(field1.hasUintF());
assertFalse(field2.hasUintF());
assertFalse(field3.hasUintF());
assertFalse(field4.hasUintF());
}
private void checkMergedFields(MessageDataOrBuilder msg) {
assertEquals(321, msg.getMsgF().getIntF());
assertEquals(123, msg.getMsgF().getUintF());
assertEquals(432, msg.getGroupF().getIntF());
assertEquals(234, msg.getGroupF().getUintF());
assertEquals(2, msg.getMsgRCount());
assertEquals(543, msg.getMsgR(0).getIntF());
assertEquals(345, msg.getMsgR(1).getUintF());
assertEquals(2, msg.getGroupRCount());
assertEquals(654, msg.getGroupR(0).getIntF());
assertEquals(456, msg.getGroupR(1).getUintF());
assertEquals(765, msg.getExtension(MessageFields.msgFe).getIntF());
assertEquals(567, msg.getExtension(MessageFields.msgFe).getUintF());
assertEquals(876, msg.getExtension(MessageFields.groupFe).getIntF());
assertEquals(678, msg.getExtension(MessageFields.groupFe).getUintF());
assertEquals(2, msg.getExtensionCount(MessageFields.msgRe));
assertEquals(987, msg.getExtension(MessageFields.msgRe, 0).getIntF());
assertEquals(789, msg.getExtension(MessageFields.msgRe, 1).getUintF());
assertEquals(2, msg.getExtensionCount(MessageFields.groupRe));
assertEquals(98, msg.getExtension(MessageFields.groupRe, 0).getIntF());
assertEquals(890, msg.getExtension(MessageFields.groupRe, 1).getUintF());
}
private void checkFields(MessageDataOrBuilder msg) {
assertEquals(11, msg.getMsgF().getIntF());
assertEquals(12, msg.getInnerMsgF().getIntF());
assertEquals(13, msg.getRecursiveMsgF().getMsgF().getIntF());
assertEquals(14, msg.getGroupF().getIntF());
assertEquals(15, msg.getMsgSetF().getExtension(MessageData.msgExt).getIntF());
assertEquals(21, msg.getMsgR(0).getIntF());
assertEquals(31, msg.getMsgR(1).getIntF());
assertEquals(22, msg.getInnerMsgR(0).getIntF());
assertEquals(32, msg.getInnerMsgR(1).getIntF());
assertEquals(23, msg.getRecursiveMsgR(0).getMsgF().getIntF());
assertEquals(33, msg.getRecursiveMsgR(1).getMsgF().getIntF());
assertEquals(24, msg.getGroupR(0).getIntF());
assertEquals(34, msg.getGroupR(1).getIntF());
assertEquals(25, msg.getMsgSetR(0).getExtension(MessageData.msgExt).getIntF());
assertEquals(35, msg.getMsgSetR(1).getExtension(MessageData.msgExt).getIntF());
assertEquals(41, msg.getExtension(MessageFields.msgFe).getIntF());
assertEquals(42, msg.getExtension(MessageFields.innerMsgFe).getIntF());
assertEquals(43, msg.getExtension(MessageFields.recursiveMsgFe).getMsgF().getIntF());
assertEquals(44, msg.getExtension(MessageFields.groupFe).getIntF());
assertEquals(51, msg.getExtension(MessageFields.msgRe, 0).getIntF());
assertEquals(61, msg.getExtension(MessageFields.msgRe, 1).getIntF());
assertEquals(52, msg.getExtension(MessageFields.innerMsgRe, 0).getIntF());
assertEquals(62, msg.getExtension(MessageFields.innerMsgRe, 1).getIntF());
assertEquals(53, msg.getExtension(MessageFields.recursiveMsgRe, 0).getMsgF().getIntF());
assertEquals(63, msg.getExtension(MessageFields.recursiveMsgRe, 1).getMsgF().getIntF());
assertEquals(54, msg.getExtension(MessageFields.groupRe, 0).getIntF());
assertEquals(64, msg.getExtension(MessageFields.groupRe, 1).getIntF());
}
private MessageData getFilledMessage() {
return MessageData.newBuilder()
.setMsgF(SubMsg.newBuilder().setIntF(11).build())
.setInnerMsgF(InnerMsg.newBuilder().setIntF(12).build())
.setRecursiveMsgF(MessageData.newBuilder().setMsgF(
SubMsg.newBuilder().setIntF(13).build()).build())
.setGroupF(GroupF.newBuilder().setIntF(14).build())
.setMsgSetF(MessageSet.newBuilder().setExtension(
MessageData.msgExt, SubMsg.newBuilder().setIntF(15).build()))
.addMsgR(SubMsg.newBuilder().setIntF(21).build())
.addMsgR(SubMsg.newBuilder().setIntF(31).build())
.addInnerMsgR(InnerMsg.newBuilder().setIntF(22).build())
.addInnerMsgR(InnerMsg.newBuilder().setIntF(32).build())
.addRecursiveMsgR(MessageData.newBuilder().setMsgF(
SubMsg.newBuilder().setIntF(23).build()).build())
.addRecursiveMsgR(MessageData.newBuilder().setMsgF(
SubMsg.newBuilder().setIntF(33).build()).build())
.addGroupR(GroupR.newBuilder().setIntF(24).build())
.addGroupR(GroupR.newBuilder().setIntF(34).build())
.addMsgSetR(MessageSet.newBuilder().setExtension(
MessageData.msgExt, SubMsg.newBuilder().setIntF(25).build()))
.addMsgSetR(MessageSet.newBuilder().setExtension(
MessageData.msgExt, SubMsg.newBuilder().setIntF(35).build()))
.setExtension(MessageFields.msgFe, SubMsg.newBuilder().setIntF(41).build())
.setExtension(MessageFields.innerMsgFe, InnerMsg.newBuilder().setIntF(42).build())
.setExtension(MessageFields.recursiveMsgFe, MessageData.newBuilder().setMsgF(
SubMsg.newBuilder().setIntF(43).build()).build())
.setExtension(MessageFields.groupFe, GroupFe.newBuilder().setIntF(44).build())
.addExtension(MessageFields.msgRe, SubMsg.newBuilder().setIntF(51).build())
.addExtension(MessageFields.msgRe, SubMsg.newBuilder().setIntF(61).build())
.addExtension(MessageFields.innerMsgRe, InnerMsg.newBuilder().setIntF(52).build())
.addExtension(MessageFields.innerMsgRe, InnerMsg.newBuilder().setIntF(62).build())
.addExtension(MessageFields.recursiveMsgRe, MessageData.newBuilder().setMsgF(
SubMsg.newBuilder().setIntF(53).build()).build())
.addExtension(MessageFields.recursiveMsgRe, MessageData.newBuilder().setMsgF(
SubMsg.newBuilder().setIntF(63).build()).build())
.addExtension(MessageFields.groupRe, GroupRe.newBuilder().setIntF(54).build())
.addExtension(MessageFields.groupRe, GroupRe.newBuilder().setIntF(64).build())
.build();
}
private static final byte[] ALL_MESSAGES_BYTES = asBytes(new int[] {
0x0A, 0x02, 0x08, 0x0B, 0x12, 0x02, 0x08, 0x0C, 0x1A, 0x04, 0x0A, 0x02, 0x08, 0x0D, 0x23, 0x08,
0x0E, 0x24, 0x2A, 0x09, 0x0B, 0x10, 0xE8, 0x07, 0x1A, 0x02, 0x08, 0x0F, 0x0C, 0xAA, 0x01, 0x02,
0x08, 0x15, 0xAA, 0x01, 0x02, 0x08, 0x1F, 0xB2, 0x01, 0x02, 0x08, 0x16, 0xB2, 0x01, 0x02, 0x08,
0x20, 0xBA, 0x01, 0x04, 0x0A, 0x02, 0x08, 0x17, 0xBA, 0x01, 0x04, 0x0A, 0x02, 0x08, 0x21, 0xC3,
0x01, 0x08, 0x18, 0xC4, 0x01, 0xC3, 0x01, 0x08, 0x22, 0xC4, 0x01, 0xCA, 0x01, 0x09, 0x0B, 0x10,
0xE8, 0x07, 0x1A, 0x02, 0x08, 0x19, 0x0C, 0xCA, 0x01, 0x09, 0x0B, 0x10, 0xE8, 0x07, 0x1A, 0x02,
0x08, 0x23, 0x0C, 0xCA, 0x3E, 0x02, 0x08, 0x29, 0xD2, 0x3E, 0x02, 0x08, 0x2A, 0xDA, 0x3E, 0x04,
0x0A, 0x02, 0x08, 0x2B, 0xE3, 0x3E, 0x08, 0x2C, 0xE4, 0x3E, 0xEA, 0x3F, 0x02, 0x08, 0x33, 0xEA,
0x3F, 0x02, 0x08, 0x3D, 0xF2, 0x3F, 0x02, 0x08, 0x34, 0xF2, 0x3F, 0x02, 0x08, 0x3E, 0xFA, 0x3F,
0x04, 0x0A, 0x02, 0x08, 0x35, 0xFA, 0x3F, 0x04, 0x0A, 0x02, 0x08, 0x3F, 0x83, 0x40, 0x08, 0x36,
0x84, 0x40, 0x83, 0x40, 0x08, 0x40, 0x84, 0x40
});
// Same as above, except that the message set fields have the type id and messages in the reverse
// order.
private static final byte[] ALL_MESSAGES_WITH_MESSAGE_SETS_REVERSED_BYTES = asBytes(new int[] {
0x0A, 0x02, 0x08, 0x0B, 0x12, 0x02, 0x08, 0x0C, 0x1A, 0x04, 0x0A, 0x02, 0x08, 0x0D, 0x23, 0x08,
0x0E, 0x24, 0x2A, 0x09, 0x0B, 0x1A, 0x02, 0x08, 0x0F, 0x10, 0xE8, 0x07, 0x0C, 0xAA, 0x01, 0x02,
0x08, 0x15, 0xAA, 0x01, 0x02, 0x08, 0x1F, 0xB2, 0x01, 0x02, 0x08, 0x16, 0xB2, 0x01, 0x02, 0x08,
0x20, 0xBA, 0x01, 0x04, 0x0A, 0x02, 0x08, 0x17, 0xBA, 0x01, 0x04, 0x0A, 0x02, 0x08, 0x21, 0xC3,
0x01, 0x08, 0x18, 0xC4, 0x01, 0xC3, 0x01, 0x08, 0x22, 0xC4, 0x01, 0xCA, 0x01, 0x09, 0x0B, 0x1A,
0x02, 0x08, 0x19, 0x10, 0xE8, 0x07, 0x0C, 0xCA, 0x01, 0x09, 0x0B, 0x1A, 0x02, 0x08, 0x23, 0x10,
0xE8, 0x07, 0x0C, 0xCA, 0x3E, 0x02, 0x08, 0x29, 0xD2, 0x3E, 0x02, 0x08, 0x2A, 0xDA, 0x3E, 0x04,
0x0A, 0x02, 0x08, 0x2B, 0xE3, 0x3E, 0x08, 0x2C, 0xE4, 0x3E, 0xEA, 0x3F, 0x02, 0x08, 0x33, 0xEA,
0x3F, 0x02, 0x08, 0x3D, 0xF2, 0x3F, 0x02, 0x08, 0x34, 0xF2, 0x3F, 0x02, 0x08, 0x3E, 0xFA, 0x3F,
0x04, 0x0A, 0x02, 0x08, 0x35, 0xFA, 0x3F, 0x04, 0x0A, 0x02, 0x08, 0x3F, 0x83, 0x40, 0x08, 0x36,
0x84, 0x40, 0x83, 0x40, 0x08, 0x40, 0x84, 0x40
});
}