private FlatBuffersSchemaTypeDependencyNode AddNode(FlatBuffersSchemaTypeDependencyNode node)
        {
            var typeModel = node.TypeModel;

            if (!typeModel.IsObject && !typeModel.IsEnum && !typeModel.IsUnion)
            {
                return(null);
            }

            // TODO: Perhaps a dictionary?
            if (_nodes.Any(i => i.TypeModel.Name == typeModel.Name))
            {
                throw new ArgumentException("TypeModel already exists");
            }

            var dependentTypes = GetDependentTypes(node);

            foreach (var depType in dependentTypes)
            {
                if (_nodes.All(i => i.TypeModel.Name != depType.TypeModel.Name))
                {
                    if (depType.TypeModel != null)
                    {
                        AddType(depType.TypeModel);
                    }
                }
            }

            node.AddDependencies(dependentTypes);
            _nodes.Add(node);
            return(node);
        }
 internal void AddDependency(FlatBuffersSchemaTypeDependencyNode typeModel)
 {
     if (_dependentTypes.All(i => i.TypeModel.Name != typeModel.TypeModel.Name))
     {
         _dependentTypes.Add(typeModel);
     }
 }
 private void ResolveDependency(FlatBuffersSchemaTypeDependencyNode node, ICollection <FlatBuffersSchemaTypeDependencyNode> resolved, ICollection <FlatBuffersSchemaTypeDependencyNode> seen)
 {
     seen.Add(node);
     foreach (var dep in node.DependentTypes)
     {
         if (resolved.All(i => i.TypeModel.Name != dep.TypeModel.Name))
         {
             if (seen.Any(i => i.TypeModel.Name == dep.TypeModel.Name))
             {
                 throw new Exception(string.Format("Circular dependency detected between {0} -> {1}", node.TypeModel.Name, dep.TypeModel.Name));
             }
             ResolveDependency(dep, resolved, seen);
         }
     }
     resolved.Add(node);
 }
        /// <summary>
        /// Sets the Root <see cref="TypeModel"/> of this schema
        /// </summary>
        /// <param name="typeModel">The root type</param>
        /// <returns>A dependency node for the root type</returns>
        public FlatBuffersSchemaTypeDependencyNode SetRootType(TypeModel typeModel)
        {
            if (HasRootType)
            {
                throw new FlatBuffersSchemaException("Schema already has a root type");
            }

            if (!typeModel.IsObject)
            {
                throw new FlatBuffersSchemaException("Type must be a Table or Struct type to be used as a root type");
            }

            var node = AddType(typeModel);

            _rootTypeNode = node;
            return(node);
        }
 internal FlatBuffersSchemaTypeDependencyNode(TypeModel typeModel, FlatBuffersSchemaTypeDependencyNode parent)
 {
     TypeModel = typeModel;
     Parent    = parent;
 }
        private List <FlatBuffersSchemaTypeDependencyNode> GetDependentTypes(FlatBuffersSchemaTypeDependencyNode node)
        {
            var deps      = new List <FlatBuffersSchemaTypeDependencyNode>();
            var typeModel = node.TypeModel;

            if (!typeModel.IsObject)
            {
                return(deps);
            }

            var structDef = typeModel.StructDef;

            foreach (var field in structDef.Fields)
            {
                if (field.TypeModel.IsVector && field.TypeModel.ElementType == BaseType.Struct)
                {
                    var elementType = field.TypeModel.GetElementTypeModel();

                    if (elementType != null)
                    {
                        deps.Add(GetDependencyNode(elementType, node));
                    }

                    continue;
                }

                if (!field.TypeModel.IsObject && !field.TypeModel.IsEnum && !field.TypeModel.IsUnion && !field.TypeModel.IsUnion)
                {
                    continue;
                }

                if (field.TypeModel.IsUnion)
                {
                    var unionDeps = field.TypeModel.UnionDef.Fields.Where(i => i.MemberType != null).Select(i => GetDependencyNode(i.MemberType, node));
                    foreach (var u in unionDeps)
                    {
                        if (deps.All(i => i.TypeModel != null && i.TypeModel.Name != u.TypeModel.Name))
                        {
                            deps.Add(GetDependencyNode(u.TypeModel, node));
                        }
                    }
                }

                if (field.TypeModel.IsVector && field.TypeModel.ElementType == BaseType.Struct)
                {
                    var elementType = field.TypeModel.GetElementTypeModel();

                    if (elementType != null)
                    {
                        deps.Add(GetDependencyNode(elementType, node));
                    }

                    continue;
                }

                if (field.HasNestedFlatBufferType)
                {
                    if (deps.All(i => i.TypeModel.Name != field.NestedFlatBufferType.Name))
                    {
                        deps.Add(GetDependencyNode(field.NestedFlatBufferType, node));
                    }
                }

                if (deps.All(i => i.TypeModel.Name != field.TypeModel.Name))
                {
                    deps.Add(GetDependencyNode(field.TypeModel, node));
                }
            }
            return(deps);
        }
        private FlatBuffersSchemaTypeDependencyNode GetDependencyNode(TypeModel typeModel, FlatBuffersSchemaTypeDependencyNode parent)
        {
            var dep = _nodes.FirstOrDefault(i => i.TypeModel.Name == typeModel.Name);

            return(dep ?? new FlatBuffersSchemaTypeDependencyNode(typeModel, parent));
        }