private static IEnumerable <PropertyTypeNode> ParseContainersSchema( IDictionary <string, object> d, Dictionary <string, PropertyTypeNode.TypeTag> injectBuiltinTypes) { var definitions = new List <PropertyTypeNode>(); if (!IsCompatibleVersion(d)) { throw new Exception($"Incompatible schema versions CurrentVersion : {CurrentVersion}"); } var referenceAssemblyNames = new List <string>(); if (d.ContainsKey(Keys.RequiredAssembliesKey)) { var assemblyNames = d[Keys.RequiredAssembliesKey] as IEnumerable; if (assemblyNames != null) { referenceAssemblyNames.AddRange(assemblyNames.OfType <string>().ToList()); } } if (d.ContainsKey(Keys.TypesKey)) { var types = d[Keys.TypesKey] as IEnumerable; if (types == null) { return(definitions); } // 1. Do a first pass to collect the list of symbols var builtinSymbols = new Dictionary <string, PropertyTypeNode.TypeTag>(); if (injectBuiltinTypes != null) { builtinSymbols = builtinSymbols.Union(injectBuiltinTypes) .ToDictionary(k => k.Key, v => v.Value); } CollectTypesFromTypeTree(types, builtinSymbols); // 2. Actual parsing var resolver = new TypeResolver(referenceAssemblyNames, builtinSymbols); definitions.AddRange( types.OfType <IDictionary <string, object> >().Select( e => PropertyTypeNodeJsonSerializer.FromJson(e, resolver) ) ); } // Post fix if (d.ContainsKey(Keys.NamespaceKey) && !string.IsNullOrEmpty(d[Keys.NamespaceKey] as string)) { var globalNamespace = d[Keys.NamespaceKey] as string; definitions = definitions.Select(definition => { if (string.IsNullOrEmpty(definition.TypePath.Namespace)) { definition.TypePath.Namespace = globalNamespace; } return(definition); }).ToList(); } return(definitions); }