Ejemplo n.º 1
0
        /// <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());
        }