code: @SuppressWarnings("unchecked")
    protected Object singleFieldToTuple(FieldDescriptor fieldDescriptor, Object fieldValue) {
      assert fieldDescriptor.getType() != FieldDescriptor.Type.MESSAGE : "messageToFieldSchema 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 "primitive" like int, float, String, etc.
        // We have to make a single-item tuple out of it to put it in the bag.
        List<Object> fieldValueList = (List<Object>) (fieldValue != null ? fieldValue : Collections.emptyList());
        DataBag bag = new NonSpillableDataBag(fieldValueList.size());
        for (Object singleFieldValue : fieldValueList) {
          Object nonEnumFieldValue = coerceToPigTypes(fieldDescriptor, singleFieldValue);
          Tuple innerTuple = tupleFactory_.newTuple(1);
          try {
            innerTuple.set(0, nonEnumFieldValue);
          } catch (ExecException e) { // not expected
            throw new RuntimeException(e);
          }
          bag.add(innerTuple);
        }
        return bag;
      } else {
        return coerceToPigTypes(fieldDescriptor, fieldValue);
      }
    }
docs: Translate a single field 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 single field.
  @throws ExecException if Pig decides to.  Shouldn't happen because we won't walk off the end of a tuple's field set.