protected PrimitiveType build()

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


    protected PrimitiveType build(String name) {
      if (length == 0 && logicalTypeAnnotation instanceof LogicalTypeAnnotation.UUIDLogicalTypeAnnotation) {
        length = LogicalTypeAnnotation.UUIDLogicalTypeAnnotation.BYTES;
      }
      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.Float16LogicalTypeAnnotation float16LogicalType) {
                return checkFixedPrimitiveType(
                    LogicalTypeAnnotation.Float16LogicalTypeAnnotation.BYTES, float16LogicalType);
              }

              @Override
              public Optional<Boolean> visit(
                  LogicalTypeAnnotation.UnknownLogicalTypeAnnotation unknownLogicalType) {
                return Optional.of(true);
              }

              @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);
              }

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

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

              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);
      }
    }