下面列出了com.google.protobuf.Message#hasField ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Nonnull
@Override
public <M extends Message> List<Key.Evaluated> evaluateFunction(@Nullable FDBRecord<M> record,
@Nullable Message message,
@Nonnull Key.Evaluated arguments) {
if (message == null) {
return Collections.emptyList();
}
List<Key.Evaluated> keys = new ArrayList<>();
Descriptors.Descriptor descriptor = message.getDescriptorForType();
Descriptors.FieldDescriptor strField = descriptor.findFieldByNumber(TypesRecord.STR_VALUE_FIELD_NUMBER);
Descriptors.FieldDescriptor strListField = descriptor.findFieldByNumber(TypesRecord.STR_LIST_VALUE_FIELD_NUMBER);
if (message.hasField(strField)) {
keys.add(toKey((String) message.getField(strField)));
}
final int len = message.getRepeatedFieldCount(strListField);
for (int i = 0; i < len; i++) {
keys.add(toKey((String) message.getRepeatedField(strListField, i)));
}
return keys;
}
/**
* Retrieves and converts Protobuf fields from a Message.
* <p>
* If the field in the {@link com.google.protobuf.Descriptors.Descriptor} exists in the {@link Message}, the value is
* retrieved and converted using {@link #getFieldValue(Descriptors.FieldDescriptor, Object, DataType)}.
* Otherwise, the field value is {@code null}.
* The extraction honors the order of the {@code Descriptor}.
*
* @param dsc the Protobuf Descriptor with all fields
* @param msg the Message with the current field values
* @param schema the Dataset schema derived from the Descriptor
* @return a list of converted values
*/
public static List<Object> buildRowValues(Descriptors.Descriptor dsc, Message msg, StructType schema) {
List<Object> values = new ArrayList<>();
Object val;
for (Descriptors.FieldDescriptor fd : dsc.getFields()) {
if ( (!fd.isRepeated() && msg.hasField(fd)) || (fd.isRepeated() && msg.getRepeatedFieldCount(fd) > 0) ) {
val = getFieldValue(fd, msg.getField(fd), schema.apply(fd.getName()).dataType());
} else {
LOG.trace("FieldDescriptor[{}] => not found", fd.getFullName());
val = null;
}
values.add(val);
}
return values;
}
/** Encode the given message as a JSON array. */
public JsonArray encode(Message message) {
JsonArray array = new JsonArray();
for (FieldDescriptor field : message.getDescriptorForType().getFields()) {
if (field.isRepeated() || message.hasField(field)) {
JsonElement element = encodeField(field, message.getField(field));
if (!element.isJsonNull()) {
while (array.size() < field.getNumber()) {
array.add(JsonNull.INSTANCE);
}
array.set(field.getNumber() - 1, element);
}
}
}
return array;
}
@Override
Object getFromProtoMessage(Message message) {
if (message.hasField(getFieldDescriptor(message))) {
Message wrapper = (Message) message.getField(getFieldDescriptor(message));
return valueConvert.getFromProtoMessage(wrapper);
}
return null;
}
@Override
Object getFromProtoMessage(Message message) {
FieldDescriptor fieldDescriptor = getFieldDescriptor(message);
if (message.hasField(fieldDescriptor)) {
Message wrapper = (Message) message.getField(fieldDescriptor);
return convertFromProtoValue(wrapper);
}
return null;
}
@Override
Object getFromProtoMessage(Message message) {
FieldDescriptor fieldDescriptor = getFieldDescriptor(message);
if (message.hasField(fieldDescriptor)) {
Message wrapper = (Message) message.getField(fieldDescriptor);
return convertFromProtoValue(wrapper);
}
return null;
}
@Override
Object getFromProtoMessage(Message message) {
FieldDescriptor fieldDescriptor = getFieldDescriptor(message);
if (message.hasField(fieldDescriptor)) {
return convertFromProtoValue(message.getField(fieldDescriptor));
}
return null;
}
@Override
Object getFromProtoMessage(Message message) {
if (message.hasField(getFieldDescriptor(message))) {
return fieldOverlay.getFromProtoMessage(message);
}
return null;
}
private static void requiredFields(Message msg, int... fields) {
for(int fieldNumber : fields) {
FieldDescriptor field = msg.getDescriptorForType().findFieldByNumber(fieldNumber);
if(!msg.hasField(field)) {
throw new IllegalArgumentException("Missing field: " + field.getName());
}
}
}
/**
* Find out which field in the incoming message contains the payload that is.
* delivered to the service method.
*/
protected FieldDescriptor resolvePayloadField(Message message) {
for (FieldDescriptor field : message.getDescriptorForType().getFields()) {
if (message.hasField(field)) {
return field;
}
}
throw new RuntimeException("No payload found in message " + message);
}
@Nonnull
@Override
@SuppressWarnings("unchecked")
public <M extends Message> List<Key.Evaluated> evaluateMessage(@Nullable FDBRecord<M> record, @Nullable Message message) {
if (message == null) {
return getNullResult();
}
Descriptors.Descriptor recordDescriptor = message.getDescriptorForType();
Descriptors.FieldDescriptor fieldDescriptor = recordDescriptor.findFieldByName(fieldName);
// TODO: Part of this is working around a deficiency in DynamicMessage.getField() prior
// to 2.5, where a repeated message field returns an empty message instead of an
// empty collection.
if (fieldDescriptor != null && fieldDescriptor.isRepeated()) {
List<Object> values;
if (message.getRepeatedFieldCount(fieldDescriptor) > 0) {
values = (List<Object>)message.getField(fieldDescriptor);
} else {
values = Collections.emptyList();
}
switch (fanType) {
case FanOut:
return Key.Evaluated.fan(values);
case Concatenate:
return Collections.singletonList(Key.Evaluated.scalar(values));
case None:
throw new RecordCoreException("FanType.None with repeated field");
default:
throw new RecordCoreException(String.format("unknown fan type: %s", fanType));
}
} else if (fieldDescriptor != null && (nullStandin == Key.Evaluated.NullStandin.NOT_NULL || message.hasField(fieldDescriptor))) {
Object value = message.getField(fieldDescriptor);
if (fieldDescriptor.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE &&
TupleFieldsHelper.isTupleField(fieldDescriptor.getMessageType())) {
value = TupleFieldsHelper.fromProto((Message)value, fieldDescriptor.getMessageType());
}
// ignore FanType
return Collections.singletonList(Key.Evaluated.scalar(value));
} else {
return getNullResult();
}
}
private static void compare(
FieldMask.Builder mask, String currentField, Message original, Message modified) {
Descriptor descriptor = original.getDescriptorForType();
for (FieldDescriptor field : descriptor.getFields()) {
String fieldName = getFieldName(currentField, field);
Object originalValue = original.getField(field);
Object modifiedValue = modified.getField(field);
if (field.isRepeated()) {
if (!Objects.equals(originalValue, modifiedValue)) {
mask.addPaths(fieldName);
}
} else {
switch (field.getJavaType()) {
case MESSAGE:
// Because getField never returns null, we use hasField to distinguish null
// from empty message when getType() == MESSAGE
if (original.hasField(field) != modified.hasField(field)
|| !Objects.equals(originalValue, modifiedValue)) {
if (isWrapperType(field.getMessageType())) {
// For wrapper types, just emit the field name.
mask.addPaths(fieldName);
} else if (!modified.hasField(field)) {
// Just emit the deleted field name
mask.addPaths(fieldName);
} else {
// Recursively compare to find different values
compare(mask, fieldName, (Message) originalValue, (Message) modifiedValue);
}
}
break;
case INT:
case LONG:
case FLOAT:
case DOUBLE:
case BOOLEAN:
case STRING:
case BYTE_STRING:
case ENUM:
// Handle all java types except MESSAGE
if (!Objects.equals(originalValue, modifiedValue)) {
mask.addPaths(fieldName);
}
break;
default:
throw new IllegalArgumentException(
"Unexpected java type "
+ field.getJavaType()
+ " encountered for field "
+ fieldName);
}
}
}
}