[json] IJPL-166426 Log the number of various resolve-related method invocations to be able to compare with the updated version in the future.

The goal is to reduce both number of local and remote url resolve attempts


(cherry picked from commit 8b347c28c75b6241e2a15d2bf5d7ac509da6d178)

IJ-CR-149952

GitOrigin-RevId: eb13dd5f224091d7c73fec7a46b5d30248e1d49d
This commit is contained in:
Nikita Katkov
2024-11-13 20:20:41 +01:00
committed by intellij-monorepo-bot
parent bf2a7a3672
commit c4e34440e7
23 changed files with 233 additions and 13 deletions

View File

@@ -133,6 +133,7 @@
<lang.floatingToolbar language="JSON" minimal="true"/>
<pluginSuggestionProvider implementation="com.jetbrains.jsonSchema.wiremock.WireMockSuggestionProvider"/>
<statistics.counterUsagesCollector implementationClass="com.jetbrains.jsonSchema.fus.JsonFeatureUsageCollector"/>
</extensions>
<extensions defaultExtensionNs="JavaScript">

View File

@@ -0,0 +1,78 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.jsonSchema.fus
import com.intellij.internal.statistic.eventLog.EventLogGroup
import com.intellij.internal.statistic.eventLog.events.EventField
import com.intellij.internal.statistic.eventLog.events.EventFields
import com.intellij.internal.statistic.eventLog.events.EventFields.StringValidatedByRegexpReference
import com.intellij.internal.statistic.eventLog.events.RoundedIntEventField
import com.intellij.internal.statistic.eventLog.events.StringEventField
import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector
import org.jetbrains.annotations.ApiStatus
internal object JsonFeatureUsageCollector : CounterUsagesCollector() {
private val jsonSchemaGroup = EventLogGroup(
id = "json.schema.features",
version = 1,
)
internal val jsonSchemaHighlightingSessionData =
jsonSchemaGroup.registerVarargEvent(
"jsonSchemaHighlightingSession",
*JsonSchemaFusFeature.getAllRegistered().toTypedArray()
)
override fun getGroup(): EventLogGroup = jsonSchemaGroup
}
@ApiStatus.Internal
sealed interface JsonSchemaFusFeature {
val event: EventField<*>
companion object {
fun getAllRegistered(): List<EventField<*>> {
return listOf(
JsonSchemaFusRegexpFeature.entries,
JsonSchemaFusCountedUniqueFeature.entries,
JsonSchemaFusCountedFeature.entries
).flatten()
.map { it.event }
}
}
}
enum class JsonSchemaFusRegexpFeature(override val event: StringEventField) : JsonSchemaFusFeature {
JsonFusSchemaId(StringValidatedByRegexpReference("schemaId", "^(https?):\\/\\/[^\\s/$.?#].[^\\s]*$"))
}
enum class JsonSchemaFusCountedUniqueFeature(override val event: RoundedIntEventField) : JsonSchemaFusFeature {
UniqueRemoteUrlDownloadRequest(EventFields.RoundedInt("uniqueRemoteUrlDownloadRequest")),
SchemaAccessWithoutReadLock(EventFields.RoundedInt("schemaAccessWithoutReadLock")),
}
@ApiStatus.Internal
enum class JsonSchemaFusCountedFeature(override val event: RoundedIntEventField) : JsonSchemaFusFeature {
ExecutedHttpVirtualFileDownloadRequest(EventFields.RoundedInt("executedHttpVirtualFileDownloadRequest")),
RemoteUrlResolveRequest(EventFields.RoundedInt("remoteUrlResolveRequest")),
LocalReferenceResolveRequest(EventFields.RoundedInt("localFileResolveRequest")),
JsonSchemaResolveTreeBuild(EventFields.RoundedInt("jsonSchemaResolveTreeBuild")),
AllJsonSchemaResolveTreeBuild(EventFields.RoundedInt("allJsonSchemaResolveTreeBuild")),
ArrayValidation(EventFields.RoundedInt("arrayValidation")),
ConstantNodeValidation(EventFields.RoundedInt("constantNodeValidation")),
EnumValidation(EventFields.RoundedInt("enumValidation")),
NotValidation(EventFields.RoundedInt("notValidation")),
StringValidation(EventFields.RoundedInt("stringValidation")),
NumberValidation(EventFields.RoundedInt("numberValidation")),
ObjectValidation(EventFields.RoundedInt("objectValidation")),
TypeValidation(EventFields.RoundedInt("typeValidation")),
OneOfExpanded(EventFields.RoundedInt("oneOfExpanded")),
AnyOfExpanded(EventFields.RoundedInt("anyOfExpanded")),
AllOfExpanded(EventFields.RoundedInt("allOfExpanded")),
IfElseExpanded(EventFields.RoundedInt("ifElseExpanded")),
DefinitionsExpanded(EventFields.RoundedInt("definitionsExpanded")),
SchemaInherited(EventFields.RoundedInt("schemaInherited")),
SchemaMerged(EventFields.RoundedInt("schemaMerged")),
}

View File

@@ -0,0 +1,78 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.jsonSchema.fus
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.psi.util.ReadActionCachedValue
import org.jetbrains.annotations.ApiStatus
import java.util.concurrent.atomic.AtomicInteger
@Service(Service.Level.APP)
@ApiStatus.Internal
class JsonSchemaHighlightingSessionStatisticsCollector {
companion object {
@JvmStatic
fun getInstance(): JsonSchemaHighlightingSessionStatisticsCollector {
return service<JsonSchemaHighlightingSessionStatisticsCollector>()
}
}
private inner class JsonSchemaHighlightingSession {
val featuresWithCount = mutableMapOf<JsonSchemaFusFeature, Int>()
var schemaType: String? = null
val requestedRemoteSchemas = mutableSetOf<String>()
}
// Expected to be zero, but let's collect it to prove there are no additional cases to consider
private val requestsOutsideHighlightingCounter = AtomicInteger(0)
private val currentHighlightingSession = ReadActionCachedValue<JsonSchemaHighlightingSession> {
JsonSchemaHighlightingSession()
}
private fun getOrComputeCurrentSession(): JsonSchemaHighlightingSession? {
if (!ApplicationManager.getApplication().isReadAccessAllowed) {
thisLogger().debug("reportSchemaUsageFeature() must not be called outside read action")
requestsOutsideHighlightingCounter.incrementAndGet()
return null
}
return currentHighlightingSession.getCachedOrEvaluate()
}
fun reportSchemaType(schemaId: String?) {
val currentSession = getOrComputeCurrentSession() ?: return
currentSession.schemaType = schemaId
}
fun reportSchemaUsageFeature(featureKind: JsonSchemaFusFeature) {
val currentSession = getOrComputeCurrentSession() ?: return
currentSession.featuresWithCount[featureKind] = currentSession.featuresWithCount.getOrDefault(featureKind, 0) + 1
}
fun reportUniqueUrlDownloadRequestUsage(schemaUrl: String) {
val currentSession = getOrComputeCurrentSession() ?: return
currentSession.requestedRemoteSchemas.add(schemaUrl)
}
fun flushHighlightingSessionDataToFus() {
val sessionData = currentHighlightingSession.getCachedOrEvaluate()
val allCountEventsDuringSession = JsonSchemaFusCountedFeature.entries
.map { feature -> feature to sessionData.featuresWithCount.getOrDefault(feature, 0) }
.map { (feature, usagesCount) -> feature.event.with(usagesCount) }
val uniqueSchemasCount = JsonSchemaFusCountedUniqueFeature.UniqueRemoteUrlDownloadRequest.event.with(sessionData.requestedRemoteSchemas.size)
val schemaAccessOutsideHighlightingCount = JsonSchemaFusCountedUniqueFeature.SchemaAccessWithoutReadLock.event.with(requestsOutsideHighlightingCounter.getAndSet(0))
val schemaId = JsonSchemaFusRegexpFeature.JsonFusSchemaId.event.with(sessionData.schemaType)
val allDataAccumulated = allCountEventsDuringSession + uniqueSchemasCount + schemaAccessOutsideHighlightingCount + schemaId
JsonFeatureUsageCollector.jsonSchemaHighlightingSessionData.log(allDataAccumulated)
if (thisLogger().isDebugEnabled) {
val printableStatistics = allDataAccumulated.joinToString(prefix = "\n", postfix = "\n", separator = "\n") { eventPair -> "${eventPair.field.name}: ${eventPair.data}" }
thisLogger().debug("JSON schema highlighting session statistics: $printableStatistics")
}
}
}

View File

@@ -16,6 +16,7 @@ import com.intellij.util.SmartList;
import com.jetbrains.jsonSchema.extension.JsonLikePsiWalker;
import com.jetbrains.jsonSchema.extension.adapters.JsonPropertyAdapter;
import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -58,6 +59,12 @@ public final class JsonSchemaComplianceChecker {
}
public void annotate(final @NotNull PsiElement element) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaType(myRootSchema.getId());
doAnnotate(element);
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().flushHighlightingSessionDataToFus();
}
private void doAnnotate(@NotNull PsiElement element) {
Project project = element.getProject();
final JsonPropertyAdapter firstProp = myWalker.getParentPropertyAdapter(element);
if (firstProp != null) {

View File

@@ -14,6 +14,8 @@ import com.jetbrains.jsonSchema.extension.adapters.JsonArrayValueAdapter;
import com.jetbrains.jsonSchema.extension.adapters.JsonObjectValueAdapter;
import com.jetbrains.jsonSchema.extension.adapters.JsonPropertyAdapter;
import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.ide.JsonSchemaService;
import com.jetbrains.jsonSchema.impl.tree.JsonSchemaNodeExpansionRequest;
import org.jetbrains.annotations.NotNull;
@@ -67,6 +69,7 @@ public final class JsonSchemaResolver {
}
public MatchResult detailedResolve() {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.JsonSchemaResolveTreeBuild);
final JsonSchemaTreeNode node = JsonSchemaVariantsTreeBuilder.buildTree(myProject, myExpansionRequest, mySchema, myPosition, false);
return MatchResult.create(node);
}

View File

@@ -6,6 +6,8 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.ThreeState;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.ide.JsonSchemaService;
import com.jetbrains.jsonSchema.impl.tree.JsonSchemaNodeExpansionRequest;
import com.jetbrains.jsonSchema.impl.tree.Operation;

View File

@@ -4,6 +4,8 @@ package com.jetbrains.jsonSchema.impl.light
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.impl.http.HttpVirtualFile
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector
import com.jetbrains.jsonSchema.ide.JsonSchemaService
import com.jetbrains.jsonSchema.impl.JsonSchemaObject
import com.jetbrains.jsonSchema.impl.light.legacy.JsonSchemaObjectReadingUtils
@@ -32,13 +34,16 @@ internal data object RemoteSchemaReferenceResolver : JsonSchemaReferenceResolver
referenceOwner: JsonSchemaObjectBackedByJacksonBase,
service: JsonSchemaService,
): JsonSchemaObject? {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().run {
reportSchemaUsageFeature(JsonSchemaFusCountedFeature.RemoteUrlResolveRequest)
reportUniqueUrlDownloadRequestUsage(reference)
}
// leave tests with default behaviour to not accidentally miss even more bugs
if (!ApplicationManager.getApplication().isUnitTestMode && !Registry.`is`("json.schema.object.v2.enable.nested.remote.schema.resolve")) {
return null
}
val resolvedRemoteSchema = resolveRemoteSchemaByUrl(reference, referenceOwner, service) ?: return null
return resolvedRemoteSchema
return resolveRemoteSchemaByUrl(reference, referenceOwner, service)
}
}
@@ -57,6 +62,7 @@ internal fun resolveLocalSchemaNode(
maybeEmptyReference: String,
currentSchemaNode: JsonSchemaObjectBackedByJacksonBase,
): JsonSchemaObject? {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.LocalReferenceResolveRequest)
return when {
maybeEmptyReference.startsWith("#/") -> resolveReference(maybeEmptyReference, currentSchemaNode)
maybeEmptyReference.startsWith("/") -> resolveReference(maybeEmptyReference, currentSchemaNode)

View File

@@ -12,6 +12,8 @@ import com.intellij.openapi.vfs.impl.http.RemoteFileInfo;
import com.intellij.openapi.vfs.impl.http.RemoteFileState;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.FactoryMap;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.ide.JsonSchemaService;
import com.jetbrains.jsonSchema.impl.*;
import com.jetbrains.jsonSchema.remote.JsonFileResolver;
@@ -138,6 +140,7 @@ public final class JsonSchemaObjectReadingUtils {
if (info != null) {
RemoteFileState state = info.getState();
if (state == RemoteFileState.DOWNLOADING_NOT_STARTED) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.ExecutedHttpVirtualFileDownloadRequest);
JsonFileResolver.startFetchingHttpFileIfNeeded(refFile, service.getProject());
return NULL_OBJ;
}

View File

@@ -3,6 +3,8 @@ package com.jetbrains.jsonSchema.impl.light.nodes
import com.intellij.openapi.progress.ProgressManager
import com.intellij.util.containers.ContainerUtil
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector
import com.jetbrains.jsonSchema.impl.JsonSchemaObject
import com.jetbrains.jsonSchema.impl.MergedJsonSchemaObject
import com.jetbrains.jsonSchema.impl.light.legacy.JsonSchemaObjectMerger
@@ -15,6 +17,7 @@ internal object LightweightJsonSchemaObjectMerger : JsonSchemaObjectMerger {
if (base === other) {
return base
}
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.SchemaMerged)
return MergedJsonSchemaObjectView(base, other, pointTo)
}
}

View File

@@ -2,18 +2,18 @@
package com.jetbrains.jsonSchema.impl.light.nodes
import com.intellij.util.asSafely
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector
import com.jetbrains.jsonSchema.impl.JsonSchemaObject
// todo: avoid casting after JsonSchemaObject is made an interface
internal fun inheritBaseSchemaIfNeeded(parent: JsonSchemaObject, child: JsonSchemaObject): JsonSchemaObject {
//val parentUrl = parent.fileUrl
//val childUrl = child.fileUrl
//if (parentUrl == null || parentUrl == childUrl) return child
return child.asSafely<JsonSchemaObjectBackedByJacksonBase>()
?.rootSchemaObject
?.schemaInterpretationStrategy
?.inheritBaseSchema(parent, child)
?: child
val inheritedSchema = child.asSafely<JsonSchemaObjectBackedByJacksonBase>()
?.rootSchemaObject
?.schemaInterpretationStrategy
?.inheritBaseSchema(parent, child)
if (inheritedSchema == null) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.SchemaInherited)
}
return inheritedSchema ?: child
}

View File

@@ -2,6 +2,8 @@
package com.jetbrains.jsonSchema.impl.tree;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.ide.JsonSchemaService;
import com.jetbrains.jsonSchema.impl.JsonSchemaObject;
import com.jetbrains.jsonSchema.impl.SchemaResolveState;
@@ -24,6 +26,7 @@ public final class AllOfOperation extends Operation {
@Override
public void map(final @NotNull Set<JsonSchemaObject> visited) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.AllOfExpanded);
var allOf = mySourceNode.getAllOf();
assert allOf != null;
myChildOperations.addAll(ContainerUtil.map(allOf, sourceNode -> new ProcessDefinitionsOperation(sourceNode, myService, myExpansionRequest)));

View File

@@ -2,6 +2,8 @@
package com.jetbrains.jsonSchema.impl.tree;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.ide.JsonSchemaService;
import com.jetbrains.jsonSchema.impl.JsonSchemaObject;
import com.jetbrains.jsonSchema.impl.SchemaResolveState;
@@ -22,6 +24,7 @@ public class AnyOfOperation extends Operation {
@Override
public void map(final @NotNull Set<JsonSchemaObject> visited) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.AnyOfExpanded);
var anyOf = mySourceNode.getAnyOf();
assert anyOf != null;
myChildOperations.addAll(ContainerUtil.map(anyOf, sourceNode -> new ProcessDefinitionsOperation(sourceNode, myService, myExpansionRequest)));

View File

@@ -3,6 +3,8 @@ package com.jetbrains.jsonSchema.impl.tree
import com.jetbrains.jsonSchema.extension.JsonLikePsiWalker
import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector
import com.jetbrains.jsonSchema.ide.JsonSchemaService
import com.jetbrains.jsonSchema.impl.JsonSchemaObject
import com.jetbrains.jsonSchema.impl.JsonSchemaResolver
@@ -11,6 +13,7 @@ import com.jetbrains.jsonSchema.impl.light.nodes.inheritBaseSchemaIfNeeded
internal class IfThenElseBranchOperation(schemaObject: JsonSchemaObject, expansionRequest: JsonSchemaNodeExpansionRequest?, private val jsonSchemaService: JsonSchemaService) : Operation(schemaObject, expansionRequest) {
override fun map(visited: MutableSet<JsonSchemaObject>) {
if (visited.contains(mySourceNode)) return
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.IfElseExpanded);
val effectiveBranches = computeEffectiveIfThenElseBranches(myExpansionRequest, mySourceNode)
?.mapNotNull {

View File

@@ -3,6 +3,8 @@ package com.jetbrains.jsonSchema.impl.tree;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.ide.JsonSchemaService;
import com.jetbrains.jsonSchema.impl.JsonSchemaObject;
import com.jetbrains.jsonSchema.impl.SchemaResolveState;
@@ -24,6 +26,7 @@ class OneOfOperation extends Operation {
@Override
public void map(final @NotNull Set<JsonSchemaObject> visited) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.OneOfExpanded);
var oneOf = mySourceNode.getOneOf();
assert oneOf != null;
myChildOperations.addAll(ContainerUtil.map(oneOf, sourceNode -> new ProcessDefinitionsOperation(sourceNode, myService, myExpansionRequest)));

View File

@@ -3,6 +3,8 @@ package com.jetbrains.jsonSchema.impl.tree;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.text.StringUtil;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.ide.JsonSchemaService;
import com.jetbrains.jsonSchema.impl.JsonSchemaObject;
import com.jetbrains.jsonSchema.impl.SchemaResolveState;
@@ -25,6 +27,7 @@ public final class ProcessDefinitionsOperation extends Operation {
@Override
public void map(final @NotNull Set<JsonSchemaObject> visited) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.DefinitionsExpanded);
var current = mySourceNode;
while (!StringUtil.isEmptyOrSpaces(current.getRef())) {
ProgressManager.checkCanceled();

View File

@@ -9,6 +9,8 @@ import com.jetbrains.jsonSchema.extension.JsonSchemaValidation;
import com.jetbrains.jsonSchema.extension.JsonValidationHost;
import com.jetbrains.jsonSchema.extension.adapters.JsonArrayValueAdapter;
import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.impl.JsonComplianceCheckerOptions;
import com.jetbrains.jsonSchema.impl.JsonSchemaObject;
import com.jetbrains.jsonSchema.impl.JsonSchemaType;
@@ -27,6 +29,7 @@ public class ArrayValidation implements JsonSchemaValidation {
@Nullable JsonSchemaType schemaType,
@NotNull JsonValidationHost consumer,
@NotNull JsonComplianceCheckerOptions options) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.ArrayValidation);
return checkArray(propValue, schema, consumer, options);
}

View File

@@ -6,12 +6,15 @@ import com.jetbrains.jsonSchema.extension.JsonErrorPriority
import com.jetbrains.jsonSchema.extension.JsonSchemaValidation
import com.jetbrains.jsonSchema.extension.JsonValidationHost
import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector
import com.jetbrains.jsonSchema.impl.JsonComplianceCheckerOptions
import com.jetbrains.jsonSchema.impl.JsonSchemaObject
import com.jetbrains.jsonSchema.impl.JsonSchemaType
internal object ConstantSchemaValidation: JsonSchemaValidation {
internal object ConstantSchemaValidation : JsonSchemaValidation {
override fun validate(propValue: JsonValueAdapter, schema: JsonSchemaObject, schemaType: JsonSchemaType?, consumer: JsonValidationHost, options: JsonComplianceCheckerOptions): Boolean {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.ConstantNodeValidation)
if (schema.constantSchema == false) {
consumer.error(JsonBundle.message("schema.validation.constant.schema"), propValue.delegate.parent, JsonErrorPriority.LOW_PRIORITY)
return false

View File

@@ -11,6 +11,8 @@ import com.jetbrains.jsonSchema.extension.adapters.JsonArrayValueAdapter;
import com.jetbrains.jsonSchema.extension.adapters.JsonObjectValueAdapter;
import com.jetbrains.jsonSchema.extension.adapters.JsonPropertyAdapter;
import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.impl.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -29,6 +31,7 @@ public final class EnumValidation implements JsonSchemaValidation {
@Nullable JsonSchemaType schemaType,
@NotNull JsonValidationHost consumer,
@NotNull JsonComplianceCheckerOptions options) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.EnumValidation);
List<Object> enumItems = schema.getEnum();
if (enumItems == null) return true;
final JsonLikePsiWalker walker = JsonLikePsiWalker.getWalker(propValue.getDelegate(), schema);

View File

@@ -7,6 +7,8 @@ import com.jetbrains.jsonSchema.extension.JsonErrorPriority;
import com.jetbrains.jsonSchema.extension.JsonSchemaValidation;
import com.jetbrains.jsonSchema.extension.JsonValidationHost;
import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.impl.JsonComplianceCheckerOptions;
import com.jetbrains.jsonSchema.impl.JsonSchemaObject;
import com.jetbrains.jsonSchema.impl.JsonSchemaType;
@@ -24,6 +26,7 @@ public final class NotValidation implements JsonSchemaValidation {
@Nullable JsonSchemaType schemaType,
@NotNull JsonValidationHost consumer,
@NotNull JsonComplianceCheckerOptions options) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.NotValidation);
final MatchResult result = consumer.resolve(schema.getNot(), propValue);
if (result.mySchemas.isEmpty() && result.myExcludingSchemas.isEmpty()) return true;

View File

@@ -7,6 +7,8 @@ import com.jetbrains.jsonSchema.extension.JsonErrorPriority;
import com.jetbrains.jsonSchema.extension.JsonSchemaValidation;
import com.jetbrains.jsonSchema.extension.JsonValidationHost;
import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.impl.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -140,6 +142,7 @@ public final class NumericValidation implements JsonSchemaValidation {
@Nullable JsonSchemaType schemaType,
@NotNull JsonValidationHost consumer,
@NotNull JsonComplianceCheckerOptions options) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.NumberValidation);
return checkNumber(propValue.getDelegate(), schema, schemaType, consumer, options);
}
}

View File

@@ -17,6 +17,8 @@ import com.jetbrains.jsonSchema.extension.JsonValidationHost;
import com.jetbrains.jsonSchema.extension.adapters.JsonObjectValueAdapter;
import com.jetbrains.jsonSchema.extension.adapters.JsonPropertyAdapter;
import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.impl.*;
import kotlin.collections.CollectionsKt;
import one.util.streamex.StreamEx;
@@ -38,6 +40,7 @@ public final class ObjectValidation implements JsonSchemaValidation {
@Nullable JsonSchemaType schemaType,
@NotNull JsonValidationHost consumer,
@NotNull JsonComplianceCheckerOptions options) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.ObjectValidation);
return checkObject(propValue, schema, consumer, options);
}

View File

@@ -8,6 +8,8 @@ import com.jetbrains.jsonSchema.extension.JsonErrorPriority;
import com.jetbrains.jsonSchema.extension.JsonSchemaValidation;
import com.jetbrains.jsonSchema.extension.JsonValidationHost;
import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.impl.JsonComplianceCheckerOptions;
import com.jetbrains.jsonSchema.impl.JsonSchemaObject;
import com.jetbrains.jsonSchema.impl.JsonSchemaType;
@@ -24,6 +26,7 @@ public final class StringValidation implements JsonSchemaValidation {
@Nullable JsonSchemaType schemaType,
@NotNull JsonValidationHost consumer,
@NotNull JsonComplianceCheckerOptions options) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.StringValidation);
return checkString(propValue.getDelegate(), schema, consumer, options);
}

View File

@@ -4,6 +4,8 @@ package com.jetbrains.jsonSchema.impl.validations;
import com.jetbrains.jsonSchema.extension.JsonSchemaValidation;
import com.jetbrains.jsonSchema.extension.JsonValidationHost;
import com.jetbrains.jsonSchema.extension.adapters.JsonValueAdapter;
import com.jetbrains.jsonSchema.fus.JsonSchemaFusCountedFeature;
import com.jetbrains.jsonSchema.fus.JsonSchemaHighlightingSessionStatisticsCollector;
import com.jetbrains.jsonSchema.impl.JsonComplianceCheckerOptions;
import com.jetbrains.jsonSchema.impl.JsonSchemaAnnotatorChecker;
import com.jetbrains.jsonSchema.impl.JsonSchemaObject;
@@ -21,6 +23,7 @@ public final class TypeValidation implements JsonSchemaValidation {
@Nullable JsonSchemaType schemaType,
@NotNull JsonValidationHost consumer,
@NotNull JsonComplianceCheckerOptions options) {
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaUsageFeature(JsonSchemaFusCountedFeature.TypeValidation);
JsonSchemaType otherType = JsonSchemaAnnotatorChecker.getMatchingSchemaType(schema, schemaType);
if (otherType != null && !otherType.equals(schemaType) && !otherType.equals(propValue.getAlternateType(schemaType))) {
consumer.typeError(propValue.getDelegate(), propValue.getAlternateType(schemaType), JsonSchemaAnnotatorChecker.getExpectedTypes(Collections.singleton(schema)));