func (p *toml) lookupTable(t *ast.Table, keys []string) (*ast.Table, error) { for _, s := range keys { val, exists := t.Fields[s] if !exists { tbl := &ast.Table{ Line: p.line, Name: s, Type: ast.TableTypeNormal, } if t.Fields == nil { t.Fields = make(map[string]interface{}) } t.Fields[s] = tbl t = tbl continue } switch v := val.(type) { case *ast.Table: t = v case []*ast.Table: t = v[len(v)-1] case *ast.KeyValue: return nil, fmt.Errorf("key `%s' is in conflict with line %d", s, v.Line) default: return nil, fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", s, v) } } return t, nil }
func (p *toml) setArrayTable(t *ast.Table, buf []rune, begin, end int) { name := string(buf[begin:end]) if t, exists := p.tableMap[name]; exists && t.Type == ast.TableTypeNormal { p.Error(fmt.Errorf("table `%s' is in conflict with %v table in line %d", name, t.Type, t.Line)) } names := splitTableKey(name) t, err := p.lookupTable(t, names[:len(names)-1]) if err != nil { p.Error(err) } last := names[len(names)-1] tbl := &ast.Table{ Position: ast.Position{begin, end}, Line: p.line, Name: last, Type: ast.TableTypeArray, } switch v := t.Fields[last].(type) { case nil: if t.Fields == nil { t.Fields = make(map[string]interface{}) } t.Fields[last] = []*ast.Table{tbl} case []*ast.Table: t.Fields[last] = append(v, tbl) case *ast.KeyValue: p.Error(fmt.Errorf("key `%s' is in conflict with line %d", last, v.Line)) default: p.Error(fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", last, v)) } p.currentTable = tbl p.tableMap[name] = p.currentTable }