private static Object getValue( Descriptors.FieldDescriptor f, Field field, Record record, String protoFieldPath, Map<String, Set<Descriptors.FieldDescriptor>> messageTypeToExtensionMap, Map<String, Object> defaultValueMap) throws DataGeneratorException { Object value = null; try { if (field.getValue() != null) { switch (f.getJavaType()) { case BOOLEAN: value = field.getValueAsBoolean(); break; case BYTE_STRING: value = ByteString.copyFrom(field.getValueAsByteArray()); break; case DOUBLE: value = field.getValueAsDouble(); break; case ENUM: value = f.getEnumType().findValueByName(field.getValueAsString()); break; case FLOAT: value = field.getValueAsFloat(); break; case INT: value = field.getValueAsInteger(); break; case LONG: value = field.getValueAsLong(); break; case STRING: value = field.getValueAsString(); break; case MESSAGE: Descriptors.Descriptor messageType = f.getMessageType(); value = sdcFieldToProtobufMsg( record, field, protoFieldPath, messageType, messageTypeToExtensionMap, defaultValueMap); break; default: throw new DataGeneratorException(Errors.PROTOBUF_03, f.getJavaType().name()); } } } catch (IllegalArgumentException e) { throw new DataGeneratorException( Errors.PROTOBUF_11, field.getValue(), f.getJavaType().name(), e); } return value; }
private static Field createSdcField( Record record, String fieldPath, Descriptors.FieldDescriptor fieldDescriptor, Map<String, Set<Descriptors.FieldDescriptor>> messageTypeToExtensionMap, Object value) throws DataParserException { Field f; switch (fieldDescriptor.getJavaType()) { case BOOLEAN: f = Field.create(Field.Type.BOOLEAN, value); break; case BYTE_STRING: f = Field.create(Field.Type.BYTE_ARRAY, ((ByteString) value).toByteArray()); break; case DOUBLE: f = Field.create(Field.Type.DOUBLE, value); break; case ENUM: f = Field.create(Field.Type.STRING, ((Descriptors.EnumValueDescriptor) value).getName()); break; case FLOAT: f = Field.create(Field.Type.FLOAT, value); break; case INT: f = Field.create(Field.Type.INTEGER, value); break; case LONG: f = Field.create(Field.Type.LONG, value); break; case STRING: f = Field.create(Field.Type.STRING, value); break; case MESSAGE: f = protobufToSdcField( record, fieldPath + FORWARD_SLASH + fieldDescriptor.getName(), fieldDescriptor.getMessageType(), messageTypeToExtensionMap, value); break; default: throw new DataParserException(Errors.PROTOBUF_03, fieldDescriptor.getJavaType().name()); } return f; }
private static void handleRepeatedField( Record record, Field field, String fieldPath, Map<String, Set<Descriptors.FieldDescriptor>> messageTypeToExtensionMap, Map<String, Object> defaultValueMap, Descriptors.FieldDescriptor f, DynamicMessage.Builder builder) throws DataGeneratorException { List<Object> toReturn = new ArrayList<>(); List<Field> valueAsList = field.getValueAsList(); if (valueAsList != null) { // According to proto 2 and 3 language guide repeated fields can have 0 elements. // Also null is treated as empty in case of json mappings so I guess we can ignore if it is // null. for (int i = 0; i < valueAsList.size(); i++) { if (f.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) { // repeated field of type message toReturn.add( sdcFieldToProtobufMsg( record, valueAsList.get(i), fieldPath + FORWARD_SLASH + f.getName() + "[" + i + "]", f.getMessageType(), messageTypeToExtensionMap, defaultValueMap)); } else { // repeated field of primitive types toReturn.add( getValue( f, valueAsList.get(i), record, fieldPath + FORWARD_SLASH + f.getName(), messageTypeToExtensionMap, defaultValueMap)); } } } builder.setField(f, toReturn); }
private static void handleRepeatedField( Record record, Field field, String fieldPath, Map<String, Set<Descriptors.FieldDescriptor>> messageTypeToExtensionMap, Map<String, Object> defaultValueMap, Descriptors.FieldDescriptor f, DynamicMessage.Builder builder) throws DataGeneratorException { List<Object> toReturn = new ArrayList<>(); List<Field> valueAsList = field.getValueAsList(); for (int i = 0; i < valueAsList.size(); i++) { if (f.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) { // repeated field of type message toReturn.add( sdcFieldToProtobufMsg( record, valueAsList.get(i), fieldPath + FORWARD_SLASH + f.getName() + "[" + i + "]", f.getMessageType(), messageTypeToExtensionMap, defaultValueMap)); } else { // repeated field of primitive types toReturn.add( getValue( f, valueAsList.get(i), record, fieldPath + FORWARD_SLASH + f.getName(), messageTypeToExtensionMap, defaultValueMap)); } } builder.setField(f, toReturn); }
/** * Creates an SDC Record Field from the provided protobuf message and descriptor. * * @param record record to be augmented * @param fieldPath field path in the record to insert new Field * @param fieldDescriptor descriptor for this message * @param messageTypeToExtensionMap protobuf type extensions * @param message protobuf message to decode * @return reference to the Field added to the record. * @throws DataParserException */ @SuppressWarnings("unchecked") private static Field createField( Record record, String fieldPath, Descriptors.FieldDescriptor fieldDescriptor, Map<String, Set<Descriptors.FieldDescriptor>> messageTypeToExtensionMap, Object message) throws DataParserException { Field newField; if (message == null) { // If the message does not contain required fields then builder.build() throws // UninitializedMessageException Object defaultValue = null; // get default values only for optional fields and non-message types if (fieldDescriptor.isOptional() && fieldDescriptor.getJavaType() != Descriptors.FieldDescriptor.JavaType.MESSAGE) { defaultValue = fieldDescriptor.getDefaultValue(); } newField = Field.create(getFieldType(fieldDescriptor.getJavaType()), defaultValue); } else if (fieldDescriptor.isMapField()) { // Map entry (protobuf 3 map) Map<String, Field> sdcMapFieldValues = new HashMap<>(); Collection<DynamicMessage> mapEntries = (Collection<DynamicMessage>) message; // MapEntry for (DynamicMessage dynamicMessage : mapEntries) { // MapEntry has 2 fields, key and value Map<Descriptors.FieldDescriptor, Object> kv = dynamicMessage.getAllFields(); String key = null; Object value = null; Descriptors.FieldDescriptor valueDescriptor = null; for (Map.Entry<Descriptors.FieldDescriptor, Object> entry : kv.entrySet()) { switch (entry.getKey().getName()) { case KEY: key = entry.getValue().toString(); break; case VALUE: value = entry.getValue(); valueDescriptor = entry.getKey(); break; default: throw new DataParserException(Errors.PROTOBUF_09, entry.getKey().getName()); } } if (key != null && valueDescriptor != null) { sdcMapFieldValues.put( key, createSdcField(record, fieldPath, valueDescriptor, messageTypeToExtensionMap, value)); } } newField = Field.create(sdcMapFieldValues); } else if (fieldDescriptor.isRepeated()) { // List entry (repeated) List<?> list = (List<?>) message; List<Field> listField = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { if (fieldDescriptor.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) { listField.add( protobufToSdcField( record, fieldPath + "[" + i + "]", fieldDescriptor.getMessageType(), messageTypeToExtensionMap, list.get(i))); } else { listField.add( createSdcField( record, fieldPath + "[" + i + "]", fieldDescriptor, messageTypeToExtensionMap, list.get(i))); } } newField = Field.create(listField); } else { // normal entry newField = createSdcField(record, fieldPath, fieldDescriptor, messageTypeToExtensionMap, message); } return newField; }