github.com/matm/etcd@v0.3.1-0.20140328024009-5b4a473f1453/third_party/code.google.com/p/goprotobuf/proto/text.go (about)

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