private void checkTagByDescriptor(final XmlTag tag) {
    String name = tag.getName();

    XmlElementDescriptor elementDescriptor;

    final PsiElement parent = tag.getParent();
    if (parent instanceof XmlTag) {
      XmlTag parentTag = (XmlTag) parent;

      elementDescriptor = XmlUtil.getDescriptorFromContext(tag);

      final XmlElementDescriptor parentDescriptor = parentTag.getDescriptor();

      if (parentDescriptor != null && elementDescriptor == null && shouldBeValidated(tag)) {
        if (tag instanceof HtmlTag) {
          // XmlEntitiesInspection inspection = getInspectionProfile(tag,
          // HtmlStyleLocalInspection.SHORT_NAME);
          // if (inspection != null /*&&
          // isAdditionallyDeclared(inspection.getAdditionalEntries(XmlEntitiesInspection.UNKNOWN_TAG), name)*/) {
          return;
          // }
        }

        addElementsForTag(
            tag,
            XmlErrorMessages.message("element.is.not.allowed.here", name),
            getTagProblemInfoType(tag),
            null);
        return;
      }

      if (elementDescriptor instanceof AnyXmlElementDescriptor || elementDescriptor == null) {
        elementDescriptor = tag.getDescriptor();
      }

      if (elementDescriptor == null) return;
    } else {
      // root tag
      elementDescriptor = tag.getDescriptor();

      if (elementDescriptor == null) {
        addElementsForTag(
            tag,
            XmlErrorMessages.message("element.must.be.declared", name),
            HighlightInfoType.WRONG_REF,
            null);
        return;
      }
    }

    checkRequiredAttributes(tag, name, elementDescriptor);

    if (elementDescriptor instanceof Validator) {
      //noinspection unchecked
      ((Validator<XmlTag>) elementDescriptor).validate(tag, this);
    }
  }
  @Override
  protected void checkTag(
      @NotNull final XmlTag tag, @NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
    if (!(tag instanceof HtmlTag)
        || !XmlHighlightVisitor.shouldBeValidated(tag)
        || isInSpecialHtml5Namespace(tag)) {
      return;
    }

    XmlElementDescriptor descriptorFromContext = XmlUtil.getDescriptorFromContext(tag);

    PsiElement parent = tag.getParent();
    XmlElementDescriptor parentDescriptor =
        parent instanceof XmlTag ? ((XmlTag) parent).getDescriptor() : null;

    XmlElementDescriptor ownDescriptor =
        isAbstractDescriptor(descriptorFromContext) ? tag.getDescriptor() : descriptorFromContext;

    if (isAbstractDescriptor(ownDescriptor)
        || (parentDescriptor instanceof HtmlElementDescriptorImpl
            && ownDescriptor instanceof HtmlElementDescriptorImpl
            && isAbstractDescriptor(descriptorFromContext))) {

      final String name = tag.getName();

      if (!isCustomValuesEnabled() || !isCustomValue(name)) {
        final AddCustomTagOrAttributeIntentionAction action =
            new AddCustomTagOrAttributeIntentionAction(
                TAG_KEY, name, XmlEntitiesInspection.UNKNOWN_TAG);

        // todo: support "element is not allowed" message for html5
        // some tags in html5 cannot be found in xhtml5.xsd if they are located in incorrect
        // context, so they get any-element descriptor (ex. "canvas: tag)
        final String message =
            isAbstractDescriptor(ownDescriptor)
                ? XmlErrorMessages.message("unknown.html.tag", name)
                : XmlErrorMessages.message("element.is.not.allowed.here", name);

        final PsiElement startTagName = XmlTagUtil.getStartTagNameElement(tag);
        assert startTagName != null;
        final PsiElement endTagName = XmlTagUtil.getEndTagNameElement(tag);

        List<LocalQuickFix> quickfixes = new ArrayList<LocalQuickFix>();
        quickfixes.add(action);
        if (isOnTheFly) {
          ContainerUtil.addIfNotNull(
              CreateNSDeclarationIntentionFix.createFix(startTagName, ""), quickfixes);
        }
        if (HtmlUtil.isHtml5Tag(name) && !HtmlUtil.hasNonHtml5Doctype(tag)) {
          quickfixes.add(new SwitchToHtml5WithHighPriorityAction());
        }
        ProblemHighlightType highlightType =
            tag.getContainingFile().getContext() == null
                ? ProblemHighlightType.GENERIC_ERROR_OR_WARNING
                : ProblemHighlightType.INFORMATION;
        if (startTagName.getTextLength() > 0) {
          holder.registerProblem(
              startTagName,
              message,
              highlightType,
              quickfixes.toArray(new LocalQuickFix[quickfixes.size()]));
        }

        if (endTagName != null) {
          holder.registerProblem(
              endTagName,
              message,
              highlightType,
              quickfixes.toArray(new LocalQuickFix[quickfixes.size()]));
        }
      }
    }
  }