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