@Override
  protected void checkTag(@NotNull XmlTag tag, @NotNull ProblemsHolder holder, boolean isOnTheFly) {

    String name = tag.getName();
    XmlElementDescriptor elementDescriptor = XmlUtil.getDescriptorFromContext(tag);
    if (elementDescriptor instanceof AnyXmlElementDescriptor || elementDescriptor == null) {
      elementDescriptor = tag.getDescriptor();
    }

    if (elementDescriptor == null) return;
    if ((elementDescriptor instanceof XmlHighlightingAwareElementDescriptor) &&
        !((XmlHighlightingAwareElementDescriptor)elementDescriptor).shouldCheckRequiredAttributes()) {
      return;
    }

    XmlAttributeDescriptor[] attributeDescriptors = elementDescriptor.getAttributesDescriptors(tag);
    Set<String> requiredAttributes = null;

    for (XmlAttributeDescriptor attribute : attributeDescriptors) {
      if (attribute != null && attribute.isRequired()) {
        if (requiredAttributes == null) {
          requiredAttributes = new HashSet<>();
        }
        requiredAttributes.add(attribute.getName(tag));
      }
    }

    if (requiredAttributes != null) {
      for (final String attrName : requiredAttributes) {
        if (!hasAttribute(tag, attrName) &&
            !XmlExtension.getExtension(tag.getContainingFile()).isRequiredAttributeImplicitlyPresent(tag, attrName)) {

          LocalQuickFix insertRequiredAttributeIntention =
            isOnTheFly ? XmlQuickFixFactory.getInstance().insertRequiredAttributeFix(tag, attrName) : null;
          final String localizedMessage =
            XmlAnalysisBundle.message("xml.inspections.element.doesnt.have.required.attribute", name, attrName);
          reportOneTagProblem(
            tag,
            attrName,
            localizedMessage,
            insertRequiredAttributeIntention,
            holder,
            getIntentionAction(attrName),
            isOnTheFly
          );
        }
      }
    }
  }
@Override
  protected void checkTag(@NotNull XmlTag tag, @NotNull ProblemsHolder holder, boolean isOnTheFly)