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

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