github.com/asifdxtreme/cli@v6.1.3-0.20150123051144-9ead8700b4ae+incompatible/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto/text.go (about) 1 // Extensions for Protocol Buffers to create more go like structures. 2 // 3 // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. 4 // http://code.google.com/p/gogoprotobuf/gogoproto 5 // 6 // Go support for Protocol Buffers - Google's data interchange format 7 // 8 // Copyright 2010 The Go Authors. All rights reserved. 9 // http://code.google.com/p/goprotobuf/ 10 // 11 // Redistribution and use in source and binary forms, with or without 12 // modification, are permitted provided that the following conditions are 13 // met: 14 // 15 // * Redistributions of source code must retain the above copyright 16 // notice, this list of conditions and the following disclaimer. 17 // * Redistributions in binary form must reproduce the above 18 // copyright notice, this list of conditions and the following disclaimer 19 // in the documentation and/or other materials provided with the 20 // distribution. 21 // * Neither the name of Google Inc. nor the names of its 22 // contributors may be used to endorse or promote products derived from 23 // this software without specific prior written permission. 24 // 25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 37 package proto 38 39 // Functions for writing the text protocol buffer format. 40 41 import ( 42 "bufio" 43 "bytes" 44 "fmt" 45 "io" 46 "log" 47 "math" 48 "os" 49 "reflect" 50 "sort" 51 "strings" 52 ) 53 54 var ( 55 newline = []byte("\n") 56 spaces = []byte(" ") 57 gtNewline = []byte(">\n") 58 endBraceNewline = []byte("}\n") 59 backslashN = []byte{'\\', 'n'} 60 backslashR = []byte{'\\', 'r'} 61 backslashT = []byte{'\\', 't'} 62 backslashDQ = []byte{'\\', '"'} 63 backslashBS = []byte{'\\', '\\'} 64 posInf = []byte("inf") 65 negInf = []byte("-inf") 66 nan = []byte("nan") 67 ) 68 69 type writer interface { 70 io.Writer 71 WriteByte(byte) error 72 } 73 74 // textWriter is an io.Writer that tracks its indentation level. 75 type textWriter struct { 76 ind int 77 complete bool // if the current position is a complete line 78 compact bool // whether to write out as a one-liner 79 w writer 80 } 81 82 // textMarshaler is implemented by Messages that can marshal themsleves. 83 // It is identical to encoding.TextMarshaler, introduced in go 1.2, 84 // which will eventually replace it. 85 type textMarshaler interface { 86 MarshalText() (text []byte, err error) 87 } 88 89 func (w *textWriter) WriteString(s string) (n int, err error) { 90 if !strings.Contains(s, "\n") { 91 if !w.compact && w.complete { 92 w.writeIndent() 93 } 94 w.complete = false 95 return io.WriteString(w.w, s) 96 } 97 // WriteString is typically called without newlines, so this 98 // codepath and its copy are rare. We copy to avoid 99 // duplicating all of Write's logic here. 100 return w.Write([]byte(s)) 101 } 102 103 func (w *textWriter) Write(p []byte) (n int, err error) { 104 newlines := bytes.Count(p, newline) 105 if newlines == 0 { 106 if !w.compact && w.complete { 107 w.writeIndent() 108 } 109 n, err = w.w.Write(p) 110 w.complete = false 111 return n, err 112 } 113 114 frags := bytes.SplitN(p, newline, newlines+1) 115 if w.compact { 116 for i, frag := range frags { 117 if i > 0 { 118 if err := w.w.WriteByte(' '); err != nil { 119 return n, err 120 } 121 n++ 122 } 123 nn, err := w.w.Write(frag) 124 n += nn 125 if err != nil { 126 return n, err 127 } 128 } 129 return n, nil 130 } 131 132 for i, frag := range frags { 133 if w.complete { 134 w.writeIndent() 135 } 136 nn, err := w.w.Write(frag) 137 n += nn 138 if err != nil { 139 return n, err 140 } 141 if i+1 < len(frags) { 142 if err := w.w.WriteByte('\n'); err != nil { 143 return n, err 144 } 145 n++ 146 } 147 } 148 w.complete = len(frags[len(frags)-1]) == 0 149 return n, nil 150 } 151 152 func (w *textWriter) WriteByte(c byte) error { 153 if w.compact && c == '\n' { 154 c = ' ' 155 } 156 if !w.compact && w.complete { 157 w.writeIndent() 158 } 159 err := w.w.WriteByte(c) 160 w.complete = c == '\n' 161 return err 162 } 163 164 func (w *textWriter) indent() { w.ind++ } 165 166 func (w *textWriter) unindent() { 167 if w.ind == 0 { 168 log.Printf("proto: textWriter unindented too far") 169 return 170 } 171 w.ind-- 172 } 173 174 func writeName(w *textWriter, props *Properties) error { 175 if _, err := w.WriteString(props.OrigName); err != nil { 176 return err 177 } 178 if props.Wire != "group" { 179 return w.WriteByte(':') 180 } 181 return nil 182 } 183 184 var ( 185 messageSetType = reflect.TypeOf((*MessageSet)(nil)).Elem() 186 ) 187 188 // raw is the interface satisfied by RawMessage. 189 type raw interface { 190 Bytes() []byte 191 } 192 193 func writeStruct(w *textWriter, sv reflect.Value) error { 194 if sv.Type() == messageSetType { 195 return writeMessageSet(w, sv.Addr().Interface().(*MessageSet)) 196 } 197 198 st := sv.Type() 199 sprops := GetProperties(st) 200 for i := 0; i < sv.NumField(); i++ { 201 fv := sv.Field(i) 202 props := sprops.Prop[i] 203 name := st.Field(i).Name 204 205 if strings.HasPrefix(name, "XXX_") { 206 // There are two XXX_ fields: 207 // XXX_unrecognized []byte 208 // XXX_extensions map[int32]proto.Extension 209 // The first is handled here; 210 // the second is handled at the bottom of this function. 211 if name == "XXX_unrecognized" && !fv.IsNil() { 212 if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil { 213 return err 214 } 215 } 216 continue 217 } 218 if fv.Kind() == reflect.Ptr && fv.IsNil() { 219 // Field not filled in. This could be an optional field or 220 // a required field that wasn't filled in. Either way, there 221 // isn't anything we can show for it. 222 continue 223 } 224 if fv.Kind() == reflect.Slice && fv.IsNil() { 225 // Repeated field that is empty, or a bytes field that is unused. 226 continue 227 } 228 229 if props.Repeated && fv.Kind() == reflect.Slice { 230 // Repeated field. 231 for j := 0; j < fv.Len(); j++ { 232 if err := writeName(w, props); err != nil { 233 return err 234 } 235 if !w.compact { 236 if err := w.WriteByte(' '); err != nil { 237 return err 238 } 239 } 240 v := fv.Index(j) 241 if v.Kind() == reflect.Ptr && v.IsNil() { 242 // A nil message in a repeated field is not valid, 243 // but we can handle that more gracefully than panicking. 244 if _, err := w.Write([]byte("<nil>\n")); err != nil { 245 return err 246 } 247 continue 248 } 249 if len(props.Enum) > 0 { 250 if err := writeEnum(w, v, props); err != nil { 251 return err 252 } 253 } else if err := writeAny(w, v, props); err != nil { 254 return err 255 } 256 if err := w.WriteByte('\n'); err != nil { 257 return err 258 } 259 } 260 continue 261 } 262 263 if err := writeName(w, props); err != nil { 264 return err 265 } 266 if !w.compact { 267 if err := w.WriteByte(' '); err != nil { 268 return err 269 } 270 } 271 if b, ok := fv.Interface().(raw); ok { 272 if err := writeRaw(w, b.Bytes()); err != nil { 273 return err 274 } 275 continue 276 } 277 278 if len(props.Enum) > 0 { 279 if err := writeEnum(w, fv, props); err != nil { 280 return err 281 } 282 } else if err := writeAny(w, fv, props); err != nil { 283 return err 284 } 285 286 if err := w.WriteByte('\n'); err != nil { 287 return err 288 } 289 } 290 291 // Extensions (the XXX_extensions field). 292 pv := sv.Addr() 293 if pv.Type().Implements(extendableProtoType) { 294 if err := writeExtensions(w, pv); err != nil { 295 return err 296 } 297 } 298 299 return nil 300 } 301 302 // writeRaw writes an uninterpreted raw message. 303 func writeRaw(w *textWriter, b []byte) error { 304 if err := w.WriteByte('<'); err != nil { 305 return err 306 } 307 if !w.compact { 308 if err := w.WriteByte('\n'); err != nil { 309 return err 310 } 311 } 312 w.indent() 313 if err := writeUnknownStruct(w, b); err != nil { 314 return err 315 } 316 w.unindent() 317 if err := w.WriteByte('>'); err != nil { 318 return err 319 } 320 return nil 321 } 322 323 // writeAny writes an arbitrary field. 324 func writeAny(w *textWriter, v reflect.Value, props *Properties) error { 325 v = reflect.Indirect(v) 326 327 if props != nil && len(props.CustomType) > 0 { 328 var custom Marshaler = v.Interface().(Marshaler) 329 data, err := custom.Marshal() 330 if err != nil { 331 return err 332 } 333 if err := writeString(w, string(data)); err != nil { 334 return err 335 } 336 return nil 337 } 338 339 // Floats have special cases. 340 if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { 341 x := v.Float() 342 var b []byte 343 switch { 344 case math.IsInf(x, 1): 345 b = posInf 346 case math.IsInf(x, -1): 347 b = negInf 348 case math.IsNaN(x): 349 b = nan 350 } 351 if b != nil { 352 _, err := w.Write(b) 353 return err 354 } 355 // Other values are handled below. 356 } 357 358 // We don't attempt to serialise every possible value type; only those 359 // that can occur in protocol buffers. 360 switch v.Kind() { 361 case reflect.Slice: 362 // Should only be a []byte; repeated fields are handled in writeStruct. 363 if err := writeString(w, string(v.Interface().([]byte))); err != nil { 364 return err 365 } 366 case reflect.String: 367 if err := writeString(w, v.String()); err != nil { 368 return err 369 } 370 case reflect.Struct: 371 // Required/optional group/message. 372 var bra, ket byte = '<', '>' 373 if props != nil && props.Wire == "group" { 374 bra, ket = '{', '}' 375 } 376 if err := w.WriteByte(bra); err != nil { 377 return err 378 } 379 if !w.compact { 380 if err := w.WriteByte('\n'); err != nil { 381 return err 382 } 383 } 384 w.indent() 385 if tm, ok := v.Interface().(textMarshaler); ok { 386 text, err := tm.MarshalText() 387 if err != nil { 388 return err 389 } 390 if _, err = w.Write(text); err != nil { 391 return err 392 } 393 } else if err := writeStruct(w, v); err != nil { 394 return err 395 } 396 w.unindent() 397 if err := w.WriteByte(ket); err != nil { 398 return err 399 } 400 default: 401 _, err := fmt.Fprint(w, v.Interface()) 402 return err 403 } 404 return nil 405 } 406 407 // equivalent to C's isprint. 408 func isprint(c byte) bool { 409 return c >= 0x20 && c < 0x7f 410 } 411 412 // writeString writes a string in the protocol buffer text format. 413 // It is similar to strconv.Quote except we don't use Go escape sequences, 414 // we treat the string as a byte sequence, and we use octal escapes. 415 // These differences are to maintain interoperability with the other 416 // languages' implementations of the text format. 417 func writeString(w *textWriter, s string) error { 418 // use WriteByte here to get any needed indent 419 if err := w.WriteByte('"'); err != nil { 420 return err 421 } 422 // Loop over the bytes, not the runes. 423 for i := 0; i < len(s); i++ { 424 var err error 425 // Divergence from C++: we don't escape apostrophes. 426 // There's no need to escape them, and the C++ parser 427 // copes with a naked apostrophe. 428 switch c := s[i]; c { 429 case '\n': 430 _, err = w.w.Write(backslashN) 431 case '\r': 432 _, err = w.w.Write(backslashR) 433 case '\t': 434 _, err = w.w.Write(backslashT) 435 case '"': 436 _, err = w.w.Write(backslashDQ) 437 case '\\': 438 _, err = w.w.Write(backslashBS) 439 default: 440 if isprint(c) { 441 err = w.w.WriteByte(c) 442 } else { 443 _, err = fmt.Fprintf(w.w, "\\%03o", c) 444 } 445 } 446 if err != nil { 447 return err 448 } 449 } 450 return w.WriteByte('"') 451 } 452 453 func writeMessageSet(w *textWriter, ms *MessageSet) error { 454 for _, item := range ms.Item { 455 id := *item.TypeId 456 if msd, ok := messageSetMap[id]; ok { 457 // Known message set type. 458 if _, err := fmt.Fprintf(w, "[%s]: <\n", msd.name); err != nil { 459 return err 460 } 461 w.indent() 462 463 pb := reflect.New(msd.t.Elem()) 464 if err := Unmarshal(item.Message, pb.Interface().(Message)); err != nil { 465 if _, err := fmt.Fprintf(w, "/* bad message: %v */\n", err); err != nil { 466 return err 467 } 468 } else { 469 if err := writeStruct(w, pb.Elem()); err != nil { 470 return err 471 } 472 } 473 } else { 474 // Unknown type. 475 if _, err := fmt.Fprintf(w, "[%d]: <\n", id); err != nil { 476 return err 477 } 478 w.indent() 479 if err := writeUnknownStruct(w, item.Message); err != nil { 480 return err 481 } 482 } 483 w.unindent() 484 if _, err := w.Write(gtNewline); err != nil { 485 return err 486 } 487 } 488 return nil 489 } 490 491 func writeUnknownStruct(w *textWriter, data []byte) (err error) { 492 if !w.compact { 493 if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil { 494 return err 495 } 496 } 497 b := NewBuffer(data) 498 for b.index < len(b.buf) { 499 x, err := b.DecodeVarint() 500 if err != nil { 501 _, err := fmt.Fprintf(w, "/* %v */\n", err) 502 return err 503 } 504 wire, tag := x&7, x>>3 505 if wire == WireEndGroup { 506 w.unindent() 507 if _, err := w.Write(endBraceNewline); err != nil { 508 return err 509 } 510 continue 511 } 512 if _, err := fmt.Fprint(w, tag); err != nil { 513 return err 514 } 515 if wire != WireStartGroup { 516 if err := w.WriteByte(':'); err != nil { 517 return err 518 } 519 } 520 if !w.compact || wire == WireStartGroup { 521 if err := w.WriteByte(' '); err != nil { 522 return err 523 } 524 } 525 switch wire { 526 case WireBytes: 527 buf, e := b.DecodeRawBytes(false) 528 if e == nil { 529 _, err = fmt.Fprintf(w, "%q", buf) 530 } else { 531 _, err = fmt.Fprintf(w, "/* %v */", e) 532 } 533 case WireFixed32: 534 x, err = b.DecodeFixed32() 535 err = writeUnknownInt(w, x, err) 536 case WireFixed64: 537 x, err = b.DecodeFixed64() 538 err = writeUnknownInt(w, x, err) 539 case WireStartGroup: 540 err = w.WriteByte('{') 541 w.indent() 542 case WireVarint: 543 x, err = b.DecodeVarint() 544 err = writeUnknownInt(w, x, err) 545 default: 546 _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire) 547 } 548 if err != nil { 549 return err 550 } 551 if err = w.WriteByte('\n'); err != nil { 552 return err 553 } 554 } 555 return nil 556 } 557 558 func writeUnknownInt(w *textWriter, x uint64, err error) error { 559 if err == nil { 560 _, err = fmt.Fprint(w, x) 561 } else { 562 _, err = fmt.Fprintf(w, "/* %v */", err) 563 } 564 return err 565 } 566 567 type int32Slice []int32 568 569 func (s int32Slice) Len() int { return len(s) } 570 func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } 571 func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 572 573 // writeExtensions writes all the extensions in pv. 574 // pv is assumed to be a pointer to a protocol message struct that is extendable. 575 func writeExtensions(w *textWriter, pv reflect.Value) error { 576 emap := extensionMaps[pv.Type().Elem()] 577 ep := pv.Interface().(extendableProto) 578 579 // Order the extensions by ID. 580 // This isn't strictly necessary, but it will give us 581 // canonical output, which will also make testing easier. 582 var m map[int32]Extension 583 if em, ok := ep.(extensionsMap); ok { 584 m = em.ExtensionMap() 585 } else if em, ok := ep.(extensionsBytes); ok { 586 eb := em.GetExtensions() 587 var err error 588 m, err = BytesToExtensionsMap(*eb) 589 if err != nil { 590 return err 591 } 592 } 593 594 ids := make([]int32, 0, len(m)) 595 for id := range m { 596 ids = append(ids, id) 597 } 598 sort.Sort(int32Slice(ids)) 599 600 for _, extNum := range ids { 601 ext := m[extNum] 602 var desc *ExtensionDesc 603 if emap != nil { 604 desc = emap[extNum] 605 } 606 if desc == nil { 607 // Unknown extension. 608 if err := writeUnknownStruct(w, ext.enc); err != nil { 609 return err 610 } 611 continue 612 } 613 614 pb, err := GetExtension(ep, desc) 615 if err != nil { 616 if _, err := fmt.Fprintln(os.Stderr, "proto: failed getting extension: ", err); err != nil { 617 return err 618 } 619 continue 620 } 621 622 // Repeated extensions will appear as a slice. 623 if !desc.repeated() { 624 if err := writeExtension(w, desc.Name, pb); err != nil { 625 return err 626 } 627 } else { 628 v := reflect.ValueOf(pb) 629 for i := 0; i < v.Len(); i++ { 630 if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { 631 return err 632 } 633 } 634 } 635 } 636 return nil 637 } 638 639 func writeExtension(w *textWriter, name string, pb interface{}) error { 640 if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil { 641 return err 642 } 643 if !w.compact { 644 if err := w.WriteByte(' '); err != nil { 645 return err 646 } 647 } 648 if err := writeAny(w, reflect.ValueOf(pb), nil); err != nil { 649 return err 650 } 651 if err := w.WriteByte('\n'); err != nil { 652 return err 653 } 654 return nil 655 } 656 657 func (w *textWriter) writeIndent() { 658 if !w.complete { 659 return 660 } 661 remain := w.ind * 2 662 for remain > 0 { 663 n := remain 664 if n > len(spaces) { 665 n = len(spaces) 666 } 667 w.w.Write(spaces[:n]) 668 remain -= n 669 } 670 w.complete = false 671 } 672 673 func marshalText(w io.Writer, pb Message, compact bool) error { 674 val := reflect.ValueOf(pb) 675 if pb == nil || val.IsNil() { 676 w.Write([]byte("<nil>")) 677 return nil 678 } 679 var bw *bufio.Writer 680 ww, ok := w.(writer) 681 if !ok { 682 bw = bufio.NewWriter(w) 683 ww = bw 684 } 685 aw := &textWriter{ 686 w: ww, 687 complete: true, 688 compact: compact, 689 } 690 691 if tm, ok := pb.(textMarshaler); ok { 692 text, err := tm.MarshalText() 693 if err != nil { 694 return err 695 } 696 if _, err = aw.Write(text); err != nil { 697 return err 698 } 699 if bw != nil { 700 return bw.Flush() 701 } 702 return nil 703 } 704 // Dereference the received pointer so we don't have outer < and >. 705 v := reflect.Indirect(val) 706 if err := writeStruct(aw, v); err != nil { 707 return err 708 } 709 if bw != nil { 710 return bw.Flush() 711 } 712 return nil 713 } 714 715 // MarshalText writes a given protocol buffer in text format. 716 // The only errors returned are from w. 717 func MarshalText(w io.Writer, pb Message) error { 718 return marshalText(w, pb, false) 719 } 720 721 // MarshalTextString is the same as MarshalText, but returns the string directly. 722 func MarshalTextString(pb Message) string { 723 var buf bytes.Buffer 724 marshalText(&buf, pb, false) 725 return buf.String() 726 } 727 728 // CompactText writes a given protocol buffer in compact text format (one line). 729 func CompactText(w io.Writer, pb Message) error { return marshalText(w, pb, true) } 730 731 // CompactTextString is the same as CompactText, but returns the string directly. 732 func CompactTextString(pb Message) string { 733 var buf bytes.Buffer 734 marshalText(&buf, pb, true) 735 return buf.String() 736 }