| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845 | // Go support for Protocol Buffers - Google's data interchange format//// Copyright 2010 The Go Authors.  All rights reserved.// https://github.com/golang/protobuf//// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:////     * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following disclaimer// in the documentation and/or other materials provided with the// distribution.//     * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived from// this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.package proto// Functions for writing the text protocol buffer format.import (	"bufio"	"bytes"	"encoding"	"errors"	"fmt"	"io"	"log"	"math"	"reflect"	"sort"	"strings")var (	newline         = []byte("\n")	spaces          = []byte("                                        ")	endBraceNewline = []byte("}\n")	backslashN      = []byte{'\\', 'n'}	backslashR      = []byte{'\\', 'r'}	backslashT      = []byte{'\\', 't'}	backslashDQ     = []byte{'\\', '"'}	backslashBS     = []byte{'\\', '\\'}	posInf          = []byte("inf")	negInf          = []byte("-inf")	nan             = []byte("nan"))type writer interface {	io.Writer	WriteByte(byte) error}// textWriter is an io.Writer that tracks its indentation level.type textWriter struct {	ind      int	complete bool // if the current position is a complete line	compact  bool // whether to write out as a one-liner	w        writer}func (w *textWriter) WriteString(s string) (n int, err error) {	if !strings.Contains(s, "\n") {		if !w.compact && w.complete {			w.writeIndent()		}		w.complete = false		return io.WriteString(w.w, s)	}	// WriteString is typically called without newlines, so this	// codepath and its copy are rare.  We copy to avoid	// duplicating all of Write's logic here.	return w.Write([]byte(s))}func (w *textWriter) Write(p []byte) (n int, err error) {	newlines := bytes.Count(p, newline)	if newlines == 0 {		if !w.compact && w.complete {			w.writeIndent()		}		n, err = w.w.Write(p)		w.complete = false		return n, err	}	frags := bytes.SplitN(p, newline, newlines+1)	if w.compact {		for i, frag := range frags {			if i > 0 {				if err := w.w.WriteByte(' '); err != nil {					return n, err				}				n++			}			nn, err := w.w.Write(frag)			n += nn			if err != nil {				return n, err			}		}		return n, nil	}	for i, frag := range frags {		if w.complete {			w.writeIndent()		}		nn, err := w.w.Write(frag)		n += nn		if err != nil {			return n, err		}		if i+1 < len(frags) {			if err := w.w.WriteByte('\n'); err != nil {				return n, err			}			n++		}	}	w.complete = len(frags[len(frags)-1]) == 0	return n, nil}func (w *textWriter) WriteByte(c byte) error {	if w.compact && c == '\n' {		c = ' '	}	if !w.compact && w.complete {		w.writeIndent()	}	err := w.w.WriteByte(c)	w.complete = c == '\n'	return err}func (w *textWriter) indent() { w.ind++ }func (w *textWriter) unindent() {	if w.ind == 0 {		log.Print("proto: textWriter unindented too far")		return	}	w.ind--}func writeName(w *textWriter, props *Properties) error {	if _, err := w.WriteString(props.OrigName); err != nil {		return err	}	if props.Wire != "group" {		return w.WriteByte(':')	}	return nil}func requiresQuotes(u string) bool {	// When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.	for _, ch := range u {		switch {		case ch == '.' || ch == '/' || ch == '_':			continue		case '0' <= ch && ch <= '9':			continue		case 'A' <= ch && ch <= 'Z':			continue		case 'a' <= ch && ch <= 'z':			continue		default:			return true		}	}	return false}// isAny reports whether sv is a google.protobuf.Any messagefunc isAny(sv reflect.Value) bool {	type wkt interface {		XXX_WellKnownType() string	}	t, ok := sv.Addr().Interface().(wkt)	return ok && t.XXX_WellKnownType() == "Any"}// writeProto3Any writes an expanded google.protobuf.Any message.//// It returns (false, nil) if sv value can't be unmarshaled (e.g. because// required messages are not linked in).//// It returns (true, error) when sv was written in expanded format or an error// was encountered.func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) {	turl := sv.FieldByName("TypeUrl")	val := sv.FieldByName("Value")	if !turl.IsValid() || !val.IsValid() {		return true, errors.New("proto: invalid google.protobuf.Any message")	}	b, ok := val.Interface().([]byte)	if !ok {		return true, errors.New("proto: invalid google.protobuf.Any message")	}	parts := strings.Split(turl.String(), "/")	mt := MessageType(parts[len(parts)-1])	if mt == nil {		return false, nil	}	m := reflect.New(mt.Elem())	if err := Unmarshal(b, m.Interface().(Message)); err != nil {		return false, nil	}	w.Write([]byte("["))	u := turl.String()	if requiresQuotes(u) {		writeString(w, u)	} else {		w.Write([]byte(u))	}	if w.compact {		w.Write([]byte("]:<"))	} else {		w.Write([]byte("]: <\n"))		w.ind++	}	if err := tm.writeStruct(w, m.Elem()); err != nil {		return true, err	}	if w.compact {		w.Write([]byte("> "))	} else {		w.ind--		w.Write([]byte(">\n"))	}	return true, nil}func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {	if tm.ExpandAny && isAny(sv) {		if canExpand, err := tm.writeProto3Any(w, sv); canExpand {			return err		}	}	st := sv.Type()	sprops := GetProperties(st)	for i := 0; i < sv.NumField(); i++ {		fv := sv.Field(i)		props := sprops.Prop[i]		name := st.Field(i).Name		if name == "XXX_NoUnkeyedLiteral" {			continue		}		if strings.HasPrefix(name, "XXX_") {			// There are two XXX_ fields:			//   XXX_unrecognized []byte			//   XXX_extensions   map[int32]proto.Extension			// The first is handled here;			// the second is handled at the bottom of this function.			if name == "XXX_unrecognized" && !fv.IsNil() {				if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil {					return err				}			}			continue		}		if fv.Kind() == reflect.Ptr && fv.IsNil() {			// Field not filled in. This could be an optional field or			// a required field that wasn't filled in. Either way, there			// isn't anything we can show for it.			continue		}		if fv.Kind() == reflect.Slice && fv.IsNil() {			// Repeated field that is empty, or a bytes field that is unused.			continue		}		if props.Repeated && fv.Kind() == reflect.Slice {			// Repeated field.			for j := 0; j < fv.Len(); j++ {				if err := writeName(w, props); err != nil {					return err				}				if !w.compact {					if err := w.WriteByte(' '); err != nil {						return err					}				}				v := fv.Index(j)				if v.Kind() == reflect.Ptr && v.IsNil() {					// A nil message in a repeated field is not valid,					// but we can handle that more gracefully than panicking.					if _, err := w.Write([]byte("<nil>\n")); err != nil {						return err					}					continue				}				if err := tm.writeAny(w, v, props); err != nil {					return err				}				if err := w.WriteByte('\n'); err != nil {					return err				}			}			continue		}		if fv.Kind() == reflect.Map {			// Map fields are rendered as a repeated struct with key/value fields.			keys := fv.MapKeys()			sort.Sort(mapKeys(keys))			for _, key := range keys {				val := fv.MapIndex(key)				if err := writeName(w, props); err != nil {					return err				}				if !w.compact {					if err := w.WriteByte(' '); err != nil {						return err					}				}				// open struct				if err := w.WriteByte('<'); err != nil {					return err				}				if !w.compact {					if err := w.WriteByte('\n'); err != nil {						return err					}				}				w.indent()				// key				if _, err := w.WriteString("key:"); err != nil {					return err				}				if !w.compact {					if err := w.WriteByte(' '); err != nil {						return err					}				}				if err := tm.writeAny(w, key, props.MapKeyProp); err != nil {					return err				}				if err := w.WriteByte('\n'); err != nil {					return err				}				// nil values aren't legal, but we can avoid panicking because of them.				if val.Kind() != reflect.Ptr || !val.IsNil() {					// value					if _, err := w.WriteString("value:"); err != nil {						return err					}					if !w.compact {						if err := w.WriteByte(' '); err != nil {							return err						}					}					if err := tm.writeAny(w, val, props.MapValProp); err != nil {						return err					}					if err := w.WriteByte('\n'); err != nil {						return err					}				}				// close struct				w.unindent()				if err := w.WriteByte('>'); err != nil {					return err				}				if err := w.WriteByte('\n'); err != nil {					return err				}			}			continue		}		if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {			// empty bytes field			continue		}		if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {			// proto3 non-repeated scalar field; skip if zero value			if isProto3Zero(fv) {				continue			}		}		if fv.Kind() == reflect.Interface {			// Check if it is a oneof.			if st.Field(i).Tag.Get("protobuf_oneof") != "" {				// fv is nil, or holds a pointer to generated struct.				// That generated struct has exactly one field,				// which has a protobuf struct tag.				if fv.IsNil() {					continue				}				inner := fv.Elem().Elem() // interface -> *T -> T				tag := inner.Type().Field(0).Tag.Get("protobuf")				props = new(Properties) // Overwrite the outer props var, but not its pointee.				props.Parse(tag)				// Write the value in the oneof, not the oneof itself.				fv = inner.Field(0)				// Special case to cope with malformed messages gracefully:				// If the value in the oneof is a nil pointer, don't panic				// in writeAny.				if fv.Kind() == reflect.Ptr && fv.IsNil() {					// Use errors.New so writeAny won't render quotes.					msg := errors.New("/* nil */")					fv = reflect.ValueOf(&msg).Elem()				}			}		}		if err := writeName(w, props); err != nil {			return err		}		if !w.compact {			if err := w.WriteByte(' '); err != nil {				return err			}		}		// Enums have a String method, so writeAny will work fine.		if err := tm.writeAny(w, fv, props); err != nil {			return err		}		if err := w.WriteByte('\n'); err != nil {			return err		}	}	// Extensions (the XXX_extensions field).	pv := sv.Addr()	if _, err := extendable(pv.Interface()); err == nil {		if err := tm.writeExtensions(w, pv); err != nil {			return err		}	}	return nil}var textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()// writeAny writes an arbitrary field.func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {	v = reflect.Indirect(v)	// Floats have special cases.	if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {		x := v.Float()		var b []byte		switch {		case math.IsInf(x, 1):			b = posInf		case math.IsInf(x, -1):			b = negInf		case math.IsNaN(x):			b = nan		}		if b != nil {			_, err := w.Write(b)			return err		}		// Other values are handled below.	}	// We don't attempt to serialise every possible value type; only those	// that can occur in protocol buffers.	switch v.Kind() {	case reflect.Slice:		// Should only be a []byte; repeated fields are handled in writeStruct.		if err := writeString(w, string(v.Bytes())); err != nil {			return err		}	case reflect.String:		if err := writeString(w, v.String()); err != nil {			return err		}	case reflect.Struct:		// Required/optional group/message.		var bra, ket byte = '<', '>'		if props != nil && props.Wire == "group" {			bra, ket = '{', '}'		}		if err := w.WriteByte(bra); err != nil {			return err		}		if !w.compact {			if err := w.WriteByte('\n'); err != nil {				return err			}		}		w.indent()		if v.CanAddr() {			// Calling v.Interface on a struct causes the reflect package to			// copy the entire struct. This is racy with the new Marshaler			// since we atomically update the XXX_sizecache.			//			// Thus, we retrieve a pointer to the struct if possible to avoid			// a race since v.Interface on the pointer doesn't copy the struct.			//			// If v is not addressable, then we are not worried about a race			// since it implies that the binary Marshaler cannot possibly be			// mutating this value.			v = v.Addr()		}		if v.Type().Implements(textMarshalerType) {			text, err := v.Interface().(encoding.TextMarshaler).MarshalText()			if err != nil {				return err			}			if _, err = w.Write(text); err != nil {				return err			}		} else {			if v.Kind() == reflect.Ptr {				v = v.Elem()			}			if err := tm.writeStruct(w, v); err != nil {				return err			}		}		w.unindent()		if err := w.WriteByte(ket); err != nil {			return err		}	default:		_, err := fmt.Fprint(w, v.Interface())		return err	}	return nil}// equivalent to C's isprint.func isprint(c byte) bool {	return c >= 0x20 && c < 0x7f}// writeString writes a string in the protocol buffer text format.// It is similar to strconv.Quote except we don't use Go escape sequences,// we treat the string as a byte sequence, and we use octal escapes.// These differences are to maintain interoperability with the other// languages' implementations of the text format.func writeString(w *textWriter, s string) error {	// use WriteByte here to get any needed indent	if err := w.WriteByte('"'); err != nil {		return err	}	// Loop over the bytes, not the runes.	for i := 0; i < len(s); i++ {		var err error		// Divergence from C++: we don't escape apostrophes.		// There's no need to escape them, and the C++ parser		// copes with a naked apostrophe.		switch c := s[i]; c {		case '\n':			_, err = w.w.Write(backslashN)		case '\r':			_, err = w.w.Write(backslashR)		case '\t':			_, err = w.w.Write(backslashT)		case '"':			_, err = w.w.Write(backslashDQ)		case '\\':			_, err = w.w.Write(backslashBS)		default:			if isprint(c) {				err = w.w.WriteByte(c)			} else {				_, err = fmt.Fprintf(w.w, "\\%03o", c)			}		}		if err != nil {			return err		}	}	return w.WriteByte('"')}func writeUnknownStruct(w *textWriter, data []byte) (err error) {	if !w.compact {		if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {			return err		}	}	b := NewBuffer(data)	for b.index < len(b.buf) {		x, err := b.DecodeVarint()		if err != nil {			_, err := fmt.Fprintf(w, "/* %v */\n", err)			return err		}		wire, tag := x&7, x>>3		if wire == WireEndGroup {			w.unindent()			if _, err := w.Write(endBraceNewline); err != nil {				return err			}			continue		}		if _, err := fmt.Fprint(w, tag); err != nil {			return err		}		if wire != WireStartGroup {			if err := w.WriteByte(':'); err != nil {				return err			}		}		if !w.compact || wire == WireStartGroup {			if err := w.WriteByte(' '); err != nil {				return err			}		}		switch wire {		case WireBytes:			buf, e := b.DecodeRawBytes(false)			if e == nil {				_, err = fmt.Fprintf(w, "%q", buf)			} else {				_, err = fmt.Fprintf(w, "/* %v */", e)			}		case WireFixed32:			x, err = b.DecodeFixed32()			err = writeUnknownInt(w, x, err)		case WireFixed64:			x, err = b.DecodeFixed64()			err = writeUnknownInt(w, x, err)		case WireStartGroup:			err = w.WriteByte('{')			w.indent()		case WireVarint:			x, err = b.DecodeVarint()			err = writeUnknownInt(w, x, err)		default:			_, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire)		}		if err != nil {			return err		}		if err = w.WriteByte('\n'); err != nil {			return err		}	}	return nil}func writeUnknownInt(w *textWriter, x uint64, err error) error {	if err == nil {		_, err = fmt.Fprint(w, x)	} else {		_, err = fmt.Fprintf(w, "/* %v */", err)	}	return err}type int32Slice []int32func (s int32Slice) Len() int           { return len(s) }func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }func (s int32Slice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }// writeExtensions writes all the extensions in pv.// pv is assumed to be a pointer to a protocol message struct that is extendable.func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {	emap := extensionMaps[pv.Type().Elem()]	ep, _ := extendable(pv.Interface())	// Order the extensions by ID.	// This isn't strictly necessary, but it will give us	// canonical output, which will also make testing easier.	m, mu := ep.extensionsRead()	if m == nil {		return nil	}	mu.Lock()	ids := make([]int32, 0, len(m))	for id := range m {		ids = append(ids, id)	}	sort.Sort(int32Slice(ids))	mu.Unlock()	for _, extNum := range ids {		ext := m[extNum]		var desc *ExtensionDesc		if emap != nil {			desc = emap[extNum]		}		if desc == nil {			// Unknown extension.			if err := writeUnknownStruct(w, ext.enc); err != nil {				return err			}			continue		}		pb, err := GetExtension(ep, desc)		if err != nil {			return fmt.Errorf("failed getting extension: %v", err)		}		// Repeated extensions will appear as a slice.		if !desc.repeated() {			if err := tm.writeExtension(w, desc.Name, pb); err != nil {				return err			}		} else {			v := reflect.ValueOf(pb)			for i := 0; i < v.Len(); i++ {				if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {					return err				}			}		}	}	return nil}func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {	if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {		return err	}	if !w.compact {		if err := w.WriteByte(' '); err != nil {			return err		}	}	if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {		return err	}	if err := w.WriteByte('\n'); err != nil {		return err	}	return nil}func (w *textWriter) writeIndent() {	if !w.complete {		return	}	remain := w.ind * 2	for remain > 0 {		n := remain		if n > len(spaces) {			n = len(spaces)		}		w.w.Write(spaces[:n])		remain -= n	}	w.complete = false}// TextMarshaler is a configurable text format marshaler.type TextMarshaler struct {	Compact   bool // use compact text format (one line).	ExpandAny bool // expand google.protobuf.Any messages of known types}// Marshal writes a given protocol buffer in text format.// The only errors returned are from w.func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {	val := reflect.ValueOf(pb)	if pb == nil || val.IsNil() {		w.Write([]byte("<nil>"))		return nil	}	var bw *bufio.Writer	ww, ok := w.(writer)	if !ok {		bw = bufio.NewWriter(w)		ww = bw	}	aw := &textWriter{		w:        ww,		complete: true,		compact:  tm.Compact,	}	if etm, ok := pb.(encoding.TextMarshaler); ok {		text, err := etm.MarshalText()		if err != nil {			return err		}		if _, err = aw.Write(text); err != nil {			return err		}		if bw != nil {			return bw.Flush()		}		return nil	}	// Dereference the received pointer so we don't have outer < and >.	v := reflect.Indirect(val)	if err := tm.writeStruct(aw, v); err != nil {		return err	}	if bw != nil {		return bw.Flush()	}	return nil}// Text is the same as Marshal, but returns the string directly.func (tm *TextMarshaler) Text(pb Message) string {	var buf bytes.Buffer	tm.Marshal(&buf, pb)	return buf.String()}var (	defaultTextMarshaler = TextMarshaler{}	compactTextMarshaler = TextMarshaler{Compact: true})// TODO: consider removing some of the Marshal functions below.// MarshalText writes a given protocol buffer in text format.// The only errors returned are from w.func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }// MarshalTextString is the same as MarshalText, but returns the string directly.func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }// CompactText writes a given protocol buffer in compact text format (one line).func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }// CompactTextString is the same as CompactText, but returns the string directly.func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }
 |