func (a *MapExp) ArrayLength() int {
	return -1
}
If KnownLength is true and CallMode is ModeArrayCall, ArrayLength returns
the length of the array referred to by this source.  Otherwise it will
return -1.
package syntax
import (
	"fmt"
	"strings"
)
type CallMode int
const (
	ModeSingleCall = CallMode(iota)
	ModeArrayCall
	ModeMapCall
	ModeUnknownMapCall
	ModeNullMapCall
)
func (m CallMode) MarshalText() ([]byte, error) {
	switch m {
	case ModeSingleCall:
		return nil, nil
	case ModeArrayCall:
		return []byte(KindArray), nil
	case ModeMapCall:
		return []byte(KindMap), nil
	case ModeUnknownMapCall:
		return []byte("unknown"), nil
	}
	return nil, fmt.Errorf("invalid map call mode %d", m)
}
func (m *CallMode) UnmarshalText(b []byte) error {
	if len(b) == 0 || isNullBytes(b) {
		*m = 0
		return nil
	}
	switch ExpKind(b) {
	case KindArray:
		*m = ModeArrayCall
	case KindMap:
		*m = ModeMapCall
	case "unknown":
		*m = ModeUnknownMapCall
	default:
		return fmt.Errorf("invalid map call mode %s", string(b))
	}
	return nil
}
func (m CallMode) String() string {
	switch m {
	case ModeSingleCall:
		return "simple"
	case ModeArrayCall:
		return string(KindArray)
	case ModeMapCall:
		return string(KindMap)
	case ModeUnknownMapCall:
		return "unknown"
	case ModeNullMapCall:
		return string(KindNull)
	}
	return "invalid"
}
type MapCallSource interface {
	fmt.GoStringer
	CallMode() CallMode
	KnownLength() bool
	ArrayLength() int
	Keys() map[string]Exp
}
type placeholderMapSource struct{}
var mapSourcePlaceholder placeholderMapSource
func (*placeholderMapSource) CallMode() CallMode {
	return ModeUnknownMapCall
}
func (*placeholderMapSource) KnownLength() bool {
	return false
}
func (*placeholderMapSource) ArrayLength() int {
	return -1
}
func (*placeholderMapSource) Keys() map[string]Exp {
	return nil
}
func (*placeholderMapSource) GoString() string {
	return "placeholder"
}
func (m *placeholderMapSource) Equal(o MapCallSource) bool {
	return m == o
}
type placeholderArrayMapSource struct {
	placeholderMapSource
}
func (*placeholderArrayMapSource) CallMode() CallMode {
	return ModeArrayCall
}
func (*placeholderArrayMapSource) GoString() string {
	return "placeholder array"
}
type placeholderMapMapSource struct {
	placeholderMapSource
}
func (*placeholderMapMapSource) CallMode() CallMode {
	return ModeMapCall
}
func (*placeholderMapMapSource) GoString() string {
	return "placeholder map"
}
func (*NullExp) CallMode() CallMode {
	return ModeNullMapCall
}
func (*NullExp) KnownLength() bool {
	return true
}
func (*NullExp) ArrayLength() int {
	return 0
}
func (*NullExp) Keys() map[string]Exp {
	return nil
}
var emptyMap MapExp
var emptyArray ArrayExp
type MapCallSet struct {
	Master MapCallSource `json:"primary_source"`
	Sources SourceList `json:"-"`
}
type SourceList []MapCallSource
func (srcs *SourceList) Add(src MapCallSource) {
	for _, s := range *srcs {
		if s == src {
			return
		}
	}
	*srcs = append(*srcs, src)
}
func (m *MapCallSet) CallMode() CallMode {
	if m == nil || m.Master == nil {
		return ModeSingleCall
	}
	return m.Master.CallMode()
}
func (m *MapCallSet) KnownLength() bool {
	if m == nil || m.Master == nil {
		return false
	}
	return m.Master.KnownLength()
}
func (m *MapCallSet) ArrayLength() int {
	if m == nil || m.Master == nil {
		return -1
	}
	return m.Master.ArrayLength()
}
func (m *MapCallSet) Keys() map[string]Exp {
	if m == nil || m.Master == nil {
		return nil
	}
	return m.Master.Keys()
}
func (m *MapCallSet) GoString() string {
	var buf strings.Builder
	ma := m.Master.GoString()
	buf.Grow(6 + (1+len(ma))*len(m.Sources))
	if _, err := buf.WriteString("set {"); err != nil {
		panic(err)
	}
	if _, err := buf.WriteString(ma); err != nil {
		panic(err)
	}
	for _, s := range m.Sources {
		if s != m.Master {
			if err := buf.WriteByte(';'); err != nil {
				panic(err)
			}
			if _, err := buf.WriteString(s.GoString()); err != nil {
				panic(err)
			}
		}
	}
	if err := buf.WriteByte('}'); err != nil {
		panic(err)
	}
	return buf.String()
}
func MergeMapCallSources(a, b MapCallSource) (MapCallSource, error) {
	if a == b {
		return a, nil
	}
	if a == nil {
		return b, nil
	}
	if b == nil {
		return a, nil
	}
	switch a := a.(type) {
	case *CallStm:
		src, err := MergeMapCallSources(a.Mapping, b)
		if err == nil {
			a.Mapping = src
		}
		return src, err
	case *MergeExp:
		src, err := MergeMapCallSources(a.MergeOver, b)
		if err == nil {
			a.MergeOver = src
		}
		return src, err
	}
	switch b := b.(type) {
	case *CallStm:
		src, err := MergeMapCallSources(a, b.Mapping)
		if err == nil {
			b.Mapping = src
		}
		return src, err
	case *MergeExp:
		src, err := MergeMapCallSources(a, b.MergeOver)
		if err == nil {
			b.MergeOver = src
		}
		return src, err
	}
	if b == nil || b.CallMode() == ModeSingleCall {
		return a, nil
	}
	if a == nil || a.CallMode() == ModeSingleCall {
		return b, nil
	}
	if b.CallMode() == ModeUnknownMapCall {
		switch bs := b.(type) {
		case *RefExp:
		case *MapCallSet:
			if as, ok := a.(*MapCallSet); ok {
				if as.CallMode() != ModeUnknownMapCall {
					for _, k := range bs.Sources {
						as.Sources.Add(k)
					}
					return a, nil
				} else {
					for _, k := range as.Sources {
						bs.Sources.Add(k)
					}
					return b, nil
				}
			}
		default:
			return a, nil
		}
		switch as := a.(type) {
		case *placeholderMapSource:
			return b, nil
		case *MapCallSet:
			as.Sources.Add(b)
			return as, nil
		default:
			return &MapCallSet{
				Master:  a,
				Sources: SourceList{a, b},
			}, nil
		}
	} else if a.CallMode() == ModeUnknownMapCall {
		switch as := a.(type) {
		case *RefExp:
		case *MapCallSet:
			if bs, ok := b.(*MapCallSet); ok {
				if bs.CallMode() != ModeUnknownMapCall {
					for _, k := range as.Sources {
						bs.Sources.Add(k)
					}
					return b, nil
				} else {
					for _, k := range bs.Sources {
						as.Sources.Add(k)
					}
					return a, nil
				}
			}
		default:
			return b, nil
		}
		switch bs := b.(type) {
		case *placeholderMapSource:
			return a, nil
		case *MapCallSet:
			bs.Sources.Add(a)
			return bs, nil
		default:
			return &MapCallSet{
				Master:  b,
				Sources: SourceList{a, b},
			}, nil
		}
	}
	switch b.(type) {
	case *placeholderArrayMapSource, *placeholderMapMapSource, *placeholderMapSource:
		if am, bm := a.CallMode(), b.CallMode(); am != ModeNullMapCall &&
			bm != ModeNullMapCall && am != bm {
			return a, fmt.Errorf("cannot split over both %vs and %vs", am, bm)
		}
		return a, nil
	}
	switch a.(type) {
	case *placeholderArrayMapSource, *placeholderMapMapSource, *placeholderMapSource:
		if am, bm := a.CallMode(), b.CallMode(); am != ModeNullMapCall &&
			bm != ModeNullMapCall && am != bm {
			return b, fmt.Errorf("cannot split over both %vs and %vs", am, bm)
		}
		return b, nil
	}
	if am, bm := a.CallMode(), b.CallMode(); am != bm && am != ModeNullMapCall && bm != ModeNullMapCall {
		return nil, fmt.Errorf("cannot split over both arrays and maps")
	} else if bm == ModeNullMapCall {
		return a, nil
	} else if am == ModeNullMapCall {
		return b, nil
	}
	if a.KnownLength() && b.KnownLength() {
		switch a.CallMode() {
		case ModeArrayCall:
			if la, lb := a.ArrayLength(), b.ArrayLength(); la != lb {
				return nil, fmt.Errorf("array length mismatch %d vs %d",
					la, lb)
			}
		case ModeMapCall:
			ka, kb := a.Keys(), b.Keys()
			if len(ka) != len(kb) {
				return nil, fmt.Errorf("map length mismatch %d vs %d",
					len(ka), len(kb))
			}
			for k := range ka {
				if _, ok := kb[k]; !ok {
					return nil, fmt.Errorf("map key missing %q", k)
				}
			}
		case ModeNullMapCall:
			switch b.CallMode() {
			case ModeArrayCall:
				if b.ArrayLength() != 0 {
					return nil, fmt.Errorf("array was not empty")
				}
			case ModeMapCall:
				if len(b.Keys()) != 0 {
					return nil, fmt.Errorf("map was not empty")
				}
			}
		}
	}
	if as, ok := a.(*MapCallSet); ok {
		switch bs := b.(type) {
		case *MapCallSet:
			if as.KnownLength() || !bs.KnownLength() {
				for _, s := range bs.Sources {
					as.Sources.Add(s)
				}
				return as, nil
			} else {
				for _, s := range as.Sources {
					bs.Sources.Add(s)
				}
				return bs, nil
			}
		default:
			as.Sources.Add(b)
			if !as.KnownLength() && b.KnownLength() {
				if b.CallMode() == ModeNullMapCall {
					if m := as.CallMode(); m == ModeArrayCall {
						as.Master = &emptyArray
					} else if m == ModeMapCall {
						as.Master = &emptyMap
					} else {
						as.Master = b
					}
				} else {
					as.Master = b
				}
			}
			return as, nil
		}
	} else if bs, ok := b.(*MapCallSet); ok {
		bs.Sources.Add(a)
		if !bs.KnownLength() && a.KnownLength() {
			if a.CallMode() == ModeNullMapCall {
				if m := bs.CallMode(); m == ModeArrayCall {
					bs.Master = &emptyArray
				} else if m == ModeMapCall {
					bs.Master = &emptyMap
				} else {
					bs.Master = a
				}
			} else {
				bs.Master = a
			}
		}
		return bs, nil
	} else {
		set := MapCallSet{
			Sources: SourceList{a, b},
			Master:  a,
		}
		if a.CallMode() == ModeNullMapCall {
			switch b.CallMode() {
			case ModeArrayCall:
				set.Master = &emptyArray
			case ModeMapCall:
				set.Master = &emptyMap
			}
		}
		if !set.KnownLength() {
			if b.KnownLength() {
				if b.CallMode() == ModeNullMapCall {
					switch a.CallMode() {
					case ModeArrayCall:
						set.Master = &emptyArray
					case ModeMapCall:
						set.Master = &emptyMap
					}
				} else {
					set.Master = b
				}
			}
		}
		return &set, nil
	}
}
func (c *CallStm) CallMode() CallMode {
	m := c.Mapping
	if m == nil {
		return ModeSingleCall
	}
	return m.CallMode()
}
func (c *CallStm) KnownLength() bool {
	m := c.Mapping
	if m == nil {
		return false
	}
	return m.KnownLength()
}
func (c *CallStm) ArrayLength() int {
	m := c.Mapping
	if m == nil {
		return -1
	}
	return m.ArrayLength()
}
func (c *CallStm) Keys() map[string]Exp {
	m := c.Mapping
	if m == nil {
		return nil
	}
	return m.Keys()
}
func (a *ArrayExp) CallMode() CallMode {
	return ModeArrayCall
}
func (a *ArrayExp) KnownLength() bool {
	return true
}
func (a *ArrayExp) ArrayLength() int {
	if a == nil {
		return 0
	}
	return len(a.Value)
}
func (a *ArrayExp) Keys() map[string]Exp {
	return nil
}
func (a *MapExp) CallMode() CallMode {
	return ModeMapCall
}
func (a *MapExp) KnownLength() bool {
	return true
}