package css_ast

import (
	
	
	
)
CSS syntax comes in two layers: a minimal syntax that generally accepts anything that looks vaguely like CSS, and a large set of built-in rules (the things browsers actually interpret). That way CSS parsers can read unknown rules and skip over them without having to stop due to errors. This AST format is mostly just the minimal syntax. It parses unknown rules into a tree with enough information that it can write them back out again. There are some additional layers of syntax including selectors and @-rules which allow for better pretty-printing and minification. Most of the AST just references ranges of the original file by keeping the original "Token" values around from the lexer. This is a memory-efficient representation that helps provide good parsing and printing performance.

type AST struct {
	ImportRecords []ast.ImportRecord
	Rules         []R
}
We create a lot of tokens, so make sure this layout is memory-efficient. The layout here isn't optimal because it biases for convenience (e.g. "string" could be shorter) but at least the ordering of fields was deliberately chosen to minimize size.
This is the raw contents of the token most of the time. However, it contains the decoded string contents for "TString" tokens.
	Text string // 16 bytes
Contains the child tokens for component values that are simple blocks. These are either "(", "{", "[", or function tokens. The closing token is implicit and is not stored.
	Children *[]Token // 8 bytes
URL tokens have an associated import record at the top-level of the AST. This index points to that import record.
The division between the number and the unit for "TDimension" tokens.
	UnitOffset uint16 // 2 bytes
This will never be "TWhitespace" because whitespace isn't stored as a token directly. Instead it is stored in "HasWhitespaceAfter" on the previous token. This is to make it easier to pattern-match against tokens when handling CSS rules, since whitespace almost always doesn't matter. That way you can pattern match against e.g. "rgb(r, g, b)" and not have to handle all possible combinations of embedded whitespace tokens. There is one exception to this: when in verbatim whitespace mode and the token list is non-empty and is only whitespace tokens. In that case a single whitespace token is emitted. This is because otherwise there would be no tokens to attach the whitespace before/after flags to.
	Kind css_lexer.T // 1 byte
These flags indicate the presence of a "TWhitespace" token before or after this token. There should be whitespace printed between two tokens if either token indicates that there should be whitespace. Note that whitespace may be altered by processing in certain situations (e.g. minification).
	Whitespace WhitespaceFlags // 1 byte
}

type WhitespaceFlags uint8

const (
	WhitespaceBefore WhitespaceFlags = 1 << iota
	WhitespaceAfter
)

func ( Token) () string {
	return .Text[:len(.Text)-1]
}

func ( Token) () string {
	return .Text[:.UnitOffset]
}

func ( Token) () string {
	return .Text[.UnitOffset:]
}
This interface is never called. Its purpose is to encode a variant type in Go's type system.
type R interface {
	isRule()
}

type RAtCharset struct {
	Encoding string
}

type RAtImport struct {
	ImportRecordIndex uint32
}

type RAtKeyframes struct {
	AtToken string
	Name    string
	Blocks  []KeyframeBlock
}

type KeyframeBlock struct {
	Selectors []string
	Rules     []R
}

type RKnownAt struct {
	AtToken string
	Prelude []Token
	Rules   []R
}

type RUnknownAt struct {
	AtToken string
	Prelude []Token
	Block   []Token
}

type RSelector struct {
	Selectors []ComplexSelector
	Rules     []R
}

type RQualified struct {
	Prelude []Token
	Rules   []R
}

type RDeclaration struct {
	KeyText   string
	Value     []Token
	KeyRange  logger.Range
	Key       D // Compare using this instead of "Key" for speed
	Important bool
}

type RBadDeclaration struct {
	Tokens []Token
}

func (*RAtCharset) ()      {}
func (*RAtImport) ()       {}
func (*RAtKeyframes) ()    {}
func (*RKnownAt) ()        {}
func (*RUnknownAt) ()      {}
func (*RSelector) ()       {}
func (*RQualified) ()      {}
func (*RDeclaration) ()    {}
func (*RBadDeclaration) () {}

type ComplexSelector struct {
	Selectors []CompoundSelector
}

type CompoundSelector struct {
	HasNestPrefix        bool   // "&"
	Combinator           string // Optional, may be ""
	TypeSelector         *NamespacedName
	SubclassSelectors    []SS
	PseudoClassSelectors []SSPseudoClass // If present, these follow a ":" character
}

type NameToken struct {
	Kind css_lexer.T
	Text string
}

If present, this is an identifier or "*" and is followed by a "|" character
This is an identifier or "*" or "&"
This interface is never called. Its purpose is to encode a variant type in Go's type system.
type SS interface {
	isSubclassSelector()
}

type SSHash struct {
	Name string
}

type SSClass struct {
	Name string
}

type SSAttribute struct {
	NamespacedName  NamespacedName
	MatcherOp       string
	MatcherValue    string
	MatcherModifier byte
}

type SSPseudoClass struct {
	Name string
	Args []Token
}

func (*SSHash) ()        {}
func (*SSClass) ()       {}
func (*SSAttribute) ()   {}