content: /*
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you under the Apache License, Version 2.0 (the
   * "License"); you may not use this file except in compliance
   * with the License.  You may obtain a copy of the License at
   *
   *   http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing,
   * software distributed under the License is distributed on an
   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   * KIND, either express or implied.  See the License for the
   * specific language governing permissions and limitations
   * under the License.
   */
  package org.apache.asterix.om.types;
  
  import static org.apache.asterix.om.types.ATypeTag.VALUE_TYPE_MAPPING;
  
  import org.apache.asterix.om.base.IAObject;
  import org.apache.hyracks.api.io.IJsonSerializable;
  import org.apache.hyracks.api.io.IPersistedResourceRegistry;
  
  import com.fasterxml.jackson.databind.JsonNode;
  import com.fasterxml.jackson.databind.ObjectMapper;
  import com.fasterxml.jackson.databind.node.ObjectNode;
  
  public abstract class BuiltinType implements IAType {
  
      private static final long serialVersionUID = 1L;
      private static final String TAG_FIELD = "tag";
  
      public abstract static class LowerCaseConstructorType extends BuiltinType {
          private static final long serialVersionUID = 1L;
  
          @Override
          public String getConstructor() {
              return getTypeTag().toString().toLowerCase();
          }
      }
  
      /** the type of all types */
      public static final BuiltinType ALL_TYPE = new BuiltinType() {
  
          private static final long serialVersionUID = -6449893468153263063L;
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.TYPE;
          }
  
          @Override
          public String getDisplayName() {
              return "AllType";
          }
  
          @Override
          public String getTypeName() {
              return "ALL_TYPE";
          }
  
          @Override
          public String getConstructor() {
              return null;
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ALL_TYPE");
              return type;
          }
      };
  
      public static final BuiltinType AINT8 = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = -3548486253352636441L;
  
          @Override
          public String getDisplayName() {
              return "AInt8";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.TINYINT;
          }
  
          @Override
          public String getTypeName() {
              return "int8";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "AInt8");
              return type;
          }
      };
  
      public static final BuiltinType AINT16 = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 7372637344359144146L;
  
          @Override
          public String getDisplayName() {
              return "AInt16";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.SMALLINT;
          }
  
          @Override
          public String getTypeName() {
              return "int16";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "AInt16");
              return type;
          }
      };
  
      public static final BuiltinType AINT32 = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = -2019098705812691759L;
  
          @Override
          public String getDisplayName() {
              return "AInt32";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.INTEGER;
          }
  
          @Override
          public String getTypeName() {
              return "int32";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "AInt32");
              return type;
          }
      };
  
      public static final BuiltinType AINT64 = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = -1512324312146380842L;
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.BIGINT;
          }
  
          @Override
          public String getDisplayName() {
              return "AInt64";
          }
  
          @Override
          public String getTypeName() {
              return "int64";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "AInt64");
              return type;
          }
      };
  
      public static final BuiltinType ABINARY = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 6267661034873713699L;
  
          @Override
          public String getDisplayName() {
              return "ABinary";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.BINARY;
          }
  
          @Override
          public String getTypeName() {
              return "binary";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ABinary");
              return type;
          }
      };
  
      public static final BuiltinType AFLOAT = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 3677347396583352706L;
  
          @Override
          public String getDisplayName() {
              return "AFloat";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.FLOAT;
          }
  
          @Override
          public String getTypeName() {
              return "float";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "AFloat");
              return type;
          }
      };
  
      public static final BuiltinType ADOUBLE = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = -4541634684505456336L;
  
          @Override
          public String getDisplayName() {
              return "ADouble";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.DOUBLE;
          }
  
          @Override
          public String getTypeName() {
              return "double";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ADouble");
              return type;
          }
      };
  
      public static final BuiltinType ASTRING = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = -7772076532516609205L;
  
          @Override
          public String getDisplayName() {
              return "AString";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.STRING;
          }
  
          @Override
          public String getTypeName() {
              return "string";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "AString");
              return type;
          }
      };
  
      public static final BuiltinType AMISSING = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 7776297133205477953L;
  
          @Override
          public String getDisplayName() {
              return "Missing";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.MISSING;
          }
  
          @Override
          public String getTypeName() {
              return "missing";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "AMISSING");
              return type;
          }
      };
  
      public static final BuiltinType ANULL = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = -8499117420923359476L;
  
          @Override
          public String getDisplayName() {
              return "Null";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.NULL;
          }
  
          @Override
          public String getTypeName() {
              return "null";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ANULL");
              return type;
          }
      };
  
      public static final BuiltinType ABOOLEAN = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = -3974299905945243639L;
  
          @Override
          public String getDisplayName() {
              return "ABoolean";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.BOOLEAN;
          }
  
          @Override
          public String getTypeName() {
              return "boolean";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ABoolean");
              return type;
          }
      };
  
      public static final BuiltinType ATIME = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 4868038022671454583L;
  
          @Override
          public String getDisplayName() {
              return "ATime";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.TIME;
          }
  
          @Override
          public String getTypeName() {
              return "time";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ATime");
              return type;
          }
      };
  
      public static final BuiltinType ADATE = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 4037452728204123123L;
  
          @Override
          public String getDisplayName() {
              return "ADate";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.DATE;
          }
  
          @Override
          public String getTypeName() {
              return "date";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ADate");
              return type;
          }
      };
  
      public static final BuiltinType ADATETIME = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 8133030540756758494L;
  
          @Override
          public String getDisplayName() {
              return "ADateTime";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.DATETIME;
          }
  
          @Override
          public String getTypeName() {
              return "datetime";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ADateTime");
              return type;
          }
      };
  
      public static final BuiltinType ADURATION = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 2724423960287103412L;
  
          @Override
          public String getDisplayName() {
              return "ADuration";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.DURATION;
          }
  
          @Override
          public String getTypeName() {
              return "duration";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ADuration");
              return type;
          }
      };
  
      public static final BuiltinType AYEARMONTHDURATION = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = -5424462543021800169L;
  
          @Override
          public String getDisplayName() {
              return "AYearMonthDuration";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.YEARMONTHDURATION;
          }
  
          @Override
          public String getTypeName() {
              return "year-month-duration";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "AYearMonthDuration");
              return type;
          }
      };
  
      public static final BuiltinType ADAYTIMEDURATION = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 1605907151536226966L;
  
          @Override
          public String getDisplayName() {
              return "ADayTimeDuration";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.DAYTIMEDURATION;
          }
  
          @Override
          public String getTypeName() {
              return "day-time-duration";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ADayTimeDuration");
              return type;
          }
      };
  
      public static final BuiltinType AINTERVAL = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 6503802193278692294L;
  
          @Override
          public String getDisplayName() {
              return "AInterval";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.INTERVAL;
          }
  
          @Override
          public String getTypeName() {
              return "interval";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              return null;
          }
      };
  
      public static final BuiltinType APOINT = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = -8095235249315628525L;
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.POINT;
          }
  
          @Override
          public String getDisplayName() {
              return "APoint";
          }
  
          @Override
          public String getTypeName() {
              return "point";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "APoint");
              return type;
          }
      };
  
      public static final BuiltinType APOINT3D = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 8511348838989487264L;
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.POINT3D;
          }
  
          @Override
          public String getDisplayName() {
              return "APoint3D";
          }
  
          @Override
          public String getTypeName() {
              return "point3d";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "APoint3D");
              return type;
          }
      };
  
      public static final BuiltinType ALINE = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = -5081002479268381298L;
  
          @Override
          public String getDisplayName() {
              return "ALINE";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.LINE;
          }
  
          @Override
          public String getTypeName() {
              return "line";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ALINE");
              return type;
          }
      };
  
      public static final BuiltinType APOLYGON = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = -1150256493732890410L;
  
          @Override
          public String getDisplayName() {
              return "APOLYGON";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.POLYGON;
          }
  
          @Override
          public String getTypeName() {
              return "polygon";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "APOLYGON");
              return type;
          }
      };
  
      public static final BuiltinType AGEOMETRY = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 1561894254022047509L;
  
          @Override
          public String getDisplayName() {
              return "AGEOMETRY";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.GEOMETRY;
          }
  
          @Override
          public String getTypeName() {
              return "geometry";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectNode type = new ObjectMapper().createObjectNode();
              type.put("type", "AGEOMETRY");
              return type;
          }
      };
  
      public static final BuiltinType ACIRCLE = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 2609452848446856772L;
  
          @Override
          public String getDisplayName() {
              return "ACIRCLE";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.CIRCLE;
          }
  
          @Override
          public String getTypeName() {
              return "circle";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ACIRCLE");
              return type;
          }
      };
  
      public static final BuiltinType ARECTANGLE = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 3751474563396177041L;
  
          @Override
          public String getDisplayName() {
              return "ARECTANGLE";
          }
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.RECTANGLE;
          }
  
          @Override
          public String getTypeName() {
              return "rectangle";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ARECTANGLE");
              return type;
          }
      };
  
      public static final IAType ABITARRAY = new LowerCaseConstructorType() {
  
          private static final long serialVersionUID = 9071500011277554477L;
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.BITARRAY;
          }
  
          @Override
          public String getDisplayName() {
              return "ABitArray";
          }
  
          @Override
          public String getTypeName() {
              return "abitarray";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ABitArray");
              return type;
          }
      };
  
      public static final BuiltinType AUUID = new LowerCaseConstructorType() {
          private static final long serialVersionUID = -8403791895909921192L;
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.UUID;
          }
  
          @Override
          public String getDisplayName() {
              return "UUID";
          }
  
          @Override
          public String getTypeName() {
              return "uuid";
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", getDisplayName());
              return type;
          }
      };
  
      public static final BuiltinType ANY = new BuiltinType() {
  
          private static final long serialVersionUID = -4041457851203593309L;
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.ANY;
          }
  
          @Override
          public String getTypeName() {
              return "any";
          }
  
          @Override
          public String getDisplayName() {
              return "ANY";
          }
  
          @Override
          public String getConstructor() {
              return null;
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "ANY");
              return type;
          }
      };
  
      public static final BuiltinType SHORTWITHOUTTYPEINFO = new BuiltinType() {
  
          private static final long serialVersionUID = -1769780932699820665L;
  
          @Override
          public ATypeTag getTypeTag() {
              return ATypeTag.SHORTWITHOUTTYPEINFO;
          }
  
          @Override
          public String getTypeName() {
              return "shortwithouttypeinfo";
          }
  
          @Override
          public String getDisplayName() {
              return "SHORTWITHOUTTYPEINFO";
          }
  
          @Override
          public String getConstructor() {
              return null;
          }
  
          @Override
          public JsonNode toJson(IPersistedResourceRegistry registry) {
              return convertToJson(registry, getTypeTag().serialize(), serialVersionUID);
          }
  
          @Override
          public ObjectNode toJSON() {
              ObjectMapper om = new ObjectMapper();
              ObjectNode type = om.createObjectNode();
              type.put("type", "SHORTWITHOUTTYPEINFO");
              return type;
          }
      };
  
      public abstract String getConstructor();
  
      @Override
      public IAType getType() {
          return ALL_TYPE;
      }
  
      @Override
      public String toString() {
          return getTypeTag().toString();
      }
  
      @Override
      public boolean deepEqual(IAObject obj) {
          if (obj == this) {
              return true;
          }
          if (!(obj instanceof BuiltinType)) {
              return false;
          }
          return ((BuiltinType) obj).getTypeTag().equals(getTypeTag());
      }
  
      @Override
      public boolean equals(Object object) {
          return object instanceof IAObject && deepEqual((IAObject) object);
      }
  
      @Override
      public int hashCode() {
          return getTypeTag().hashCode();
      }
  
      @Override
      public int hash() {
          return getType().getTypeTag().serialize();
      }
  
      /**
       * Visit built-in type as a flat type
       */
      @Override
      public <R, T> R accept(IATypeVisitor<R, T> visitor, T arg) {
          return visitor.visitFlat(this, arg);
      }
  
      private static JsonNode convertToJson(IPersistedResourceRegistry registry, short tag, long version) {
          ObjectNode jsonNode = registry.getClassIdentifier(BuiltinType.class, version);
          jsonNode.put(TAG_FIELD, tag);
          return jsonNode;
      }
  
      @SuppressWarnings("squid:S1172") // unused parameter
      public static IJsonSerializable fromJson(IPersistedResourceRegistry registry, JsonNode json) {
          byte tag = (byte) json.get(TAG_FIELD).shortValue();
          return getBuiltinType(VALUE_TYPE_MAPPING[tag]);
      }
  
      public static IAType getBuiltinType(ATypeTag typeTag) {
          switch (typeTag) {
              case TYPE:
                  return ALL_TYPE;
              case TINYINT:
                  return AINT8;
              case SMALLINT:
                  return AINT16;
              case INTEGER:
                  return AINT32;
              case BIGINT:
                  return AINT64;
              case FLOAT:
                  return AFLOAT;
              case DOUBLE:
                  return ADOUBLE;
              case STRING:
                  return ASTRING;
              case BINARY:
                  return ABINARY;
              case MISSING:
                  return AMISSING;
              case NULL:
                  return ANULL;
              case BOOLEAN:
                  return ABOOLEAN;
              case TIME:
                  return ATIME;
              case DATE:
                  return ADATE;
              case DATETIME:
                  return ADATETIME;
              case DURATION:
                  return ADURATION;
              case YEARMONTHDURATION:
                  return AYEARMONTHDURATION;
              case DAYTIMEDURATION:
                  return ADAYTIMEDURATION;
              case INTERVAL:
                  return AINTERVAL;
              case POINT:
                  return APOINT;
              case POINT3D:
                  return APOINT3D;
              case LINE:
                  return ALINE;
              case POLYGON:
                  return APOLYGON;
              case GEOMETRY:
                  return AGEOMETRY;
              case CIRCLE:
                  return ACIRCLE;
              case RECTANGLE:
                  return ARECTANGLE;
              case BITARRAY:
                  return ABITARRAY;
              case UUID:
                  return AUUID;
              case ANY:
                  return ANY;
              case SHORTWITHOUTTYPEINFO:
                  return SHORTWITHOUTTYPEINFO;
              default:
                  throw new UnsupportedOperationException(typeTag.toString());
          }
      }
  }
  