List<XmlElementDescriptor> (XmlElementsGroup group) { if (group.getMinOccurs() < 1) return Collections.emptyList(); switch (group.getGroupType()) { case LEAF -> { XmlElementDescriptor descriptor = group.getLeafDescriptor(); if (descriptor == null) return Collections.emptyList(); PsiElement declaration = descriptor.getDeclaration(); // don't add abstract elements to required sub tags list if (declaration instanceof XmlTag) { XmlTag tag = (XmlTag)descriptor.getDeclaration(); String abstractValue = tag.getAttributeValue("abstract", XMLConstants.W3C_XML_SCHEMA_NS_URI); if ("true".equals(abstractValue)) { return Collections.emptyList(); } } return Collections.singletonList(descriptor); } case CHOICE -> { LinkedHashSet<XmlElementDescriptor> set = null; for (XmlElementsGroup subGroup : group.getSubGroups()) { List<XmlElementDescriptor> descriptors = computeRequiredSubTags(subGroup); if (set == null) { set = new LinkedHashSet<>(descriptors); } else { set.retainAll(descriptors); } } if (set == null || set.isEmpty()) { return Collections.singletonList(null); // placeholder for smart completion } return new ArrayList<>(set); } default -> { ArrayList<XmlElementDescriptor> list = new ArrayList<>(); for (XmlElementsGroup subGroup : group.getSubGroups()) { list.addAll(computeRequiredSubTags(subGroup)); } return list; } } }