private static Org.Apache.REEF.Tang.Protobuf.Node NewClassNode(string name,
                                                                       string fullName, bool isInjectionCandidate,
                                                                       bool isExternalConstructor, bool isUnit,
                                                                       IList <Org.Apache.REEF.Tang.Protobuf.ConstructorDef> injectableConstructors,
                                                                       IList <Org.Apache.REEF.Tang.Protobuf.ConstructorDef> otherConstructors,
                                                                       IList <string> implFullNames, IList <Org.Apache.REEF.Tang.Protobuf.Node> children)
        {
            Org.Apache.REEF.Tang.Protobuf.ClassNode classNode = new Org.Apache.REEF.Tang.Protobuf.ClassNode();
            classNode.is_injection_candidate = isInjectionCandidate;
            foreach (var ic in injectableConstructors)
            {
                classNode.InjectableConstructors.Add(ic);
            }

            foreach (var oc in otherConstructors)
            {
                classNode.OtherConstructors.Add(oc);
            }
            foreach (var implFullName in implFullNames)
            {
                classNode.impl_full_names.Add(implFullName);
            }

            Org.Apache.REEF.Tang.Protobuf.Node n = new Org.Apache.REEF.Tang.Protobuf.Node();
            n.name       = name;
            n.full_name  = fullName;
            n.class_node = classNode;

            foreach (var c in children)
            {
                n.children.Add(c);
            }

            return(n);
        }
        public static void Serialize(string fileName, IClassHierarchy classHierarchy)
        {
            Org.Apache.REEF.Tang.Protobuf.Node node = Serialize(classHierarchy);

            using (var file = File.Create(fileName))
            {
                Serializer.Serialize <Org.Apache.REEF.Tang.Protobuf.Node>(file, node);
            }
        }
 private void WireUpInheritanceRelationships(Org.Apache.REEF.Tang.Protobuf.Node n)
 {
     if (n.class_node != null)
     {
         Org.Apache.REEF.Tang.Protobuf.ClassNode cn = n.class_node;
         IClassNode iface = null;
         try
         {
             iface = (IClassNode)GetNode(n.full_name);
         }
         catch (NameResolutionException e)
         {
             Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
             var ex = new IllegalStateException("When reading protocol buffer node "
                                                + n.full_name + " does not exist.  Full record is " + n, e);
             Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
         }
         foreach (string impl in cn.impl_full_names)
         {
             try
             {
                 iface.PutImpl((IClassNode)GetNode(impl));
             }
             catch (NameResolutionException e)
             {
                 Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
                 var ex = new IllegalStateException("When reading protocol buffer node "
                                                    + n + " refers to non-existent implementation:" + impl);
                 Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
             }
             catch (InvalidCastException e)
             {
                 Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
                 try
                 {
                     var ex = new IllegalStateException(
                         "When reading protocol buffer node " + n
                         + " found implementation" + GetNode(impl)
                         + " which is not a ClassNode!");
                     Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
                 }
                 catch (NameResolutionException ne)
                 {
                     Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Caught(ne, Level.Error, LOGGER);
                     var ex = new IllegalStateException(
                         "Got 'cant happen' exception when producing error message for " + e);
                     Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
                 }
             }
         }
     }
 }
        private static void ParseSubHierarchy(INode parent, Org.Apache.REEF.Tang.Protobuf.Node n)
        {
            INode parsed = null;

            if (n.package_node != null)
            {
                parsed = new PackageNodeImpl(parent, n.name, n.full_name);
            }
            else if (n.named_parameter_node != null)
            {
                Org.Apache.REEF.Tang.Protobuf.NamedParameterNode np = n.named_parameter_node;
                parsed = new NamedParameterNodeImpl(parent, n.name,
                                                    n.full_name, np.full_arg_class_name, np.simple_arg_class_name,
                                                    np.is_set, np.is_list, np.documentation, np.short_name,
                                                    np.instance_default.ToArray());
            }
            else if (n.class_node != null)
            {
                Org.Apache.REEF.Tang.Protobuf.ClassNode cn     = n.class_node;
                IList <IConstructorDef> injectableConstructors = new List <IConstructorDef>();
                IList <IConstructorDef> allConstructors        = new List <IConstructorDef>();

                foreach (Org.Apache.REEF.Tang.Protobuf.ConstructorDef injectable in cn.InjectableConstructors)
                {
                    IConstructorDef def = ParseConstructorDef(injectable, true);
                    injectableConstructors.Add(def);
                    allConstructors.Add(def);
                }
                foreach (Org.Apache.REEF.Tang.Protobuf.ConstructorDef other in cn.OtherConstructors)
                {
                    IConstructorDef def = ParseConstructorDef(other, false);
                    allConstructors.Add(def);
                }

                IConstructorDef[] dummy = new ConstructorDefImpl[0];
                parsed = new ClassNodeImpl(parent, n.name, n.full_name,
                                           cn.is_unit, cn.is_injection_candidate,
                                           cn.is_external_constructor, injectableConstructors,
                                           allConstructors, cn.default_implementation);
            }
            else
            {
                Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Bad protocol buffer: got abstract node" + n), LOGGER);
            }

            foreach (Org.Apache.REEF.Tang.Protobuf.Node child in n.children)
            {
                ParseSubHierarchy(parsed, child);
            }
        }
        private static Org.Apache.REEF.Tang.Protobuf.Node NewNamedParameterNode(string name,
                                                                                string fullName, string simpleArgClassName, string fullArgClassName,
                                                                                bool isSet, bool isList, string documentation, // can be null
                                                                                string shortName,                              // can be null
                                                                                string[] instanceDefault,                      // can be null
                                                                                IList <Org.Apache.REEF.Tang.Protobuf.Node> children,
                                                                                string alias, Language aliasLanguage)
        {
            Org.Apache.REEF.Tang.Protobuf.NamedParameterNode namedParameterNode = new Org.Apache.REEF.Tang.Protobuf.NamedParameterNode();
            namedParameterNode.simple_arg_class_name = simpleArgClassName;
            namedParameterNode.full_arg_class_name   = fullArgClassName;
            namedParameterNode.is_set  = isSet;
            namedParameterNode.is_list = isList;

            if (documentation != null)
            {
                namedParameterNode.documentation = documentation;
            }

            if (shortName != null)
            {
                namedParameterNode.short_name = shortName;
            }

            if (alias != null)
            {
                namedParameterNode.alias_name = alias;
            }

            namedParameterNode.alias_language = aliasLanguage.ToString();

            foreach (var id in instanceDefault)
            {
                namedParameterNode.instance_default.Add(id);
            }

            Org.Apache.REEF.Tang.Protobuf.Node n = new Org.Apache.REEF.Tang.Protobuf.Node();
            n.name                 = name;
            n.full_name            = fullName;
            n.named_parameter_node = namedParameterNode;

            foreach (var c in children)
            {
                n.children.Add(c);
            }

            return(n);
        }
        private static Org.Apache.REEF.Tang.Protobuf.Node NewPackageNode(string name,
                                                                         string fullName, IList <Org.Apache.REEF.Tang.Protobuf.Node> children)
        {
            Org.Apache.REEF.Tang.Protobuf.PackageNode packageNode = new Org.Apache.REEF.Tang.Protobuf.PackageNode();
            Org.Apache.REEF.Tang.Protobuf.Node        n           = new Org.Apache.REEF.Tang.Protobuf.Node();
            n.name         = name;
            n.full_name    = fullName;
            n.package_node = packageNode;

            foreach (var c in children)
            {
                n.children.Add(c);
            }

            return(n);
        }
        public ProtocolBufferClassHierarchy(Org.Apache.REEF.Tang.Protobuf.Node root)
        {
            this.rootNode = new PackageNodeImpl();
            if (root.package_node == null)
            {
                Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException("Expected a package node.  Got: " + root), LOGGER);
            }
            // Register all the classes.
            foreach (Org.Apache.REEF.Tang.Protobuf.Node child in root.children)
            {
                ParseSubHierarchy(rootNode, child);
            }

            BuildHashTable(rootNode);

            foreach (Org.Apache.REEF.Tang.Protobuf.Node child in root.children)
            {
                WireUpInheritanceRelationships(child);
            }
        }
        private static void ParseSubHierarchy(INode parent, Org.Apache.REEF.Tang.Protobuf.Node n)
        {
            INode parsed = null;

            if (n.package_node != null)
            {
                parsed = new PackageNodeImpl(parent, n.name, n.full_name);
            }
            else if (n.named_parameter_node != null)
            {
                Org.Apache.REEF.Tang.Protobuf.NamedParameterNode np = n.named_parameter_node;

                if (!string.IsNullOrWhiteSpace(np.alias_name) && !string.IsNullOrWhiteSpace(np.alias_language))
                {
                    Language language;
                    try
                    {
                        Enum.TryParse(np.alias_language, true, out language);
                    }
                    catch (Exception)
                    {
                        string msg = string.Format(CultureInfo.CurrentCulture, "Language {0} passed in is not supported", np.alias_language);
                        throw new ArgumentException(msg);
                    }

                    parsed = new NamedParameterNodeImpl(parent, n.name,
                                                        n.full_name, np.full_arg_class_name, np.simple_arg_class_name,
                                                        np.is_set, np.is_list, np.documentation, np.short_name,
                                                        np.instance_default.ToArray(), np.alias_name, language);
                }
                else
                {
                    parsed = new NamedParameterNodeImpl(parent, n.name,
                                                        n.full_name, np.full_arg_class_name, np.simple_arg_class_name,
                                                        np.is_set, np.is_list, np.documentation, np.short_name,
                                                        np.instance_default.ToArray());
                }
            }
            else if (n.class_node != null)
            {
                Org.Apache.REEF.Tang.Protobuf.ClassNode cn     = n.class_node;
                IList <IConstructorDef> injectableConstructors = new List <IConstructorDef>();
                IList <IConstructorDef> allConstructors        = new List <IConstructorDef>();

                foreach (Org.Apache.REEF.Tang.Protobuf.ConstructorDef injectable in cn.InjectableConstructors)
                {
                    IConstructorDef def = ParseConstructorDef(injectable, true);
                    injectableConstructors.Add(def);
                    allConstructors.Add(def);
                }
                foreach (Org.Apache.REEF.Tang.Protobuf.ConstructorDef other in cn.OtherConstructors)
                {
                    IConstructorDef def = ParseConstructorDef(other, false);
                    allConstructors.Add(def);
                }

                IConstructorDef[] dummy = new ConstructorDefImpl[0];
                parsed = new ClassNodeImpl(parent, n.name, n.full_name,
                                           cn.is_unit, cn.is_injection_candidate,
                                           cn.is_external_constructor, injectableConstructors,
                                           allConstructors, cn.default_implementation);
            }
            else
            {
                Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Bad protocol buffer: got abstract node" + n), LOGGER);
            }

            foreach (Org.Apache.REEF.Tang.Protobuf.Node child in n.children)
            {
                ParseSubHierarchy(parsed, child);
            }
        }
        private static Org.Apache.REEF.Tang.Protobuf.Node NewPackageNode(string name,
            string fullName, IList<Org.Apache.REEF.Tang.Protobuf.Node> children)
        {
            Org.Apache.REEF.Tang.Protobuf.PackageNode packageNode = new Org.Apache.REEF.Tang.Protobuf.PackageNode();
            Org.Apache.REEF.Tang.Protobuf.Node n = new Org.Apache.REEF.Tang.Protobuf.Node();
            n.name = name;
            n.full_name = fullName;
            n.package_node = packageNode;

            foreach (var c in children)
            {
                n.children.Add(c);
            }

            return n;
        }
        private static Org.Apache.REEF.Tang.Protobuf.Node NewNamedParameterNode(string name,
            string fullName, string simpleArgClassName, string fullArgClassName,
            bool isSet, bool isList, string documentation, // can be null
            string shortName, // can be null
            string[] instanceDefault, // can be null
            IList<Org.Apache.REEF.Tang.Protobuf.Node> children,
            string alias, Language aliasLanguage)
        {
            Org.Apache.REEF.Tang.Protobuf.NamedParameterNode namedParameterNode = new Org.Apache.REEF.Tang.Protobuf.NamedParameterNode();
            namedParameterNode.simple_arg_class_name = simpleArgClassName;
            namedParameterNode.full_arg_class_name = fullArgClassName;
            namedParameterNode.is_set = isSet;
            namedParameterNode.is_list = isList;

            if (documentation != null)
            {
                namedParameterNode.documentation = documentation;
            }

            if (shortName != null)
            {
                namedParameterNode.short_name = shortName;
            }

            if (alias != null)
            {
                namedParameterNode.alias_name = alias;
            }

            namedParameterNode.alias_language = aliasLanguage.ToString();

            foreach (var id in instanceDefault)
            {
                namedParameterNode.instance_default.Add(id);
            }

            Org.Apache.REEF.Tang.Protobuf.Node n = new Org.Apache.REEF.Tang.Protobuf.Node();
            n.name = name;
            n.full_name = fullName;
            n.named_parameter_node = namedParameterNode;

            foreach (var c in children)
            {
                n.children.Add(c);
            }

            return n;
        }
        private static Org.Apache.REEF.Tang.Protobuf.Node NewClassNode(String name,
            String fullName, bool isInjectionCandidate,
            bool isExternalConstructor, bool isUnit,
            IList<Org.Apache.REEF.Tang.Protobuf.ConstructorDef> injectableConstructors,
            IList<Org.Apache.REEF.Tang.Protobuf.ConstructorDef> otherConstructors,
            IList<String> implFullNames, IList<Org.Apache.REEF.Tang.Protobuf.Node> children)
        {
            Org.Apache.REEF.Tang.Protobuf.ClassNode classNode = new Org.Apache.REEF.Tang.Protobuf.ClassNode();
            classNode.is_injection_candidate = isInjectionCandidate;
            foreach (var ic in injectableConstructors)
            {
                classNode.InjectableConstructors.Add(ic);
            }

            foreach (var oc in otherConstructors)
            {
                classNode.OtherConstructors.Add(oc);
            }
            foreach (var implFullName in implFullNames)
            {
                classNode.impl_full_names.Add(implFullName);
            }

            Org.Apache.REEF.Tang.Protobuf.Node n = new Org.Apache.REEF.Tang.Protobuf.Node();
            n.name = name;
            n.full_name = fullName;
            n.class_node = classNode;

            foreach (var c in children)
            {
                n.children.Add(c);
            }

            return n;
        }