parseSnowflakeVariantPath parses the tail of a Snowflake VARIANT path expression. The current token must be `:`. Returns a VariantPath with the given root and the parsed segments. Grammar: path := ':' step ( '.' field | '[' expr ']' )* step := field | '"' quoted '"' field := ident
(root ast.Expression)
| 403 | // step := field | '"' quoted '"' |
| 404 | // field := identifier |
| 405 | func (p *Parser) parseSnowflakeVariantPath(root ast.Expression) (*ast.VariantPath, error) { |
| 406 | pos := p.currentLocation() |
| 407 | if !p.isType(models.TokenTypeColon) { |
| 408 | return nil, p.expectedError(":") |
| 409 | } |
| 410 | p.advance() // Consume leading : |
| 411 | |
| 412 | vp := &ast.VariantPath{Root: root, Pos: pos} |
| 413 | |
| 414 | // First segment must be a field name (identifier or string literal). |
| 415 | name, err := p.parseVariantFieldName() |
| 416 | if err != nil { |
| 417 | return nil, err |
| 418 | } |
| 419 | vp.Segments = append(vp.Segments, ast.VariantPathSegment{Name: name}) |
| 420 | |
| 421 | // Subsequent segments: `.field` | `[expr]` | `:field` (rare). |
| 422 | for { |
| 423 | switch { |
| 424 | case p.isType(models.TokenTypePeriod): |
| 425 | p.advance() |
| 426 | n, err := p.parseVariantFieldName() |
| 427 | if err != nil { |
| 428 | return nil, err |
| 429 | } |
| 430 | vp.Segments = append(vp.Segments, ast.VariantPathSegment{Name: n}) |
| 431 | case p.isType(models.TokenTypeColon): |
| 432 | p.advance() |
| 433 | n, err := p.parseVariantFieldName() |
| 434 | if err != nil { |
| 435 | return nil, err |
| 436 | } |
| 437 | vp.Segments = append(vp.Segments, ast.VariantPathSegment{Name: n}) |
| 438 | case p.isType(models.TokenTypeLBracket): |
| 439 | p.advance() // Consume [ |
| 440 | idx, err := p.parseExpression() |
| 441 | if err != nil { |
| 442 | return nil, err |
| 443 | } |
| 444 | if !p.isType(models.TokenTypeRBracket) { |
| 445 | return nil, p.expectedError("]") |
| 446 | } |
| 447 | p.advance() // Consume ] |
| 448 | vp.Segments = append(vp.Segments, ast.VariantPathSegment{Index: idx}) |
| 449 | default: |
| 450 | return vp, nil |
| 451 | } |
| 452 | } |
| 453 | } |
| 454 | |
| 455 | // parseVariantFieldName consumes one VARIANT path field name, which may be |
| 456 | // a bare identifier or a double-quoted string. Returns the name and |
no test coverage detected