private static void convertEntitiesIntoUdts()

in mapper-processor/src/main/java/com/datastax/oss/driver/internal/mapper/processor/util/generation/GeneratedCodePatterns.java [467:602]


  private static void convertEntitiesIntoUdts(
      String mappedObjectName,
      String rawObjectName,
      PropertyType type,
      CodeBlock currentCqlType,
      CodeBlock.Builder udtTypesBuilder,
      CodeBlock.Builder conversionBuilder,
      BindableHandlingSharedCode enclosingClass,
      boolean useLeniency) {

    if (type instanceof PropertyType.SingleEntity) {
      ClassName entityClass = ((PropertyType.SingleEntity) type).entityName;
      String udtTypeName =
          enclosingClass
              .getNameIndex()
              .uniqueField(Capitalizer.decapitalize(entityClass.simpleName()) + "UdtType");
      udtTypesBuilder.addStatement(
          "$1T $2L = ($1T) $3L", UserDefinedType.class, udtTypeName, currentCqlType);

      String entityHelperName = enclosingClass.addEntityHelperField(entityClass);
      conversionBuilder
          .addStatement("$T $L = $L.newValue()", UdtValue.class, rawObjectName, udtTypeName)
          // driver doesn't have the ability to send partial UDT, unset values values will be
          // serialized to null - set NullSavingStrategy.DO_NOT_SET explicitly
          .addStatement(
              "$L.set($L, $L, $T.$L, $L)",
              entityHelperName,
              mappedObjectName,
              rawObjectName,
              NullSavingStrategy.class,
              NullSavingStrategy.DO_NOT_SET,
              useLeniency ? "lenient" : false);
    } else if (type instanceof PropertyType.EntityList) {
      TypeName rawCollectionType = type.asRawTypeName();
      conversionBuilder.addStatement(
          "$T $L = $T.newArrayListWithExpectedSize($L.size())",
          rawCollectionType,
          rawObjectName,
          Lists.class,
          mappedObjectName);
      PropertyType mappedElementType = ((PropertyType.EntityList) type).elementType;
      String mappedElementName = enclosingClass.getNameIndex().uniqueField("mappedElement");
      conversionBuilder.beginControlFlow(
          "for ($T $L: $L)", mappedElementType.asTypeName(), mappedElementName, mappedObjectName);
      String rawElementName = enclosingClass.getNameIndex().uniqueField("rawElement");
      convertEntitiesIntoUdts(
          mappedElementName,
          rawElementName,
          mappedElementType,
          CodeBlock.of("(($T) $L).getElementType()", ListType.class, currentCqlType),
          udtTypesBuilder,
          conversionBuilder,
          enclosingClass,
          useLeniency);
      conversionBuilder.addStatement("$L.add($L)", rawObjectName, rawElementName).endControlFlow();
    } else if (type instanceof PropertyType.EntitySet) {
      TypeName rawCollectionType = type.asRawTypeName();
      conversionBuilder.addStatement(
          "$T $L = $T.newLinkedHashSetWithExpectedSize($L.size())",
          rawCollectionType,
          rawObjectName,
          Sets.class,
          mappedObjectName);
      PropertyType mappedElementType = ((PropertyType.EntitySet) type).elementType;
      String mappedElementName = enclosingClass.getNameIndex().uniqueField("mappedElement");
      conversionBuilder.beginControlFlow(
          "for ($T $L: $L)", mappedElementType.asTypeName(), mappedElementName, mappedObjectName);
      String rawElementName = enclosingClass.getNameIndex().uniqueField("rawElement");
      convertEntitiesIntoUdts(
          mappedElementName,
          rawElementName,
          mappedElementType,
          CodeBlock.of("(($T) $L).getElementType()", SetType.class, currentCqlType),
          udtTypesBuilder,
          conversionBuilder,
          enclosingClass,
          useLeniency);
      conversionBuilder.addStatement("$L.add($L)", rawObjectName, rawElementName).endControlFlow();
    } else if (type instanceof PropertyType.EntityMap) {
      TypeName rawCollectionType = type.asRawTypeName();
      conversionBuilder.addStatement(
          "$T $L = $T.newLinkedHashMapWithExpectedSize($L.size())",
          rawCollectionType,
          rawObjectName,
          Maps.class,
          mappedObjectName);
      PropertyType mappedKeyType = ((PropertyType.EntityMap) type).keyType;
      PropertyType mappedValueType = ((PropertyType.EntityMap) type).valueType;
      String mappedEntryName = enclosingClass.getNameIndex().uniqueField("mappedEntry");
      conversionBuilder.beginControlFlow(
          "for ($T $L: $L.entrySet())",
          ParameterizedTypeName.get(
              ClassName.get(Map.Entry.class),
              mappedKeyType.asTypeName(),
              mappedValueType.asTypeName()),
          mappedEntryName,
          mappedObjectName);
      String mappedKeyName = CodeBlock.of("$L.getKey()", mappedEntryName).toString();
      String rawKeyName;
      if (mappedKeyType instanceof PropertyType.Simple) {
        rawKeyName = mappedKeyName; // no conversion, use the instance as-is
      } else {
        rawKeyName = enclosingClass.getNameIndex().uniqueField("rawKey");
        convertEntitiesIntoUdts(
            mappedKeyName,
            rawKeyName,
            mappedKeyType,
            CodeBlock.of("(($T) $L).getKeyType()", MapType.class, currentCqlType),
            udtTypesBuilder,
            conversionBuilder,
            enclosingClass,
            useLeniency);
      }
      String mappedValueName = CodeBlock.of("$L.getValue()", mappedEntryName).toString();
      String rawValueName;
      if (mappedValueType instanceof PropertyType.Simple) {
        rawValueName = mappedValueName;
      } else {
        rawValueName = enclosingClass.getNameIndex().uniqueField("rawValue");
        convertEntitiesIntoUdts(
            mappedValueName,
            rawValueName,
            mappedValueType,
            CodeBlock.of("(($T) $L).getValueType()", MapType.class, currentCqlType),
            udtTypesBuilder,
            conversionBuilder,
            enclosingClass,
            useLeniency);
      }
      conversionBuilder
          .addStatement("$L.put($L, $L)", rawObjectName, rawKeyName, rawValueName)
          .endControlFlow();
    } else {
      throw new AssertionError("Unsupported type " + type.asTypeName());
    }
  }