Example #1
0
        /// <summary>
        /// Adds a new document part to this context, inserting where appropriate and updating the
        /// doc scope as necessary.
        /// </summary>
        /// <param name="docPart">The document part to add to this context.</param>
        public void AddDocumentPart(IDocumentPart docPart)
        {
            switch (docPart)
            {
            case QueryOperation qo:
                this.AddOrUpdateContextItem(qo);
                this.BeginNewOperation(qo);
                _activePart = qo;
                break;

            case QueryVariable qv:
                this.AddOrUpdateContextItem(qv);
                var variables = _operation?.CreateVariableCollection();
                variables?.AddVariable(qv);
                _activePart = qv;
                break;

            case QueryFragment qf:
                this.AddOrUpdateContextItem(qf);
                this.BeginNewDocumentScope();
                break;

            case FieldSelection fs:
                this.AddOrUpdateContextItem(fs);
                _selectionSet.AddFieldSelection(fs);
                this.DocumentScope = new DocumentScope(this.DocumentScope, fs);
                _activePart        = fs;
                break;

            case QueryDirective qd:
                // directives never alter the current scope, they just work within it
                this.AddOrUpdateContextItem(qd);
                this.DocumentScope.InsertDirective(qd);
                _activePart = qd;
                break;

            case QueryInputArgument qa:
                if (_activePart is IQueryArgumentContainerDocumentPart argContainer)
                {
                    argContainer.AddArgument(qa);
                }

                // query arguments never retain parent scopes; they are considered independent
                this.AddOrUpdateContextItem(qa);
                this.DocumentScope = new DocumentScope(part: qa);
                _activePart        = qa;
                break;

            case QueryInputValue qiv:
                if (_activePart is IInputValueDocumentPart qia)
                {
                    qia.AssignValue(qiv);
                }
                else if (_activePart is QueryInputValue partQiv)
                {
                    partQiv.AddChild(qiv);
                }

                this.AddOrUpdateContextItem(qiv, typeof(QueryInputValue));
                _activePart = qiv;
                break;

            default:
                this.Messages.Critical(
                    $"Unrecognized document element or position. The document element at the current position " +
                    "could not be processed and the query was terminated. Double check your document and try again.",
                    Constants.ErrorCodes.INVALID_DOCUMENT,
                    this.ActiveNode.Location.AsOrigin());
                break;
            }
        }