private RecordMetadata parseRecordMetadata()

in core/src/main/java/com/jetbrains/youtrackdb/internal/core/serialization/serializer/record/string/JSONSerializerJackson.java [376:575]


  private RecordMetadata parseRecordMetadata(
      @Nonnull DatabaseSessionInternal session,
      @Nullable JsonParser jsonParser,
      @Nullable String defaultClassName,
      Byte defaultRecordType,
      boolean asValue
  ) throws IOException {

    var token = jsonParser.nextToken();
    RecordIdInternal recordId = null;
    var recordType = defaultRecordType;
    var className = defaultClassName;
    Map<String, String> fieldTypes = new HashMap<>();
    var entityType = EntityType.PUBLIC;
    Boolean embeddedFlag = null;
    Integer recordVersion = null;

    var fieldsCount = 0;

    while (token != JsonToken.END_OBJECT) {
      if (token == JsonToken.FIELD_NAME) {
        var fieldName = jsonParser.currentName();
        if (fieldName.charAt(0) != '@') {
          break;
        }

        fieldsCount++;
        switch (fieldName) {
          case FieldTypesString.ATTRIBUTE_FIELD_TYPES -> {
            fieldTypes = parseFieldTypes(jsonParser);
            token = jsonParser.nextToken();
          }
          case EntityHelper.ATTRIBUTE_TYPE -> {
            token = jsonParser.nextToken();
            if (token != JsonToken.VALUE_STRING) {
              throw new SerializationException(session,
                  "Expected field value as string.");
            }
            var fieldValueAsString = jsonParser.getText();
            if (fieldValueAsString.length() != 1) {
              throw new SerializationException(session,
                  "Invalid record type: " + fieldValueAsString);
            }
            recordType = (byte) fieldValueAsString.charAt(0);
            token = jsonParser.nextToken();
          }
          case EntityHelper.ATTRIBUTE_RID -> {
            token = jsonParser.nextToken();
            if (token != JsonToken.VALUE_STRING) {
              throw new SerializationException(session,
                  "Expected field value as string");
            }
            var fieldValueAsString = jsonParser.getText();
            if (!fieldValueAsString.isEmpty()) {
              recordId = RecordIdInternal.fromString(fieldValueAsString, false);
            }
            token = jsonParser.nextToken();
          }
          case EntityHelper.ATTRIBUTE_CLASS -> {
            token = jsonParser.nextToken();
            if (token != JsonToken.VALUE_STRING) {
              throw new SerializationException(session,
                  "Expected field value as string");
            }
            var fieldValueAsString = jsonParser.getText();
            className = "null".equals(fieldValueAsString) ? null : fieldValueAsString;
            token = jsonParser.nextToken();
          }
          case EntityHelper.ATTRIBUTE_INTERNAL_ENTITY -> {
            token = jsonParser.nextToken();
            if (token != JsonToken.VALUE_TRUE && token != JsonToken.VALUE_FALSE) {
              throw new SerializationException(session,
                  "Expected field value as boolean");
            }
            var internalRecord = jsonParser.getBooleanValue();
            if (internalRecord) {
              entityType = EntityType.INTERNAL;
            }
            token = jsonParser.nextToken();
          }
          case EntityHelper.ATTRIBUTE_INDEX_MANAGER_ENTITY -> {
            token = jsonParser.nextToken();
            if (token != JsonToken.VALUE_TRUE && token != JsonToken.VALUE_FALSE) {
              throw new SerializationException(session,
                  "Expected field value as boolean");
            }
            var internalRecord = jsonParser.getBooleanValue();
            if (internalRecord) {
              if (entityType != EntityType.PUBLIC) {
                throw new SerializationException(
                    "Entity type already marked as internal : " + entityType);
              }
              entityType = EntityType.INDEX_MANAGER;
            }
            token = jsonParser.nextToken();
          }

          case EntityHelper.ATTRIBUTE_SCHEMA_MANAGER_ENTITY -> {
            token = jsonParser.nextToken();
            if (token != JsonToken.VALUE_TRUE && token != JsonToken.VALUE_FALSE) {
              throw new SerializationException(session,
                  "Expected field value as boolean");
            }
            var internalRecord = jsonParser.getBooleanValue();
            if (internalRecord) {
              if (entityType != EntityType.PUBLIC) {
                throw new SerializationException(
                    "Entity type already marked as internal : " + entityType);
              }
              entityType = EntityType.SCHEMA_MANAGER;
            }
            token = jsonParser.nextToken();
          }
          case EntityHelper.ATTRIBUTE_EMBEDDED -> {
            token = jsonParser.nextToken();
            if (token != JsonToken.VALUE_TRUE && token != JsonToken.VALUE_FALSE) {
              throw new SerializationException(session,
                  "Expected field value as boolean");
            }
            embeddedFlag = jsonParser.getBooleanValue();
            token = jsonParser.nextToken();
          }
          case EntityHelper.ATTRIBUTE_VERSION -> {
            token = jsonParser.nextToken();
            if (token != JsonToken.VALUE_NUMBER_INT) {
              throw new SerializationException(session,
                  "Expected field value integer");
            }
            recordVersion = jsonParser.getIntValue();
            token = jsonParser.nextToken();
          }
          default -> throw new SerializationException(session,
              "Unexpected field name: " + fieldName);
        }
      } else {
        throw new SerializationException(session, "Expected field name");
      }
    }

    if (fieldsCount == 0) {
      return null;
    }

    var schema = session.getMetadata().getImmutableSchemaSnapshot();
    SchemaClass schemaClass = null;
    if (className == null && defaultClassName == null && recordId != null) {
      schemaClass = schema.getClassByCollectionId(recordId.getCollectionId());

      if (schemaClass != null) {
        className = schemaClass.getName();
      }
    }

    if (recordType == null) {
      if (schemaClass == null && className != null) {
        schemaClass = schema.getClass(className);

        if (schemaClass == null) {
          throw new SerializationException(session,
              "Class not found: " + className);
        }
      }

      if (schemaClass != null) {
        if (schemaClass.isVertexType()) {
          recordType = VertexEntityImpl.RECORD_TYPE;
        } else if (schemaClass.isEdgeType()) {
          recordType = StatefullEdgeEntityImpl.RECORD_TYPE;
        } else {
          recordType = EntityImpl.RECORD_TYPE;
        }
      } else {
        recordType = EntityImpl.RECORD_TYPE;
      }
    }

    boolean embeddedValue;
    if (embeddedFlag == null) {
      if (className == null) {
        embeddedValue = asValue && recordId == null;
      } else {
        var cls = session.getMetadata().getImmutableSchemaSnapshot().getClass(className);
        if (cls != null) {
          embeddedValue = cls.isAbstract();
        } else {
          throw new SerializationException(session,
              "Class not found: " + className);
        }
      }
    } else {
      embeddedValue = embeddedFlag;
    }

    return new RecordMetadata(
        recordType,
        recordId,
        entityType.isInternal() ? null : className,
        fieldTypes, embeddedValue, recordVersion, entityType
    );
  }