1 // Protocol Buffers for Go with Gadgets
3 // Copyright (c) 2013, The GoGo Authors. All rights reserved.
4 // http://github.com/gogo/protobuf
6 // Go support for Protocol Buffers - Google's data interchange format
8 // Copyright 2010 The Go Authors. All rights reserved.
9 // https://github.com/golang/protobuf
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
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
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.
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.
39 // Functions for writing the text protocol buffer format.
58 newline = []byte("\n")
60 endBraceNewline = []byte("}\n")
61 backslashN = []byte{'\\', 'n'}
62 backslashR = []byte{'\\', 'r'}
63 backslashT = []byte{'\\', 't'}
64 backslashDQ = []byte{'\\', '"'}
65 backslashBS = []byte{'\\', '\\'}
66 posInf = []byte("inf")
67 negInf = []byte("-inf")
71 type writer interface {
76 // textWriter is an io.Writer that tracks its indentation level.
77 type textWriter struct {
79 complete bool // if the current position is a complete line
80 compact bool // whether to write out as a one-liner
84 func (w *textWriter) WriteString(s string) (n int, err error) {
85 if !strings.Contains(s, "\n") {
86 if !w.compact && w.complete {
90 return io.WriteString(w.w, s)
92 // WriteString is typically called without newlines, so this
93 // codepath and its copy are rare. We copy to avoid
94 // duplicating all of Write's logic here.
95 return w.Write([]byte(s))
98 func (w *textWriter) Write(p []byte) (n int, err error) {
99 newlines := bytes.Count(p, newline)
101 if !w.compact && w.complete {
104 n, err = w.w.Write(p)
109 frags := bytes.SplitN(p, newline, newlines+1)
111 for i, frag := range frags {
113 if err := w.w.WriteByte(' '); err != nil {
118 nn, err := w.w.Write(frag)
127 for i, frag := range frags {
131 nn, err := w.w.Write(frag)
136 if i+1 < len(frags) {
137 if err := w.w.WriteByte('\n'); err != nil {
143 w.complete = len(frags[len(frags)-1]) == 0
147 func (w *textWriter) WriteByte(c byte) error {
148 if w.compact && c == '\n' {
151 if !w.compact && w.complete {
154 err := w.w.WriteByte(c)
155 w.complete = c == '\n'
159 func (w *textWriter) indent() { w.ind++ }
161 func (w *textWriter) unindent() {
163 log.Print("proto: textWriter unindented too far")
169 func writeName(w *textWriter, props *Properties) error {
170 if _, err := w.WriteString(props.OrigName); err != nil {
173 if props.Wire != "group" {
174 return w.WriteByte(':')
179 func requiresQuotes(u string) bool {
180 // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
181 for _, ch := range u {
183 case ch == '.' || ch == '/' || ch == '_':
185 case '0' <= ch && ch <= '9':
187 case 'A' <= ch && ch <= 'Z':
189 case 'a' <= ch && ch <= 'z':
198 // isAny reports whether sv is a google.protobuf.Any message
199 func isAny(sv reflect.Value) bool {
201 XXX_WellKnownType() string
203 t, ok := sv.Addr().Interface().(wkt)
204 return ok && t.XXX_WellKnownType() == "Any"
207 // writeProto3Any writes an expanded google.protobuf.Any message.
209 // It returns (false, nil) if sv value can't be unmarshaled (e.g. because
210 // required messages are not linked in).
212 // It returns (true, error) when sv was written in expanded format or an error
214 func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) {
215 turl := sv.FieldByName("TypeUrl")
216 val := sv.FieldByName("Value")
217 if !turl.IsValid() || !val.IsValid() {
218 return true, errors.New("proto: invalid google.protobuf.Any message")
221 b, ok := val.Interface().([]byte)
223 return true, errors.New("proto: invalid google.protobuf.Any message")
226 parts := strings.Split(turl.String(), "/")
227 mt := MessageType(parts[len(parts)-1])
231 m := reflect.New(mt.Elem())
232 if err := Unmarshal(b, m.Interface().(Message)); err != nil {
237 if requiresQuotes(u) {
243 w.Write([]byte("]:<"))
245 w.Write([]byte("]: <\n"))
248 if err := tm.writeStruct(w, m.Elem()); err != nil {
252 w.Write([]byte("> "))
255 w.Write([]byte(">\n"))
260 func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
261 if tm.ExpandAny && isAny(sv) {
262 if canExpand, err := tm.writeProto3Any(w, sv); canExpand {
267 sprops := GetProperties(st)
268 for i := 0; i < sv.NumField(); i++ {
270 props := sprops.Prop[i]
271 name := st.Field(i).Name
273 if name == "XXX_NoUnkeyedLiteral" {
277 if strings.HasPrefix(name, "XXX_") {
278 // There are two XXX_ fields:
279 // XXX_unrecognized []byte
280 // XXX_extensions map[int32]proto.Extension
281 // The first is handled here;
282 // the second is handled at the bottom of this function.
283 if name == "XXX_unrecognized" && !fv.IsNil() {
284 if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil {
290 if fv.Kind() == reflect.Ptr && fv.IsNil() {
291 // Field not filled in. This could be an optional field or
292 // a required field that wasn't filled in. Either way, there
293 // isn't anything we can show for it.
296 if fv.Kind() == reflect.Slice && fv.IsNil() {
297 // Repeated field that is empty, or a bytes field that is unused.
301 if props.Repeated && fv.Kind() == reflect.Slice {
303 for j := 0; j < fv.Len(); j++ {
304 if err := writeName(w, props); err != nil {
308 if err := w.WriteByte(' '); err != nil {
313 if v.Kind() == reflect.Ptr && v.IsNil() {
314 // A nil message in a repeated field is not valid,
315 // but we can handle that more gracefully than panicking.
316 if _, err := w.Write([]byte("<nil>\n")); err != nil {
321 if len(props.Enum) > 0 {
322 if err := tm.writeEnum(w, v, props); err != nil {
325 } else if err := tm.writeAny(w, v, props); err != nil {
328 if err := w.WriteByte('\n'); err != nil {
334 if fv.Kind() == reflect.Map {
335 // Map fields are rendered as a repeated struct with key/value fields.
337 sort.Sort(mapKeys(keys))
338 for _, key := range keys {
339 val := fv.MapIndex(key)
340 if err := writeName(w, props); err != nil {
344 if err := w.WriteByte(' '); err != nil {
349 if err := w.WriteByte('<'); err != nil {
353 if err := w.WriteByte('\n'); err != nil {
359 if _, err := w.WriteString("key:"); err != nil {
363 if err := w.WriteByte(' '); err != nil {
367 if err := tm.writeAny(w, key, props.MapKeyProp); err != nil {
370 if err := w.WriteByte('\n'); err != nil {
373 // nil values aren't legal, but we can avoid panicking because of them.
374 if val.Kind() != reflect.Ptr || !val.IsNil() {
376 if _, err := w.WriteString("value:"); err != nil {
380 if err := w.WriteByte(' '); err != nil {
384 if err := tm.writeAny(w, val, props.MapValProp); err != nil {
387 if err := w.WriteByte('\n'); err != nil {
393 if err := w.WriteByte('>'); err != nil {
396 if err := w.WriteByte('\n'); err != nil {
402 if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {
406 if props.proto3 && fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
407 // proto3 non-repeated scalar field; skip if zero value
408 if isProto3Zero(fv) {
413 if fv.Kind() == reflect.Interface {
414 // Check if it is a oneof.
415 if st.Field(i).Tag.Get("protobuf_oneof") != "" {
416 // fv is nil, or holds a pointer to generated struct.
417 // That generated struct has exactly one field,
418 // which has a protobuf struct tag.
422 inner := fv.Elem().Elem() // interface -> *T -> T
423 tag := inner.Type().Field(0).Tag.Get("protobuf")
424 props = new(Properties) // Overwrite the outer props var, but not its pointee.
426 // Write the value in the oneof, not the oneof itself.
429 // Special case to cope with malformed messages gracefully:
430 // If the value in the oneof is a nil pointer, don't panic
432 if fv.Kind() == reflect.Ptr && fv.IsNil() {
433 // Use errors.New so writeAny won't render quotes.
434 msg := errors.New("/* nil */")
435 fv = reflect.ValueOf(&msg).Elem()
440 if err := writeName(w, props); err != nil {
444 if err := w.WriteByte(' '); err != nil {
449 if len(props.Enum) > 0 {
450 if err := tm.writeEnum(w, fv, props); err != nil {
453 } else if err := tm.writeAny(w, fv, props); err != nil {
457 if err := w.WriteByte('\n'); err != nil {
462 // Extensions (the XXX_extensions field).
467 pv = reflect.New(sv.Type())
470 if _, err := extendable(pv.Interface()); err == nil {
471 if err := tm.writeExtensions(w, pv); err != nil {
479 // writeAny writes an arbitrary field.
480 func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
481 v = reflect.Indirect(v)
484 if len(props.CustomType) > 0 {
485 custom, ok := v.Interface().(Marshaler)
487 data, err := custom.Marshal()
491 if err := writeString(w, string(data)); err != nil {
496 } else if len(props.CastType) > 0 {
497 if _, ok := v.Interface().(interface {
501 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
502 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
503 _, err := fmt.Fprintf(w, "%d", v.Interface())
507 } else if props.StdTime {
508 t, ok := v.Interface().(time.Time)
510 return fmt.Errorf("stdtime is not time.Time, but %T", v.Interface())
512 tproto, err := timestampProto(t)
516 propsCopy := *props // Make a copy so that this is goroutine-safe
517 propsCopy.StdTime = false
518 err = tm.writeAny(w, reflect.ValueOf(tproto), &propsCopy)
520 } else if props.StdDuration {
521 d, ok := v.Interface().(time.Duration)
523 return fmt.Errorf("stdtime is not time.Duration, but %T", v.Interface())
525 dproto := durationProto(d)
526 propsCopy := *props // Make a copy so that this is goroutine-safe
527 propsCopy.StdDuration = false
528 err := tm.writeAny(w, reflect.ValueOf(dproto), &propsCopy)
533 // Floats have special cases.
534 if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
538 case math.IsInf(x, 1):
540 case math.IsInf(x, -1):
549 // Other values are handled below.
552 // We don't attempt to serialise every possible value type; only those
553 // that can occur in protocol buffers.
556 // Should only be a []byte; repeated fields are handled in writeStruct.
557 if err := writeString(w, string(v.Bytes())); err != nil {
561 if err := writeString(w, v.String()); err != nil {
565 // Required/optional group/message.
566 var bra, ket byte = '<', '>'
567 if props != nil && props.Wire == "group" {
570 if err := w.WriteByte(bra); err != nil {
574 if err := w.WriteByte('\n'); err != nil {
580 // Calling v.Interface on a struct causes the reflect package to
581 // copy the entire struct. This is racy with the new Marshaler
582 // since we atomically update the XXX_sizecache.
584 // Thus, we retrieve a pointer to the struct if possible to avoid
585 // a race since v.Interface on the pointer doesn't copy the struct.
587 // If v is not addressable, then we are not worried about a race
588 // since it implies that the binary Marshaler cannot possibly be
589 // mutating this value.
592 if etm, ok := v.Interface().(encoding.TextMarshaler); ok {
593 text, err := etm.MarshalText()
597 if _, err = w.Write(text); err != nil {
601 if v.Kind() == reflect.Ptr {
604 if err := tm.writeStruct(w, v); err != nil {
609 if err := w.WriteByte(ket); err != nil {
613 _, err := fmt.Fprint(w, v.Interface())
619 // equivalent to C's isprint.
620 func isprint(c byte) bool {
621 return c >= 0x20 && c < 0x7f
624 // writeString writes a string in the protocol buffer text format.
625 // It is similar to strconv.Quote except we don't use Go escape sequences,
626 // we treat the string as a byte sequence, and we use octal escapes.
627 // These differences are to maintain interoperability with the other
628 // languages' implementations of the text format.
629 func writeString(w *textWriter, s string) error {
630 // use WriteByte here to get any needed indent
631 if err := w.WriteByte('"'); err != nil {
634 // Loop over the bytes, not the runes.
635 for i := 0; i < len(s); i++ {
637 // Divergence from C++: we don't escape apostrophes.
638 // There's no need to escape them, and the C++ parser
639 // copes with a naked apostrophe.
640 switch c := s[i]; c {
642 _, err = w.w.Write(backslashN)
644 _, err = w.w.Write(backslashR)
646 _, err = w.w.Write(backslashT)
648 _, err = w.w.Write(backslashDQ)
650 _, err = w.w.Write(backslashBS)
653 err = w.w.WriteByte(c)
655 _, err = fmt.Fprintf(w.w, "\\%03o", c)
662 return w.WriteByte('"')
665 func writeUnknownStruct(w *textWriter, data []byte) (err error) {
667 if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
672 for b.index < len(b.buf) {
673 x, err := b.DecodeVarint()
675 _, ferr := fmt.Fprintf(w, "/* %v */\n", err)
678 wire, tag := x&7, x>>3
679 if wire == WireEndGroup {
681 if _, werr := w.Write(endBraceNewline); werr != nil {
686 if _, ferr := fmt.Fprint(w, tag); ferr != nil {
689 if wire != WireStartGroup {
690 if err = w.WriteByte(':'); err != nil {
694 if !w.compact || wire == WireStartGroup {
695 if err = w.WriteByte(' '); err != nil {
701 buf, e := b.DecodeRawBytes(false)
703 _, err = fmt.Fprintf(w, "%q", buf)
705 _, err = fmt.Fprintf(w, "/* %v */", e)
708 x, err = b.DecodeFixed32()
709 err = writeUnknownInt(w, x, err)
711 x, err = b.DecodeFixed64()
712 err = writeUnknownInt(w, x, err)
714 err = w.WriteByte('{')
717 x, err = b.DecodeVarint()
718 err = writeUnknownInt(w, x, err)
720 _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire)
725 if err := w.WriteByte('\n'); err != nil {
732 func writeUnknownInt(w *textWriter, x uint64, err error) error {
734 _, err = fmt.Fprint(w, x)
736 _, err = fmt.Fprintf(w, "/* %v */", err)
741 type int32Slice []int32
743 func (s int32Slice) Len() int { return len(s) }
744 func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
745 func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
747 // writeExtensions writes all the extensions in pv.
748 // pv is assumed to be a pointer to a protocol message struct that is extendable.
749 func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {
750 emap := extensionMaps[pv.Type().Elem()]
751 e := pv.Interface().(Message)
753 var m map[int32]Extension
755 if em, ok := e.(extensionsBytes); ok {
756 eb := em.GetExtensions()
758 m, err = BytesToExtensionsMap(*eb)
763 } else if _, ok := e.(extendableProto); ok {
764 ep, _ := extendable(e)
765 m, mu = ep.extensionsRead()
771 // Order the extensions by ID.
772 // This isn't strictly necessary, but it will give us
773 // canonical output, which will also make testing easier.
776 ids := make([]int32, 0, len(m))
778 ids = append(ids, id)
780 sort.Sort(int32Slice(ids))
783 for _, extNum := range ids {
785 var desc *ExtensionDesc
790 // Unknown extension.
791 if err := writeUnknownStruct(w, ext.enc); err != nil {
797 pb, err := GetExtension(e, desc)
799 return fmt.Errorf("failed getting extension: %v", err)
802 // Repeated extensions will appear as a slice.
803 if !desc.repeated() {
804 if err := tm.writeExtension(w, desc.Name, pb); err != nil {
808 v := reflect.ValueOf(pb)
809 for i := 0; i < v.Len(); i++ {
810 if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
819 func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {
820 if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
824 if err := w.WriteByte(' '); err != nil {
828 if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {
831 if err := w.WriteByte('\n'); err != nil {
837 func (w *textWriter) writeIndent() {
847 w.w.Write(spaces[:n])
853 // TextMarshaler is a configurable text format marshaler.
854 type TextMarshaler struct {
855 Compact bool // use compact text format (one line).
856 ExpandAny bool // expand google.protobuf.Any messages of known types
859 // Marshal writes a given protocol buffer in text format.
860 // The only errors returned are from w.
861 func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
862 val := reflect.ValueOf(pb)
863 if pb == nil || val.IsNil() {
864 w.Write([]byte("<nil>"))
870 bw = bufio.NewWriter(w)
879 if etm, ok := pb.(encoding.TextMarshaler); ok {
880 text, err := etm.MarshalText()
884 if _, err = aw.Write(text); err != nil {
892 // Dereference the received pointer so we don't have outer < and >.
893 v := reflect.Indirect(val)
894 if err := tm.writeStruct(aw, v); err != nil {
903 // Text is the same as Marshal, but returns the string directly.
904 func (tm *TextMarshaler) Text(pb Message) string {
911 defaultTextMarshaler = TextMarshaler{}
912 compactTextMarshaler = TextMarshaler{Compact: true}
915 // TODO: consider removing some of the Marshal functions below.
917 // MarshalText writes a given protocol buffer in text format.
918 // The only errors returned are from w.
919 func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }
921 // MarshalTextString is the same as MarshalText, but returns the string directly.
922 func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }
924 // CompactText writes a given protocol buffer in compact text format (one line).
925 func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }
927 // CompactTextString is the same as CompactText, but returns the string directly.
928 func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }