/// <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; } }