/*
Copyright 2019 HAProxy Technologies

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package parser

import (
	"github.com/haproxytech/config-parser/v5/parsers"
	"github.com/haproxytech/config-parser/v5/parsers/extra"
	"github.com/haproxytech/config-parser/v5/parsers/filters"
	"github.com/haproxytech/config-parser/v5/parsers/http"
	"github.com/haproxytech/config-parser/v5/parsers/simple"
	"github.com/haproxytech/config-parser/v5/parsers/stats"
	"github.com/haproxytech/config-parser/v5/parsers/tcp"
)

func addParser(parser map[string]ParserInterface, sequence *[]Section, p ParserInterface) {
	p.Init()
	parser[p.GetParserName()] = p
	*sequence = append(*sequence, Section(p.GetParserName()))
}

func (p *configParser) createParsers(parser map[string]ParserInterface, sequence []Section) *Parsers {
	addParser(parser, &sequence, &extra.Section{Name: "defaults"})
	addParser(parser, &sequence, &extra.Section{Name: "global"})
	addParser(parser, &sequence, &extra.Section{Name: "frontend"})
	addParser(parser, &sequence, &extra.Section{Name: "backend"})
	addParser(parser, &sequence, &extra.Section{Name: "listen"})
	addParser(parser, &sequence, &extra.Section{Name: "resolvers"})
	addParser(parser, &sequence, &extra.Section{Name: "userlist"})
	addParser(parser, &sequence, &extra.Section{Name: "peers"})
	addParser(parser, &sequence, &extra.Section{Name: "mailers"})
	addParser(parser, &sequence, &extra.Section{Name: "cache"})
	addParser(parser, &sequence, &extra.Section{Name: "program"})
	addParser(parser, &sequence, &extra.Section{Name: "http-errors"})
	addParser(parser, &sequence, &extra.Section{Name: "ring"})
	addParser(parser, &sequence, &extra.Section{Name: "log-forward"})
	addParser(parser, &sequence, &extra.Section{Name: "fcgi-app"})
	if !p.Options.DisableUnProcessed {
		addParser(parser, &sequence, &extra.UnProcessed{})
	}

	for _, parser := range parser {
		parser.Init()
	}

	return &Parsers{Parsers: parser, ParserSequence: sequence}
}

func (p *configParser) getStartParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	if p.Options.UseMd5Hash {
		addParser(parser, &sequence, &extra.ConfigHash{})
	}
	addParser(parser, &sequence, &extra.ConfigVersion{})
	addParser(parser, &sequence, &extra.Comments{})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getDefaultParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	addParser(parser, &sequence, &simple.Enabled{Name: "enabled"})
	addParser(parser, &sequence, &simple.Enabled{Name: "disabled"})
	addParser(parser, &sequence, &parsers.Mode{})
	addParser(parser, &sequence, &parsers.MonitorURI{})
	addParser(parser, &sequence, &parsers.HashType{})
	addParser(parser, &sequence, &parsers.Balance{})
	addParser(parser, &sequence, &parsers.MaxConn{})
	addParser(parser, &sequence, &simple.Number{Name: "backlog"})
	addParser(parser, &sequence, &parsers.Log{})
	addParser(parser, &sequence, &parsers.OptionHTTPLog{})
	addParser(parser, &sequence, &parsers.EmailAlert{})
	addParser(parser, &sequence, &stats.Stats{Mode: "defaults"})
	addParser(parser, &sequence, &simple.Word{Name: "log-tag"})
	addParser(parser, &sequence, &simple.String{Name: "log-format"})
	addParser(parser, &sequence, &simple.String{Name: "log-format-sd"})
	addParser(parser, &sequence, &simple.String{Name: "error-log-format"})
	addParser(parser, &sequence, &parsers.Cookie{})
	addParser(parser, &sequence, &simple.Word{Name: "dynamic-cookie-key"})
	addParser(parser, &sequence, &parsers.BindProcess{})
	addParser(parser, &sequence, &simple.Option{Name: "tcplog"})
	addParser(parser, &sequence, &simple.Option{Name: "httpclose"})
	addParser(parser, &sequence, &simple.Option{Name: "http-use-htx"})
	addParser(parser, &sequence, &parsers.OptionRedispatch{})
	addParser(parser, &sequence, &simple.Option{Name: "dontlognull"})
	addParser(parser, &sequence, &simple.Option{Name: "log-separate-errors"})
	addParser(parser, &sequence, &simple.Option{Name: "http-buffer-request"})
	addParser(parser, &sequence, &simple.Option{Name: "http-server-close"})
	addParser(parser, &sequence, &simple.Option{Name: "http-keep-alive"})
	addParser(parser, &sequence, &simple.Option{Name: "http-pretend-keepalive"})
	addParser(parser, &sequence, &simple.Option{Name: "http-no-delay"})
	addParser(parser, &sequence, &simple.Option{Name: "http-proxy"})
	addParser(parser, &sequence, &simple.Option{Name: "tcpka"})
	addParser(parser, &sequence, &simple.Option{Name: "clitcpka"})
	addParser(parser, &sequence, &simple.Option{Name: "srvtcpka"})
	addParser(parser, &sequence, &simple.Option{Name: "contstats"})
	addParser(parser, &sequence, &simple.Option{Name: "ssl-hello-chk"})
	addParser(parser, &sequence, &parsers.OptionSmtpchk{})
	addParser(parser, &sequence, &simple.Option{Name: "ldap-check"})
	addParser(parser, &sequence, &parsers.OptionMysqlCheck{})
	addParser(parser, &sequence, &simple.Option{Name: "abortonclose"})
	addParser(parser, &sequence, &parsers.OptionPgsqlCheck{})
	addParser(parser, &sequence, &simple.Option{Name: "redis-check"})
	addParser(parser, &sequence, &simple.Option{Name: "splice-auto"})
	addParser(parser, &sequence, &simple.Option{Name: "splice-request"})
	addParser(parser, &sequence, &simple.Option{Name: "splice-response"})
	addParser(parser, &sequence, &simple.Option{Name: "logasap"})
	addParser(parser, &sequence, &simple.Option{Name: "log-health-checks"})
	addParser(parser, &sequence, &simple.Option{Name: "allbackups"})
	addParser(parser, &sequence, &simple.Option{Name: "external-check"})
	addParser(parser, &sequence, &parsers.OptionForwardFor{})
	addParser(parser, &sequence, &simple.Option{Name: "accept-invalid-http-request"})
	addParser(parser, &sequence, &simple.Option{Name: "accept-invalid-http-response"})
	addParser(parser, &sequence, &simple.Option{Name: "h1-case-adjust-bogus-client"})
	addParser(parser, &sequence, &simple.Option{Name: "h1-case-adjust-bogus-server"})
	addParser(parser, &sequence, &simple.Option{Name: "disable-h2-upgrade"})
	addParser(parser, &sequence, &simple.Option{Name: "tcp-check"})
	addParser(parser, &sequence, &simple.Option{Name: "checkcache"})
	addParser(parser, &sequence, &simple.Option{Name: "http-ignore-probes"})
	addParser(parser, &sequence, &simple.Option{Name: "http-use-proxy-header"})
	addParser(parser, &sequence, &simple.Option{Name: "httpslog"})
	addParser(parser, &sequence, &simple.Option{Name: "independent-streams"})
	addParser(parser, &sequence, &simple.Option{Name: "nolinger"})
	addParser(parser, &sequence, &parsers.OptionOriginalTo{})
	addParser(parser, &sequence, &simple.Option{Name: "persist"})
	addParser(parser, &sequence, &simple.Option{Name: "prefer-last-server"})
	addParser(parser, &sequence, &simple.Option{Name: "socket-stats"})
	addParser(parser, &sequence, &simple.Option{Name: "tcp-smart-accept"})
	addParser(parser, &sequence, &simple.Option{Name: "tcp-smart-connect"})
	addParser(parser, &sequence, &simple.Option{Name: "transparent"})
	addParser(parser, &sequence, &simple.Option{Name: "idle-close-on-response"})
	addParser(parser, &sequence, &simple.Option{Name: "dontlog-normal"})
	addParser(parser, &sequence, &parsers.OptionHTTPRestrictReqHdrNames{})
	addParser(parser, &sequence, &tcp.Checks{})
	addParser(parser, &sequence, &parsers.OptionHttpchk{})
	if p.Options.UseV2HTTPCheck {
		addParser(parser, &sequence, &parsers.HTTPCheckV2{})
	} else {
		addParser(parser, &sequence, &http.Checks{Mode: "defaults"})
	}
	addParser(parser, &sequence, &parsers.ExternalCheckPath{})
	addParser(parser, &sequence, &parsers.ExternalCheckCommand{})
	addParser(parser, &sequence, &parsers.HTTPReuse{})
	addParser(parser, &sequence, &simple.Timeout{Name: "http-request"})
	addParser(parser, &sequence, &simple.Timeout{Name: "check"})
	addParser(parser, &sequence, &simple.Timeout{Name: "connect"})
	addParser(parser, &sequence, &simple.Timeout{Name: "client"})
	addParser(parser, &sequence, &simple.Timeout{Name: "client-fin"})
	addParser(parser, &sequence, &simple.Timeout{Name: "queue"})
	addParser(parser, &sequence, &simple.Timeout{Name: "server"})
	addParser(parser, &sequence, &simple.Timeout{Name: "server-fin"})
	addParser(parser, &sequence, &simple.Timeout{Name: "tunnel"})
	addParser(parser, &sequence, &simple.Timeout{Name: "http-keep-alive"})
	addParser(parser, &sequence, &simple.Timeout{Name: "tarpit"})
	addParser(parser, &sequence, &simple.Number{Name: "retries"})
	addParser(parser, &sequence, &simple.Number{Name: "clitcpka-cnt"})
	addParser(parser, &sequence, &simple.Time{Name: "clitcpka-idle"})
	addParser(parser, &sequence, &simple.Time{Name: "clitcpka-intvl"})
	addParser(parser, &sequence, &simple.Number{Name: "srvtcpka-cnt"})
	addParser(parser, &sequence, &simple.Time{Name: "srvtcpka-idle"})
	addParser(parser, &sequence, &simple.Time{Name: "srvtcpka-intvl"})
	addParser(parser, &sequence, &simple.Word{Name: "server-state-file-name"})
	addParser(parser, &sequence, &parsers.CompressionAlgo{})
	addParser(parser, &sequence, &parsers.CompressionType{})
	addParser(parser, &sequence, &parsers.CompressionOffload{})
	addParser(parser, &sequence, &parsers.DefaultServer{})
	addParser(parser, &sequence, &parsers.LoadServerStateFromFile{})
	addParser(parser, &sequence, &parsers.ErrorFile{})
	addParser(parser, &sequence, &parsers.ErrorFiles{})
	addParser(parser, &sequence, &parsers.ErrorLoc302{})
	addParser(parser, &sequence, &parsers.ErrorLoc303{})
	addParser(parser, &sequence, &parsers.DefaultBackend{})
	addParser(parser, &sequence, &parsers.UniqueIDFormat{})
	addParser(parser, &sequence, &parsers.UniqueIDHeader{})
	addParser(parser, &sequence, &simple.Number{Name: "fullconn"})
	addParser(parser, &sequence, &parsers.HTTPSendNameHeader{})
	addParser(parser, &sequence, &simple.Number{Name: "max-keep-alive-queue"})
	addParser(parser, &sequence, &simple.String{Name: "retry-on"})
	addParser(parser, &sequence, &http.HTTPErrors{})
	addParser(parser, &sequence, &parsers.Source{})
	addParser(parser, &sequence, &parsers.Persist{})
	addParser(parser, &sequence, &simple.Number{Name: "rate-limit sessions"})
	// the ConfigSnippet must be at the end to parsers load order to ensure
	// the overloading of any option has been declared previously
	addParser(parser, &sequence, &parsers.ConfigSnippet{})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getGlobalParser() *Parsers { //nolint: maintidx
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	// environment directives are placed before the rest,
	// because HAProxy can use the environment vars in subsequent config
	addParser(parser, &sequence, &parsers.SetVar{})
	addParser(parser, &sequence, &parsers.SetVarFmt{})
	addParser(parser, &sequence, &simple.ArrayKeyValue{Name: "presetenv"})
	addParser(parser, &sequence, &simple.StringSlice{Name: "resetenv"})
	addParser(parser, &sequence, &simple.ArrayKeyValue{Name: "setenv"})
	addParser(parser, &sequence, &simple.StringSlice{Name: "unsetenv"})
	addParser(parser, &sequence, &parsers.Daemon{})
	addParser(parser, &sequence, &parsers.DefaultPath{})
	addParser(parser, &sequence, &simple.String{Name: "localpeer"})
	addParser(parser, &sequence, &simple.Word{Name: "chroot"})
	addParser(parser, &sequence, &simple.Number{Name: "uid"})
	addParser(parser, &sequence, &simple.Word{Name: "user"})
	addParser(parser, &sequence, &simple.Number{Name: "gid"})
	addParser(parser, &sequence, &simple.Word{Name: "group"})
	addParser(parser, &sequence, &simple.Word{Name: "ca-base"})
	addParser(parser, &sequence, &simple.Word{Name: "crt-base"})
	addParser(parser, &sequence, &parsers.MasterWorker{})
	addParser(parser, &sequence, &parsers.ExternalCheck{})
	addParser(parser, &sequence, &parsers.NoSplice{})
	addParser(parser, &sequence, &parsers.NbProc{})
	addParser(parser, &sequence, &parsers.NbThread{})
	addParser(parser, &sequence, &parsers.CPUMap{})
	addParser(parser, &sequence, &parsers.Mode{})
	addParser(parser, &sequence, &parsers.MaxConn{})
	addParser(parser, &sequence, &simple.Number{Name: "maxconnrate"})
	addParser(parser, &sequence, &simple.Number{Name: "maxcomprate"})
	addParser(parser, &sequence, &simple.Number{Name: "maxcompcpuusage"})
	addParser(parser, &sequence, &simple.Number{Name: "maxpipes"})
	addParser(parser, &sequence, &simple.Number{Name: "maxsessrate"})
	addParser(parser, &sequence, &simple.Number{Name: "maxsslconn"})
	addParser(parser, &sequence, &simple.Number{Name: "maxsslrate"})
	addParser(parser, &sequence, &simple.Number{Name: "maxzlibmem"})
	addParser(parser, &sequence, &simple.String{Name: "pidfile"})
	addParser(parser, &sequence, &parsers.Socket{})
	addParser(parser, &sequence, &parsers.StatsTimeout{})
	addParser(parser, &sequence, &simple.Number{Name: "anonkey"})
	addParser(parser, &sequence, &simple.OnOff{Name: "httpclient.resolvers.disabled"})
	addParser(parser, &sequence, &simple.Word{Name: "httpclient.resolvers.id"})
	addParser(parser, &sequence, &parsers.HTTPClientResolversPrefer{})
	addParser(parser, &sequence, &simple.Number{Name: "httpclient.retries"})
	addParser(parser, &sequence, &simple.Word{Name: "httpclient.ssl.ca-file"})
	addParser(parser, &sequence, &simple.Time{Name: "httpclient.timeout.connect"})
	addParser(parser, &sequence, &parsers.HTTPClientSSLVerify{})
	addParser(parser, &sequence, &simple.Enabled{Name: "limited-quic"})
	addParser(parser, &sequence, &simple.Enabled{Name: "prealloc-fd"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.buffers.limit"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.buffers.reserve"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.bufsize"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.comp.maxlevel"})
	addParser(parser, &sequence, &simple.Enabled{Name: "tune.disable-zero-copy-forwarding"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.events.max-events-at-once"})
	addParser(parser, &sequence, &simple.Enabled{Name: "tune.fail-alloc"})
	addParser(parser, &sequence, &simple.OnOff{Name: "tune.fd.edge-triggered"})
	addParser(parser, &sequence, &simple.OnOff{Name: "tune.h1.zero-copy-fwd-recv"})
	addParser(parser, &sequence, &simple.OnOff{Name: "tune.h1.zero-copy-fwd-send"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.h2.be.initial-window-size"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.h2.header-table-size"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.h2.initial-window-size"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.h2.be.max-concurrent-streams"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.h2.fe.initial-window-size"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.h2.fe.max-concurrent-streams"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.h2.max-concurrent-streams"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.h2.max-frame-size"})
	addParser(parser, &sequence, &simple.OnOff{Name: "tune.h2.zero-copy-fwd-send"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.http.cookielen"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.http.logurilen"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.http.maxhdr"})
	addParser(parser, &sequence, &simple.OnOff{Name: "tune.idle-pool.shared"})
	addParser(parser, &sequence, &simple.Time{Name: "tune.idletimer"})
	addParser(parser, &sequence, &simple.String{Name: "tune.listener.default-shards"})
	addParser(parser, &sequence, &simple.OnOff{Name: "tune.listener.multi-queue"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.lua.forced-yield"})
	addParser(parser, &sequence, &simple.Enabled{Name: "tune.lua.maxmem"})
	addParser(parser, &sequence, &simple.Time{Name: "tune.lua.session-timeout"})
	addParser(parser, &sequence, &simple.Time{Name: "tune.lua.burst-timeout"})
	addParser(parser, &sequence, &simple.Time{Name: "tune.lua.task-timeout"})
	addParser(parser, &sequence, &simple.Time{Name: "tune.lua.service-timeout"})
	addParser(parser, &sequence, &simple.OnOff{Name: "tune.lua.log.loggers"})
	addParser(parser, &sequence, &simple.AutoOnOff{Name: "tune.lua.log.stderr"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.max-checks-per-thread"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.maxaccept"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.maxpollevents"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.maxrewrite"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.memory.hot-size"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.pattern.cache-size"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.peers.max-updates-at-once"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.pipesize"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.pool-high-fd-ratio"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.pool-low-fd-ratio"})
	addParser(parser, &sequence, &simple.OnOff{Name: "tune.pt.zero-copy-forwarding"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.rcvbuf.backend"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.rcvbuf.client"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.rcvbuf.frontend"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.rcvbuf.server"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.recv_enough"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.runqueue-depth"})
	addParser(parser, &sequence, &simple.OnOff{Name: "tune.sched.low-latency"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.sndbuf.backend"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.sndbuf.client"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.sndbuf.frontend"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.sndbuf.server"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.ssl.cachesize"})
	addParser(parser, &sequence, &simple.Enabled{Name: "tune.ssl.force-private-cache"})
	addParser(parser, &sequence, &simple.OnOff{Name: "tune.ssl.keylog"})
	addParser(parser, &sequence, &simple.Time{Name: "tune.ssl.lifetime"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.ssl.maxrecord"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.ssl.default-dh-param"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.ssl.ssl-ctx-cache-size"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.ssl.capture-buffer-size"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.ssl.ocsp-update.maxdelay"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.ssl.ocsp-update.mindelay"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.stick-counters"})
	addParser(parser, &sequence, &simple.Size{Name: "tune.vars.global-max-size"})
	addParser(parser, &sequence, &simple.Size{Name: "tune.vars.proc-max-size"})
	addParser(parser, &sequence, &simple.Size{Name: "tune.vars.reqres-max-size"})
	addParser(parser, &sequence, &simple.Size{Name: "tune.vars.sess-max-size"})
	addParser(parser, &sequence, &simple.Size{Name: "tune.vars.txn-max-size"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.quic.frontend.conn-tx-buffers.limit"})
	addParser(parser, &sequence, &simple.Time{Name: "tune.quic.frontend.max-idle-timeout"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.quic.frontend.max-streams-bidi"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.quic.max-frame-loss"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.quic.retry-threshold"})
	addParser(parser, &sequence, &parsers.QuicSocketOwner{})
	addParser(parser, &sequence, &simple.Enabled{Name: "no-quic"})
	addParser(parser, &sequence, &simple.Word{Name: "cluster-secret"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.zlib.memlevel"})
	addParser(parser, &sequence, &simple.Number{Name: "tune.zlib.windowsize"})
	addParser(parser, &sequence, &simple.String{Name: "ssl-default-bind-options"})
	addParser(parser, &sequence, &simple.String{Name: "ssl-default-bind-sigalgs"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-default-bind-ciphers"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-default-bind-ciphersuites"})
	addParser(parser, &sequence, &simple.String{Name: "ssl-default-server-options"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-default-server-ciphers"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-default-server-ciphersuites"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-default-server-client-sigalgs"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-default-server-curves"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-default-server-sigalgs"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-default-bind-client-sigalgs"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-default-bind-curves"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-dh-param-file"})
	addParser(parser, &sequence, &simple.Enabled{Name: "ssl-load-extra-del-ext"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-propquery"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-provider"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-provider-path"})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-server-verify"})
	addParser(parser, &sequence, &simple.Enabled{Name: "ssl-skip-self-issued-ca"})
	addParser(parser, &sequence, &simple.Time{Name: "hard-stop-after"})
	addParser(parser, &sequence, &parsers.Log{})
	addParser(parser, &sequence, &parsers.LogSendHostName{})
	addParser(parser, &sequence, &parsers.LuaPrependPath{})
	addParser(parser, &sequence, &parsers.LuaLoad{})
	addParser(parser, &sequence, &simple.Word{Name: "server-state-file"})
	addParser(parser, &sequence, &simple.Word{Name: "server-state-base"})
	addParser(parser, &sequence, &parsers.SslEngine{})
	addParser(parser, &sequence, &parsers.SslModeAsync{})
	addParser(parser, &sequence, &simple.Word{Name: "h1-case-adjust-file"})
	addParser(parser, &sequence, &parsers.H1CaseAdjust{})
	addParser(parser, &sequence, &simple.Enabled{Name: "busy-polling"})
	addParser(parser, &sequence, &simple.String{Name: "max-spread-checks"})
	addParser(parser, &sequence, &simple.String{Name: "close-spread-time"})
	addParser(parser, &sequence, &simple.Enabled{Name: "noepoll"})
	addParser(parser, &sequence, &simple.Enabled{Name: "nokqueue"})
	addParser(parser, &sequence, &simple.Enabled{Name: "noevports"})
	addParser(parser, &sequence, &simple.Enabled{Name: "nopoll"})
	addParser(parser, &sequence, &simple.Enabled{Name: "nosplice"})
	addParser(parser, &sequence, &simple.Enabled{Name: "nogetaddrinfo"})
	addParser(parser, &sequence, &simple.Enabled{Name: "noreuseport"})
	addParser(parser, &sequence, &simple.AutoOnOff{Name: "profiling.tasks"})
	addParser(parser, &sequence, &simple.Number{Name: "spread-checks"})
	addParser(parser, &sequence, &simple.String{Name: "wurfl-data-file"})
	addParser(parser, &sequence, &simple.String{Name: "wurfl-information-list"})
	addParser(parser, &sequence, &simple.String{Name: "wurfl-information-list-separator"})
	addParser(parser, &sequence, &simple.String{Name: "wurfl-patch-file"})
	addParser(parser, &sequence, &simple.Number{Name: "wurfl-cache-size"})
	addParser(parser, &sequence, &simple.String{Name: "description"})
	addParser(parser, &sequence, &simple.Enabled{Name: "expose-experimental-directives"})
	addParser(parser, &sequence, &simple.String{Name: "grace"})
	addParser(parser, &sequence, &simple.Enabled{Name: "insecure-fork-wanted"})
	addParser(parser, &sequence, &simple.Enabled{Name: "insecure-setuid-wanted"})
	addParser(parser, &sequence, &simple.String{Name: "issuers-chain-path"})
	addParser(parser, &sequence, &simple.Enabled{Name: "h2-workaround-bogus-websocket-clients"})
	addParser(parser, &sequence, &simple.String{Name: "lua-load-per-thread"})
	addParser(parser, &sequence, &simple.Number{Name: "mworker-max-reloads"})
	addParser(parser, &sequence, &simple.String{Name: "node"})
	addParser(parser, &sequence, &parsers.NumaCPUMapping{})
	addParser(parser, &sequence, &simple.Enabled{Name: "pp2-never-send-local"})
	addParser(parser, &sequence, &simple.Number{Name: "ulimit-n"})
	addParser(parser, &sequence, &simple.Enabled{Name: "set-dumpable"})
	addParser(parser, &sequence, &simple.Enabled{Name: "strict-limits"})
	addParser(parser, &sequence, &parsers.UnixBind{})
	addParser(parser, &sequence, &simple.String{Name: "deviceatlas-json-file"})
	addParser(parser, &sequence, &simple.String{Name: "deviceatlas-log-level"})
	addParser(parser, &sequence, &simple.String{Name: "deviceatlas-separator"})
	addParser(parser, &sequence, &simple.String{Name: "deviceatlas-properties-cookie"})
	addParser(parser, &sequence, &simple.Word{Name: "51degrees-data-file"})
	addParser(parser, &sequence, &simple.String{Name: "51degrees-property-name-list"})
	addParser(parser, &sequence, &simple.String{Name: "51degrees-property-separator"})
	addParser(parser, &sequence, &simple.Number{Name: "51degrees-cache-size"})
	addParser(parser, &sequence, &simple.Number{Name: "thread-groups"})
	addParser(parser, &sequence, &parsers.StatsMaxconn{})
	addParser(parser, &sequence, &simple.Word{Name: "ssl-load-extra-files"})
	addParser(parser, &sequence, &parsers.ThreadGroup{})
	addParser(parser, &sequence, &simple.Enabled{Name: "quiet"})
	addParser(parser, &sequence, &simple.Enabled{Name: "zero-warning"})
	addParser(parser, &sequence, &simple.Word{Name: "setcap"})
	// the ConfigSnippet must be at the end to parsers load order to ensure
	// the overloading of any option has been declared previously
	addParser(parser, &sequence, &parsers.ConfigSnippet{})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getFrontendParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	addParser(parser, &sequence, &simple.Number{Name: "id"})
	addParser(parser, &sequence, &simple.String{Name: "description"})
	addParser(parser, &sequence, &simple.Enabled{Name: "enabled"})
	addParser(parser, &sequence, &simple.Enabled{Name: "disabled"})
	addParser(parser, &sequence, &parsers.Mode{})
	addParser(parser, &sequence, &parsers.MaxConn{})
	addParser(parser, &sequence, &simple.Number{Name: "backlog"})
	addParser(parser, &sequence, &parsers.Bind{})
	addParser(parser, &sequence, &parsers.ACL{})
	addParser(parser, &sequence, &parsers.MonitorURI{})
	addParser(parser, &sequence, &parsers.MonitorFail{})
	addParser(parser, &sequence, &parsers.BindProcess{})
	addParser(parser, &sequence, &simple.Word{Name: "log-tag"})
	addParser(parser, &sequence, &simple.String{Name: "log-format"})
	addParser(parser, &sequence, &simple.String{Name: "log-format-sd"})
	addParser(parser, &sequence, &simple.String{Name: "error-log-format"})
	addParser(parser, &sequence, &parsers.Log{})
	addParser(parser, &sequence, &parsers.EmailAlert{})
	addParser(parser, &sequence, &simple.Option{Name: "httpclose"})
	addParser(parser, &sequence, &simple.Option{Name: "forceclose"})
	addParser(parser, &sequence, &simple.Option{Name: "http-buffer-request"})
	addParser(parser, &sequence, &simple.Option{Name: "http-server-close"})
	addParser(parser, &sequence, &simple.Option{Name: "http-keep-alive"})
	addParser(parser, &sequence, &simple.Option{Name: "http-use-htx"})
	addParser(parser, &sequence, &simple.Option{Name: "http-no-delay"})
	addParser(parser, &sequence, &simple.Option{Name: "http-proxy"})
	addParser(parser, &sequence, &parsers.OptionForwardFor{})
	addParser(parser, &sequence, &simple.Option{Name: "tcplog"})
	addParser(parser, &sequence, &simple.Option{Name: "dontlognull"})
	addParser(parser, &sequence, &simple.Option{Name: "contstats"})
	addParser(parser, &sequence, &simple.Option{Name: "log-separate-errors"})
	addParser(parser, &sequence, &simple.Option{Name: "tcpka"})
	addParser(parser, &sequence, &simple.Option{Name: "clitcpka"})
	addParser(parser, &sequence, &simple.Option{Name: "splice-auto"})
	addParser(parser, &sequence, &simple.Option{Name: "splice-request"})
	addParser(parser, &sequence, &simple.Option{Name: "splice-response"})
	addParser(parser, &sequence, &simple.Option{Name: "accept-invalid-http-request"})
	addParser(parser, &sequence, &simple.Option{Name: "h1-case-adjust-bogus-client"})
	addParser(parser, &sequence, &simple.Option{Name: "disable-h2-upgrade"})
	addParser(parser, &sequence, &simple.Option{Name: "logasap"})
	addParser(parser, &sequence, &simple.Option{Name: "http-ignore-probes"})
	addParser(parser, &sequence, &simple.Option{Name: "http-use-proxy-header"})
	addParser(parser, &sequence, &simple.Option{Name: "httpslog"})
	addParser(parser, &sequence, &simple.Option{Name: "independent-streams"})
	addParser(parser, &sequence, &simple.Option{Name: "nolinger"})
	addParser(parser, &sequence, &parsers.OptionOriginalTo{})
	addParser(parser, &sequence, &simple.Option{Name: "socket-stats"})
	addParser(parser, &sequence, &simple.Option{Name: "tcp-smart-accept"})
	addParser(parser, &sequence, &simple.Option{Name: "idle-close-on-response"})
	addParser(parser, &sequence, &simple.Option{Name: "dontlog-normal"})
	addParser(parser, &sequence, &parsers.OptionHTTPLog{})
	addParser(parser, &sequence, &parsers.OptionHTTPRestrictReqHdrNames{})
	addParser(parser, &sequence, &simple.Timeout{Name: "http-request"})
	addParser(parser, &sequence, &simple.Timeout{Name: "client"})
	addParser(parser, &sequence, &simple.Timeout{Name: "client-fin"})
	addParser(parser, &sequence, &simple.Timeout{Name: "http-keep-alive"})
	addParser(parser, &sequence, &simple.Timeout{Name: "tarpit"})
	addParser(parser, &sequence, &simple.Number{Name: "clitcpka-cnt"})
	addParser(parser, &sequence, &simple.Time{Name: "clitcpka-idle"})
	addParser(parser, &sequence, &simple.Time{Name: "clitcpka-intvl"})
	addParser(parser, &sequence, &filters.Filters{})
	addParser(parser, &sequence, &parsers.CompressionAlgo{})
	addParser(parser, &sequence, &parsers.CompressionType{})
	addParser(parser, &sequence, &parsers.CompressionOffload{})
	addParser(parser, &sequence, &tcp.Requests{})
	addParser(parser, &sequence, &stats.Stats{Mode: "frontend"})
	addParser(parser, &sequence, &http.Requests{Mode: "frontend"})
	addParser(parser, &sequence, &http.Redirect{})
	addParser(parser, &sequence, &parsers.UniqueIDFormat{})
	addParser(parser, &sequence, &parsers.UniqueIDHeader{})
	addParser(parser, &sequence, &parsers.ErrorFile{})
	addParser(parser, &sequence, &parsers.ErrorFiles{})
	addParser(parser, &sequence, &parsers.ErrorLoc302{})
	addParser(parser, &sequence, &parsers.ErrorLoc303{})
	addParser(parser, &sequence, &parsers.ConfigSnippet{})
	addParser(parser, &sequence, &parsers.UseBackend{})
	addParser(parser, &sequence, &parsers.DefaultBackend{})
	addParser(parser, &sequence, &parsers.StickTable{})
	addParser(parser, &sequence, &tcp.Responses{})
	addParser(parser, &sequence, &http.Responses{Mode: "frontend"})
	addParser(parser, &sequence, &http.AfterResponses{})
	addParser(parser, &sequence, &http.HTTPErrors{})
	addParser(parser, &sequence, &parsers.DeclareCapture{})
	addParser(parser, &sequence, &simple.Number{Name: "rate-limit sessions"})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getBackendParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	addParser(parser, &sequence, &simple.Number{Name: "id"})
	addParser(parser, &sequence, &simple.String{Name: "description"})
	addParser(parser, &sequence, &simple.Enabled{Name: "enabled"})
	addParser(parser, &sequence, &simple.Enabled{Name: "disabled"})
	addParser(parser, &sequence, &parsers.Mode{})
	addParser(parser, &sequence, &parsers.HashType{})
	addParser(parser, &sequence, &parsers.Balance{})
	addParser(parser, &sequence, &parsers.ACL{})
	addParser(parser, &sequence, &parsers.ForcePersist{})
	addParser(parser, &sequence, &parsers.IgnorePersist{})
	addParser(parser, &sequence, &parsers.BindProcess{})
	addParser(parser, &sequence, &simple.Option{Name: "httpclose"})
	addParser(parser, &sequence, &simple.Option{Name: "forceclose"})
	addParser(parser, &sequence, &simple.Option{Name: "http-buffer-request"})
	addParser(parser, &sequence, &simple.Option{Name: "http-server-close"})
	addParser(parser, &sequence, &simple.Option{Name: "http-keep-alive"})
	addParser(parser, &sequence, &simple.Option{Name: "http-pretend-keepalive"})
	addParser(parser, &sequence, &simple.Option{Name: "http-use-htx"})
	addParser(parser, &sequence, &simple.Option{Name: "http-no-delay"})
	addParser(parser, &sequence, &simple.Option{Name: "http-proxy"})
	addParser(parser, &sequence, &parsers.OptionForwardFor{})
	addParser(parser, &sequence, &simple.Option{Name: "ssl-hello-chk"})
	addParser(parser, &sequence, &parsers.OptionSmtpchk{})
	addParser(parser, &sequence, &simple.Option{Name: "ldap-check"})
	addParser(parser, &sequence, &parsers.OptionMysqlCheck{})
	addParser(parser, &sequence, &simple.Option{Name: "abortonclose"})
	addParser(parser, &sequence, &parsers.OptionPgsqlCheck{})
	addParser(parser, &sequence, &simple.Option{Name: "redis-check"})
	addParser(parser, &sequence, &parsers.OptionRedispatch{})
	addParser(parser, &sequence, &simple.Option{Name: "external-check"})
	addParser(parser, &sequence, &simple.Option{Name: "splice-auto"})
	addParser(parser, &sequence, &simple.Option{Name: "splice-request"})
	addParser(parser, &sequence, &simple.Option{Name: "splice-response"})
	addParser(parser, &sequence, &simple.Option{Name: "log-health-checks"})
	addParser(parser, &sequence, &simple.String{Name: "log-tag"})
	addParser(parser, &sequence, &simple.Option{Name: "tcpka"})
	addParser(parser, &sequence, &simple.Option{Name: "srvtcpka"})
	addParser(parser, &sequence, &simple.Option{Name: "allbackups"})
	addParser(parser, &sequence, &simple.Option{Name: "accept-invalid-http-response"})
	addParser(parser, &sequence, &simple.Option{Name: "h1-case-adjust-bogus-server"})
	addParser(parser, &sequence, &simple.Option{Name: "tcp-check"})
	addParser(parser, &sequence, &simple.Option{Name: "checkcache"})
	addParser(parser, &sequence, &simple.Option{Name: "independent-streams"})
	addParser(parser, &sequence, &simple.Option{Name: "nolinger"})
	addParser(parser, &sequence, &parsers.OptionOriginalTo{})
	addParser(parser, &sequence, &simple.Option{Name: "persist"})
	addParser(parser, &sequence, &simple.Option{Name: "prefer-last-server"})
	addParser(parser, &sequence, &simple.Option{Name: "spop-check"})
	addParser(parser, &sequence, &simple.Option{Name: "tcp-smart-connect"})
	addParser(parser, &sequence, &simple.Option{Name: "transparent"})
	addParser(parser, &sequence, &parsers.OptionHTTPRestrictReqHdrNames{})
	addParser(parser, &sequence, &tcp.Checks{})
	addParser(parser, &sequence, &parsers.OptionHttpchk{})
	if p.Options.UseV2HTTPCheck {
		addParser(parser, &sequence, &parsers.HTTPCheckV2{})
	} else {
		addParser(parser, &sequence, &http.Checks{Mode: "backend"})
	}
	addParser(parser, &sequence, &parsers.ExternalCheckPath{})
	addParser(parser, &sequence, &parsers.ExternalCheckCommand{})
	addParser(parser, &sequence, &parsers.Log{})
	addParser(parser, &sequence, &parsers.EmailAlert{})
	addParser(parser, &sequence, &simple.Timeout{Name: "http-request"})
	addParser(parser, &sequence, &simple.Timeout{Name: "queue"})
	addParser(parser, &sequence, &simple.Timeout{Name: "http-keep-alive"})
	addParser(parser, &sequence, &simple.Timeout{Name: "check"})
	addParser(parser, &sequence, &simple.Timeout{Name: "tunnel"})
	addParser(parser, &sequence, &simple.Timeout{Name: "server"})
	addParser(parser, &sequence, &simple.Timeout{Name: "server-fin"})
	addParser(parser, &sequence, &simple.Timeout{Name: "connect"})
	addParser(parser, &sequence, &simple.Timeout{Name: "tarpit"})
	addParser(parser, &sequence, &simple.Number{Name: "srvtcpka-cnt"})
	addParser(parser, &sequence, &simple.Time{Name: "srvtcpka-idle"})
	addParser(parser, &sequence, &simple.Time{Name: "srvtcpka-intvl"})
	addParser(parser, &sequence, &parsers.DefaultServer{})
	addParser(parser, &sequence, &parsers.Stick{})
	addParser(parser, &sequence, &filters.Filters{})
	addParser(parser, &sequence, &parsers.CompressionAlgo{})
	addParser(parser, &sequence, &parsers.CompressionType{})
	addParser(parser, &sequence, &parsers.CompressionOffload{})
	addParser(parser, &sequence, &tcp.Requests{})
	addParser(parser, &sequence, &stats.Stats{Mode: "backend"})
	addParser(parser, &sequence, &parsers.HTTPReuse{})
	addParser(parser, &sequence, &http.Requests{Mode: "backend"})
	addParser(parser, &sequence, &http.Redirect{})
	addParser(parser, &sequence, &parsers.Cookie{})
	addParser(parser, &sequence, &simple.Word{Name: "dynamic-cookie-key"})
	addParser(parser, &sequence, &parsers.UseServer{})
	addParser(parser, &sequence, &parsers.StickTable{})
	addParser(parser, &sequence, &parsers.ConfigSnippet{})
	addParser(parser, &sequence, &parsers.ErrorFile{})
	addParser(parser, &sequence, &parsers.ErrorFiles{})
	addParser(parser, &sequence, &parsers.ErrorLoc302{})
	addParser(parser, &sequence, &parsers.ErrorLoc303{})
	addParser(parser, &sequence, &parsers.Server{})
	addParser(parser, &sequence, &simple.Number{Name: "retries"})
	addParser(parser, &sequence, &tcp.Responses{})
	addParser(parser, &sequence, &http.Responses{Mode: "backend"})
	addParser(parser, &sequence, &http.AfterResponses{})
	addParser(parser, &sequence, &http.HTTPErrors{})
	addParser(parser, &sequence, &parsers.ServerTemplate{})
	addParser(parser, &sequence, &parsers.LoadServerStateFromFile{})
	addParser(parser, &sequence, &parsers.UseFcgiApp{})
	addParser(parser, &sequence, &simple.Word{Name: "server-state-file-name"})
	addParser(parser, &sequence, &simple.Number{Name: "fullconn"})
	addParser(parser, &sequence, &simple.Number{Name: "max-keep-alive-queue"})
	addParser(parser, &sequence, &simple.String{Name: "retry-on"})
	addParser(parser, &sequence, &parsers.HTTPSendNameHeader{})
	addParser(parser, &sequence, &parsers.Source{})
	addParser(parser, &sequence, &parsers.Persist{})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getListenParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	if p.Options.UseListenSectionParsers {
		addParser(parser, &sequence, &simple.Number{Name: "id"})
		addParser(parser, &sequence, &simple.String{Name: "description"})
		addParser(parser, &sequence, &simple.Enabled{Name: "enabled"})
		addParser(parser, &sequence, &simple.Enabled{Name: "disabled"})
		addParser(parser, &sequence, &parsers.Mode{})
		addParser(parser, &sequence, &parsers.HashType{})
		addParser(parser, &sequence, &parsers.Balance{})
		addParser(parser, &sequence, &parsers.MaxConn{})
		addParser(parser, &sequence, &simple.Number{Name: "backlog"})
		addParser(parser, &sequence, &parsers.Bind{})
		addParser(parser, &sequence, &parsers.ACL{})
		addParser(parser, &sequence, &parsers.ForcePersist{})
		addParser(parser, &sequence, &parsers.IgnorePersist{})
		addParser(parser, &sequence, &parsers.MonitorURI{})
		addParser(parser, &sequence, &parsers.MonitorFail{})
		addParser(parser, &sequence, &parsers.BindProcess{})
		addParser(parser, &sequence, &simple.Word{Name: "log-tag"})
		addParser(parser, &sequence, &simple.String{Name: "log-format"})
		addParser(parser, &sequence, &simple.String{Name: "log-format-sd"})
		addParser(parser, &sequence, &simple.String{Name: "error-log-format"})
		addParser(parser, &sequence, &parsers.Log{})
		addParser(parser, &sequence, &simple.Option{Name: "httpclose"})
		addParser(parser, &sequence, &simple.Option{Name: "forceclose"})
		addParser(parser, &sequence, &simple.Option{Name: "http-buffer-request"})
		addParser(parser, &sequence, &simple.Option{Name: "http-server-close"})
		addParser(parser, &sequence, &simple.Option{Name: "http-keep-alive"})
		addParser(parser, &sequence, &simple.Option{Name: "http-pretend-keepalive"})
		addParser(parser, &sequence, &simple.Option{Name: "http-use-htx"})
		addParser(parser, &sequence, &simple.Option{Name: "http-no-delay"})
		addParser(parser, &sequence, &simple.Option{Name: "http-proxy"})
		addParser(parser, &sequence, &parsers.OptionForwardFor{})
		addParser(parser, &sequence, &simple.Option{Name: "ssl-hello-chk"})
		addParser(parser, &sequence, &parsers.OptionSmtpchk{})
		addParser(parser, &sequence, &simple.Option{Name: "ldap-check"})
		addParser(parser, &sequence, &parsers.OptionMysqlCheck{})
		addParser(parser, &sequence, &simple.Option{Name: "abortonclose"})
		addParser(parser, &sequence, &parsers.OptionPgsqlCheck{})
		addParser(parser, &sequence, &simple.Option{Name: "redis-check"})
		addParser(parser, &sequence, &parsers.OptionRedispatch{})
		addParser(parser, &sequence, &simple.Option{Name: "external-check"})
		addParser(parser, &sequence, &simple.Option{Name: "tcplog"})
		addParser(parser, &sequence, &simple.Option{Name: "dontlognull"})
		addParser(parser, &sequence, &simple.Option{Name: "contstats"})
		addParser(parser, &sequence, &simple.Option{Name: "log-separate-errors"})
		addParser(parser, &sequence, &simple.Option{Name: "tcpka"})
		addParser(parser, &sequence, &simple.Option{Name: "clitcpka"})
		addParser(parser, &sequence, &simple.Option{Name: "splice-auto"})
		addParser(parser, &sequence, &simple.Option{Name: "splice-request"})
		addParser(parser, &sequence, &simple.Option{Name: "splice-response"})
		addParser(parser, &sequence, &simple.Option{Name: "log-health-checks"})
		addParser(parser, &sequence, &simple.String{Name: "log-tag"})
		addParser(parser, &sequence, &simple.Option{Name: "srvtcpka"})
		addParser(parser, &sequence, &simple.Option{Name: "allbackups"})
		addParser(parser, &sequence, &simple.Option{Name: "accept-invalid-http-request"})
		addParser(parser, &sequence, &simple.Option{Name: "h1-case-adjust-bogus-client"})
		addParser(parser, &sequence, &simple.Option{Name: "disable-h2-upgrade"})
		addParser(parser, &sequence, &simple.Option{Name: "logasap"})
		addParser(parser, &sequence, &parsers.OptionHTTPLog{})
		addParser(parser, &sequence, &simple.Option{Name: "accept-invalid-http-response"})
		addParser(parser, &sequence, &simple.Option{Name: "h1-case-adjust-bogus-server"})
		addParser(parser, &sequence, &simple.Option{Name: "tcp-check"})
		addParser(parser, &sequence, &simple.Option{Name: "checkcache"})
		addParser(parser, &sequence, &simple.Option{Name: "http-ignore-probes"})
		addParser(parser, &sequence, &simple.Option{Name: "http-use-proxy-header"})
		addParser(parser, &sequence, &simple.Option{Name: "httpslog"})
		addParser(parser, &sequence, &simple.Option{Name: "independent-streams"})
		addParser(parser, &sequence, &simple.Option{Name: "nolinger"})
		addParser(parser, &sequence, &parsers.OptionOriginalTo{})
		addParser(parser, &sequence, &simple.Option{Name: "persist"})
		addParser(parser, &sequence, &simple.Option{Name: "prefer-last-server"})
		addParser(parser, &sequence, &simple.Option{Name: "socket-stats"})
		addParser(parser, &sequence, &simple.Option{Name: "tcp-smart-accept"})
		addParser(parser, &sequence, &simple.Option{Name: "tcp-smart-connect"})
		addParser(parser, &sequence, &simple.Option{Name: "transparent"})
		addParser(parser, &sequence, &simple.Option{Name: "idle-close-on-response"})
		addParser(parser, &sequence, &simple.Option{Name: "dontlog-normal"})
		addParser(parser, &sequence, &parsers.OptionHTTPRestrictReqHdrNames{})
		addParser(parser, &sequence, &tcp.Checks{})
		addParser(parser, &sequence, &parsers.OptionHttpchk{})
		if p.Options.UseV2HTTPCheck {
			addParser(parser, &sequence, &parsers.HTTPCheckV2{})
		} else {
			addParser(parser, &sequence, &http.Checks{Mode: "listen"})
		}
		addParser(parser, &sequence, &parsers.ExternalCheckPath{})
		addParser(parser, &sequence, &parsers.ExternalCheckCommand{})
		addParser(parser, &sequence, &simple.Timeout{Name: "http-request"})
		addParser(parser, &sequence, &simple.Timeout{Name: "client"})
		addParser(parser, &sequence, &simple.Timeout{Name: "client-fin"})
		addParser(parser, &sequence, &simple.Timeout{Name: "queue"})
		addParser(parser, &sequence, &simple.Timeout{Name: "http-keep-alive"})
		addParser(parser, &sequence, &simple.Timeout{Name: "check"})
		addParser(parser, &sequence, &simple.Timeout{Name: "tunnel"})
		addParser(parser, &sequence, &simple.Timeout{Name: "server"})
		addParser(parser, &sequence, &simple.Timeout{Name: "server-fin"})
		addParser(parser, &sequence, &simple.Timeout{Name: "connect"})
		addParser(parser, &sequence, &simple.Timeout{Name: "tarpit"})
		addParser(parser, &sequence, &parsers.DefaultServer{})
		addParser(parser, &sequence, &parsers.Stick{})
		addParser(parser, &sequence, &filters.Filters{})
		addParser(parser, &sequence, &parsers.CompressionAlgo{})
		addParser(parser, &sequence, &parsers.CompressionType{})
		addParser(parser, &sequence, &parsers.CompressionOffload{})
		addParser(parser, &sequence, &tcp.Requests{})
		addParser(parser, &sequence, &stats.Stats{Mode: "listen"})
		addParser(parser, &sequence, &parsers.HTTPReuse{})
		addParser(parser, &sequence, &http.Requests{Mode: "listen"})
		addParser(parser, &sequence, &http.Redirect{})
		addParser(parser, &sequence, &parsers.Cookie{})
		addParser(parser, &sequence, &simple.Word{Name: "dynamic-cookie-key"})
		addParser(parser, &sequence, &parsers.UseServer{})
		addParser(parser, &sequence, &parsers.UniqueIDFormat{})
		addParser(parser, &sequence, &parsers.UniqueIDHeader{})
		addParser(parser, &sequence, &parsers.UseFcgiApp{})
		addParser(parser, &sequence, &parsers.ConfigSnippet{})
		addParser(parser, &sequence, &parsers.UseBackend{})
		addParser(parser, &sequence, &parsers.DefaultBackend{})
		addParser(parser, &sequence, &parsers.StickTable{})
		addParser(parser, &sequence, &parsers.ConfigSnippet{})
		addParser(parser, &sequence, &parsers.ErrorFile{})
		addParser(parser, &sequence, &parsers.ErrorFiles{})
		addParser(parser, &sequence, &parsers.ErrorLoc302{})
		addParser(parser, &sequence, &parsers.ErrorLoc303{})
		addParser(parser, &sequence, &parsers.Server{})
		addParser(parser, &sequence, &simple.Number{Name: "retries"})
		addParser(parser, &sequence, &simple.Number{Name: "clitcpka-cnt"})
		addParser(parser, &sequence, &simple.Time{Name: "clitcpka-idle"})
		addParser(parser, &sequence, &simple.Time{Name: "clitcpka-intvl"})
		addParser(parser, &sequence, &simple.Number{Name: "srvtcpka-cnt"})
		addParser(parser, &sequence, &simple.Time{Name: "srvtcpka-idle"})
		addParser(parser, &sequence, &simple.Time{Name: "srvtcpka-intvl"})
		addParser(parser, &sequence, &tcp.Responses{})
		addParser(parser, &sequence, &http.Responses{Mode: "listen"})
		addParser(parser, &sequence, &http.AfterResponses{})
		addParser(parser, &sequence, &http.HTTPErrors{})
		addParser(parser, &sequence, &parsers.DeclareCapture{})
		addParser(parser, &sequence, &parsers.LoadServerStateFromFile{})
		addParser(parser, &sequence, &simple.Word{Name: "server-state-file-name"})
		addParser(parser, &sequence, &simple.Number{Name: "fullconn"})
		addParser(parser, &sequence, &simple.Number{Name: "max-keep-alive-queue"})
		addParser(parser, &sequence, &simple.String{Name: "retry-on"})
		addParser(parser, &sequence, &parsers.HTTPSendNameHeader{})
		addParser(parser, &sequence, &parsers.Source{})
		addParser(parser, &sequence, &parsers.Persist{})
		addParser(parser, &sequence, &simple.Number{Name: "rate-limit sessions"})
	}
	return p.createParsers(parser, sequence)
}

func (p *configParser) getResolverParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	addParser(parser, &sequence, &parsers.Nameserver{})
	addParser(parser, &sequence, &simple.TimeTwoWords{Keywords: []string{"hold", "nx"}})
	addParser(parser, &sequence, &simple.TimeTwoWords{Keywords: []string{"hold", "obsolete"}})
	addParser(parser, &sequence, &simple.TimeTwoWords{Keywords: []string{"hold", "other"}})
	addParser(parser, &sequence, &simple.TimeTwoWords{Keywords: []string{"hold", "refused"}})
	addParser(parser, &sequence, &simple.TimeTwoWords{Keywords: []string{"hold", "timeout"}})
	addParser(parser, &sequence, &simple.TimeTwoWords{Keywords: []string{"hold", "valid"}})
	addParser(parser, &sequence, &simple.Timeout{Name: "resolve"})
	addParser(parser, &sequence, &simple.Timeout{Name: "retry"})
	addParser(parser, &sequence, &simple.Word{Name: "accepted_payload_size"})
	addParser(parser, &sequence, &simple.Enabled{Name: "parse-resolv-conf"})
	addParser(parser, &sequence, &simple.Word{Name: "resolve_retries"})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getUserlistParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	addParser(parser, &sequence, &parsers.Group{})
	addParser(parser, &sequence, &parsers.User{})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getFcgiAppParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	addParser(parser, &sequence, &parsers.ACL{})
	addParser(parser, &sequence, &simple.String{Name: "docroot"})
	addParser(parser, &sequence, &simple.String{Name: "index"})
	addParser(parser, &sequence, &parsers.LogStdErr{})
	addParser(parser, &sequence, &parsers.PassHeader{})
	addParser(parser, &sequence, &simple.String{Name: "path-info"})
	addParser(parser, &sequence, &simple.Option{Name: "get-values"})
	addParser(parser, &sequence, &simple.Option{Name: "keep-conn"})
	addParser(parser, &sequence, &parsers.OptionMaxReqs{})
	addParser(parser, &sequence, &simple.Option{Name: "mpxs-conns"})
	addParser(parser, &sequence, &parsers.SetParam{})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getPeersParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	addParser(parser, &sequence, &simple.Enabled{Name: "enabled"})
	addParser(parser, &sequence, &simple.Enabled{Name: "disabled"})
	addParser(parser, &sequence, &parsers.Peer{})
	addParser(parser, &sequence, &parsers.DefaultBind{})
	addParser(parser, &sequence, &parsers.DefaultServer{})
	addParser(parser, &sequence, &parsers.Log{})
	addParser(parser, &sequence, &parsers.Bind{})
	addParser(parser, &sequence, &parsers.Server{})
	addParser(parser, &sequence, &parsers.StickTable{})
	addParser(parser, &sequence, &parsers.Table{})
	addParser(parser, &sequence, &simple.Number{Name: "shards"})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getMailersParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	addParser(parser, &sequence, &simple.TimeTwoWords{Keywords: []string{"timeout", "mail"}})
	addParser(parser, &sequence, &parsers.Mailer{})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getCacheParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	addParser(parser, &sequence, &simple.Number{Name: "total-max-size"})
	addParser(parser, &sequence, &simple.Number{Name: "max-object-size"})
	addParser(parser, &sequence, &simple.Number{Name: "max-age"})
	addParser(parser, &sequence, &simple.Number{Name: "max-secondary-entries"})
	addParser(parser, &sequence, &parsers.ProcessVary{})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getProgramParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	addParser(parser, &sequence, &parsers.Command{})
	addParser(parser, &sequence, &simple.String{Name: "user"})
	addParser(parser, &sequence, &simple.String{Name: "group"})
	addParser(parser, &sequence, &simple.Option{Name: "start-on-reload"})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getHTTPErrorsParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	addParser(parser, &sequence, &parsers.ErrorFile{})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getRingParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	addParser(parser, &sequence, &simple.String{Name: "description"})
	addParser(parser, &sequence, &simple.String{Name: "format"})
	addParser(parser, &sequence, &simple.Number{Name: "maxlen"})
	addParser(parser, &sequence, &simple.Size{Name: "size"})
	addParser(parser, &sequence, &simple.Timeout{Name: "connect"})
	addParser(parser, &sequence, &simple.Timeout{Name: "server"})
	addParser(parser, &sequence, &parsers.Server{})
	return p.createParsers(parser, sequence)
}

func (p *configParser) getLogForwardParser() *Parsers {
	parser := map[string]ParserInterface{}
	sequence := []Section{}
	addParser(parser, &sequence, &parsers.DgramBind{})
	addParser(parser, &sequence, &parsers.Bind{})
	addParser(parser, &sequence, &parsers.Log{})
	addParser(parser, &sequence, &simple.Number{Name: "backlog"})
	addParser(parser, &sequence, &simple.Number{Name: "maxconn"})
	addParser(parser, &sequence, &simple.Timeout{Name: "client"})
	return p.createParsers(parser, sequence)
}
