| 51 | } |
| 52 | |
| 53 | func recurseNodeProperties(nodes []*ast.MappingValueNode, line, column, nodeOffset int, properties map[string]*jsonschema.Schema, arrayAttributes bool) ([]*ast.MappingValueNode, any, bool) { |
| 54 | if len(nodes) == nodeOffset { |
| 55 | if nodes[len(nodes)-1].Key.GetToken().Position.Column >= column { |
| 56 | return nodes, nil, false |
| 57 | } |
| 58 | return nodes, properties, arrayAttributes |
| 59 | } |
| 60 | if nodes[nodeOffset].Key.GetToken().Position.Column == column { |
| 61 | return nodes[0:nodeOffset], properties, false |
| 62 | } |
| 63 | |
| 64 | value := nodes[nodeOffset].Key.GetToken().Value |
| 65 | if prop, ok := properties[value]; ok { |
| 66 | if prop.Ref != nil { |
| 67 | if len(prop.Ref.Properties) > 0 { |
| 68 | return recurseNodeProperties(nodes, line, column, nodeOffset+1, prop.Ref.Properties, false) |
| 69 | } |
| 70 | // try to match the child node to patternProperties |
| 71 | if len(nodes) > nodeOffset+1 { |
| 72 | for regexp, property := range prop.Ref.PatternProperties { |
| 73 | nextValue := nodes[nodeOffset+1].Key.GetToken().Value |
| 74 | if regexp.MatchString(nextValue) { |
| 75 | for _, nested := range property.OneOf { |
| 76 | if slices.Contains(nested.Types.ToStrings(), "object") { |
| 77 | return recurseNodeProperties(nodes, line, column, nodeOffset+2, nested.Properties, false) |
| 78 | } |
| 79 | } |
| 80 | } |
| 81 | } |
| 82 | } |
| 83 | if schema, ok := prop.Ref.Items.(*jsonschema.Schema); ok { |
| 84 | for _, nested := range schema.OneOf { |
| 85 | if nested.Types != nil && slices.Contains(nested.Types.ToStrings(), "object") { |
| 86 | if len(nested.Properties) > 0 { |
| 87 | return recurseNodeProperties(nodes, line, column, nodeOffset+1, nested.Properties, true) |
| 88 | } |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | for _, schema := range prop.OneOf { |
| 95 | if schema.Types != nil && slices.Contains(schema.Types.ToStrings(), "object") { |
| 96 | if len(schema.Properties) > 0 { |
| 97 | return recurseNodeProperties(nodes, line, column, nodeOffset+1, schema.Properties, false) |
| 98 | } |
| 99 | |
| 100 | for regexp, property := range schema.PatternProperties { |
| 101 | if len(nodes) == nodeOffset+1 { |
| 102 | return nodes, nil, false |
| 103 | } |
| 104 | |
| 105 | nextValue := nodes[nodeOffset+1].Key.GetToken().Value |
| 106 | if regexp.MatchString(nextValue) { |
| 107 | for _, nested := range property.OneOf { |
| 108 | if slices.Contains(nested.Types.ToStrings(), "object") { |
| 109 | return recurseNodeProperties(nodes, line, column, nodeOffset+2, nested.Properties, false) |
| 110 | } |