/// <summary> /// Interpretes the syntax tree and generates a contextual document that can be transformed into /// a query plan. /// </summary> /// <param name="syntaxTree">The syntax tree to create a document for.</param> /// <returns>IGraphQueryDocument.</returns> public IGraphQueryDocument CreateDocument(ISyntaxTree syntaxTree) { Validation.ThrowIfNull(syntaxTree, nameof(syntaxTree)); // -------------------------------------------- // Step 1: Parse the syntax tree // -------------------------------------------- // Walk all nodes of the tree and on a "per node" basis perform actions // that are required of that node be it a specification validation rule or // an incremental addition to the document context being built. // // Note: All packages are rendered and then named fragment nodes are processed first // as they are required by any operations referenced elsewhere in the document // -------------------------------------------- var nodeProcessor = new DocumentConstructionRuleProcessor(); var docContext = new DocumentContext(_schema); var nodeContexts = new List <DocumentConstructionContext>(); foreach (var node in syntaxTree.Nodes) { var nodeContext = docContext.ForTopLevelNode(node); nodeContexts.Add(nodeContext); } nodeContexts.Sort(new TopLevelNodeProcessingOrder()); var completedAllSteps = nodeProcessor.Execute(nodeContexts); // -------------------------------------------- // Step 2: Validate the document parts // -------------------------------------------- // Inspect the document parts that were generated during part one and, as a whole, run additional // validation rules and perform final changes before constructing the final document. // e.g. ensure all fragments were called, all variables were referenced at least once etc. // -------------------------------------------- if (completedAllSteps) { var documentProcessor = new DocumentValidationRuleProcessor(); var validationContexts = new List <DocumentValidationContext>(); foreach (var part in docContext.Children) { var partContext = new DocumentValidationContext(docContext, part); validationContexts.Add(partContext); } documentProcessor.Execute(validationContexts); } // -------------------------------------------- // Step 3: Build out the final document // -------------------------------------------- return(docContext.ConstructDocument()); }