import { defaultTo } from 'ramda';
import { ArrayElement, ObjectElement, assignSourceMap, cloneDeep, includesClasses, isArrayElement, isElement, isMemberElement, isStringElement, toValue } from '@swagger-api/apidom-core';
import { ComponentsChannelBindingsElement, ComponentsCorrelationIDsElement, ComponentsMessageBindingsElement, ComponentsMessageTraitsElement, ComponentsMessagesElement, ComponentsOperationBindingsElement, ComponentsOperationTraitsElement, ComponentsParametersElement, ComponentsSecuritySchemesElement, ComponentsServerBindingsElement, ComponentsServerVariablesElement, ComponentsServersElement, MessageTraitExamplesElement, ServerSecurityElement, ServerVariablesElement } from '@swagger-api/apidom-ns-asyncapi-2';
import mediaTypes from "../../media-types.mjs";
import AsyncApiVersionElement from "../../elements/AsyncApiVersion.mjs";
import IdentifierElement from "../../elements/Identifier.mjs";
import InfoElement from "../../elements/Info.mjs";
import ServersElement from "../../elements/Servers.mjs";
import DefaultContentTypeElement from "../../elements/DefaultContentType.mjs";
import ChannelsElement from "../../elements/Channels.mjs";
import ComponentsElement from "../../elements/Components.mjs";
import TagsElement from "../../elements/Tags.mjs";
import ExternalDocumentationElement from "../../elements/ExternalDocumentation.mjs";
import ContactElement from "../../elements/Contact.mjs";
import LicenseElement from "../../elements/License.mjs";
import ServerElement from "../../elements/Server.mjs";
import ServerVariableElement from "../../elements/ServerVariable.mjs";
import ChannelElement from "../../elements/Channel.mjs";
import SchemaElement from "../../elements/Schema.mjs";
import MessageElement from "../../elements/Message.mjs";
import MessagesElement from "../../elements/Messages.mjs";
import SecuritySchemeElement from "../../elements/SecurityScheme.mjs";
import ParameterElement from "../../elements/Parameter.mjs";
import ParametersElement from "../../elements/Parameters.mjs";
import CorrelationIDElement from "../../elements/CorrelationID.mjs";
import OperationTraitElement from "../../elements/OperationTrait.mjs";
import MessageTraitElement from "../../elements/MessageTrait.mjs";
import ServerBindingsElement from "../../elements/ServerBindings.mjs";
import ChannelBindingsElement from "../../elements/ChannelBindings.mjs";
import OperationBindingsElement from "../../elements/OperationBindings.mjs";
import MessageBindingsElement from "../../elements/MessageBindings.mjs";
import OAuthFlowsElement from "../../elements/OauthFlows.mjs";
import OAuthFlowElement from "../../elements/OauthFlow.mjs";
import OperationElement from "../../elements/Operation.mjs";
import OperationReplyElement from "../../elements/OperationReply.mjs";
import OperationReplyAddressElement from "../../elements/OperationReplyAddress.mjs";
import OperationsElement from "../../elements/Operations.mjs";
import TagElement from "../../elements/Tag.mjs";
import MessageExampleElement from "../../elements/MessageExample.mjs";
import ReferenceElement from "../../elements/Reference.mjs";
import ComponentsRepliesElement from "../../elements/nces/ComponentsReplies.mjs";
import ComponentsReplyAddressesElement from "../../elements/nces/ComponentsReplyAddresses.mjs"; // binding elements
import AmqpChannelBindingElement from "../../elements/bindings/amqp/AmqpChannelBinding.mjs";
import AmqpMessageBindingElement from "../../elements/bindings/amqp/AmqpMessageBinding.mjs";
import AmqpOperationBindingElement from "../../elements/bindings/amqp/AmqpOperationBinding.mjs";
import AmqpServerBindingElement from "../../elements/bindings/amqp/AmqpServerBinding.mjs";
import Amqp1ChannelBindingElement from "../../elements/bindings/amqp1/Amqp1ChannelBinding.mjs";
import Amqp1MessageBindingElement from "../../elements/bindings/amqp1/Amqp1MessageBinding.mjs";
import Amqp1OperationBindingElement from "../../elements/bindings/amqp1/Amqp1OperationBinding.mjs";
import Amqp1ServerBindingElement from "../../elements/bindings/amqp1/Amqp1ServerBinding.mjs";
import AnypointmqChannelBindingElement from "../../elements/bindings/anypointmq/AnypointmqChannelBinding.mjs";
import AnypointmqMessageBindingElement from "../../elements/bindings/anypointmq/AnypointmqMessageBinding.mjs";
import AnypointmqOperationBindingElement from "../../elements/bindings/anypointmq/AnypointmqOperationBinding.mjs";
import AnypointmqServerBindingElement from "../../elements/bindings/anypointmq/AnypointmqServerBinding.mjs";
import GooglepubsubChannelBindingElement from "../../elements/bindings/googlepubsub/GooglepubsubChannelBinding.mjs";
import GooglepubsubMessageBindingElement from "../../elements/bindings/googlepubsub/GooglepubsubMessageBinding.mjs";
import GooglepubsubOperationBindingElement from "../../elements/bindings/googlepubsub/GooglepubsubOperationBinding.mjs";
import GooglepubsubServerBindingElement from "../../elements/bindings/googlepubsub/GooglepubsubServerBinding.mjs";
import HttpChannelBindingElement from "../../elements/bindings/http/HttpChannelBinding.mjs";
import HttpMessageBindingElement from "../../elements/bindings/http/HttpMessageBinding.mjs";
import HttpOperationBindingElement from "../../elements/bindings/http/HttpOperationBinding.mjs";
import HttpServerBindingElement from "../../elements/bindings/http/HttpServerBinding.mjs";
import IbmmqChannelBindingElement from "../../elements/bindings/ibmmq/IbmmqChannelBinding.mjs";
import IbmmqMessageBindingElement from "../../elements/bindings/ibmmq/IbmmqMessageBinding.mjs";
import IbmmqOperationBindingElement from "../../elements/bindings/ibmmq/IbmmqOperationBinding.mjs";
import IbmmqServerBindingElement from "../../elements/bindings/ibmmq/IbmmqServerBinding.mjs";
import JmsChannelBindingElement from "../../elements/bindings/jms/JmsChannelBinding.mjs";
import JmsMessageBindingElement from "../../elements/bindings/jms/JmsMessageBinding.mjs";
import JmsOperationBindingElement from "../../elements/bindings/jms/JmsOperationBinding.mjs";
import JmsServerBindingElement from "../../elements/bindings/jms/JmsServerBinding.mjs";
import KafkaChannelBindingElement from "../../elements/bindings/kafka/KafkaChannelBinding.mjs";
import KafkaMessageBindingElement from "../../elements/bindings/kafka/KafkaMessageBinding.mjs";
import KafkaOperationBindingElement from "../../elements/bindings/kafka/KafkaOperationBinding.mjs";
import KafkaServerBindingElement from "../../elements/bindings/kafka/KafkaServerBinding.mjs";
import MercureChannelBindingElement from "../../elements/bindings/mercure/MercureChannelBinding.mjs";
import MercureMessageBindingElement from "../../elements/bindings/mercure/MercureMessageBinding.mjs";
import MercureOperationBindingElement from "../../elements/bindings/mercure/MercureOperationBinding.mjs";
import MercureServerBindingElement from "../../elements/bindings/mercure/MercureServerBinding.mjs";
import MqttChannelBindingElement from "../../elements/bindings/mqtt/MqttChannelBinding.mjs";
import MqttMessageBindingElement from "../../elements/bindings/mqtt/MqttMessageBinding.mjs";
import MqttOperationBindingElement from "../../elements/bindings/mqtt/MqttOperationBinding.mjs";
import MqttServerBindingElement from "../../elements/bindings/mqtt/MqttServerBinding.mjs";
import Mqtt5ChannelBindingElement from "../../elements/bindings/mqtt5/Mqtt5ChannelBinding.mjs";
import Mqtt5MessageBindingElement from "../../elements/bindings/mqtt5/Mqtt5MessageBinding.mjs";
import Mqtt5OperationBindingElement from "../../elements/bindings/mqtt5/Mqtt5OperationBinding.mjs";
import Mqtt5ServerBindingElement from "../../elements/bindings/mqtt5/Mqtt5ServerBinding.mjs";
import NatsChannelBindingElement from "../../elements/bindings/nats/NatsChannelBinding.mjs";
import NatsMessageBindingElement from "../../elements/bindings/nats/NatsMessageBinding.mjs";
import NatsOperationBindingElement from "../../elements/bindings/nats/NatsOperationBinding.mjs";
import NatsServerBindingElement from "../../elements/bindings/nats/NatsServerBinding.mjs";
import PulsarChannelBindingElement from "../../elements/bindings/pulsar/PulsarChannelBinding.mjs";
import PulsarMessageBindingElement from "../../elements/bindings/pulsar/PulsarMessageBinding.mjs";
import PulsarOperationBindingElement from "../../elements/bindings/pulsar/PulsarOperationBinding.mjs";
import PulsarServerBindingElement from "../../elements/bindings/pulsar/PulsarServerBinding.mjs";
import RedisChannelBindingElement from "../../elements/bindings/redis/RedisChannelBinding.mjs";
import RedisMessageBindingElement from "../../elements/bindings/redis/RedisMessageBinding.mjs";
import RedisOperationBindingElement from "../../elements/bindings/redis/RedisOperationBinding.mjs";
import RedisServerBindingElement from "../../elements/bindings/redis/RedisServerBinding.mjs";
import SnsChannelBindingElement from "../../elements/bindings/sns/SnsChannelBinding.mjs";
import SnsMessageBindingElement from "../../elements/bindings/sns/SnsMessageBinding.mjs";
import SnsOperationBindingElement from "../../elements/bindings/sns/SnsOperationBinding.mjs";
import SnsServerBindingElement from "../../elements/bindings/sns/SnsServerBinding.mjs";
import SolaceChannelBindingElement from "../../elements/bindings/solace/SolaceChannelBinding.mjs";
import SolaceMessageBindingElement from "../../elements/bindings/solace/SolaceMessageBinding.mjs";
import SolaceOperationBindingElement from "../../elements/bindings/solace/SolaceOperationBinding.mjs";
import SolaceServerBindingElement from "../../elements/bindings/solace/SolaceServerBinding.mjs";
import SqsChannelBindingElement from "../../elements/bindings/sqs/SqsChannelBinding.mjs";
import SqsMessageBindingElement from "../../elements/bindings/sqs/SqsMessageBinding.mjs";
import SqsOperationBindingElement from "../../elements/bindings/sqs/SqsOperationBinding.mjs";
import SqsServerBindingElement from "../../elements/bindings/sqs/SqsServerBinding.mjs";
import StompChannelBindingElement from "../../elements/bindings/stomp/StompChannelBinding.mjs";
import StompMessageBindingElement from "../../elements/bindings/stomp/StompMessageBinding.mjs";
import StompOperationBindingElement from "../../elements/bindings/stomp/StompOperationBinding.mjs";
import StompServerBindingElement from "../../elements/bindings/stomp/StompServerBinding.mjs";
import WebSocketChannelBindingElement from "../../elements/bindings/ws/WebSocketChannelBinding.mjs";
import WebSocketMessageBindingElement from "../../elements/bindings/ws/WebSocketMessageBinding.mjs";
import WebSocketOperationBindingElement from "../../elements/bindings/ws/WebSocketOperationBinding.mjs";
import WebSocketServerBindingElement from "../../elements/bindings/ws/WebSocketServerBinding.mjs"; // nces / helper collections
import ComponentsOperationsElement from "../../elements/nces/ComponentsOperations.mjs";
import ChannelServersElement from "../../elements/nces/ChannelServers.mjs";
import ComponentsSchemasElement from "../../elements/nces/ComponentsSchemas.mjs";
import MessageExamplesElement from "../../elements/nces/MessageExamples.mjs";
import MessageTraitsElement from "../../elements/nces/MessageTraits.mjs";
import OperationMessagesElement from "../../elements/nces/OperationMessages.mjs";
import OperationReplyMessagesElement from "../../elements/nces/OperationReplyMessages.mjs";
import OperationSecurityElement from "../../elements/nces/OperationSecurity.mjs";
import OperationTraitsElement from "../../elements/nces/OperationTraits.mjs";
import OperationTraitSecurityElement from "../../elements/nces/OperationTraitSecurity.mjs";
import SecuritySchemeScopesElement from "../../elements/nces/SecuritySchemeScopes.mjs";
import { getNodeType } from "../../traversal/visitor.mjs";
/**
 * This plugin targets YAML 1.2 empty nodes. When a mapping value is omitted,
 * it substitutes the most suitable semantic AsyncAPI 3 element.
 *
 * https://yaml.org/spec/1.2.2/#72-empty-nodes
 *
 * @example
 *
 * ```yaml
 * asyncapi: 3.0.0
 * operations:
 *   sendMessage:
 * ```
 * Refracting result without this plugin:
 *
 *  (AsyncApi3Element
 *    (MemberElement
 *      (StringElement)
 *      (OperationsElement
 *        (MemberElement
 *          (StringElement)
 *          (StringElement))))
 *
 * Refracting result with this plugin:
 *
 *  (AsyncApi3Element
 *    (MemberElement
 *      (StringElement)
 *      (OperationsElement
 *        (MemberElement
 *          (StringElement)
 *          (OperationElement))))
 */
const isEmptyElement = element => isStringElement(element) && includesClasses(['yaml-e-node', 'yaml-e-scalar'], element);
const schema = {
  AsyncApi3Element: {
    asyncapi(...args) {
      return new AsyncApiVersionElement(...args);
    },
    identifier(...args) {
      return new IdentifierElement(...args);
    },
    info(...args) {
      return new InfoElement(...args);
    },
    servers(...args) {
      return new ServersElement(...args);
    },
    defaultContentType(...args) {
      return new DefaultContentTypeElement(...args);
    },
    channels(...args) {
      return new ChannelsElement(...args);
    },
    components(...args) {
      return new ComponentsElement(...args);
    },
    operations(...args) {
      return new OperationsElement(...args);
    }
  },
  InfoElement: {
    contact(...args) {
      return new ContactElement(...args);
    },
    license(...args) {
      return new LicenseElement(...args);
    },
    tags(...args) {
      return new TagsElement(...args);
    },
    externalDocs(...args) {
      return new ExternalDocumentationElement(...args);
    }
  },
  ServersElement: {
    '[key: *]': function key(...args) {
      return new ServerElement(...args);
    }
  },
  ServerElement: {
    variables(...args) {
      return new ServerVariablesElement(...args);
    },
    security(...args) {
      return new ServerSecurityElement(...args);
    },
    tags(...args) {
      return new TagsElement(...args);
    },
    externalDocs(...args) {
      return new ExternalDocumentationElement(...args);
    },
    bindings(...args) {
      return new ServerBindingsElement(...args);
    }
  },
  ServerVariableElement: {
    enum(...args) {
      return new ArrayElement(...args);
    },
    examples(...args) {
      return new ArrayElement(...args);
    }
  },
  ChannelsElement: {
    '[key: *]': function key(...args) {
      return new ChannelElement(...args);
    }
  },
  ChannelElement: {
    servers(...args) {
      return new ChannelServersElement(...args);
    },
    parameters(...args) {
      return new ParametersElement(...args);
    },
    messages(...args) {
      return new MessagesElement(...args);
    },
    bindings(...args) {
      return new ChannelBindingsElement(...args);
    },
    tags(...args) {
      return new TagsElement(...args);
    },
    externalDocs(...args) {
      return new ExternalDocumentationElement(...args);
    }
  },
  MessagesElement: {
    '[key: *]': function key(...args) {
      return new MessageElement(...args);
    }
  },
  OperationsElement: {
    '[key: *]': function key(...args) {
      return new OperationElement(...args);
    }
  },
  OperationElement: {
    channel(...args) {
      return new ReferenceElement(...args);
    },
    tags(...args) {
      return new TagsElement(...args);
    },
    externalDocs(...args) {
      return new ExternalDocumentationElement(...args);
    },
    bindings(...args) {
      return new OperationBindingsElement(...args);
    },
    traits(...args) {
      return new OperationTraitsElement(...args);
    },
    security(...args) {
      return new OperationSecurityElement(...args);
    },
    messages(...args) {
      return new OperationMessagesElement(...args);
    },
    reply(...args) {
      return new OperationReplyElement(...args);
    }
  },
  OperationTraitElement: {
    security(...args) {
      return new OperationTraitSecurityElement(...args);
    },
    tags(...args) {
      return new TagsElement(...args);
    },
    externalDocs(...args) {
      return new ExternalDocumentationElement(...args);
    },
    bindings(...args) {
      return new OperationBindingsElement(...args);
    }
  },
  OperationReplyElement: {
    address(...args) {
      return new OperationReplyAddressElement(...args);
    },
    channel(...args) {
      return new ReferenceElement(...args);
    },
    messages(...args) {
      return new OperationReplyMessagesElement(...args);
    }
  },
  ParametersElement: {
    '[key: *]': function key(...args) {
      return new ParameterElement(...args);
    }
  },
  ParameterElement: {
    enum(...args) {
      return new ArrayElement(...args);
    },
    examples(...args) {
      return new ArrayElement(...args);
    }
  },
  ServerBindingsElement: {
    http(...args) {
      return new HttpServerBindingElement(...args);
    },
    ws(...args) {
      return new WebSocketServerBindingElement(...args);
    },
    kafka(...args) {
      return new KafkaServerBindingElement(...args);
    },
    anypointmq(...args) {
      return new AnypointmqServerBindingElement(...args);
    },
    amqp(...args) {
      return new AmqpServerBindingElement(...args);
    },
    amqp1(...args) {
      return new Amqp1ServerBindingElement(...args);
    },
    mqtt(...args) {
      return new MqttServerBindingElement(...args);
    },
    mqtt5(...args) {
      return new Mqtt5ServerBindingElement(...args);
    },
    nats(...args) {
      return new NatsServerBindingElement(...args);
    },
    jms(...args) {
      return new JmsServerBindingElement(...args);
    },
    sns(...args) {
      return new SnsServerBindingElement(...args);
    },
    solace(...args) {
      return new SolaceServerBindingElement(...args);
    },
    sqs(...args) {
      return new SqsServerBindingElement(...args);
    },
    stomp(...args) {
      return new StompServerBindingElement(...args);
    },
    redis(...args) {
      return new RedisServerBindingElement(...args);
    },
    mercure(...args) {
      return new MercureServerBindingElement(...args);
    },
    ibmmq(...args) {
      return new IbmmqServerBindingElement(...args);
    },
    googlepubsub(...args) {
      return new GooglepubsubServerBindingElement(...args);
    },
    pulsar(...args) {
      return new PulsarServerBindingElement(...args);
    }
  },
  ChannelBindingsElement: {
    http(...args) {
      return new HttpChannelBindingElement(...args);
    },
    ws(...args) {
      return new WebSocketChannelBindingElement(...args);
    },
    kafka(...args) {
      return new KafkaChannelBindingElement(...args);
    },
    anypointmq(...args) {
      return new AnypointmqChannelBindingElement(...args);
    },
    amqp(...args) {
      return new AmqpChannelBindingElement(...args);
    },
    amqp1(...args) {
      return new Amqp1ChannelBindingElement(...args);
    },
    mqtt(...args) {
      return new MqttChannelBindingElement(...args);
    },
    mqtt5(...args) {
      return new Mqtt5ChannelBindingElement(...args);
    },
    nats(...args) {
      return new NatsChannelBindingElement(...args);
    },
    jms(...args) {
      return new JmsChannelBindingElement(...args);
    },
    sns(...args) {
      return new SnsChannelBindingElement(...args);
    },
    solace(...args) {
      return new SolaceChannelBindingElement(...args);
    },
    sqs(...args) {
      return new SqsChannelBindingElement(...args);
    },
    stomp(...args) {
      return new StompChannelBindingElement(...args);
    },
    redis(...args) {
      return new RedisChannelBindingElement(...args);
    },
    mercure(...args) {
      return new MercureChannelBindingElement(...args);
    },
    ibmmq(...args) {
      return new IbmmqChannelBindingElement(...args);
    },
    googlepubsub(...args) {
      return new GooglepubsubChannelBindingElement(...args);
    },
    pulsar(...args) {
      return new PulsarChannelBindingElement(...args);
    }
  },
  OperationBindingsElement: {
    http(...args) {
      return new HttpOperationBindingElement(...args);
    },
    ws(...args) {
      return new WebSocketOperationBindingElement(...args);
    },
    kafka(...args) {
      return new KafkaOperationBindingElement(...args);
    },
    anypointmq(...args) {
      return new AnypointmqOperationBindingElement(...args);
    },
    amqp(...args) {
      return new AmqpOperationBindingElement(...args);
    },
    amqp1(...args) {
      return new Amqp1OperationBindingElement(...args);
    },
    mqtt(...args) {
      return new MqttOperationBindingElement(...args);
    },
    mqtt5(...args) {
      return new Mqtt5OperationBindingElement(...args);
    },
    nats(...args) {
      return new NatsOperationBindingElement(...args);
    },
    jms(...args) {
      return new JmsOperationBindingElement(...args);
    },
    sns(...args) {
      return new SnsOperationBindingElement(...args);
    },
    solace(...args) {
      return new SolaceOperationBindingElement(...args);
    },
    sqs(...args) {
      return new SqsOperationBindingElement(...args);
    },
    stomp(...args) {
      return new StompOperationBindingElement(...args);
    },
    redis(...args) {
      return new RedisOperationBindingElement(...args);
    },
    mercure(...args) {
      return new MercureOperationBindingElement(...args);
    },
    googlepubsub(...args) {
      return new GooglepubsubOperationBindingElement(...args);
    },
    ibmmq(...args) {
      return new IbmmqOperationBindingElement(...args);
    },
    pulsar(...args) {
      return new PulsarOperationBindingElement(...args);
    }
  },
  MessageBindingsElement: {
    http(...args) {
      return new HttpMessageBindingElement(...args);
    },
    ws(...args) {
      return new WebSocketMessageBindingElement(...args);
    },
    kafka(...args) {
      return new KafkaMessageBindingElement(...args);
    },
    anypointmq(...args) {
      return new AnypointmqMessageBindingElement(...args);
    },
    amqp(...args) {
      return new AmqpMessageBindingElement(...args);
    },
    amqp1(...args) {
      return new Amqp1MessageBindingElement(...args);
    },
    mqtt(...args) {
      return new MqttMessageBindingElement(...args);
    },
    mqtt5(...args) {
      return new Mqtt5MessageBindingElement(...args);
    },
    nats(...args) {
      return new NatsMessageBindingElement(...args);
    },
    jms(...args) {
      return new JmsMessageBindingElement(...args);
    },
    sns(...args) {
      return new SnsMessageBindingElement(...args);
    },
    solace(...args) {
      return new SolaceMessageBindingElement(...args);
    },
    sqs(...args) {
      return new SqsMessageBindingElement(...args);
    },
    stomp(...args) {
      return new StompMessageBindingElement(...args);
    },
    redis(...args) {
      return new RedisMessageBindingElement(...args);
    },
    mercure(...args) {
      return new MercureMessageBindingElement(...args);
    },
    ibmmq(...args) {
      return new IbmmqMessageBindingElement(...args);
    },
    googlepubsub(...args) {
      return new GooglepubsubMessageBindingElement(...args);
    },
    pulsar(...args) {
      return new PulsarMessageBindingElement(...args);
    }
  },
  MessageElement: {
    headers(...args) {
      return new SchemaElement(...args);
    },
    correlationId(...args) {
      return new CorrelationIDElement(...args);
    },
    tags(...args) {
      return new TagsElement(...args);
    },
    externalDocs(...args) {
      return new ExternalDocumentationElement(...args);
    },
    bindings(...args) {
      return new MessageBindingsElement(...args);
    },
    examples(...args) {
      return new MessageExamplesElement(...args);
    },
    traits(...args) {
      return new MessageTraitsElement(...args);
    },
    payload(...args) {
      return new SchemaElement(...args);
    }
  },
  MessageTraitElement: {
    headers(...args) {
      return new SchemaElement(...args);
    },
    correlationId(...args) {
      return new CorrelationIDElement(...args);
    },
    tags(...args) {
      return new TagsElement(...args);
    },
    externalDocs(...args) {
      return new ExternalDocumentationElement(...args);
    },
    bindings(...args) {
      return new MessageBindingsElement(...args);
    },
    examples(...args) {
      return new MessageExamplesElement(...args);
    }
  },
  MessageExampleElement: {
    headers(...args) {
      return new ObjectElement(...args);
    }
  },
  TagsElement: {
    '<*>': function asterisk(...args) {
      return new TagElement(...args);
    }
  },
  TagElement: {
    externalDocs(...args) {
      return new ExternalDocumentationElement(...args);
    }
  },
  ComponentsElement: {
    schemas(...args) {
      return new ComponentsSchemasElement(...args);
    },
    servers(...args) {
      return new ComponentsServersElement(...args);
    },
    serverVariables(...args) {
      return new ComponentsServerVariablesElement(...args);
    },
    messages(...args) {
      return new ComponentsMessagesElement(...args);
    },
    securitySchemes(...args) {
      return new ComponentsSecuritySchemesElement(...args);
    },
    parameters(...args) {
      return new ComponentsParametersElement(...args);
    },
    correlationIds(...args) {
      return new ComponentsCorrelationIDsElement(...args);
    },
    operationTraits(...args) {
      return new ComponentsOperationTraitsElement(...args);
    },
    messageTraits(...args) {
      return new ComponentsMessageTraitsElement(...args);
    },
    serverBindings(...args) {
      return new ComponentsServerBindingsElement(...args);
    },
    channelBindings(...args) {
      return new ComponentsChannelBindingsElement(...args);
    },
    operationBindings(...args) {
      return new ComponentsOperationBindingsElement(...args);
    },
    messageBindings(...args) {
      return new ComponentsMessageBindingsElement(...args);
    },
    operations(...args) {
      return new ComponentsOperationsElement(...args);
    },
    replies(...args) {
      return new OperationReplyElement(...args);
    },
    replyAddresses(...args) {
      return new OperationReplyAddressElement(...args);
    },
    externalDocs(...args) {
      return new ExternalDocumentationElement(...args);
    },
    tags(...args) {
      return new TagsElement(...args);
    }
  },
  MultiFormatSchemaElement: {
    schema(...args) {
      const {
        context: multiFormatSchemaElement
      } = this;
      const schemaFormat = defaultTo(mediaTypes.latest(), toValue(multiFormatSchemaElement.schemaFormat));
      if (mediaTypes.includes(schemaFormat)) {
        return new SchemaElement(...args);
      }
      return new ObjectElement(...args);
    }
  },
  SchemaElement: {
    allOf(...args) {
      const element = new ArrayElement(...args);
      element.classes.push('json-schema-allOf');
      return element;
    },
    anyOf(...args) {
      const element = new ArrayElement(...args);
      element.classes.push('json-schema-anyOf');
      return element;
    },
    oneOf(...args) {
      const element = new ArrayElement(...args);
      element.classes.push('json-schema-oneOf');
      return element;
    },
    not(...args) {
      return new SchemaElement(...args);
    },
    if(...args) {
      return new SchemaElement(...args);
    },
    then(...args) {
      return new SchemaElement(...args);
    },
    else(...args) {
      return new SchemaElement(...args);
    },
    enum(...args) {
      return new ArrayElement(...args);
    },
    items(...args) {
      return new SchemaElement(...args);
    },
    additionalItems(...args) {
      return new SchemaElement(...args);
    },
    contains(...args) {
      return new SchemaElement(...args);
    },
    required(...args) {
      const element = new ArrayElement(...args);
      element.classes.push('json-schema-required');
      return element;
    },
    properties(...args) {
      const element = new ObjectElement(...args);
      element.classes.push('json-schema-properties');
      return element;
    },
    patternProperties(...args) {
      const element = new ObjectElement(...args);
      element.classes.push('json-schema-patternProperties');
      return element;
    },
    additionalProperties(...args) {
      return new SchemaElement(...args);
    },
    dependencies(...args) {
      const element = new ObjectElement(...args);
      element.classes.push('json-schema-dependencies');
      return element;
    },
    propertyNames(...args) {
      return new SchemaElement(...args);
    },
    examples(...args) {
      const element = new ArrayElement(...args);
      element.classes.push('json-schema-examples');
      return element;
    },
    definitions(...args) {
      const element = new ObjectElement(...args);
      element.classes.push('json-schema-definitions');
      return element;
    },
    externalDocs(...args) {
      return new ExternalDocumentationElement(...args);
    }
  },
  SecuritySchemeElement: {
    flows(...args) {
      return new OAuthFlowsElement(...args);
    },
    scopes(...args) {
      return new ArrayElement(...args);
    }
  },
  OAuthFlowsElement: {
    implicit(...args) {
      return new OAuthFlowElement(...args);
    },
    password(...args) {
      return new OAuthFlowElement(...args);
    },
    clientCredentials(...args) {
      return new OAuthFlowElement(...args);
    },
    authorizationCode(...args) {
      return new OAuthFlowElement(...args);
    }
  },
  OAuthFlowElement: {
    availableScopes(...args) {
      return new SecuritySchemeScopesElement(...args);
    }
  },
  HttpOperationBindingElement: {
    query(...args) {
      return new SchemaElement(...args);
    }
  },
  HttpMessageBindingElement: {
    headers(...args) {
      return new SchemaElement(...args);
    }
  },
  WebSocketChannelBindingElement: {
    query(...args) {
      return new SchemaElement(...args);
    },
    headers(...args) {
      return new SchemaElement(...args);
    }
  },
  KafkaOperationBindingElement: {
    groupId(...args) {
      return new SchemaElement(...args);
    },
    clientId(...args) {
      return new SchemaElement(...args);
    }
  },
  KafkaChannelBindingElement: {
    topicConfiguration(...args) {
      return new ObjectElement(...args);
    }
  },
  KafkaMessageBindingElement: {
    key(...args) {
      return new SchemaElement(...args);
    }
  },
  AnypointmqMessageBindingElement: {
    headers(...args) {
      return new SchemaElement(...args);
    }
  },
  JmsServerBindingElement: {
    properties(...args) {
      return new ArrayElement(...args);
    }
  },
  JmsMessageBindingElement: {
    headers(...args) {
      return new SchemaElement(...args);
    }
  },
  AmqpChannelBindingElement: {
    exchange(...args) {
      return new ObjectElement(...args);
    },
    queue(...args) {
      return new ObjectElement(...args);
    }
  },
  AmqpOperationBindingElement: {
    cc(...args) {
      return new ArrayElement(...args);
    },
    bcc(...args) {
      return new ArrayElement(...args);
    }
  },
  IbmmqChannelBindingElement: {
    queue(...args) {
      return new ObjectElement(...args);
    },
    topic(...args) {
      return new ObjectElement(...args);
    }
  },
  MqttServerBindingElement: {
    lastWill(...args) {
      return new ObjectElement(...args);
    },
    sessionExpiryInterval(...args) {
      return new SchemaElement(...args);
    },
    maximumPacketSize(...args) {
      return new SchemaElement(...args);
    }
  },
  MqttOperationBindingElement: {
    messageExpiryInterval(...args) {
      return new SchemaElement(...args);
    }
  },
  MqttMessageBindingElement: {
    correlationData(...args) {
      return new SchemaElement(...args);
    },
    responseTopic(...args) {
      return new SchemaElement(...args);
    }
  },
  Mqtt5ServerBindingElement: {
    sessionExpiryInterval(...args) {
      return new SchemaElement(...args);
    }
  },
  SolaceOperationBindingElement: {
    destinations(...args) {
      return new ArrayElement(...args);
    },
    timeToLive(...args) {
      return new SchemaElement(...args);
    },
    priority(...args) {
      return new SchemaElement(...args);
    }
  },
  SqsChannelBindingElement: {
    queue(...args) {
      return new ObjectElement(...args);
    },
    deadLetterQueue(...args) {
      return new ObjectElement(...args);
    }
  },
  SqsOperationBindingElement: {
    queues(...args) {
      return new ArrayElement(...args);
    }
  },
  GooglepubsubChannelBindingElement: {
    labels(...args) {
      return new ObjectElement(...args);
    },
    messageStoragePolicy(...args) {
      return new ObjectElement(...args);
    },
    schemaSettings(...args) {
      return new ObjectElement(...args);
    }
  },
  GooglepubsubMessageBindingElement: {
    attributes(...args) {
      return new ObjectElement(...args);
    },
    schema(...args) {
      return new ObjectElement(...args);
    }
  },
  SnsChannelBindingElement: {
    ordering(...args) {
      return new ObjectElement(...args);
    },
    policy(...args) {
      return new ObjectElement(...args);
    },
    tags(...args) {
      return new ObjectElement(...args);
    }
  },
  SnsOperationBindingElement: {
    topic(...args) {
      return new ObjectElement(...args);
    },
    consumers(...args) {
      return new ArrayElement(...args);
    },
    deliveryPolicy(...args) {
      return new ObjectElement(...args);
    }
  },
  PulsarChannelBindingElement: {
    'geo-replication': function geoReplication(...args) {
      return new ArrayElement(...args);
    },
    retention(...args) {
      return new ObjectElement(...args);
    }
  },
  [ComponentsSchemasElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new SchemaElement(...args);
    }
  },
  [ComponentsServersElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new ServerElement(...args);
    }
  },
  [ComponentsServerVariablesElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new ServerVariableElement(...args);
    }
  },
  [ComponentsMessagesElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new MessageElement(...args);
    }
  },
  [ComponentsSecuritySchemesElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new SecuritySchemeElement(...args);
    }
  },
  [ComponentsParametersElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new ParameterElement(...args);
    }
  },
  [ComponentsCorrelationIDsElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new CorrelationIDElement(...args);
    }
  },
  [ComponentsOperationTraitsElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new OperationTraitElement(...args);
    }
  },
  [ComponentsMessageTraitsElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new MessageTraitElement(...args);
    }
  },
  [ComponentsServerBindingsElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new ServerBindingsElement(...args);
    }
  },
  [ComponentsChannelBindingsElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new ChannelBindingsElement(...args);
    }
  },
  [ComponentsOperationBindingsElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new OperationBindingsElement(...args);
    }
  },
  [ComponentsOperationsElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new OperationBindingsElement(...args);
    }
  },
  [ComponentsMessageBindingsElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new MessageBindingsElement(...args);
    }
  },
  [ComponentsOperationsElement.primaryClass]: {
    '<*>': function asterisk(...args) {
      return new OperationElement(...args);
    }
  },
  [ServerVariablesElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new ServerVariableElement(...args);
    }
  },
  [ServerSecurityElement.primaryClass]: {
    '<*>': function asterisk(...args) {
      return new SecuritySchemeElement(...args);
    }
  },
  [OperationTraitsElement.primaryClass]: {
    '<*>': function asterisk(...args) {
      return new OperationTraitElement(...args);
    }
  },
  [OperationSecurityElement.primaryClass]: {
    '<*>': function asterisk(...args) {
      return new SecuritySchemeElement(...args);
    }
  },
  [OperationMessagesElement.primaryClass]: {
    '<*>': function asterisk(...args) {
      return new ReferenceElement(...args);
    }
  },
  [OperationReplyMessagesElement.primaryClass]: {
    '<*>': function asterisk(...args) {
      return new ReferenceElement(...args);
    }
  },
  [MessageExamplesElement.primaryClass]: {
    '<*>': function asterisk(...args) {
      return new MessageExampleElement(...args);
    }
  },
  [MessageTraitsElement.primaryClass]: {
    '<*>': function asterisk(...args) {
      return new MessageTraitElement(...args);
    }
  },
  [MessageTraitExamplesElement.primaryClass]: {
    '<*>': function asterisk(...args) {
      return new MessageExampleElement(...args);
    }
  },
  [ChannelServersElement.primaryClass]: {
    '<*>': function asterisk(...args) {
      return new ReferenceElement(...args);
    }
  },
  [ComponentsRepliesElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new OperationReplyElement(...args);
    }
  },
  [ComponentsReplyAddressesElement.primaryClass]: {
    '[key: *]': function key(...args) {
      return new OperationReplyAddressElement(...args);
    }
  },
  'json-schema-properties': {
    '[key: *]': function key(...args) {
      return new SchemaElement(...args);
    }
  },
  'json-schema-allOf': {
    '<*>': function asterisk(...args) {
      return new SchemaElement(...args);
    }
  },
  'json-schema-anyOf': {
    '<*>': function asterisk(...args) {
      return new SchemaElement(...args);
    }
  },
  'json-schema-oneOf': {
    '<*>': function asterisk(...args) {
      return new SchemaElement(...args);
    }
  }
};
const findElementFactory = (ancestor, keyName) => {
  const elementType = getNodeType(ancestor);
  const keyMapping = schema[elementType !== null && elementType !== void 0 ? elementType : ''] || schema[toValue(ancestor.classes.first)];
  if (keyMapping == null || typeof keyMapping !== 'object') {
    return undefined;
  }
  return Object.prototype.hasOwnProperty.call(keyMapping, '[key: *]') ? keyMapping['[key: *]'] : keyMapping[keyName];
};

/**
 * @public
 */
const plugin = () => () => ({
  visitor: {
    StringElement(element, key, parent, path, ancestors) {
      if (!isEmptyElement(element)) return undefined;
      const lineage = [...ancestors, parent].filter(isElement);
      const parentElement = lineage.at(-1);
      let elementFactory;
      let context;
      if (isArrayElement(parentElement)) {
        context = element;
        elementFactory = findElementFactory(parentElement, '<*>');
      } else if (isMemberElement(parentElement)) {
        context = lineage.at(-2);
        elementFactory = findElementFactory(context, toValue(parentElement.key));
      }

      // no element factory found
      if (typeof elementFactory !== 'function') return undefined;
      const result = elementFactory.call({
        context
      }, undefined, cloneDeep(element.meta), cloneDeep(element.attributes));
      return assignSourceMap(result, element);
    }
  }
});
export default plugin;