Field[] reordered = new Field[rfields.size()];
int ridx = 0;
int count = 1 + wfields.size();
for (Field f : wfields) {
Field rdrField = reader.getField(f.name());
if (rdrField != null) {
reordered[ridx++] = rdrField;
}
}
for (Field rf : rfields) {
String fname = rf.name();
if (writer.getField(fname) == null) {
if (rf.defaultValue() == null) {
result = Symbol.error("Found " + writer.toString(true)
+ ", expecting " + reader.toString(true));
seen.put(wsc, result);
return result;
} else {
reordered[ridx++] = rf;
count += 3;
}
}
}
Symbol[] production = new Symbol[count];
production[--count] = new Symbol.FieldOrderAction(reordered);
/**
* We construct a symbol without filling the array. Please see
* {@link Symbol#production} for the reason.
*/
result = Symbol.seq(production);
seen.put(wsc, result);
/*
* For now every field in read-record with no default value
* must be in write-record.
* Write record may have additional fields, which will be
* skipped during read.
*/
// Handle all the writer's fields
for (Field wf : wfields) {
String fname = wf.name();
Field rf = reader.getField(fname);
if (rf == null) {
production[--count] =
new Symbol.SkipAction(generate(wf.schema(), wf.schema(), seen));
} else {
production[--count] =
generate(wf.schema(), rf.schema(), seen);
}
}
// Add default values for fields missing from Writer
for (Field rf : rfields) {
String fname = rf.name();
Field wf = writer.getField(fname);
if (wf == null) {
byte[] bb = getBinary(rf.schema(), rf.defaultValue());
production[--count] = new Symbol.DefaultStartAction(bb);
production[--count] = generate(rf.schema(), rf.schema(), seen);
production[--count] = Symbol.DEFAULT_END_ACTION;