public void AddRequiredAttributes(TagMatchingRuleDescriptorBuilder ruleBuilder)
        {
            if (string.IsNullOrEmpty(_requiredAttributes))
            {
                return;
            }
            var descriptors = new List <RequiredAttributeDescriptor>();

            PassOptionalWhitespace();

            do
            {
                var successfulParse = true;
                ruleBuilder.Attribute(attributeBuilder =>
                {
                    if (At('['))
                    {
                        if (!TryParseCssSelector(attributeBuilder))
                        {
                            successfulParse = false;
                            return;
                        }
                    }
                    else
                    {
                        ParsePlainSelector(attributeBuilder);
                    }

                    PassOptionalWhitespace();

                    if (At(','))
                    {
                        _index++;

                        if (!EnsureNotAtEnd(attributeBuilder))
                        {
                            successfulParse = false;
                            return;
                        }
                    }
                    else if (!AtEnd)
                    {
                        var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRequiredAttributeCharacter(Current, _requiredAttributes);
                        attributeBuilder.Diagnostics.Add(diagnostic);
                        successfulParse = false;
                        return;
                    }

                    PassOptionalWhitespace();
                });

                if (!successfulParse)
                {
                    break;
                }
            }while (!AtEnd);
        }
        private bool TryParseCssSelector(RequiredAttributeDescriptorBuilder attributeBuilder)
        {
            Debug.Assert(At('['));

            // Move past '['.
            _index++;
            PassOptionalWhitespace();

            ParseCssAttributeName(attributeBuilder);

            PassOptionalWhitespace();

            if (!EnsureNotAtEnd(attributeBuilder))
            {
                return(false);
            }

            if (!TryParseCssValueComparison(attributeBuilder, out RequiredAttributeDescriptor.ValueComparisonMode valueComparison))
            {
                return(false);
            }

            PassOptionalWhitespace();

            if (!EnsureNotAtEnd(attributeBuilder))
            {
                return(false);
            }

            if (valueComparison != RequiredAttributeDescriptor.ValueComparisonMode.None && !TryParseCssValue(attributeBuilder))
            {
                return(false);
            }

            PassOptionalWhitespace();

            if (At(']'))
            {
                // Move past the ending bracket.
                _index++;
                return(true);
            }
            else if (AtEnd)
            {
                var diagnostic = RazorDiagnosticFactory.CreateTagHelper_CouldNotFindMatchingEndBrace(_requiredAttributes);
                attributeBuilder.Diagnostics.Add(diagnostic);
            }
            else
            {
                var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRequiredAttributeCharacter(Current, _requiredAttributes);
                attributeBuilder.Diagnostics.Add(diagnostic);
            }

            return(false);
        }