/// <summary> /// Implements <see cref="IORMToolServices.GetVerbalizationSnippetsDictionary"/> /// </summary> protected IDictionary <Type, IVerbalizationSets> GetVerbalizationSnippetsDictionary(string target) { VerbalizationManager mgr = myVerbalizationManager; if (mgr == null) { return(null); } IDictionary <Type, IVerbalizationSets> retVal = null; IDictionary <string, IDictionary <Type, IVerbalizationSets> > targetedSnippets = myTargetedVerbalizationSnippets; bool loadTarget = false; if (targetedSnippets == null) { loadTarget = true; myTargetedVerbalizationSnippets = targetedSnippets = new Dictionary <string, IDictionary <Type, IVerbalizationSets> >(); } else if (targetedSnippets != null) { loadTarget = !targetedSnippets.TryGetValue(target, out retVal); } if (loadTarget) { IList <VerbalizationSnippetsIdentifier> identifiers = mgr.CustomSnippetsIdentifiers; targetedSnippets[target] = retVal = VerbalizationSnippetSetsManager.LoadSnippetsDictionary( this, target, mgr.SnippetsDirectory, (identifiers != null && identifiers.Count != 0) ? identifiers : null); } return(retVal); }
public ProviderBranch( string currentSettings, IEnumerable <IVerbalizationTargetProvider> targetProviders, IEnumerable <IVerbalizationSnippetsProvider> snippetProviders, #if VISUALSTUDIO_15_0 string[] verbalizationDirectories, #else string verbalizationDirectory, #endif string languageFormatString) { VerbalizationSnippetsIdentifier[] allIdentifiers = VerbalizationSnippetSetsManager.LoadAvailableSnippets( snippetProviders, #if VISUALSTUDIO_15_0 verbalizationDirectories); #else verbalizationDirectory); #endif VerbalizationSnippetsIdentifier[] currentIdentifiers = VerbalizationSnippetsIdentifier.ParseIdentifiers(currentSettings); if (languageFormatString != null) { if (languageFormatString.Length != 0) { myLanguageFormatString = languageFormatString; } else { languageFormatString = null; } } // Gather all targets List <VerbalizationTargetData> targetsList = new List <VerbalizationTargetData>(); foreach (IVerbalizationTargetProvider provider in targetProviders) { VerbalizationTargetData[] currentData = provider.ProvideVerbalizationTargets(); if (currentData != null) { for (int i = 0; i < currentData.Length; ++i) { targetsList.Add(currentData[i]); // Put it in a condition we can binary search it targetsList.Sort(TargetKeyComparer.Instance); } } } VerbalizationTargetData[] targets; myVerbalizationTargets = targets = targetsList.ToArray(); // Make sure all identifiers can map to a known target int unknownTargetsCount = 0; for (int i = 0; i < allIdentifiers.Length; ++i) { string identifierTarget = allIdentifiers[i].Target; if (!string.IsNullOrEmpty(identifierTarget) && 0 > Array.BinarySearch <VerbalizationTargetData>(targets, new VerbalizationTargetData(identifierTarget, null), TargetKeyComparer.Instance)) { ++unknownTargetsCount; allIdentifiers[i] = default(VerbalizationSnippetsIdentifier); } } if (unknownTargetsCount != 0) { VerbalizationSnippetsIdentifier[] reducedIdentifiers = new VerbalizationSnippetsIdentifier[allIdentifiers.Length - unknownTargetsCount]; int currentValidIdentifier = 0; for (int i = 0; i < allIdentifiers.Length; ++i) { VerbalizationSnippetsIdentifier identifier = allIdentifiers[i]; if (!identifier.IsEmpty) { reducedIdentifiers[currentValidIdentifier] = identifier; ++currentValidIdentifier; } } allIdentifiers = reducedIdentifiers; } // Gather all types List <SnippetsType> types = new List <SnippetsType>(); SnippetsType currentType; foreach (IVerbalizationSnippetsProvider provider in snippetProviders) { VerbalizationSnippetsData[] currentData = provider.ProvideVerbalizationSnippets(); if (currentData != null) { for (int i = 0; i < currentData.Length; ++i) { currentType = default(SnippetsType); currentType.TypeDescription = currentData[i].TypeDescription; currentType.EnumTypeName = currentData[i].EnumType.FullName; types.Add(currentType); } } } // Sort first by type description types.Sort( delegate(SnippetsType type1, SnippetsType type2) { return(string.Compare(type1.TypeDescription, type2.TypeDescription, StringComparison.CurrentCultureIgnoreCase)); }); // Sort all identifiers. First by type description on previous sort, then // putting the default identifier first, then by explicit target types, then by the identifier description int typesCount = types.Count; Array.Sort <VerbalizationSnippetsIdentifier>( allIdentifiers, delegate(VerbalizationSnippetsIdentifier identifier1, VerbalizationSnippetsIdentifier identifier2) { int retVal = 0; string typeName1 = identifier1.EnumTypeName; string typeName2 = identifier2.EnumTypeName; if (typeName1 != typeName2) { int location1 = -1; for (int i = 0; i < typesCount; ++i) { if (types[i].EnumTypeName == typeName1) { location1 = i; break; } } int location2 = -1; for (int i = 0; i < typesCount; ++i) { if (types[i].EnumTypeName == typeName2) { location2 = i; break; } } retVal = location1.CompareTo(location2); } if (retVal == 0) { string target1 = identifier1.Target; string target2 = identifier2.Target; if (target1 != target2) { if (target1 == VerbalizationSnippetsIdentifier.DefaultTarget) { retVal = -1; } else if (target2 == VerbalizationSnippetsIdentifier.DefaultTarget) { retVal = 1; } else { retVal = string.Compare(GetVerbalizationTargetDisplayName(target1), GetVerbalizationTargetDisplayName(target2), StringComparison.CurrentCultureIgnoreCase); } } } if (retVal == 0) { bool isDefault1 = identifier1.IsDefaultIdentifier; bool isDefault2 = identifier2.IsDefaultIdentifier; if (isDefault1) { if (!isDefault2) { retVal = -1; } } else if (isDefault2) { retVal = 1; } } if (retVal == 0) { retVal = string.Compare(identifier1.Description, identifier2.Description, StringComparison.CurrentCultureIgnoreCase); } return(retVal); }); // Now get a count of all targeted types int allIdentifiersCount = allIdentifiers.Length; int targetedTypesCount = 0; string lastTarget = null; // Start with invalid target string lastEnumTypeName = null; for (int i = 0; i < allIdentifiersCount; ++i) { string currentTarget = allIdentifiers[i].Target; if (currentTarget != lastTarget) { lastEnumTypeName = allIdentifiers[i].EnumTypeName; lastTarget = currentTarget; ++targetedTypesCount; } else if (lastEnumTypeName != null) { string currentEnumTypeName = allIdentifiers[i].EnumTypeName; if (currentEnumTypeName != lastEnumTypeName) { lastEnumTypeName = currentEnumTypeName; ++targetedTypesCount; } } } // Allocate targeted types and bind targeted types to types TargetedSnippetsType[] targetedTypes = new TargetedSnippetsType[targetedTypesCount]; lastTarget = null; int currentTypeIndex = -1; currentType = default(SnippetsType); TargetedSnippetsType currentTargetedType = default(TargetedSnippetsType); int currentTargetIndex = -1; lastEnumTypeName = null; for (int i = 0; i < allIdentifiersCount; ++i) { string currentTarget = allIdentifiers[i].Target; string currentEnumTypeName = allIdentifiers[i].EnumTypeName; bool enumNameChanged = lastEnumTypeName == null || currentEnumTypeName != lastEnumTypeName; if (enumNameChanged || currentTarget != lastTarget) { ++currentTargetIndex; lastTarget = currentTarget; if (enumNameChanged) { lastEnumTypeName = currentEnumTypeName; if (currentTypeIndex != -1) { types[currentTypeIndex] = currentType; } currentType = types[++currentTypeIndex]; currentType.FirstExplicitlyTargetedType = -1; currentType.FirstTargetedType = currentTargetIndex; currentType.LastTargetedType = currentTargetIndex; } else { currentType.LastTargetedType += 1; } targetedTypes[currentTargetIndex].BindType(currentTypeIndex, currentTarget); } if (!string.IsNullOrEmpty(currentTarget) && currentType.FirstExplicitlyTargetedType == -1) { currentType.FirstExplicitlyTargetedType = currentTargetIndex; } } if (currentTypeIndex != -1) { types[currentTypeIndex] = currentType; } // Now, associate indices in the sorted allIdentifiersList with each targeted type int nextIdentifier = 0; for (int i = 0; i < targetedTypesCount; ++i) { currentTargetedType = targetedTypes[i]; string matchTypeName = types[currentTargetedType.TypeIndex].EnumTypeName; string matchTarget = currentTargetedType.Target; currentTargetedType.FirstIdentifier = nextIdentifier; currentTargetedType.LastIdentifier = nextIdentifier; currentTargetedType.CurrentIdentifier = nextIdentifier; Debug.Assert(allIdentifiers[nextIdentifier].IsDefaultIdentifier && allIdentifiers[nextIdentifier].EnumTypeName == matchTypeName, "No default snippets identifier for " + matchTypeName); ++nextIdentifier; bool matchedCurrent = currentIdentifiers == null; for (; nextIdentifier < allIdentifiersCount; ++nextIdentifier) { if (allIdentifiers[nextIdentifier].Target != matchTarget || allIdentifiers[nextIdentifier].EnumTypeName != matchTypeName) { break; } currentTargetedType.LastIdentifier = nextIdentifier; if (!matchedCurrent) { if (Array.IndexOf <VerbalizationSnippetsIdentifier>(currentIdentifiers, allIdentifiers[nextIdentifier]) >= 0) { currentTargetedType.CurrentIdentifier = nextIdentifier; matchedCurrent = true; } } } targetedTypes[i] = currentTargetedType; } myTargetedTypes = targetedTypes; myTypes = types; myIdentifiers = allIdentifiers; if (languageFormatString != null) { myItemStrings = new string[allIdentifiersCount]; } }