public CompletionDataSnapshot(CompletionDataSnapshot original, List <string> tableList, List <string> columnList, List <string> measureList)
        {
            _keywords  = original._keywords;
            _functions = original._functions;

            _tables      = tableList;
            _columnList  = columnList;
            _measureList = measureList;

            _sortedCompletion = null;
        }
        public CompletionDataSnapshot(CompletionDataSnapshot original, List <DaxFunction> daxFunctions)
        {
            _keywords    = original._keywords;
            _tables      = original._tables;
            _columnList  = original._columnList;
            _measureList = original._measureList;

            _functions = new List <InputData>();
            foreach (var daxFunctionDescription in daxFunctions)
            {
                _functions.Add(new InputData()
                {
                    Name = daxFunctionDescription.Name, Description = daxFunctionDescription.Description
                });
            }

            _sortedCompletion = null;
        }
        /// <summary>
        /// Extracts the list of DAX functions
        /// </summary>
        private List <DaxFunction> ExtractDaxFunctions()
        {
            // delete existing data
            List <DaxFunction> daxFunctions = null;

            try
            {
                LogLine("Start reading DAX functions.");

                // create a new list of functions to be loaded
                daxFunctions = new List <DaxFunction>();

                // extract scalar functions
                AdomdRestrictionCollection restrictions = new AdomdRestrictionCollection();
                restrictions.Add(FUNCTIONS_RESTRICTION_ORIGIN, FUNCTIONS_ORIGIN_SCALAR);
                daxFunctions.AddRange(
                    ExtractDaxFunctionsWithRestrictions(restrictions)
                    );

                // extract relational functions
                restrictions.Clear();
                restrictions.Add(FUNCTIONS_RESTRICTION_ORIGIN, FUNCTIONS_ORIGIN_RELATIONAL);
                daxFunctions.AddRange(
                    ExtractDaxFunctionsWithRestrictions(restrictions)
                    );

                _completionDataSnapshot = new CompletionDataSnapshot(_completionDataSnapshot, daxFunctions);

                LogLine("End reading DAX functions.");
            }
            catch (Microsoft.AnalysisServices.AdomdClient.AdomdConnectionException)
            {
                // If for some reason connection to the server cannot be established return null, it will be handled outside of this class
                LogLine("Error reading DAX functions.");
            }

            return(daxFunctions);
        }
        /// <summary>
        /// Constructs declarations cache based on database object
        /// </summary>
        private void ConstructSchemaBasedDeclarations()
        {
            LogLine("Begin constructing schema based declarations.");
            List <Declaration> tableDeclarations   = new List <Declaration>();
            List <Declaration> measureDeclarations = new List <Declaration>();
            Dictionary <string, List <Declaration> > tableMembersDeclarations = new Dictionary <string, List <Declaration> >();

            List <string> tableList   = new List <string>();
            List <string> columnList  = new List <string>();
            List <string> measureList = new List <string>();

            if (null == this._database)
            {
                ClearDeclarationsCache();
                LogLine("ERROR: Database is not defined.");
                return;
            }

            foreach (Microsoft.AnalysisServices.Dimension dim in _database.Dimensions)
            {
                // Set table declarations
                tableDeclarations.Add(new Babel.Declaration(dim.Description, dim.Name, Babel.LanguageService.TABLE_GLYPH_INDEX, dim.Name));
                tableList.AddRange(GenerateValidTableNames(dim.Name));

                // Obtain column declarations for current table
                List <Declaration> columnDeclarationsCurrentTable = new List <Declaration>();
                foreach (DimensionAttribute dimAttr in dim.Attributes)
                {
                    // Skip RowNumber columns
                    if (_rowNumberColumnNames.Any(i => { return(string.Equals(i, dimAttr.Name, StringComparison.CurrentCultureIgnoreCase)); }))
                    {
                        continue;
                    }

                    var columnShortName = "[" + dimAttr.Name + "]";

                    if (dimAttr.Source is ExpressionBinding)
                    {
                        // use calc column glyph
                        columnDeclarationsCurrentTable.Add(new Babel.Declaration(dimAttr.Description, dimAttr.Name, Babel.LanguageService.CALC_COLUMN_GLYPH_INDEX, columnShortName));
                    }
                    else
                    {
                        // use base column glyph
                        columnDeclarationsCurrentTable.Add(new Babel.Declaration(dimAttr.Description, dimAttr.Name, Babel.LanguageService.BASE_COLUMN_GLYPH_INDEX, columnShortName));
                    }

                    GenerateValidTableNames(dim.Name).ForEach(i => columnList.Add(string.Format("{0}{1}", i, columnShortName)));
                }

                tableMembersDeclarations.Add(dim.Name, columnDeclarationsCurrentTable);
            }

            // Obtain measure declarations and distribute them in table member declarations
            if (this._database.Cubes.Count > 0)
            {
                var cube = this._database.Cubes[0];
                if (cube.MdxScripts.Count > 0)
                {
                    var mdxScript = cube.MdxScripts[0];
                    foreach (Command mdxCommand in mdxScript.Commands)
                    {
                        if (!string.IsNullOrEmpty(mdxCommand.Text))
                        {
                            var measures = MeasuresContainer.ParseDaxScript(mdxCommand.Text).Measures;
                            foreach (var measure in measures)
                            {
                                // Add measure declaration to the global collection
                                var measureShortName = "[" + measure.Name + "]";
                                measureDeclarations.Add(new Babel.Declaration(measure.Expression, measure.Name, Babel.LanguageService.MEASURE_GLYPH_INDEX, measureShortName));

                                GenerateValidTableNames(measure.TableName).ForEach(i => measureList.Add(string.Format("{0}{1}", i, measureShortName)));

                                // Add the measure declaration to the table member declaration list
                                if (tableMembersDeclarations.ContainsKey(measure.TableName))
                                {
                                    tableMembersDeclarations[measure.TableName].Add(new Babel.Declaration(measure.Expression, measure.Name, Babel.LanguageService.MEASURE_GLYPH_INDEX, measureShortName));
                                }
                            }
                        }
                    }
                }
            }
            // Create HTML table
            string htmlSchemaTemplate;

            using (var textStreamReader = new StreamReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("DaxEditor.Resources.ScemaTemplate.htm")))
            {
                htmlSchemaTemplate = textStreamReader.ReadToEnd();
            }
            var htmlSchemaBuilder = new StringBuilder();

            foreach (var td in tableMembersDeclarations)
            {
                htmlSchemaBuilder.AppendFormat(BeginTableTemplate, HtmlEncode(td.Key));
                foreach (var decl in td.Value)
                {
                    if (_rowNumberColumnNames.Any(i => { return(string.Equals(i, decl.Name, StringComparison.CurrentCultureIgnoreCase)); }))
                    {
                        continue;
                    }

                    switch (decl.Glyph)
                    {
                    case Babel.LanguageService.BASE_COLUMN_GLYPH_INDEX:
                        htmlSchemaBuilder.AppendFormat(RowTemplate, "column", HtmlEncode(decl.Name));
                        break;

                    case Babel.LanguageService.CALC_COLUMN_GLYPH_INDEX:
                        htmlSchemaBuilder.AppendFormat(RowTemplate, "calcolumn", HtmlEncode(decl.Name));
                        break;

                    case Babel.LanguageService.MEASURE_GLYPH_INDEX:
                        htmlSchemaBuilder.AppendFormat(RowTemplate, "measure", HtmlEncode(decl.Name));
                        break;
                    }
                }
                htmlSchemaBuilder.Append(EndTableTemplate);
            }
            htmlSchemaTemplate = htmlSchemaTemplate.Replace(TablesPlaceholder, htmlSchemaBuilder.ToString());

            // Commit the newly created declarations into the cache
            lock (this)
            {
                this._tableDeclarations        = tableDeclarations;
                this._measureDeclarations      = measureDeclarations;
                this._tableMembersDeclarations = tableMembersDeclarations;
                this._htmlSchema = htmlSchemaTemplate;

                _completionDataSnapshot = new CompletionDataSnapshot(_completionDataSnapshot, tableList, columnList, measureList);
            }

            LogLine("End constructing schema based declarations.");
        }