protected Expression readCollectionCodegen()

in java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java [1556:1642]


  protected Expression readCollectionCodegen(
      Expression buffer, Expression collection, Expression size, TypeRef<?> elementType) {
    ListExpression builder = new ListExpression();
    Invoke flags = new Invoke(buffer, "readByte", "flags", PRIMITIVE_INT_TYPE, false);
    builder.add(flags);
    Class<?> elemClass = TypeUtils.getRawType(elementType);
    walkPath.add(elementType.toString());
    boolean finalType = isMonomorphic(elemClass);
    boolean trackingRef = visitFury(fury -> fury.getClassResolver().needToWriteRef(elementType));
    if (finalType) {
      if (trackingRef) {
        builder.add(readContainerElements(elementType, true, null, null, buffer, collection, size));
      } else {
        Literal hasNullFlag = ofInt(CollectionFlags.HAS_NULL);
        Expression hasNull = eq(new BitAnd(flags.inline(), hasNullFlag), hasNullFlag, "hasNull");
        builder.add(
            hasNull,
            readContainerElements(elementType, false, null, hasNull, buffer, collection, size));
      }
    } else {
      Literal notSameTypeFlag = ofInt(CollectionFlags.NOT_SAME_TYPE);
      Expression sameElementClass =
          neq(new BitAnd(flags, notSameTypeFlag), notSameTypeFlag, "sameElementClass");
      //  if ((flags & Flags.NOT_DECL_ELEMENT_TYPE) == Flags.NOT_DECL_ELEMENT_TYPE)
      Literal notDeclTypeFlag = ofInt(CollectionFlags.NOT_DECL_ELEMENT_TYPE);
      Expression isDeclType = neq(new BitAnd(flags, notDeclTypeFlag), notDeclTypeFlag);
      Invoke serializer =
          inlineInvoke(readClassInfo(elemClass, buffer), "getSerializer", SERIALIZER_TYPE);
      TypeRef<?> serializerType = getSerializerType(elementType);
      Expression elemSerializer; // make it in scope of `if(sameElementClass)`
      boolean maybeDecl = visitFury(f -> f.getClassResolver().isSerializable(elemClass));
      if (maybeDecl) {
        elemSerializer =
            new If(
                isDeclType,
                cast(getOrCreateSerializer(elemClass), serializerType),
                cast(serializer.inline(), serializerType),
                false,
                serializerType);
      } else {
        elemSerializer = cast(serializer.inline(), serializerType);
      }
      elemSerializer = uninline(elemSerializer);
      builder.add(sameElementClass);
      Expression action;
      if (trackingRef) {
        // Same element class read start
        ListExpression readBuilder = new ListExpression(elemSerializer);
        readBuilder.add(
            readContainerElements(
                elementType, true, elemSerializer, null, buffer, collection, size));
        // Same element class read end
        Set<Expression> cutPoint = ofHashSet(buffer, collection, size);
        Expression differentElemTypeRead =
            invokeGenerated(
                ctx,
                cutPoint,
                readContainerElements(elementType, true, null, null, buffer, collection, size),
                "differentTypeElemsRead",
                false);
        action = new If(sameElementClass, readBuilder, differentElemTypeRead);
      } else {
        Literal hasNullFlag = ofInt(CollectionFlags.HAS_NULL);
        Expression hasNull = eq(new BitAnd(flags, hasNullFlag), hasNullFlag, "hasNull");
        builder.add(hasNull);
        // Same element class read start
        ListExpression readBuilder = new ListExpression(elemSerializer);
        readBuilder.add(
            readContainerElements(
                elementType, false, elemSerializer, hasNull, buffer, collection, size));
        // Same element class read end
        Set<Expression> cutPoint = ofHashSet(buffer, collection, size, hasNull);
        Expression differentTypeElemsRead =
            invokeGenerated(
                ctx,
                cutPoint,
                readContainerElements(elementType, false, null, hasNull, buffer, collection, size),
                "differentTypeElemsRead",
                false);
        action = new If(sameElementClass, readBuilder, differentTypeElemsRead);
      }
      builder.add(action);
    }
    walkPath.removeLast();
    // place newCollection as last as expr value
    return new ListExpression(size, collection, new If(gt(size, ofInt(0)), builder), collection);
  }