OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / vendor / github.com / gogo / protobuf / proto / text.go
1 // Protocol Buffers for Go with Gadgets
2 //
3 // Copyright (c) 2013, The GoGo Authors. All rights reserved.
4 // http://github.com/gogo/protobuf
5 //
6 // Go support for Protocol Buffers - Google's data interchange format
7 //
8 // Copyright 2010 The Go Authors.  All rights reserved.
9 // https://github.com/golang/protobuf
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         "encoding"
45         "errors"
46         "fmt"
47         "io"
48         "log"
49         "math"
50         "reflect"
51         "sort"
52         "strings"
53         "sync"
54         "time"
55 )
56
57 var (
58         newline         = []byte("\n")
59         spaces          = []byte("                                        ")
60         endBraceNewline = []byte("}\n")
61         backslashN      = []byte{'\\', 'n'}
62         backslashR      = []byte{'\\', 'r'}
63         backslashT      = []byte{'\\', 't'}
64         backslashDQ     = []byte{'\\', '"'}
65         backslashBS     = []byte{'\\', '\\'}
66         posInf          = []byte("inf")
67         negInf          = []byte("-inf")
68         nan             = []byte("nan")
69 )
70
71 type writer interface {
72         io.Writer
73         WriteByte(byte) error
74 }
75
76 // textWriter is an io.Writer that tracks its indentation level.
77 type textWriter struct {
78         ind      int
79         complete bool // if the current position is a complete line
80         compact  bool // whether to write out as a one-liner
81         w        writer
82 }
83
84 func (w *textWriter) WriteString(s string) (n int, err error) {
85         if !strings.Contains(s, "\n") {
86                 if !w.compact && w.complete {
87                         w.writeIndent()
88                 }
89                 w.complete = false
90                 return io.WriteString(w.w, s)
91         }
92         // WriteString is typically called without newlines, so this
93         // codepath and its copy are rare.  We copy to avoid
94         // duplicating all of Write's logic here.
95         return w.Write([]byte(s))
96 }
97
98 func (w *textWriter) Write(p []byte) (n int, err error) {
99         newlines := bytes.Count(p, newline)
100         if newlines == 0 {
101                 if !w.compact && w.complete {
102                         w.writeIndent()
103                 }
104                 n, err = w.w.Write(p)
105                 w.complete = false
106                 return n, err
107         }
108
109         frags := bytes.SplitN(p, newline, newlines+1)
110         if w.compact {
111                 for i, frag := range frags {
112                         if i > 0 {
113                                 if err := w.w.WriteByte(' '); err != nil {
114                                         return n, err
115                                 }
116                                 n++
117                         }
118                         nn, err := w.w.Write(frag)
119                         n += nn
120                         if err != nil {
121                                 return n, err
122                         }
123                 }
124                 return n, nil
125         }
126
127         for i, frag := range frags {
128                 if w.complete {
129                         w.writeIndent()
130                 }
131                 nn, err := w.w.Write(frag)
132                 n += nn
133                 if err != nil {
134                         return n, err
135                 }
136                 if i+1 < len(frags) {
137                         if err := w.w.WriteByte('\n'); err != nil {
138                                 return n, err
139                         }
140                         n++
141                 }
142         }
143         w.complete = len(frags[len(frags)-1]) == 0
144         return n, nil
145 }
146
147 func (w *textWriter) WriteByte(c byte) error {
148         if w.compact && c == '\n' {
149                 c = ' '
150         }
151         if !w.compact && w.complete {
152                 w.writeIndent()
153         }
154         err := w.w.WriteByte(c)
155         w.complete = c == '\n'
156         return err
157 }
158
159 func (w *textWriter) indent() { w.ind++ }
160
161 func (w *textWriter) unindent() {
162         if w.ind == 0 {
163                 log.Print("proto: textWriter unindented too far")
164                 return
165         }
166         w.ind--
167 }
168
169 func writeName(w *textWriter, props *Properties) error {
170         if _, err := w.WriteString(props.OrigName); err != nil {
171                 return err
172         }
173         if props.Wire != "group" {
174                 return w.WriteByte(':')
175         }
176         return nil
177 }
178
179 func requiresQuotes(u string) bool {
180         // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
181         for _, ch := range u {
182                 switch {
183                 case ch == '.' || ch == '/' || ch == '_':
184                         continue
185                 case '0' <= ch && ch <= '9':
186                         continue
187                 case 'A' <= ch && ch <= 'Z':
188                         continue
189                 case 'a' <= ch && ch <= 'z':
190                         continue
191                 default:
192                         return true
193                 }
194         }
195         return false
196 }
197
198 // isAny reports whether sv is a google.protobuf.Any message
199 func isAny(sv reflect.Value) bool {
200         type wkt interface {
201                 XXX_WellKnownType() string
202         }
203         t, ok := sv.Addr().Interface().(wkt)
204         return ok && t.XXX_WellKnownType() == "Any"
205 }
206
207 // writeProto3Any writes an expanded google.protobuf.Any message.
208 //
209 // It returns (false, nil) if sv value can't be unmarshaled (e.g. because
210 // required messages are not linked in).
211 //
212 // It returns (true, error) when sv was written in expanded format or an error
213 // was encountered.
214 func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) {
215         turl := sv.FieldByName("TypeUrl")
216         val := sv.FieldByName("Value")
217         if !turl.IsValid() || !val.IsValid() {
218                 return true, errors.New("proto: invalid google.protobuf.Any message")
219         }
220
221         b, ok := val.Interface().([]byte)
222         if !ok {
223                 return true, errors.New("proto: invalid google.protobuf.Any message")
224         }
225
226         parts := strings.Split(turl.String(), "/")
227         mt := MessageType(parts[len(parts)-1])
228         if mt == nil {
229                 return false, nil
230         }
231         m := reflect.New(mt.Elem())
232         if err := Unmarshal(b, m.Interface().(Message)); err != nil {
233                 return false, nil
234         }
235         w.Write([]byte("["))
236         u := turl.String()
237         if requiresQuotes(u) {
238                 writeString(w, u)
239         } else {
240                 w.Write([]byte(u))
241         }
242         if w.compact {
243                 w.Write([]byte("]:<"))
244         } else {
245                 w.Write([]byte("]: <\n"))
246                 w.ind++
247         }
248         if err := tm.writeStruct(w, m.Elem()); err != nil {
249                 return true, err
250         }
251         if w.compact {
252                 w.Write([]byte("> "))
253         } else {
254                 w.ind--
255                 w.Write([]byte(">\n"))
256         }
257         return true, nil
258 }
259
260 func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
261         if tm.ExpandAny && isAny(sv) {
262                 if canExpand, err := tm.writeProto3Any(w, sv); canExpand {
263                         return err
264                 }
265         }
266         st := sv.Type()
267         sprops := GetProperties(st)
268         for i := 0; i < sv.NumField(); i++ {
269                 fv := sv.Field(i)
270                 props := sprops.Prop[i]
271                 name := st.Field(i).Name
272
273                 if name == "XXX_NoUnkeyedLiteral" {
274                         continue
275                 }
276
277                 if strings.HasPrefix(name, "XXX_") {
278                         // There are two XXX_ fields:
279                         //   XXX_unrecognized []byte
280                         //   XXX_extensions   map[int32]proto.Extension
281                         // The first is handled here;
282                         // the second is handled at the bottom of this function.
283                         if name == "XXX_unrecognized" && !fv.IsNil() {
284                                 if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil {
285                                         return err
286                                 }
287                         }
288                         continue
289                 }
290                 if fv.Kind() == reflect.Ptr && fv.IsNil() {
291                         // Field not filled in. This could be an optional field or
292                         // a required field that wasn't filled in. Either way, there
293                         // isn't anything we can show for it.
294                         continue
295                 }
296                 if fv.Kind() == reflect.Slice && fv.IsNil() {
297                         // Repeated field that is empty, or a bytes field that is unused.
298                         continue
299                 }
300
301                 if props.Repeated && fv.Kind() == reflect.Slice {
302                         // Repeated field.
303                         for j := 0; j < fv.Len(); j++ {
304                                 if err := writeName(w, props); err != nil {
305                                         return err
306                                 }
307                                 if !w.compact {
308                                         if err := w.WriteByte(' '); err != nil {
309                                                 return err
310                                         }
311                                 }
312                                 v := fv.Index(j)
313                                 if v.Kind() == reflect.Ptr && v.IsNil() {
314                                         // A nil message in a repeated field is not valid,
315                                         // but we can handle that more gracefully than panicking.
316                                         if _, err := w.Write([]byte("<nil>\n")); err != nil {
317                                                 return err
318                                         }
319                                         continue
320                                 }
321                                 if len(props.Enum) > 0 {
322                                         if err := tm.writeEnum(w, v, props); err != nil {
323                                                 return err
324                                         }
325                                 } else if err := tm.writeAny(w, v, props); err != nil {
326                                         return err
327                                 }
328                                 if err := w.WriteByte('\n'); err != nil {
329                                         return err
330                                 }
331                         }
332                         continue
333                 }
334                 if fv.Kind() == reflect.Map {
335                         // Map fields are rendered as a repeated struct with key/value fields.
336                         keys := fv.MapKeys()
337                         sort.Sort(mapKeys(keys))
338                         for _, key := range keys {
339                                 val := fv.MapIndex(key)
340                                 if err := writeName(w, props); err != nil {
341                                         return err
342                                 }
343                                 if !w.compact {
344                                         if err := w.WriteByte(' '); err != nil {
345                                                 return err
346                                         }
347                                 }
348                                 // open struct
349                                 if err := w.WriteByte('<'); err != nil {
350                                         return err
351                                 }
352                                 if !w.compact {
353                                         if err := w.WriteByte('\n'); err != nil {
354                                                 return err
355                                         }
356                                 }
357                                 w.indent()
358                                 // key
359                                 if _, err := w.WriteString("key:"); err != nil {
360                                         return err
361                                 }
362                                 if !w.compact {
363                                         if err := w.WriteByte(' '); err != nil {
364                                                 return err
365                                         }
366                                 }
367                                 if err := tm.writeAny(w, key, props.MapKeyProp); err != nil {
368                                         return err
369                                 }
370                                 if err := w.WriteByte('\n'); err != nil {
371                                         return err
372                                 }
373                                 // nil values aren't legal, but we can avoid panicking because of them.
374                                 if val.Kind() != reflect.Ptr || !val.IsNil() {
375                                         // value
376                                         if _, err := w.WriteString("value:"); err != nil {
377                                                 return err
378                                         }
379                                         if !w.compact {
380                                                 if err := w.WriteByte(' '); err != nil {
381                                                         return err
382                                                 }
383                                         }
384                                         if err := tm.writeAny(w, val, props.MapValProp); err != nil {
385                                                 return err
386                                         }
387                                         if err := w.WriteByte('\n'); err != nil {
388                                                 return err
389                                         }
390                                 }
391                                 // close struct
392                                 w.unindent()
393                                 if err := w.WriteByte('>'); err != nil {
394                                         return err
395                                 }
396                                 if err := w.WriteByte('\n'); err != nil {
397                                         return err
398                                 }
399                         }
400                         continue
401                 }
402                 if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {
403                         // empty bytes field
404                         continue
405                 }
406                 if props.proto3 && fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
407                         // proto3 non-repeated scalar field; skip if zero value
408                         if isProto3Zero(fv) {
409                                 continue
410                         }
411                 }
412
413                 if fv.Kind() == reflect.Interface {
414                         // Check if it is a oneof.
415                         if st.Field(i).Tag.Get("protobuf_oneof") != "" {
416                                 // fv is nil, or holds a pointer to generated struct.
417                                 // That generated struct has exactly one field,
418                                 // which has a protobuf struct tag.
419                                 if fv.IsNil() {
420                                         continue
421                                 }
422                                 inner := fv.Elem().Elem() // interface -> *T -> T
423                                 tag := inner.Type().Field(0).Tag.Get("protobuf")
424                                 props = new(Properties) // Overwrite the outer props var, but not its pointee.
425                                 props.Parse(tag)
426                                 // Write the value in the oneof, not the oneof itself.
427                                 fv = inner.Field(0)
428
429                                 // Special case to cope with malformed messages gracefully:
430                                 // If the value in the oneof is a nil pointer, don't panic
431                                 // in writeAny.
432                                 if fv.Kind() == reflect.Ptr && fv.IsNil() {
433                                         // Use errors.New so writeAny won't render quotes.
434                                         msg := errors.New("/* nil */")
435                                         fv = reflect.ValueOf(&msg).Elem()
436                                 }
437                         }
438                 }
439
440                 if err := writeName(w, props); err != nil {
441                         return err
442                 }
443                 if !w.compact {
444                         if err := w.WriteByte(' '); err != nil {
445                                 return err
446                         }
447                 }
448
449                 if len(props.Enum) > 0 {
450                         if err := tm.writeEnum(w, fv, props); err != nil {
451                                 return err
452                         }
453                 } else if err := tm.writeAny(w, fv, props); err != nil {
454                         return err
455                 }
456
457                 if err := w.WriteByte('\n'); err != nil {
458                         return err
459                 }
460         }
461
462         // Extensions (the XXX_extensions field).
463         pv := sv
464         if pv.CanAddr() {
465                 pv = sv.Addr()
466         } else {
467                 pv = reflect.New(sv.Type())
468                 pv.Elem().Set(sv)
469         }
470         if _, err := extendable(pv.Interface()); err == nil {
471                 if err := tm.writeExtensions(w, pv); err != nil {
472                         return err
473                 }
474         }
475
476         return nil
477 }
478
479 // writeAny writes an arbitrary field.
480 func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
481         v = reflect.Indirect(v)
482
483         if props != nil {
484                 if len(props.CustomType) > 0 {
485                         custom, ok := v.Interface().(Marshaler)
486                         if ok {
487                                 data, err := custom.Marshal()
488                                 if err != nil {
489                                         return err
490                                 }
491                                 if err := writeString(w, string(data)); err != nil {
492                                         return err
493                                 }
494                                 return nil
495                         }
496                 } else if len(props.CastType) > 0 {
497                         if _, ok := v.Interface().(interface {
498                                 String() string
499                         }); ok {
500                                 switch v.Kind() {
501                                 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
502                                         reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
503                                         _, err := fmt.Fprintf(w, "%d", v.Interface())
504                                         return err
505                                 }
506                         }
507                 } else if props.StdTime {
508                         t, ok := v.Interface().(time.Time)
509                         if !ok {
510                                 return fmt.Errorf("stdtime is not time.Time, but %T", v.Interface())
511                         }
512                         tproto, err := timestampProto(t)
513                         if err != nil {
514                                 return err
515                         }
516                         propsCopy := *props // Make a copy so that this is goroutine-safe
517                         propsCopy.StdTime = false
518                         err = tm.writeAny(w, reflect.ValueOf(tproto), &propsCopy)
519                         return err
520                 } else if props.StdDuration {
521                         d, ok := v.Interface().(time.Duration)
522                         if !ok {
523                                 return fmt.Errorf("stdtime is not time.Duration, but %T", v.Interface())
524                         }
525                         dproto := durationProto(d)
526                         propsCopy := *props // Make a copy so that this is goroutine-safe
527                         propsCopy.StdDuration = false
528                         err := tm.writeAny(w, reflect.ValueOf(dproto), &propsCopy)
529                         return err
530                 }
531         }
532
533         // Floats have special cases.
534         if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
535                 x := v.Float()
536                 var b []byte
537                 switch {
538                 case math.IsInf(x, 1):
539                         b = posInf
540                 case math.IsInf(x, -1):
541                         b = negInf
542                 case math.IsNaN(x):
543                         b = nan
544                 }
545                 if b != nil {
546                         _, err := w.Write(b)
547                         return err
548                 }
549                 // Other values are handled below.
550         }
551
552         // We don't attempt to serialise every possible value type; only those
553         // that can occur in protocol buffers.
554         switch v.Kind() {
555         case reflect.Slice:
556                 // Should only be a []byte; repeated fields are handled in writeStruct.
557                 if err := writeString(w, string(v.Bytes())); err != nil {
558                         return err
559                 }
560         case reflect.String:
561                 if err := writeString(w, v.String()); err != nil {
562                         return err
563                 }
564         case reflect.Struct:
565                 // Required/optional group/message.
566                 var bra, ket byte = '<', '>'
567                 if props != nil && props.Wire == "group" {
568                         bra, ket = '{', '}'
569                 }
570                 if err := w.WriteByte(bra); err != nil {
571                         return err
572                 }
573                 if !w.compact {
574                         if err := w.WriteByte('\n'); err != nil {
575                                 return err
576                         }
577                 }
578                 w.indent()
579                 if v.CanAddr() {
580                         // Calling v.Interface on a struct causes the reflect package to
581                         // copy the entire struct. This is racy with the new Marshaler
582                         // since we atomically update the XXX_sizecache.
583                         //
584                         // Thus, we retrieve a pointer to the struct if possible to avoid
585                         // a race since v.Interface on the pointer doesn't copy the struct.
586                         //
587                         // If v is not addressable, then we are not worried about a race
588                         // since it implies that the binary Marshaler cannot possibly be
589                         // mutating this value.
590                         v = v.Addr()
591                 }
592                 if etm, ok := v.Interface().(encoding.TextMarshaler); ok {
593                         text, err := etm.MarshalText()
594                         if err != nil {
595                                 return err
596                         }
597                         if _, err = w.Write(text); err != nil {
598                                 return err
599                         }
600                 } else {
601                         if v.Kind() == reflect.Ptr {
602                                 v = v.Elem()
603                         }
604                         if err := tm.writeStruct(w, v); err != nil {
605                                 return err
606                         }
607                 }
608                 w.unindent()
609                 if err := w.WriteByte(ket); err != nil {
610                         return err
611                 }
612         default:
613                 _, err := fmt.Fprint(w, v.Interface())
614                 return err
615         }
616         return nil
617 }
618
619 // equivalent to C's isprint.
620 func isprint(c byte) bool {
621         return c >= 0x20 && c < 0x7f
622 }
623
624 // writeString writes a string in the protocol buffer text format.
625 // It is similar to strconv.Quote except we don't use Go escape sequences,
626 // we treat the string as a byte sequence, and we use octal escapes.
627 // These differences are to maintain interoperability with the other
628 // languages' implementations of the text format.
629 func writeString(w *textWriter, s string) error {
630         // use WriteByte here to get any needed indent
631         if err := w.WriteByte('"'); err != nil {
632                 return err
633         }
634         // Loop over the bytes, not the runes.
635         for i := 0; i < len(s); i++ {
636                 var err error
637                 // Divergence from C++: we don't escape apostrophes.
638                 // There's no need to escape them, and the C++ parser
639                 // copes with a naked apostrophe.
640                 switch c := s[i]; c {
641                 case '\n':
642                         _, err = w.w.Write(backslashN)
643                 case '\r':
644                         _, err = w.w.Write(backslashR)
645                 case '\t':
646                         _, err = w.w.Write(backslashT)
647                 case '"':
648                         _, err = w.w.Write(backslashDQ)
649                 case '\\':
650                         _, err = w.w.Write(backslashBS)
651                 default:
652                         if isprint(c) {
653                                 err = w.w.WriteByte(c)
654                         } else {
655                                 _, err = fmt.Fprintf(w.w, "\\%03o", c)
656                         }
657                 }
658                 if err != nil {
659                         return err
660                 }
661         }
662         return w.WriteByte('"')
663 }
664
665 func writeUnknownStruct(w *textWriter, data []byte) (err error) {
666         if !w.compact {
667                 if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
668                         return err
669                 }
670         }
671         b := NewBuffer(data)
672         for b.index < len(b.buf) {
673                 x, err := b.DecodeVarint()
674                 if err != nil {
675                         _, ferr := fmt.Fprintf(w, "/* %v */\n", err)
676                         return ferr
677                 }
678                 wire, tag := x&7, x>>3
679                 if wire == WireEndGroup {
680                         w.unindent()
681                         if _, werr := w.Write(endBraceNewline); werr != nil {
682                                 return werr
683                         }
684                         continue
685                 }
686                 if _, ferr := fmt.Fprint(w, tag); ferr != nil {
687                         return ferr
688                 }
689                 if wire != WireStartGroup {
690                         if err = w.WriteByte(':'); err != nil {
691                                 return err
692                         }
693                 }
694                 if !w.compact || wire == WireStartGroup {
695                         if err = w.WriteByte(' '); err != nil {
696                                 return err
697                         }
698                 }
699                 switch wire {
700                 case WireBytes:
701                         buf, e := b.DecodeRawBytes(false)
702                         if e == nil {
703                                 _, err = fmt.Fprintf(w, "%q", buf)
704                         } else {
705                                 _, err = fmt.Fprintf(w, "/* %v */", e)
706                         }
707                 case WireFixed32:
708                         x, err = b.DecodeFixed32()
709                         err = writeUnknownInt(w, x, err)
710                 case WireFixed64:
711                         x, err = b.DecodeFixed64()
712                         err = writeUnknownInt(w, x, err)
713                 case WireStartGroup:
714                         err = w.WriteByte('{')
715                         w.indent()
716                 case WireVarint:
717                         x, err = b.DecodeVarint()
718                         err = writeUnknownInt(w, x, err)
719                 default:
720                         _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire)
721                 }
722                 if err != nil {
723                         return err
724                 }
725                 if err := w.WriteByte('\n'); err != nil {
726                         return err
727                 }
728         }
729         return nil
730 }
731
732 func writeUnknownInt(w *textWriter, x uint64, err error) error {
733         if err == nil {
734                 _, err = fmt.Fprint(w, x)
735         } else {
736                 _, err = fmt.Fprintf(w, "/* %v */", err)
737         }
738         return err
739 }
740
741 type int32Slice []int32
742
743 func (s int32Slice) Len() int           { return len(s) }
744 func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
745 func (s int32Slice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
746
747 // writeExtensions writes all the extensions in pv.
748 // pv is assumed to be a pointer to a protocol message struct that is extendable.
749 func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {
750         emap := extensionMaps[pv.Type().Elem()]
751         e := pv.Interface().(Message)
752
753         var m map[int32]Extension
754         var mu sync.Locker
755         if em, ok := e.(extensionsBytes); ok {
756                 eb := em.GetExtensions()
757                 var err error
758                 m, err = BytesToExtensionsMap(*eb)
759                 if err != nil {
760                         return err
761                 }
762                 mu = notLocker{}
763         } else if _, ok := e.(extendableProto); ok {
764                 ep, _ := extendable(e)
765                 m, mu = ep.extensionsRead()
766                 if m == nil {
767                         return nil
768                 }
769         }
770
771         // Order the extensions by ID.
772         // This isn't strictly necessary, but it will give us
773         // canonical output, which will also make testing easier.
774
775         mu.Lock()
776         ids := make([]int32, 0, len(m))
777         for id := range m {
778                 ids = append(ids, id)
779         }
780         sort.Sort(int32Slice(ids))
781         mu.Unlock()
782
783         for _, extNum := range ids {
784                 ext := m[extNum]
785                 var desc *ExtensionDesc
786                 if emap != nil {
787                         desc = emap[extNum]
788                 }
789                 if desc == nil {
790                         // Unknown extension.
791                         if err := writeUnknownStruct(w, ext.enc); err != nil {
792                                 return err
793                         }
794                         continue
795                 }
796
797                 pb, err := GetExtension(e, desc)
798                 if err != nil {
799                         return fmt.Errorf("failed getting extension: %v", err)
800                 }
801
802                 // Repeated extensions will appear as a slice.
803                 if !desc.repeated() {
804                         if err := tm.writeExtension(w, desc.Name, pb); err != nil {
805                                 return err
806                         }
807                 } else {
808                         v := reflect.ValueOf(pb)
809                         for i := 0; i < v.Len(); i++ {
810                                 if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
811                                         return err
812                                 }
813                         }
814                 }
815         }
816         return nil
817 }
818
819 func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {
820         if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
821                 return err
822         }
823         if !w.compact {
824                 if err := w.WriteByte(' '); err != nil {
825                         return err
826                 }
827         }
828         if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {
829                 return err
830         }
831         if err := w.WriteByte('\n'); err != nil {
832                 return err
833         }
834         return nil
835 }
836
837 func (w *textWriter) writeIndent() {
838         if !w.complete {
839                 return
840         }
841         remain := w.ind * 2
842         for remain > 0 {
843                 n := remain
844                 if n > len(spaces) {
845                         n = len(spaces)
846                 }
847                 w.w.Write(spaces[:n])
848                 remain -= n
849         }
850         w.complete = false
851 }
852
853 // TextMarshaler is a configurable text format marshaler.
854 type TextMarshaler struct {
855         Compact   bool // use compact text format (one line).
856         ExpandAny bool // expand google.protobuf.Any messages of known types
857 }
858
859 // Marshal writes a given protocol buffer in text format.
860 // The only errors returned are from w.
861 func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
862         val := reflect.ValueOf(pb)
863         if pb == nil || val.IsNil() {
864                 w.Write([]byte("<nil>"))
865                 return nil
866         }
867         var bw *bufio.Writer
868         ww, ok := w.(writer)
869         if !ok {
870                 bw = bufio.NewWriter(w)
871                 ww = bw
872         }
873         aw := &textWriter{
874                 w:        ww,
875                 complete: true,
876                 compact:  tm.Compact,
877         }
878
879         if etm, ok := pb.(encoding.TextMarshaler); ok {
880                 text, err := etm.MarshalText()
881                 if err != nil {
882                         return err
883                 }
884                 if _, err = aw.Write(text); err != nil {
885                         return err
886                 }
887                 if bw != nil {
888                         return bw.Flush()
889                 }
890                 return nil
891         }
892         // Dereference the received pointer so we don't have outer < and >.
893         v := reflect.Indirect(val)
894         if err := tm.writeStruct(aw, v); err != nil {
895                 return err
896         }
897         if bw != nil {
898                 return bw.Flush()
899         }
900         return nil
901 }
902
903 // Text is the same as Marshal, but returns the string directly.
904 func (tm *TextMarshaler) Text(pb Message) string {
905         var buf bytes.Buffer
906         tm.Marshal(&buf, pb)
907         return buf.String()
908 }
909
910 var (
911         defaultTextMarshaler = TextMarshaler{}
912         compactTextMarshaler = TextMarshaler{Compact: true}
913 )
914
915 // TODO: consider removing some of the Marshal functions below.
916
917 // MarshalText writes a given protocol buffer in text format.
918 // The only errors returned are from w.
919 func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }
920
921 // MarshalTextString is the same as MarshalText, but returns the string directly.
922 func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }
923
924 // CompactText writes a given protocol buffer in compact text format (one line).
925 func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }
926
927 // CompactTextString is the same as CompactText, but returns the string directly.
928 func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }