private static void parseSubHierarchy(Node parent, ClassHierarchyProto.Node n) { final Node parsed; if (n.hasPackageNode()) { parsed = new PackageNodeImpl(parent, n.getName(), n.getFullName()); } else if (n.hasNamedParameterNode()) { ClassHierarchyProto.NamedParameterNode np = n.getNamedParameterNode(); parsed = new NamedParameterNodeImpl<Object>( parent, n.getName(), n.getFullName(), np.getFullArgClassName(), np.getSimpleArgClassName(), np.getIsSet(), np.getIsList(), np.getDocumentation(), np.getShortName(), np.getInstanceDefaultList().toArray(new String[0])); } else if (n.hasClassNode()) { ClassHierarchyProto.ClassNode cn = n.getClassNode(); List<ConstructorDef<?>> injectableConstructors = new ArrayList<>(); List<ConstructorDef<?>> allConstructors = new ArrayList<>(); for (ClassHierarchyProto.ConstructorDef injectable : cn.getInjectableConstructorsList()) { ConstructorDef<?> def = parseConstructorDef(injectable, true); injectableConstructors.add(def); allConstructors.add(def); } for (ClassHierarchyProto.ConstructorDef other : cn.getOtherConstructorsList()) { ConstructorDef<?> def = parseConstructorDef(other, false); allConstructors.add(def); } @SuppressWarnings("unchecked") ConstructorDef<Object>[] dummy = new ConstructorDef[0]; parsed = new ClassNodeImpl<>( parent, n.getName(), n.getFullName(), cn.getIsUnit(), cn.getIsInjectionCandidate(), cn.getIsExternalConstructor(), injectableConstructors.toArray(dummy), allConstructors.toArray(dummy), cn.getDefaultImplementation()); } else { throw new IllegalStateException("Bad protocol buffer: got abstract node" + n); } for (ClassHierarchyProto.Node child : n.getChildrenList()) { parseSubHierarchy(parsed, child); } }