private int convertField()

in core/src/main/java/com/twitter/elephantbird/util/ThriftToDynamicProto.java [433:502]


  private int convertField(TBase<?, ?> thriftObj, Message.Builder builder,
                           TStructDescriptor fieldDesc, int fieldId, Field tField) {
    int tmpFieldId = fieldId;
    FieldDescriptor protoFieldDesc = builder.getDescriptorForType().findFieldByName(
        tField.getName());

    if (protoFieldDesc == null) {
      // not finding a field might be ok if we're ignoring an unsupported types
      Type protoType = thriftTypeToProtoType(tField);
      if (protoType == null
          && (ignoreUnsupportedTypes
              || (!supportNestedObjects && hasNestedObject(tField)))) {
        return tmpFieldId; // no-op
      }
      throw new RuntimeException("Field " + tField.getName() + " not found in dynamic protobuf.");
    }

    Object fieldValue = fieldDesc.getFieldValue(tmpFieldId++, thriftObj);
    if (fieldValue == null) {
      return tmpFieldId;
    }

    try {
      // For non-Map containers that contain struct types,
      // we have to convert each struct into a Message.
      if (isStructContainer(tField)) {
        List<Message> convertedStructs = Lists.newLinkedList();

        Iterable<TBase<?, ?>> structIterator = (Iterable<TBase<?, ?>>) fieldValue;
        for (TBase<?, ?> struct : structIterator) {
          convertedStructs.add(doConvert(struct));
        }

        fieldValue = convertedStructs;
      } else if (tField.isMap()) {
        List<Message> convertedMapEntries = Lists.newLinkedList();

        Map<?, ?> rawMap = (Map) fieldValue;
        for (Map.Entry<?, ?> entry : rawMap.entrySet()) {
          Message.Builder mapBuilder = mapEntryProtoBuilder(fieldDesc, tField);
          Message msg = buildMapEntryMessage(mapBuilder, tField, entry.getKey(), entry.getValue());
          convertedMapEntries.add(msg);
        }

        fieldValue = convertedMapEntries;
      } else {
        // protobufs throws an exception if you try to set byte on an int32 field so we need to
        // convert it to an Integer before it gets set
        fieldValue = sanitizeRawValue(fieldValue, tField);
      }

      // Container types have to be added as repeated fields
      if (isContainer(tField)) {
        Iterable<?> container = (Iterable) fieldValue;
        for (Object obj : container) {
          builder.addRepeatedField(protoFieldDesc, obj);
        }
      } else {
        builder.setField(protoFieldDesc, fieldValue);
      }
    } catch (IllegalArgumentException e) {
      LOG.error(String.format("Could not set protoField(index=%d, name=%s, type=%s) with "
        + "thriftField(index=%d, name=%s, type=%d, value=%s)",
        protoFieldDesc.getIndex(), protoFieldDesc.getName(), protoFieldDesc.getType(),
          tmpFieldId - 1, tField.getName(), tField.getType(), fieldValue), e);
      throw e;
    }

    return tmpFieldId;
  }