<!--
/*
 *  Copyright (c) 2015-present, Jim Kynde Meyer
 *  All rights reserved.
 *
 *  This source code is licensed under the MIT license found in the
 *  LICENSE file in the root directory of this source tree.
 */
-->
<idea-plugin require-restart="true" package="com.intellij.lang.jsgraphql" allow-bundled-update="true">
  <id>com.intellij.lang.jsgraphql</id>
  <name>GraphQL</name>
  <vendor>JetBrains</vendor>
  <category>Languages</category>

  <description><![CDATA[
      <p>Provides <a href="https://graphql.org/">GraphQL</a> language support
      to all JetBrains IDEs that <a href="https://www.jetbrains.com/products/#lang=js&type=ide">support JavaScript</a>.</p>

      <h2>Features</h2>
      <ul>
        <li>Schema-aware completion, error highlighting, and documentation</li>
        <li>Syntax highlighting, code-formatting, folding, commenting, and brace-matching</li>
        <li>Execution of queries and mutations with variables against configurable endpoints</li>
        <li>Support for multiple schemas using <code>graphql-config</code></li>
      </ul>

      <h2>Getting started</h2>
      <p>For information on getting started with this plugin in IntelliJ-based IDEs,
      see the <a href="https://www.jetbrains.com/help/webstorm/graphql.html">documentation</a>.</p>
    ]]>
  </description>

  <dependencies>
    <plugin id="com.intellij.modules.lang"/>
    <module name="intellij.spellchecker"/>
    <module name="intellij.json.backend"/>
  </dependencies>

  <content>
    <module name="intellij.graphql.javascript"/>
    <module name="intellij.graphql.langInjection"/>
    <module name="intellij.graphql.yaml"/>
  </content>

  <resource-bundle>messages.GraphQLBundle</resource-bundle>

  <extensionPoints>
    <extensionPoint name="fileTypeContributor" dynamic="true"
                    interface="com.intellij.lang.jsgraphql.ide.injection.GraphQLFileTypeContributor"/>
    <extensionPoint name="injectedLanguage" dynamic="true"
                    interface="com.intellij.lang.jsgraphql.ide.injection.GraphQLInjectedLanguage"/>
    <extensionPoint name="errorFilter" dynamic="true"
                    interface="com.intellij.lang.jsgraphql.ide.validation.GraphQLErrorFilter"/>
    <extensionPoint name="configContributor" dynamic="true"
                    interface="com.intellij.lang.jsgraphql.ide.config.GraphQLConfigContributor"/>
    <extensionPoint name="configCustomLoader" dynamic="true"
                    interface="com.intellij.lang.jsgraphql.ide.config.loader.GraphQLConfigCustomLoader"/>
    <extensionPoint name="configSearchCustomizer" dynamic="true"
                    interface="com.intellij.lang.jsgraphql.ide.config.GraphQLConfigSearchCustomizer"/>
    <extensionPoint name="globalResolveFilter" dynamic="true"
                    interface="com.intellij.lang.jsgraphql.ide.resolve.GraphQLGlobalResolveFilter"/>
  </extensionPoints>

  <extensions defaultExtensionNs="com.intellij">
    <dependencySupport kind="javascript" coordinate="npm:graphql" displayName="GraphQL"/>

    <!-- Color scheme -->
    <additionalTextAttributes scheme="Default" file="colorSchemes/GraphQLLanguageDefault.xml"/>
    <additionalTextAttributes scheme="Darcula" file="colorSchemes/GraphQLLanguageDarcula.xml"/>
    <additionalTextAttributes scheme="Monokai" file="colorSchemes/GraphQLLanguageMonokai.xml"/>

    <!-- Language registration -->
    <fileType name="GraphQL" implementationClass="com.intellij.lang.jsgraphql.GraphQLFileType" fieldName="INSTANCE"
              language="GraphQL" extensions="gql;graphql;graphqls"/>
    <fileType name="JSON" extensions="graphqlconfig;graphqlrc"/>
    <lang.substitutor language="JSON"
                      implementationClass="com.intellij.lang.jsgraphql.ide.config.fileType.GraphQLConfigLanguageSubstitutor"/>

    <lang.parserDefinition language="GraphQL"
                           implementationClass="com.intellij.lang.jsgraphql.GraphQLParserDefinition"/>
    <lang.fileViewProviderFactory language="GraphQL"
                                  implementationClass="com.intellij.lang.jsgraphql.psi.GraphQLFileViewProviderFactory"/>
    <lang.fileViewProviderFactory language="JSON"
                                  implementationClass="com.intellij.lang.jsgraphql.psi.JsonFileViewProviderFactory"/>

    <!-- File templates -->
    <internalFileTemplate name="GraphQL File"/>

    <!-- Icons -->
    <iconProvider implementation="com.intellij.lang.jsgraphql.icons.GraphQLIconProvider"/>

    <!-- Project services -->
    <projectService serviceImplementation="com.intellij.lang.jsgraphql.ide.search.GraphQLPsiSearchHelper"/>
    <projectService serviceImplementation="com.intellij.lang.jsgraphql.ide.resolve.GraphQLReferenceService"/>
    <projectService
      serviceImplementation="com.intellij.lang.jsgraphql.ui.GraphQLUIProjectService"/>
    <projectService serviceImplementation="com.intellij.lang.jsgraphql.schema.library.GraphQLLibraryManager"/>

    <!-- Sources -->
    <generatedSourcesFilter implementation="com.intellij.lang.jsgraphql.ide.project.model.GraphQLIntrospectionSourcesFilter"/>
    <writingAccessProvider implementation="com.intellij.lang.jsgraphql.ide.project.model.GraphQLIntrospectionWritingAccessProvider"/>

    <!-- Indexing -->
    <fileBasedIndex implementation="com.intellij.lang.jsgraphql.ide.indexing.GraphQLIdentifierIndex"/>
    <fileBasedIndex implementation="com.intellij.lang.jsgraphql.ide.indexing.GraphQLFragmentNameIndex"/>
    <fileBasedIndex implementation="com.intellij.lang.jsgraphql.ide.indexing.GraphQLInjectionIndex"/>

    <workspaceModel.fileIndexContributor implementation="com.intellij.lang.jsgraphql.schema.library.GraphQLLibraryIndexContributor"/>
    <projectView.externalLibraries.workspaceModelNodesProvider
      implementation="com.intellij.lang.jsgraphql.schema.library.GraphQLLibraryWorkspaceModelNodesProvider"/>

    <indexedRootsProvider
      implementation="com.intellij.lang.jsgraphql.ide.introspection.indexing.GraphQLIntrospectionIndexableSetContributor"/>

    <!-- Startup -->
    <postStartupActivity implementation="com.intellij.lang.jsgraphql.ide.startup.GraphQLStartupActivity"/>

    <!-- Syntax and error highlighting -->
    <lang.syntaxHighlighterFactory language="GraphQL"
                                   implementationClass="com.intellij.lang.jsgraphql.ide.highlighting.GraphQLSyntaxHighlighterFactory"/>
    <annotator language="GraphQL"
               implementationClass="com.intellij.lang.jsgraphql.ide.highlighting.GraphQLSyntaxAnnotator"
               order="first"/>
    <annotator language="GraphQL"
               implementationClass="com.intellij.lang.jsgraphql.ide.validation.GraphQLValidationAnnotator"/>
    <annotator language="GraphQL"
               implementationClass="com.intellij.lang.jsgraphql.ide.validation.GraphQLSchemaAnnotator"/>
    <colorSettingsPage implementation="com.intellij.lang.jsgraphql.ide.highlighting.GraphQLColorSettingsPage"/>
    <daemon.highlightInfoFilter implementation="com.intellij.lang.jsgraphql.ide.highlighting.GraphQLInjectionHighlightInfoFilter"/>

    <!-- Formatting and folding -->
    <lang.formatter language="GraphQL"
                    implementationClass="com.intellij.lang.jsgraphql.ide.formatter.GraphQLFormattingModelBuilder"/>
    <langCodeStyleSettingsProvider
      implementation="com.intellij.lang.jsgraphql.ide.formatter.GraphQLLanguageCodeStyleSettingsProvider"/>
    <lang.foldingBuilder language="GraphQL"
                         implementationClass="com.intellij.lang.jsgraphql.ide.editor.GraphQLFoldingBuilder"/>

    <!-- Editing -->
    <lang.braceMatcher language="GraphQL"
                       implementationClass="com.intellij.lang.jsgraphql.ide.editor.GraphQLBraceMatcher"/>
    <lang.quoteHandler language="GraphQL"
                       implementationClass="com.intellij.lang.jsgraphql.ide.editor.GraphQLQuoteHandler"/>
    <lang.commenter language="GraphQL" implementationClass="com.intellij.lang.jsgraphql.ide.editor.GraphQLCommenter"/>
    <enterBetweenBracesDelegate language="GraphQL"
                                implementationClass="com.intellij.lang.jsgraphql.ide.formatter.GraphQLEnterBetweenBracesHandler"/>
    <typedHandler implementation="com.intellij.lang.jsgraphql.ide.editor.GraphQLTypedHandlerDelegate"/>

    <!-- Notifications -->
    <editorNotificationProvider
      implementation="com.intellij.lang.jsgraphql.ide.introspection.source.GraphQLGeneratedSourcesEditorNotificationProvider"/>
    <editorNotificationProvider
      implementation="com.intellij.lang.jsgraphql.ide.config.migration.GraphQLMigrateLegacyConfigEditorNotificationProvider"/>
    <editorNotificationProvider implementation="com.intellij.lang.jsgraphql.ide.config.GraphQLConfigStatusEditorNotificationProvider"/>

    <!-- Completion -->
    <lookup.charFilter implementation="com.intellij.lang.jsgraphql.ide.completion.GraphQLCharFilter"/>

    <completion.contributor language="GraphQL"
                            implementationClass="com.intellij.lang.jsgraphql.ide.completion.GraphQLCompletionContributor"/>

    <!-- Find usages and renaming refactors -->
    <lang.findUsagesProvider language="GraphQL"
                             implementationClass="com.intellij.lang.jsgraphql.ide.findUsages.GraphQLFindUsagesProvider"/>
    <usageTypeProvider implementation="com.intellij.lang.jsgraphql.ide.findUsages.GraphQLUsageTypeProvider"/>
    <lang.elementManipulator forClass="com.intellij.lang.jsgraphql.psi.impl.GraphQLIdentifierImpl"
                             implementationClass="com.intellij.lang.jsgraphql.ide.resolve.GraphQLIdentifierManipulator"/>

    <!-- Search (find implementations etc.) -->
    <definitionsSearch implementation="com.intellij.lang.jsgraphql.ide.search.GraphQLDefinitionsSearchExecutor"/>

    <!-- Settings -->
    <projectConfigurable id="settings.jsgraphql" groupId="language"
                         instance="com.intellij.lang.jsgraphql.ui.GraphQLSettingsConfigurable"
                         bundle="messages.GraphQLBundle" key="graphql"/>

    <!-- Introspection -->
    <codeInsight.lineMarkerProvider
      implementationClass="com.intellij.lang.jsgraphql.ide.introspection.GraphQLIntrospectionJsonToSDLLineMarkerProvider"
      language="JSON"/>
    <codeInsight.lineMarkerProvider
      implementationClass="com.intellij.lang.jsgraphql.ide.introspection.editor.json.GraphQLIntrospectionJsonLineMarkerProvider"
      language="JSON"/>
    <projectViewNestingRulesProvider
      implementation="com.intellij.lang.jsgraphql.ide.project.GraphQLIntrospectionProjectViewNestingRulesProvider"/>
    <editorTabTitleProvider
      implementation="com.intellij.lang.jsgraphql.ide.introspection.GraphQLIntrospectionEditorTabTitleProvider"/>

    <!-- Tool window -->
    <toolWindow id="GraphQL" factoryClass="com.intellij.lang.jsgraphql.ide.project.toolwindow.GraphQLToolWindow"
                anchor="bottom" icon="com.intellij.lang.jsgraphql.icons.GraphQLIcons.UI.GraphQLToolWindow"/>

    <!-- Spellchecking and to-do view-->
    <spellchecker.support language="GraphQL"
                          implementationClass="com.intellij.lang.jsgraphql.ide.spellchecking.GraphQLSpellcheckingStrategy"/>

    <!-- Language -->
    <lang.psiStructureViewFactory language="GraphQL"
                                  implementationClass="com.intellij.lang.jsgraphql.ide.structureView.GraphQLPsiStructureViewFactory"/>

    <!-- Error highlighting and annotations -->
    <daemon.changeLocalityDetector order="first"
                                   implementation="com.intellij.lang.jsgraphql.ide.validation.GraphQLChangeLocalityDetector"/>

    <!-- Query context highlighter -->
    <!--<highlightVisitor implementation="com.intellij.lang.jsgraphql.ide.highlighting.query.GraphQLQueryContextHighlightVisitor"/>-->

    <!-- Schema documentation -->
    <lang.documentationProvider language="GraphQL"
                                implementationClass="com.intellij.lang.jsgraphql.ide.documentation.GraphQLDocumentationProvider"/>

    <!-- Note: JSX/TSX documentation providers are registered in their base language (JS), so we do the same to not take over the entire doc impl -->
    <lang.documentationProvider language="JavaScript"
                                implementationClass="com.intellij.lang.jsgraphql.ide.documentation.GraphQLDocumentationProvider"/>

    <!-- Query execution (see com.intellij.openapi.actionSystem.IdeActions.ACTION_EDITOR_SPLIT which is ctrl+enter by default) -->
    <editorActionHandler action="EditorSplitLine"
                         implementationClass="com.intellij.lang.jsgraphql.ide.actions.GraphQLExecuteEditorActionHandler"
                         order="first"/>
    <highlightErrorFilter
      implementation="com.intellij.lang.jsgraphql.ide.highlighting.GraphQLVariablesHighlightErrorFilter"/>

    <!-- Keys -->
    <registryKey key="graphql.request.timeout" defaultValue="15000" description="GraphQL request timeout"/>
    <registryKey key="graphql.request.connect.timeout" defaultValue="5000" description="GraphQL request connection timeout"/>
    <registryKey key="graphql.config.scope.module.libraries" defaultValue="true"
                 description="GraphQL search for definitions in module libraries"/>
    <registryKey key="graphql.schema.build.timeout" defaultValue="500" description="GraphQL schema build timeout in ms"/>
    <registryKey key="graphql.schema.size.definitions.limit" defaultValue="4000"
                 description="A limit on the total number of type definitions in a GraphQL schema"/>
    <registryKey key="graphql.error.validation.for.complex.schemas" defaultValue="true"
                 description="Enables validation of GraphQL schemas that contain a large number of type definitions"/>
    <registryKey key="graphql.introspection.custom.query"
                 defaultValue=""
                 description="Defines a custom query for server introspection, overriding the default behavior"/>
    <registryKey key="graphql.schema.reformat.timeout" defaultValue="3000"
                 description="The maximum allowed time to wait for the GraphQL schema to be reformatted, in milliseconds"/>
    <registryKey key="graphql.schema.reformat.line.count.threshold" defaultValue="80000"
                 description="The maximum number of lines in a GraphQL schema that will be reformatted"/>

    <advancedSetting id="graphql.introspection.detect.schema.capabilities" default="ADAPTIVE"
                     enumClass="com.intellij.lang.jsgraphql.ide.introspection.GraphQLSchemaCapabilitiesDetectionStrategy"
                     groupKey="group.advanced.settings.graphql" bundle="messages.GraphQLBundle"
                     descriptionKey="advanced.setting.graphql.introspection.detect.schema.capabilities.description"/>
    <advancedSetting id="graphql.introspection.skip.default.values" default="false"
                     groupKey="group.advanced.settings.graphql" bundle="messages.GraphQLBundle"
                     descriptionKey="advanced.setting.graphql.introspection.skip.default.values.description"/>
    <advancedSetting id="graphql.introspection.include.empty.types" default="true"
                     groupKey="group.advanced.settings.graphql" bundle="messages.GraphQLBundle"/>

    <!-- Inspections -->
    <localInspection language="GraphQL" key="graphql.inspection.display.name.unresolved.reference"
                     enabledByDefault="true"
                     groupKey="graphql.inspection.group.general" groupPathKey="graphql" unfair="true" level="ERROR"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLUnresolvedReferenceInspection"/>
    <localInspection language="GraphQL" key="graphql.inspection.display.name.deprecated.symbols"
                     enabledByDefault="true"
                     groupKey="graphql.inspection.group.general" groupPathKey="graphql" level="WEAK WARNING"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLDeprecatedSymbolsInspection"/>

    <!-- Schema inspections -->
    <localInspection language="GraphQL" key="graphql.inspection.display.name.schema.validation" enabledByDefault="true"
                     groupKey="graphql.inspection.group.schema" groupPathKey="graphql" unfair="true" level="ERROR"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLSchemaValidationInspection"/>
    <localInspection language="GraphQL" key="graphql.inspection.display.name.type.redefinition" enabledByDefault="true"
                     groupKey="graphql.inspection.group.schema" groupPathKey="graphql" unfair="true" level="ERROR"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLTypeRedefinitionInspection"/>
    <localInspection language="GraphQL" key="graphql.inspection.display.name.unexpected.type" enabledByDefault="true"
                     groupKey="graphql.inspection.group.schema" groupPathKey="graphql" unfair="true" level="ERROR"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLUnexpectedTypeInspection"/>
    <localInspection language="GraphQL" key="graphql.inspection.display.name.member.redefinition"
                     enabledByDefault="true"
                     groupKey="graphql.inspection.group.schema" groupPathKey="graphql" unfair="true" level="ERROR"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLMemberRedefinitionInspection"/>
    <localInspection language="GraphQL" key="graphql.inspection.display.name.illegal.name" enabledByDefault="true"
                     groupKey="graphql.inspection.group.schema" groupPathKey="graphql" unfair="true" level="ERROR"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLIllegalNameInspection"/>
    <localInspection language="GraphQL" key="graphql.inspection.display.name.empty.type" enabledByDefault="true"
                     groupKey="graphql.inspection.group.schema" groupPathKey="graphql" unfair="true" level="ERROR"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLEmptyTypeInspection"/>
    <localInspection language="GraphQL" key="graphql.inspection.display.name.duplicate.argument" enabledByDefault="true"
                     groupKey="graphql.inspection.group.schema" groupPathKey="graphql" unfair="true" level="ERROR"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLDuplicateArgumentInspection"/>
    <localInspection language="GraphQL" key="graphql.inspection.display.name.interface.implementation"
                     enabledByDefault="true"
                     groupKey="graphql.inspection.group.schema" groupPathKey="graphql" unfair="true" level="ERROR"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLInterfaceImplementationInspection"/>
    <localInspection language="GraphQL" key="graphql.inspection.display.name.duplicate.directive"
                     enabledByDefault="true"
                     groupKey="graphql.inspection.group.schema" groupPathKey="graphql" unfair="true" level="ERROR"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLDuplicateDirectiveInspection"/>
    <localInspection language="GraphQL" key="graphql.inspection.display.name.missing.type" enabledByDefault="true"
                     groupKey="graphql.inspection.group.schema" groupPathKey="graphql" unfair="true" level="ERROR"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLMissingTypeInspection"/>
    <localInspection language="GraphQL" key="graphql.inspection.display.name.illegal.directive.argument"
                     enabledByDefault="true"
                     groupKey="graphql.inspection.group.schema" groupPathKey="graphql" unfair="true" level="ERROR"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLIllegalDirectiveArgumentInspection"/>
    <localInspection language="GraphQL" key="graphql.inspection.display.name.invalid.directive.location"
                     enabledByDefault="true"
                     groupKey="graphql.inspection.group.schema" groupPathKey="graphql" unfair="true" level="ERROR"
                     implementationClass="com.intellij.lang.jsgraphql.ide.validation.inspections.GraphQLInvalidDirectiveLocationInspection"/>

    <lang.inspectionSuppressor language="GraphQL"
                               implementationClass="com.intellij.lang.jsgraphql.ide.validation.GraphQLInspectionSuppressor"/>

    <microservices.endpointsProvider implementation="com.intellij.lang.jsgraphql.ide.microservices.GraphQLEndpointsProvider"/>
  </extensions>

  <extensions defaultExtensionNs="JavaScript">
    <JsonSchema.ProviderFactory
      implementation="com.intellij.lang.jsgraphql.ide.config.jsonSchema.GraphQLConfigJsonSchemaProvider"/>
  </extensions>

  <extensions defaultExtensionNs="com.intellij.lang.jsgraphql">
    <errorFilter implementation="com.intellij.lang.jsgraphql.ide.validation.GraphQLGeneralErrorFilter"/>
    <errorFilter implementation="com.intellij.lang.jsgraphql.frameworks.relay.GraphQLRelayErrorFilter"/>
    <errorFilter implementation="com.intellij.lang.jsgraphql.frameworks.apollo.GraphQLApolloErrorFilter"/>
    <errorFilter implementation="com.intellij.lang.jsgraphql.frameworks.federation.GraphQLFederationErrorFilter"/>

    <fileTypeContributor implementation="com.intellij.lang.jsgraphql.ide.injection.GraphQLDefaultFileTypeContributor"/>

    <configSearchCustomizer implementation="com.intellij.lang.jsgraphql.frameworks.gatsby.GraphQLGatsbyConfigSearchCustomizer"/>
  </extensions>

  <actions>
    <action id="GraphQLNewFileAction" class="com.intellij.lang.jsgraphql.ide.actions.GraphQLNewFileAction"
            icon="com.intellij.lang.jsgraphql.icons.GraphQLIcons.Files.GraphQL">
      <add-to-group group-id="NewWebDevelopment"/>
    </action>

    <action id="GraphQLCreateConfigFile" class="com.intellij.lang.jsgraphql.ide.actions.GraphQLCreateConfigFileAction"
            icon="com.intellij.lang.jsgraphql.icons.GraphQLIcons.Files.GraphQLConfig">
      <add-to-group group-id="NewWebDevelopment"/>
    </action>

    <action id="GraphQLExecuteEditor" class="com.intellij.lang.jsgraphql.ide.actions.GraphQLExecuteEditorAction"
            icon="com.intellij.icons.AllIcons.Actions.Execute">
      <keyboard-shortcut first-keystroke="control ENTER" keymap="$default"/>
      <keyboard-shortcut first-keystroke="meta ENTER" keymap="Mac OS X"/>
      <keyboard-shortcut first-keystroke="meta ENTER" keymap="Mac OS X 10.5+"/>
    </action>

    <action id="GraphQLRerunLatestIntrospection"
            class="com.intellij.lang.jsgraphql.ide.introspection.GraphQLRerunLatestIntrospectionAction"
            icon="com.intellij.icons.AllIcons.Actions.Rerun"/>

    <action id="GraphQLRestartSchemaDiscovery"
            class="com.intellij.lang.jsgraphql.ide.actions.GraphQLRestartSchemaDiscoveryAction"
            icon="com.intellij.icons.AllIcons.Actions.Restart"/>

    <action id="GraphQLMigrateLegacyConfig"
            class="com.intellij.lang.jsgraphql.ide.config.migration.GraphQLMigrateLegacyConfigAction"/>

    <action id="GraphQLEditEnvironmentVariables"
            class="com.intellij.lang.jsgraphql.ide.config.env.GraphQLEditEnvironmentVariablesAction"
            icon="com.intellij.icons.AllIcons.Actions.Properties">
      <add-to-group group-id="EditorPopupMenu" anchor="last"/>
    </action>
  </actions>

</idea-plugin>
