// NB at the moment this doesn't track comment and strings state,
// so it will fail if unbalanced '(' are found in either.
510672
func isBalanced(str string) bool {
	parens := 0
	squares := 0

	for _, c := range str {
		switch c {
		case '(':
			parens++
		case ')':
			parens--
		case '[':
			squares++
		case ']':
			squares--
		}
	}

	return parens == 0 && squares == 0
}
1080972
func FnBase64(name string, input interface{}, template interface{}) interface{} {

	// { "Fn::Base64" : valueToEncode }

	// Check the input is a string
	if src, ok := input.(string); ok {
		return base64.StdEncoding.EncodeToString([]byte(src))
	}

	return nil

}
255210
func lexComment(l *lexer) stateFn {
	l.pos += Pos(len(leftComment))
	i := strings.Index(l.input[l.pos:], rightComment)
	if i < 0 {
		return l.errorf("unclosed comment")
	}
	l.pos += Pos(i + len(rightComment))
	if !strings.HasPrefix(l.input[l.pos:], l.rightDelim) {
		return l.errorf("comment ends before closing delimiter")

	}
	l.pos += Pos(len(l.rightDelim))
	l.ignore()
	return lexText
}
253187
func (p *parser) consumeComment() (comment *ast.Comment, endline int) {
	// /*-style comments may end on a different line than where they start.
	// Scan the comment for '\n' chars and adjust endline accordingly.
	endline = p.file.Line(p.pos)
	if p.lit[1] == '*' {
		for _, b := range p.lit {
			if b == '\n' {
				endline++
			}
		}
	}

	comment = &ast.Comment{p.pos, p.lit}
	p.next0()

	return
}
344177
func (section *Section) AddComment(comment string) {
	section.comments = append(section.comments, comment)
}
334707
func (t *Tree) SetWithComment(key string, comment string, commented bool, value interface{}) {
	t.SetPathWithComment(strings.Split(key, "."), comment, commented, value)
}
65989
func loadCommentsAttributes(e Engine, comments []*Comment) (err error) {
	for i := range comments {
		if err = comments[i].loadAttributes(e); err != nil {
			return fmt.Errorf("loadAttributes [%d]: %v", comments[i].ID, err)
		}
	}

	return nil
}
493544
func (p Comment) String() string {
	var buf bytes.Buffer
	if p.TranslatorComment != "" {
		ss := strings.Split(p.TranslatorComment, "\n")
		for i := 0; i < len(ss); i++ {
			fmt.Fprintf(&buf, "# %s\n", ss[i])
		}
	}
	if p.ExtractedComment != "" {
		ss := strings.Split(p.ExtractedComment, "\n")
		for i := 0; i < len(ss); i++ {
			fmt.Fprintf(&buf, "#. %s\n", ss[i])
		}
	}
	if a, b := len(p.ReferenceFile), len(p.ReferenceLine); a != 0 && a == b {
		fmt.Fprintf(&buf, "#:")
		for i := 0; i < len(p.ReferenceFile); i++ {
			fmt.Fprintf(&buf, " %s:%d", p.ReferenceFile[i], p.ReferenceLine[i])
		}
		fmt.Fprintf(&buf, "\n")
	}
	if len(p.Flags) != 0 {
		fmt.Fprintf(&buf, "#, %s", p.Flags[0])
		for i := 1; i < len(p.Flags); i++ {
			fmt.Fprintf(&buf, ", %s", p.Flags[i])
		}
		fmt.Fprintf(&buf, "\n")
	}
	if p.PrevMsgContext != "" {
		s := encodeCommentPoString(p.PrevMsgContext)
		fmt.Fprintf(&buf, "#| msgctxt %s\n", s)
	}
	if p.PrevMsgId != "" {
		s := encodeCommentPoString(p.PrevMsgId)
		fmt.Fprintf(&buf, "#| msgid %s\n", s)
	}
	return buf.String()
}
408084
func (sm *StateMachine) Comment(comment string) *StateMachine {
	sm.comment = comment
	return sm
}
656507
func validateNoNewLineOrTab(s string) bool {
	return !(strings.Contains(s, "\n") || strings.Contains(s, "\t"))
}
550706
func (cm CommentMap) AddComments(node Node, comments []*Comment, position CommentPosition) {
	for _, comment := range comments {
		if comment.Position == TBD {
			comment.Position = position
		}
		cm.AddComment(node, comment)
	}
}
1016606
func split(text []byte) [][]byte {
	// count lines (comment text never ends in a newline)
	n := 1
	for _, c := range text {
		if c == '\n' {
			n++
		}
	}

	// split
	lines := make([][]byte, n)
	n = 0
	i := 0
	for j, c := range text {
		if c == '\n' {
			lines[n] = text[i:j] // exclude newline
			i = j + 1            // discard newline
			n++
		}
	}
	lines[n] = text[i:]

	return lines
}
303569
func (col *column) parseColumnComment() {
	comment := strings.TrimSpace(col.comment)
	start := strings.Index(comment, "[[")
	end := strings.Index(comment, "]]")
	var content string
	if start < end {
		content = comment[start+2 : end]
	}

	fields := strings.Split(content, ";")
	for _, field := range fields {
		field = strings.TrimSpace(field)
		kvs := strings.Split(field, "=")
		col.parseRule(kvs)
	}
}
1008385
func (c Comment) String() string {
	return fmt.Sprintf("%s%s", c.cs, c.comment)
}
952232
func (c *Comments) Unset() {
	if c.Current != nil {
		c.applyComments(c.Current, c.Current, TRAILING)
		c.Current = nil
	}
	c.wasLineBreak = false
	c.primary = false
	c.afterBlock = false
}
219335
func DontPanicf(format string, i ...interface{}) {
	msg := fmt.Sprintf("%v\n %s", fmt.Sprintf(format, i...), debug.Stack())
	logMessage("PANIC - ", msg)
}
1023464
func (lexer *Lexer) dumpComment() {
	str := lexer.buffer.String()
	lexer.buffer.Reset()
	lexer.AppendToken(lexer.Token(TokenComment, str))
}