github.com/vcilabs/webrpc@v0.5.2-0.20201116131534-162e27b1b33b/schema/ridl/type_parser.go (about) 1 package ridl 2 3 import ( 4 "errors" 5 ) 6 7 func (p *parser) expectMapDefinition() (*token, error) { 8 9 tok := p.cursor() 10 if tok.val != "map" { 11 return nil, errors.New(`expecting "map"`) 12 } 13 p.next() 14 15 tokens := []*token{tok} 16 17 loop: 18 for { 19 tok := p.cursor() 20 21 switch tok.tt { 22 23 case tokenWhitespace: 24 p.next() 25 continue loop 26 27 case tokenCloseAngleBracket: 28 p.next() 29 break loop 30 31 case tokenOpenAngleBracket: 32 types, err := p.expectTypeList() 33 if err != nil { 34 return nil, err 35 } 36 37 tokens = append(tokens, types) 38 continue loop 39 40 default: 41 return nil, errUnexpectedToken 42 } 43 } 44 45 return composedValue(tokens) 46 } 47 48 func (p *parser) expectArgumentList() ([]*ArgumentNode, error) { 49 values := []*ArgumentNode{} 50 51 matches, err := p.match(tokenWord, tokenWhitespace) 52 if err == nil { 53 if matches[0].val != "stream" { 54 return nil, errUnexpectedToken 55 } 56 } 57 58 tok, err := p.match(tokenOpenParen) 59 if err != nil { 60 return nil, err 61 } 62 63 tokens := []*token{tok[0]} 64 65 loop: 66 for { 67 tok := p.cursor() 68 69 switch tok.tt { 70 71 case tokenWhitespace: 72 p.next() 73 continue 74 75 case tokenCloseParen: 76 tokens = append(tokens, tok) 77 p.next() 78 break loop 79 80 case tokenComma: 81 tokens = append(tokens, tok) 82 p.next() 83 84 case tokenWord: 85 var argument []*token 86 var name *token 87 88 optional := false 89 90 matches, err := p.match(tokenWord, tokenQuestionMark, tokenColon, tokenWhitespace) 91 if err == nil { 92 argument = []*token{matches[0], matches[1], matches[2]} 93 name = matches[0] 94 optional = true 95 } else { 96 matches, err = p.match(tokenWord, tokenColon, tokenWhitespace) 97 if err != nil { 98 return nil, err 99 } 100 argument = []*token{matches[0], matches[1]} 101 name = matches[0] 102 } 103 104 varType, err := p.expectType() 105 if err != nil { 106 return nil, err 107 } 108 109 values = append(values, &ArgumentNode{ 110 name: newTokenNode(name), 111 argumentType: newTokenNode(varType), 112 optional: optional, 113 }) 114 115 tokens = append(tokens, append(argument, varType)...) 116 117 default: 118 return nil, errUnexpectedToken 119 120 } 121 } 122 123 //return composedValue(tokens) 124 125 return values, nil 126 } 127 128 func (p *parser) expectTypeList() (*token, error) { 129 130 tok, err := p.match(tokenOpenAngleBracket) 131 if err != nil { 132 return nil, err 133 } 134 135 tokens := []*token{tok[0]} 136 137 loop: 138 for { 139 tok := p.cursor() 140 141 switch tok.tt { 142 143 case tokenWhitespace: 144 p.next() 145 continue 146 147 case tokenCloseAngleBracket: 148 tokens = append(tokens, tok) 149 break loop 150 151 case tokenComma: 152 tokens = append(tokens, tok) 153 p.next() 154 155 case tokenWord, tokenOpenBracket: 156 tok, err := p.expectType() 157 if err != nil { 158 return nil, err 159 } 160 161 tokens = append(tokens, tok) 162 163 default: 164 return nil, errUnexpectedToken 165 } 166 } 167 168 return composedValue(tokens) 169 } 170 171 func (p *parser) expectType() (*token, error) { 172 tokens := []*token{} 173 174 loop: 175 for { 176 tok := p.cursor() 177 178 switch tok.tt { 179 180 case tokenNewLine, tokenWhitespace, tokenComma, tokenCloseAngleBracket, tokenCloseParen, tokenHash: 181 break loop 182 183 case tokenEOF: 184 return nil, errUnexpectedEOF 185 186 case tokenOpenBracket: 187 brackets, err := p.match(tokenOpenBracket, tokenCloseBracket) 188 if err != nil { 189 return nil, err 190 } 191 192 typeName, err := p.expectType() 193 if err != nil { 194 return nil, err 195 } 196 197 tokens = append(tokens, append(brackets, typeName)...) 198 continue loop 199 200 case tokenWord: 201 202 switch tok.val { 203 204 case "map": 205 var err error 206 207 tok, err = p.expectMapDefinition() 208 if err != nil { 209 return nil, err 210 } 211 212 tokens = append(tokens, tok) 213 continue loop 214 } 215 216 tokens = append(tokens, tok) 217 p.next() 218 continue 219 220 default: 221 return nil, errUnexpectedToken 222 } 223 224 p.next() 225 } 226 227 return composedValue(tokens) 228 }