{
  "name": "GraphQL",
  "scopeName": "source.graphql",
  "fileTypes": ["graphql", "graphqls", "gql", "graphcool"],
  "patterns": [{ "include": "#graphql" }],
  "repository": {
    "graphql": {
      "patterns": [
        { "include": "#graphql-fragment-definition" },
        { "include": "#graphql-type-interface" },
        { "include": "#graphql-enum" },
        { "include": "#graphql-scalar" },
        { "include": "#graphql-union" },
        { "include": "#graphql-schema" },
        { "include": "#graphql-operation-def" },
        { "include": "#graphql-comment" },
        { "include": "#literal-quasi-embedded" }
      ]
    },
    "graphql-operation-def": {
      "patterns": [
        { "include": "#graphql-query-mutation-subscription" },
        { "include": "#graphql-directive-definition" },
        { "include": "#graphql-name" },
        { "include": "#graphql-variable-definitions" },
        { "include": "#graphql-directive" },
        { "include": "#graphql-selection-set" }
      ]
    },
    "graphql-fragment-definition": {
      "name": "meta.fragment.graphql",
      "begin": "\\s*(?:(\\bfragment\\b)\\s*([_A-Za-z][_0-9A-Za-z]*)?\\s*(?:(\\bon\\b)\\s*([_A-Za-z][_0-9A-Za-z]*)))",
      "end": "(?<=})",
      "captures": {
        "1": { "name": "keyword.fragment.graphql" },
        "2": { "name": "entity.name.fragment.graphql" },
        "3": { "name": "keyword.on.graphql" },
        "4": { "name": "support.type.graphql" }
      },
      "patterns": [
        { "include": "#graphql-comment" },
        { "include": "#graphql-selection-set" },
        { "include": "#graphql-directive" },
        { "include": "#graphql-skip-newlines" },
        { "include": "#literal-quasi-embedded" }
      ]
    },
    "graphql-query-mutation-subscription": {
      "match": "\\s*\\b(query|mutation|subscription)\\b",
      "captures": {
        "1": { "name": "keyword.operation.graphql" }
      }
    },
    "graphql-type-interface": {
      "name": "meta.type.interface.graphql",
      "begin": "\\s*\\b(?:(extend)?\\b\\s*\\b(type)|(interface)|(input))\\b\\s*([_A-Za-z][_0-9A-Za-z]*)?",
      "end": "(?<=})",
      "captures": {
        "1": { "name": "keyword.extend.graphql" },
        "2": { "name": "keyword.type.graphql" },
        "3": { "name": "keyword.interface.graphql" },
        "4": { "name": "keyword.input.graphql" },
        "5": { "name": "support.type.graphql" }
      },
      "patterns": [
        {
          "begin": "\\s*\\b(implements)\\b\\s*",
          "end": "\\s*(?=[{@])",
          "beginCaptures": {
            "1": { "name": "keyword.implements.graphql.RRR" }
          },
          "patterns": [
            {
              "match": "\\s*([_A-Za-z][_0-9A-Za-z]*)",
              "captures": {
                "1": { "name": "support.type.graphql.XXX" }
              }
            },
            { "include": "#graphql-comma" }
          ]
        },
        { "include": "#graphql-directive" },
        { "include": "#graphql-comment" },
        { "include": "#graphql-type-object" },
        { "include": "#literal-quasi-embedded" }
      ]
    },
    "graphql-type-object": {
      "name": "meta.type.object.graphql",
      "begin": "\\s*({)",
      "end": "\\s*(})",
      "beginCaptures": {
        "1": { "name": "punctuation.operation.graphql" }
      },
      "endCaptures": {
        "1": { "name": "punctuation.operation.graphql" }
      },
      "patterns": [
        { "include": "#graphql-object-type" },

        { "include": "#graphql-comment" },
        { "include": "#graphql-type-definition" },
        { "include": "#literal-quasi-embedded" }
      ]
    },
    "graphql-type-definition": {
      "comment": "key (optionalArgs): Type",
      "begin": "\\s*([_A-Za-z][_0-9A-Za-z]*)(?=\\s*\\(|:)",
      "end": "(?=\\s*(([_A-Za-z][_0-9A-Za-z]*)\\s*(\\(|:)|(})))|\\s*(,)",
      "beginCaptures": {
        "1": { "name": "variable.graphql" }
      },
      "endCaptures": {
        "5": { "name": "punctuation.comma.graphql" }
      },
      "patterns": [
        { "include": "#graphql-comment" },
        { "include": "#graphql-variable-definitions" },
        { "include": "#graphql-type-object" },
        { "include": "#graphql-colon" },
        { "include": "#graphql-input-types" },
        { "include": "#graphql-directive" },
        { "include": "#literal-quasi-embedded" }
      ]
    },
    "graphql-schema": {
      "begin": "\\s*\\b(extend)?\\b\\s*\\b(schema)\\b",
      "end": "\\s*(?!\\s|#|{|@|$)",
      "beginCaptures": {
        "1": { "name": "keyword.extend.graphql" },
        "2": { "name": "keyword.schema.graphql" }
      },
      "patterns": [
        {
          "begin": "\\s*({)",
          "end": "\\s*(})",
          "beginCaptures": {
            "1": { "name": "punctuation.operation.graphql" }
          },
          "endCaptures": {
            "1": { "name": "punctuation.operation.graphql" }
          },
          "patterns": [
            {
              "begin": "\\s*([_A-Za-z][_0-9A-Za-z]*)(?=\\s*\\(|:)",
              "end": "(?=\\s*(([_A-Za-z][_0-9A-Za-z]*)\\s*(\\(|:)|(})))|\\s*(,)",
              "beginCaptures": {
                "1": { "name": "variable.arguments.graphql" }
              },
              "endCaptures": {
                "5": { "name": "punctuation.comma.graphql" }
              },
              "patterns": [
                {
                  "match": "\\s*([_A-Za-z][_0-9A-Za-z]*)",
                  "captures": {
                    "1": { "name": "support.type.graphql" }
                  }
                },
                { "include": "#graphql-colon" },
                { "include": "#graphql-comment" },
                { "include": "#graphql-skip-newlines" }
              ]
            },
            { "include": "#graphql-comment" },
            { "include": "#graphql-skip-newlines" }
          ]
        },
        { "include": "#graphql-directive" },
        { "include": "#graphql-comment" },
        { "include": "#graphql-skip-newlines" }
      ]
    },
    "graphql-directive-definition": {
      "begin": "\\s*(\\bdirective\\b)\\s*(@[_A-Za-z][_0-9A-Za-z]*)",
      "end": "(?=.)",
      "applyEndPatternLast": 1,
      "beginCaptures": {
        "1": { "name": "keyword.directive.graphql" },
        "2": { "name": "entity.name.function.directive.graphql" }
      },
      "patterns": [
        { "include": "#graphql-variable-definitions" },
        {
          "begin": "\\s*(\\bon\\b)\\s*([_A-Za-z]*)",
          "end": "(?=.)",
          "applyEndPatternLast": 1,
          "beginCaptures": {
            "1": { "name": "keyword.on.graphql" },
            "2": { "name": "support.type.location.graphql" }
          },
          "patterns": [
            { "include": "#graphql-skip-newlines" },
            { "include": "#graphql-comment" },
            { "include": "#literal-quasi-embedded" },
            {
              "match": "\\s*(\\|)\\s*([_A-Za-z]*)",
              "captures": {
                "2": { "name": "support.type.location.graphql" }
              }
            }
          ]
        },
        { "include": "#graphql-skip-newlines" },
        { "include": "#graphql-comment" },
        { "include": "#literal-quasi-embedded" }
      ]
    },
    "graphql-comment": {
      "patterns": [
        {
          "comment": "need to prefix comment space with a scope else Atom's reflow cmd doesn't work",
          "name": "comment.line.graphql.js",
          "match": "(\\s*)(#).*",
          "captures": {
            "1": { "name": "punctuation.whitespace.comment.leading.graphql" }
          }
        },
        {
          "name": "comment.line.graphql.js",
          "begin": "(\"\"\")",
          "end": "(\"\"\")",
          "beginCaptures": {
            "1": { "name": "punctuation.whitespace.comment.leading.graphql" }
          }
        },
        {
          "name": "comment.line.graphql.js",
          "begin": "(\")",
          "end": "(\")",
          "beginCaptures": {
            "1": { "name": "punctuation.whitespace.comment.leading.graphql" }
          }
        }
      ]
    },
    "graphql-variable-definitions": {
      "begin": "\\s*(\\()",
      "end": "\\s*(\\))",
      "captures": {
        "1": { "name": "meta.brace.round.graphql" }
      },
      "patterns": [
        { "include": "#graphql-comment" },
        { "include": "#graphql-variable-definition" },
        { "include": "#literal-quasi-embedded" }
      ]
    },
    "graphql-variable-definition": {
      "comment": "variable: type = value,.... which may be a list",
      "name": "meta.variables.graphql",
      "begin": "\\s*(\\$?[_A-Za-z][_0-9A-Za-z]*)(?=\\s*\\(|:)",
      "end": "(?=\\s*((\\$?[_A-Za-z][_0-9A-Za-z]*)\\s*(\\(|:)|(}|\\))))|\\s*(,)",
      "beginCaptures": {
        "1": { "name": "variable.parameter.graphql" }
      },
      "endCaptures": {
        "5": { "name": "punctuation.comma.graphql" }
      },
      "patterns": [
        { "include": "#graphql-comment" },
        { "include": "#graphql-colon" },
        { "include": "#graphql-input-types" },
        { "include": "#graphql-variable-assignment" },
        { "include": "#literal-quasi-embedded" },
        { "include": "#graphql-skip-newlines" },
        { "include": "#graphql-directive" }
      ]
    },
    "graphql-input-types": {
      "patterns": [
        { "include": "#graphql-scalar-type" },
        {
          "match": "\\s*([_A-Za-z][_0-9A-Za-z]*)(?:\\s*(!))?",
          "captures": {
            "1": { "name": "support.type.graphql" },
            "2": { "name": "keyword.operator.nulltype.graphql" }
          }
        },
        {
          "name": "meta.type.list.graphql",
          "begin": "\\s*(\\[)",
          "end": "\\s*(\\])(?:\\s*(!))?",
          "captures": {
            "1": { "name": "meta.brace.square.graphql" },
            "2": { "name": "keyword.operator.nulltype.graphql" }
          },
          "patterns": [
            { "include": "#graphql-input-types" },
            { "include": "#graphql-comment" },
            { "include": "#graphql-comma" },
            { "include": "#literal-quasi-embedded" }
          ]
        }
      ]
    },
    "graphql-scalar": {
      "match": "\\s*\\b(scalar)\\b\\s*([_A-Za-z][_0-9A-Za-z]*)",
      "captures": {
        "1": { "name": "keyword.scalar.graphql" },
        "2": { "name": "support.type.enum.graphql" }
      }
    },
    "graphql-scalar-type": {
      "match": "\\s*\\b(Int|Float|String|Boolean|ID)\\b(?:\\s*(!))?",
      "captures": {
        "1": { "name": "support.type.builtin.graphql" },
        "2": { "name": "keyword.operator.nulltype.graphql" }
      }
    },
    "graphql-variable-assignment": {
      "begin": "\\s(=)",
      "end": "(?=[\n,)])",
      "applyEndPatternLast": 1,
      "beginCaptures": {
        "1": { "name": "punctuation.assignment.graphql" }
      },
      "patterns": [{ "include": "#graphql-value" }]
    },
    "graphql-comma": {
      "match": "\\s*(,)",
      "captures": {
        "1": { "name": "punctuation.comma.graphql" }
      }
    },
    "graphql-colon": {
      "match": "\\s*(:)",
      "captures": {
        "1": { "name": "punctuation.colon.graphql" }
      }
    },
    "graphql-union-mark": {
      "match": "\\s*(\\|)",
      "captures": {
        "1": { "name": "punctuation.union.graphql" }
      }
    },
    "graphql-name": {
      "match": "\\s*([_A-Za-z][_0-9A-Za-z]*)",
      "captures": {
        "1": { "name": "entity.name.function.graphql" }
      }
    },
    "graphql-directive": {
      "contentName": "meta.embedded.block.directive.graphql",
      "begin": "\\s*(?=@)",
      "end": "(?=.)",
      "applyEndPatternLast": 1,
      "patterns": [{ "include": "#graphql-directive-body" }]
    },
    "graphql-directive-body": {
      "begin": "((@)\\s*([_A-Za-z][_0-9A-Za-z]*))",
      "end": "(?=.)",
      "applyEndPatternLast": 1,
      "beginCaptures": {
        "1": { "name": "entity.name.function.directive.graphql" }
      },
      "patterns": [
        { "include": "#graphql-arguments" },
        { "include": "#graphql-comment" },
        { "include": "#literal-quasi-embedded" },
        { "include": "#graphql-skip-newlines" }
      ]
    },
    "graphql-selection-set": {
      "name": "meta.selectionset.graphql",
      "begin": "\\s*({)",
      "end": "\\s*(})",
      "beginCaptures": {
        "1": { "name": "punctuation.operation.graphql" }
      },
      "endCaptures": {
        "1": { "name": "punctuation.operation.graphql" }
      },
      "patterns": [
        { "include": "#graphql-field" },
        { "include": "#graphql-fragment-spread" },
        { "include": "#graphql-inline-fragment" },
        { "include": "#graphql-comma" },
        { "include": "#graphql-comment" },
        { "include": "#native-interpolation" },
        { "include": "#literal-quasi-embedded" }
      ]
    },
    "graphql-field": {
      "patterns": [
        {
          "match": "\\s*([_A-Za-z][_0-9A-Za-z]*)\\s*(:)",
          "captures": {
            "1": { "name": "string.unquoted.alias.graphql" },
            "2": { "name": "punctuation.colon.graphql" }
          }
        },
        {
          "match": "\\s*([_A-Za-z][_0-9A-Za-z]*)",
          "captures": {
            "1": { "name": "variable.graphql" }
          }
        },
        { "include": "#graphql-arguments" },
        { "include": "#graphql-directive" },
        { "include": "#graphql-selection-set" },
        { "include": "#literal-quasi-embedded" },
        { "include": "#graphql-skip-newlines" }
      ]
    },
    "graphql-fragment-spread": {
      "begin": "\\s*(\\.\\.\\.)\\s*(?!\\bon\\b)([_A-Za-z][_0-9A-Za-z]*)",
      "end": "(?=.)",
      "applyEndPatternLast": 1,
      "captures": {
        "1": { "name": "keyword.operator.spread.graphql" },
        "2": { "name": "variable.fragment.graphql" }
      },
      "patterns": [
        { "include": "#graphql-comment" },
        { "include": "#graphql-selection-set" },
        { "include": "#graphql-directive" },
        { "include": "#literal-quasi-embedded" },
        { "include": "#graphql-skip-newlines" }
      ]
    },
    "graphql-inline-fragment": {
      "begin": "\\s*(\\.\\.\\.)\\s*(?:(\\bon\\b)\\s*([_A-Za-z][_0-9A-Za-z]*))?",
      "end": "(?=.)",
      "applyEndPatternLast": 1,
      "captures": {
        "1": { "name": "keyword.operator.spread.graphql" },
        "2": { "name": "keyword.on.graphql" },
        "3": { "name": "support.type.graphql" }
      },
      "patterns": [
        { "include": "#graphql-comment" },
        { "include": "#graphql-selection-set" },
        { "include": "#graphql-directive" },
        { "include": "#graphql-skip-newlines" },
        { "include": "#literal-quasi-embedded" }
      ]
    },
    "graphql-arguments": {
      "name": "meta.arguments.graphql",
      "begin": "\\s*(\\()",
      "end": "\\s*(\\))",
      "beginCaptures": {
        "1": { "name": "meta.brace.round.directive.graphql" }
      },
      "endCaptures": {
        "1": { "name": "meta.brace.round.directive.graphql" }
      },
      "patterns": [
        { "include": "#graphql-comment" },
        {
          "begin": "\\s*([_A-Za-z][_0-9A-Za-z]*)(?:\\s*(:))",
          "end": "(?=\\s*(?:(?:([_A-Za-z][_0-9A-Za-z]*)\\s*(:))|\\)))|\\s*(,)",
          "beginCaptures": {
            "1": { "name": "variable.parameter.graphql" },
            "2": { "name": "punctuation.colon.graphql" }
          },
          "endCaptures": {
            "3": { "name": "punctuation.comma.graphql" }
          },
          "patterns": [
            { "include": "#graphql-value" },
            { "include": "#graphql-comment" },
            { "include": "#graphql-skip-newlines" }
          ]
        },
        { "include": "#literal-quasi-embedded" }
      ]
    },
    "graphql-variable-name": {
      "match": "\\s*(\\$[_A-Za-z][_0-9A-Za-z]*)",
      "captures": {
        "1": { "name": "variable.graphql" }
      }
    },
    "graphql-float-value": {
      "match": "\\s*(-?(0|[1-9][0-9]*)(\\.[0-9]+)?((e|E)(\\+|-)?[0-9]+)?)",
      "captures": {
        "1": { "name": "constant.numeric.float.graphql" }
      }
    },
    "graphql-boolean-value": {
      "match": "\\s*\\b(true|false)\\b",
      "captures": {
        "1": { "name": "constant.language.boolean.graphql" }
      }
    },
    "graphql-null-value": {
      "match": "\\s*\\b(null)\\b",
      "captures": {
        "1": { "name": "constant.language.null.graphql" }
      }
    },
    "graphql-block-string-value": {
      "contentName": "string.quoted.triple.block.graphql",
      "begin": "\\s*+((\"\"\"))",
      "end": "\\s*+((\"\"\"))",
      "beginCaptures": {
        "1": { "name": "string.quoted.triple.block.graphql" },
        "2": { "name": "punctuation.definition.string.begin.graphql" }
      },
      "endCaptures": {
        "1": { "name": "string.quoted.triple.block.graphql" },
        "2": { "name": "punctuation.definition.string.end.graphql" }
      }
    },
    "graphql-string-value": {
      "contentName": "string.quoted.double.graphql",
      "begin": "\\s*+((\"))",
      "end": "\\s*+(?:((\"))|(\n))",
      "beginCaptures": {
        "1": { "name": "string.quoted.double.graphql" },
        "2": { "name": "punctuation.definition.string.begin.graphql" }
      },
      "endCaptures": {
        "1": { "name": "string.quoted.double.graphql" },
        "2": { "name": "punctuation.definition.string.end.graphql" },
        "3": { "name": "invalid.illegal.newline.graphql" }
      },
      "patterns": [
        { "include": "#graphql-string-content" },
        { "include": "#literal-quasi-embedded" }
      ]
    },
    "graphql-string-content": {
      "patterns": [
        {
          "name": "constant.character.escape.graphql",
          "match": "\\\\[/'\"\\\\nrtbf]"
        },
        {
          "name": "constant.character.escape.graphql",
          "match": "\\\\u([0-9a-fA-F]{4})"
        }
      ]
    },
    "graphql-enum": {
      "name": "meta.enum.graphql",
      "begin": "\\s*+\\b(enum)\\b\\s*([_A-Za-z][_0-9A-Za-z]*)",
      "end": "(?<=})",
      "beginCaptures": {
        "1": { "name": "keyword.enum.graphql" },
        "2": { "name": "support.type.enum.graphql" }
      },
      "patterns": [
        {
          "name": "meta.type.object.graphql",
          "begin": "\\s*({)",
          "end": "\\s*(})",
          "beginCaptures": {
            "1": { "name": "punctuation.operation.graphql" }
          },
          "endCaptures": {
            "1": { "name": "punctuation.operation.graphql" }
          },
          "patterns": [
            { "include": "#graphql-object-type" },
            { "include": "#graphql-directive" },
            { "include": "#graphql-comment" },
            { "include": "#graphql-enum-value" },
            { "include": "#literal-quasi-embedded" }
          ]
        },
        { "include": "#graphql-directive" }
      ]
    },
    "graphql-enum-value": {
      "name": "constant.character.enum.graphql",
      "match": "\\s*(?!=\\b(true|false|null)\\b)([_A-Za-z][_0-9A-Za-z]*)"
    },
    "graphql-value": {
      "patterns": [
        { "include": "#graphql-variable-name" },
        { "include": "#graphql-float-value" },
        { "include": "#graphql-block-string-value" },
        { "include": "#graphql-string-value" },
        { "include": "#graphql-boolean-value" },
        { "include": "#graphql-null-value" },
        { "include": "#graphql-enum-value" },
        { "include": "#graphql-list-value" },
        { "include": "#graphql-object-value" },
        { "include": "#graphql-comment" },
        { "include": "#literal-quasi-embedded" }
      ]
    },
    "graphql-list-value": {
      "patterns": [
        {
          "name": "meta.listvalues.graphql",
          "begin": "\\s*+(\\[)",
          "end": "\\s*(\\])",
          "endCaptures": {
            "1": { "name": "meta.brace.square.graphql" }
          },
          "beginCaptures": {
            "1": { "name": "meta.brace.square.graphql" }
          },
          "patterns": [{ "include": "#graphql-value" }]
        }
      ]
    },
    "graphql-object-value": {
      "patterns": [
        {
          "name": "meta.objectvalues.graphql",
          "begin": "\\s*+({)",
          "end": "\\s*(})",
          "beginCaptures": {
            "1": { "name": "meta.brace.curly.graphql" }
          },
          "endCaptures": {
            "1": { "name": "meta.brace.curly.graphql" }
          },
          "patterns": [
            { "include": "#graphql-object-field" },
            { "include": "#graphql-value" }
          ]
        }
      ]
    },
    "graphql-object-field": {
      "match": "\\s*(([_A-Za-z][_0-9A-Za-z]*))\\s*(:)",
      "captures": {
        "1": { "name": "string.unquoted.graphql" },
        "2": { "name": "variable.object.key.graphql" },
        "3": { "name": "punctuation.graphql" }
      }
    },
    "graphql-union": {
      "begin": "\\s*\\b(union)\\b\\s*([_A-Za-z][_0-9A-Za-z]*)",
      "end": "(?=.)",
      "applyEndPatternLast": 1,
      "captures": {
        "1": { "name": "keyword.union.graphql" },
        "2": { "name": "support.type.graphql" }
      },
      "patterns": [
        {
          "begin": "\\s*(=)\\s*([_A-Za-z][_0-9A-Za-z]*)",
          "end": "(?=.)",
          "applyEndPatternLast": 1,
          "captures": {
            "1": { "name": "punctuation.assignment.graphql" },
            "2": { "name": "support.type.graphql" }
          },
          "patterns": [
            { "include": "#graphql-skip-newlines" },
            { "include": "#graphql-comment" },
            { "include": "#literal-quasi-embedded" },
            {
              "match": "\\s*(\\|)\\s*([_A-Za-z][_0-9A-Za-z]*)",
              "captures": {
                "1": { "name": "punctuation.or.graphql" },
                "2": { "name": "support.type.graphql" }
              }
            }
          ]
        },
        { "include": "#graphql-skip-newlines" },
        { "include": "#graphql-comment" },
        { "include": "#literal-quasi-embedded" }
      ]
    },
    "native-interpolation": {
      "name": "native.interpolation",
      "begin": "\\s*(\\${)",
      "end": "(})",
      "beginCaptures": {
        "1": { "name": "keyword.other.substitution.begin" }
      },
      "endCaptures": {
        "1": { "name": "keyword.other.substitution.end" }
      },
      "patterns": [
        { "include": "source.js" },
        { "include": "source.ts" },
        { "include": "source.jsx" },
        { "include": "source.tsx" }
      ]
    },
    "graphql-skip-newlines": {
      "match": "\\s*\n"
    }
  }
}
