protected PrimitiveType build()

in parquet-column/src/main/java/org/apache/parquet/schema/Types.java [437:588]


    protected PrimitiveType build(String name) {
      if (PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY == primitiveType) {
        Preconditions.checkArgument(length > 0,
            "Invalid FIXED_LEN_BYTE_ARRAY length: %s", length);
      }

      DecimalMetadata meta = decimalMetadata();

      // validate type annotations and required metadata
      if (logicalTypeAnnotation != null) {
        logicalTypeAnnotation.accept(new LogicalTypeAnnotation.LogicalTypeAnnotationVisitor<Boolean>() {
          @Override
          public Optional<Boolean> visit(LogicalTypeAnnotation.StringLogicalTypeAnnotation stringLogicalType) {
            return checkBinaryPrimitiveType(stringLogicalType);
          }

          @Override
          public Optional<Boolean> visit(LogicalTypeAnnotation.JsonLogicalTypeAnnotation jsonLogicalType) {
            return checkBinaryPrimitiveType(jsonLogicalType);
          }

          @Override
          public Optional<Boolean> visit(LogicalTypeAnnotation.BsonLogicalTypeAnnotation bsonLogicalType) {
            return checkBinaryPrimitiveType(bsonLogicalType);
          }

          @Override
          public Optional<Boolean> visit(LogicalTypeAnnotation.UUIDLogicalTypeAnnotation uuidLogicalType) {
            return checkFixedPrimitiveType(LogicalTypeAnnotation.UUIDLogicalTypeAnnotation.BYTES, uuidLogicalType);
          }

          @Override
          public Optional<Boolean> visit(LogicalTypeAnnotation.DecimalLogicalTypeAnnotation decimalLogicalType) {
            Preconditions.checkState(
                (primitiveType == PrimitiveTypeName.INT32) ||
                (primitiveType == PrimitiveTypeName.INT64) ||
                (primitiveType == PrimitiveTypeName.BINARY) ||
                (primitiveType == PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY),
                "DECIMAL can only annotate INT32, INT64, BINARY, and FIXED"
            );
            if (primitiveType == PrimitiveTypeName.INT32) {
              Preconditions.checkState(
                  meta.getPrecision() <= MAX_PRECISION_INT32,
                  "INT32 cannot store %s digits (max %s)", 
                  meta.getPrecision(), MAX_PRECISION_INT32);
            } else if (primitiveType == PrimitiveTypeName.INT64) {
              Preconditions.checkState(
                  meta.getPrecision() <= MAX_PRECISION_INT64,
                  "INT64 cannot store %s digits (max %s)", 
                  meta.getPrecision(), MAX_PRECISION_INT64);
              if (meta.getPrecision() <= MAX_PRECISION_INT32) {
                LOGGER.warn("Decimal with {} digits is stored in an INT64, but fits in an INT32. See {}.",
                            precision, LOGICAL_TYPES_DOC_URL);
              }
            } else if (primitiveType == PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY) {
              Preconditions.checkState(
                  meta.getPrecision() <= maxPrecision(length),
                  "FIXED(%s) cannot store %s digits (max %s)", 
                  length, meta.getPrecision(), maxPrecision(length));
            }
            return Optional.of(true);
          }

          @Override
          public Optional<Boolean> visit(LogicalTypeAnnotation.DateLogicalTypeAnnotation dateLogicalType) {
            return checkInt32PrimitiveType(dateLogicalType);
          }

          @Override
          public Optional<Boolean> visit(LogicalTypeAnnotation.TimeLogicalTypeAnnotation timeLogicalType) {
            LogicalTypeAnnotation.TimeUnit unit = timeLogicalType.getUnit();
            switch (unit) {
              case MILLIS:
                checkInt32PrimitiveType(timeLogicalType);
                break;
              case MICROS:
              case NANOS:
                checkInt64PrimitiveType(timeLogicalType);
                break;
              default:
                throw new RuntimeException("Invalid time unit: " + unit);
            }
            return Optional.of(true);
          }

          @Override
          public Optional<Boolean> visit(LogicalTypeAnnotation.IntLogicalTypeAnnotation intLogicalType) {
            int bitWidth = intLogicalType.getBitWidth();
            switch (bitWidth) {
              case 8:
              case 16:
              case 32:
                checkInt32PrimitiveType(intLogicalType);
                break;
              case 64:
                checkInt64PrimitiveType(intLogicalType);
                break;
              default:
                throw new RuntimeException("Invalid bit width: " + bitWidth);
            }
            return Optional.of(true);
          }

          @Override
          public Optional<Boolean> visit(LogicalTypeAnnotation.TimestampLogicalTypeAnnotation timestampLogicalType) {
            return checkInt64PrimitiveType(timestampLogicalType);
          }

          @Override
          public Optional<Boolean> visit(LogicalTypeAnnotation.IntervalLogicalTypeAnnotation intervalLogicalType) {
            return checkFixedPrimitiveType(12, intervalLogicalType);
          }

          @Override
          public Optional<Boolean> visit(LogicalTypeAnnotation.EnumLogicalTypeAnnotation enumLogicalType) {
            return checkBinaryPrimitiveType(enumLogicalType);
          }

          private Optional<Boolean> checkFixedPrimitiveType(int l, LogicalTypeAnnotation logicalTypeAnnotation) {
            Preconditions.checkState(
                primitiveType == PrimitiveTypeName.FIXED_LEN_BYTE_ARRAY && length == l,
              "%s can only annotate FIXED_LEN_BYTE_ARRAY(%s)", logicalTypeAnnotation, l);
            return Optional.of(true);
          }

          private Optional<Boolean> checkBinaryPrimitiveType(LogicalTypeAnnotation logicalTypeAnnotation) {
            Preconditions.checkState(
                primitiveType == PrimitiveTypeName.BINARY,
              "%s can only annotate BINARY", logicalTypeAnnotation);
            return Optional.of(true);
          }

          private Optional<Boolean> checkInt32PrimitiveType(LogicalTypeAnnotation logicalTypeAnnotation) {
            Preconditions.checkState(primitiveType == PrimitiveTypeName.INT32,
              "%s can only annotate INT32", logicalTypeAnnotation);
            return Optional.of(true);
          }

          private Optional<Boolean> checkInt64PrimitiveType(LogicalTypeAnnotation logicalTypeAnnotation) {
            Preconditions.checkState(primitiveType == PrimitiveTypeName.INT64,
              "%s can only annotate INT64", logicalTypeAnnotation);
            return Optional.of(true);
          }
        }).orElseThrow(() -> new IllegalStateException(logicalTypeAnnotation + " can not be applied to a primitive type"));
      }

      if (newLogicalTypeSet) {
        return new PrimitiveType(repetition, primitiveType, length, name, logicalTypeAnnotation, id, columnOrder);
      } else {
        return new PrimitiveType(repetition, primitiveType, length, name, getOriginalType(), meta, id, columnOrder);
      }
    }