private PropertyTypeNode ParseContainer( IDictionary <string, object> t, ContainerTypeTreePath context, bool ignoreNamespace = false) { var containerTypeName = SafeGetKeyValue(t, JsonSchema.Keys.ContainerNameKey); if (string.IsNullOrWhiteSpace(containerTypeName)) { throw new Exception( $"Invalid container type (empty) while parsing json (path: '{context.FullPath}')"); } if (!ignoreNamespace) { context.Namespace = SafeGetKeyValue(t, JsonSchema.Keys.NamespaceKey); } var generatedUserHooks = SafeGetKeyValue(t, JsonSchema.Keys.GeneratedUserHooksKey); var overrideDefaultBaseClass = SafeGetKeyValue(t, JsonSchema.Keys.OverrideDefaultBaseClassKey); bool isAbstractClass; if (!bool.TryParse( SafeGetKeyValue(t, JsonSchema.Keys.IsAbstractClassKey), out isAbstractClass)) { isAbstractClass = PropertyTypeNode.Defaults.IsAbstractClass; } bool noDefaultImplementation; if (!bool.TryParse( SafeGetKeyValue(t, JsonSchema.Keys.NoDefaultImplementationKey), out noDefaultImplementation)) { noDefaultImplementation = PropertyTypeNode.Defaults.NoDefaultImplementation; } var n = new PropertyTypeNode { TypePath = new ContainerTypeTreePath(context), TypeName = containerTypeName, Tag = GetTypeTagFromPropertyName(containerTypeName, context), UserHooks = UserHooks.From(generatedUserHooks), OverrideDefaultBaseClass = overrideDefaultBaseClass, IsAbstractClass = isAbstractClass, Properties = ParseProperties(t, context), NativeType = TryExtractPropertyNativeType(containerTypeName), NoDefaultImplementation = noDefaultImplementation, }; if (t.ContainsKey(JsonSchema.Keys.ConstructedFromKey)) { var constructorParams = t[JsonSchema.Keys.ConstructedFromKey] as IEnumerable; var paramTypes = new List <KeyValuePair <string, string> >(); if (constructorParams != null) { paramTypes.AddRange(from object p in constructorParams select p as IDictionary <string, object> into dp let paramType = dp.ContainsKey(JsonSchema.Keys.PropertyTypeKey) ? (dp[JsonSchema.Keys.PropertyTypeKey] as string) : "" let paramName = dp.ContainsKey(JsonSchema.Keys.PropertyNameKey) ? (dp[JsonSchema.Keys.PropertyNameKey] as string) : "" where !string.IsNullOrEmpty(paramName) && !string.IsNullOrEmpty(paramType) select new KeyValuePair <string, string>(paramType, paramName)); } n.Constructor.ParameterTypes = paramTypes; } if (!t.ContainsKey(JsonSchema.Keys.NestedTypesKey) || !(t[JsonSchema.Keys.NestedTypesKey] is IEnumerable)) { return(n); } var nestedContainers = (IEnumerable)t[JsonSchema.Keys.NestedTypesKey]; context.TypePath.Push(containerTypeName); foreach (var nestedContainerEnumerable in nestedContainers) { var nestedContainer = nestedContainerEnumerable as IDictionary <string, object>; if (nestedContainer == null) { continue; } n.NestedContainers.Add( ParseContainer( nestedContainer, context, true ) ); } context.TypePath.Pop(); return(n); }
private static void ParseContainersSchema(IDictionary <string, object> d, List <PropertyTypeNode> definitions) { Assert.IsNotNull(definitions); var ns = d.ContainsKey(SerializedKeys.NamespaceKey) ? (d[SerializedKeys.NamespaceKey] as string) : ""; var symbolsTable = new Dictionary <string, PropertyTypeNode>(); if (d.ContainsKey(SerializedKeys.TypesKey)) { // 1. First pass // Here we just check the meta info for the types // to fill some sort of a symbol table. Those meta info // will then useful in the case of // types cross referencing other types in that schema, so that // we know what that user defined type is (value type). // We could add am optional { "IsValueType": false } to all the subtypes // but it would be redundant (every time a type could refer that another // it would duplicate that info ..). var types = d[SerializedKeys.TypesKey] as IEnumerable; if (types != null) { foreach (var type in types) { var t = type as IDictionary <string, object>; if (t != null) { var containerTypeName = SafeGetKeyValue(t, SerializedKeys.ContainerNameKey); var generatedUserHooks = SafeGetKeyValue(t, SerializedKeys.GeneratedUserHooksKey); var overrideDefaultBaseClass = SafeGetKeyValue(t, SerializedKeys.OverrideDefaultBaseClassKey); bool isAbstractClass; if (!Boolean.TryParse( SafeGetKeyValue(t, SerializedKeys.IsAbstractClassKey), out isAbstractClass)) { isAbstractClass = false; } var n = new PropertyTypeNode { Namespace = ns, Name = containerTypeName, TypeName = containerTypeName, RawNode = t, Tag = TypeTagForSymbol(t), UserHooks = UserHooks.From(generatedUserHooks), OverrideDefaultBaseClass = overrideDefaultBaseClass, IsAbstractClass = isAbstractClass }; if (n.Name != null) { symbolsTable[n.Name] = n; } } } } // 2. Second pass foreach (var symbol in symbolsTable) { var node = symbol.Value; ParsePropertyContainer(node, symbolsTable); definitions.Add(node); } } }