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