1 // Go support for Protocol Buffers - Google's data interchange format
3 // Copyright 2010 The Go Authors. All rights reserved.
4 // https://github.com/golang/protobuf
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
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
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.
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.
34 // Functions for writing the text protocol buffer format.
51 newline = []byte("\n")
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")
65 type writer interface {
70 // textWriter is an io.Writer that tracks its indentation level.
71 type textWriter struct {
73 complete bool // if the current position is a complete line
74 compact bool // whether to write out as a one-liner
78 func (w *textWriter) WriteString(s string) (n int, err error) {
79 if !strings.Contains(s, "\n") {
80 if !w.compact && w.complete {
84 return io.WriteString(w.w, s)
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))
92 func (w *textWriter) Write(p []byte) (n int, err error) {
93 newlines := bytes.Count(p, newline)
95 if !w.compact && w.complete {
103 frags := bytes.SplitN(p, newline, newlines+1)
105 for i, frag := range frags {
107 if err := w.w.WriteByte(' '); err != nil {
112 nn, err := w.w.Write(frag)
121 for i, frag := range frags {
125 nn, err := w.w.Write(frag)
130 if i+1 < len(frags) {
131 if err := w.w.WriteByte('\n'); err != nil {
137 w.complete = len(frags[len(frags)-1]) == 0
141 func (w *textWriter) WriteByte(c byte) error {
142 if w.compact && c == '\n' {
145 if !w.compact && w.complete {
148 err := w.w.WriteByte(c)
149 w.complete = c == '\n'
153 func (w *textWriter) indent() { w.ind++ }
155 func (w *textWriter) unindent() {
157 log.Print("proto: textWriter unindented too far")
163 func writeName(w *textWriter, props *Properties) error {
164 if _, err := w.WriteString(props.OrigName); err != nil {
167 if props.Wire != "group" {
168 return w.WriteByte(':')
173 // raw is the interface satisfied by RawMessage.
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 {
182 case ch == '.' || ch == '/' || ch == '_':
184 case '0' <= ch && ch <= '9':
186 case 'A' <= ch && ch <= 'Z':
188 case 'a' <= ch && ch <= 'z':
197 // isAny reports whether sv is a google.protobuf.Any message
198 func isAny(sv reflect.Value) bool {
200 XXX_WellKnownType() string
202 t, ok := sv.Addr().Interface().(wkt)
203 return ok && t.XXX_WellKnownType() == "Any"
206 // writeProto3Any writes an expanded google.protobuf.Any message.
208 // It returns (false, nil) if sv value can't be unmarshaled (e.g. because
209 // required messages are not linked in).
211 // It returns (true, error) when sv was written in expanded format or an error
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")
220 b, ok := val.Interface().([]byte)
222 return true, errors.New("proto: invalid google.protobuf.Any message")
225 parts := strings.Split(turl.String(), "/")
226 mt := MessageType(parts[len(parts)-1])
230 m := reflect.New(mt.Elem())
231 if err := Unmarshal(b, m.Interface().(Message)); err != nil {
236 if requiresQuotes(u) {
242 w.Write([]byte("]:<"))
244 w.Write([]byte("]: <\n"))
247 if err := tm.writeStruct(w, m.Elem()); err != nil {
251 w.Write([]byte("> "))
254 w.Write([]byte(">\n"))
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 {
266 sprops := GetProperties(st)
267 for i := 0; i < sv.NumField(); i++ {
269 props := sprops.Prop[i]
270 name := st.Field(i).Name
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 {
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.
291 if fv.Kind() == reflect.Slice && fv.IsNil() {
292 // Repeated field that is empty, or a bytes field that is unused.
296 if props.Repeated && fv.Kind() == reflect.Slice {
298 for j := 0; j < fv.Len(); j++ {
299 if err := writeName(w, props); err != nil {
303 if err := w.WriteByte(' '); err != nil {
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 {
316 if err := tm.writeAny(w, v, props); err != nil {
319 if err := w.WriteByte('\n'); err != nil {
325 if fv.Kind() == reflect.Map {
326 // Map fields are rendered as a repeated struct with key/value fields.
328 sort.Sort(mapKeys(keys))
329 for _, key := range keys {
330 val := fv.MapIndex(key)
331 if err := writeName(w, props); err != nil {
335 if err := w.WriteByte(' '); err != nil {
340 if err := w.WriteByte('<'); err != nil {
344 if err := w.WriteByte('\n'); err != nil {
350 if _, err := w.WriteString("key:"); err != nil {
354 if err := w.WriteByte(' '); err != nil {
358 if err := tm.writeAny(w, key, props.mkeyprop); err != nil {
361 if err := w.WriteByte('\n'); err != nil {
364 // nil values aren't legal, but we can avoid panicking because of them.
365 if val.Kind() != reflect.Ptr || !val.IsNil() {
367 if _, err := w.WriteString("value:"); err != nil {
371 if err := w.WriteByte(' '); err != nil {
375 if err := tm.writeAny(w, val, props.mvalprop); err != nil {
378 if err := w.WriteByte('\n'); err != nil {
384 if err := w.WriteByte('>'); err != nil {
387 if err := w.WriteByte('\n'); err != nil {
393 if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {
397 if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
398 // proto3 non-repeated scalar field; skip if zero value
399 if isProto3Zero(fv) {
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.
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.
417 // Write the value in the oneof, not the oneof itself.
420 // Special case to cope with malformed messages gracefully:
421 // If the value in the oneof is a nil pointer, don't panic
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()
431 if err := writeName(w, props); err != nil {
435 if err := w.WriteByte(' '); err != nil {
439 if b, ok := fv.Interface().(raw); ok {
440 if err := writeRaw(w, b.Bytes()); err != nil {
446 // Enums have a String method, so writeAny will work fine.
447 if err := tm.writeAny(w, fv, props); err != nil {
451 if err := w.WriteByte('\n'); err != nil {
456 // Extensions (the XXX_extensions field).
458 if _, ok := extendable(pv.Interface()); ok {
459 if err := tm.writeExtensions(w, pv); err != nil {
467 // writeRaw writes an uninterpreted raw message.
468 func writeRaw(w *textWriter, b []byte) error {
469 if err := w.WriteByte('<'); err != nil {
473 if err := w.WriteByte('\n'); err != nil {
478 if err := writeUnknownStruct(w, b); err != nil {
482 if err := w.WriteByte('>'); err != nil {
488 // writeAny writes an arbitrary field.
489 func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
490 v = reflect.Indirect(v)
492 // Floats have special cases.
493 if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
497 case math.IsInf(x, 1):
499 case math.IsInf(x, -1):
508 // Other values are handled below.
511 // We don't attempt to serialise every possible value type; only those
512 // that can occur in protocol buffers.
515 // Should only be a []byte; repeated fields are handled in writeStruct.
516 if err := writeString(w, string(v.Bytes())); err != nil {
520 if err := writeString(w, v.String()); err != nil {
524 // Required/optional group/message.
525 var bra, ket byte = '<', '>'
526 if props != nil && props.Wire == "group" {
529 if err := w.WriteByte(bra); err != nil {
533 if err := w.WriteByte('\n'); err != nil {
538 if etm, ok := v.Interface().(encoding.TextMarshaler); ok {
539 text, err := etm.MarshalText()
543 if _, err = w.Write(text); err != nil {
546 } else if err := tm.writeStruct(w, v); err != nil {
550 if err := w.WriteByte(ket); err != nil {
554 _, err := fmt.Fprint(w, v.Interface())
560 // equivalent to C's isprint.
561 func isprint(c byte) bool {
562 return c >= 0x20 && c < 0x7f
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 {
575 // Loop over the bytes, not the runes.
576 for i := 0; i < len(s); i++ {
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 {
583 _, err = w.w.Write(backslashN)
585 _, err = w.w.Write(backslashR)
587 _, err = w.w.Write(backslashT)
589 _, err = w.w.Write(backslashDQ)
591 _, err = w.w.Write(backslashBS)
594 err = w.w.WriteByte(c)
596 _, err = fmt.Fprintf(w.w, "\\%03o", c)
603 return w.WriteByte('"')
606 func writeUnknownStruct(w *textWriter, data []byte) (err error) {
608 if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
613 for b.index < len(b.buf) {
614 x, err := b.DecodeVarint()
616 _, err := fmt.Fprintf(w, "/* %v */\n", err)
619 wire, tag := x&7, x>>3
620 if wire == WireEndGroup {
622 if _, err := w.Write(endBraceNewline); err != nil {
627 if _, err := fmt.Fprint(w, tag); err != nil {
630 if wire != WireStartGroup {
631 if err := w.WriteByte(':'); err != nil {
635 if !w.compact || wire == WireStartGroup {
636 if err := w.WriteByte(' '); err != nil {
642 buf, e := b.DecodeRawBytes(false)
644 _, err = fmt.Fprintf(w, "%q", buf)
646 _, err = fmt.Fprintf(w, "/* %v */", e)
649 x, err = b.DecodeFixed32()
650 err = writeUnknownInt(w, x, err)
652 x, err = b.DecodeFixed64()
653 err = writeUnknownInt(w, x, err)
655 err = w.WriteByte('{')
658 x, err = b.DecodeVarint()
659 err = writeUnknownInt(w, x, err)
661 _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire)
666 if err = w.WriteByte('\n'); err != nil {
673 func writeUnknownInt(w *textWriter, x uint64, err error) error {
675 _, err = fmt.Fprint(w, x)
677 _, err = fmt.Fprintf(w, "/* %v */", err)
682 type int32Slice []int32
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] }
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, _ := extendable(pv.Interface())
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, mu := ep.extensionsRead()
702 ids := make([]int32, 0, len(m))
704 ids = append(ids, id)
706 sort.Sort(int32Slice(ids))
709 for _, extNum := range ids {
711 var desc *ExtensionDesc
716 // Unknown extension.
717 if err := writeUnknownStruct(w, ext.enc); err != nil {
723 pb, err := GetExtension(ep, desc)
725 return fmt.Errorf("failed getting extension: %v", err)
728 // Repeated extensions will appear as a slice.
729 if !desc.repeated() {
730 if err := tm.writeExtension(w, desc.Name, pb); err != nil {
734 v := reflect.ValueOf(pb)
735 for i := 0; i < v.Len(); i++ {
736 if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
745 func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {
746 if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
750 if err := w.WriteByte(' '); err != nil {
754 if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {
757 if err := w.WriteByte('\n'); err != nil {
763 func (w *textWriter) writeIndent() {
773 w.w.Write(spaces[:n])
779 // TextMarshaler is a configurable text format marshaler.
780 type TextMarshaler struct {
781 Compact bool // use compact text format (one line).
782 ExpandAny bool // expand google.protobuf.Any messages of known types
785 // Marshal writes a given protocol buffer in text format.
786 // The only errors returned are from w.
787 func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
788 val := reflect.ValueOf(pb)
789 if pb == nil || val.IsNil() {
790 w.Write([]byte("<nil>"))
796 bw = bufio.NewWriter(w)
805 if etm, ok := pb.(encoding.TextMarshaler); ok {
806 text, err := etm.MarshalText()
810 if _, err = aw.Write(text); err != nil {
818 // Dereference the received pointer so we don't have outer < and >.
819 v := reflect.Indirect(val)
820 if err := tm.writeStruct(aw, v); err != nil {
829 // Text is the same as Marshal, but returns the string directly.
830 func (tm *TextMarshaler) Text(pb Message) string {
837 defaultTextMarshaler = TextMarshaler{}
838 compactTextMarshaler = TextMarshaler{Compact: true}
841 // TODO: consider removing some of the Marshal functions below.
843 // MarshalText writes a given protocol buffer in text format.
844 // The only errors returned are from w.
845 func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }
847 // MarshalTextString is the same as MarshalText, but returns the string directly.
848 func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }
850 // CompactText writes a given protocol buffer in compact text format (one line).
851 func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }
853 // CompactTextString is the same as CompactText, but returns the string directly.
854 func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }