code: @SuppressWarnings("unchecked")
    protected Object messageToTuple(FieldDescriptor fieldDescriptor, Object fieldValue) {
      if (fieldValue == null) {
        // protobufs unofficially ensures values are not null. just in case:
        return null;
      }
      assert fieldDescriptor.getType() == FieldDescriptor.Type.MESSAGE : "messageToTuple called with field of type " + fieldDescriptor.getType();
  
      if (fieldDescriptor.isRepeated()) {
        // The protobuf contract is that if the field is repeated, then the object returned is actually a List
        // of the underlying datatype, which in this case is a nested message.
        List<Message> messageList = (List<Message>) (fieldValue != null ? fieldValue : Lists.newArrayList());
  
        DataBag bag = new NonSpillableDataBag(messageList.size());
        for (Message m : messageList) {
          bag.add(new ProtobufTuple(m));
        }
        return bag;
      } else {
        return new ProtobufTuple((Message)fieldValue);
      }
    }
docs: Translate a nested message to a tuple.  If the field is repeated, it walks the list and adds each to a bag.
  Otherwise, it just adds the given one.
  @param fieldDescriptor the descriptor object for the given field.
  @param fieldValue the object representing the value of this field, possibly null.
  @return the object representing fieldValue in Pig -- either a bag or a tuple.