1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20package thrift 21 22import ( 23 "context" 24 "encoding/base64" 25 "fmt" 26) 27 28const ( 29 THRIFT_JSON_PROTOCOL_VERSION = 1 30) 31 32// for references to _ParseContext see tsimplejson_protocol.go 33 34// JSON protocol implementation for thrift. 35// 36// This protocol produces/consumes a simple output format 37// suitable for parsing by scripting languages. It should not be 38// confused with the full-featured TJSONProtocol. 39// 40type TJSONProtocol struct { 41 *TSimpleJSONProtocol 42} 43 44// Constructor 45func NewTJSONProtocol(t TTransport) *TJSONProtocol { 46 v := &TJSONProtocol{TSimpleJSONProtocol: NewTSimpleJSONProtocol(t)} 47 v.parseContextStack = append(v.parseContextStack, int(_CONTEXT_IN_TOPLEVEL)) 48 v.dumpContext = append(v.dumpContext, int(_CONTEXT_IN_TOPLEVEL)) 49 return v 50} 51 52// Factory 53type TJSONProtocolFactory struct{} 54 55func (p *TJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol { 56 return NewTJSONProtocol(trans) 57} 58 59func NewTJSONProtocolFactory() *TJSONProtocolFactory { 60 return &TJSONProtocolFactory{} 61} 62 63func (p *TJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error { 64 p.resetContextStack() // THRIFT-3735 65 if e := p.OutputListBegin(); e != nil { 66 return e 67 } 68 if e := p.WriteI32(THRIFT_JSON_PROTOCOL_VERSION); e != nil { 69 return e 70 } 71 if e := p.WriteString(name); e != nil { 72 return e 73 } 74 if e := p.WriteByte(int8(typeId)); e != nil { 75 return e 76 } 77 if e := p.WriteI32(seqId); e != nil { 78 return e 79 } 80 return nil 81} 82 83func (p *TJSONProtocol) WriteMessageEnd() error { 84 return p.OutputListEnd() 85} 86 87func (p *TJSONProtocol) WriteStructBegin(name string) error { 88 if e := p.OutputObjectBegin(); e != nil { 89 return e 90 } 91 return nil 92} 93 94func (p *TJSONProtocol) WriteStructEnd() error { 95 return p.OutputObjectEnd() 96} 97 98func (p *TJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) error { 99 if e := p.WriteI16(id); e != nil { 100 return e 101 } 102 if e := p.OutputObjectBegin(); e != nil { 103 return e 104 } 105 s, e1 := p.TypeIdToString(typeId) 106 if e1 != nil { 107 return e1 108 } 109 if e := p.WriteString(s); e != nil { 110 return e 111 } 112 return nil 113} 114 115func (p *TJSONProtocol) WriteFieldEnd() error { 116 return p.OutputObjectEnd() 117} 118 119func (p *TJSONProtocol) WriteFieldStop() error { return nil } 120 121func (p *TJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error { 122 if e := p.OutputListBegin(); e != nil { 123 return e 124 } 125 s, e1 := p.TypeIdToString(keyType) 126 if e1 != nil { 127 return e1 128 } 129 if e := p.WriteString(s); e != nil { 130 return e 131 } 132 s, e1 = p.TypeIdToString(valueType) 133 if e1 != nil { 134 return e1 135 } 136 if e := p.WriteString(s); e != nil { 137 return e 138 } 139 if e := p.WriteI64(int64(size)); e != nil { 140 return e 141 } 142 return p.OutputObjectBegin() 143} 144 145func (p *TJSONProtocol) WriteMapEnd() error { 146 if e := p.OutputObjectEnd(); e != nil { 147 return e 148 } 149 return p.OutputListEnd() 150} 151 152func (p *TJSONProtocol) WriteListBegin(elemType TType, size int) error { 153 return p.OutputElemListBegin(elemType, size) 154} 155 156func (p *TJSONProtocol) WriteListEnd() error { 157 return p.OutputListEnd() 158} 159 160func (p *TJSONProtocol) WriteSetBegin(elemType TType, size int) error { 161 return p.OutputElemListBegin(elemType, size) 162} 163 164func (p *TJSONProtocol) WriteSetEnd() error { 165 return p.OutputListEnd() 166} 167 168func (p *TJSONProtocol) WriteBool(b bool) error { 169 if b { 170 return p.WriteI32(1) 171 } 172 return p.WriteI32(0) 173} 174 175func (p *TJSONProtocol) WriteByte(b int8) error { 176 return p.WriteI32(int32(b)) 177} 178 179func (p *TJSONProtocol) WriteI16(v int16) error { 180 return p.WriteI32(int32(v)) 181} 182 183func (p *TJSONProtocol) WriteI32(v int32) error { 184 return p.OutputI64(int64(v)) 185} 186 187func (p *TJSONProtocol) WriteI64(v int64) error { 188 return p.OutputI64(int64(v)) 189} 190 191func (p *TJSONProtocol) WriteDouble(v float64) error { 192 return p.OutputF64(v) 193} 194 195func (p *TJSONProtocol) WriteString(v string) error { 196 return p.OutputString(v) 197} 198 199func (p *TJSONProtocol) WriteBinary(v []byte) error { 200 // JSON library only takes in a string, 201 // not an arbitrary byte array, to ensure bytes are transmitted 202 // efficiently we must convert this into a valid JSON string 203 // therefore we use base64 encoding to avoid excessive escaping/quoting 204 if e := p.OutputPreValue(); e != nil { 205 return e 206 } 207 if _, e := p.write(JSON_QUOTE_BYTES); e != nil { 208 return NewTProtocolException(e) 209 } 210 writer := base64.NewEncoder(base64.StdEncoding, p.writer) 211 if _, e := writer.Write(v); e != nil { 212 p.writer.Reset(p.trans) // THRIFT-3735 213 return NewTProtocolException(e) 214 } 215 if e := writer.Close(); e != nil { 216 return NewTProtocolException(e) 217 } 218 if _, e := p.write(JSON_QUOTE_BYTES); e != nil { 219 return NewTProtocolException(e) 220 } 221 return p.OutputPostValue() 222} 223 224// Reading methods. 225func (p *TJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) { 226 p.resetContextStack() // THRIFT-3735 227 if isNull, err := p.ParseListBegin(); isNull || err != nil { 228 return name, typeId, seqId, err 229 } 230 version, err := p.ReadI32() 231 if err != nil { 232 return name, typeId, seqId, err 233 } 234 if version != THRIFT_JSON_PROTOCOL_VERSION { 235 e := fmt.Errorf("Unknown Protocol version %d, expected version %d", version, THRIFT_JSON_PROTOCOL_VERSION) 236 return name, typeId, seqId, NewTProtocolExceptionWithType(INVALID_DATA, e) 237 238 } 239 if name, err = p.ReadString(); err != nil { 240 return name, typeId, seqId, err 241 } 242 bTypeId, err := p.ReadByte() 243 typeId = TMessageType(bTypeId) 244 if err != nil { 245 return name, typeId, seqId, err 246 } 247 if seqId, err = p.ReadI32(); err != nil { 248 return name, typeId, seqId, err 249 } 250 return name, typeId, seqId, nil 251} 252 253func (p *TJSONProtocol) ReadMessageEnd() error { 254 err := p.ParseListEnd() 255 return err 256} 257 258func (p *TJSONProtocol) ReadStructBegin() (name string, err error) { 259 _, err = p.ParseObjectStart() 260 return "", err 261} 262 263func (p *TJSONProtocol) ReadStructEnd() error { 264 return p.ParseObjectEnd() 265} 266 267func (p *TJSONProtocol) ReadFieldBegin() (string, TType, int16, error) { 268 b, _ := p.reader.Peek(1) 269 if len(b) < 1 || b[0] == JSON_RBRACE[0] || b[0] == JSON_RBRACKET[0] { 270 return "", STOP, -1, nil 271 } 272 fieldId, err := p.ReadI16() 273 if err != nil { 274 return "", STOP, fieldId, err 275 } 276 if _, err = p.ParseObjectStart(); err != nil { 277 return "", STOP, fieldId, err 278 } 279 sType, err := p.ReadString() 280 if err != nil { 281 return "", STOP, fieldId, err 282 } 283 fType, err := p.StringToTypeId(sType) 284 return "", fType, fieldId, err 285} 286 287func (p *TJSONProtocol) ReadFieldEnd() error { 288 return p.ParseObjectEnd() 289} 290 291func (p *TJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e error) { 292 if isNull, e := p.ParseListBegin(); isNull || e != nil { 293 return VOID, VOID, 0, e 294 } 295 296 // read keyType 297 sKeyType, e := p.ReadString() 298 if e != nil { 299 return keyType, valueType, size, e 300 } 301 keyType, e = p.StringToTypeId(sKeyType) 302 if e != nil { 303 return keyType, valueType, size, e 304 } 305 306 // read valueType 307 sValueType, e := p.ReadString() 308 if e != nil { 309 return keyType, valueType, size, e 310 } 311 valueType, e = p.StringToTypeId(sValueType) 312 if e != nil { 313 return keyType, valueType, size, e 314 } 315 316 // read size 317 iSize, e := p.ReadI64() 318 if e != nil { 319 return keyType, valueType, size, e 320 } 321 size = int(iSize) 322 323 _, e = p.ParseObjectStart() 324 return keyType, valueType, size, e 325} 326 327func (p *TJSONProtocol) ReadMapEnd() error { 328 e := p.ParseObjectEnd() 329 if e != nil { 330 return e 331 } 332 return p.ParseListEnd() 333} 334 335func (p *TJSONProtocol) ReadListBegin() (elemType TType, size int, e error) { 336 return p.ParseElemListBegin() 337} 338 339func (p *TJSONProtocol) ReadListEnd() error { 340 return p.ParseListEnd() 341} 342 343func (p *TJSONProtocol) ReadSetBegin() (elemType TType, size int, e error) { 344 return p.ParseElemListBegin() 345} 346 347func (p *TJSONProtocol) ReadSetEnd() error { 348 return p.ParseListEnd() 349} 350 351func (p *TJSONProtocol) ReadBool() (bool, error) { 352 value, err := p.ReadI32() 353 return (value != 0), err 354} 355 356func (p *TJSONProtocol) ReadByte() (int8, error) { 357 v, err := p.ReadI64() 358 return int8(v), err 359} 360 361func (p *TJSONProtocol) ReadI16() (int16, error) { 362 v, err := p.ReadI64() 363 return int16(v), err 364} 365 366func (p *TJSONProtocol) ReadI32() (int32, error) { 367 v, err := p.ReadI64() 368 return int32(v), err 369} 370 371func (p *TJSONProtocol) ReadI64() (int64, error) { 372 v, _, err := p.ParseI64() 373 return v, err 374} 375 376func (p *TJSONProtocol) ReadDouble() (float64, error) { 377 v, _, err := p.ParseF64() 378 return v, err 379} 380 381func (p *TJSONProtocol) ReadString() (string, error) { 382 var v string 383 if err := p.ParsePreValue(); err != nil { 384 return v, err 385 } 386 f, _ := p.reader.Peek(1) 387 if len(f) > 0 && f[0] == JSON_QUOTE { 388 p.reader.ReadByte() 389 value, err := p.ParseStringBody() 390 v = value 391 if err != nil { 392 return v, err 393 } 394 } else if len(f) > 0 && f[0] == JSON_NULL[0] { 395 b := make([]byte, len(JSON_NULL)) 396 _, err := p.reader.Read(b) 397 if err != nil { 398 return v, NewTProtocolException(err) 399 } 400 if string(b) != string(JSON_NULL) { 401 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) 402 return v, NewTProtocolExceptionWithType(INVALID_DATA, e) 403 } 404 } else { 405 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) 406 return v, NewTProtocolExceptionWithType(INVALID_DATA, e) 407 } 408 return v, p.ParsePostValue() 409} 410 411func (p *TJSONProtocol) ReadBinary() ([]byte, error) { 412 var v []byte 413 if err := p.ParsePreValue(); err != nil { 414 return nil, err 415 } 416 f, _ := p.reader.Peek(1) 417 if len(f) > 0 && f[0] == JSON_QUOTE { 418 p.reader.ReadByte() 419 value, err := p.ParseBase64EncodedBody() 420 v = value 421 if err != nil { 422 return v, err 423 } 424 } else if len(f) > 0 && f[0] == JSON_NULL[0] { 425 b := make([]byte, len(JSON_NULL)) 426 _, err := p.reader.Read(b) 427 if err != nil { 428 return v, NewTProtocolException(err) 429 } 430 if string(b) != string(JSON_NULL) { 431 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) 432 return v, NewTProtocolExceptionWithType(INVALID_DATA, e) 433 } 434 } else { 435 e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) 436 return v, NewTProtocolExceptionWithType(INVALID_DATA, e) 437 } 438 439 return v, p.ParsePostValue() 440} 441 442func (p *TJSONProtocol) Flush(ctx context.Context) (err error) { 443 err = p.writer.Flush() 444 if err == nil { 445 err = p.trans.Flush(ctx) 446 } 447 return NewTProtocolException(err) 448} 449 450func (p *TJSONProtocol) Skip(fieldType TType) (err error) { 451 return SkipDefaultDepth(p, fieldType) 452} 453 454func (p *TJSONProtocol) Transport() TTransport { 455 return p.trans 456} 457 458func (p *TJSONProtocol) OutputElemListBegin(elemType TType, size int) error { 459 if e := p.OutputListBegin(); e != nil { 460 return e 461 } 462 s, e1 := p.TypeIdToString(elemType) 463 if e1 != nil { 464 return e1 465 } 466 if e := p.WriteString(s); e != nil { 467 return e 468 } 469 if e := p.WriteI64(int64(size)); e != nil { 470 return e 471 } 472 return nil 473} 474 475func (p *TJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) { 476 if isNull, e := p.ParseListBegin(); isNull || e != nil { 477 return VOID, 0, e 478 } 479 sElemType, err := p.ReadString() 480 if err != nil { 481 return VOID, size, err 482 } 483 elemType, err = p.StringToTypeId(sElemType) 484 if err != nil { 485 return elemType, size, err 486 } 487 nSize, err2 := p.ReadI64() 488 size = int(nSize) 489 return elemType, size, err2 490} 491 492func (p *TJSONProtocol) readElemListBegin() (elemType TType, size int, e error) { 493 if isNull, e := p.ParseListBegin(); isNull || e != nil { 494 return VOID, 0, e 495 } 496 sElemType, err := p.ReadString() 497 if err != nil { 498 return VOID, size, err 499 } 500 elemType, err = p.StringToTypeId(sElemType) 501 if err != nil { 502 return elemType, size, err 503 } 504 nSize, err2 := p.ReadI64() 505 size = int(nSize) 506 return elemType, size, err2 507} 508 509func (p *TJSONProtocol) writeElemListBegin(elemType TType, size int) error { 510 if e := p.OutputListBegin(); e != nil { 511 return e 512 } 513 s, e1 := p.TypeIdToString(elemType) 514 if e1 != nil { 515 return e1 516 } 517 if e := p.OutputString(s); e != nil { 518 return e 519 } 520 if e := p.OutputI64(int64(size)); e != nil { 521 return e 522 } 523 return nil 524} 525 526func (p *TJSONProtocol) TypeIdToString(fieldType TType) (string, error) { 527 switch byte(fieldType) { 528 case BOOL: 529 return "tf", nil 530 case BYTE: 531 return "i8", nil 532 case I16: 533 return "i16", nil 534 case I32: 535 return "i32", nil 536 case I64: 537 return "i64", nil 538 case DOUBLE: 539 return "dbl", nil 540 case STRING: 541 return "str", nil 542 case STRUCT: 543 return "rec", nil 544 case MAP: 545 return "map", nil 546 case SET: 547 return "set", nil 548 case LIST: 549 return "lst", nil 550 } 551 552 e := fmt.Errorf("Unknown fieldType: %d", int(fieldType)) 553 return "", NewTProtocolExceptionWithType(INVALID_DATA, e) 554} 555 556func (p *TJSONProtocol) StringToTypeId(fieldType string) (TType, error) { 557 switch fieldType { 558 case "tf": 559 return TType(BOOL), nil 560 case "i8": 561 return TType(BYTE), nil 562 case "i16": 563 return TType(I16), nil 564 case "i32": 565 return TType(I32), nil 566 case "i64": 567 return TType(I64), nil 568 case "dbl": 569 return TType(DOUBLE), nil 570 case "str": 571 return TType(STRING), nil 572 case "rec": 573 return TType(STRUCT), nil 574 case "map": 575 return TType(MAP), nil 576 case "set": 577 return TType(SET), nil 578 case "lst": 579 return TType(LIST), nil 580 } 581 582 e := fmt.Errorf("Unknown type identifier: %s", fieldType) 583 return TType(STOP), NewTProtocolExceptionWithType(INVALID_DATA, e) 584} 585