code: func walk(node ast.Node) ([]string, error) {
  	var l []string
  
  	switch n := node.(type) {
  	case *ast.IndexExpr:
  		ret, err := walk(n.X)
  		if err != nil {
  			return nil, err
  		}
  		l = append(l, ret...)
  
  		ret, err = walk(n.Index)
  		if err != nil {
  			return nil, err
  		}
  		l = append(l, ret...)
  	case *ast.SelectorExpr:
  		ret, err := walk(n.X)
  		if err != nil {
  			return nil, err
  		}
  		l = append(l, ret...)
  
  		ret, err = walk(n.Sel)
  		if err != nil {
  			return nil, err
  		}
  		l = append(l, ret...)
  	case *ast.Ident:
  		return []string{n.Name}, nil
  	case *ast.BasicLit:
  		value, err := strconv.Unquote(n.Value)
  		if err != nil {
  			return nil, err
  		}
  		return []string{value}, nil
  	default:
  		return nil, trace.BadParameter("unknown node type: %T", n)
  	}
  
  	return l, nil
  }
docs: // walk will walk the ast tree and gather all the variable parts into a slice and return it.