in stetho/src/main/java/com/facebook/stetho/inspector/elements/ShadowDocument.java [391:447]
private void validateTree(Map<Object, ElementInfo> elementToInfoMap) {
// We need a tree, not a forest.
HashSet<Object> rootElements = new HashSet<>();
for (Map.Entry<Object, ElementInfo> entry : elementToInfoMap.entrySet()) {
final Object element = entry.getKey();
final ElementInfo elementInfo = entry.getValue();
if (element != elementInfo.element) {
// should not be possible
throw new IllegalStateException("element != elementInfo.element");
}
// Verify children
for (int i = 0, N = elementInfo.children.size(); i < N; ++i) {
final Object childElement = elementInfo.children.get(i);
final ElementInfo childElementInfo = elementToInfoMap.get(childElement);
if (childElementInfo == null) {
throw new IllegalStateException(String.format(
"elementInfo.get(elementInfo.children.get(%s)) == null",
i));
}
if (childElementInfo.parentElement != element) {
throw new IllegalStateException("childElementInfo.parentElement != element");
}
}
// Verify parent
if (elementInfo.parentElement == null) {
rootElements.add(element);
} else {
final ElementInfo parentElementInfo = elementToInfoMap.get(elementInfo.parentElement);
if (parentElementInfo == null) {
throw new IllegalStateException(
"elementToInfoMap.get(elementInfo.parentElementInfo) == NULL");
}
if (elementInfo.parentElement != parentElementInfo.element) {
// should not be possible
throw new IllegalStateException(
"elementInfo.parentElementInfo != parentElementInfo.parent");
}
if (!parentElementInfo.children.contains(element)) {
throw new IllegalStateException(
"parentElementInfo.children.contains(element) == FALSE");
}
}
}
if (rootElements.size() != 1) {
throw new IllegalStateException(
"elementToInfoMap is a forest, not a tree. rootElements.size() != 1");
}
}