private void createFSsFromHeaps()

in uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes.java [1657:1876]


  private void createFSsFromHeaps(boolean isDelta, int startPos, CommonSerDesSequential csds) {
    final int heapsz = heap.getCellsUsed();
    final Int2ObjHashMap<TOP, TOP> addr2fs = csds.addr2fs;
    tsi = baseCas.getTypeSystemImpl();
    TOP fs;
    TypeImpl type;
    CASImpl initialView = baseCas.getInitialView(); // creates if needed

    List<Runnable> fixups4forwardFsRefs = new ArrayList<>();
    List<Runnable> fixups4UimaSerialization = new ArrayList<>();

    for (int heapIndex = startPos; heapIndex < heapsz; heapIndex += getFsSpaceReq(fs, type)) {
      // int typecode = heap.heap[heapIndex];
      // if (isBeforeV3 && typecode > TypeSystemConstants.lastBuiltinV2TypeCode) {
      // typecode = typecode + TypeSystemConstants.numberOfNewBuiltInsSinceV2;
      // }
      type = tsi.getTypeForCode(heap.heap[heapIndex]);
      if (type == null) {
        throw new CASRuntimeException(CASRuntimeException.deserialized_type_not_found,
                heap.heap[heapIndex]);
      }
      if (type.isArray()) {
        final int len = heap.heap[heapIndex + arrayLengthFeatOffset];

        fs = baseCas.createArray(type, len);
        csds.addFS(fs, heapIndex);

        if (len > 0) {
          final int bhi = heap.heap[heapIndex + arrayContentOffset];
          final int hhi = heapIndex + arrayContentOffset;

          switch (type.getComponentSlotKind()) {

            case Slot_BooleanRef: {
              boolean[] ba = ((BooleanArray) fs)._getTheArray();
              for (int ai = 0; ai < len; ai++) {
                ba[ai] = byteHeap.heap[bhi + ai] == (byte) 1;
              }
              break;
            }

            case Slot_ByteRef:
              System.arraycopy(byteHeap.heap, bhi, ((ByteArray) fs)._getTheArray(), 0, len);
              break;

            case Slot_ShortRef:
              System.arraycopy(shortHeap.heap, bhi, ((ShortArray) fs)._getTheArray(), 0, len);
              break;

            case Slot_LongRef:
              System.arraycopy(longHeap.heap, bhi, ((LongArray) fs)._getTheArray(), 0, len);
              break;

            case Slot_DoubleRef: {
              double[] da = ((DoubleArray) fs)._getTheArray();
              for (int ai = 0; ai < len; ai++) {
                da[ai] = CASImpl.long2double(longHeap.heap[bhi + ai]);
              }
              break;
            }

            case Slot_Int:
              System.arraycopy(heap.heap, hhi, ((IntegerArray) fs)._getTheArray(), 0, len);
              break;

            case Slot_Float: {
              float[] fa = ((FloatArray) fs)._getTheArray();
              for (int ai = 0; ai < len; ai++) {
                fa[ai] = CASImpl.int2float(heap.heap[hhi + ai]);
              }
              break;
            }

            case Slot_StrRef: {
              String[] sa = ((StringArray) fs)._getTheArray();
              for (int ai = 0; ai < len; ai++) {
                sa[ai] = stringHeap.getStringForCode(heap.heap[hhi + ai]);
              }
              break;
            }

            case Slot_HeapRef: {
              TOP[] fsa = ((FSArray<?>) fs)._getTheArray();
              for (int ai = 0; ai < len; ai++) {
                int a = heap.heap[hhi + ai];
                if (a == 0) {
                  continue;
                }
                TOP item = addr2fs.get(a);
                if (item != null) {
                  fsa[ai] = item;
                } else {
                  final int aiSaved = ai;
                  final int addrSaved = a;
                  fixups4forwardFsRefs.add(() -> {
                    fsa[aiSaved] = addr2fs.get(addrSaved);
                  });
                }
              }
              break;
            }

            default:
              Misc.internalError();

          } // end of switch
        }
      } else { // end of arrays
               // start of normal non-array
        CASImpl view = null;
        boolean isSofa = false;
        boolean documentAnnotationPreviouslyIndexed = false;
        if (type.isAnnotationBaseType()) {
          Sofa sofa = getSofaFromAnnotBase(heapIndex, stringHeap, addr2fs, csds); // creates sofa if
                                                                                  // needed and
                                                                                  // exists (forward
                                                                                  // ref case)
          view = (sofa == null) ? baseCas.getInitialView() : baseCas.getView(sofa);
          if (type == tsi.docType) {
            Annotation documentAnnotationPrevious = view.getDocumentAnnotationNoCreate();
            if (documentAnnotationPrevious == null) {
              // document annotation not present
              fs = view.createDocumentAnnotationNoRemoveNoIndex(0); // create but don't index
              view.set_deserialized_doc_annot_not_indexed((Annotation) fs); // for use by other code
                                                                            // that sets length, if
                                                                            // this is not indexed
              // documentAnnotationPreviouslyIndex == false, preset above
            } else {
              fs = documentAnnotationPrevious;
              // remove from Corruptable indexes, because we'll be updating it.
              view.removeFromCorruptableIndexAnyView(fs, view.getAddbackSingle());
              documentAnnotationPreviouslyIndexed = true;
            }
          } else {
            fs = view.createFS(type);
            if (fs instanceof UimaSerializable ufs) {
              fixups4UimaSerialization.add(ufs::_init_from_cas_data);
            }
          }
        } else if (type == tsi.sofaType) {
          fs = makeSofaFromHeap(heapIndex, stringHeap, csds, SOFA_IN_NORMAL_ORDER); // creates Sofa
                                                                                    // if not
                                                                                    // already
                                                                                    // created due
                                                                                    // to
                                                                                    // annotationbase
                                                                                    // code above
          isSofa = true;
        } else {
          fs = initialView.createFS(type);
          if (fs instanceof UimaSerializable ufs) {
            fixups4UimaSerialization.add(ufs::_init_from_cas_data);
          }
        }
        if (!isSofa) { // if it was a sofa, other code added or pended it
          csds.addFS(fs, heapIndex);
        }

        for (final FeatureImpl feat : type.getFeatureImpls()) {
          SlotKind slotKind = feat.getSlotKind();
          switch (slotKind) {
            case Slot_Boolean:
            case Slot_Byte:
            case Slot_Short:
            case Slot_Int:
            case Slot_Float:
              if (!isSofa || feat != tsi.sofaNum) {
                fs._setIntLikeValueNcNj(slotKind, feat, heapFeat(heapIndex, feat));
              }
              break;

            case Slot_LongRef:
              fs._setLongValueNcNj(feat, longHeap.heap[heapFeat(heapIndex, feat)]);
              break;
            case Slot_DoubleRef:
              fs._setDoubleValueNcNj(feat,
                      CASImpl.long2double(longHeap.heap[heapFeat(heapIndex, feat)]));
              break;
            case Slot_StrRef: {
              String s = stringHeap.getStringForCode(heapFeat(heapIndex, feat));
              if (updateStringFeature(fs, feat, s, fixups4forwardFsRefs)) {
                fs._setStringValueNcNj(feat, s);
              }
              break;
            }

            case Slot_HeapRef: {
              final TOP finalFs = fs;
              if (feat == tsi.annotBaseSofaFeat) {
                break; // already set
              }
              setFeatOrDefer(heapIndex, feat, fixups4forwardFsRefs, item -> {
                if (feat == tsi.sofaArray) {
                  ((Sofa) finalFs).setLocalSofaData(item);
                } else {
                  finalFs._setFeatureValueNcNj(feat, item);
                }
              }, addr2fs);
              break;
            }

            default:
              Misc.internalError();
          } // end of switch
        } // end of for-loop-over-all-features

        if (type == tsi.docType && documentAnnotationPreviouslyIndexed) {
          view.addbackSingle(fs);
        }
      } // end of non-array, normal fs
    } // end of loop over all fs in main array

    for (Runnable r : fixups4forwardFsRefs) {
      r.run();
    }

    for (Runnable r : fixups4UimaSerialization) {
      r.run();
    }
  }