github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/golang/protobuf/proto/text.go (about)

     1  // Go support for Protocol Buffers - Google's data interchange format
     2  //
     3  // Copyright 2010 The Go Authors.  All rights reserved.
     4  // https://yougam/libraries/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.Printf("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 pv.Type().Implements(extendableProtoType) {
   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.Interface().([]byte))); 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 := pv.Interface().(extendableProto)
   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 := ep.ExtensionMap()
   698  	ids := make([]int32, 0, len(m))
   699  	for id := range m {
   700  		ids = append(ids, id)
   701  	}
   702  	sort.Sort(int32Slice(ids))
   703  
   704  	for _, extNum := range ids {
   705  		ext := m[extNum]
   706  		var desc *ExtensionDesc
   707  		if emap != nil {
   708  			desc = emap[extNum]
   709  		}
   710  		if desc == nil {
   711  			// Unknown extension.
   712  			if err := writeUnknownStruct(w, ext.enc); err != nil {
   713  				return err
   714  			}
   715  			continue
   716  		}
   717  
   718  		pb, err := GetExtension(ep, desc)
   719  		if err != nil {
   720  			return fmt.Errorf("failed getting extension: %v", err)
   721  		}
   722  
   723  		// Repeated extensions will appear as a slice.
   724  		if !desc.repeated() {
   725  			if err := tm.writeExtension(w, desc.Name, pb); err != nil {
   726  				return err
   727  			}
   728  		} else {
   729  			v := reflect.ValueOf(pb)
   730  			for i := 0; i < v.Len(); i++ {
   731  				if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
   732  					return err
   733  				}
   734  			}
   735  		}
   736  	}
   737  	return nil
   738  }
   739  
   740  func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {
   741  	if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
   742  		return err
   743  	}
   744  	if !w.compact {
   745  		if err := w.WriteByte(' '); err != nil {
   746  			return err
   747  		}
   748  	}
   749  	if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {
   750  		return err
   751  	}
   752  	if err := w.WriteByte('\n'); err != nil {
   753  		return err
   754  	}
   755  	return nil
   756  }
   757  
   758  func (w *textWriter) writeIndent() {
   759  	if !w.complete {
   760  		return
   761  	}
   762  	remain := w.ind * 2
   763  	for remain > 0 {
   764  		n := remain
   765  		if n > len(spaces) {
   766  			n = len(spaces)
   767  		}
   768  		w.w.Write(spaces[:n])
   769  		remain -= n
   770  	}
   771  	w.complete = false
   772  }
   773  
   774  // TextMarshaler is a configurable text format marshaler.
   775  type TextMarshaler struct {
   776  	Compact   bool // use compact text format (one line).
   777  	ExpandAny bool // expand google.protobuf.Any messages of known types
   778  }
   779  
   780  // Marshal writes a given protocol buffer in text format.
   781  // The only errors returned are from w.
   782  func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
   783  	val := reflect.ValueOf(pb)
   784  	if pb == nil || val.IsNil() {
   785  		w.Write([]byte("<nil>"))
   786  		return nil
   787  	}
   788  	var bw *bufio.Writer
   789  	ww, ok := w.(writer)
   790  	if !ok {
   791  		bw = bufio.NewWriter(w)
   792  		ww = bw
   793  	}
   794  	aw := &textWriter{
   795  		w:        ww,
   796  		complete: true,
   797  		compact:  tm.Compact,
   798  	}
   799  
   800  	if etm, ok := pb.(encoding.TextMarshaler); ok {
   801  		text, err := etm.MarshalText()
   802  		if err != nil {
   803  			return err
   804  		}
   805  		if _, err = aw.Write(text); err != nil {
   806  			return err
   807  		}
   808  		if bw != nil {
   809  			return bw.Flush()
   810  		}
   811  		return nil
   812  	}
   813  	// Dereference the received pointer so we don't have outer < and >.
   814  	v := reflect.Indirect(val)
   815  	if err := tm.writeStruct(aw, v); err != nil {
   816  		return err
   817  	}
   818  	if bw != nil {
   819  		return bw.Flush()
   820  	}
   821  	return nil
   822  }
   823  
   824  // Text is the same as Marshal, but returns the string directly.
   825  func (tm *TextMarshaler) Text(pb Message) string {
   826  	var buf bytes.Buffer
   827  	tm.Marshal(&buf, pb)
   828  	return buf.String()
   829  }
   830  
   831  var (
   832  	defaultTextMarshaler = TextMarshaler{}
   833  	compactTextMarshaler = TextMarshaler{Compact: true}
   834  )
   835  
   836  // TODO: consider removing some of the Marshal functions below.
   837  
   838  // MarshalText writes a given protocol buffer in text format.
   839  // The only errors returned are from w.
   840  func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }
   841  
   842  // MarshalTextString is the same as MarshalText, but returns the string directly.
   843  func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }
   844  
   845  // CompactText writes a given protocol buffer in compact text format (one line).
   846  func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }
   847  
   848  // CompactTextString is the same as CompactText, but returns the string directly.
   849  func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }