mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-13 15:52:01 +07:00
[json schema] IJPL-163460 Get rid of vararg in API to avoid accidental excessive arrays copying
(cherry picked from commit 100b1a8277016b3a6f99c26fccb357101a64d3f0) IJ-CR-147983 GitOrigin-RevId: 70dd14ac5cb2836eff3ad14cf4063d8f319f353f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
2503b96301
commit
53af24ec04
@@ -30,7 +30,7 @@ public abstract class JsonSchemaObject {
|
||||
public abstract @Nullable Boolean getConstantSchema();
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public abstract boolean hasChildFieldsExcept(@NotNull String @NotNull ... namesToSkip);
|
||||
public abstract boolean hasChildFieldsExcept(@NotNull List<@NotNull String> namesToSkip);
|
||||
|
||||
public abstract @NotNull Iterable<JsonSchemaValidation> getValidations(@Nullable JsonSchemaType type, @NotNull JsonValueAdapter value);
|
||||
|
||||
@@ -154,9 +154,9 @@ public abstract class JsonSchemaObject {
|
||||
|
||||
public abstract @NotNull Iterator<String> getDefinitionNames();
|
||||
|
||||
public abstract @Nullable String readChildNodeValue(@NotNull String @NotNull ... childNodeName);
|
||||
public abstract @Nullable String readChildNodeValue(@NotNull String childNodeName);
|
||||
|
||||
public abstract boolean hasChildNode(@NotNull String @NotNull ... childNodeName);
|
||||
public abstract boolean hasChildNode(@NotNull String childNodeName);
|
||||
|
||||
public abstract @NotNull Iterator<String> getPropertyNames();
|
||||
|
||||
|
||||
@@ -121,12 +121,12 @@ public class JsonSchemaObjectImpl extends JsonSchemaObject {
|
||||
public final UserDataHolderBase myUserDataHolder = new UserDataHolderBase();
|
||||
|
||||
@Override
|
||||
public @Nullable String readChildNodeValue(@NotNull String @NotNull ... childNodeName) {
|
||||
public @Nullable String readChildNodeValue(@NotNull String childNodeName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChildNode(@NotNull String @NotNull ... childNodeName) {
|
||||
public boolean hasChildNode(@NotNull String childNodeName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ public class JsonSchemaObjectImpl extends JsonSchemaObject {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChildFieldsExcept(@NotNull String @NotNull ... namesToSkip) {
|
||||
public boolean hasChildFieldsExcept(@NotNull List<@NotNull String> namesToSkip) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
package com.jetbrains.jsonSchema.impl.light
|
||||
|
||||
import com.jetbrains.jsonSchema.impl.JsonSchemaObject
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
interface JsonSchemaNodePointer<T> {
|
||||
val rawSchemaNode: T
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
interface JsonSchemaObjectFactory<T, V> where V : JsonSchemaObject, V : JsonSchemaNodePointer<T> {
|
||||
/**
|
||||
* @return an instance of schema object backed by physically existing schema node that can be found by a combined json pointer, where
|
||||
@@ -32,18 +35,18 @@ interface RawJsonSchemaNodeAccessor<T> {
|
||||
/**
|
||||
* Resolve raw schema node from the given schema node by the given node's name
|
||||
*/
|
||||
fun resolveRelativeNode(node: T, vararg relativeChildPath: String): T?
|
||||
fun resolveRelativeNode(node: T, relativeChildPath: String? = null): T?
|
||||
|
||||
fun hasChildNode(node: T, vararg relativeChildPath: String): Boolean
|
||||
fun hasChildNode(node: T, relativeChildPath: String): Boolean
|
||||
|
||||
fun readTextNodeValue(node: T, vararg relativeChildPath: String): String?
|
||||
fun readBooleanNodeValue(node: T, vararg relativeChildPath: String): Boolean?
|
||||
fun readNumberNodeValue(node: T, vararg relativeChildPath: String): Number?
|
||||
fun readUntypedNodeValueAsText(node: T, vararg relativeChildPath: String): String?
|
||||
fun readTextNodeValue(node: T, relativeChildPath: String? = null): String?
|
||||
fun readBooleanNodeValue(node: T, relativeChildPath: String? = null): Boolean?
|
||||
fun readNumberNodeValue(node: T, relativeChildPath: String? = null): Number?
|
||||
fun readUntypedNodeValueAsText(node: T, relativeChildPath: String? = null): String?
|
||||
|
||||
fun readNodeKeys(node: T, vararg relativeChildPath: String): Sequence<String>?
|
||||
fun readNodeKeys(node: T, relativeChildPath: String? = null): Sequence<String>?
|
||||
|
||||
fun readUntypedNodesCollection(node: T, vararg relativeChildPath: String): Sequence<Any>?
|
||||
fun readNodeAsMapEntries(node: T, vararg relativeChildPath: String): Sequence<Pair<String, T>>?
|
||||
fun readNodeAsMultiMapEntries(node: T, vararg relativeChildPath: String): Sequence<Pair<String, List<String>>>?
|
||||
fun readUntypedNodesCollection(node: T, relativeChildPath: String? = null): Sequence<Any>?
|
||||
fun readNodeAsMapEntries(node: T, relativeChildPath: String? = null): Sequence<Pair<String, T>>?
|
||||
fun readNodeAsMultiMapEntries(node: T, relativeChildPath: String? = null): Sequence<Pair<String, List<String>>>?
|
||||
}
|
||||
@@ -35,15 +35,15 @@ internal class InheritedJsonSchemaObjectView(
|
||||
return other.ref
|
||||
}
|
||||
|
||||
override fun readChildNodeValue(vararg childNodeName: String): String? {
|
||||
override fun readChildNodeValue(childNodeName: String): String? {
|
||||
return baseIfConditionOrOtherWithArgument(JsonSchemaObject::readChildNodeValue, childNodeName, String?::isNotBlank)
|
||||
}
|
||||
|
||||
override fun hasChildNode(vararg childNodeName: String): Boolean {
|
||||
return other.hasChildNode(*childNodeName)
|
||||
override fun hasChildNode(childNodeName: String): Boolean {
|
||||
return other.hasChildNode(childNodeName)
|
||||
}
|
||||
|
||||
override fun hasChildFieldsExcept(namesToSkip: Array<String>): Boolean {
|
||||
override fun hasChildFieldsExcept(namesToSkip: List<String>): Boolean {
|
||||
return booleanOrWithArgument(JsonSchemaObject::hasChildFieldsExcept, namesToSkip)
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ private const val INVALID_PATTERN_FALLBACK = "__invalid_ij_pattern"
|
||||
@ApiStatus.Internal
|
||||
abstract class JsonSchemaObjectBackedByJacksonBase(
|
||||
override val rawSchemaNode: JsonNode,
|
||||
private val jsonPointer: String
|
||||
private val jsonPointer: String,
|
||||
) : JsonSchemaObjectLegacyAdapter(), JsonSchemaNodePointer<JsonNode> {
|
||||
|
||||
abstract override fun getRootSchemaObject(): RootJsonSchemaObjectBackedByJackson
|
||||
@@ -87,18 +87,18 @@ abstract class JsonSchemaObjectBackedByJacksonBase(
|
||||
return getRootSchemaObject().rawFile
|
||||
}
|
||||
|
||||
override fun hasChildFieldsExcept(namesToSkip: Array<String>): Boolean {
|
||||
override fun hasChildFieldsExcept(namesToSkip: List<String>): Boolean {
|
||||
return JacksonSchemaNodeAccessor.readNodeKeys(rawSchemaNode)
|
||||
.orEmpty()
|
||||
.any { it !in namesToSkip }
|
||||
}
|
||||
|
||||
override fun hasChildNode(vararg childNodeName: String): Boolean {
|
||||
return JacksonSchemaNodeAccessor.hasChildNode(rawSchemaNode, *childNodeName)
|
||||
override fun hasChildNode(childNodeName: String): Boolean {
|
||||
return JacksonSchemaNodeAccessor.hasChildNode(rawSchemaNode, childNodeName)
|
||||
}
|
||||
|
||||
override fun readChildNodeValue(vararg childNodeName: String): String? {
|
||||
return JacksonSchemaNodeAccessor.readUntypedNodeValueAsText(rawSchemaNode, *childNodeName)
|
||||
override fun readChildNodeValue(childNodeName: String): String? {
|
||||
return JacksonSchemaNodeAccessor.readUntypedNodeValueAsText(rawSchemaNode, childNodeName)
|
||||
}
|
||||
|
||||
override fun getConstantSchema(): Boolean? {
|
||||
@@ -474,11 +474,11 @@ abstract class JsonSchemaObjectBackedByJacksonBase(
|
||||
.toList()
|
||||
}
|
||||
|
||||
private fun createChildMap(vararg childMapName: String): Map<String, JsonSchemaObject>? {
|
||||
return JacksonSchemaNodeAccessor.readNodeAsMapEntries(rawSchemaNode, *childMapName)
|
||||
private fun createChildMap(childMapName: String): Map<String, JsonSchemaObject>? {
|
||||
return JacksonSchemaNodeAccessor.readNodeAsMapEntries(rawSchemaNode, childMapName)
|
||||
?.mapNotNull { (key, value) ->
|
||||
if (!value.isObject) return@mapNotNull null
|
||||
val childObject = createResolvableChild(*childMapName, key) ?: return@mapNotNull null
|
||||
val childObject = createResolvableChild(childMapName, key) ?: return@mapNotNull null
|
||||
key to childObject
|
||||
}?.toMap()
|
||||
}
|
||||
@@ -510,16 +510,21 @@ abstract class JsonSchemaObjectBackedByJacksonBase(
|
||||
}
|
||||
|
||||
override fun getLanguageInjection(): String? {
|
||||
return JacksonSchemaNodeAccessor.readTextNodeValue(rawSchemaNode, X_INTELLIJ_LANGUAGE_INJECTION)
|
||||
?: JacksonSchemaNodeAccessor.readTextNodeValue(rawSchemaNode, X_INTELLIJ_LANGUAGE_INJECTION, LANGUAGE)
|
||||
val directChild = JacksonSchemaNodeAccessor.readTextNodeValue(rawSchemaNode, X_INTELLIJ_LANGUAGE_INJECTION)
|
||||
if (directChild != null) return directChild
|
||||
|
||||
val intermediateNode = JacksonSchemaNodeAccessor.resolveRelativeNode(rawSchemaNode, X_INTELLIJ_LANGUAGE_INJECTION) ?: return null
|
||||
return JacksonSchemaNodeAccessor.readTextNodeValue(intermediateNode, LANGUAGE)
|
||||
}
|
||||
|
||||
override fun getLanguageInjectionPrefix(): String? {
|
||||
return JacksonSchemaNodeAccessor.readTextNodeValue(rawSchemaNode, X_INTELLIJ_LANGUAGE_INJECTION, PREFIX)
|
||||
val intermediateNode = JacksonSchemaNodeAccessor.resolveRelativeNode(rawSchemaNode, X_INTELLIJ_LANGUAGE_INJECTION) ?: return null
|
||||
return JacksonSchemaNodeAccessor.readTextNodeValue(intermediateNode, PREFIX)
|
||||
}
|
||||
|
||||
override fun getLanguageInjectionPostfix(): String? {
|
||||
return JacksonSchemaNodeAccessor.readTextNodeValue(rawSchemaNode, X_INTELLIJ_LANGUAGE_INJECTION, SUFFIX)
|
||||
val intermediateNode = JacksonSchemaNodeAccessor.resolveRelativeNode(rawSchemaNode, X_INTELLIJ_LANGUAGE_INJECTION) ?: return null
|
||||
return JacksonSchemaNodeAccessor.readTextNodeValue(intermediateNode, SUFFIX)
|
||||
}
|
||||
|
||||
override fun isShouldValidateAgainstJSType(): Boolean {
|
||||
|
||||
@@ -37,15 +37,15 @@ internal class MergedJsonSchemaObjectView(
|
||||
return other.ref
|
||||
}
|
||||
|
||||
override fun readChildNodeValue(vararg childNodeName: String): String? {
|
||||
override fun readChildNodeValue(childNodeName: String): String? {
|
||||
return baseIfConditionOrOtherWithArgument(JsonSchemaObject::readChildNodeValue, childNodeName, String?::isNotBlank)
|
||||
}
|
||||
|
||||
override fun hasChildNode(vararg childNodeName: String): Boolean {
|
||||
override fun hasChildNode(childNodeName: String): Boolean {
|
||||
return booleanOrWithArgument(JsonSchemaObject::hasChildNode, childNodeName)
|
||||
}
|
||||
|
||||
override fun hasChildFieldsExcept(namesToSkip: Array<String>): Boolean {
|
||||
override fun hasChildFieldsExcept(namesToSkip: List<String>): Boolean {
|
||||
return booleanOrWithArgument(JsonSchemaObject::hasChildFieldsExcept, namesToSkip)
|
||||
}
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ internal object MissingJsonSchemaObject : JsonSchemaObjectBackedByJacksonBase(Mi
|
||||
throw UnsupportedOperationException(ERROR_MESSAGE)
|
||||
}
|
||||
|
||||
override fun hasChildFieldsExcept(namesToSkip: Array<String>): Boolean {
|
||||
override fun hasChildFieldsExcept(namesToSkip: List<String>): Boolean {
|
||||
throw UnsupportedOperationException(ERROR_MESSAGE)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,49 +19,43 @@ internal object JacksonSchemaNodeAccessor : RawJsonSchemaNodeAccessor<JsonNode>
|
||||
return rootNode.at(compiledPointer)?.takeIf { it !is MissingNode }
|
||||
}
|
||||
|
||||
override fun resolveRelativeNode(node: JsonNode, vararg relativeChildPath: String): JsonNode? {
|
||||
return relativeChildPath.asSequence().map(::escapeForbiddenJsonPointerSymbols).fold(node) { currentNode, childName ->
|
||||
val childByName = currentNode.get(childName)
|
||||
if (childByName != null) return@fold childByName
|
||||
|
||||
val maybeIndex = childName.toIntOrNull() ?: return@fold MissingNode.getInstance()
|
||||
return currentNode.get(maybeIndex)
|
||||
}.takeIf { it !is MissingNode }
|
||||
override fun resolveRelativeNode(node: JsonNode, relativeChildPath: String?): JsonNode? {
|
||||
return getExistingChildByNonEmptyPathOrSelf(node, relativeChildPath)
|
||||
}
|
||||
|
||||
override fun hasChildNode(node: JsonNode, vararg relativeChildPath: String): Boolean {
|
||||
override fun hasChildNode(node: JsonNode, relativeChildPath: String): Boolean {
|
||||
if (!node.isObject) return false
|
||||
return !getChild(node, *relativeChildPath).isMissingNode
|
||||
return !getExistingChildByNonEmptyPathOrSelf(node, relativeChildPath).isMissingNode
|
||||
}
|
||||
|
||||
override fun readUntypedNodeValueAsText(node: JsonNode, vararg relativeChildPath: String): String? {
|
||||
override fun readUntypedNodeValueAsText(node: JsonNode, relativeChildPath: String?): String? {
|
||||
if (!node.isObject) return null
|
||||
return getChild(node, *relativeChildPath)
|
||||
return getExistingChildByNonEmptyPathOrSelf(node, relativeChildPath)
|
||||
.takeIf { it !is MissingNode }
|
||||
?.toPrettyString()
|
||||
}
|
||||
|
||||
override fun readTextNodeValue(node: JsonNode, vararg relativeChildPath: String): String? {
|
||||
override fun readTextNodeValue(node: JsonNode, relativeChildPath: String?): String? {
|
||||
if (!node.isObject) return null
|
||||
val maybeString = getChild(node, *relativeChildPath)
|
||||
val maybeString = getExistingChildByNonEmptyPathOrSelf(node, relativeChildPath)
|
||||
return if (maybeString.isTextual)
|
||||
maybeString.asText()
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
override fun readBooleanNodeValue(node: JsonNode, vararg relativeChildPath: String): Boolean? {
|
||||
if (!(node.isObject || (node.isBoolean && relativeChildPath.isEmpty()))) return null
|
||||
val maybeBoolean = getChild(node, *relativeChildPath)
|
||||
override fun readBooleanNodeValue(node: JsonNode, relativeChildPath: String?): Boolean? {
|
||||
if (!(node.isObject || (node.isBoolean && relativeChildPath == null))) return null
|
||||
val maybeBoolean = if (relativeChildPath == null) node else getExistingChildByNonEmptyPathOrSelf(node, relativeChildPath)
|
||||
return if (maybeBoolean.isBoolean)
|
||||
maybeBoolean.asBoolean()
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
override fun readNumberNodeValue(node: JsonNode, vararg relativeChildPath: String): Number? {
|
||||
override fun readNumberNodeValue(node: JsonNode, relativeChildPath: String?): Number? {
|
||||
if (!node.isObject) return null
|
||||
val maybeNumber = getChild(node, *relativeChildPath)
|
||||
val maybeNumber = getExistingChildByNonEmptyPathOrSelf(node, relativeChildPath)
|
||||
return when {
|
||||
maybeNumber.isInt -> maybeNumber.asInt()
|
||||
maybeNumber.isDouble -> maybeNumber.asDouble()
|
||||
@@ -70,45 +64,43 @@ internal object JacksonSchemaNodeAccessor : RawJsonSchemaNodeAccessor<JsonNode>
|
||||
}
|
||||
}
|
||||
|
||||
override fun readUntypedNodesCollection(node: JsonNode, vararg relativeChildPath: String): Sequence<Any>? {
|
||||
return getChildArrayItems(node, *relativeChildPath)
|
||||
override fun readUntypedNodesCollection(node: JsonNode, relativeChildPath: String?): Sequence<Any>? {
|
||||
return getChildArrayItems(node, relativeChildPath)
|
||||
?.mapNotNull(JacksonSchemaNodeAccessor::readAnything)
|
||||
}
|
||||
|
||||
override fun readNodeAsMapEntries(node: JsonNode, vararg relativeChildPath: String): Sequence<Pair<String, JsonNode>>? {
|
||||
override fun readNodeAsMapEntries(node: JsonNode, relativeChildPath: String?): Sequence<Pair<String, JsonNode>>? {
|
||||
if (!node.isObject) return null
|
||||
return getChild(node, *relativeChildPath)
|
||||
return getExistingChildByNonEmptyPathOrSelf(node, relativeChildPath)
|
||||
.takeIf { it.isObject }
|
||||
?.fields()
|
||||
?.asSequence()
|
||||
?.map { it.key to it.value }
|
||||
}
|
||||
|
||||
override fun readNodeAsMultiMapEntries(node: JsonNode, vararg relativeChildPath: String): Sequence<Pair<String, List<String>>>? {
|
||||
return readNodeAsMapEntries(node, *relativeChildPath)
|
||||
override fun readNodeAsMultiMapEntries(node: JsonNode, relativeChildPath: String?): Sequence<Pair<String, List<String>>>? {
|
||||
return readNodeAsMapEntries(node, relativeChildPath)
|
||||
?.mapNotNull { (stringKey, arrayValue) ->
|
||||
if (!arrayValue.isArray) return@mapNotNull null
|
||||
stringKey to arrayValue.elements().asSequence().mapNotNull { if (it.isTextual) it.asText() else null }.toList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun readNodeKeys(node: JsonNode, vararg relativeChildPath: String): Sequence<String>? {
|
||||
val expandedNode = if (relativeChildPath.isEmpty())
|
||||
node
|
||||
else
|
||||
getChild(node, *relativeChildPath)
|
||||
override fun readNodeKeys(node: JsonNode, relativeChildPath: String?): Sequence<String>? {
|
||||
val expandedNode = getExistingChildByNonEmptyPathOrSelf(node, relativeChildPath)
|
||||
return expandedNode.fieldNames().takeIf(Iterator<String>::hasNext)?.asSequence()
|
||||
}
|
||||
|
||||
private fun getChild(node: JsonNode, vararg relativePath: String): JsonNode {
|
||||
return relativePath.fold(node) { parentNode, childName ->
|
||||
parentNode.get(childName) ?: return MissingNode.getInstance()
|
||||
}
|
||||
private fun getExistingChildByNonEmptyPathOrSelf(node: JsonNode, directChildName: String? = null): JsonNode {
|
||||
return if (directChildName == null)
|
||||
node
|
||||
else
|
||||
node.get(directChildName) ?: MissingNode.getInstance()
|
||||
}
|
||||
|
||||
private fun getChildArrayItems(node: JsonNode, vararg name: String): Sequence<JsonNode>? {
|
||||
private fun getChildArrayItems(node: JsonNode, name: String?): Sequence<JsonNode>? {
|
||||
if (!node.isObject) return null
|
||||
return getChild(node, *name)
|
||||
return getExistingChildByNonEmptyPathOrSelf(node, name)
|
||||
.takeIf { it.isArray }
|
||||
?.asSafely<ArrayNode>()
|
||||
?.elements()
|
||||
|
||||
@@ -110,18 +110,11 @@ interface JsonSchemaInterpretationStrategy {
|
||||
|| baseSchema.rawFile != null && baseSchema.rawFile == childSchema.rawFile
|
||||
}
|
||||
|
||||
private fun isNodeWithDifferentPointers(
|
||||
baseSchema: JsonSchemaObject,
|
||||
childSchema: JsonSchemaObject,
|
||||
): Boolean {
|
||||
return baseSchema.pointer != childSchema.pointer
|
||||
}
|
||||
|
||||
private fun isApplicatorBranchWithNonEmptyParent(
|
||||
baseSchema: JsonSchemaObject,
|
||||
childSchema: JsonSchemaObject,
|
||||
): Boolean {
|
||||
if (!baseSchema.hasChildFieldsExcept(ONE_OF, ALL_OF, ANY_OF)) return false
|
||||
if (!baseSchema.hasChildFieldsExcept(APPLICATOR_MARKERS)) return false
|
||||
|
||||
return sequence {
|
||||
yieldAll(baseSchema.oneOf.orEmpty())
|
||||
@@ -134,10 +127,13 @@ interface JsonSchemaInterpretationStrategy {
|
||||
baseSchema: JsonSchemaObject,
|
||||
childSchema: JsonSchemaObject,
|
||||
): Boolean {
|
||||
if (!baseSchema.hasChildFieldsExcept(IF, THEN, ELSE)) return false
|
||||
if (!baseSchema.hasChildFieldsExcept(IF_ELSE_MARKERS)) return false
|
||||
|
||||
return baseSchema.ifThenElse?.any { condition ->
|
||||
condition.then == childSchema || condition.`else` == childSchema
|
||||
} ?: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val IF_ELSE_MARKERS = listOf(IF, THEN, ELSE)
|
||||
private val APPLICATOR_MARKERS = listOf(ONE_OF, ALL_OF, ANY_OF)
|
||||
Reference in New Issue
Block a user