// Copyright (C) 2016 The Android Open Source Project
//
// 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 semantic

import "fmt"

// Visit invokes visitor for all the children of the supplied node.
func Visit(node Node, visitor func(Node)) {
	Replace(node, func(n Node) Node { visitor(n); return n })
}

// Replace invokes visitor for all the children of the supplied node, replacing
// the node with the returned value.
func Replace(node Node, visitor func(Node) Node) {
	switch n := node.(type) {
	case *Abort:
	case *API:
		(*Symbols)(&n.members).Visit(func(_ string, n Node) { visitor(n) })
	case *ArrayAssign:
		n.To = visitor(n.To).(*ArrayIndex)
		n.Value = visitor(n.Value).(Expression)
	case *ArrayIndex:
		n.Array = visitor(n.Array).(Expression)
		n.Index = visitor(n.Index).(Expression)
	case *ArrayInitializer:
		n.Array = visitor(n.Array).(Type)
		for i, c := range n.Values {
			n.Values[i] = visitor(c).(Expression)
		}
	case *Slice:
		n.To = visitor(n.To).(Type)
	case *SliceIndex:
		n.Slice = visitor(n.Slice).(Expression)
		n.Index = visitor(n.Index).(Expression)
	case *SliceAssign:
		n.To = visitor(n.To).(*SliceIndex)
		n.Value = visitor(n.Value).(Expression)
	case *Assert:
		n.Condition = visitor(n.Condition).(Expression)
	case *Assign:
		n.LHS = visitor(n.LHS).(Expression)
		n.RHS = visitor(n.RHS).(Expression)
	case *Annotation:
		for i, c := range n.Arguments {
			n.Arguments[i] = visitor(c).(Expression)
		}
	case *Block:
		for i, c := range n.Statements {
			n.Statements[i] = visitor(c)
		}
	case BoolValue:
	case *BinaryOp:
		n.LHS = visitor(n.LHS).(Expression)
		n.RHS = visitor(n.RHS).(Expression)
	case *BitTest:
		n.Bitfield = visitor(n.Bitfield).(Expression)
		n.Bits = visitor(n.Bits).(Expression)
	case *UnaryOp:
		n.Expression = visitor(n.Expression).(Expression)
	case *Branch:
		n.Condition = visitor(n.Condition).(Expression)
		n.True = visitor(n.True).(*Block)
		if n.False != nil {
			n.False = visitor(n.False).(*Block)
		}
	case *Builtin:
	case *Reference:
		n.To = visitor(n.To).(Type)
	case *Call:
		n.Type = visitor(n.Type).(Type)
		n.Target = visitor(n.Target).(*Callable)
		for i, a := range n.Arguments {
			n.Arguments[i] = visitor(a).(Expression)
		}
	case *Callable:
		if n.Object != nil {
			n.Object = visitor(n.Object).(Expression)
		}
		n.Function = visitor(n.Function).(*Function)
	case *Case:
		for i, c := range n.Conditions {
			n.Conditions[i] = visitor(c).(Expression)
		}
		n.Block = visitor(n.Block).(*Block)
	case *Cast:
		n.Object = visitor(n.Object).(Expression)
		n.Type = visitor(n.Type).(Type)
	case *Class:
		for i, f := range n.Fields {
			n.Fields[i] = visitor(f).(*Field)
		}
		for i, m := range n.Methods {
			n.Methods[i] = visitor(m).(*Function)
		}
	case *ClassInitializer:
		for i, f := range n.Fields {
			n.Fields[i] = visitor(f).(*FieldInitializer)
		}
	case *Choice:
		for i, c := range n.Conditions {
			n.Conditions[i] = visitor(c).(Expression)
		}
		n.Expression = visitor(n.Expression).(Expression)
	case *Definition:
		n.Expression = visitor(n.Expression).(Expression)
	case *DefinitionUsage:
		n.Expression = visitor(n.Expression).(Expression)
		n.Definition = visitor(n.Definition).(*Definition)
	case *DeclareLocal:
		n.Local = visitor(n.Local).(*Local)
		if n.Local.Value != nil {
			n.Local.Value = visitor(n.Local.Value).(Expression)
		}
	case Documentation:
	case *Enum:
		for i, e := range n.Extends {
			n.Extends[i] = visitor(e).(*Enum)
		}
		for i, e := range n.Entries {
			n.Entries[i] = visitor(e).(*EnumEntry)
		}
	case *EnumEntry:
	case *Label:
	case *Pseudonym:
		n.To = visitor(n.To).(Type)
		for i, m := range n.Methods {
			n.Methods[i] = visitor(m).(*Function)
		}
		for i, l := range n.labels {
			n.labels[i] = visitor(l).(*Label)
		}
	case *Fence:
		if n.Statement != nil {
			n.Statement = visitor(n.Statement).(Node)
		}
	case *Field:
		n.Type = visitor(n.Type).(Type)
		if n.Default != nil {
			n.Default = visitor(n.Default).(Expression)
		}
	case *FieldInitializer:
		n.Value = visitor(n.Value).(Expression)
	case Float32Value:
	case Float64Value:
	case *Function:
		n.Docs = visitor(n.Docs).(Documentation)
		n.Return = visitor(n.Return).(*Parameter)
		for i, c := range n.FullParameters {
			n.FullParameters[i] = visitor(c).(*Parameter)
		}
		if n.Block != nil {
			n.Block = visitor(n.Block).(*Block)
		}
		n.Signature = visitor(n.Signature).(*Signature)
	case *Parameter:
		for i, c := range n.Annotations {
			n.Annotations[i] = visitor(c).(*Annotation)
		}
		n.Type = visitor(n.Type).(Type)
	case *Global:
	case *StaticArray:
	case *Signature:
	case Int8Value:
	case Int16Value:
	case Int32Value:
	case Int64Value:
	case *Iteration:
		n.Iterator = visitor(n.Iterator).(*Local)
		n.Iterable = visitor(n.Iterable).(Expression)
		n.Block = visitor(n.Block).(*Block)
	case *Length:
		n.Object = visitor(n.Object).(Expression)
	case *Local:
		n.Type = visitor(n.Type).(Type)
	case *Map:
		n.KeyType = visitor(n.KeyType).(Type)
		n.ValueType = visitor(n.ValueType).(Type)
	case *MapAssign:
		n.To = visitor(n.To).(*MapIndex)
		n.Value = visitor(n.Value).(Expression)
	case *MapContains:
		n.Key = visitor(n.Key).(Expression)
		n.Map = visitor(n.Map).(Expression)
	case *MapIndex:
		n.Map = visitor(n.Map).(Expression)
		n.Index = visitor(n.Index).(Expression)
	case *MapRemove:
		n.Map = visitor(n.Map).(Expression)
		n.Key = visitor(n.Key).(Expression)
	case *Member:
		n.Object = visitor(n.Object).(Expression)
		n.Field = visitor(n.Field).(*Field)
	case *Pointer:
		n.To = visitor(n.To).(Type)
	case *Return:
		if n.Value != nil {
			n.Value = visitor(n.Value).(Expression)
		}
	case *Select:
		n.Value = visitor(n.Value).(Expression)
		for i, c := range n.Choices {
			n.Choices[i] = visitor(c).(*Choice)
		}
		if n.Default != nil {
			n.Default = visitor(n.Default).(Expression)
		}
	case StringValue:
	case *Switch:
		n.Value = visitor(n.Value).(Expression)
		for i, c := range n.Cases {
			n.Cases[i] = visitor(c).(*Case)
		}
		if n.Default != nil {
			n.Default = visitor(n.Default).(*Block)
		}
	case Uint8Value:
	case Uint16Value:
	case Uint32Value:
	case Uint64Value:
	case *Unknown:
	case *Clone:
		n.Slice = visitor(n.Slice).(Expression)
	case *Copy:
		n.Src = visitor(n.Src).(Expression)
		n.Dst = visitor(n.Dst).(Expression)
	case *Create:
	case *Ignore:
	case *Make:
		n.Size = visitor(n.Size).(Expression)
	case Null:
	case *PointerRange:
		n.Pointer = visitor(n.Pointer).(Expression)
		n.Range = visitor(n.Range).(*BinaryOp)
	case *Read:
		n.Slice = visitor(n.Slice).(Expression)
	case *SliceRange:
		n.Slice = visitor(n.Slice).(Expression)
		n.Range = visitor(n.Range).(*BinaryOp)
	case *Write:
		n.Slice = visitor(n.Slice).(Expression)
	default:
		panic(fmt.Errorf("Unsupported semantic node type %T", n))
	}
}
