/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * 
 * @fullSyntaxTransform
 * @format
 */
'use strict';

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));

var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));

var RelayTransformError = require("./RelayTransformError");

var find = require("./find");

var invariant = require("./invariant");

var util = require("util");

var _require = require("./GraphQLRelayDirective"),
    GraphQLRelayDirective = _require.GraphQLRelayDirective;

var _require2 = require("./RelayQLNodeInterface"),
    ID = _require2.ID;

var _require3 = require("graphql"),
    GraphQLBoolean = _require3.GraphQLBoolean,
    GraphQLEnumType = _require3.GraphQLEnumType,
    GraphQLFloat = _require3.GraphQLFloat,
    GraphQLID = _require3.GraphQLID,
    GraphQLInputObjectType = _require3.GraphQLInputObjectType,
    GraphQLInt = _require3.GraphQLInt,
    GraphQLInterfaceType = _require3.GraphQLInterfaceType,
    GraphQLList = _require3.GraphQLList,
    GraphQLNonNull = _require3.GraphQLNonNull,
    GraphQLObjectType = _require3.GraphQLObjectType,
    GraphQLScalarType = _require3.GraphQLScalarType,
    GraphQLString = _require3.GraphQLString,
    GraphQLUnionType = _require3.GraphQLUnionType,
    isAbstractType = _require3.isAbstractType,
    SchemaMetaFieldDef = _require3.SchemaMetaFieldDef,
    TypeMetaFieldDef = _require3.TypeMetaFieldDef,
    TypeNameMetaFieldDef = _require3.TypeNameMetaFieldDef;

var RelayQLNode =
/*#__PURE__*/
function () {
  function RelayQLNode(context, ast) {
    this.ast = ast;
    this.context = context;
  }

  var _proto = RelayQLNode.prototype;

  _proto.getLocation = function getLocation() {
    return this.ast.loc;
  };

  _proto.getType = function getType() {
    !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'Missing Implementation') : invariant(false) : void 0;
  };

  _proto.getField = function getField(fieldName) {
    return find(this.getFields(), function (field) {
      return field.getName() === fieldName;
    });
  };

  _proto.getFields = function getFields() {
    var fields = [];
    this.getSelections().forEach(function (selection) {
      if (selection instanceof RelayQLField) {
        fields.push(selection);
      }
    });
    return fields;
  };

  _proto.getSelections = function getSelections() {
    var _this = this;

    /* $FlowFixMe(>=0.68.0 site=react_native_fb,react_native_oss) This comment
     * suppresses an error found when Flow v0.68 was deployed. To see the error
     * delete this comment and run Flow. */
    if (!this.ast.selectionSet) {
      return [];
    } // $FlowFixMe


    return this.ast.selectionSet.selections.map(function (selection) {
      if (selection.kind === 'Field') {
        return new RelayQLField(_this.context, selection, _this.getType());
      } else if (selection.kind === 'FragmentSpread') {
        return new RelayQLFragmentSpread(_this.context, selection);
      } else if (selection.kind === 'InlineFragment') {
        return new RelayQLInlineFragment(_this.context, selection, _this.getType());
      } else {
        throw new RelayTransformError(util.format('Unexpected selection kind: %s', selection.kind), _this.getLocation());
      }
    });
  };

  _proto.getDirectives = function getDirectives() {
    var _this2 = this;

    // $FlowFixMe
    return (this.ast.directives || []).map(function (directive) {
      return new RelayQLDirective(_this2.context, directive);
    });
  };

  _proto.hasDirective = function hasDirective(name) {
    // $FlowFixMe
    return (this.ast.directives || []).some(function (d) {
      return d.name.value === name;
    });
  };

  _proto.isPattern = function isPattern() {
    return this.context.isPattern;
  };

  return RelayQLNode;
}();

var RelayQLDefinition =
/*#__PURE__*/
function (_RelayQLNode) {
  (0, _inheritsLoose2["default"])(RelayQLDefinition, _RelayQLNode);

  function RelayQLDefinition() {
    return _RelayQLNode.apply(this, arguments) || this;
  }

  var _proto2 = RelayQLDefinition.prototype;

  _proto2.getName = function getName() {
    // TODO: this.context.definitionName;

    /* $FlowFixMe(>=0.68.0 site=react_native_fb,react_native_oss) This comment
     * suppresses an error found when Flow v0.68 was deployed. To see the error
     * delete this comment and run Flow. */
    return this.ast.name ? // $FlowFixMe
    this.ast.name.value : this.getType().getName({
      modifiers: false
    });
  };

  return RelayQLDefinition;
}(RelayQLNode);

var RelayQLFragment =
/*#__PURE__*/
function (_RelayQLDefinition) {
  (0, _inheritsLoose2["default"])(RelayQLFragment, _RelayQLDefinition);

  function RelayQLFragment(context, ast, parentType) {
    var _this3;

    var relayDirectiveArgs = {};
    var relayDirective = find(ast.directives || [], function (directive) {
      return directive.name.value === 'relay';
    });

    if (relayDirective) {
      (relayDirective.arguments || []).forEach(function (arg) {
        relayDirectiveArgs[arg.name.value] = arg.value;
      });
    } // @relay(pattern: true)


    var isPattern = relayDirectiveArgs.pattern && relayDirectiveArgs.pattern.kind === 'BooleanValue' && relayDirectiveArgs.pattern.value;
    _this3 = _RelayQLDefinition.call(this, (0, _objectSpread2["default"])({}, context, {
      isPattern: isPattern
    }), ast) || this;
    _this3.parentType = parentType;
    return _this3;
  }

  var _proto3 = RelayQLFragment.prototype;

  _proto3.getType = function getType() {
    var type = this.ast.typeCondition;

    if (type) {
      // Convert `ListType` and `NonNullType` into `NamedType`.
      while (type.kind !== 'NamedType') {
        type = type.type;
      }

      return new RelayQLType(this.context, this.context.schema.getType(type.name.value));
    } else if (this.ast.kind === 'InlineFragment') {
      // Inline fragments without type conditions fall back to parent type.
      if (!this.parentType) {
        throw new RelayTransformError('Cannot get type of typeless inline fragment without parent type.', this.getLocation());
      }

      return this.parentType;
    } else {
      throw new RelayTransformError(util.format('Unexpected fragment kind: %s', this.ast.kind), this.getLocation());
    }
  };

  return RelayQLFragment;
}(RelayQLDefinition); // $FlowFixMe TT24544397


var RelayQLMutation =
/*#__PURE__*/
function (_RelayQLDefinition2) {
  (0, _inheritsLoose2["default"])(RelayQLMutation, _RelayQLDefinition2);

  function RelayQLMutation() {
    return _RelayQLDefinition2.apply(this, arguments) || this;
  }

  var _proto4 = RelayQLMutation.prototype;

  _proto4.getType = function getType() {
    return new RelayQLType(this.context, this.context.schema.getMutationType());
  };

  return RelayQLMutation;
}(RelayQLDefinition); // $FlowFixMe TT24544397


var RelayQLQuery =
/*#__PURE__*/
function (_RelayQLDefinition3) {
  (0, _inheritsLoose2["default"])(RelayQLQuery, _RelayQLDefinition3);

  function RelayQLQuery() {
    return _RelayQLDefinition3.apply(this, arguments) || this;
  }

  var _proto5 = RelayQLQuery.prototype;

  _proto5.getType = function getType() {
    return new RelayQLType(this.context, this.context.schema.getQueryType());
  };

  return RelayQLQuery;
}(RelayQLDefinition); // $FlowFixMe TT24544397


var RelayQLSubscription =
/*#__PURE__*/
function (_RelayQLDefinition4) {
  (0, _inheritsLoose2["default"])(RelayQLSubscription, _RelayQLDefinition4);

  function RelayQLSubscription() {
    return _RelayQLDefinition4.apply(this, arguments) || this;
  }

  var _proto6 = RelayQLSubscription.prototype;

  _proto6.getType = function getType() {
    return new RelayQLType(this.context, this.context.schema.getSubscriptionType());
  };

  return RelayQLSubscription;
}(RelayQLDefinition); // $FlowFixMe TT24544397


var RelayQLField =
/*#__PURE__*/
function (_RelayQLNode2) {
  (0, _inheritsLoose2["default"])(RelayQLField, _RelayQLNode2);

  function RelayQLField(context, ast, parentType) {
    var _this4;

    _this4 = _RelayQLNode2.call(this, context, ast) || this;
    var fieldName = _this4.ast.name.value;
    var fieldDef = parentType.getFieldDefinition(fieldName, ast);

    if (!fieldDef) {
      throw new RelayTransformError(util.format('You supplied a field named `%s` on type `%s`, but no such field ' + 'exists on that type.', fieldName, parentType.getName({
        modifiers: false
      })), _this4.getLocation());
    }

    _this4.fieldDef = fieldDef;
    return _this4;
  }

  var _proto7 = RelayQLField.prototype;

  _proto7.getName = function getName() {
    return this.ast.name.value;
  };

  _proto7.getAlias = function getAlias() {
    return this.ast.alias ? this.ast.alias.value : null;
  };

  _proto7.getType = function getType() {
    return this.fieldDef.getType();
  };

  _proto7.hasArgument = function hasArgument(argName) {
    return this.getArguments().some(function (arg) {
      return arg.getName() === argName;
    });
  };

  _proto7.findArgument = function findArgument(argName) {
    return find(this.getArguments(), function (arg) {
      return arg.getName() === argName;
    });
  };

  _proto7.getArguments = function getArguments() {
    var _this5 = this;

    var argTypes = this.fieldDef.getDeclaredArguments();
    return (this.ast.arguments || []).map(function (arg) {
      var argName = arg.name.value;
      var argType = argTypes[argName];

      if (!argType) {
        throw new RelayTransformError(util.format('You supplied an argument named `%s` on field `%s`, but no such ' + 'argument exists on that field.', argName, _this5.getName()), _this5.getLocation());
      }

      return new RelayQLArgument(_this5.context, arg, argType);
    });
  };

  _proto7.hasDeclaredArgument = function hasDeclaredArgument(argName) {
    return this.fieldDef.getDeclaredArguments().hasOwnProperty(argName);
  };

  _proto7.getDeclaredArgument = function getDeclaredArgument(argName) {
    return this.fieldDef.getArgument(argName);
  };

  _proto7.getDeclaredArguments = function getDeclaredArguments() {
    return this.fieldDef.getDeclaredArguments();
  };

  return RelayQLField;
}(RelayQLNode); // $FlowFixMe TT24544397


var RelayQLFragmentSpread =
/*#__PURE__*/
function (_RelayQLNode3) {
  (0, _inheritsLoose2["default"])(RelayQLFragmentSpread, _RelayQLNode3);

  function RelayQLFragmentSpread() {
    return _RelayQLNode3.apply(this, arguments) || this;
  }

  var _proto8 = RelayQLFragmentSpread.prototype;

  _proto8.getName = function getName() {
    return this.ast.name.value;
  };

  _proto8.getSelections = function getSelections() {
    throw new RelayTransformError('Cannot get selection of a fragment spread.', this.getLocation());
  };

  return RelayQLFragmentSpread;
}(RelayQLNode); // $FlowFixMe TT24544397


var RelayQLInlineFragment =
/*#__PURE__*/
function (_RelayQLNode4) {
  (0, _inheritsLoose2["default"])(RelayQLInlineFragment, _RelayQLNode4);

  function RelayQLInlineFragment(context, ast, parentType) {
    var _this6;

    _this6 = _RelayQLNode4.call(this, context, ast) || this;
    _this6.parentType = parentType;
    return _this6;
  }

  var _proto9 = RelayQLInlineFragment.prototype;

  _proto9.getFragment = function getFragment() {
    return new RelayQLFragment(this.context, this.ast, this.parentType);
  };

  return RelayQLInlineFragment;
}(RelayQLNode);

var RelayQLDirective =
/*#__PURE__*/
function () {
  function RelayQLDirective(context, ast) {
    var _this7 = this;

    this.ast = ast;
    this.context = context;
    this.argTypes = {};
    var directiveName = ast.name.value;
    var schemaDirective = directiveName === GraphQLRelayDirective.name ? GraphQLRelayDirective : context.schema.getDirective(directiveName);

    if (!schemaDirective) {
      throw new RelayTransformError(util.format('You supplied a directive named `%s`, but no such directive exists.', directiveName), this.getLocation());
    }

    schemaDirective.args.forEach(function (schemaArg) {
      _this7.argTypes[schemaArg.name] = new RelayQLArgumentType(schemaArg.type);
    });
  }

  var _proto10 = RelayQLDirective.prototype;

  _proto10.getLocation = function getLocation() {
    return this.ast.loc;
  };

  _proto10.getName = function getName() {
    return this.ast.name.value;
  };

  _proto10.getArguments = function getArguments() {
    var _this8 = this;

    return (this.ast.arguments || []).map(function (arg) {
      var argName = arg.name.value;
      var argType = _this8.argTypes[argName];

      if (!argType) {
        throw new RelayTransformError(util.format('You supplied an argument named `%s` on directive `%s`, but no ' + 'such argument exists on that directive.', argName, _this8.getName()), _this8.getLocation());
      }

      return new RelayQLArgument(_this8.context, arg, argType);
    });
  };

  return RelayQLDirective;
}();

var RelayQLArgument =
/*#__PURE__*/
function () {
  function RelayQLArgument(context, ast, type) {
    this.ast = ast;
    this.context = context;
    this.type = type;
  }

  var _proto11 = RelayQLArgument.prototype;

  _proto11.getLocation = function getLocation() {
    return this.ast.loc;
  };

  _proto11.getName = function getName() {
    return this.ast.name.value;
  };

  _proto11.getType = function getType() {
    return this.type;
  };

  _proto11.isVariable = function isVariable() {
    return this.ast.value.kind === 'Variable';
  };

  _proto11.getVariableName = function getVariableName() {
    if (this.ast.value.kind !== 'Variable') {
      throw new RelayTransformError('Cannot get variable name of an argument value.', this.getLocation());
    }

    return this.ast.value.name.value;
  };

  _proto11.getValue = function getValue() {
    var _this9 = this;

    if (this.isVariable()) {
      throw new RelayTransformError('Cannot get value of an argument variable.', this.getLocation());
    }

    var value = this.ast.value;

    if (value.kind === 'ListValue') {
      return value.values.map(function (val) {
        return new RelayQLArgument(_this9.context, (0, _objectSpread2["default"])({}, _this9.ast, {
          value: val
        }), _this9.type.ofType());
      });
    } else {
      return getLiteralValue(value);
    }
  };

  return RelayQLArgument;
}();

var RelayQLType =
/*#__PURE__*/
function () {
  function RelayQLType(context, schemaModifiedType) {
    this.context = context;

    var _stripMarkerTypes = stripMarkerTypes(schemaModifiedType),
        isListType = _stripMarkerTypes.isListType,
        isNonNullType = _stripMarkerTypes.isNonNullType,
        schemaUnmodifiedType = _stripMarkerTypes.schemaUnmodifiedType;

    this.isListType = isListType;
    this.isNonNullType = isNonNullType;
    this.schemaUnmodifiedType = schemaUnmodifiedType;
    this.schemaModifiedType = schemaModifiedType;
  }

  var _proto12 = RelayQLType.prototype;

  _proto12.canHaveSubselections = function canHaveSubselections() {
    return !(this.schemaUnmodifiedType instanceof GraphQLScalarType || this.schemaUnmodifiedType instanceof GraphQLEnumType);
  };

  _proto12.getName = function getName(_ref) {
    var modifiers = _ref.modifiers;
    return modifiers ? this.schemaModifiedType.toString() : this.schemaUnmodifiedType.toString();
  };

  _proto12.hasField = function hasField(fieldName) {
    return !!this.getFieldDefinition(fieldName);
  };

  _proto12.getFieldDefinition = function getFieldDefinition(fieldName, fieldAST) {
    var type = this.schemaUnmodifiedType;
    var isQueryType = type === this.context.schema.getQueryType();
    var hasTypeName = type instanceof GraphQLObjectType || type instanceof GraphQLInterfaceType || type instanceof GraphQLUnionType;
    var hasFields = type instanceof GraphQLObjectType || type instanceof GraphQLInterfaceType;
    var schemaFieldDef;

    if (isQueryType && fieldName === SchemaMetaFieldDef.name) {
      schemaFieldDef = SchemaMetaFieldDef;
    } else if (isQueryType && fieldName === TypeMetaFieldDef.name) {
      schemaFieldDef = TypeMetaFieldDef;
    } else if (hasTypeName && fieldName === TypeNameMetaFieldDef.name) {
      schemaFieldDef = TypeNameMetaFieldDef;
    } else if (hasFields) {
      schemaFieldDef = type.getFields()[fieldName];
    } // Temporary workaround to support fixme_fat_interface


    if (!schemaFieldDef && isAbstractType(type) && fieldAST && fieldAST.directives && fieldAST.directives.some(function (directive) {
      return directive.name.value === 'fixme_fat_interface';
    })) {
      var possibleTypes = this.context.schema.getPossibleTypes(type);

      var _loop = function _loop(ii) {
        var possibleField = possibleTypes[ii].getFields()[fieldName];

        if (possibleField) {
          // Fat interface fields can have differing arguments. Try to return
          // a field with matching arguments, but still return a field if the
          // arguments do not match.
          schemaFieldDef = possibleField;

          if (fieldAST && fieldAST.arguments) {
            var argumentsAllExist = fieldAST.arguments.every(function (argument) {
              return find(possibleField.args, function (argDef) {
                return argDef.name === argument.name.value;
              });
            });

            if (argumentsAllExist) {
              return "break";
            }
          }
        }
      };

      for (var ii = 0; ii < possibleTypes.length; ii++) {
        var _ret = _loop(ii);

        if (_ret === "break") break;
      }
    }

    return schemaFieldDef ? new RelayQLFieldDefinition(this.context, schemaFieldDef) : null;
  };

  _proto12.getInterfaces = function getInterfaces() {
    var _this10 = this;

    if (this.schemaUnmodifiedType instanceof GraphQLObjectType) {
      return this.schemaUnmodifiedType.getInterfaces().map(function (schemaInterface) {
        return new RelayQLType(_this10.context, schemaInterface);
      });
    }

    return [];
  };

  _proto12.getConcreteTypes = function getConcreteTypes() {
    var _this11 = this;

    !this.isAbstract() ? process.env.NODE_ENV !== "production" ? invariant(false, 'Cannot get concrete types of a concrete type.') : invariant(false) : void 0;
    return this.context.schema.getPossibleTypes(this.schemaUnmodifiedType).map(function (concreteType) {
      return new RelayQLType(_this11.context, concreteType);
    });
  };

  _proto12.getIdentifyingFieldDefinition = function getIdentifyingFieldDefinition() {
    if (this.alwaysImplements('Node')) {
      return this.getFieldDefinition(ID);
    }

    return null;
  };

  _proto12.isAbstract = function isAbstract() {
    return isAbstractType(this.schemaUnmodifiedType);
  };

  _proto12.isList = function isList() {
    return this.isListType;
  };

  _proto12.isNonNull = function isNonNull() {
    return this.isNonNullType;
  };

  _proto12.isQueryType = function isQueryType() {
    return this.schemaUnmodifiedType === this.context.schema.getQueryType();
  };

  _proto12.isConnection = function isConnection() {
    if (!/Connection$/.test(this.getName({
      modifiers: false
    }))) {
      return false;
    }

    var edges = this.getFieldDefinition('edges');

    if (!edges || !edges.getType().canHaveSubselections()) {
      return false;
    }

    var node = edges.getType().getFieldDefinition('node');

    if (!node || !node.getType().canHaveSubselections()) {
      return false;
    }

    var cursor = edges.getType().getFieldDefinition('cursor');

    if (!cursor || cursor.getType().canHaveSubselections()) {
      return false;
    }

    return true;
  };

  _proto12.isConnectionEdge = function isConnectionEdge() {
    return /Edge$/.test(this.getName({
      modifiers: false
    })) && this.hasField('node') && this.hasField('cursor');
  };

  _proto12.isConnectionPageInfo = function isConnectionPageInfo() {
    return this.getName({
      modifiers: false
    }) === 'PageInfo';
  };

  _proto12.alwaysImplements = function alwaysImplements(typeName) {
    return this.getName({
      modifiers: false
    }) === typeName || this.getInterfaces().some(function (type) {
      return type.getName({
        modifiers: false
      }) === typeName;
    }) || this.isAbstract() && this.getConcreteTypes().every(function (type) {
      return type.alwaysImplements(typeName);
    });
  };

  _proto12.mayImplement = function mayImplement(typeName) {
    return this.getName({
      modifiers: false
    }) === typeName || this.getInterfaces().some(function (type) {
      return type.getName({
        modifiers: false
      }) === typeName;
    }) || this.isAbstract() && this.getConcreteTypes().some(function (type) {
      return type.alwaysImplements(typeName);
    });
  };

  _proto12.generateField = function generateField(fieldName) {
    var generatedFieldAST = {
      kind: 'Field',
      name: {
        kind: 'Name',
        value: fieldName
      }
    };
    return new RelayQLField(this.context, generatedFieldAST, this);
  };

  _proto12.generateIdFragment = function generateIdFragment() {
    var generatedFragmentAST = {
      kind: 'Fragment',
      name: {
        kind: 'Name',
        value: 'IdFragment'
      },
      typeCondition: {
        kind: 'NamedType',
        name: {
          value: 'Node'
        }
      } // ID field will be generated by the printer; we won't declare it here.

    };
    return new RelayQLFragment(this.context, generatedFragmentAST, this);
  };

  return RelayQLType;
}();

var RelayQLFieldDefinition =
/*#__PURE__*/
function () {
  function RelayQLFieldDefinition(context, schemaFieldDef) {
    this.context = context;
    this.schemaFieldDef = schemaFieldDef;
  }

  var _proto13 = RelayQLFieldDefinition.prototype;

  _proto13.getName = function getName() {
    return this.schemaFieldDef.name;
  };

  _proto13.getType = function getType() {
    return new RelayQLType(this.context, this.schemaFieldDef.type);
  };

  _proto13.hasArgument = function hasArgument(argName) {
    return this.schemaFieldDef.args.some(function (schemaArg) {
      return schemaArg.name === argName;
    });
  };

  _proto13.getArgument = function getArgument(argName) {
    var schemaArg = find(this.schemaFieldDef.args, function (arg) {
      return arg.name === argName;
    });
    !schemaArg ? process.env.NODE_ENV !== "production" ? invariant(false, 'You tried to get an argument named `%s` on field `%s`, but no such ' + 'argument exists on that field.', argName, this.getName()) : invariant(false) : void 0;
    return new RelayQLArgumentType(schemaArg.type);
  };

  _proto13.getDeclaredArguments = function getDeclaredArguments() {
    var args = {};
    this.schemaFieldDef.args.forEach(function (schemaArg) {
      args[schemaArg.name] = new RelayQLArgumentType(schemaArg.type);
    });
    return args;
  };

  return RelayQLFieldDefinition;
}();

var RelayQLArgumentType =
/*#__PURE__*/
function () {
  function RelayQLArgumentType(schemaModifiedArgType) {
    var _stripMarkerTypes2 = stripMarkerTypes(schemaModifiedArgType),
        isListType = _stripMarkerTypes2.isListType,
        isNonNullType = _stripMarkerTypes2.isNonNullType,
        schemaUnmodifiedType = _stripMarkerTypes2.schemaUnmodifiedType;

    this.isListType = isListType;
    this.isNonNullType = isNonNullType;
    this.schemaUnmodifiedArgType = schemaUnmodifiedType;
    this.schemaModifiedArgType = schemaModifiedArgType;
  }

  var _proto14 = RelayQLArgumentType.prototype;

  _proto14.getName = function getName(_ref2) {
    var modifiers = _ref2.modifiers;
    return modifiers ? this.schemaModifiedArgType.toString() : this.schemaUnmodifiedArgType.toString();
  };

  _proto14.ofType = function ofType() {
    !(this.isList() || this.isNonNull()) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Can only get type of list or non-null type.') : invariant(false) : void 0;
    return new RelayQLArgumentType(this.schemaUnmodifiedArgType);
  };

  _proto14.isCustomScalar = function isCustomScalar() {
    return this.isScalar() && !(this.schemaUnmodifiedArgType === GraphQLBoolean || this.schemaUnmodifiedArgType === GraphQLFloat || this.schemaUnmodifiedArgType === GraphQLID || this.schemaUnmodifiedArgType === GraphQLInt || this.schemaUnmodifiedArgType === GraphQLString);
  };

  _proto14.isBoolean = function isBoolean() {
    return this.schemaUnmodifiedArgType === GraphQLBoolean;
  };

  _proto14.isEnum = function isEnum() {
    return this.schemaUnmodifiedArgType instanceof GraphQLEnumType;
  };

  _proto14.isID = function isID() {
    return this.schemaUnmodifiedArgType === GraphQLID;
  };

  _proto14.isList = function isList() {
    return this.isListType;
  };

  _proto14.isNonNull = function isNonNull() {
    return this.isNonNullType;
  };

  _proto14.isNumber = function isNumber() {
    return this.schemaUnmodifiedArgType === GraphQLFloat || this.schemaUnmodifiedArgType === GraphQLInt;
  };

  _proto14.isObject = function isObject() {
    return this.schemaUnmodifiedArgType instanceof GraphQLInputObjectType;
  };

  _proto14.isScalar = function isScalar() {
    return this.schemaUnmodifiedArgType instanceof GraphQLScalarType;
  };

  _proto14.isString = function isString() {
    return this.schemaUnmodifiedArgType === GraphQLString;
  };

  return RelayQLArgumentType;
}();

function stripMarkerTypes(schemaModifiedType) {
  var isListType = false;
  var isNonNullType = false;
  var schemaUnmodifiedType = schemaModifiedType;

  while (true) {
    if (schemaUnmodifiedType instanceof GraphQLList) {
      isListType = true;
    } else if (schemaUnmodifiedType instanceof GraphQLNonNull) {
      isNonNullType = true;
    } else {
      break;
    }

    schemaUnmodifiedType = schemaUnmodifiedType.ofType;
  }

  return {
    isListType: isListType,
    isNonNullType: isNonNullType,
    schemaUnmodifiedType: schemaUnmodifiedType
  };
}

function getLiteralValue(value) {
  switch (value.kind) {
    case 'IntValue':
      return parseInt(value.value, 10);

    case 'FloatValue':
      return parseFloat(value.value);

    case 'StringValue':
    case 'BooleanValue':
    case 'EnumValue':
      return value.value;

    case 'ListValue':
      return value.values.map(getLiteralValue);

    case 'NullValue':
      return null;

    case 'ObjectValue':
      var object = {};
      value.fields.forEach(function (field) {
        object[field.name.value] = getLiteralValue(field.value);
      });
      return object;

    case 'Variable':
      throw new RelayTransformError(util.format('Unexpected nested variable `%s`; variables are supported as top-' + 'level arguments - `node(id: $id)` - or directly within lists - ' + '`nodes(ids: [$id])`.', value.name.value), value.loc);

    default:
      throw new RelayTransformError(util.format('Unexpected value kind: %s', value.kind), value.loc);
  }
}

module.exports = {
  RelayQLArgument: RelayQLArgument,
  RelayQLArgumentType: RelayQLArgumentType,
  RelayQLDefinition: RelayQLDefinition,
  RelayQLDirective: RelayQLDirective,
  RelayQLField: RelayQLField,
  RelayQLFieldDefinition: RelayQLFieldDefinition,
  RelayQLFragment: RelayQLFragment,
  RelayQLFragmentSpread: RelayQLFragmentSpread,
  RelayQLInlineFragment: RelayQLInlineFragment,
  RelayQLMutation: RelayQLMutation,
  RelayQLNode: RelayQLNode,
  RelayQLQuery: RelayQLQuery,
  RelayQLSubscription: RelayQLSubscription,
  RelayQLType: RelayQLType
};