github.com/matm/etcd@v0.3.1-0.20140328024009-5b4a473f1453/third_party/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 func (w *textWriter) WriteString(s string) (n int, err error) { 83 if !strings.Contains(s, "\n") { 84 if !w.compact && w.complete { 85 w.writeIndent() 86 } 87 w.complete = false 88 return io.WriteString(w.w, s) 89 } 90 // WriteString is typically called without newlines, so this 91 // codepath and its copy are rare. We copy to avoid 92 // duplicating all of Write's logic here. 93 return w.Write([]byte(s)) 94 } 95 96 func (w *textWriter) Write(p []byte) (n int, err error) { 97 newlines := bytes.Count(p, newline) 98 if newlines == 0 { 99 if !w.compact && w.complete { 100 w.writeIndent() 101 } 102 n, err = w.w.Write(p) 103 w.complete = false 104 return n, err 105 } 106 107 frags := bytes.SplitN(p, newline, newlines+1) 108 if w.compact { 109 for i, frag := range frags { 110 if i > 0 { 111 if err := w.w.WriteByte(' '); err != nil { 112 return n, err 113 } 114 n++ 115 } 116 nn, err := w.w.Write(frag) 117 n += nn 118 if err != nil { 119 return n, err 120 } 121 } 122 return n, nil 123 } 124 125 for i, frag := range frags { 126 if w.complete { 127 w.writeIndent() 128 } 129 nn, err := w.w.Write(frag) 130 n += nn 131 if err != nil { 132 return n, err 133 } 134 if i+1 < len(frags) { 135 if err := w.w.WriteByte('\n'); err != nil { 136 return n, err 137 } 138 n++ 139 } 140 } 141 w.complete = len(frags[len(frags)-1]) == 0 142 return n, nil 143 } 144 145 func (w *textWriter) WriteByte(c byte) error { 146 if w.compact && c == '\n' { 147 c = ' ' 148 } 149 if !w.compact && w.complete { 150 w.writeIndent() 151 } 152 err := w.w.WriteByte(c) 153 w.complete = c == '\n' 154 return err 155 } 156 157 func (w *textWriter) indent() { w.ind++ } 158 159 func (w *textWriter) unindent() { 160 if w.ind == 0 { 161 log.Printf("proto: textWriter unindented too far") 162 return 163 } 164 w.ind-- 165 } 166 167 func writeName(w *textWriter, props *Properties) error { 168 if _, err := w.WriteString(props.OrigName); err != nil { 169 return err 170 } 171 if props.Wire != "group" { 172 return w.WriteByte(':') 173 } 174 return nil 175 } 176 177 var ( 178 messageSetType = reflect.TypeOf((*MessageSet)(nil)).Elem() 179 ) 180 181 // raw is the interface satisfied by RawMessage. 182 type raw interface { 183 Bytes() []byte 184 } 185 186 func writeStruct(w *textWriter, sv reflect.Value) error { 187 if sv.Type() == messageSetType { 188 return writeMessageSet(w, sv.Addr().Interface().(*MessageSet)) 189 } 190 191 st := sv.Type() 192 sprops := GetProperties(st) 193 for i := 0; i < sv.NumField(); i++ { 194 fv := sv.Field(i) 195 props := sprops.Prop[i] 196 name := st.Field(i).Name 197 198 if strings.HasPrefix(name, "XXX_") { 199 // There are two XXX_ fields: 200 // XXX_unrecognized []byte 201 // XXX_extensions map[int32]proto.Extension 202 // The first is handled here; 203 // the second is handled at the bottom of this function. 204 if name == "XXX_unrecognized" && !fv.IsNil() { 205 if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil { 206 return err 207 } 208 } 209 continue 210 } 211 if fv.Kind() == reflect.Ptr && fv.IsNil() { 212 // Field not filled in. This could be an optional field or 213 // a required field that wasn't filled in. Either way, there 214 // isn't anything we can show for it. 215 continue 216 } 217 if fv.Kind() == reflect.Slice && fv.IsNil() { 218 // Repeated field that is empty, or a bytes field that is unused. 219 continue 220 } 221 222 if props.Repeated && fv.Kind() == reflect.Slice { 223 // Repeated field. 224 for j := 0; j < fv.Len(); j++ { 225 if err := writeName(w, props); err != nil { 226 return err 227 } 228 if !w.compact { 229 if err := w.WriteByte(' '); err != nil { 230 return err 231 } 232 } 233 if len(props.Enum) > 0 { 234 if err := writeEnum(w, fv.Index(j), props); err != nil { 235 return err 236 } 237 } else if err := writeAny(w, fv.Index(j), props); err != nil { 238 return err 239 } 240 if err := w.WriteByte('\n'); err != nil { 241 return err 242 } 243 } 244 continue 245 } 246 247 if err := writeName(w, props); err != nil { 248 return err 249 } 250 if !w.compact { 251 if err := w.WriteByte(' '); err != nil { 252 return err 253 } 254 } 255 if b, ok := fv.Interface().(raw); ok { 256 if err := writeRaw(w, b.Bytes()); err != nil { 257 return err 258 } 259 continue 260 } 261 262 if len(props.Enum) > 0 { 263 if err := writeEnum(w, fv, props); err != nil { 264 return err 265 } 266 } else if err := writeAny(w, fv, props); err != nil { 267 return err 268 } 269 270 if err := w.WriteByte('\n'); err != nil { 271 return err 272 } 273 } 274 275 // Extensions (the XXX_extensions field). 276 pv := sv.Addr() 277 if pv.Type().Implements(extendableProtoType) { 278 if err := writeExtensions(w, pv); err != nil { 279 return err 280 } 281 } 282 283 return nil 284 } 285 286 // writeRaw writes an uninterpreted raw message. 287 func writeRaw(w *textWriter, b []byte) error { 288 if err := w.WriteByte('<'); err != nil { 289 return err 290 } 291 if !w.compact { 292 if err := w.WriteByte('\n'); err != nil { 293 return err 294 } 295 } 296 w.indent() 297 if err := writeUnknownStruct(w, b); err != nil { 298 return err 299 } 300 w.unindent() 301 if err := w.WriteByte('>'); err != nil { 302 return err 303 } 304 return nil 305 } 306 307 // writeAny writes an arbitrary field. 308 func writeAny(w *textWriter, v reflect.Value, props *Properties) error { 309 v = reflect.Indirect(v) 310 311 if props != nil && len(props.CustomType) > 0 { 312 var custom Marshaler = v.Interface().(Marshaler) 313 data, err := custom.Marshal() 314 if err != nil { 315 return err 316 } 317 if err := writeString(w, string(data)); err != nil { 318 return err 319 } 320 return nil 321 } 322 323 // Floats have special cases. 324 if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { 325 x := v.Float() 326 var b []byte 327 switch { 328 case math.IsInf(x, 1): 329 b = posInf 330 case math.IsInf(x, -1): 331 b = negInf 332 case math.IsNaN(x): 333 b = nan 334 } 335 if b != nil { 336 _, err := w.Write(b) 337 return err 338 } 339 // Other values are handled below. 340 } 341 342 // We don't attempt to serialise every possible value type; only those 343 // that can occur in protocol buffers. 344 switch v.Kind() { 345 case reflect.Slice: 346 // Should only be a []byte; repeated fields are handled in writeStruct. 347 if err := writeString(w, string(v.Interface().([]byte))); err != nil { 348 return err 349 } 350 case reflect.String: 351 if err := writeString(w, v.String()); err != nil { 352 return err 353 } 354 case reflect.Struct: 355 // Required/optional group/message. 356 var bra, ket byte = '<', '>' 357 if props != nil && props.Wire == "group" { 358 bra, ket = '{', '}' 359 } 360 if err := w.WriteByte(bra); err != nil { 361 return err 362 } 363 if !w.compact { 364 if err := w.WriteByte('\n'); err != nil { 365 return err 366 } 367 } 368 w.indent() 369 if err := writeStruct(w, v); err != nil { 370 return err 371 } 372 w.unindent() 373 if err := w.WriteByte(ket); err != nil { 374 return err 375 } 376 default: 377 _, err := fmt.Fprint(w, v.Interface()) 378 return err 379 } 380 return nil 381 } 382 383 // equivalent to C's isprint. 384 func isprint(c byte) bool { 385 return c >= 0x20 && c < 0x7f 386 } 387 388 // writeString writes a string in the protocol buffer text format. 389 // It is similar to strconv.Quote except we don't use Go escape sequences, 390 // we treat the string as a byte sequence, and we use octal escapes. 391 // These differences are to maintain interoperability with the other 392 // languages' implementations of the text format. 393 func writeString(w *textWriter, s string) error { 394 // use WriteByte here to get any needed indent 395 if err := w.WriteByte('"'); err != nil { 396 return err 397 } 398 // Loop over the bytes, not the runes. 399 for i := 0; i < len(s); i++ { 400 var err error 401 // Divergence from C++: we don't escape apostrophes. 402 // There's no need to escape them, and the C++ parser 403 // copes with a naked apostrophe. 404 switch c := s[i]; c { 405 case '\n': 406 _, err = w.w.Write(backslashN) 407 case '\r': 408 _, err = w.w.Write(backslashR) 409 case '\t': 410 _, err = w.w.Write(backslashT) 411 case '"': 412 _, err = w.w.Write(backslashDQ) 413 case '\\': 414 _, err = w.w.Write(backslashBS) 415 default: 416 if isprint(c) { 417 err = w.w.WriteByte(c) 418 } else { 419 _, err = fmt.Fprintf(w.w, "\\%03o", c) 420 } 421 } 422 if err != nil { 423 return err 424 } 425 } 426 return w.WriteByte('"') 427 } 428 429 func writeMessageSet(w *textWriter, ms *MessageSet) error { 430 for _, item := range ms.Item { 431 id := *item.TypeId 432 if msd, ok := messageSetMap[id]; ok { 433 // Known message set type. 434 if _, err := fmt.Fprintf(w, "[%s]: <\n", msd.name); err != nil { 435 return err 436 } 437 w.indent() 438 439 pb := reflect.New(msd.t.Elem()) 440 if err := Unmarshal(item.Message, pb.Interface().(Message)); err != nil { 441 if _, err := fmt.Fprintf(w, "/* bad message: %v */\n", err); err != nil { 442 return err 443 } 444 } else { 445 if err := writeStruct(w, pb.Elem()); err != nil { 446 return err 447 } 448 } 449 } else { 450 // Unknown type. 451 if _, err := fmt.Fprintf(w, "[%d]: <\n", id); err != nil { 452 return err 453 } 454 w.indent() 455 if err := writeUnknownStruct(w, item.Message); err != nil { 456 return err 457 } 458 } 459 w.unindent() 460 if _, err := w.Write(gtNewline); err != nil { 461 return err 462 } 463 } 464 return nil 465 } 466 467 func writeUnknownStruct(w *textWriter, data []byte) (err error) { 468 if !w.compact { 469 if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil { 470 return err 471 } 472 } 473 b := NewBuffer(data) 474 for b.index < len(b.buf) { 475 x, err := b.DecodeVarint() 476 if err != nil { 477 _, err := fmt.Fprintf(w, "/* %v */\n", err) 478 return err 479 } 480 wire, tag := x&7, x>>3 481 if wire == WireEndGroup { 482 w.unindent() 483 if _, err := w.Write(endBraceNewline); err != nil { 484 return err 485 } 486 continue 487 } 488 if _, err := fmt.Fprint(w, tag); err != nil { 489 return err 490 } 491 if wire != WireStartGroup { 492 if err := w.WriteByte(':'); err != nil { 493 return err 494 } 495 } 496 if !w.compact || wire == WireStartGroup { 497 if err := w.WriteByte(' '); err != nil { 498 return err 499 } 500 } 501 switch wire { 502 case WireBytes: 503 buf, e := b.DecodeRawBytes(false) 504 if e == nil { 505 _, err = fmt.Fprintf(w, "%q", buf) 506 } else { 507 _, err = fmt.Fprintf(w, "/* %v */", e) 508 } 509 case WireFixed32: 510 x, err = b.DecodeFixed32() 511 err = writeUnknownInt(w, x, err) 512 case WireFixed64: 513 x, err = b.DecodeFixed64() 514 err = writeUnknownInt(w, x, err) 515 case WireStartGroup: 516 err = w.WriteByte('{') 517 w.indent() 518 case WireVarint: 519 x, err = b.DecodeVarint() 520 err = writeUnknownInt(w, x, err) 521 default: 522 _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire) 523 } 524 if err != nil { 525 return err 526 } 527 if err = w.WriteByte('\n'); err != nil { 528 return err 529 } 530 } 531 return nil 532 } 533 534 func writeUnknownInt(w *textWriter, x uint64, err error) error { 535 if err == nil { 536 _, err = fmt.Fprint(w, x) 537 } else { 538 _, err = fmt.Fprintf(w, "/* %v */", err) 539 } 540 return err 541 } 542 543 type int32Slice []int32 544 545 func (s int32Slice) Len() int { return len(s) } 546 func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } 547 func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 548 549 // writeExtensions writes all the extensions in pv. 550 // pv is assumed to be a pointer to a protocol message struct that is extendable. 551 func writeExtensions(w *textWriter, pv reflect.Value) error { 552 emap := extensionMaps[pv.Type().Elem()] 553 ep := pv.Interface().(extendableProto) 554 555 // Order the extensions by ID. 556 // This isn't strictly necessary, but it will give us 557 // canonical output, which will also make testing easier. 558 m := ep.ExtensionMap() 559 ids := make([]int32, 0, len(m)) 560 for id := range m { 561 ids = append(ids, id) 562 } 563 sort.Sort(int32Slice(ids)) 564 565 for _, extNum := range ids { 566 ext := m[extNum] 567 var desc *ExtensionDesc 568 if emap != nil { 569 desc = emap[extNum] 570 } 571 if desc == nil { 572 // Unknown extension. 573 if err := writeUnknownStruct(w, ext.enc); err != nil { 574 return err 575 } 576 continue 577 } 578 579 pb, err := GetExtension(ep, desc) 580 if err != nil { 581 if _, err := fmt.Fprintln(os.Stderr, "proto: failed getting extension: ", err); err != nil { 582 return err 583 } 584 continue 585 } 586 587 // Repeated extensions will appear as a slice. 588 if !desc.repeated() { 589 if err := writeExtension(w, desc.Name, pb); err != nil { 590 return err 591 } 592 } else { 593 v := reflect.ValueOf(pb) 594 for i := 0; i < v.Len(); i++ { 595 if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { 596 return err 597 } 598 } 599 } 600 } 601 return nil 602 } 603 604 func writeExtension(w *textWriter, name string, pb interface{}) error { 605 if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil { 606 return err 607 } 608 if !w.compact { 609 if err := w.WriteByte(' '); err != nil { 610 return err 611 } 612 } 613 if err := writeAny(w, reflect.ValueOf(pb), nil); err != nil { 614 return err 615 } 616 if err := w.WriteByte('\n'); err != nil { 617 return err 618 } 619 return nil 620 } 621 622 func (w *textWriter) writeIndent() { 623 if !w.complete { 624 return 625 } 626 remain := w.ind * 2 627 for remain > 0 { 628 n := remain 629 if n > len(spaces) { 630 n = len(spaces) 631 } 632 w.w.Write(spaces[:n]) 633 remain -= n 634 } 635 w.complete = false 636 } 637 638 func marshalText(w io.Writer, pb Message, compact bool) error { 639 val := reflect.ValueOf(pb) 640 if pb == nil || val.IsNil() { 641 w.Write([]byte("<nil>")) 642 return nil 643 } 644 var bw *bufio.Writer 645 ww, ok := w.(writer) 646 if !ok { 647 bw = bufio.NewWriter(w) 648 ww = bw 649 } 650 aw := &textWriter{ 651 w: ww, 652 complete: true, 653 compact: compact, 654 } 655 656 // Dereference the received pointer so we don't have outer < and >. 657 v := reflect.Indirect(val) 658 if err := writeStruct(aw, v); err != nil { 659 return err 660 } 661 if bw != nil { 662 return bw.Flush() 663 } 664 return nil 665 } 666 667 // MarshalText writes a given protocol buffer in text format. 668 // The only errors returned are from w. 669 func MarshalText(w io.Writer, pb Message) error { return marshalText(w, pb, false) } 670 671 // MarshalTextString is the same as MarshalText, but returns the string directly. 672 func MarshalTextString(pb Message) string { 673 var buf bytes.Buffer 674 marshalText(&buf, pb, false) 675 return buf.String() 676 } 677 678 // CompactText writes a given protocol buffer in compact text format (one line). 679 func CompactText(w io.Writer, pb Message) error { return marshalText(w, pb, true) } 680 681 // CompactTextString is the same as CompactText, but returns the string directly. 682 func CompactTextString(pb Message) string { 683 var buf bytes.Buffer 684 marshalText(&buf, pb, true) 685 return buf.String() 686 }