@Override
    public S read(Decoder decoder, Object reuse) throws IOException {
      S struct = reuseOrCreate(reuse);

      if (decoder instanceof ResolvingDecoder) {
        // this may not set all of the fields. nulls are set by default.
        for (Schema.Field field : ((ResolvingDecoder) decoder).readFieldOrder()) {
          Object reusedValue = get(struct, field.pos());
          set(struct, field.pos(), readers[field.pos()].read(decoder, reusedValue));
        }

      } else {
        for (int i = 0; i < readers.length; i += 1) {
          Object reusedValue = get(struct, i);
          set(struct, i, readers[i].read(decoder, reusedValue));
        }
      }

      for (int i = 0; i < positions.length; i += 1) {
        set(struct, positions[i], constants[i]);
      }

      return struct;
    }
Builds a read plan for record classes that use planned reads instead of a ResolvingDecoder.

@param expected expected StructType
@param record Avro record schema
@param fieldReaders list of readers for each field in the Avro record schema
@param idToConstant a map of field ID to constants values
@param convert function to convert from internal classes to the target object model
@return a read plan that is a list of (position, reader) pairs
iceberg/patched-iceberg-core/src/main/java/org/apache/iceberg/avro/ValueReaders.java