*/
@Override
protected void encodeFieldType(RecordDataSchema.Field field) throws IOException
{
boolean optional = field.getOptional();
DataSchema fieldSchema = field.getType();
UnionDataSchema unionDataSchema =
(fieldSchema.getDereferencedType() == DataSchema.Type.UNION ?
(UnionDataSchema) fieldSchema.getDereferencedDataSchema() :
null);
_builder.writeFieldName(TYPE_KEY);
if (optional == false && unionDataSchema == null)
{
encode(fieldSchema);
}
else
{
// special handling for unions
// output will be an union if the field is optional or its type is a union
// whether to add null to translated union,
// set to true for optional non-union type or optional union without null member
boolean addNullMemberType;
// DataSchema of default value, null if there is no default value.
DataSchema defaultValueSchema;
// members of the union (excluding null introduced by optional)
List<DataSchema> resultMemberTypes;
Object defaultValue = field.getDefault();
if (optional)
{
if (unionDataSchema == null)
{
addNullMemberType = true;
resultMemberTypes = new ArrayList<DataSchema>(1);
resultMemberTypes.add(fieldSchema);
defaultValueSchema = (
defaultValue != null && _options.getOptionalDefaultMode() == OptionalDefaultMode.TRANSLATE_DEFAULT ?
fieldSchema :
DataSchemaConstants.NULL_DATA_SCHEMA);
}
else
{
addNullMemberType = unionDataSchema.getType(DataSchemaConstants.NULL_TYPE) == null;
resultMemberTypes = unionDataSchema.getTypes();
defaultValueSchema = (
defaultValue != null && _options.getOptionalDefaultMode() == OptionalDefaultMode.TRANSLATE_DEFAULT ?
unionValueDataSchema(unionDataSchema, defaultValue) :
DataSchemaConstants.NULL_DATA_SCHEMA);
}
assert(_options.getOptionalDefaultMode() != OptionalDefaultMode.TRANSLATE_TO_NULL ||
defaultValueSchema == DataSchemaConstants.NULL_DATA_SCHEMA);
}
else
{
// must be union
addNullMemberType = false;
resultMemberTypes = unionDataSchema.getTypes();
defaultValueSchema = unionValueDataSchema(unionDataSchema, defaultValue);
}
// encode the member types
// add null member type if addNullMemberType is present
_builder.writeStartArray();
// this variable keeps track of whether null member type has been emitted
boolean emittedNull = false;
// if field has a default, defaultValueSchema != null, always encode it 1st
if (defaultValueSchema != null)
{
emittedNull |= (defaultValueSchema.getDereferencedType() == DataSchema.Type.NULL);
encode(defaultValueSchema);
}
for (DataSchema type : resultMemberTypes)
{
if (defaultValueSchema == type)