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