func (s *Subscripting) AsProto() *pb.Expression {
	identifier := s.Array.AsProto().GetIdentifier()
	identifier.Items = append(identifier.GetItems(), &pb.Identifier_IdentifierItem{
		Item: &pb.Identifier_IdentifierItem_Index{
			Index: s.Index.AsProto(),
		},
	})
	return &pb.Expression{
		Expression: &pb.Expression_Identifier{
			Identifier: identifier,
		},
	}
}
AsProto returns the Expression serialized as a pb.Expression.
package ast
import (
	"fmt"
	"io"
	"strings"
	"github.com/VirusTotal/gyp/pb"
	"github.com/golang/protobuf/proto"
)
type Node interface {
	WriteSource(io.Writer) error
	Children() []Node
}
type Expression interface {
	Node
	AsProto() *pb.Expression
}
type Keyword string
const (
	KeywordAll        Keyword = "all"
	KeywordAny        Keyword = "any"
	KeywordNone       Keyword = "none"
	KeywordEntrypoint Keyword = "entrypoint"
	KeywordFalse      Keyword = "false"
	KeywordFilesize   Keyword = "filesize"
	KeywordThem       Keyword = "them"
	KeywordTrue       Keyword = "true"
)
type Group struct {
	Expression
}
type LiteralInteger struct {
	Value int64
}
type LiteralFloat struct {
	Value float64
}
type LiteralString struct {
	Value string
}
type RegexpModifiers int
const (
	_ = iota
	RegexpCaseInsensitive RegexpModifiers = 1 << iota
	RegexpDotAll
)
type LiteralRegexp struct {
	Value     string
	Modifiers RegexpModifiers
}
type Minus struct {
	Expression
}
type Not struct {
	Expression
}
type BitwiseNot struct {
	Expression
}
type Range struct {
	Start Expression
	End   Expression
}
type Enum struct {
	Values []Expression
}
type Identifier struct {
	Identifier string
}
type StringIdentifier struct {
	Identifier string
	At         Expression
	In         *Range
}
type StringCount struct {
	Identifier string
}
type StringOffset struct {
	Identifier string
	Index      Expression
}
type StringLength struct {
	Identifier string
	Index      Expression
}
type FunctionCall struct {
	Callable  Expression
	Arguments []Expression
}
type MemberAccess struct {
	Container Expression
	Member    string
}
type Subscripting struct {
	Array Expression
	Index Expression
}
type Quantifier struct {
	Expression
}
type ForIn struct {
	Quantifier *Quantifier
	Variables  []string
	Iterator   Node
	Condition  Expression
}
type ForOf struct {
	Quantifier *Quantifier
	Strings    Node
	Condition  Expression
}
type Of struct {
	Quantifier *Quantifier
	Strings    Node
}
type Operation struct {
	Operator OperatorType
	Operands []Expression
}
func (l *LiteralString) String() string {
	return fmt.Sprintf(`"%s"`, l.Value)
}
func (l *LiteralRegexp) String() string {
	var modifiers string
	if l.Modifiers&RegexpCaseInsensitive != 0 {
		modifiers += "i"
	}
	if l.Modifiers&RegexpDotAll != 0 {
		modifiers += "s"
	}
	return fmt.Sprintf("/%s/%s", l.Value, modifiers)
}
func (k Keyword) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, string(k))
	return err
}
func (g *Group) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, "(")
	if err == nil {
		err = g.Expression.WriteSource(w)
	}
	if err == nil {
		_, err = io.WriteString(w, ")")
	}
	return err
}
func (l *LiteralInteger) WriteSource(w io.Writer) error {
	_, err := fmt.Fprint(w, l.Value)
	return err
}
func (l *LiteralFloat) WriteSource(w io.Writer) error {
	_, err := fmt.Fprintf(w, "%f", l.Value)
	return err
}
func (l *LiteralString) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, l.String())
	return err
}
func (l *LiteralRegexp) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, l.String())
	return err
}
func (m *Minus) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, "-")
	if err == nil {
		err = m.Expression.WriteSource(w)
	}
	return err
}
func (n *Not) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, "not ")
	if err == nil {
		err = n.Expression.WriteSource(w)
	}
	return err
}
func (b *BitwiseNot) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, "~")
	if err == nil {
		err = b.Expression.WriteSource(w)
	}
	return err
}
func (r *Range) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, "(")
	if err == nil {
		err = r.Start.WriteSource(w)
	}
	if err == nil {
		_, err = io.WriteString(w, "..")
	}
	if err == nil {
		err = r.End.WriteSource(w)
	}
	if err == nil {
		_, err = io.WriteString(w, ")")
	}
	return err
}
func (e *Enum) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, "(")
	for i, expr := range e.Values {
		err = expr.WriteSource(w)
		if err == nil && i < len(e.Values)-1 {
			_, err = io.WriteString(w, ", ")
		}
		if err != nil {
			return err
		}
	}
	if err == nil {
		_, err = io.WriteString(w, ")")
	}
	return err
}
func (i *Identifier) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, i.Identifier)
	return err
}
func (s *StringIdentifier) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, fmt.Sprintf("$%s", s.Identifier))
	if err == nil && s.At != nil {
		_, err = io.WriteString(w, " at ")
		if err == nil {
			err = s.At.WriteSource(w)
		}
	}
	if err == nil && s.In != nil {
		_, err = io.WriteString(w, " in ")
		if err == nil {
			err = s.In.WriteSource(w)
		}
	}
	return err
}
func (s *StringCount) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, fmt.Sprintf("#%s", s.Identifier))
	return err
}
func (s *StringOffset) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, fmt.Sprintf("@%s", s.Identifier))
	if err == nil && s.Index != nil {
		_, err = io.WriteString(w, "[")
	}
	if err == nil && s.Index != nil {
		err = s.Index.WriteSource(w)
	}
	if err == nil && s.Index != nil {
		_, err = io.WriteString(w, "]")
	}
	return err
}
func (s *StringLength) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, fmt.Sprintf("!%s", s.Identifier))
	if err == nil && s.Index != nil {
		_, err = io.WriteString(w, "[")
	}
	if err == nil && s.Index != nil {
		err = s.Index.WriteSource(w)
	}
	if err == nil && s.Index != nil {
		_, err = io.WriteString(w, "]")
	}
	return err
}
func (f *FunctionCall) WriteSource(w io.Writer) error {
	err := f.Callable.WriteSource(w)
	if err == nil {
		_, err = io.WriteString(w, "(")
	}
	if err == nil {
		for i, arg := range f.Arguments {
			err = arg.WriteSource(w)
			if err == nil && i < len(f.Arguments)-1 {
				_, err = io.WriteString(w, ", ")
			}
		}
	}
	if err == nil {
		_, err = io.WriteString(w, ")")
	}
	return err
}
func (m *MemberAccess) WriteSource(w io.Writer) error {
	err := m.Container.WriteSource(w)
	if err == nil {
		_, err = io.WriteString(w, ".")
	}
	if err == nil {
		_, err = io.WriteString(w, m.Member)
	}
	return err
}
func (s *Subscripting) WriteSource(w io.Writer) error {
	err := s.Array.WriteSource(w)
	if err == nil {
		_, err = io.WriteString(w, "[")
	}
	if err == nil {
		err = s.Index.WriteSource(w)
	}
	if err == nil {
		_, err = io.WriteString(w, "]")
	}
	return err
}
func (f *ForIn) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, "for ")
	if err == nil {
		err = f.Quantifier.WriteSource(w)
	}
	if err == nil {
		_, err = io.WriteString(w,
			fmt.Sprintf(" %s in ", strings.Join(f.Variables, ",")))
	}
	if err == nil {
		err = f.Iterator.WriteSource(w)
	}
	if err == nil {
		_, err = io.WriteString(w, " : (")
	}
	if err == nil {
		err = f.Condition.WriteSource(w)
	}
	if err == nil {
		_, err = io.WriteString(w, ")")
	}
	return err
}
func (f *ForOf) WriteSource(w io.Writer) error {
	_, err := io.WriteString(w, "for ")
	if err == nil {
		err = f.Quantifier.WriteSource(w)
	}
	if err == nil {
		_, err = io.WriteString(w, " of ")
	}
	if err == nil {
		err = f.Strings.WriteSource(w)
	}
	if err == nil {
		_, err = io.WriteString(w, " : (")
	}
	if err == nil {
		err = f.Condition.WriteSource(w)
	}
	if err == nil {
		_, err = io.WriteString(w, ")")
	}
	return err
}
func (o *Of) WriteSource(w io.Writer) error {
	err := o.Quantifier.WriteSource(w)
	if err == nil {
		_, err = io.WriteString(w, " of ")
	}
	if err == nil {
		err = o.Strings.WriteSource(w)
	}
	return err
}
func (o *Operation) WriteSource(w io.Writer) error {
	if len(o.Operands) < 2 {
		panic("expecting two or more operands")
	}
	if err := o.Operands[0].WriteSource(w); err != nil {
		return err
	}
	for _, operand := range o.Operands[1:] {
		if _, err := fmt.Fprintf(w, " %s ", o.Operator); err != nil {
			return err
		}
		if err := operand.WriteSource(w); err != nil {
			return err
		}
	}
	return nil
}
func (k Keyword) Children() []Node {
	return []Node{}
}
func (l *LiteralInteger) Children() []Node {
	return []Node{}
}
func (l *LiteralFloat) Children() []Node {
	return []Node{}
}
func (l *LiteralString) Children() []Node {
	return []Node{}
}
func (l *LiteralRegexp) Children() []Node {
	return []Node{}
}
func (i *Identifier) Children() []Node {
	return []Node{}
}
func (r *Range) Children() []Node {
	return []Node{r.Start, r.End}
}
func (e *Enum) Children() []Node {
	nodes := make([]Node, len(e.Values))
	for i, v := range e.Values {
		nodes[i] = v
	}
	return nodes
}
func (s *StringIdentifier) Children() []Node {
	children := make([]Node, 0)
	if s.At != nil {
		children = append(children, s.At)
	}
	if s.In != nil {
		children = append(children, s.In)
	}
	return children
}
func (s *StringCount) Children() []Node {
	return []Node{}
}
func (s *StringOffset) Children() []Node {
	return []Node{s.Index}
}
func (s *StringLength) Children() []Node {
	return []Node{s.Index}
}
func (f *FunctionCall) Children() []Node {
	expressions := append([]Expression{f.Callable}, f.Arguments...)
	nodes := make([]Node, len(expressions))
	for i, e := range expressions {
		nodes[i] = e
	}
	return nodes
}
func (m *MemberAccess) Children() []Node {
	return []Node{m.Container}
}
func (s *Subscripting) Children() []Node {
	return []Node{s.Array, s.Index}
}
func (f *ForIn) Children() []Node {
	return []Node{f.Quantifier, f.Iterator, f.Condition}
}
func (f *ForOf) Children() []Node {
	return []Node{f.Quantifier, f.Strings, f.Condition}
}
func (o *Of) Children() []Node {
	return []Node{o.Quantifier, o.Strings}
}
func (o *Operation) Children() []Node {
	nodes := make([]Node, len(o.Operands))
	for i, o := range o.Operands {
		nodes[i] = o
	}
	return nodes
}
func (k Keyword) AsProto() *pb.Expression {
	switch k {
	case KeywordTrue:
		return &pb.Expression{
			Expression: &pb.Expression_BoolValue{
				BoolValue: true,
			}}
	case KeywordFalse:
		return &pb.Expression{
			Expression: &pb.Expression_BoolValue{
				BoolValue: false,
			}}
	case KeywordEntrypoint:
		return &pb.Expression{
			Expression: &pb.Expression_Keyword{
				Keyword: pb.Keyword_ENTRYPOINT,
			}}
	case KeywordFilesize:
		return &pb.Expression{
			Expression: &pb.Expression_Keyword{
				Keyword: pb.Keyword_FILESIZE,
			}}
	default:
		panic(fmt.Sprintf(`unexpected keyword "%s"`, k))
	}
}
func (l *LiteralInteger) AsProto() *pb.Expression {
	return &pb.Expression{
		Expression: &pb.Expression_NumberValue{
			NumberValue: l.Value,
		},
	}
}
func (l *LiteralFloat) AsProto() *pb.Expression {
	return &pb.Expression{
		Expression: &pb.Expression_DoubleValue{
			DoubleValue: l.Value,
		},
	}
}
func (l *LiteralString) AsProto() *pb.Expression {
	return &pb.Expression{
		Expression: &pb.Expression_Text{
			Text: l.Value,
		},
	}
}
func (l *LiteralRegexp) AsProto() *pb.Expression {
	return &pb.Expression{
		Expression: &pb.Expression_Regexp{
			Regexp: &pb.Regexp{
				Text: proto.String(l.Value),
				Modifiers: &pb.StringModifiers{
					S: proto.Bool(l.Modifiers&RegexpDotAll != 0),
					I: proto.Bool(l.Modifiers&RegexpCaseInsensitive != 0),
				},
			},
		},
	}
}
func (m *Minus) AsProto() *pb.Expression {
	return &pb.Expression{
		Expression: &pb.Expression_UnaryExpression{
			UnaryExpression: &pb.UnaryExpression{
				Operator:   pb.UnaryExpression_UNARY_MINUS.Enum(),
				Expression: m.Expression.AsProto(),
			},
		},
	}
}
func (n *Not) AsProto() *pb.Expression {
	return &pb.Expression{
		Expression: &pb.Expression_NotExpression{
			NotExpression: n.Expression.AsProto(),
		},
	}
}
func (r *Range) AsProto() *pb.Range {
	return &pb.Range{
		Start: r.Start.AsProto(),
		End:   r.End.AsProto(),
	}
}
func (e *Enum) AsProto() *pb.IntegerEnumeration {
	values := make([]*pb.Expression, len(e.Values))
	for i, v := range e.Values {
		values[i] = v.AsProto()
	}
	return &pb.IntegerEnumeration{
		Values: values,
	}
}
func (i *Identifier) AsProto() *pb.Expression {
	return &pb.Expression{
		Expression: &pb.Expression_Identifier{
			Identifier: &pb.Identifier{
				Items: []*pb.Identifier_IdentifierItem{
					&pb.Identifier_IdentifierItem{
						Item: &pb.Identifier_IdentifierItem_Identifier{
							Identifier: i.Identifier,
						},
					},
				},
			},
		},
	}
}
func (s *StringIdentifier) AsProto() *pb.Expression {
	expr := &pb.Expression{
		Expression: &pb.Expression_StringIdentifier{
			StringIdentifier: fmt.Sprintf("$%s", s.Identifier),
		},
	}
	if s.At != nil {
		expr = &pb.Expression{
			Expression: &pb.Expression_BinaryExpression{
				BinaryExpression: &pb.BinaryExpression{
					Operator: pb.BinaryExpression_AT.Enum(),
					Left:     expr,
					Right:    s.At.AsProto(),
				},
			},
		}
	}
	if s.In != nil {
		expr = &pb.Expression{
			Expression: &pb.Expression_BinaryExpression{
				BinaryExpression: &pb.BinaryExpression{
					Operator: pb.BinaryExpression_IN.Enum(),
					Left:     expr,
					Right: &pb.Expression{
						Expression: &pb.Expression_Range{
							Range: s.In.AsProto(),
						},
					},
				},
			},
		}
	}
	return expr
}
func (s *StringCount) AsProto() *pb.Expression {
	return &pb.Expression{
		Expression: &pb.Expression_StringCount{
			StringCount: fmt.Sprintf("#%s", s.Identifier),
		},
	}
}
func (s *StringOffset) AsProto() *pb.Expression {
	var index *pb.Expression
	if s.Index != nil {
		index = s.Index.AsProto()
	}
	return &pb.Expression{
		Expression: &pb.Expression_StringOffset{
			StringOffset: &pb.StringOffset{
				StringIdentifier: proto.String(fmt.Sprintf("@%s", s.Identifier)),
				Index:            index,
			},
		},
	}
}
func (s *StringLength) AsProto() *pb.Expression {
	var index *pb.Expression
	if s.Index != nil {
		index = s.Index.AsProto()
	}
	return &pb.Expression{
		Expression: &pb.Expression_StringLength{
			StringLength: &pb.StringLength{
				StringIdentifier: proto.String(fmt.Sprintf("!%s", s.Identifier)),
				Index:            index,
			},
		},
	}
}
func (f *FunctionCall) AsProto() *pb.Expression {
	args := make([]*pb.Expression, len(f.Arguments))
	for i, arg := range f.Arguments {
		args[i] = arg.AsProto()
	}
	callable := f.Callable.AsProto()
	identifier := callable.GetIdentifier()
	identifier.Items = append(identifier.GetItems(), &pb.Identifier_IdentifierItem{
		Item: &pb.Identifier_IdentifierItem_Arguments{
			Arguments: &pb.Expressions{
				Terms: args,
			},
		},
	})
	return &pb.Expression{
		Expression: &pb.Expression_Identifier{
			Identifier: identifier,
		},
	}
}
func (m *MemberAccess) AsProto() *pb.Expression {
	expr := m.Container.AsProto()
	identifier := expr.GetIdentifier()
	identifier.Items = append(identifier.GetItems(), &pb.Identifier_IdentifierItem{
		Item: &pb.Identifier_IdentifierItem_Identifier{
			Identifier: m.Member,
		},
	})
	return &pb.Expression{
		Expression: &pb.Expression_Identifier{
			Identifier: identifier,
		},
	}
}