public void deserializeAfterVersion()

in uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes6.java [1873:2128]


  public void deserializeAfterVersion(DataInputStream istream, boolean aIsDelta,
          AllowPreexistingFS aAllowPreexistingFS) throws IOException {

    allowPreexistingFS = aAllowPreexistingFS;
    if (aAllowPreexistingFS == AllowPreexistingFS.ignore) {
      throw new UnsupportedOperationException("AllowPreexistingFS.ignore not an allowed setting");
    }

    deserIn = istream;
    isDelta = isReadingDelta = aIsDelta;
    setupReadStreams();

    /************************************************
     * Read in the common string(s)
     ************************************************/
    int lenCmnStrs = readVnumber(strChars_dis);
    readCommonString = new String[lenCmnStrs];
    for (int i = 0; i < lenCmnStrs; i++) {
      readCommonString[i] = DataIO.readUTFv(strChars_dis);
    }
    only1CommonString = lenCmnStrs == 1;
    /***************************
     * Prepare to walk main heap
     ***************************/
    int nbrNewFSsInTarget = readVnumber(control_dis);
    // is nbr of FSs serialized (excluding mods) in v3
    // is totalMappedHeapSize in v2
    int totalMappedHeapSize = bcsd.isBeforeV3 ? nbrNewFSsInTarget : -1;
    if (bcsd.isBeforeV3) {
      nbrNewFSsInTarget = -1; // for safety
    }

    // stringTableOffset = isReadingDelta ? (stringHeapObj.getSize() - 1) : 0;
    nextFsId = isReadingDelta ? cas.peekNextFsId() : 0;

    // if (!isReadingDelta) {
    // heapObj.reinitSizeOnly(1);
    // heap = heapObj.heap;
    // }

    Arrays.fill(prevHeapInstanceWithIntValues, null);
    prevFsWithLongValues.clear();

    if (nextFsId == 0) {
      nextFsId = 1; // slot 0 not serialized, it's null / 0
    }

    // @formatter:off
    // For Delta CAS,
    //   Reuse previously computed map of addr <--> seq for existing FSs below mark line
    //                             map of seq(this CAS) <--> seq(incoming) 
    //                               that accounts for type code mismatch using typeMapper
    // note: rest of maps computed incrementally as we deserialize
    //   Two possibilities:  The CAS has a type, but the incoming is missing that type (services)
    //                       The incoming has a type, but the CAS is missing it - (deser from file)
    //     Below the merge line: only the 1st is possible
    //     Above the merge line: only the 2nd is possible
    // @formatter:on
    if (isReadingDelta) {
      if (!reuseInfoProvided) {
        throw new IllegalStateException("Reading Delta into CAS not serialized from");
      }
    }

    fixupsNeeded.clear();
    // preventFsGc.clear();
    // these two values are used when incrementing to the next before v3 heap addr
    TypeImpl tgtType;
    lastArrayLength = 0;
    /**********************************************************
     * Read in new FSs being deserialized and add them to heap
     **********************************************************/

    // @formatter:off
    // currentFsId is ID of next to be deserialized FS
    //   only incremented when something is "stored", not skipped
    // nextFsAddr only used for loop  termination , pre v3
    //   could be gt than fsId, because some FSs are "skipped" in deserialization
    // @formatter:n
    
    // currentFsId only used in error message
    for (int currentFsId = nextFsId, nbrFSs = 0, nextFsAddr = 1; bcsd.isBeforeV3
            ? nextFsAddr < totalMappedHeapSize
            : nbrFSs < nbrNewFSsInTarget; nbrFSs++, nextFsAddr += bcsd.isBeforeV3
                    ? tgtType.getFsSpaceReq(lastArrayLength)
                    : 0) {

      final int tgtTypeCode = readVnumber(typeCode_dis); // get type code
      // final int adjTgtTypeCode = tgtTypeCode + ((this.bcsd.isBeforeV3 && tgtTypeCode >
      // TypeSystemConstants.lastBuiltinV2TypeCode)
      // ? TypeSystemConstants.numberOfNewBuiltInsSinceV2
      // : 0);
      tgtType = (isTypeMapping ? tgtTs : srcTs).getTypeForCode(tgtTypeCode);
      if (tgtType == null) {
        /**
         * Deserializing Compressed Form 6, a type code: {0} has no corresponding type. currentFsId:
         * {1} nbrFSs: {2} nextFsAddr: {3}
         */
        throw new CASRuntimeException(CASRuntimeException.DESER_FORM_6_BAD_TYPE_CODE, tgtTypeCode,
                currentFsId, nbrFSs, nextFsAddr);
      }
      final TypeImpl srcType = isTypeMapping ? typeMapper.mapTypeCodeTgt2Src(tgtTypeCode) : tgtType;

      final boolean storeIt = srcType != null;
      // A receiving client from a service always
      // has a superset of the service's types due to type merging so this
      // won't happen for that use case. But
      // a deserialize-from-file could hit this if the receiving type system
      // deleted a type.

      // The strategy for deserializing heap refs depends on finding
      // the prev value for that type. This must be done in the context
      // of the sending CAS's type system

      // SlotKind slotKind = srcType.slotKind;

      if (storeIt) {
        // we can skip the cache for prev values if the value will not be stored.
        // typeImpl = tgtType;
        initPrevIntValue(tgtType);
      }

      // typeInfo = storeIt ? srcTypeInfo : tgtTypeInfo; // if !storeIt, then srcTypeInfo is null.

      // fsStartIndexes.addSrcAddrForTgt(currentFsId, storeIt);

      if (TRACE_DES) {
        System.out.format("Des: fsnbr %,4d fsid %,4d adjTgtTypeCode: %,3d %13s srcTypeCode: %s%n",
                nbrFSs, cas.getLastUsedFsId() + 1, tgtTypeCode, tgtType.getShortName(),
                null == srcType ? "<null>" : Integer.toString(srcType.getCode()));
      }

      if (tgtType.isArray()) {
        readArray(storeIt, srcType, tgtType);

      } else {
          // @formatter:off
        /**
         * is not array, handle features
         * If storing the value, create the FS unless it's a Sofa or a subtype of AnnotationBase
         *   Those are deferred until the slots are known, because they're needed
         *   as part of the creation of the FS due to final values. 
         */
          // @formatter:on
        if (storeIt) {
          if (!srcTs.annotBaseType.subsumes(srcType) && // defer subtypes of AnnotationBase
                  srcTs.sofaType != srcType) { // defer sofa types
            createCurrentFs(srcType, cas);
          } else {
            currentFs = null;
            singleFsDefer.clear();
            sofaRef = null;
            sofaNum = -1;
            sofaName = null;
            sofaMimeType = null;
          }
        }

        // is normal type with slots, not an array
        if (isTypeMapping && storeIt) {
          for (FeatureImpl tgtFeat : tgtType.getFeatureImpls()) {
            final FeatureImpl srcFeat = typeMapper.getSrcFeature(tgtType, tgtFeat);
            readByKind(currentFs, tgtFeat, srcFeat, storeIt, tgtType);
          }
        } else {
          for (FeatureImpl tgtFeat : tgtType.getFeatureImpls()) {
            readByKind(currentFs, tgtFeat, tgtFeat, storeIt, tgtType);
          }
        }

        if (currentFs == null) {

          // @formatter:off
          /**
           * Create single deferred FS
           *   Either: Sofa (has final fields) or
           *           Subtype of AnnotationBase - needs to be in the right view
           *   
           *   For the latter, handle document annotation specially
           */
            // @formatter:on

          if (srcTs.sofaType == srcType) {
            if (cas.hasView(sofaName)) {
              // sofa was already created, by an annotationBase subtype deserialized prior to this
              // one
              currentFs = (TOP) cas.getView(sofaName).getSofa();
            } else {
              currentFs = cas.createSofa(sofaNum, sofaName, sofaMimeType);
            }
          } else {

            CASImpl view = null == sofaRef ? cas.getInitialView() // https://issues.apache.org/jira/browse/UIMA-5588
                    : (CASImpl) cas.getView(sofaRef);

            // if (srcType.getCode() == TypeSystemConstants.docTypeCode) {
            // currentFs = view.getDocumentAnnotation(); // creates the document annotation if it
            // doesn't exist
            //
            // // we could remove this from the indexes until deserialization is over, but then,
            // other calls to getDocumentAnnotation
            // // would end up creating additional instances
            // } else {
            createCurrentFs(srcType, view);
            // }
          }
          if (srcType.getCode() == TypeSystemConstants.docTypeCode) {
            boolean wasRemoved = cas.removeFromCorruptableIndexAnyView(currentFs,
                    cas.getAddbackSingle());
            for (Runnable r : singleFsDefer) {
              r.run();
            }
            cas.addbackSingleIfWasRemoved(wasRemoved, currentFs);
          } else {
            for (Runnable r : singleFsDefer) {
              r.run();
            }
          }
        } // end of handling deferred current fs
      } // of not-an-array
      // if (storeIt) {
      // prevFsByType[srcType.getCode()] = currentFs; // make this one the "prev" one for subsequent
      // testing
      // //debug
      // assert(currentFs._id == currentFsId);
      // }
      // todo need to incr src heap by amt filtered (in case some slots missing,
      // need to incr tgt (for checking end) by unfiltered amount
      // need to fixup final heap to account for skipped slots
      // need to have read skip slots not present in src
      // targetHeapUsed += incrToNextFs(heap, currentFsId, tgtTypeInfo); // typeInfo is target type
      // info
      fsStartIndexes.addSrcFsForTgt(currentFs, storeIt);
      currentFsId += storeIt ? cas.lastV2IdIncr() : 0;
    } // end of for loop over items in main heap

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

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

    // process the index information
    readIndexedFeatureStructures();
    // for delta, process below-the-line updates
    if (isReadingDelta) {
      new ReadModifiedFSs().readModifiedFSs();
    }

    // preventFsGc.clear();

    closeDataInputs();
    // System.out.format("Deserialize took %,d ms%n", System.currentTimeMillis() - startTime1);
  }