public Optional generate()

in mapper-processor/src/main/java/com/datastax/oss/driver/internal/mapper/processor/dao/DaoSetEntityMethodGenerator.java [54:146]


  public Optional<MethodSpec> generate() {

    String entityParameterName = null;
    TypeElement entityElement = null;
    String targetParameterName = null;

    // Validate the parameters: one is an annotated entity, and the other a subtype of
    // SettableByName.
    if (methodElement.getParameters().size() != 2) {
      context
          .getMessager()
          .error(
              methodElement,
              "Wrong number of parameters: %s methods must have two",
              SetEntity.class.getSimpleName());
      return Optional.empty();
    }
    TypeMirror targetParameterType = null;
    for (VariableElement parameterElement : methodElement.getParameters()) {
      TypeMirror parameterType = parameterElement.asType();
      if (context.getClassUtils().implementsSettableByName(parameterType)) {
        targetParameterName = parameterElement.getSimpleName().toString();
        targetParameterType = parameterElement.asType();
      } else if (parameterType.getKind() == TypeKind.DECLARED
          || parameterType.getKind() == TypeKind.TYPEVAR) {
        TypeElement parameterTypeElement =
            EntityUtils.asEntityElement(parameterType, typeParameters);
        if (parameterTypeElement != null) {
          entityParameterName = parameterElement.getSimpleName().toString();
          entityElement = parameterTypeElement;
        }
      }
    }
    if (entityParameterName == null || targetParameterName == null) {
      context
          .getMessager()
          .error(
              methodElement,
              "Wrong parameter types: %s methods must take a %s "
                  + "and an annotated entity (in any order)",
              SetEntity.class.getSimpleName(),
              SettableByName.class.getSimpleName());
      return Optional.empty();
    }

    // Validate the return type: either void or the same SettableByName as the parameter
    TypeMirror returnType = methodElement.getReturnType();
    boolean isVoid = returnType.getKind() == TypeKind.VOID;
    if (isVoid) {
      if (context.getClassUtils().isSame(targetParameterType, BoundStatement.class)) {
        context
            .getMessager()
            .warn(
                methodElement,
                "BoundStatement is immutable, "
                    + "this method will not modify '%s' in place. "
                    + "It should probably return BoundStatement rather than void",
                targetParameterName);
      }
    } else if (!context.getTypeUtils().isSameType(returnType, targetParameterType)) {
      context
          .getMessager()
          .error(
              methodElement,
              "Invalid return type: %s methods must either be void, or return the same "
                  + "type as their settable parameter (in this case, %s to match '%s')",
              SetEntity.class.getSimpleName(),
              targetParameterType,
              targetParameterName);
      return Optional.empty();
    }

    // Generate the method:
    String helperFieldName = enclosingClass.addEntityHelperField(ClassName.get(entityElement));

    NullSavingStrategy nullSavingStrategy =
        nullSavingStrategyValidation.getNullSavingStrategy(
            SetEntity.class, SetEntity::nullSavingStrategy, methodElement, enclosingClass);

    // Forward to the base injector in the helper:
    return Optional.of(
        GeneratedCodePatterns.override(methodElement, typeParameters)
            .addStatement(
                "$1L$2L.set($3L, $4L, $5T.$6L, $7L)",
                isVoid ? "" : "return ",
                helperFieldName,
                entityParameterName,
                targetParameterName,
                NullSavingStrategy.class,
                nullSavingStrategy,
                lenient)
            .build());
  }