diff -Nru golang-goprotobuf-0.0~git20130901/debian/changelog golang-goprotobuf-0.0~git20150526/debian/changelog --- golang-goprotobuf-0.0~git20130901/debian/changelog 2013-09-19 16:06:28.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/debian/changelog 2015-08-11 22:45:07.000000000 +0000 @@ -1,3 +1,22 @@ +golang-goprotobuf (0.0~git20150526-2ubuntu1~trusty+syseleven1) trusty; urgency=medium + + * Package for PPA + + -- David Jarosch Tue, 11 Aug 2015 15:44:47 -0700 + +golang-goprotobuf (0.0~git20150526-2) unstable; urgency=medium + + * Add compatibility symlink to not break non-updated rdeps + + -- Michael Stapelberg Sat, 27 Jun 2015 12:46:45 +0200 + +golang-goprotobuf (0.0~git20150526-1) unstable; urgency=low + + * New upstream release. + * Bump Standards-Version to 3.9.6 (no changes necessary). + + -- Michael Stapelberg Sat, 13 Jun 2015 16:25:36 +0200 + golang-goprotobuf (0.0~git20130901-1) unstable; urgency=low * Initial release. Closes: #722975 diff -Nru golang-goprotobuf-0.0~git20130901/debian/control golang-goprotobuf-0.0~git20150526/debian/control --- golang-goprotobuf-0.0~git20130901/debian/control 2013-09-26 17:57:14.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/debian/control 2015-06-27 10:43:59.000000000 +0000 @@ -1,10 +1,12 @@ Source: golang-goprotobuf Section: devel Priority: extra -Maintainer: Tonnerre Lombard +Maintainer: pkg-go +Uploaders: Tonnerre Lombard , + Michael Stapelberg Build-Depends: debhelper (>= 9), dh-golang, golang-go (>= 1.0) -Standards-Version: 3.9.4 -Homepage: https://code.google.com/p/protobuf/ +Standards-Version: 3.9.6 +Homepage: https://github.com/golang/protobuf Vcs-Git: git://anonscm.debian.org/pkg-go/packages/golang-goprotobuf.git Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-go/packages/golang-goprotobuf.git;a=summary diff -Nru golang-goprotobuf-0.0~git20130901/debian/copyright golang-goprotobuf-0.0~git20150526/debian/copyright --- golang-goprotobuf-0.0~git20130901/debian/copyright 2013-10-07 22:07:51.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/debian/copyright 2015-06-27 10:43:59.000000000 +0000 @@ -1,6 +1,6 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: golang-goprotobuf -Source: https://code.google.com/p/protobuf/ +Source: https://github.com/golang/protobuf Files: * Copyright: 2008-2013, The Go Authors. diff -Nru golang-goprotobuf-0.0~git20130901/debian/golang-goprotobuf-dev.lintian-overrides golang-goprotobuf-0.0~git20150526/debian/golang-goprotobuf-dev.lintian-overrides --- golang-goprotobuf-0.0~git20130901/debian/golang-goprotobuf-dev.lintian-overrides 2013-09-25 19:52:04.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/debian/golang-goprotobuf-dev.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -# The Go compiler is currently unable to produce read-only relocations -# (it produces static binaries). -statically-linked-binary usr/bin/protoc-gen-go diff -Nru golang-goprotobuf-0.0~git20130901/debian/links golang-goprotobuf-0.0~git20150526/debian/links --- golang-goprotobuf-0.0~git20130901/debian/links 1970-01-01 00:00:00.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/debian/links 2015-06-27 10:47:14.000000000 +0000 @@ -0,0 +1 @@ +usr/share/gocode/src/github.com/golang/protobuf usr/share/gocode/src/code.google.com/p/protobuf diff -Nru golang-goprotobuf-0.0~git20130901/debian/rules golang-goprotobuf-0.0~git20150526/debian/rules --- golang-goprotobuf-0.0~git20130901/debian/rules 2013-09-22 00:07:36.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/debian/rules 2015-06-27 10:43:59.000000000 +0000 @@ -5,7 +5,7 @@ # DH_GOPKG is the upstream path which you would normally “go get”. # Using it allows us to build applications without patching locations. -export DH_GOPKG := code.google.com/p/goprotobuf +export DH_GOPKG := github.com/golang/protobuf %: dh $@ --buildsystem=golang --with=golang diff -Nru golang-goprotobuf-0.0~git20130901/.hgignore golang-goprotobuf-0.0~git20150526/.hgignore --- golang-goprotobuf-0.0~git20130901/.hgignore 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/.hgignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -syntax:glob -.DS_Store -.git -.gitignore -*.[568ao] -*.pb.go -*.ao -*.so -*.pyc -._* -.nfs.* -[568a].out -*~ -*.orig -core -_obj -_test -_testmain.go -compiler/protoc-gen-go -compiler/testdata/extension_test diff -Nru golang-goprotobuf-0.0~git20130901/lib/codereview/codereview.cfg golang-goprotobuf-0.0~git20150526/lib/codereview/codereview.cfg --- golang-goprotobuf-0.0~git20130901/lib/codereview/codereview.cfg 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/lib/codereview/codereview.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -defaultcc: golang-dev@googlegroups.com -contributors: http://go.googlecode.com/hg/CONTRIBUTORS diff -Nru golang-goprotobuf-0.0~git20130901/LICENSE golang-goprotobuf-0.0~git20150526/LICENSE --- golang-goprotobuf-0.0~git20130901/LICENSE 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/LICENSE 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ Go support for Protocol Buffers - Google's data interchange format Copyright 2010 The Go Authors. All rights reserved. -http://code.google.com/p/goprotobuf/ +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 diff -Nru golang-goprotobuf-0.0~git20130901/Makefile golang-goprotobuf-0.0~git20150526/Makefile --- golang-goprotobuf-0.0~git20130901/Makefile 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/Makefile 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ # Go support for Protocol Buffers - Google's data interchange format # # Copyright 2010 The Go Authors. All rights reserved. -# http://code.google.com/p/goprotobuf/ +# 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 diff -Nru golang-goprotobuf-0.0~git20130901/Make.protobuf golang-goprotobuf-0.0~git20150526/Make.protobuf --- golang-goprotobuf-0.0~git20130901/Make.protobuf 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/Make.protobuf 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ # Go support for Protocol Buffers - Google's data interchange format # # Copyright 2010 The Go Authors. All rights reserved. -# http://code.google.com/p/goprotobuf/ +# 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 @@ -33,7 +33,7 @@ # (Google protocol buffer descriptions). # Typical use if myproto.proto is a file in package mypackage in this directory: # -# include $(GOROOT)/src/pkg/code.google.com/p/goprotobuf/Make.protobuf +# include $(GOROOT)/src/pkg/github.com/golang/protobuf/Make.protobuf %.pb.go: %.proto protoc --go_out=. $< diff -Nru golang-goprotobuf-0.0~git20130901/proto/all_test.go golang-goprotobuf-0.0~git20150526/proto/all_test.go --- golang-goprotobuf-0.0~git20130901/proto/all_test.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/all_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -34,6 +34,7 @@ import ( "bytes" "encoding/json" + "errors" "fmt" "math" "math/rand" @@ -43,8 +44,8 @@ "testing" "time" - . "./testdata" - . "code.google.com/p/goprotobuf/proto" + . "github.com/golang/protobuf/proto" + . "github.com/golang/protobuf/proto/testdata" ) var globalO *Buffer @@ -394,6 +395,63 @@ } } +// fakeMarshaler is a simple struct implementing Marshaler and Message interfaces. +type fakeMarshaler struct { + b []byte + err error +} + +func (f fakeMarshaler) Marshal() ([]byte, error) { + return f.b, f.err +} + +func (f fakeMarshaler) String() string { + return fmt.Sprintf("Bytes: %v Error: %v", f.b, f.err) +} + +func (f fakeMarshaler) ProtoMessage() {} + +func (f fakeMarshaler) Reset() {} + +// Simple tests for proto messages that implement the Marshaler interface. +func TestMarshalerEncoding(t *testing.T) { + tests := []struct { + name string + m Message + want []byte + wantErr error + }{ + { + name: "Marshaler that fails", + m: fakeMarshaler{ + err: errors.New("some marshal err"), + b: []byte{5, 6, 7}, + }, + // Since there's an error, nothing should be written to buffer. + want: nil, + wantErr: errors.New("some marshal err"), + }, + { + name: "Marshaler that succeeds", + m: fakeMarshaler{ + b: []byte{0, 1, 2, 3, 4, 127, 255}, + }, + want: []byte{0, 1, 2, 3, 4, 127, 255}, + wantErr: nil, + }, + } + for _, test := range tests { + b := NewBuffer(nil) + err := b.Marshal(test.m) + if !reflect.DeepEqual(test.wantErr, err) { + t.Errorf("%s: got err %v wanted %v", test.name, err, test.wantErr) + } + if !reflect.DeepEqual(test.want, b.Bytes()) { + t.Errorf("%s: got bytes %v wanted %v", test.name, b.Bytes(), test.want) + } + } +} + // Simple tests for bytes func TestBytesPrimitives(t *testing.T) { o := old() @@ -431,7 +489,7 @@ err := o.Marshal(pb) if err == nil { t.Error("did not catch missing required fields") - } else if strings.Index(err.Error(), "GoTest") < 0 { + } else if strings.Index(err.Error(), "Kind") < 0 { t.Error("wrong error type:", err) } } @@ -989,6 +1047,35 @@ } } +// Check that an int32 field can be upgraded to an int64 field. +func TestNegativeInt32(t *testing.T) { + om := &OldMessage{ + Num: Int32(-1), + } + b, err := Marshal(om) + if err != nil { + t.Fatalf("Marshal of OldMessage: %v", err) + } + + // Check the size. It should be 11 bytes; + // 1 for the field/wire type, and 10 for the negative number. + if len(b) != 11 { + t.Errorf("%v marshaled as %q, wanted 11 bytes", om, b) + } + + // Unmarshal into a NewMessage. + nm := new(NewMessage) + if err := Unmarshal(b, nm); err != nil { + t.Fatalf("Unmarshal to NewMessage: %v", err) + } + want := &NewMessage{ + Num: Int64(-1), + } + if !Equal(nm, want) { + t.Errorf("nm = %v, want %v", nm, want) + } +} + // Check that we can grow an array (repeated field) to have many elements. // This test doesn't depend only on our encoding; for variety, it makes sure // we create, encode, and decode the correct contents explicitly. It's therefore @@ -1116,13 +1203,10 @@ // Now Unmarshal it to the wrong type. pb2 := initGoTestField() err := o.Unmarshal(pb2) - switch err { - case ErrWrongType: - // fine - case nil: - t.Error("expected wrong type error, got no error") - default: - t.Error("expected wrong type error, got", err) + if err == nil { + t.Error("expected error, got no error") + } else if !strings.Contains(err.Error(), "bad wiretype") { + t.Error("expected bad wiretype error, got", err) } } @@ -1168,7 +1252,8 @@ } o := old() - if err := o.Marshal(pb); err != ErrRepeatedHasNil { + err := o.Marshal(pb) + if err == nil || !strings.Contains(err.Error(), "repeated field Message has nil") { t.Fatalf("unexpected or no error when marshaling: %v", err) } } @@ -1205,7 +1290,7 @@ _, err := Marshal(pb) if err == nil { t.Error("marshal: expected error, got nil") - } else if strings.Index(err.Error(), "GoTestField") < 0 { + } else if strings.Index(err.Error(), "Label") < 0 { t.Errorf("marshal: bad error type: %v", err) } @@ -1216,7 +1301,7 @@ err = Unmarshal(buf, pb) if err == nil { t.Error("unmarshal: expected error, got nil") - } else if strings.Index(err.Error(), "GoTestField") < 0 { + } else if strings.Index(err.Error(), "{Unknown}") < 0 { t.Errorf("unmarshal: bad error type: %v", err) } } @@ -1303,10 +1388,11 @@ F_Pinf: Float32(float32(math.Inf(1))), F_Ninf: Float32(float32(math.Inf(-1))), F_Nan: Float32(1.7), + StrZero: String(""), } SetDefaults(m) if !Equal(m, expected) { - t.Errorf(" got %v\nwant %v", m, expected) + t.Errorf("SetDefaults failed\n got %v\nwant %v", m, expected) } } @@ -1356,6 +1442,17 @@ } } +func TestSetDefaultWithRepeatedNonMessage(t *testing.T) { + m := &MyMessage{ + Pet: []string{"turtle", "wombat"}, + } + expected := Clone(m) + SetDefaults(m) + if !Equal(m, expected) { + t.Errorf("\n got %v\nwant %v", m, expected) + } +} + func TestMaximumTagNumber(t *testing.T) { m := &MaxTag{ LastField: String("natural goat essence"), @@ -1382,7 +1479,7 @@ }, Bikeshed: MyMessage_GREEN.Enum(), } - const expected = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":"GREEN"}` + const expected = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":1}` b, err := json.Marshal(m) if err != nil { @@ -1401,8 +1498,8 @@ t.Fatalf("got %s, want %s", received, m) } - // Test unmarshalling of older json wire format. - const old = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":1}` + // Test unmarshalling of JSON with symbolic enum name. + const old = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":"GREEN"}` received.Reset() if err := json.Unmarshal([]byte(old), received); err != nil { t.Fatalf("json.Unmarshal failed: %v", err) @@ -1655,7 +1752,8 @@ n int }{ {&Defaults{F_Int32: Int32(math.MaxInt32)}, 6}, - {&Defaults{F_Int32: Int32(math.MinInt32)}, 6}, + {&Defaults{F_Int32: Int32(math.MinInt32)}, 11}, + {&Defaults{F_Uint32: Uint32(uint32(math.MaxInt32) + 1)}, 6}, {&Defaults{F_Uint32: Uint32(math.MaxUint32)}, 6}, } for _, test := range tests { @@ -1670,6 +1768,70 @@ } } +func TestRequiredNotSetError(t *testing.T) { + pb := initGoTest(false) + pb.RequiredField.Label = nil + pb.F_Int32Required = nil + pb.F_Int64Required = nil + + expected := "0807" + // field 1, encoding 0, value 7 + "2206" + "120474797065" + // field 4, encoding 2 (GoTestField) + "5001" + // field 10, encoding 0, value 1 + "6d20000000" + // field 13, encoding 5, value 0x20 + "714000000000000000" + // field 14, encoding 1, value 0x40 + "78a019" + // field 15, encoding 0, value 0xca0 = 3232 + "8001c032" + // field 16, encoding 0, value 0x1940 = 6464 + "8d0100004a45" + // field 17, encoding 5, value 3232.0 + "9101000000000040b940" + // field 18, encoding 1, value 6464.0 + "9a0106" + "737472696e67" + // field 19, encoding 2, string "string" + "b304" + // field 70, encoding 3, start group + "ba0408" + "7265717569726564" + // field 71, encoding 2, string "required" + "b404" + // field 70, encoding 4, end group + "aa0605" + "6279746573" + // field 101, encoding 2, string "bytes" + "b0063f" + // field 102, encoding 0, 0x3f zigzag32 + "b8067f" // field 103, encoding 0, 0x7f zigzag64 + + o := old() + bytes, err := Marshal(pb) + if _, ok := err.(*RequiredNotSetError); !ok { + fmt.Printf("marshal-1 err = %v, want *RequiredNotSetError", err) + o.DebugPrint("", bytes) + t.Fatalf("expected = %s", expected) + } + if strings.Index(err.Error(), "RequiredField.Label") < 0 { + t.Errorf("marshal-1 wrong err msg: %v", err) + } + if !equal(bytes, expected, t) { + o.DebugPrint("neq 1", bytes) + t.Fatalf("expected = %s", expected) + } + + // Now test Unmarshal by recreating the original buffer. + pbd := new(GoTest) + err = Unmarshal(bytes, pbd) + if _, ok := err.(*RequiredNotSetError); !ok { + t.Fatalf("unmarshal err = %v, want *RequiredNotSetError", err) + o.DebugPrint("", bytes) + t.Fatalf("string = %s", expected) + } + if strings.Index(err.Error(), "RequiredField.{Unknown}") < 0 { + t.Errorf("unmarshal wrong err msg: %v", err) + } + bytes, err = Marshal(pbd) + if _, ok := err.(*RequiredNotSetError); !ok { + t.Errorf("marshal-2 err = %v, want *RequiredNotSetError", err) + o.DebugPrint("", bytes) + t.Fatalf("string = %s", expected) + } + if strings.Index(err.Error(), "RequiredField.Label") < 0 { + t.Errorf("marshal-2 wrong err msg: %v", err) + } + if !equal(bytes, expected, t) { + o.DebugPrint("neq 2", bytes) + t.Fatalf("string = %s", expected) + } +} + func fuzzUnmarshal(t *testing.T, data []byte) { defer func() { if e := recover(); e != nil { @@ -1683,78 +1845,214 @@ Unmarshal(data, pb) } -func benchmarkMsg(bytes bool) *GoTest { - pb := initGoTest(true) - if bytes { - buf := make([]byte, 4000) - for i := range buf { - buf[i] = byte(i) - } - pb.F_BytesDefaulted = buf - } else { - const N = 1000 // Internally the library starts much smaller. - pb.F_Int32Repeated = make([]int32, N) - pb.F_DoubleRepeated = make([]float64, N) - for i := 0; i < N; i++ { - pb.F_Int32Repeated[i] = int32(i) - pb.F_DoubleRepeated[i] = float64(i) +func TestMapFieldMarshal(t *testing.T) { + m := &MessageWithMap{ + NameMapping: map[int32]string{ + 1: "Rob", + 4: "Ian", + 8: "Dave", + }, + } + b, err := Marshal(m) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + + // b should be the concatenation of these three byte sequences in some order. + parts := []string{ + "\n\a\b\x01\x12\x03Rob", + "\n\a\b\x04\x12\x03Ian", + "\n\b\b\x08\x12\x04Dave", + } + ok := false + for i := range parts { + for j := range parts { + if j == i { + continue + } + for k := range parts { + if k == i || k == j { + continue + } + try := parts[i] + parts[j] + parts[k] + if bytes.Equal(b, []byte(try)) { + ok = true + break + } + } + } + } + if !ok { + t.Fatalf("Incorrect Marshal output.\n got %q\nwant %q (or a permutation of that)", b, parts[0]+parts[1]+parts[2]) + } + t.Logf("FYI b: %q", b) + + (new(Buffer)).DebugPrint("Dump of b", b) +} + +func TestMapFieldRoundTrips(t *testing.T) { + m := &MessageWithMap{ + NameMapping: map[int32]string{ + 1: "Rob", + 4: "Ian", + 8: "Dave", + }, + MsgMapping: map[int64]*FloatingPoint{ + 0x7001: &FloatingPoint{F: Float64(2.0)}, + }, + ByteMapping: map[bool][]byte{ + false: []byte("that's not right!"), + true: []byte("aye, 'tis true!"), + }, + } + b, err := Marshal(m) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + t.Logf("FYI b: %q", b) + m2 := new(MessageWithMap) + if err := Unmarshal(b, m2); err != nil { + t.Fatalf("Unmarshal: %v", err) + } + for _, pair := range [][2]interface{}{ + {m.NameMapping, m2.NameMapping}, + {m.MsgMapping, m2.MsgMapping}, + {m.ByteMapping, m2.ByteMapping}, + } { + if !reflect.DeepEqual(pair[0], pair[1]) { + t.Errorf("Map did not survive a round trip.\ninitial: %v\n final: %v", pair[0], pair[1]) } } +} + +func TestMapFieldWithNil(t *testing.T) { + m := &MessageWithMap{ + MsgMapping: map[int64]*FloatingPoint{ + 1: nil, + }, + } + b, err := Marshal(m) + if err == nil { + t.Fatalf("Marshal of bad map should have failed, got these bytes: %v", b) + } +} + +// Benchmarks + +func testMsg() *GoTest { + pb := initGoTest(true) + const N = 1000 // Internally the library starts much smaller. + pb.F_Int32Repeated = make([]int32, N) + pb.F_DoubleRepeated = make([]float64, N) + for i := 0; i < N; i++ { + pb.F_Int32Repeated[i] = int32(i) + pb.F_DoubleRepeated[i] = float64(i) + } return pb } -func BenchmarkMarshal(b *testing.B) { - pb := benchmarkMsg(false) - p := NewBuffer(nil) +func bytesMsg() *GoTest { + pb := initGoTest(true) + buf := make([]byte, 4000) + for i := range buf { + buf[i] = byte(i) + } + pb.F_BytesDefaulted = buf + return pb +} +func benchmarkMarshal(b *testing.B, pb Message, marshal func(Message) ([]byte, error)) { + d, _ := marshal(pb) + b.SetBytes(int64(len(d))) b.ResetTimer() for i := 0; i < b.N; i++ { - p.Reset() - p.Marshal(pb) + marshal(pb) } - b.SetBytes(int64(len(p.Bytes()))) } -func BenchmarkUnmarshal(b *testing.B) { - pb := benchmarkMsg(false) +func benchmarkBufferMarshal(b *testing.B, pb Message) { p := NewBuffer(nil) - p.Marshal(pb) - b.SetBytes(int64(len(p.Bytes()))) - p2 := NewBuffer(nil) - pbd := new(GoTest) + benchmarkMarshal(b, pb, func(pb0 Message) ([]byte, error) { + p.Reset() + err := p.Marshal(pb0) + return p.Bytes(), err + }) +} - b.ResetTimer() - for i := 0; i < b.N; i++ { - p2.SetBuf(p.Bytes()) - p2.Unmarshal(pbd) +func benchmarkSize(b *testing.B, pb Message) { + benchmarkMarshal(b, pb, func(pb0 Message) ([]byte, error) { + Size(pb) + return nil, nil + }) +} + +func newOf(pb Message) Message { + in := reflect.ValueOf(pb) + if in.IsNil() { + return pb } + return reflect.New(in.Type().Elem()).Interface().(Message) } -func BenchmarkMarshalBytes(b *testing.B) { - pb := benchmarkMsg(true) - p := NewBuffer(nil) +func benchmarkUnmarshal(b *testing.B, pb Message, unmarshal func([]byte, Message) error) { + d, _ := Marshal(pb) + b.SetBytes(int64(len(d))) + pbd := newOf(pb) b.ResetTimer() for i := 0; i < b.N; i++ { - p.Reset() - p.Marshal(pb) + unmarshal(d, pbd) } - b.SetBytes(int64(len(p.Bytes()))) } -func BenchmarkUnmarshalBytes(b *testing.B) { - pb := benchmarkMsg(true) +func benchmarkBufferUnmarshal(b *testing.B, pb Message) { p := NewBuffer(nil) - p.Marshal(pb) - b.SetBytes(int64(len(p.Bytes()))) - p2 := NewBuffer(nil) - pbd := new(GoTest) + benchmarkUnmarshal(b, pb, func(d []byte, pb0 Message) error { + p.SetBuf(d) + return p.Unmarshal(pb0) + }) +} - b.ResetTimer() - for i := 0; i < b.N; i++ { - p2.SetBuf(p.Bytes()) - p2.Unmarshal(pbd) - } +// Benchmark{Marshal,BufferMarshal,Size,Unmarshal,BufferUnmarshal}{,Bytes} + +func BenchmarkMarshal(b *testing.B) { + benchmarkMarshal(b, testMsg(), Marshal) +} + +func BenchmarkBufferMarshal(b *testing.B) { + benchmarkBufferMarshal(b, testMsg()) +} + +func BenchmarkSize(b *testing.B) { + benchmarkSize(b, testMsg()) +} + +func BenchmarkUnmarshal(b *testing.B) { + benchmarkUnmarshal(b, testMsg(), Unmarshal) +} + +func BenchmarkBufferUnmarshal(b *testing.B) { + benchmarkBufferUnmarshal(b, testMsg()) +} + +func BenchmarkMarshalBytes(b *testing.B) { + benchmarkMarshal(b, bytesMsg(), Marshal) +} + +func BenchmarkBufferMarshalBytes(b *testing.B) { + benchmarkBufferMarshal(b, bytesMsg()) +} + +func BenchmarkSizeBytes(b *testing.B) { + benchmarkSize(b, bytesMsg()) +} + +func BenchmarkUnmarshalBytes(b *testing.B) { + benchmarkUnmarshal(b, bytesMsg(), Unmarshal) +} + +func BenchmarkBufferUnmarshalBytes(b *testing.B) { + benchmarkBufferUnmarshal(b, bytesMsg()) } func BenchmarkUnmarshalUnrecognizedFields(b *testing.B) { diff -Nru golang-goprotobuf-0.0~git20130901/proto/clone.go golang-goprotobuf-0.0~git20150526/proto/clone.go --- golang-goprotobuf-0.0~git20130901/proto/clone.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/clone.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2011 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -29,7 +29,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Protocol buffer deep copy. +// Protocol buffer deep copy and merge. // TODO: MessageSet and RawMessage. package proto @@ -113,6 +113,29 @@ case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64: out.Set(in) + case reflect.Map: + if in.Len() == 0 { + return + } + if out.IsNil() { + out.Set(reflect.MakeMap(in.Type())) + } + // For maps with value types of *T or []byte we need to deep copy each value. + elemKind := in.Type().Elem().Kind() + for _, key := range in.MapKeys() { + var val reflect.Value + switch elemKind { + case reflect.Ptr: + val = reflect.New(in.Type().Elem().Elem()) + mergeAny(val, in.MapIndex(key)) + case reflect.Slice: + val = in.MapIndex(key) + val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) + default: + val = in.MapIndex(key) + } + out.SetMapIndex(key, val) + } case reflect.Ptr: if in.IsNil() { return @@ -125,13 +148,21 @@ if in.IsNil() { return } + if in.Type().Elem().Kind() == reflect.Uint8 { + // []byte is a scalar bytes field, not a repeated field. + // Make a deep copy. + // Append to []byte{} instead of []byte(nil) so that we never end up + // with a nil result. + out.SetBytes(append([]byte{}, in.Bytes()...)) + return + } n := in.Len() if out.IsNil() { out.Set(reflect.MakeSlice(in.Type(), 0, n)) } switch in.Type().Elem().Kind() { case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, - reflect.String, reflect.Uint32, reflect.Uint64, reflect.Uint8: + reflect.String, reflect.Uint32, reflect.Uint64: out.Set(reflect.AppendSlice(out, in)) default: for i := 0; i < n; i++ { diff -Nru golang-goprotobuf-0.0~git20130901/proto/clone_test.go golang-goprotobuf-0.0~git20150526/proto/clone_test.go --- golang-goprotobuf-0.0~git20130901/proto/clone_test.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/clone_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2011 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -34,9 +34,9 @@ import ( "testing" - "code.google.com/p/goprotobuf/proto" + "github.com/golang/protobuf/proto" - pb "./testdata" + pb "github.com/golang/protobuf/proto/testdata" ) var cloneTestMessage = &pb.MyMessage{ @@ -79,6 +79,22 @@ if proto.Equal(m, cloneTestMessage) { t.Error("Mutating clone changed the original") } + // Byte fields and repeated fields should be copied. + if &m.Pet[0] == &cloneTestMessage.Pet[0] { + t.Error("Pet: repeated field not copied") + } + if &m.Others[0] == &cloneTestMessage.Others[0] { + t.Error("Others: repeated field not copied") + } + if &m.Others[0].Value[0] == &cloneTestMessage.Others[0].Value[0] { + t.Error("Others[0].Value: bytes field not copied") + } + if &m.RepBytes[0] == &cloneTestMessage.RepBytes[0] { + t.Error("RepBytes: repeated field not copied") + } + if &m.RepBytes[0][0] == &cloneTestMessage.RepBytes[0][0] { + t.Error("RepBytes[0]: bytes field not copied") + } } func TestCloneNil(t *testing.T) { @@ -167,6 +183,37 @@ RepBytes: [][]byte{[]byte("sham"), []byte("wow")}, }, }, + // Check that a scalar bytes field replaces rather than appends. + { + src: &pb.OtherMessage{Value: []byte("foo")}, + dst: &pb.OtherMessage{Value: []byte("bar")}, + want: &pb.OtherMessage{Value: []byte("foo")}, + }, + { + src: &pb.MessageWithMap{ + NameMapping: map[int32]string{6: "Nigel"}, + MsgMapping: map[int64]*pb.FloatingPoint{ + 0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)}, + }, + ByteMapping: map[bool][]byte{true: []byte("wowsa")}, + }, + dst: &pb.MessageWithMap{ + NameMapping: map[int32]string{ + 6: "Bruce", // should be overwritten + 7: "Andrew", + }, + }, + want: &pb.MessageWithMap{ + NameMapping: map[int32]string{ + 6: "Nigel", + 7: "Andrew", + }, + MsgMapping: map[int64]*pb.FloatingPoint{ + 0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)}, + }, + ByteMapping: map[bool][]byte{true: []byte("wowsa")}, + }, + }, } func TestMerge(t *testing.T) { diff -Nru golang-goprotobuf-0.0~git20130901/proto/decode.go golang-goprotobuf-0.0~git20150526/proto/decode.go --- golang-goprotobuf-0.0~git20130901/proto/decode.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/decode.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -43,11 +43,6 @@ "reflect" ) -// ErrWrongType occurs when the wire encoding for the field disagrees with -// that specified in the type being decoded. This is usually caused by attempting -// to convert an encoded protocol buffer into a struct of the wrong type. -var ErrWrongType = errors.New("field/encoding mismatch: wrong type for field") - // errOverflow is returned when an integer is too large to be represented. var errOverflow = errors.New("proto: integer overflow") @@ -183,7 +178,7 @@ func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { n, err := p.DecodeVarint() if err != nil { - return + return nil, err } nb := int(n) @@ -235,12 +230,6 @@ ptr := structPointer_Bytes(base, unrecField) - if *ptr == nil { - // This is the first skipped element, - // allocate a new buffer. - *ptr = o.bufalloc() - } - // Add the skipped field to struct field obuf := o.buf @@ -353,6 +342,7 @@ // unmarshalType does the work of unmarshaling a structure. func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error { + var state errorState required, reqFields := prop.reqCount, uint64(0) var err error @@ -368,11 +358,11 @@ if is_group { return nil // input is satisfied } - return ErrWrongType + return fmt.Errorf("proto: %s: wiretype end group for non-group", st) } tag := int(u >> 3) if tag <= 0 { - return fmt.Errorf("proto: illegal tag %d", tag) + return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire) } fieldnum, ok := prop.decoderTags.get(tag) if !ok { @@ -402,11 +392,14 @@ // a packable field dec = p.packedDec } else { - err = ErrWrongType + err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType) continue } } - err = dec(o, p, base) + decErr := dec(o, p, base) + if decErr != nil && !state.shouldContinue(decErr, p) { + err = decErr + } if err == nil && p.Required { // Successfully decoded a required field. if tag <= 64 { @@ -430,8 +423,14 @@ if is_group { return io.ErrUnexpectedEOF } + if state.err != nil { + return state.err + } if required > 0 { - return &ErrRequiredNotSet{st} + // Not enough information to determine the exact field. If we use extra + // CPU, we could determine the field only if the missing required field + // has a tag <= 64 and we check reqFields. + return &RequiredNotSetError{"{Unknown}"} } } return err @@ -466,6 +465,15 @@ return nil } +func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + *structPointer_BoolVal(base, p.field) = u != 0 + return nil +} + // Decode an int32. func (o *Buffer) dec_int32(p *Properties, base structPointer) error { u, err := p.valDec(o) @@ -476,6 +484,15 @@ return nil } +func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u)) + return nil +} + // Decode an int64. func (o *Buffer) dec_int64(p *Properties, base structPointer) error { u, err := p.valDec(o) @@ -486,15 +503,31 @@ return nil } +func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + word64Val_Set(structPointer_Word64Val(base, p.field), o, u) + return nil +} + // Decode a string. func (o *Buffer) dec_string(p *Properties, base structPointer) error { s, err := o.DecodeStringBytes() if err != nil { return err } - sp := new(string) - *sp = s - *structPointer_String(base, p.field) = sp + *structPointer_String(base, p.field) = &s + return nil +} + +func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error { + s, err := o.DecodeStringBytes() + if err != nil { + return err + } + *structPointer_StringVal(base, p.field) = s return nil } @@ -633,6 +666,78 @@ return nil } +// Decode a map field. +func (o *Buffer) dec_new_map(p *Properties, base structPointer) error { + raw, err := o.DecodeRawBytes(false) + if err != nil { + return err + } + oi := o.index // index at the end of this map entry + o.index -= len(raw) // move buffer back to start of map entry + + mptr := structPointer_Map(base, p.field, p.mtype) // *map[K]V + if mptr.Elem().IsNil() { + mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem())) + } + v := mptr.Elem() // map[K]V + + // Prepare addressable doubly-indirect placeholders for the key and value types. + // See enc_new_map for why. + keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K + keybase := toStructPointer(keyptr.Addr()) // **K + + var valbase structPointer + var valptr reflect.Value + switch p.mtype.Elem().Kind() { + case reflect.Slice: + // []byte + var dummy []byte + valptr = reflect.ValueOf(&dummy) // *[]byte + valbase = toStructPointer(valptr) // *[]byte + case reflect.Ptr: + // message; valptr is **Msg; need to allocate the intermediate pointer + valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V + valptr.Set(reflect.New(valptr.Type().Elem())) + valbase = toStructPointer(valptr) + default: + // everything else + valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V + valbase = toStructPointer(valptr.Addr()) // **V + } + + // Decode. + // This parses a restricted wire format, namely the encoding of a message + // with two fields. See enc_new_map for the format. + for o.index < oi { + // tagcode for key and value properties are always a single byte + // because they have tags 1 and 2. + tagcode := o.buf[o.index] + o.index++ + switch tagcode { + case p.mkeyprop.tagcode[0]: + if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil { + return err + } + case p.mvalprop.tagcode[0]: + if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil { + return err + } + default: + // TODO: Should we silently skip this instead? + return fmt.Errorf("proto: bad map data tag %d", raw[0]) + } + } + keyelem, valelem := keyptr.Elem(), valptr.Elem() + if !keyelem.IsValid() || !valelem.IsValid() { + // We did not decode the key or the value in the map entry. + // Either way, it's an invalid map entry. + return fmt.Errorf("proto: bad map data: missing key/val") + } + + v.SetMapIndex(keyelem, valelem) + return nil +} + // Decode a group. func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error { bas := structPointer_GetStructPointer(base, p.field) diff -Nru golang-goprotobuf-0.0~git20130901/proto/encode.go golang-goprotobuf-0.0~git20150526/proto/encode.go --- golang-goprotobuf-0.0~git20130901/proto/encode.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/encode.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -37,27 +37,32 @@ import ( "errors" + "fmt" "reflect" "sort" ) -// ErrRequiredNotSet is the error returned if Marshal is called with +// RequiredNotSetError is the error returned if Marshal is called with // a protocol buffer struct whose required fields have not // all been initialized. It is also the error returned if Unmarshal is // called with an encoded protocol buffer that does not include all the // required fields. -type ErrRequiredNotSet struct { - t reflect.Type +// +// When printed, RequiredNotSetError reports the first unset required field in a +// message. If the field cannot be precisely determined, it is reported as +// "{Unknown}". +type RequiredNotSetError struct { + field string } -func (e *ErrRequiredNotSet) Error() string { - return "proto: required fields not set in " + e.t.String() +func (e *RequiredNotSetError) Error() string { + return fmt.Sprintf("proto: required field %q not set", e.field) } var ( - // ErrRepeatedHasNil is the error returned if Marshal is called with + // errRepeatedHasNil is the error returned if Marshal is called with // a struct with a repeated field containing a nil element. - ErrRepeatedHasNil = errors.New("proto: repeated field has nil element") + errRepeatedHasNil = errors.New("proto: repeated field has nil element") // ErrNil is the error returned if Marshal is called with nil. ErrNil = errors.New("proto: Marshal called with nil") @@ -100,6 +105,17 @@ return nil } +func sizeVarint(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} + // EncodeFixed64 writes a 64-bit integer to the Buffer. // This is the format for the // fixed64, sfixed64, and double protocol buffer types. @@ -116,6 +132,10 @@ return nil } +func sizeFixed64(x uint64) int { + return 8 +} + // EncodeFixed32 writes a 32-bit integer to the Buffer. // This is the format for the // fixed32, sfixed32, and float protocol buffer types. @@ -128,6 +148,10 @@ return nil } +func sizeFixed32(x uint64) int { + return 4 +} + // EncodeZigzag64 writes a zigzag-encoded 64-bit integer // to the Buffer. // This is the format used for the sint64 protocol buffer type. @@ -136,6 +160,10 @@ return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func sizeZigzag64(x uint64) int { + return sizeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} + // EncodeZigzag32 writes a zigzag-encoded 32-bit integer // to the Buffer. // This is the format used for the sint32 protocol buffer type. @@ -144,6 +172,10 @@ return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) } +func sizeZigzag32(x uint64) int { + return sizeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) +} + // EncodeRawBytes writes a count-delimited byte buffer to the Buffer. // This is the format used for the bytes protocol buffer // type and for embedded messages. @@ -153,6 +185,11 @@ return nil } +func sizeRawBytes(b []byte) int { + return sizeVarint(uint64(len(b))) + + len(b) +} + // EncodeStringBytes writes an encoded string to the Buffer. // This is the format used for the proto2 string type. func (p *Buffer) EncodeStringBytes(s string) error { @@ -161,6 +198,11 @@ return nil } +func sizeStringBytes(s string) int { + return sizeVarint(uint64(len(s))) + + len(s) +} + // Marshaler is the interface representing objects that can marshal themselves. type Marshaler interface { Marshal() ([]byte, error) @@ -175,9 +217,14 @@ } p := NewBuffer(nil) err := p.Marshal(pb) - if err != nil { + var state errorState + if err != nil && !state.shouldContinue(err, nil) { return nil, err } + if p.buf == nil && err == nil { + // Return a non-nil slice on success. + return []byte{}, nil + } return p.buf, err } @@ -200,7 +247,7 @@ return ErrNil } if err == nil { - err = p.enc_struct(t.Elem(), GetProperties(t.Elem()), base) + err = p.enc_struct(GetProperties(t.Elem()), base) } if collectStats { @@ -210,6 +257,30 @@ return err } +// Size returns the encoded size of a protocol buffer. +func Size(pb Message) (n int) { + // Can the object marshal itself? If so, Size is slow. + // TODO: add Size to Marshaler, or add a Sizer interface. + if m, ok := pb.(Marshaler); ok { + b, _ := m.Marshal() + return len(b) + } + + t, base, err := getbase(pb) + if structPointer_IsNil(base) { + return 0 + } + if err == nil { + n = size_struct(GetProperties(t.Elem()), base) + } + + if collectStats { + stats.Size++ + } + + return +} + // Individual type encoders. // Encode a bool. @@ -227,18 +298,123 @@ return nil } +func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error { + v := *structPointer_BoolVal(base, p.field) + if !v { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, 1) + return nil +} + +func size_bool(p *Properties, base structPointer) int { + v := *structPointer_Bool(base, p.field) + if v == nil { + return 0 + } + return len(p.tagcode) + 1 // each bool takes exactly one byte +} + +func size_proto3_bool(p *Properties, base structPointer) int { + v := *structPointer_BoolVal(base, p.field) + if !v { + return 0 + } + return len(p.tagcode) + 1 // each bool takes exactly one byte +} + // Encode an int32. func (o *Buffer) enc_int32(p *Properties, base structPointer) error { v := structPointer_Word32(base, p.field) if word32_IsNil(v) { return ErrNil } + x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error { + v := structPointer_Word32Val(base, p.field) + x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range + if x == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func size_int32(p *Properties, base structPointer) (n int) { + v := structPointer_Word32(base, p.field) + if word32_IsNil(v) { + return 0 + } + x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range + n += len(p.tagcode) + n += p.valSize(uint64(x)) + return +} + +func size_proto3_int32(p *Properties, base structPointer) (n int) { + v := structPointer_Word32Val(base, p.field) + x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range + if x == 0 { + return 0 + } + n += len(p.tagcode) + n += p.valSize(uint64(x)) + return +} + +// Encode a uint32. +// Exactly the same as int32, except for no sign extension. +func (o *Buffer) enc_uint32(p *Properties, base structPointer) error { + v := structPointer_Word32(base, p.field) + if word32_IsNil(v) { + return ErrNil + } x := word32_Get(v) o.buf = append(o.buf, p.tagcode...) p.valEnc(o, uint64(x)) return nil } +func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error { + v := structPointer_Word32Val(base, p.field) + x := word32Val_Get(v) + if x == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func size_uint32(p *Properties, base structPointer) (n int) { + v := structPointer_Word32(base, p.field) + if word32_IsNil(v) { + return 0 + } + x := word32_Get(v) + n += len(p.tagcode) + n += p.valSize(uint64(x)) + return +} + +func size_proto3_uint32(p *Properties, base structPointer) (n int) { + v := structPointer_Word32Val(base, p.field) + x := word32Val_Get(v) + if x == 0 { + return 0 + } + n += len(p.tagcode) + n += p.valSize(uint64(x)) + return +} + // Encode an int64. func (o *Buffer) enc_int64(p *Properties, base structPointer) error { v := structPointer_Word64(base, p.field) @@ -251,6 +427,39 @@ return nil } +func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error { + v := structPointer_Word64Val(base, p.field) + x := word64Val_Get(v) + if x == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, x) + return nil +} + +func size_int64(p *Properties, base structPointer) (n int) { + v := structPointer_Word64(base, p.field) + if word64_IsNil(v) { + return 0 + } + x := word64_Get(v) + n += len(p.tagcode) + n += p.valSize(x) + return +} + +func size_proto3_int64(p *Properties, base structPointer) (n int) { + v := structPointer_Word64Val(base, p.field) + x := word64Val_Get(v) + if x == 0 { + return 0 + } + n += len(p.tagcode) + n += p.valSize(x) + return +} + // Encode a string. func (o *Buffer) enc_string(p *Properties, base structPointer) error { v := *structPointer_String(base, p.field) @@ -263,6 +472,37 @@ return nil } +func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error { + v := *structPointer_StringVal(base, p.field) + if v == "" { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeStringBytes(v) + return nil +} + +func size_string(p *Properties, base structPointer) (n int) { + v := *structPointer_String(base, p.field) + if v == nil { + return 0 + } + x := *v + n += len(p.tagcode) + n += sizeStringBytes(x) + return +} + +func size_proto3_string(p *Properties, base structPointer) (n int) { + v := *structPointer_StringVal(base, p.field) + if v == "" { + return 0 + } + n += len(p.tagcode) + n += sizeStringBytes(v) + return +} + // All protocol buffer fields are nillable, but be careful. func isNil(v reflect.Value) bool { switch v.Kind() { @@ -274,6 +514,7 @@ // Encode a message struct. func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error { + var state errorState structp := structPointer_GetStructPointer(base, p.field) if structPointer_IsNil(structp) { return ErrNil @@ -283,7 +524,7 @@ if p.isMarshaler { m := structPointer_Interface(structp, p.stype).(Marshaler) data, err := m.Marshal() - if err != nil { + if err != nil && !state.shouldContinue(err, nil) { return err } o.buf = append(o.buf, p.tagcode...) @@ -291,39 +532,58 @@ return nil } - // need the length before we can write out the message itself, - // so marshal into a separate byte buffer first. - obuf := o.buf - o.buf = o.bufalloc() - - err := o.enc_struct(p.stype, p.sprop, structp) - - nbuf := o.buf - o.buf = obuf - if err != nil { - o.buffree(nbuf) - return err - } o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(nbuf) - o.buffree(nbuf) - return nil + return o.enc_len_struct(p.sprop, structp, &state) +} + +func size_struct_message(p *Properties, base structPointer) int { + structp := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(structp) { + return 0 + } + + // Can the object marshal itself? + if p.isMarshaler { + m := structPointer_Interface(structp, p.stype).(Marshaler) + data, _ := m.Marshal() + n0 := len(p.tagcode) + n1 := sizeRawBytes(data) + return n0 + n1 + } + + n0 := len(p.tagcode) + n1 := size_struct(p.sprop, structp) + n2 := sizeVarint(uint64(n1)) // size of encoded length + return n0 + n1 + n2 } // Encode a group struct. func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error { + var state errorState b := structPointer_GetStructPointer(base, p.field) if structPointer_IsNil(b) { return ErrNil } o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup)) - err := o.enc_struct(p.stype, p.sprop, b) - if err != nil { + err := o.enc_struct(p.sprop, b) + if err != nil && !state.shouldContinue(err, nil) { return err } o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup)) - return nil + return state.err +} + +func size_struct_group(p *Properties, base structPointer) (n int) { + b := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(b) { + return 0 + } + + n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup)) + n += size_struct(p.sprop, b) + n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup)) + return } // Encode a slice of bools ([]bool). @@ -344,6 +604,15 @@ return nil } +func size_slice_bool(p *Properties, base structPointer) int { + s := *structPointer_BoolSlice(base, p.field) + l := len(s) + if l == 0 { + return 0 + } + return l * (len(p.tagcode) + 1) // each bool takes exactly one byte +} + // Encode a slice of bools ([]bool) in packed format. func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error { s := *structPointer_BoolSlice(base, p.field) @@ -363,6 +632,18 @@ return nil } +func size_slice_packed_bool(p *Properties, base structPointer) (n int) { + s := *structPointer_BoolSlice(base, p.field) + l := len(s) + if l == 0 { + return 0 + } + n += len(p.tagcode) + n += sizeVarint(uint64(l)) + n += l // each bool takes exactly one byte + return +} + // Encode a slice of bytes ([]byte). func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error { s := *structPointer_Bytes(base, p.field) @@ -374,6 +655,36 @@ return nil } +func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error { + s := *structPointer_Bytes(base, p.field) + if len(s) == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(s) + return nil +} + +func size_slice_byte(p *Properties, base structPointer) (n int) { + s := *structPointer_Bytes(base, p.field) + if s == nil { + return 0 + } + n += len(p.tagcode) + n += sizeRawBytes(s) + return +} + +func size_proto3_slice_byte(p *Properties, base structPointer) (n int) { + s := *structPointer_Bytes(base, p.field) + if len(s) == 0 { + return 0 + } + n += len(p.tagcode) + n += sizeRawBytes(s) + return +} + // Encode a slice of int32s ([]int32). func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error { s := structPointer_Word32Slice(base, p.field) @@ -383,12 +694,26 @@ } for i := 0; i < l; i++ { o.buf = append(o.buf, p.tagcode...) - x := s.Index(i) + x := int32(s.Index(i)) // permit sign extension to use full 64-bit range p.valEnc(o, uint64(x)) } return nil } +func size_slice_int32(p *Properties, base structPointer) (n int) { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + for i := 0; i < l; i++ { + n += len(p.tagcode) + x := int32(s.Index(i)) // permit sign extension to use full 64-bit range + n += p.valSize(uint64(x)) + } + return +} + // Encode a slice of int32s ([]int32) in packed format. func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error { s := structPointer_Word32Slice(base, p.field) @@ -399,6 +724,75 @@ // TODO: Reuse a Buffer. buf := NewBuffer(nil) for i := 0; i < l; i++ { + x := int32(s.Index(i)) // permit sign extension to use full 64-bit range + p.valEnc(buf, uint64(x)) + } + + o.buf = append(o.buf, p.tagcode...) + o.EncodeVarint(uint64(len(buf.buf))) + o.buf = append(o.buf, buf.buf...) + return nil +} + +func size_slice_packed_int32(p *Properties, base structPointer) (n int) { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + var bufSize int + for i := 0; i < l; i++ { + x := int32(s.Index(i)) // permit sign extension to use full 64-bit range + bufSize += p.valSize(uint64(x)) + } + + n += len(p.tagcode) + n += sizeVarint(uint64(bufSize)) + n += bufSize + return +} + +// Encode a slice of uint32s ([]uint32). +// Exactly the same as int32, except for no sign extension. +func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + for i := 0; i < l; i++ { + o.buf = append(o.buf, p.tagcode...) + x := s.Index(i) + p.valEnc(o, uint64(x)) + } + return nil +} + +func size_slice_uint32(p *Properties, base structPointer) (n int) { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + for i := 0; i < l; i++ { + n += len(p.tagcode) + x := s.Index(i) + n += p.valSize(uint64(x)) + } + return +} + +// Encode a slice of uint32s ([]uint32) in packed format. +// Exactly the same as int32, except for no sign extension. +func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + // TODO: Reuse a Buffer. + buf := NewBuffer(nil) + for i := 0; i < l; i++ { p.valEnc(buf, uint64(s.Index(i))) } @@ -408,6 +802,23 @@ return nil } +func size_slice_packed_uint32(p *Properties, base structPointer) (n int) { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + var bufSize int + for i := 0; i < l; i++ { + bufSize += p.valSize(uint64(s.Index(i))) + } + + n += len(p.tagcode) + n += sizeVarint(uint64(bufSize)) + n += bufSize + return +} + // Encode a slice of int64s ([]int64). func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error { s := structPointer_Word64Slice(base, p.field) @@ -422,6 +833,19 @@ return nil } +func size_slice_int64(p *Properties, base structPointer) (n int) { + s := structPointer_Word64Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + for i := 0; i < l; i++ { + n += len(p.tagcode) + n += p.valSize(s.Index(i)) + } + return +} + // Encode a slice of int64s ([]int64) in packed format. func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error { s := structPointer_Word64Slice(base, p.field) @@ -441,6 +865,23 @@ return nil } +func size_slice_packed_int64(p *Properties, base structPointer) (n int) { + s := structPointer_Word64Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + var bufSize int + for i := 0; i < l; i++ { + bufSize += p.valSize(s.Index(i)) + } + + n += len(p.tagcode) + n += sizeVarint(uint64(bufSize)) + n += bufSize + return +} + // Encode a slice of slice of bytes ([][]byte). func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error { ss := *structPointer_BytesSlice(base, p.field) @@ -450,40 +891,62 @@ } for i := 0; i < l; i++ { o.buf = append(o.buf, p.tagcode...) - s := ss[i] - o.EncodeRawBytes(s) + o.EncodeRawBytes(ss[i]) } return nil } +func size_slice_slice_byte(p *Properties, base structPointer) (n int) { + ss := *structPointer_BytesSlice(base, p.field) + l := len(ss) + if l == 0 { + return 0 + } + n += l * len(p.tagcode) + for i := 0; i < l; i++ { + n += sizeRawBytes(ss[i]) + } + return +} + // Encode a slice of strings ([]string). func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error { ss := *structPointer_StringSlice(base, p.field) l := len(ss) for i := 0; i < l; i++ { o.buf = append(o.buf, p.tagcode...) - s := ss[i] - o.EncodeStringBytes(s) + o.EncodeStringBytes(ss[i]) } return nil } +func size_slice_string(p *Properties, base structPointer) (n int) { + ss := *structPointer_StringSlice(base, p.field) + l := len(ss) + n += l * len(p.tagcode) + for i := 0; i < l; i++ { + n += sizeStringBytes(ss[i]) + } + return +} + // Encode a slice of message structs ([]*struct). func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error { + var state errorState s := structPointer_StructPointerSlice(base, p.field) l := s.Len() for i := 0; i < l; i++ { structp := s.Index(i) if structPointer_IsNil(structp) { - return ErrRepeatedHasNil + return errRepeatedHasNil } // Can the object marshal itself? if p.isMarshaler { m := structPointer_Interface(structp, p.stype).(Marshaler) data, err := m.Marshal() - if err != nil { + if err != nil && !state.shouldContinue(err, nil) { return err } o.buf = append(o.buf, p.tagcode...) @@ -491,53 +954,87 @@ continue } - obuf := o.buf - o.buf = o.bufalloc() - - err := o.enc_struct(p.stype, p.sprop, structp) - - nbuf := o.buf - o.buf = obuf - if err != nil { - o.buffree(nbuf) + o.buf = append(o.buf, p.tagcode...) + err := o.enc_len_struct(p.sprop, structp, &state) + if err != nil && !state.shouldContinue(err, nil) { if err == ErrNil { - return ErrRepeatedHasNil + return errRepeatedHasNil } return err } - o.buf = append(o.buf, p.tagcode...) - o.EncodeRawBytes(nbuf) + } + return state.err +} + +func size_slice_struct_message(p *Properties, base structPointer) (n int) { + s := structPointer_StructPointerSlice(base, p.field) + l := s.Len() + n += l * len(p.tagcode) + for i := 0; i < l; i++ { + structp := s.Index(i) + if structPointer_IsNil(structp) { + return // return the size up to this point + } - o.buffree(nbuf) + // Can the object marshal itself? + if p.isMarshaler { + m := structPointer_Interface(structp, p.stype).(Marshaler) + data, _ := m.Marshal() + n += len(p.tagcode) + n += sizeRawBytes(data) + continue + } + + n0 := size_struct(p.sprop, structp) + n1 := sizeVarint(uint64(n0)) // size of encoded length + n += n0 + n1 } - return nil + return } // Encode a slice of group structs ([]*struct). func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error { + var state errorState s := structPointer_StructPointerSlice(base, p.field) l := s.Len() for i := 0; i < l; i++ { b := s.Index(i) if structPointer_IsNil(b) { - return ErrRepeatedHasNil + return errRepeatedHasNil } o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup)) - err := o.enc_struct(p.stype, p.sprop, b) + err := o.enc_struct(p.sprop, b) - if err != nil { + if err != nil && !state.shouldContinue(err, nil) { if err == ErrNil { - return ErrRepeatedHasNil + return errRepeatedHasNil } return err } o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup)) } - return nil + return state.err +} + +func size_slice_struct_group(p *Properties, base structPointer) (n int) { + s := structPointer_StructPointerSlice(base, p.field) + l := s.Len() + + n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup)) + n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup)) + for i := 0; i < l; i++ { + b := s.Index(i) + if structPointer_IsNil(b) { + return // return size up to this point + } + + n += size_struct(p.sprop, b) + } + return } // Encode an extension map. @@ -567,29 +1064,142 @@ return nil } +func size_map(p *Properties, base structPointer) int { + v := *structPointer_ExtMap(base, p.field) + return sizeExtensionMap(v) +} + +// Encode a map field. +func (o *Buffer) enc_new_map(p *Properties, base structPointer) error { + var state errorState // XXX: or do we need to plumb this through? + + /* + A map defined as + map map_field = N; + is encoded in the same way as + message MapFieldEntry { + key_type key = 1; + value_type value = 2; + } + repeated MapFieldEntry map_field = N; + */ + + v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V + if v.Len() == 0 { + return nil + } + + keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype) + + enc := func() error { + if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil { + return err + } + if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil { + return err + } + return nil + } + + keys := v.MapKeys() + sort.Sort(mapKeys(keys)) + for _, key := range keys { + val := v.MapIndex(key) + + // The only illegal map entry values are nil message pointers. + if val.Kind() == reflect.Ptr && val.IsNil() { + return errors.New("proto: map has nil element") + } + + keycopy.Set(key) + valcopy.Set(val) + + o.buf = append(o.buf, p.tagcode...) + if err := o.enc_len_thing(enc, &state); err != nil { + return err + } + } + return nil +} + +func size_new_map(p *Properties, base structPointer) int { + v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V + + keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype) + + n := 0 + for _, key := range v.MapKeys() { + val := v.MapIndex(key) + keycopy.Set(key) + valcopy.Set(val) + + // Tag codes for key and val are the responsibility of the sub-sizer. + keysize := p.mkeyprop.size(p.mkeyprop, keybase) + valsize := p.mvalprop.size(p.mvalprop, valbase) + entry := keysize + valsize + // Add on tag code and length of map entry itself. + n += len(p.tagcode) + sizeVarint(uint64(entry)) + entry + } + return n +} + +// mapEncodeScratch returns a new reflect.Value matching the map's value type, +// and a structPointer suitable for passing to an encoder or sizer. +func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) { + // Prepare addressable doubly-indirect placeholders for the key and value types. + // This is needed because the element-type encoders expect **T, but the map iteration produces T. + + keycopy = reflect.New(mapType.Key()).Elem() // addressable K + keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K + keyptr.Set(keycopy.Addr()) // + keybase = toStructPointer(keyptr.Addr()) // **K + + // Value types are more varied and require special handling. + switch mapType.Elem().Kind() { + case reflect.Slice: + // []byte + var dummy []byte + valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte + valbase = toStructPointer(valcopy.Addr()) + case reflect.Ptr: + // message; the generated field type is map[K]*Msg (so V is *Msg), + // so we only need one level of indirection. + valcopy = reflect.New(mapType.Elem()).Elem() // addressable V + valbase = toStructPointer(valcopy.Addr()) + default: + // everything else + valcopy = reflect.New(mapType.Elem()).Elem() // addressable V + valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V + valptr.Set(valcopy.Addr()) // + valbase = toStructPointer(valptr.Addr()) // **V + } + return +} + // Encode a struct. -func (o *Buffer) enc_struct(t reflect.Type, prop *StructProperties, base structPointer) error { - required := prop.reqCount +func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error { + var state errorState // Encode fields in tag order so that decoders may use optimizations // that depend on the ordering. - // http://code.google.com/apis/protocolbuffers/docs/encoding.html#order + // https://developers.google.com/protocol-buffers/docs/encoding#order for _, i := range prop.order { p := prop.Prop[i] if p.enc != nil { err := p.enc(o, p, base) if err != nil { - if err != ErrNil { + if err == ErrNil { + if p.Required && state.err == nil { + state.err = &RequiredNotSetError{p.Name} + } + } else if err == errRepeatedHasNil { + // Give more context to nil values in repeated fields. + return errors.New("repeated field " + p.OrigName + " has nil element") + } else if !state.shouldContinue(err, p) { return err } - } else if p.Required { - required-- } } } - // See if we encoded all required fields. - if required > 0 { - return &ErrRequiredNotSet{t} - } // Add unrecognized fields at the end. if prop.unrecField.IsValid() { @@ -599,5 +1209,85 @@ } } - return nil + return state.err +} + +func size_struct(prop *StructProperties, base structPointer) (n int) { + for _, i := range prop.order { + p := prop.Prop[i] + if p.size != nil { + n += p.size(p, base) + } + } + + // Add unrecognized fields at the end. + if prop.unrecField.IsValid() { + v := *structPointer_Bytes(base, prop.unrecField) + n += len(v) + } + + return +} + +var zeroes [20]byte // longer than any conceivable sizeVarint + +// Encode a struct, preceded by its encoded length (as a varint). +func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error { + return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state) +} + +// Encode something, preceded by its encoded length (as a varint). +func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error { + iLen := len(o.buf) + o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length + iMsg := len(o.buf) + err := enc() + if err != nil && !state.shouldContinue(err, nil) { + return err + } + lMsg := len(o.buf) - iMsg + lLen := sizeVarint(uint64(lMsg)) + switch x := lLen - (iMsg - iLen); { + case x > 0: // actual length is x bytes larger than the space we reserved + // Move msg x bytes right. + o.buf = append(o.buf, zeroes[:x]...) + copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg]) + case x < 0: // actual length is x bytes smaller than the space we reserved + // Move msg x bytes left. + copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg]) + o.buf = o.buf[:len(o.buf)+x] // x is negative + } + // Encode the length in the reserved space. + o.buf = o.buf[:iLen] + o.EncodeVarint(uint64(lMsg)) + o.buf = o.buf[:len(o.buf)+lMsg] + return state.err +} + +// errorState maintains the first error that occurs and updates that error +// with additional context. +type errorState struct { + err error +} + +// shouldContinue reports whether encoding should continue upon encountering the +// given error. If the error is RequiredNotSetError, shouldContinue returns true +// and, if this is the first appearance of that error, remembers it for future +// reporting. +// +// If prop is not nil, it may update any error with additional context about the +// field with the error. +func (s *errorState) shouldContinue(err error, prop *Properties) bool { + // Ignore unset required fields. + reqNotSet, ok := err.(*RequiredNotSetError) + if !ok { + return false + } + if s.err == nil { + if prop != nil { + err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field} + } + s.err = err + } + return true } diff -Nru golang-goprotobuf-0.0~git20130901/proto/equal.go golang-goprotobuf-0.0~git20150526/proto/equal.go --- golang-goprotobuf-0.0~git20130901/proto/equal.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/equal.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2011 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -57,7 +57,7 @@ although represented by []byte, is not a repeated field) - Two unset fields are equal. - Two unknown field sets are equal if their current - encoded state is equal. (TODO) + encoded state is equal. - Two extension sets are equal iff they have corresponding elements that are pairwise equal. - Every other combination of things are not equal. @@ -154,6 +154,21 @@ return v1.Float() == v2.Float() case reflect.Int32, reflect.Int64: return v1.Int() == v2.Int() + case reflect.Map: + if v1.Len() != v2.Len() { + return false + } + for _, key := range v1.MapKeys() { + val2 := v2.MapIndex(key) + if !val2.IsValid() { + // This key was not found in the second map. + return false + } + if !equalAny(v1.MapIndex(key), val2) { + return false + } + } + return true case reflect.Ptr: return equalAny(v1.Elem(), v2.Elem()) case reflect.Slice: diff -Nru golang-goprotobuf-0.0~git20130901/proto/equal_test.go golang-goprotobuf-0.0~git20150526/proto/equal_test.go --- golang-goprotobuf-0.0~git20130901/proto/equal_test.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/equal_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2011 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -34,8 +34,8 @@ import ( "testing" - pb "./testdata" - . "code.google.com/p/goprotobuf/proto" + . "github.com/golang/protobuf/proto" + pb "github.com/golang/protobuf/proto/testdata" ) // Four identical base messages. @@ -155,6 +155,31 @@ }, true, }, + + { + "map same", + &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + true, + }, + { + "map different entry", + &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + &pb.MessageWithMap{NameMapping: map[int32]string{2: "Rob"}}, + false, + }, + { + "map different key only", + &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + &pb.MessageWithMap{NameMapping: map[int32]string{2: "Ken"}}, + false, + }, + { + "map different value only", + &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}}, + false, + }, } func TestEqual(t *testing.T) { diff -Nru golang-goprotobuf-0.0~git20130901/proto/extensions.go golang-goprotobuf-0.0~git20150526/proto/extensions.go --- golang-goprotobuf-0.0~git20130901/proto/extensions.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/extensions.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -37,6 +37,7 @@ import ( "errors" + "fmt" "reflect" "strconv" "sync" @@ -109,11 +110,11 @@ func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { // Check the extended type. if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b { - return errors.New("bad extended type; " + b.String() + " does not extend " + a.String()) + return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String()) } // Check the range. if !isExtensionField(pb, extension.Field) { - return errors.New("bad extension number; not in declared ranges") + return errors.New("proto: bad extension number; not in declared ranges") } return nil } @@ -183,6 +184,30 @@ return nil } +func sizeExtensionMap(m map[int32]Extension) (n int) { + for _, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + n += len(e.enc) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + et := reflect.TypeOf(e.desc.ExtensionType) + props := extensionProperties(e.desc) + + // If e.value has type T, the encoder expects a *struct{ X T }. + // Pass a *T with a zero field and hope it all works out. + x := reflect.New(et) + x.Elem().Set(reflect.ValueOf(e.value)) + n += props.size(props, toStructPointer(x)) + } + return +} + // HasExtension returns whether the given extension is present in pb. func HasExtension(pb extendableProto, extension *ExtensionDesc) bool { // TODO: Check types, field numbers, etc.? @@ -197,18 +222,20 @@ } // GetExtension parses and returns the given extension of pb. -// If the extension is not present it returns ErrMissingExtension. -// If the returned extension is modified, SetExtension must be called -// for the modifications to be reflected in pb. +// If the extension is not present and has no default value it returns ErrMissingExtension. func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) { if err := checkExtensionTypes(pb, extension); err != nil { return nil, err } - e, ok := pb.ExtensionMap()[extension.Field] + emap := pb.ExtensionMap() + e, ok := emap[extension.Field] if !ok { - return nil, ErrMissingExtension + // defaultExtensionValue returns the default value or + // ErrMissingExtension if there is no default. + return defaultExtensionValue(extension) } + if e.value != nil { // Already decoded. Check the descriptor, though. if e.desc != extension { @@ -230,9 +257,45 @@ e.value = v e.desc = extension e.enc = nil + emap[extension.Field] = e return e.value, nil } +// defaultExtensionValue returns the default value for extension. +// If no default for an extension is defined ErrMissingExtension is returned. +func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { + t := reflect.TypeOf(extension.ExtensionType) + props := extensionProperties(extension) + + sf, _, err := fieldDefault(t, props) + if err != nil { + return nil, err + } + + if sf == nil || sf.value == nil { + // There is no default value. + return nil, ErrMissingExtension + } + + if t.Kind() != reflect.Ptr { + // We do not need to return a Ptr, we can directly return sf.value. + return sf.value, nil + } + + // We need to return an interface{} that is a pointer to sf.value. + value := reflect.New(t).Elem() + value.Set(reflect.New(value.Type().Elem())) + if sf.kind == reflect.Int32 { + // We may have an int32 or an enum, but the underlying data is int32. + // Since we can't set an int32 into a non int32 reflect.value directly + // set it as a int32. + value.Elem().SetInt(int64(sf.value.(int32))) + } else { + value.Elem().Set(reflect.ValueOf(sf.value)) + } + return value.Interface(), nil +} + // decodeExtension decodes an extension encoded in b. func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { o := NewBuffer(b) @@ -272,12 +335,15 @@ func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { epb, ok := pb.(extendableProto) if !ok { - err = errors.New("not an extendable proto") + err = errors.New("proto: not an extendable proto") return } extensions = make([]interface{}, len(es)) for i, e := range es { extensions[i], err = GetExtension(epb, e) + if err == ErrMissingExtension { + err = nil + } if err != nil { return } @@ -292,7 +358,15 @@ } typ := reflect.TypeOf(extension.ExtensionType) if typ != reflect.TypeOf(value) { - return errors.New("bad extension value type") + return errors.New("proto: bad extension value type") + } + // nil extension values need to be caught early, because the + // encoder can't distinguish an ErrNil due to a nil extension + // from an ErrNil due to a missing field. Extensions are + // always optional, so the encoder would just swallow the error + // and drop all the extensions from the encoded message. + if reflect.ValueOf(value).IsNil() { + return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) } pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value} diff -Nru golang-goprotobuf-0.0~git20130901/proto/extensions_test.go golang-goprotobuf-0.0~git20150526/proto/extensions_test.go --- golang-goprotobuf-0.0~git20130901/proto/extensions_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/extensions_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -0,0 +1,292 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2014 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_test + +import ( + "fmt" + "reflect" + "testing" + + "github.com/golang/protobuf/proto" + pb "github.com/golang/protobuf/proto/testdata" +) + +func TestGetExtensionsWithMissingExtensions(t *testing.T) { + msg := &pb.MyMessage{} + ext1 := &pb.Ext{} + if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil { + t.Fatalf("Could not set ext1: %s", ext1) + } + exts, err := proto.GetExtensions(msg, []*proto.ExtensionDesc{ + pb.E_Ext_More, + pb.E_Ext_Text, + }) + if err != nil { + t.Fatalf("GetExtensions() failed: %s", err) + } + if exts[0] != ext1 { + t.Errorf("ext1 not in returned extensions: %T %v", exts[0], exts[0]) + } + if exts[1] != nil { + t.Errorf("ext2 in returned extensions: %T %v", exts[1], exts[1]) + } +} + +func TestGetExtensionStability(t *testing.T) { + check := func(m *pb.MyMessage) bool { + ext1, err := proto.GetExtension(m, pb.E_Ext_More) + if err != nil { + t.Fatalf("GetExtension() failed: %s", err) + } + ext2, err := proto.GetExtension(m, pb.E_Ext_More) + if err != nil { + t.Fatalf("GetExtension() failed: %s", err) + } + return ext1 == ext2 + } + msg := &pb.MyMessage{Count: proto.Int32(4)} + ext0 := &pb.Ext{} + if err := proto.SetExtension(msg, pb.E_Ext_More, ext0); err != nil { + t.Fatalf("Could not set ext1: %s", ext0) + } + if !check(msg) { + t.Errorf("GetExtension() not stable before marshaling") + } + bb, err := proto.Marshal(msg) + if err != nil { + t.Fatalf("Marshal() failed: %s", err) + } + msg1 := &pb.MyMessage{} + err = proto.Unmarshal(bb, msg1) + if err != nil { + t.Fatalf("Unmarshal() failed: %s", err) + } + if !check(msg1) { + t.Errorf("GetExtension() not stable after unmarshaling") + } +} + +func TestGetExtensionDefaults(t *testing.T) { + var setFloat64 float64 = 1 + var setFloat32 float32 = 2 + var setInt32 int32 = 3 + var setInt64 int64 = 4 + var setUint32 uint32 = 5 + var setUint64 uint64 = 6 + var setBool = true + var setBool2 = false + var setString = "Goodnight string" + var setBytes = []byte("Goodnight bytes") + var setEnum = pb.DefaultsMessage_TWO + + type testcase struct { + ext *proto.ExtensionDesc // Extension we are testing. + want interface{} // Expected value of extension, or nil (meaning that GetExtension will fail). + def interface{} // Expected value of extension after ClearExtension(). + } + tests := []testcase{ + {pb.E_NoDefaultDouble, setFloat64, nil}, + {pb.E_NoDefaultFloat, setFloat32, nil}, + {pb.E_NoDefaultInt32, setInt32, nil}, + {pb.E_NoDefaultInt64, setInt64, nil}, + {pb.E_NoDefaultUint32, setUint32, nil}, + {pb.E_NoDefaultUint64, setUint64, nil}, + {pb.E_NoDefaultSint32, setInt32, nil}, + {pb.E_NoDefaultSint64, setInt64, nil}, + {pb.E_NoDefaultFixed32, setUint32, nil}, + {pb.E_NoDefaultFixed64, setUint64, nil}, + {pb.E_NoDefaultSfixed32, setInt32, nil}, + {pb.E_NoDefaultSfixed64, setInt64, nil}, + {pb.E_NoDefaultBool, setBool, nil}, + {pb.E_NoDefaultBool, setBool2, nil}, + {pb.E_NoDefaultString, setString, nil}, + {pb.E_NoDefaultBytes, setBytes, nil}, + {pb.E_NoDefaultEnum, setEnum, nil}, + {pb.E_DefaultDouble, setFloat64, float64(3.1415)}, + {pb.E_DefaultFloat, setFloat32, float32(3.14)}, + {pb.E_DefaultInt32, setInt32, int32(42)}, + {pb.E_DefaultInt64, setInt64, int64(43)}, + {pb.E_DefaultUint32, setUint32, uint32(44)}, + {pb.E_DefaultUint64, setUint64, uint64(45)}, + {pb.E_DefaultSint32, setInt32, int32(46)}, + {pb.E_DefaultSint64, setInt64, int64(47)}, + {pb.E_DefaultFixed32, setUint32, uint32(48)}, + {pb.E_DefaultFixed64, setUint64, uint64(49)}, + {pb.E_DefaultSfixed32, setInt32, int32(50)}, + {pb.E_DefaultSfixed64, setInt64, int64(51)}, + {pb.E_DefaultBool, setBool, true}, + {pb.E_DefaultBool, setBool2, true}, + {pb.E_DefaultString, setString, "Hello, string"}, + {pb.E_DefaultBytes, setBytes, []byte("Hello, bytes")}, + {pb.E_DefaultEnum, setEnum, pb.DefaultsMessage_ONE}, + } + + checkVal := func(test testcase, msg *pb.DefaultsMessage, valWant interface{}) error { + val, err := proto.GetExtension(msg, test.ext) + if err != nil { + if valWant != nil { + return fmt.Errorf("GetExtension(): %s", err) + } + if want := proto.ErrMissingExtension; err != want { + return fmt.Errorf("Unexpected error: got %v, want %v", err, want) + } + return nil + } + + // All proto2 extension values are either a pointer to a value or a slice of values. + ty := reflect.TypeOf(val) + tyWant := reflect.TypeOf(test.ext.ExtensionType) + if got, want := ty, tyWant; got != want { + return fmt.Errorf("unexpected reflect.TypeOf(): got %v want %v", got, want) + } + tye := ty.Elem() + tyeWant := tyWant.Elem() + if got, want := tye, tyeWant; got != want { + return fmt.Errorf("unexpected reflect.TypeOf().Elem(): got %v want %v", got, want) + } + + // Check the name of the type of the value. + // If it is an enum it will be type int32 with the name of the enum. + if got, want := tye.Name(), tye.Name(); got != want { + return fmt.Errorf("unexpected reflect.TypeOf().Elem().Name(): got %v want %v", got, want) + } + + // Check that value is what we expect. + // If we have a pointer in val, get the value it points to. + valExp := val + if ty.Kind() == reflect.Ptr { + valExp = reflect.ValueOf(val).Elem().Interface() + } + if got, want := valExp, valWant; !reflect.DeepEqual(got, want) { + return fmt.Errorf("unexpected reflect.DeepEqual(): got %v want %v", got, want) + } + + return nil + } + + setTo := func(test testcase) interface{} { + setTo := reflect.ValueOf(test.want) + if typ := reflect.TypeOf(test.ext.ExtensionType); typ.Kind() == reflect.Ptr { + setTo = reflect.New(typ).Elem() + setTo.Set(reflect.New(setTo.Type().Elem())) + setTo.Elem().Set(reflect.ValueOf(test.want)) + } + return setTo.Interface() + } + + for _, test := range tests { + msg := &pb.DefaultsMessage{} + name := test.ext.Name + + // Check the initial value. + if err := checkVal(test, msg, test.def); err != nil { + t.Errorf("%s: %v", name, err) + } + + // Set the per-type value and check value. + name = fmt.Sprintf("%s (set to %T %v)", name, test.want, test.want) + if err := proto.SetExtension(msg, test.ext, setTo(test)); err != nil { + t.Errorf("%s: SetExtension(): %v", name, err) + continue + } + if err := checkVal(test, msg, test.want); err != nil { + t.Errorf("%s: %v", name, err) + continue + } + + // Set and check the value. + name += " (cleared)" + proto.ClearExtension(msg, test.ext) + if err := checkVal(test, msg, test.def); err != nil { + t.Errorf("%s: %v", name, err) + } + } +} + +func TestExtensionsRoundTrip(t *testing.T) { + msg := &pb.MyMessage{} + ext1 := &pb.Ext{ + Data: proto.String("hi"), + } + ext2 := &pb.Ext{ + Data: proto.String("there"), + } + exists := proto.HasExtension(msg, pb.E_Ext_More) + if exists { + t.Error("Extension More present unexpectedly") + } + if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil { + t.Error(err) + } + if err := proto.SetExtension(msg, pb.E_Ext_More, ext2); err != nil { + t.Error(err) + } + e, err := proto.GetExtension(msg, pb.E_Ext_More) + if err != nil { + t.Error(err) + } + x, ok := e.(*pb.Ext) + if !ok { + t.Errorf("e has type %T, expected testdata.Ext", e) + } else if *x.Data != "there" { + t.Errorf("SetExtension failed to overwrite, got %+v, not 'there'", x) + } + proto.ClearExtension(msg, pb.E_Ext_More) + if _, err = proto.GetExtension(msg, pb.E_Ext_More); err != proto.ErrMissingExtension { + t.Errorf("got %v, expected ErrMissingExtension", e) + } + if _, err := proto.GetExtension(msg, pb.E_X215); err == nil { + t.Error("expected bad extension error, got nil") + } + if err := proto.SetExtension(msg, pb.E_X215, 12); err == nil { + t.Error("expected extension err") + } + if err := proto.SetExtension(msg, pb.E_Ext_More, 12); err == nil { + t.Error("expected some sort of type mismatch error, got nil") + } +} + +func TestNilExtension(t *testing.T) { + msg := &pb.MyMessage{ + Count: proto.Int32(1), + } + if err := proto.SetExtension(msg, pb.E_Ext_Text, proto.String("hello")); err != nil { + t.Fatal(err) + } + if err := proto.SetExtension(msg, pb.E_Ext_More, (*pb.Ext)(nil)); err == nil { + t.Error("expected SetExtension to fail due to a nil extension") + } else if want := "proto: SetExtension called with nil value of type *testdata.Ext"; err.Error() != want { + t.Errorf("expected error %v, got %v", want, err) + } + // Note: if the behavior of Marshal is ever changed to ignore nil extensions, update + // this test to verify that E_Ext_Text is properly propagated through marshal->unmarshal. +} diff -Nru golang-goprotobuf-0.0~git20130901/proto/lib.go golang-goprotobuf-0.0~git20150526/proto/lib.go --- golang-goprotobuf-0.0~git20130901/proto/lib.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/lib.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -30,171 +30,179 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* - Package proto converts data structures to and from the wire format of - protocol buffers. It works in concert with the Go source code generated - for .proto files by the protocol compiler. - - A summary of the properties of the protocol buffer interface - for a protocol buffer variable v: - - - Names are turned from camel_case to CamelCase for export. - - There are no methods on v to set fields; just treat - them as structure fields. - - There are getters that return a field's value if set, - and return the field's default value if unset. - The getters work even if the receiver is a nil message. - - The zero value for a struct is its correct initialization state. - All desired fields must be set before marshaling. - - A Reset() method will restore a protobuf struct to its zero state. - - Non-repeated fields are pointers to the values; nil means unset. - That is, optional or required field int32 f becomes F *int32. - - Repeated fields are slices. - - Helper functions are available to aid the setting of fields. - Helpers for getting values are superseded by the - GetFoo methods and their use is deprecated. - msg.Foo = proto.String("hello") // set field - - Constants are defined to hold the default values of all fields that - have them. They have the form Default_StructName_FieldName. - Because the getter methods handle defaulted values, - direct use of these constants should be rare. - - Enums are given type names and maps from names to values. - Enum values are prefixed with the enum's type name. Enum types have - a String method, and a Enum method to assist in message construction. - - Nested groups and enums have type names prefixed with the name of - the surrounding message type. - - Extensions are given descriptor names that start with E_, - followed by an underscore-delimited list of the nested messages - that contain it (if any) followed by the CamelCased name of the - extension field itself. HasExtension, ClearExtension, GetExtension - and SetExtension are functions for manipulating extensions. - - Marshal and Unmarshal are functions to encode and decode the wire format. - - The simplest way to describe this is to see an example. - Given file test.proto, containing - - package example; - - enum FOO { X = 17; }; - - message Test { - required string label = 1; - optional int32 type = 2 [default=77]; - repeated int64 reps = 3; - optional group OptionalGroup = 4 { - required string RequiredField = 5; - } - } - - The resulting file, test.pb.go, is: - - package example - - import "code.google.com/p/goprotobuf/proto" - - type FOO int32 - const ( - FOO_X FOO = 17 - ) - var FOO_name = map[int32]string{ - 17: "X", - } - var FOO_value = map[string]int32{ - "X": 17, - } - - func (x FOO) Enum() *FOO { - p := new(FOO) - *p = x - return p - } - func (x FOO) String() string { - return proto.EnumName(FOO_name, int32(x)) +Package proto converts data structures to and from the wire format of +protocol buffers. It works in concert with the Go source code generated +for .proto files by the protocol compiler. + +A summary of the properties of the protocol buffer interface +for a protocol buffer variable v: + + - Names are turned from camel_case to CamelCase for export. + - There are no methods on v to set fields; just treat + them as structure fields. + - There are getters that return a field's value if set, + and return the field's default value if unset. + The getters work even if the receiver is a nil message. + - The zero value for a struct is its correct initialization state. + All desired fields must be set before marshaling. + - A Reset() method will restore a protobuf struct to its zero state. + - Non-repeated fields are pointers to the values; nil means unset. + That is, optional or required field int32 f becomes F *int32. + - Repeated fields are slices. + - Helper functions are available to aid the setting of fields. + msg.Foo = proto.String("hello") // set field + - Constants are defined to hold the default values of all fields that + have them. They have the form Default_StructName_FieldName. + Because the getter methods handle defaulted values, + direct use of these constants should be rare. + - Enums are given type names and maps from names to values. + Enum values are prefixed by the enclosing message's name, or by the + enum's type name if it is a top-level enum. Enum types have a String + method, and a Enum method to assist in message construction. + - Nested messages, groups and enums have type names prefixed with the name of + the surrounding message type. + - Extensions are given descriptor names that start with E_, + followed by an underscore-delimited list of the nested messages + that contain it (if any) followed by the CamelCased name of the + extension field itself. HasExtension, ClearExtension, GetExtension + and SetExtension are functions for manipulating extensions. + - Marshal and Unmarshal are functions to encode and decode the wire format. + +The simplest way to describe this is to see an example. +Given file test.proto, containing + + package example; + + enum FOO { X = 17; } + + message Test { + required string label = 1; + optional int32 type = 2 [default=77]; + repeated int64 reps = 3; + optional group OptionalGroup = 4 { + required string RequiredField = 5; + } + } + +The resulting file, test.pb.go, is: + + package example + + import proto "github.com/golang/protobuf/proto" + import math "math" + + type FOO int32 + const ( + FOO_X FOO = 17 + ) + var FOO_name = map[int32]string{ + 17: "X", + } + var FOO_value = map[string]int32{ + "X": 17, + } + + func (x FOO) Enum() *FOO { + p := new(FOO) + *p = x + return p + } + func (x FOO) String() string { + return proto.EnumName(FOO_name, int32(x)) + } + func (x *FOO) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FOO_value, data) + if err != nil { + return err } + *x = FOO(value) + return nil + } - type Test struct { - Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` - Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` - Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` - Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` - XXX_unrecognized []byte `json:"-"` - } - func (this *Test) Reset() { *this = Test{} } - func (this *Test) String() string { return proto.CompactTextString(this) } - const Default_Test_Type int32 = 77 + type Test struct { + Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` + Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` + Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` + Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` + XXX_unrecognized []byte `json:"-"` + } + func (m *Test) Reset() { *m = Test{} } + func (m *Test) String() string { return proto.CompactTextString(m) } + func (*Test) ProtoMessage() {} + const Default_Test_Type int32 = 77 - func (this *Test) GetLabel() string { - if this != nil && this.Label != nil { - return *this.Label - } - return "" + func (m *Test) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label } + return "" + } - func (this *Test) GetType() int32 { - if this != nil && this.Type != nil { - return *this.Type - } - return Default_Test_Type + func (m *Test) GetType() int32 { + if m != nil && m.Type != nil { + return *m.Type } + return Default_Test_Type + } - func (this *Test) GetOptionalgroup() *Test_OptionalGroup { - if this != nil { - return this.Optionalgroup - } - return nil + func (m *Test) GetOptionalgroup() *Test_OptionalGroup { + if m != nil { + return m.Optionalgroup } + return nil + } - type Test_OptionalGroup struct { - RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` - XXX_unrecognized []byte `json:"-"` - } - func (this *Test_OptionalGroup) Reset() { *this = Test_OptionalGroup{} } - func (this *Test_OptionalGroup) String() string { return proto.CompactTextString(this) } + type Test_OptionalGroup struct { + RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` + } + func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} } + func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) } - func (this *Test_OptionalGroup) GetRequiredField() string { - if this != nil && this.RequiredField != nil { - return *this.RequiredField - } - return "" + func (m *Test_OptionalGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField } + return "" + } - func init() { - proto.RegisterEnum("example.FOO", FOO_name, FOO_value) - } + func init() { + proto.RegisterEnum("example.FOO", FOO_name, FOO_value) + } - To create and play with a Test object: +To create and play with a Test object: - package main +package main - import ( - "log" + import ( + "log" - "code.google.com/p/goprotobuf/proto" - "./example.pb" - ) + "github.com/golang/protobuf/proto" + pb "./example.pb" + ) - func main() { - test := &example.Test{ - Label: proto.String("hello"), - Type: proto.Int32(17), - Optionalgroup: &example.Test_OptionalGroup{ - RequiredField: proto.String("good bye"), - }, - } - data, err := proto.Marshal(test) - if err != nil { - log.Fatal("marshaling error: ", err) - } - newTest := new(example.Test) - err = proto.Unmarshal(data, newTest) - if err != nil { - log.Fatal("unmarshaling error: ", err) - } - // Now test and newTest contain the same data. - if test.GetLabel() != newTest.GetLabel() { - log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) - } - // etc. + func main() { + test := &pb.Test{ + Label: proto.String("hello"), + Type: proto.Int32(17), + Optionalgroup: &pb.Test_OptionalGroup{ + RequiredField: proto.String("good bye"), + }, + } + data, err := proto.Marshal(test) + if err != nil { + log.Fatal("marshaling error: ", err) + } + newTest := &pb.Test{} + err = proto.Unmarshal(data, newTest) + if err != nil { + log.Fatal("unmarshaling error: ", err) + } + // Now test and newTest contain the same data. + if test.GetLabel() != newTest.GetLabel() { + log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) } + // etc. + } */ package proto @@ -223,6 +231,7 @@ Decode uint64 // number of decodes Chit uint64 // number of cache hits Cmiss uint64 // number of cache misses + Size uint64 // number of sizes } // Set to true to enable stats collection. @@ -239,10 +248,8 @@ // the global functions Marshal and Unmarshal create a // temporary Buffer and are fine for most applications. type Buffer struct { - buf []byte // encode/decode byte stream - index int // write point - freelist [10][]byte // list of available buffers - nfreelist int // number of free buffers + buf []byte // encode/decode byte stream + index int // write point // pools of basic types to amortize allocation. bools []bool @@ -259,20 +266,11 @@ // NewBuffer allocates a new Buffer and initializes its internal data to // the contents of the argument slice. func NewBuffer(e []byte) *Buffer { - p := new(Buffer) - if e == nil { - e = p.bufalloc() - } - p.buf = e - p.index = 0 - return p + return &Buffer{buf: e} } // Reset resets the Buffer, ready for marshaling a new protocol buffer. func (p *Buffer) Reset() { - if p.buf == nil { - p.buf = p.bufalloc() - } p.buf = p.buf[0:0] // for reading/writing p.index = 0 // for reading } @@ -287,44 +285,6 @@ // Bytes returns the contents of the Buffer. func (p *Buffer) Bytes() []byte { return p.buf } -// Allocate a buffer for the Buffer. -func (p *Buffer) bufalloc() []byte { - if p.nfreelist > 0 { - // reuse an old one - p.nfreelist-- - s := p.freelist[p.nfreelist] - return s[0:0] - } - // make a new one - s := make([]byte, 0, 16) - return s -} - -// Free (and remember in freelist) a byte buffer for the Buffer. -func (p *Buffer) buffree(s []byte) { - if p.nfreelist < len(p.freelist) { - // Take next slot. - p.freelist[p.nfreelist] = s - p.nfreelist++ - return - } - - // Find the smallest. - besti := -1 - bestl := len(s) - for i, b := range p.freelist { - if len(b) < bestl { - besti = i - bestl = len(b) - } - } - - // Overwrite the smallest. - if besti >= 0 { - p.freelist[besti] = s - } -} - /* * Helper routines for simplifying the creation of optional fields of basic type. */ @@ -371,9 +331,7 @@ // Uint32 is a helper routine that allocates a new uint32 value // to store v and returns a pointer to it. func Uint32(v uint32) *uint32 { - p := new(uint32) - *p = v - return p + return &v } // Uint64 is a helper routine that allocates a new uint64 value @@ -403,9 +361,7 @@ // names to its int values, and a byte buffer containing the JSON-encoded // value, it returns an int32 that can be cast to the enum type by the caller. // -// The function can deal with older JSON representations, which represented -// enums directly by their int32 values, or with newer representations, which -// use the symbolic name as a string. +// The function can deal with both JSON representations, numeric and symbolic. func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { if data[0] == '"' { // New style: enums are strings. @@ -429,13 +385,13 @@ // DebugPrint dumps the encoded data in b in a debugging format with a header // including the string s. Used in testing but made available for general debugging. -func (o *Buffer) DebugPrint(s string, b []byte) { +func (p *Buffer) DebugPrint(s string, b []byte) { var u uint64 - obuf := o.buf - index := o.index - o.buf = b - o.index = 0 + obuf := p.buf + index := p.index + p.buf = b + p.index = 0 depth := 0 fmt.Printf("\n--- %s ---\n", s) @@ -446,12 +402,12 @@ fmt.Print(" ") } - index := o.index - if index == len(o.buf) { + index := p.index + if index == len(p.buf) { break } - op, err := o.DecodeVarint() + op, err := p.DecodeVarint() if err != nil { fmt.Printf("%3d: fetching op err %v\n", index, err) break out @@ -468,7 +424,7 @@ case WireBytes: var r []byte - r, err = o.DecodeRawBytes(false) + r, err = p.DecodeRawBytes(false) if err != nil { break out } @@ -489,7 +445,7 @@ fmt.Printf("\n") case WireFixed32: - u, err = o.DecodeFixed32() + u, err = p.DecodeFixed32() if err != nil { fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err) break out @@ -497,7 +453,7 @@ fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u) case WireFixed64: - u, err = o.DecodeFixed64() + u, err = p.DecodeFixed64() if err != nil { fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err) break out @@ -506,7 +462,7 @@ break case WireVarint: - u, err = o.DecodeVarint() + u, err = p.DecodeVarint() if err != nil { fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err) break out @@ -532,12 +488,12 @@ } if depth != 0 { - fmt.Printf("%3d: start-end not balanced %d\n", o.index, depth) + fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth) } fmt.Printf("\n") - o.buf = obuf - o.index = index + p.buf = obuf + p.index = index } // SetDefaults sets unset protocol buffer fields to their default values. @@ -651,13 +607,15 @@ for _, ni := range dm.nested { f := v.Field(ni) - if f.IsNil() { - continue - } - // f is *T or []*T - if f.Kind() == reflect.Ptr { + // f is *T or []*T or map[T]*T + switch f.Kind() { + case reflect.Ptr: + if f.IsNil() { + continue + } setDefaults(f, recur, zeros) - } else { + + case reflect.Slice: for i := 0; i < f.Len(); i++ { e := f.Index(i) if e.IsNil() { @@ -665,6 +623,15 @@ } setDefaults(e, recur, zeros) } + + case reflect.Map: + for _, k := range f.MapKeys() { + e := f.MapIndex(k) + if e.IsNil() { + continue + } + setDefaults(e, recur, zeros) + } } } } @@ -690,10 +657,6 @@ value interface{} // the proto-declared default value, or nil } -func ptrToStruct(t reflect.Type) bool { - return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct -} - // t is a struct type. func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { sprop := GetProperties(t) @@ -705,86 +668,129 @@ } ft := t.Field(fi).Type - // nested messages - if ptrToStruct(ft) || (ft.Kind() == reflect.Slice && ptrToStruct(ft.Elem())) { + sf, nested, err := fieldDefault(ft, prop) + switch { + case err != nil: + log.Print(err) + case nested: dm.nested = append(dm.nested, fi) - continue + case sf != nil: + sf.index = fi + dm.scalars = append(dm.scalars, *sf) } + } - sf := scalarField{ - index: fi, - kind: ft.Elem().Kind(), - } + return dm +} - // scalar fields without defaults - if prop.Default == "" { - dm.scalars = append(dm.scalars, sf) - continue +// fieldDefault returns the scalarField for field type ft. +// sf will be nil if the field can not have a default. +// nestedMessage will be true if this is a nested message. +// Note that sf.index is not set on return. +func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) { + var canHaveDefault bool + switch ft.Kind() { + case reflect.Ptr: + if ft.Elem().Kind() == reflect.Struct { + nestedMessage = true + } else { + canHaveDefault = true // proto2 scalar field } - // a scalar field: either *T or []byte + case reflect.Slice: switch ft.Elem().Kind() { - case reflect.Bool: - x, err := strconv.ParseBool(prop.Default) - if err != nil { - log.Printf("proto: bad default bool %q: %v", prop.Default, err) - continue - } - sf.value = x - case reflect.Float32: - x, err := strconv.ParseFloat(prop.Default, 32) - if err != nil { - log.Printf("proto: bad default float32 %q: %v", prop.Default, err) - continue - } - sf.value = float32(x) - case reflect.Float64: - x, err := strconv.ParseFloat(prop.Default, 64) - if err != nil { - log.Printf("proto: bad default float64 %q: %v", prop.Default, err) - continue - } - sf.value = x - case reflect.Int32: - x, err := strconv.ParseInt(prop.Default, 10, 32) - if err != nil { - log.Printf("proto: bad default int32 %q: %v", prop.Default, err) - continue - } - sf.value = int32(x) - case reflect.Int64: - x, err := strconv.ParseInt(prop.Default, 10, 64) - if err != nil { - log.Printf("proto: bad default int64 %q: %v", prop.Default, err) - continue - } - sf.value = x - case reflect.String: - sf.value = prop.Default + case reflect.Ptr: + nestedMessage = true // repeated message case reflect.Uint8: - // []byte (not *uint8) - sf.value = []byte(prop.Default) - case reflect.Uint32: - x, err := strconv.ParseUint(prop.Default, 10, 32) - if err != nil { - log.Printf("proto: bad default uint32 %q: %v", prop.Default, err) - continue - } - sf.value = uint32(x) - case reflect.Uint64: - x, err := strconv.ParseUint(prop.Default, 10, 64) - if err != nil { - log.Printf("proto: bad default uint64 %q: %v", prop.Default, err) - continue - } - sf.value = x - default: - log.Printf("proto: unhandled def kind %v", ft.Elem().Kind()) - continue + canHaveDefault = true // bytes field } - dm.scalars = append(dm.scalars, sf) + case reflect.Map: + if ft.Elem().Kind() == reflect.Ptr { + nestedMessage = true // map with message values + } } - return dm + if !canHaveDefault { + if nestedMessage { + return nil, true, nil + } + return nil, false, nil + } + + // We now know that ft is a pointer or slice. + sf = &scalarField{kind: ft.Elem().Kind()} + + // scalar fields without defaults + if !prop.HasDefault { + return sf, false, nil + } + + // a scalar field: either *T or []byte + switch ft.Elem().Kind() { + case reflect.Bool: + x, err := strconv.ParseBool(prop.Default) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Float32: + x, err := strconv.ParseFloat(prop.Default, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err) + } + sf.value = float32(x) + case reflect.Float64: + x, err := strconv.ParseFloat(prop.Default, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Int32: + x, err := strconv.ParseInt(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err) + } + sf.value = int32(x) + case reflect.Int64: + x, err := strconv.ParseInt(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.String: + sf.value = prop.Default + case reflect.Uint8: + // []byte (not *uint8) + sf.value = []byte(prop.Default) + case reflect.Uint32: + x, err := strconv.ParseUint(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err) + } + sf.value = uint32(x) + case reflect.Uint64: + x, err := strconv.ParseUint(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err) + } + sf.value = x + default: + return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind()) + } + + return sf, false, nil +} + +// Map fields may have key types of non-float scalars, strings and enums. +// The easiest way to sort them in some deterministic order is to use fmt. +// If this turns out to be inefficient we can always consider other options, +// such as doing a Schwartzian transform. + +type mapKeys []reflect.Value + +func (s mapKeys) Len() int { return len(s) } +func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s mapKeys) Less(i, j int) bool { + return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface()) } diff -Nru golang-goprotobuf-0.0~git20130901/proto/Makefile golang-goprotobuf-0.0~git20150526/proto/Makefile --- golang-goprotobuf-0.0~git20130901/proto/Makefile 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/Makefile 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ # Go support for Protocol Buffers - Google's data interchange format # # Copyright 2010 The Go Authors. All rights reserved. -# http://code.google.com/p/goprotobuf/ +# 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 @@ -37,4 +37,7 @@ generate-test-pbs: - make install && cd testdata && make + make install + make -C testdata + protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto + make diff -Nru golang-goprotobuf-0.0~git20130901/proto/message_set.go golang-goprotobuf-0.0~git20150526/proto/message_set.go --- golang-goprotobuf-0.0~git20130901/proto/message_set.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/message_set.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -36,7 +36,10 @@ */ import ( + "bytes" + "encoding/json" "errors" + "fmt" "reflect" "sort" ) @@ -127,7 +130,7 @@ mti, ok := pb.(messageTypeIder) if !ok { - return ErrWrongType // TODO: custom error? + return ErrNoMessageTypeId } mtid := mti.MessageTypeId() @@ -188,16 +191,84 @@ return err } for _, item := range ms.Item { - // restore wire type and field number varint, plus length varint. - b := EncodeVarint(uint64(*item.TypeId)<<3 | WireBytes) - b = append(b, EncodeVarint(uint64(len(item.Message)))...) - b = append(b, item.Message...) + id := *item.TypeId + msg := item.Message + + // Restore wire type and field number varint, plus length varint. + // Be careful to preserve duplicate items. + b := EncodeVarint(uint64(id)<<3 | WireBytes) + if ext, ok := m[id]; ok { + // Existing data; rip off the tag and length varint + // so we join the new data correctly. + // We can assume that ext.enc is set because we are unmarshaling. + o := ext.enc[len(b):] // skip wire type and field number + _, n := DecodeVarint(o) // calculate length of length varint + o = o[n:] // skip length varint + msg = append(o, msg...) // join old data and new data + } + b = append(b, EncodeVarint(uint64(len(msg)))...) + b = append(b, msg...) - m[*item.TypeId] = Extension{enc: b} + m[id] = Extension{enc: b} } return nil } +// MarshalMessageSetJSON encodes the extension map represented by m in JSON format. +// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option. +func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) { + var b bytes.Buffer + b.WriteByte('{') + + // Process the map in key order for deterministic output. + ids := make([]int32, 0, len(m)) + for id := range m { + ids = append(ids, id) + } + sort.Sort(int32Slice(ids)) // int32Slice defined in text.go + + for i, id := range ids { + ext := m[id] + if i > 0 { + b.WriteByte(',') + } + + msd, ok := messageSetMap[id] + if !ok { + // Unknown type; we can't render it, so skip it. + continue + } + fmt.Fprintf(&b, `"[%s]":`, msd.name) + + x := ext.value + if x == nil { + x = reflect.New(msd.t.Elem()).Interface() + if err := Unmarshal(ext.enc, x.(Message)); err != nil { + return nil, err + } + } + d, err := json.Marshal(x) + if err != nil { + return nil, err + } + b.Write(d) + } + b.WriteByte('}') + return b.Bytes(), nil +} + +// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format. +// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option. +func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error { + // Common-case fast path. + if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) { + return nil + } + + // This is fairly tricky, and it's not clear that it is needed. + return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented") +} + // A global registry of types that can be used in a MessageSet. var messageSetMap = make(map[int32]messageSetDesc) @@ -208,9 +279,9 @@ } // RegisterMessageSetType is called from the generated code. -func RegisterMessageSetType(i messageTypeIder, name string) { - messageSetMap[i.MessageTypeId()] = messageSetDesc{ - t: reflect.TypeOf(i), +func RegisterMessageSetType(m Message, fieldNum int32, name string) { + messageSetMap[fieldNum] = messageSetDesc{ + t: reflect.TypeOf(m), name: name, } } diff -Nru golang-goprotobuf-0.0~git20130901/proto/message_set_test.go golang-goprotobuf-0.0~git20150526/proto/message_set_test.go --- golang-goprotobuf-0.0~git20130901/proto/message_set_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/message_set_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -0,0 +1,66 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2014 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 + +import ( + "bytes" + "testing" +) + +func TestUnmarshalMessageSetWithDuplicate(t *testing.T) { + // Check that a repeated message set entry will be concatenated. + in := &MessageSet{ + Item: []*_MessageSet_Item{ + {TypeId: Int32(12345), Message: []byte("hoo")}, + {TypeId: Int32(12345), Message: []byte("hah")}, + }, + } + b, err := Marshal(in) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + t.Logf("Marshaled bytes: %q", b) + + m := make(map[int32]Extension) + if err := UnmarshalMessageSet(b, m); err != nil { + t.Fatalf("UnmarshalMessageSet: %v", err) + } + ext, ok := m[12345] + if !ok { + t.Fatalf("Didn't retrieve extension 12345; map is %v", m) + } + // Skip wire type/field number and length varints. + got := skipVarint(skipVarint(ext.enc)) + if want := []byte("hoohah"); !bytes.Equal(got, want) { + t.Errorf("Combined extension is %q, want %q", got, want) + } +} diff -Nru golang-goprotobuf-0.0~git20130901/proto/pointer_reflect.go golang-goprotobuf-0.0~git20150526/proto/pointer_reflect.go --- golang-goprotobuf-0.0~git20130901/proto/pointer_reflect.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/pointer_reflect.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2012 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -114,6 +114,11 @@ return structPointer_ifield(p, f).(**bool) } +// BoolVal returns the address of a bool field in the struct. +func structPointer_BoolVal(p structPointer, f field) *bool { + return structPointer_ifield(p, f).(*bool) +} + // BoolSlice returns the address of a []bool field in the struct. func structPointer_BoolSlice(p structPointer, f field) *[]bool { return structPointer_ifield(p, f).(*[]bool) @@ -124,6 +129,11 @@ return structPointer_ifield(p, f).(**string) } +// StringVal returns the address of a string field in the struct. +func structPointer_StringVal(p structPointer, f field) *string { + return structPointer_ifield(p, f).(*string) +} + // StringSlice returns the address of a []string field in the struct. func structPointer_StringSlice(p structPointer, f field) *[]string { return structPointer_ifield(p, f).(*[]string) @@ -134,6 +144,11 @@ return structPointer_ifield(p, f).(*map[int32]Extension) } +// Map returns the reflect.Value for the address of a map field in the struct. +func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value { + return structPointer_field(p, f).Addr() +} + // SetStructPointer writes a *struct field in the struct. func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { structPointer_field(p, f).Set(q.v) @@ -235,6 +250,49 @@ return word32{structPointer_field(p, f)} } +// A word32Val represents a field of type int32, uint32, float32, or enum. +// That is, v.Type() is int32, uint32, float32, or enum and v is assignable. +type word32Val struct { + v reflect.Value +} + +// Set sets *p to x. +func word32Val_Set(p word32Val, x uint32) { + switch p.v.Type() { + case int32Type: + p.v.SetInt(int64(x)) + return + case uint32Type: + p.v.SetUint(uint64(x)) + return + case float32Type: + p.v.SetFloat(float64(math.Float32frombits(x))) + return + } + + // must be enum + p.v.SetInt(int64(int32(x))) +} + +// Get gets the bits pointed at by p, as a uint32. +func word32Val_Get(p word32Val) uint32 { + elem := p.v + switch elem.Kind() { + case reflect.Int32: + return uint32(elem.Int()) + case reflect.Uint32: + return uint32(elem.Uint()) + case reflect.Float32: + return math.Float32bits(float32(elem.Float())) + } + panic("unreachable") +} + +// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct. +func structPointer_Word32Val(p structPointer, f field) word32Val { + return word32Val{structPointer_field(p, f)} +} + // A word32Slice is a slice of 32-bit values. // That is, v.Type() is []int32, []uint32, []float32, or []enum. type word32Slice struct { @@ -339,6 +397,43 @@ return word64{structPointer_field(p, f)} } +// word64Val is like word32Val but for 64-bit values. +type word64Val struct { + v reflect.Value +} + +func word64Val_Set(p word64Val, o *Buffer, x uint64) { + switch p.v.Type() { + case int64Type: + p.v.SetInt(int64(x)) + return + case uint64Type: + p.v.SetUint(x) + return + case float64Type: + p.v.SetFloat(math.Float64frombits(x)) + return + } + panic("unreachable") +} + +func word64Val_Get(p word64Val) uint64 { + elem := p.v + switch elem.Kind() { + case reflect.Int64: + return uint64(elem.Int()) + case reflect.Uint64: + return elem.Uint() + case reflect.Float64: + return math.Float64bits(elem.Float()) + } + panic("unreachable") +} + +func structPointer_Word64Val(p structPointer, f field) word64Val { + return word64Val{structPointer_field(p, f)} +} + type word64Slice struct { v reflect.Value } diff -Nru golang-goprotobuf-0.0~git20130901/proto/pointer_unsafe.go golang-goprotobuf-0.0~git20150526/proto/pointer_unsafe.go --- golang-goprotobuf-0.0~git20130901/proto/pointer_unsafe.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/pointer_unsafe.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2012 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -100,6 +100,11 @@ return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) } +// BoolVal returns the address of a bool field in the struct. +func structPointer_BoolVal(p structPointer, f field) *bool { + return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + // BoolSlice returns the address of a []bool field in the struct. func structPointer_BoolSlice(p structPointer, f field) *[]bool { return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) @@ -110,6 +115,11 @@ return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f))) } +// StringVal returns the address of a string field in the struct. +func structPointer_StringVal(p structPointer, f field) *string { + return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + // StringSlice returns the address of a []string field in the struct. func structPointer_StringSlice(p structPointer, f field) *[]string { return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f))) @@ -120,6 +130,11 @@ return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f))) } +// Map returns the reflect.Value for the address of a map field in the struct. +func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value { + return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f))) +} + // SetStructPointer writes a *struct field in the struct. func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q @@ -170,6 +185,24 @@ return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f)))) } +// A word32Val is the address of a 32-bit value field. +type word32Val *uint32 + +// Set sets *p to x. +func word32Val_Set(p word32Val, x uint32) { + *p = x +} + +// Get gets the value pointed at by p. +func word32Val_Get(p word32Val) uint32 { + return *p +} + +// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct. +func structPointer_Word32Val(p structPointer, f field) word32Val { + return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f)))) +} + // A word32Slice is a slice of 32-bit values. type word32Slice []uint32 @@ -206,6 +239,21 @@ return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f)))) } +// word64Val is like word32Val but for 64-bit values. +type word64Val *uint64 + +func word64Val_Set(p word64Val, o *Buffer, x uint64) { + *p = x +} + +func word64Val_Get(p word64Val) uint64 { + return *p +} + +func structPointer_Word64Val(p structPointer, f field) word64Val { + return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f)))) +} + // word64Slice is like word32Slice but for 64-bit values. type word64Slice []uint64 diff -Nru golang-goprotobuf-0.0~git20130901/proto/properties.go golang-goprotobuf-0.0~git20150526/proto/properties.go --- golang-goprotobuf-0.0~git20130901/proto/properties.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/properties.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -59,7 +59,7 @@ const startSize = 10 // initial slice/string sizes -// Encoders are defined in encoder.go +// Encoders are defined in encode.go // An encoder outputs the full representation of a field, including its // tag and encoder type. type encoder func(p *Buffer, prop *Properties, base structPointer) error @@ -67,6 +67,15 @@ // A valueEncoder encodes a single integer in a particular encoding. type valueEncoder func(o *Buffer, x uint64) error +// Sizers are defined in encode.go +// A sizer returns the encoded size of a field, including its tag and encoder +// type. +type sizer func(prop *Properties, base structPointer) int + +// A valueSizer returns the encoded size of a single integer in a particular +// encoding. +type valueSizer func(x uint64) int + // Decoders are defined in decode.go // A decoder creates a value from its wire representation. // Unrecognized subelements are saved in unrec. @@ -126,7 +135,7 @@ } // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. -// See encoder.go, (*Buffer).enc_struct. +// See encode.go, (*Buffer).enc_struct. func (sp *StructProperties) Len() int { return len(sp.order) } func (sp *StructProperties) Less(i, j int) bool { @@ -136,17 +145,20 @@ // Properties represents the protocol-specific behavior of a single struct field. type Properties struct { - Name string // name of the field, for error messages - OrigName string // original name before protocol compiler (always set) - Wire string - WireType int - Tag int - Required bool - Optional bool - Repeated bool - Packed bool // relevant for repeated primitives only - Enum string // set for enum types only + Name string // name of the field, for error messages + OrigName string // original name before protocol compiler (always set) + Wire string + WireType int + Tag int + Required bool + Optional bool + Repeated bool + Packed bool // relevant for repeated primitives only + Enum string // set for enum types only + proto3 bool // whether this is known to be a proto3 field; set for []byte only + Default string // default value + HasDefault bool // whether an explicit default was provided def_uint64 uint64 enc encoder @@ -159,6 +171,13 @@ isMarshaler bool isUnmarshaler bool + mtype reflect.Type // set for map types only + mkeyprop *Properties // set for map types only + mvalprop *Properties // set for map types only + + size sizer + valSize valueSizer // set for bool and numeric types only + dec decoder valDec valueDecoder // set for bool and numeric types only @@ -186,10 +205,13 @@ if p.OrigName != p.Name { s += ",name=" + p.OrigName } + if p.proto3 { + s += ",proto3" + } if len(p.Enum) > 0 { s += ",enum=" + p.Enum } - if len(p.Default) > 0 { + if p.HasDefault { s += ",def=" + p.Default } return s @@ -210,22 +232,27 @@ p.WireType = WireVarint p.valEnc = (*Buffer).EncodeVarint p.valDec = (*Buffer).DecodeVarint + p.valSize = sizeVarint case "fixed32": p.WireType = WireFixed32 p.valEnc = (*Buffer).EncodeFixed32 p.valDec = (*Buffer).DecodeFixed32 + p.valSize = sizeFixed32 case "fixed64": p.WireType = WireFixed64 p.valEnc = (*Buffer).EncodeFixed64 p.valDec = (*Buffer).DecodeFixed64 + p.valSize = sizeFixed64 case "zigzag32": p.WireType = WireVarint p.valEnc = (*Buffer).EncodeZigzag32 p.valDec = (*Buffer).DecodeZigzag32 + p.valSize = sizeZigzag32 case "zigzag64": p.WireType = WireVarint p.valEnc = (*Buffer).EncodeZigzag64 p.valDec = (*Buffer).DecodeZigzag64 + p.valSize = sizeZigzag64 case "bytes", "group": p.WireType = WireBytes // no numeric converter for non-numeric types @@ -255,7 +282,10 @@ p.OrigName = f[5:] case strings.HasPrefix(f, "enum="): p.Enum = f[5:] + case f == "proto3": + p.proto3 = true case strings.HasPrefix(f, "def="): + p.HasDefault = true p.Default = f[4:] // rest of string if i+1 < len(fields) { // Commas aren't escaped, and def is always last. @@ -273,37 +303,79 @@ var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() // Initialize the fields for encoding and decoding. -func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) { +func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { p.enc = nil p.dec = nil + p.size = nil switch t1 := typ; t1.Kind() { default: - fmt.Fprintf(os.Stderr, "proto: no coders for %T\n", t1) + fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1) + + // proto3 scalar types + + case reflect.Bool: + p.enc = (*Buffer).enc_proto3_bool + p.dec = (*Buffer).dec_proto3_bool + p.size = size_proto3_bool + case reflect.Int32: + p.enc = (*Buffer).enc_proto3_int32 + p.dec = (*Buffer).dec_proto3_int32 + p.size = size_proto3_int32 + case reflect.Uint32: + p.enc = (*Buffer).enc_proto3_uint32 + p.dec = (*Buffer).dec_proto3_int32 // can reuse + p.size = size_proto3_uint32 + case reflect.Int64, reflect.Uint64: + p.enc = (*Buffer).enc_proto3_int64 + p.dec = (*Buffer).dec_proto3_int64 + p.size = size_proto3_int64 + case reflect.Float32: + p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits + p.dec = (*Buffer).dec_proto3_int32 + p.size = size_proto3_uint32 + case reflect.Float64: + p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits + p.dec = (*Buffer).dec_proto3_int64 + p.size = size_proto3_int64 + case reflect.String: + p.enc = (*Buffer).enc_proto3_string + p.dec = (*Buffer).dec_proto3_string + p.size = size_proto3_string case reflect.Ptr: switch t2 := t1.Elem(); t2.Kind() { default: - fmt.Fprintf(os.Stderr, "proto: no encoder function for %T -> %T\n", t1, t2) + fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2) break case reflect.Bool: p.enc = (*Buffer).enc_bool p.dec = (*Buffer).dec_bool - case reflect.Int32, reflect.Uint32: + p.size = size_bool + case reflect.Int32: p.enc = (*Buffer).enc_int32 p.dec = (*Buffer).dec_int32 + p.size = size_int32 + case reflect.Uint32: + p.enc = (*Buffer).enc_uint32 + p.dec = (*Buffer).dec_int32 // can reuse + p.size = size_uint32 case reflect.Int64, reflect.Uint64: p.enc = (*Buffer).enc_int64 p.dec = (*Buffer).dec_int64 + p.size = size_int64 case reflect.Float32: - p.enc = (*Buffer).enc_int32 // can just treat them as bits + p.enc = (*Buffer).enc_uint32 // can just treat them as bits p.dec = (*Buffer).dec_int32 + p.size = size_uint32 case reflect.Float64: p.enc = (*Buffer).enc_int64 // can just treat them as bits p.dec = (*Buffer).dec_int64 + p.size = size_int64 case reflect.String: p.enc = (*Buffer).enc_string p.dec = (*Buffer).dec_string + p.size = size_string case reflect.Struct: p.stype = t1.Elem() p.isMarshaler = isMarshaler(t1) @@ -311,9 +383,11 @@ if p.Wire == "bytes" { p.enc = (*Buffer).enc_struct_message p.dec = (*Buffer).dec_struct_message + p.size = size_struct_message } else { p.enc = (*Buffer).enc_struct_group p.dec = (*Buffer).dec_struct_group + p.size = size_struct_group } } @@ -325,46 +399,66 @@ case reflect.Bool: if p.Packed { p.enc = (*Buffer).enc_slice_packed_bool + p.size = size_slice_packed_bool } else { p.enc = (*Buffer).enc_slice_bool + p.size = size_slice_bool } p.dec = (*Buffer).dec_slice_bool p.packedDec = (*Buffer).dec_slice_packed_bool - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - switch t2.Bits() { - case 32: - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_int32 - } else { - p.enc = (*Buffer).enc_slice_int32 - } - p.dec = (*Buffer).dec_slice_int32 - p.packedDec = (*Buffer).dec_slice_packed_int32 - case 64: - if p.Packed { - p.enc = (*Buffer).enc_slice_packed_int64 - } else { - p.enc = (*Buffer).enc_slice_int64 - } - p.dec = (*Buffer).dec_slice_int64 - p.packedDec = (*Buffer).dec_slice_packed_int64 - case 8: - if t2.Kind() == reflect.Uint8 { - p.enc = (*Buffer).enc_slice_byte - p.dec = (*Buffer).dec_slice_byte - } - default: - logNoSliceEnc(t1, t2) - break + case reflect.Int32: + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_int32 + p.size = size_slice_packed_int32 + } else { + p.enc = (*Buffer).enc_slice_int32 + p.size = size_slice_int32 + } + p.dec = (*Buffer).dec_slice_int32 + p.packedDec = (*Buffer).dec_slice_packed_int32 + case reflect.Uint32: + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_uint32 + p.size = size_slice_packed_uint32 + } else { + p.enc = (*Buffer).enc_slice_uint32 + p.size = size_slice_uint32 + } + p.dec = (*Buffer).dec_slice_int32 + p.packedDec = (*Buffer).dec_slice_packed_int32 + case reflect.Int64, reflect.Uint64: + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_int64 + p.size = size_slice_packed_int64 + } else { + p.enc = (*Buffer).enc_slice_int64 + p.size = size_slice_int64 + } + p.dec = (*Buffer).dec_slice_int64 + p.packedDec = (*Buffer).dec_slice_packed_int64 + case reflect.Uint8: + p.enc = (*Buffer).enc_slice_byte + p.dec = (*Buffer).dec_slice_byte + p.size = size_slice_byte + // This is a []byte, which is either a bytes field, + // or the value of a map field. In the latter case, + // we always encode an empty []byte, so we should not + // use the proto3 enc/size funcs. + // f == nil iff this is the key/value of a map field. + if p.proto3 && f != nil { + p.enc = (*Buffer).enc_proto3_slice_byte + p.size = size_proto3_slice_byte } case reflect.Float32, reflect.Float64: switch t2.Bits() { case 32: // can just treat them as bits if p.Packed { - p.enc = (*Buffer).enc_slice_packed_int32 + p.enc = (*Buffer).enc_slice_packed_uint32 + p.size = size_slice_packed_uint32 } else { - p.enc = (*Buffer).enc_slice_int32 + p.enc = (*Buffer).enc_slice_uint32 + p.size = size_slice_uint32 } p.dec = (*Buffer).dec_slice_int32 p.packedDec = (*Buffer).dec_slice_packed_int32 @@ -372,8 +466,10 @@ // can just treat them as bits if p.Packed { p.enc = (*Buffer).enc_slice_packed_int64 + p.size = size_slice_packed_int64 } else { p.enc = (*Buffer).enc_slice_int64 + p.size = size_slice_int64 } p.dec = (*Buffer).dec_slice_int64 p.packedDec = (*Buffer).dec_slice_packed_int64 @@ -384,6 +480,7 @@ case reflect.String: p.enc = (*Buffer).enc_slice_string p.dec = (*Buffer).dec_slice_string + p.size = size_slice_string case reflect.Ptr: switch t3 := t2.Elem(); t3.Kind() { default: @@ -393,11 +490,14 @@ p.stype = t2.Elem() p.isMarshaler = isMarshaler(t2) p.isUnmarshaler = isUnmarshaler(t2) - p.enc = (*Buffer).enc_slice_struct_group - p.dec = (*Buffer).dec_slice_struct_group if p.Wire == "bytes" { p.enc = (*Buffer).enc_slice_struct_message p.dec = (*Buffer).dec_slice_struct_message + p.size = size_slice_struct_message + } else { + p.enc = (*Buffer).enc_slice_struct_group + p.dec = (*Buffer).dec_slice_struct_group + p.size = size_slice_struct_group } } case reflect.Slice: @@ -408,8 +508,26 @@ case reflect.Uint8: p.enc = (*Buffer).enc_slice_slice_byte p.dec = (*Buffer).dec_slice_slice_byte + p.size = size_slice_slice_byte } } + + case reflect.Map: + p.enc = (*Buffer).enc_new_map + p.dec = (*Buffer).dec_new_map + p.size = size_new_map + + p.mtype = t1 + p.mkeyprop = &Properties{} + p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) + p.mvalprop = &Properties{} + vtype := p.mtype.Elem() + if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { + // The value type is not a message (*T) or bytes ([]byte), + // so we need encoders for the pointer to this type. + vtype = reflect.PtrTo(vtype) + } + p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) } // precalculate tag code @@ -478,23 +596,40 @@ return } p.Parse(tag) - p.setEncAndDec(typ, lockGetProp) + p.setEncAndDec(typ, f, lockGetProp) } var ( - mutex sync.Mutex + propertiesMu sync.RWMutex propertiesMap = make(map[reflect.Type]*StructProperties) ) // GetProperties returns the list of properties for the type represented by t. +// t must represent a generated struct type of a protocol message. func GetProperties(t reflect.Type) *StructProperties { - mutex.Lock() - sprop := getPropertiesLocked(t) - mutex.Unlock() + if t.Kind() != reflect.Struct { + panic("proto: type must have kind struct") + } + + // Most calls to GetProperties in a long-running program will be + // retrieving details for types we have seen before. + propertiesMu.RLock() + sprop, ok := propertiesMap[t] + propertiesMu.RUnlock() + if ok { + if collectStats { + stats.Chit++ + } + return sprop + } + + propertiesMu.Lock() + sprop = getPropertiesLocked(t) + propertiesMu.Unlock() return sprop } -// getPropertiesLocked requires that mutex is held. +// getPropertiesLocked requires that propertiesMu is held. func getPropertiesLocked(t reflect.Type) *StructProperties { if prop, ok := propertiesMap[t]; ok { if collectStats { @@ -525,6 +660,7 @@ if f.Name == "XXX_extensions" { // special case p.enc = (*Buffer).enc_map p.dec = nil // not needed + p.size = size_map } if f.Name == "XXX_unrecognized" { // special case prop.unrecField = toField(&f) diff -Nru golang-goprotobuf-0.0~git20130901/proto/proto3_proto/proto3.pb.go golang-goprotobuf-0.0~git20150526/proto/proto3_proto/proto3.pb.go --- golang-goprotobuf-0.0~git20130901/proto/proto3_proto/proto3.pb.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/proto3_proto/proto3.pb.go 2015-06-13 14:23:31.000000000 +0000 @@ -0,0 +1,122 @@ +// Code generated by protoc-gen-go. +// source: proto3_proto/proto3.proto +// DO NOT EDIT! + +/* +Package proto3_proto is a generated protocol buffer package. + +It is generated from these files: + proto3_proto/proto3.proto + +It has these top-level messages: + Message + Nested + MessageWithMap +*/ +package proto3_proto + +import proto "github.com/golang/protobuf/proto" +import testdata "github.com/golang/protobuf/proto/testdata" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal + +type Message_Humour int32 + +const ( + Message_UNKNOWN Message_Humour = 0 + Message_PUNS Message_Humour = 1 + Message_SLAPSTICK Message_Humour = 2 + Message_BILL_BAILEY Message_Humour = 3 +) + +var Message_Humour_name = map[int32]string{ + 0: "UNKNOWN", + 1: "PUNS", + 2: "SLAPSTICK", + 3: "BILL_BAILEY", +} +var Message_Humour_value = map[string]int32{ + "UNKNOWN": 0, + "PUNS": 1, + "SLAPSTICK": 2, + "BILL_BAILEY": 3, +} + +func (x Message_Humour) String() string { + return proto.EnumName(Message_Humour_name, int32(x)) +} + +type Message struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Hilarity Message_Humour `protobuf:"varint,2,opt,name=hilarity,enum=proto3_proto.Message_Humour" json:"hilarity,omitempty"` + HeightInCm uint32 `protobuf:"varint,3,opt,name=height_in_cm" json:"height_in_cm,omitempty"` + Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` + ResultCount int64 `protobuf:"varint,7,opt,name=result_count" json:"result_count,omitempty"` + TrueScotsman bool `protobuf:"varint,8,opt,name=true_scotsman" json:"true_scotsman,omitempty"` + Score float32 `protobuf:"fixed32,9,opt,name=score" json:"score,omitempty"` + Key []uint64 `protobuf:"varint,5,rep,name=key" json:"key,omitempty"` + Nested *Nested `protobuf:"bytes,6,opt,name=nested" json:"nested,omitempty"` + Terrain map[string]*Nested `protobuf:"bytes,10,rep,name=terrain" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Proto2Field *testdata.SubDefaults `protobuf:"bytes,11,opt,name=proto2_field" json:"proto2_field,omitempty"` + Proto2Value map[string]*testdata.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` +} + +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} + +func (m *Message) GetNested() *Nested { + if m != nil { + return m.Nested + } + return nil +} + +func (m *Message) GetTerrain() map[string]*Nested { + if m != nil { + return m.Terrain + } + return nil +} + +func (m *Message) GetProto2Field() *testdata.SubDefaults { + if m != nil { + return m.Proto2Field + } + return nil +} + +func (m *Message) GetProto2Value() map[string]*testdata.SubDefaults { + if m != nil { + return m.Proto2Value + } + return nil +} + +type Nested struct { + Bunny string `protobuf:"bytes,1,opt,name=bunny" json:"bunny,omitempty"` +} + +func (m *Nested) Reset() { *m = Nested{} } +func (m *Nested) String() string { return proto.CompactTextString(m) } +func (*Nested) ProtoMessage() {} + +type MessageWithMap struct { + ByteMapping map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (m *MessageWithMap) Reset() { *m = MessageWithMap{} } +func (m *MessageWithMap) String() string { return proto.CompactTextString(m) } +func (*MessageWithMap) ProtoMessage() {} + +func (m *MessageWithMap) GetByteMapping() map[bool][]byte { + if m != nil { + return m.ByteMapping + } + return nil +} + +func init() { + proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value) +} diff -Nru golang-goprotobuf-0.0~git20130901/proto/proto3_proto/proto3.proto golang-goprotobuf-0.0~git20150526/proto/proto3_proto/proto3.proto --- golang-goprotobuf-0.0~git20130901/proto/proto3_proto/proto3.proto 1970-01-01 00:00:00.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/proto3_proto/proto3.proto 2015-06-13 14:23:31.000000000 +0000 @@ -0,0 +1,68 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2014 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. + +syntax = "proto3"; + +import "testdata/test.proto"; + +package proto3_proto; + +message Message { + enum Humour { + UNKNOWN = 0; + PUNS = 1; + SLAPSTICK = 2; + BILL_BAILEY = 3; + } + + string name = 1; + Humour hilarity = 2; + uint32 height_in_cm = 3; + bytes data = 4; + int64 result_count = 7; + bool true_scotsman = 8; + float score = 9; + + repeated uint64 key = 5; + Nested nested = 6; + + map terrain = 10; + testdata.SubDefaults proto2_field = 11; + map proto2_value = 13; +} + +message Nested { + string bunny = 1; +} + +message MessageWithMap { + map byte_mapping = 1; +} diff -Nru golang-goprotobuf-0.0~git20130901/proto/proto3_test.go golang-goprotobuf-0.0~git20150526/proto/proto3_test.go --- golang-goprotobuf-0.0~git20130901/proto/proto3_test.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/proto3_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -0,0 +1,125 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2014 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_test + +import ( + "testing" + + "github.com/golang/protobuf/proto" + pb "github.com/golang/protobuf/proto/proto3_proto" + tpb "github.com/golang/protobuf/proto/testdata" +) + +func TestProto3ZeroValues(t *testing.T) { + tests := []struct { + desc string + m proto.Message + }{ + {"zero message", &pb.Message{}}, + {"empty bytes field", &pb.Message{Data: []byte{}}}, + } + for _, test := range tests { + b, err := proto.Marshal(test.m) + if err != nil { + t.Errorf("%s: proto.Marshal: %v", test.desc, err) + continue + } + if len(b) > 0 { + t.Errorf("%s: Encoding is non-empty: %q", test.desc, b) + } + } +} + +func TestRoundTripProto3(t *testing.T) { + m := &pb.Message{ + Name: "David", // (2 | 1<<3): 0x0a 0x05 "David" + Hilarity: pb.Message_PUNS, // (0 | 2<<3): 0x10 0x01 + HeightInCm: 178, // (0 | 3<<3): 0x18 0xb2 0x01 + Data: []byte("roboto"), // (2 | 4<<3): 0x20 0x06 "roboto" + ResultCount: 47, // (0 | 7<<3): 0x38 0x2f + TrueScotsman: true, // (0 | 8<<3): 0x40 0x01 + Score: 8.1, // (5 | 9<<3): 0x4d <8.1> + + Key: []uint64{1, 0xdeadbeef}, + Nested: &pb.Nested{ + Bunny: "Monty", + }, + } + t.Logf(" m: %v", m) + + b, err := proto.Marshal(m) + if err != nil { + t.Fatalf("proto.Marshal: %v", err) + } + t.Logf(" b: %q", b) + + m2 := new(pb.Message) + if err := proto.Unmarshal(b, m2); err != nil { + t.Fatalf("proto.Unmarshal: %v", err) + } + t.Logf("m2: %v", m2) + + if !proto.Equal(m, m2) { + t.Errorf("proto.Equal returned false:\n m: %v\nm2: %v", m, m2) + } +} + +func TestProto3SetDefaults(t *testing.T) { + in := &pb.Message{ + Terrain: map[string]*pb.Nested{ + "meadow": new(pb.Nested), + }, + Proto2Field: new(tpb.SubDefaults), + Proto2Value: map[string]*tpb.SubDefaults{ + "badlands": new(tpb.SubDefaults), + }, + } + + got := proto.Clone(in).(*pb.Message) + proto.SetDefaults(got) + + // There are no defaults in proto3. Everything should be the zero value, but + // we need to remember to set defaults for nested proto2 messages. + want := &pb.Message{ + Terrain: map[string]*pb.Nested{ + "meadow": new(pb.Nested), + }, + Proto2Field: &tpb.SubDefaults{N: proto.Int64(7)}, + Proto2Value: map[string]*tpb.SubDefaults{ + "badlands": &tpb.SubDefaults{N: proto.Int64(7)}, + }, + } + + if !proto.Equal(got, want) { + t.Errorf("with in = %v\nproto.SetDefaults(in) =>\ngot %v\nwant %v", in, got, want) + } +} diff -Nru golang-goprotobuf-0.0~git20130901/proto/size2_test.go golang-goprotobuf-0.0~git20150526/proto/size2_test.go --- golang-goprotobuf-0.0~git20130901/proto/size2_test.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/size2_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2012 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 diff -Nru golang-goprotobuf-0.0~git20130901/proto/size.go golang-goprotobuf-0.0~git20150526/proto/size.go --- golang-goprotobuf-0.0~git20130901/proto/size.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/size.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,193 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2012 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ -// -// 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. - -// Functions to determine the size of an encoded protocol buffer. - -package proto - -import ( - "log" - "reflect" - "strings" -) - -// Size returns the encoded size of a protocol buffer. -// This function is expensive enough to be avoided unless proven worthwhile with instrumentation. -func Size(pb Message) int { - in := reflect.ValueOf(pb) - if in.IsNil() { - return 0 - } - return sizeStruct(in.Elem()) -} - -func sizeStruct(x reflect.Value) (n int) { - sprop := GetProperties(x.Type()) - for _, prop := range sprop.Prop { - if strings.HasPrefix(prop.Name, "XXX_") { // handled below - continue - } - fi, _ := sprop.decoderTags.get(prop.Tag) - f := x.Field(fi) - switch f.Kind() { - case reflect.Ptr: - if f.IsNil() { - continue - } - n += len(prop.tagcode) - f = f.Elem() // avoid a recursion in sizeField - case reflect.Slice: - if f.IsNil() { - continue - } - if f.Len() == 0 && f.Type().Elem().Kind() != reflect.Uint8 { - // short circuit for empty repeated fields. - // []byte isn't a repeated field. - continue - } - default: - log.Printf("proto: unknown struct field type %v", f.Type()) - continue - } - n += sizeField(f, prop) - } - - if em, ok := x.Addr().Interface().(extendableProto); ok { - for _, ext := range em.ExtensionMap() { - ms := len(ext.enc) - if ext.enc == nil { - props := new(Properties) - props.Init(reflect.TypeOf(ext.desc.ExtensionType), "x", ext.desc.Tag, nil) - ms = len(props.tagcode) + sizeField(reflect.ValueOf(ext.value), props) - } - n += ms - } - } - - if uf := x.FieldByName("XXX_unrecognized"); uf.IsValid() { - n += uf.Len() - } - - return n -} - -func sizeField(x reflect.Value, prop *Properties) (n int) { - if x.Type().Kind() == reflect.Slice { - n := x.Len() - et := x.Type().Elem() - if et.Kind() == reflect.Uint8 { - // []byte is easy. - return len(prop.tagcode) + sizeVarint(uint64(n)) + n - } - - var nb int - - // []bool and repeated fixed integer types are easy. - switch { - case et.Kind() == reflect.Bool: - nb += n - case prop.WireType == WireFixed64: - nb += n * 8 - case prop.WireType == WireFixed32: - nb += n * 4 - default: - for i := 0; i < n; i++ { - nb += sizeField(x.Index(i), prop) - } - } - // Non-packed repeated fields have a per-element header of the tagcode. - // Packed repeated fields only have a single header: the tag code plus a varint of the number of bytes. - if !prop.Packed { - nb += len(prop.tagcode) * n - } else { - nb += len(prop.tagcode) + sizeVarint(uint64(nb)) - } - return nb - } - - // easy scalars - switch prop.WireType { - case WireFixed64: - return 8 - case WireFixed32: - return 4 - } - - switch x.Kind() { - case reflect.Bool: - return 1 - case reflect.Int32, reflect.Int64: - if prop.Wire == "varint" { - return sizeVarint(uint64(x.Int())) - } else if prop.Wire == "zigzag32" || prop.Wire == "zigzag64" { - return sizeZigZag(uint64(x.Int())) - } - case reflect.Ptr: - return sizeField(x.Elem(), prop) - case reflect.String: - n := x.Len() - return sizeVarint(uint64(n)) + n - case reflect.Struct: - nb := sizeStruct(x) - if prop.Wire == "group" { - // Groups have start and end tags instead of a start tag and a length. - return nb + len(prop.tagcode) - } - return sizeVarint(uint64(nb)) + nb - case reflect.Uint32, reflect.Uint64: - if prop.Wire == "varint" { - return sizeVarint(uint64(x.Uint())) - } else if prop.Wire == "zigzag32" || prop.Wire == "zigzag64" { - return sizeZigZag(uint64(x.Int())) - } - default: - log.Printf("proto.sizeField: unhandled kind %v", x.Kind()) - } - - // unknown type, so not a protocol buffer - log.Printf("proto: don't know size of %v", x.Type()) - return 0 -} - -func sizeVarint(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } - } - return n -} - -func sizeZigZag(x uint64) (n int) { - return sizeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} diff -Nru golang-goprotobuf-0.0~git20130901/proto/size_test.go golang-goprotobuf-0.0~git20150526/proto/size_test.go --- golang-goprotobuf-0.0~git20130901/proto/size_test.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/size_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2012 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -33,10 +33,12 @@ import ( "log" + "strings" "testing" - pb "./testdata" - . "code.google.com/p/goprotobuf/proto" + . "github.com/golang/protobuf/proto" + proto3pb "github.com/golang/protobuf/proto/proto3_proto" + pb "github.com/golang/protobuf/proto/testdata" ) var messageWithExtension1 = &pb.MyMessage{Count: Int32(7)} @@ -65,8 +67,10 @@ // Basic types. {"bool", &pb.Defaults{F_Bool: Bool(true)}}, {"int32", &pb.Defaults{F_Int32: Int32(12)}}, + {"negative int32", &pb.Defaults{F_Int32: Int32(-1)}}, {"small int64", &pb.Defaults{F_Int64: Int64(1)}}, {"big int64", &pb.Defaults{F_Int64: Int64(1 << 20)}}, + {"negative int64", &pb.Defaults{F_Int64: Int64(-1)}}, {"fixed32", &pb.Defaults{F_Fixed32: Uint32(71)}}, {"fixed64", &pb.Defaults{F_Fixed64: Uint64(72)}}, {"uint32", &pb.Defaults{F_Uint32: Uint32(123)}}, @@ -83,7 +87,7 @@ {"empty repeated bool", &pb.MoreRepeated{Bools: []bool{}}}, {"repeated bool", &pb.MoreRepeated{Bools: []bool{false, true, true, false}}}, {"packed repeated bool", &pb.MoreRepeated{BoolsPacked: []bool{false, true, true, false, true, true, true}}}, - {"repeated int32", &pb.MoreRepeated{Ints: []int32{1, 12203, 1729}}}, + {"repeated int32", &pb.MoreRepeated{Ints: []int32{1, 12203, 1729, -1}}}, {"repeated int32 packed", &pb.MoreRepeated{IntsPacked: []int32{1, 12203, 1729}}}, {"repeated int64 packed", &pb.MoreRepeated{Int64SPacked: []int64{ // Need enough large numbers to verify that the header is counting the number of bytes @@ -100,6 +104,26 @@ {"unrecognized", &pb.MoreRepeated{XXX_unrecognized: []byte{13<<3 | 0, 4}}}, {"extension (unencoded)", messageWithExtension1}, {"extension (encoded)", messageWithExtension3}, + // proto3 message + {"proto3 empty", &proto3pb.Message{}}, + {"proto3 bool", &proto3pb.Message{TrueScotsman: true}}, + {"proto3 int64", &proto3pb.Message{ResultCount: 1}}, + {"proto3 uint32", &proto3pb.Message{HeightInCm: 123}}, + {"proto3 float", &proto3pb.Message{Score: 12.6}}, + {"proto3 string", &proto3pb.Message{Name: "Snezana"}}, + {"proto3 bytes", &proto3pb.Message{Data: []byte("wowsa")}}, + {"proto3 bytes, empty", &proto3pb.Message{Data: []byte{}}}, + {"proto3 enum", &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}}, + {"proto3 map field with empty bytes", &proto3pb.MessageWithMap{ByteMapping: map[bool][]byte{false: []byte{}}}}, + + {"map field", &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob", 7: "Andrew"}}}, + {"map field with message", &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{0x7001: &pb.FloatingPoint{F: Float64(2.0)}}}}, + {"map field with bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte("this time for sure")}}}, + {"map field with empty bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte{}}}}, + + {"map field with big entry", &pb.MessageWithMap{NameMapping: map[int32]string{8: strings.Repeat("x", 125)}}}, + {"map field with big key and val", &pb.MessageWithMap{StrToStr: map[string]string{strings.Repeat("x", 70): strings.Repeat("y", 70)}}}, + {"map field with big numeric key", &pb.MessageWithMap{NameMapping: map[int32]string{0xf00d: "om nom nom"}}}, } func TestSize(t *testing.T) { diff -Nru golang-goprotobuf-0.0~git20130901/proto/testdata/golden_test.go golang-goprotobuf-0.0~git20150526/proto/testdata/golden_test.go --- golang-goprotobuf-0.0~git20130901/proto/testdata/golden_test.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/testdata/golden_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2012 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 diff -Nru golang-goprotobuf-0.0~git20130901/proto/testdata/Makefile golang-goprotobuf-0.0~git20150526/proto/testdata/Makefile --- golang-goprotobuf-0.0~git20130901/proto/testdata/Makefile 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/testdata/Makefile 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ # Go support for Protocol Buffers - Google's data interchange format # # Copyright 2010 The Go Authors. All rights reserved. -# http://code.google.com/p/goprotobuf/ +# 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 @@ -37,11 +37,11 @@ regenerate: rm -f test.pb.go make test.pb.go - + # The following rules are just aids to development. Not needed for typical testing. diff: regenerate - hg diff test.pb.go + git diff test.pb.go restore: cp test.pb.go.golden test.pb.go diff -Nru golang-goprotobuf-0.0~git20130901/proto/testdata/test.pb.go golang-goprotobuf-0.0~git20150526/proto/testdata/test.pb.go --- golang-goprotobuf-0.0~git20130901/proto/testdata/test.pb.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/testdata/test.pb.go 2015-06-13 14:23:31.000000000 +0000 @@ -2,15 +2,47 @@ // source: test.proto // DO NOT EDIT! +/* +Package testdata is a generated protocol buffer package. + +It is generated from these files: + test.proto + +It has these top-level messages: + GoEnum + GoTestField + GoTest + GoSkipTest + NonPackedTest + PackedTest + MaxTag + OldMessage + NewMessage + InnerMessage + OtherMessage + MyMessage + Ext + DefaultsMessage + MyMessageSet + Empty + MessageList + Strings + Defaults + SubDefaults + RepeatedEnum + MoreRepeated + GroupOld + GroupNew + FloatingPoint + MessageWithMap +*/ package testdata -import proto "code.google.com/p/goprotobuf/proto" -import json "encoding/json" +import proto "github.com/golang/protobuf/proto" import math "math" -// Reference proto, json, and math imports to suppress error if they are not otherwise used. +// Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal -var _ = &json.SyntaxError{} var _ = math.Inf type FOO int32 @@ -34,9 +66,6 @@ func (x FOO) String() string { return proto.EnumName(FOO_name, int32(x)) } -func (x FOO) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *FOO) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(FOO_value, data, "FOO") if err != nil { @@ -108,9 +137,6 @@ func (x GoTest_KIND) String() string { return proto.EnumName(GoTest_KIND_name, int32(x)) } -func (x GoTest_KIND) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *GoTest_KIND) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(GoTest_KIND_value, data, "GoTest_KIND") if err != nil { @@ -147,9 +173,6 @@ func (x MyMessage_Color) String() string { return proto.EnumName(MyMessage_Color_name, int32(x)) } -func (x MyMessage_Color) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *MyMessage_Color) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(MyMessage_Color_value, data, "MyMessage_Color") if err != nil { @@ -159,6 +182,42 @@ return nil } +type DefaultsMessage_DefaultsEnum int32 + +const ( + DefaultsMessage_ZERO DefaultsMessage_DefaultsEnum = 0 + DefaultsMessage_ONE DefaultsMessage_DefaultsEnum = 1 + DefaultsMessage_TWO DefaultsMessage_DefaultsEnum = 2 +) + +var DefaultsMessage_DefaultsEnum_name = map[int32]string{ + 0: "ZERO", + 1: "ONE", + 2: "TWO", +} +var DefaultsMessage_DefaultsEnum_value = map[string]int32{ + "ZERO": 0, + "ONE": 1, + "TWO": 2, +} + +func (x DefaultsMessage_DefaultsEnum) Enum() *DefaultsMessage_DefaultsEnum { + p := new(DefaultsMessage_DefaultsEnum) + *p = x + return p +} +func (x DefaultsMessage_DefaultsEnum) String() string { + return proto.EnumName(DefaultsMessage_DefaultsEnum_name, int32(x)) +} +func (x *DefaultsMessage_DefaultsEnum) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(DefaultsMessage_DefaultsEnum_value, data, "DefaultsMessage_DefaultsEnum") + if err != nil { + return err + } + *x = DefaultsMessage_DefaultsEnum(value) + return nil +} + type Defaults_Color int32 const ( @@ -186,9 +245,6 @@ func (x Defaults_Color) String() string { return proto.EnumName(Defaults_Color_name, int32(x)) } -func (x Defaults_Color) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *Defaults_Color) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(Defaults_Color_value, data, "Defaults_Color") if err != nil { @@ -219,9 +275,6 @@ func (x RepeatedEnum_Color) String() string { return proto.EnumName(RepeatedEnum_Color_name, int32(x)) } -func (x RepeatedEnum_Color) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *RepeatedEnum_Color) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(RepeatedEnum_Color_value, data, "RepeatedEnum_Color") if err != nil { @@ -244,7 +297,7 @@ if m != nil && m.Foo != nil { return *m.Foo } - return 0 + return FOO_FOO1 } type GoTestField struct { @@ -378,7 +431,7 @@ if m != nil && m.Kind != nil { return *m.Kind } - return 0 + return GoTest_VOID } func (m *GoTest) GetTable() string { @@ -1055,6 +1108,7 @@ type OldMessage struct { Nested *OldMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"` + Num *int32 `protobuf:"varint,2,opt,name=num" json:"num,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -1069,6 +1123,13 @@ return nil } +func (m *OldMessage) GetNum() int32 { + if m != nil && m.Num != nil { + return *m.Num + } + return 0 +} + type OldMessage_Nested struct { Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` XXX_unrecognized []byte `json:"-"` @@ -1088,8 +1149,10 @@ // NewMessage is wire compatible with OldMessage; // imagine it as a future version. type NewMessage struct { - Nested *NewMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"` - XXX_unrecognized []byte `json:"-"` + Nested *NewMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"` + // This is an int32 in OldMessage. + Num *int64 `protobuf:"varint,2,opt,name=num" json:"num,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *NewMessage) Reset() { *m = NewMessage{} } @@ -1103,6 +1166,13 @@ return nil } +func (m *NewMessage) GetNum() int64 { + if m != nil && m.Num != nil { + return *m.Num + } + return 0 +} + type NewMessage_Nested struct { Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` FoodGroup *string `protobuf:"bytes,2,opt,name=food_group" json:"food_group,omitempty"` @@ -1289,7 +1359,7 @@ if m != nil && m.Bikeshed != nil { return *m.Bikeshed } - return 0 + return MyMessage_RED } func (m *MyMessage) GetSomegroup() *MyMessage_SomeGroup { @@ -1369,6 +1439,29 @@ Tag: "varint,105,opt,name=number", } +type DefaultsMessage struct { + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *DefaultsMessage) Reset() { *m = DefaultsMessage{} } +func (m *DefaultsMessage) String() string { return proto.CompactTextString(m) } +func (*DefaultsMessage) ProtoMessage() {} + +var extRange_DefaultsMessage = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*DefaultsMessage) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_DefaultsMessage +} +func (m *DefaultsMessage) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + type MyMessageSet struct { XXX_extensions map[int32]proto.Extension `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -1384,6 +1477,12 @@ func (m *MyMessageSet) Unmarshal(buf []byte) error { return proto.UnmarshalMessageSet(buf, m.ExtensionMap()) } +func (m *MyMessageSet) MarshalJSON() ([]byte, error) { + return proto.MarshalMessageSetJSON(m.XXX_extensions) +} +func (m *MyMessageSet) UnmarshalJSON(buf []byte) error { + return proto.UnmarshalMessageSetJSON(buf, m.XXX_extensions) +} // ensure MyMessageSet satisfies proto.Marshaler and proto.Unmarshaler var _ proto.Marshaler = (*MyMessageSet)(nil) @@ -1497,8 +1596,10 @@ F_Ninf *float32 `protobuf:"fixed32,16,opt,def=-inf" json:"F_Ninf,omitempty"` F_Nan *float32 `protobuf:"fixed32,17,opt,def=nan" json:"F_Nan,omitempty"` // Sub-message. - Sub *SubDefaults `protobuf:"bytes,18,opt,name=sub" json:"sub,omitempty"` - XXX_unrecognized []byte `json:"-"` + Sub *SubDefaults `protobuf:"bytes,18,opt,name=sub" json:"sub,omitempty"` + // Redundant but explicit defaults. + StrZero *string `protobuf:"bytes,19,opt,name=str_zero,def=" json:"str_zero,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *Defaults) Reset() { *m = Defaults{} } @@ -1652,6 +1753,13 @@ return nil } +func (m *Defaults) GetStrZero() string { + if m != nil && m.StrZero != nil { + return *m.StrZero + } + return "" +} + type SubDefaults struct { N *int64 `protobuf:"varint,1,opt,name=n,def=7" json:"n,omitempty"` XXX_unrecognized []byte `json:"-"` @@ -1838,6 +1946,46 @@ return 0 } +type MessageWithMap struct { + NameMapping map[int32]string `protobuf:"bytes,1,rep,name=name_mapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + MsgMapping map[int64]*FloatingPoint `protobuf:"bytes,2,rep,name=msg_mapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + ByteMapping map[bool][]byte `protobuf:"bytes,3,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + StrToStr map[string]string `protobuf:"bytes,4,rep,name=str_to_str" json:"str_to_str,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MessageWithMap) Reset() { *m = MessageWithMap{} } +func (m *MessageWithMap) String() string { return proto.CompactTextString(m) } +func (*MessageWithMap) ProtoMessage() {} + +func (m *MessageWithMap) GetNameMapping() map[int32]string { + if m != nil { + return m.NameMapping + } + return nil +} + +func (m *MessageWithMap) GetMsgMapping() map[int64]*FloatingPoint { + if m != nil { + return m.MsgMapping + } + return nil +} + +func (m *MessageWithMap) GetByteMapping() map[bool][]byte { + if m != nil { + return m.ByteMapping + } + return nil +} + +func (m *MessageWithMap) GetStrToStr() map[string]string { + if m != nil { + return m.StrToStr + } + return nil +} + var E_Greeting = &proto.ExtensionDesc{ ExtendedType: (*MyMessage)(nil), ExtensionType: ([]string)(nil), @@ -1846,6 +1994,262 @@ Tag: "bytes,106,rep,name=greeting", } +var E_NoDefaultDouble = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float64)(nil), + Field: 101, + Name: "testdata.no_default_double", + Tag: "fixed64,101,opt,name=no_default_double", +} + +var E_NoDefaultFloat = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float32)(nil), + Field: 102, + Name: "testdata.no_default_float", + Tag: "fixed32,102,opt,name=no_default_float", +} + +var E_NoDefaultInt32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 103, + Name: "testdata.no_default_int32", + Tag: "varint,103,opt,name=no_default_int32", +} + +var E_NoDefaultInt64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 104, + Name: "testdata.no_default_int64", + Tag: "varint,104,opt,name=no_default_int64", +} + +var E_NoDefaultUint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 105, + Name: "testdata.no_default_uint32", + Tag: "varint,105,opt,name=no_default_uint32", +} + +var E_NoDefaultUint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 106, + Name: "testdata.no_default_uint64", + Tag: "varint,106,opt,name=no_default_uint64", +} + +var E_NoDefaultSint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 107, + Name: "testdata.no_default_sint32", + Tag: "zigzag32,107,opt,name=no_default_sint32", +} + +var E_NoDefaultSint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 108, + Name: "testdata.no_default_sint64", + Tag: "zigzag64,108,opt,name=no_default_sint64", +} + +var E_NoDefaultFixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 109, + Name: "testdata.no_default_fixed32", + Tag: "fixed32,109,opt,name=no_default_fixed32", +} + +var E_NoDefaultFixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 110, + Name: "testdata.no_default_fixed64", + Tag: "fixed64,110,opt,name=no_default_fixed64", +} + +var E_NoDefaultSfixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 111, + Name: "testdata.no_default_sfixed32", + Tag: "fixed32,111,opt,name=no_default_sfixed32", +} + +var E_NoDefaultSfixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 112, + Name: "testdata.no_default_sfixed64", + Tag: "fixed64,112,opt,name=no_default_sfixed64", +} + +var E_NoDefaultBool = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*bool)(nil), + Field: 113, + Name: "testdata.no_default_bool", + Tag: "varint,113,opt,name=no_default_bool", +} + +var E_NoDefaultString = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*string)(nil), + Field: 114, + Name: "testdata.no_default_string", + Tag: "bytes,114,opt,name=no_default_string", +} + +var E_NoDefaultBytes = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: ([]byte)(nil), + Field: 115, + Name: "testdata.no_default_bytes", + Tag: "bytes,115,opt,name=no_default_bytes", +} + +var E_NoDefaultEnum = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*DefaultsMessage_DefaultsEnum)(nil), + Field: 116, + Name: "testdata.no_default_enum", + Tag: "varint,116,opt,name=no_default_enum,enum=testdata.DefaultsMessage_DefaultsEnum", +} + +var E_DefaultDouble = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float64)(nil), + Field: 201, + Name: "testdata.default_double", + Tag: "fixed64,201,opt,name=default_double,def=3.1415", +} + +var E_DefaultFloat = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float32)(nil), + Field: 202, + Name: "testdata.default_float", + Tag: "fixed32,202,opt,name=default_float,def=3.14", +} + +var E_DefaultInt32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 203, + Name: "testdata.default_int32", + Tag: "varint,203,opt,name=default_int32,def=42", +} + +var E_DefaultInt64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 204, + Name: "testdata.default_int64", + Tag: "varint,204,opt,name=default_int64,def=43", +} + +var E_DefaultUint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 205, + Name: "testdata.default_uint32", + Tag: "varint,205,opt,name=default_uint32,def=44", +} + +var E_DefaultUint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 206, + Name: "testdata.default_uint64", + Tag: "varint,206,opt,name=default_uint64,def=45", +} + +var E_DefaultSint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 207, + Name: "testdata.default_sint32", + Tag: "zigzag32,207,opt,name=default_sint32,def=46", +} + +var E_DefaultSint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 208, + Name: "testdata.default_sint64", + Tag: "zigzag64,208,opt,name=default_sint64,def=47", +} + +var E_DefaultFixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 209, + Name: "testdata.default_fixed32", + Tag: "fixed32,209,opt,name=default_fixed32,def=48", +} + +var E_DefaultFixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 210, + Name: "testdata.default_fixed64", + Tag: "fixed64,210,opt,name=default_fixed64,def=49", +} + +var E_DefaultSfixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 211, + Name: "testdata.default_sfixed32", + Tag: "fixed32,211,opt,name=default_sfixed32,def=50", +} + +var E_DefaultSfixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 212, + Name: "testdata.default_sfixed64", + Tag: "fixed64,212,opt,name=default_sfixed64,def=51", +} + +var E_DefaultBool = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*bool)(nil), + Field: 213, + Name: "testdata.default_bool", + Tag: "varint,213,opt,name=default_bool,def=1", +} + +var E_DefaultString = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*string)(nil), + Field: 214, + Name: "testdata.default_string", + Tag: "bytes,214,opt,name=default_string,def=Hello, string", +} + +var E_DefaultBytes = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: ([]byte)(nil), + Field: 215, + Name: "testdata.default_bytes", + Tag: "bytes,215,opt,name=default_bytes,def=Hello, bytes", +} + +var E_DefaultEnum = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*DefaultsMessage_DefaultsEnum)(nil), + Field: 216, + Name: "testdata.default_enum", + Tag: "varint,216,opt,name=default_enum,enum=testdata.DefaultsMessage_DefaultsEnum,def=1", +} + var E_X201 = &proto.ExtensionDesc{ ExtendedType: (*MyMessageSet)(nil), ExtensionType: (*Empty)(nil), @@ -2250,12 +2654,45 @@ proto.RegisterEnum("testdata.FOO", FOO_name, FOO_value) proto.RegisterEnum("testdata.GoTest_KIND", GoTest_KIND_name, GoTest_KIND_value) proto.RegisterEnum("testdata.MyMessage_Color", MyMessage_Color_name, MyMessage_Color_value) + proto.RegisterEnum("testdata.DefaultsMessage_DefaultsEnum", DefaultsMessage_DefaultsEnum_name, DefaultsMessage_DefaultsEnum_value) proto.RegisterEnum("testdata.Defaults_Color", Defaults_Color_name, Defaults_Color_value) proto.RegisterEnum("testdata.RepeatedEnum_Color", RepeatedEnum_Color_name, RepeatedEnum_Color_value) proto.RegisterExtension(E_Ext_More) proto.RegisterExtension(E_Ext_Text) proto.RegisterExtension(E_Ext_Number) proto.RegisterExtension(E_Greeting) + proto.RegisterExtension(E_NoDefaultDouble) + proto.RegisterExtension(E_NoDefaultFloat) + proto.RegisterExtension(E_NoDefaultInt32) + proto.RegisterExtension(E_NoDefaultInt64) + proto.RegisterExtension(E_NoDefaultUint32) + proto.RegisterExtension(E_NoDefaultUint64) + proto.RegisterExtension(E_NoDefaultSint32) + proto.RegisterExtension(E_NoDefaultSint64) + proto.RegisterExtension(E_NoDefaultFixed32) + proto.RegisterExtension(E_NoDefaultFixed64) + proto.RegisterExtension(E_NoDefaultSfixed32) + proto.RegisterExtension(E_NoDefaultSfixed64) + proto.RegisterExtension(E_NoDefaultBool) + proto.RegisterExtension(E_NoDefaultString) + proto.RegisterExtension(E_NoDefaultBytes) + proto.RegisterExtension(E_NoDefaultEnum) + proto.RegisterExtension(E_DefaultDouble) + proto.RegisterExtension(E_DefaultFloat) + proto.RegisterExtension(E_DefaultInt32) + proto.RegisterExtension(E_DefaultInt64) + proto.RegisterExtension(E_DefaultUint32) + proto.RegisterExtension(E_DefaultUint64) + proto.RegisterExtension(E_DefaultSint32) + proto.RegisterExtension(E_DefaultSint64) + proto.RegisterExtension(E_DefaultFixed32) + proto.RegisterExtension(E_DefaultFixed64) + proto.RegisterExtension(E_DefaultSfixed32) + proto.RegisterExtension(E_DefaultSfixed64) + proto.RegisterExtension(E_DefaultBool) + proto.RegisterExtension(E_DefaultString) + proto.RegisterExtension(E_DefaultBytes) + proto.RegisterExtension(E_DefaultEnum) proto.RegisterExtension(E_X201) proto.RegisterExtension(E_X202) proto.RegisterExtension(E_X203) diff -Nru golang-goprotobuf-0.0~git20130901/proto/testdata/test.proto golang-goprotobuf-0.0~git20150526/proto/testdata/test.proto --- golang-goprotobuf-0.0~git20130901/proto/testdata/test.proto 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/testdata/test.proto 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -203,6 +203,8 @@ optional string name = 1; } optional Nested nested = 1; + + optional int32 num = 2; } // NewMessage is wire compatible with OldMessage; @@ -213,6 +215,9 @@ optional string food_group = 2; } optional Nested nested = 1; + + // This is an int32 in OldMessage. + optional int64 num = 2; } // Smaller tests for ASCII formatting. @@ -272,6 +277,51 @@ repeated string greeting = 106; } +message DefaultsMessage { + enum DefaultsEnum { + ZERO = 0; + ONE = 1; + TWO = 2; + }; + extensions 100 to max; +} + +extend DefaultsMessage { + optional double no_default_double = 101; + optional float no_default_float = 102; + optional int32 no_default_int32 = 103; + optional int64 no_default_int64 = 104; + optional uint32 no_default_uint32 = 105; + optional uint64 no_default_uint64 = 106; + optional sint32 no_default_sint32 = 107; + optional sint64 no_default_sint64 = 108; + optional fixed32 no_default_fixed32 = 109; + optional fixed64 no_default_fixed64 = 110; + optional sfixed32 no_default_sfixed32 = 111; + optional sfixed64 no_default_sfixed64 = 112; + optional bool no_default_bool = 113; + optional string no_default_string = 114; + optional bytes no_default_bytes = 115; + optional DefaultsMessage.DefaultsEnum no_default_enum = 116; + + optional double default_double = 201 [default = 3.1415]; + optional float default_float = 202 [default = 3.14]; + optional int32 default_int32 = 203 [default = 42]; + optional int64 default_int64 = 204 [default = 43]; + optional uint32 default_uint32 = 205 [default = 44]; + optional uint64 default_uint64 = 206 [default = 45]; + optional sint32 default_sint32 = 207 [default = 46]; + optional sint64 default_sint64 = 208 [default = 47]; + optional fixed32 default_fixed32 = 209 [default = 48]; + optional fixed64 default_fixed64 = 210 [default = 49]; + optional sfixed32 default_sfixed32 = 211 [default = 50]; + optional sfixed64 default_sfixed64 = 212 [default = 51]; + optional bool default_bool = 213 [default = true]; + optional string default_string = 214 [default = "Hello, string"]; + optional bytes default_bytes = 215 [default = "Hello, bytes"]; + optional DefaultsMessage.DefaultsEnum default_enum = 216 [default = ONE]; +} + message MyMessageSet { option message_set_wire_format = true; extensions 100 to max; @@ -376,6 +426,9 @@ // Sub-message. optional SubDefaults sub = 18; + + // Redundant but explicit defaults. + optional string str_zero = 19 [default=""]; } message SubDefaults { @@ -418,3 +471,10 @@ message FloatingPoint { required double f = 1; } + +message MessageWithMap { + map name_mapping = 1; + map msg_mapping = 2; + map byte_mapping = 3; + map str_to_str = 4; +} diff -Nru golang-goprotobuf-0.0~git20130901/proto/text.go golang-goprotobuf-0.0~git20150526/proto/text.go --- golang-goprotobuf-0.0~git20130901/proto/text.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/text.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -36,6 +36,7 @@ import ( "bufio" "bytes" + "encoding" "fmt" "io" "log" @@ -225,7 +226,84 @@ return err } } - if err := writeAny(w, fv.Index(j), props); err != nil { + 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("\n")); err != nil { + return err + } + continue + } + if err := 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() // TODO: should we sort these for deterministic output? + 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 := writeAny(w, key, props.mkeyprop); 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 := writeAny(w, val, props.mvalprop); 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 { @@ -234,6 +312,35 @@ } 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 + switch fv.Kind() { + case reflect.Bool: + if !fv.Bool() { + continue + } + case reflect.Int32, reflect.Int64: + if fv.Int() == 0 { + continue + } + case reflect.Uint32, reflect.Uint64: + if fv.Uint() == 0 { + continue + } + case reflect.Float32, reflect.Float64: + if fv.Float() == 0 { + continue + } + case reflect.String: + if fv.String() == "" { + continue + } + } + } if err := writeName(w, props); err != nil { return err @@ -342,7 +449,15 @@ } } w.indent() - if err := writeStruct(w, v); err != nil { + if tm, ok := v.Interface().(encoding.TextMarshaler); ok { + text, err := tm.MarshalText() + if err != nil { + return err + } + if _, err = w.Write(text); err != nil { + return err + } + } else if err := writeStruct(w, v); err != nil { return err } w.unindent() @@ -477,7 +592,7 @@ switch wire { case WireBytes: buf, e := b.DecodeRawBytes(false) - if err == nil { + if e == nil { _, err = fmt.Fprintf(w, "%q", buf) } else { _, err = fmt.Fprintf(w, "/* %v */", e) @@ -629,6 +744,19 @@ compact: compact, } + if tm, ok := pb.(encoding.TextMarshaler); ok { + text, err := tm.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 := writeStruct(aw, v); err != nil { @@ -642,7 +770,9 @@ // 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 marshalText(w, pb, false) } +func MarshalText(w io.Writer, pb Message) error { + return marshalText(w, pb, false) +} // MarshalTextString is the same as MarshalText, but returns the string directly. func MarshalTextString(pb Message) string { diff -Nru golang-goprotobuf-0.0~git20130901/proto/text_parser.go golang-goprotobuf-0.0~git20150526/proto/text_parser.go --- golang-goprotobuf-0.0~git20130901/proto/text_parser.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/text_parser.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -35,6 +35,7 @@ // TODO: message sets. import ( + "encoding" "errors" "fmt" "reflect" @@ -193,8 +194,8 @@ } var ( - errBadUTF8 = errors.New("bad UTF-8") - errBadHex = errors.New("bad hexadecimal") + errBadUTF8 = errors.New("proto: bad UTF-8") + errBadHex = errors.New("proto: bad hexadecimal") ) func unquoteC(s string, quote rune) (string, error) { @@ -354,8 +355,20 @@ return &p.cur } -// Return an error indicating which required field was not set. -func (p *textParser) missingRequiredFieldError(sv reflect.Value) *ParseError { +func (p *textParser) consumeToken(s string) error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != s { + p.back() + return p.errorf("expected %q, found %q", s, tok.value) + } + return nil +} + +// Return a RequiredNotSetError indicating which required field was not set. +func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError { st := sv.Type() sprops := GetProperties(st) for i := 0; i < st.NumField(); i++ { @@ -365,10 +378,10 @@ props := sprops.Prop[i] if props.Required { - return p.errorf("message %v missing required field %q", st, props.OrigName) + return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)} } } - return p.errorf("message %v missing required field", st) // should not happen + return &RequiredNotSetError{fmt.Sprintf("%v.", st)} // should not happen } // Returns the index in the struct for the named field, as well as the parsed tag properties. @@ -408,6 +421,10 @@ if typ.Elem().Kind() != reflect.Ptr { break } + } else if typ.Kind() == reflect.String { + // The proto3 exception is for a string field, + // which requires a colon. + break } needColon = false } @@ -419,9 +436,11 @@ return nil } -func (p *textParser) readStruct(sv reflect.Value, terminator string) *ParseError { +func (p *textParser) readStruct(sv reflect.Value, terminator string) error { st := sv.Type() reqCount := GetProperties(st).reqCount + var reqFieldErr error + fieldSet := make(map[string]bool) // A struct is a sequence of "name: value", terminated by one of // '>' or '}', or the end of the input. A name may also be // "[extension]". @@ -482,7 +501,10 @@ ext = reflect.New(typ.Elem()).Elem() } if err := p.readAny(ext, props); err != nil { - return err + if _, ok := err.(*RequiredNotSetError); !ok { + return err + } + reqFieldErr = err } ep := sv.Addr().Interface().(extendableProto) if !rep { @@ -500,17 +522,77 @@ } } else { // This is a normal, non-extension field. - fi, props, ok := structFieldByName(st, tok.value) + name := tok.value + fi, props, ok := structFieldByName(st, name) if !ok { - return p.errorf("unknown field name %q in %v", tok.value, st) + return p.errorf("unknown field name %q in %v", name, st) } dst := sv.Field(fi) - isDstNil := isNil(dst) + + if dst.Kind() == reflect.Map { + // Consume any colon. + if err := p.checkForColon(props, dst.Type()); err != nil { + return err + } + + // Construct the map if it doesn't already exist. + if dst.IsNil() { + dst.Set(reflect.MakeMap(dst.Type())) + } + key := reflect.New(dst.Type().Key()).Elem() + val := reflect.New(dst.Type().Elem()).Elem() + + // The map entry should be this sequence of tokens: + // < key : KEY value : VALUE > + // Technically the "key" and "value" could come in any order, + // but in practice they won't. + + tok := p.next() + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + if err := p.consumeToken("key"); err != nil { + return err + } + if err := p.consumeToken(":"); err != nil { + return err + } + if err := p.readAny(key, props.mkeyprop); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + if err := p.consumeToken("value"); err != nil { + return err + } + if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { + return err + } + if err := p.readAny(val, props.mvalprop); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + if err := p.consumeToken(terminator); err != nil { + return err + } + + dst.SetMapIndex(key, val) + continue + } // Check that it's not already set if it's not a repeated field. - if !props.Repeated && !isDstNil { - return p.errorf("non-repeated field %q was repeated", tok.value) + if !props.Repeated && fieldSet[name] { + return p.errorf("non-repeated field %q was repeated", name) } if err := p.checkForColon(props, st.Field(fi).Type); err != nil { @@ -518,32 +600,43 @@ } // Parse into the field. + fieldSet[name] = true if err := p.readAny(dst, props); err != nil { - return err - } - - if props.Required { + if _, ok := err.(*RequiredNotSetError); !ok { + return err + } + reqFieldErr = err + } else if props.Required { reqCount-- } } - // For backward compatibility, permit a semicolon or comma after a field. - tok = p.next() - if tok.err != nil { - return tok.err - } - if tok.value != ";" && tok.value != "," { - p.back() + if err := p.consumeOptionalSeparator(); err != nil { + return err } + } if reqCount > 0 { return p.missingRequiredFieldError(sv) } + return reqFieldErr +} + +// consumeOptionalSeparator consumes an optional semicolon or comma. +// It is used in readStruct to provide backward compatibility. +func (p *textParser) consumeOptionalSeparator() error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ";" && tok.value != "," { + p.back() + } return nil } -func (p *textParser) readAny(v reflect.Value, props *Properties) *ParseError { +func (p *textParser) readAny(v reflect.Value, props *Properties) error { tok := p.next() if tok.err != nil { return tok.err @@ -605,6 +698,7 @@ fv.SetInt(x) return nil } + if len(props.Enum) == 0 { break } @@ -623,6 +717,7 @@ fv.SetInt(x) return nil } + case reflect.Ptr: // A basic field (indirected through pointer), or a repeated message/group p.back() @@ -643,6 +738,7 @@ default: return p.errorf("expected '{' or '<', found %q", tok.value) } + // TODO: Handle nested messages which implement encoding.TextUnmarshaler. return p.readStruct(fv, terminator) case reflect.Uint32: if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { @@ -660,7 +756,13 @@ // UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb // before starting to unmarshal, so any existing data in pb is always removed. +// If a required field is not set and no other error occurs, +// UnmarshalText returns *RequiredNotSetError. func UnmarshalText(s string, pb Message) error { + if um, ok := pb.(encoding.TextUnmarshaler); ok { + err := um.UnmarshalText([]byte(s)) + return err + } pb.Reset() v := reflect.ValueOf(pb) if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil { diff -Nru golang-goprotobuf-0.0~git20130901/proto/text_parser_test.go golang-goprotobuf-0.0~git20150526/proto/text_parser_test.go --- golang-goprotobuf-0.0~git20130901/proto/text_parser_test.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/text_parser_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -36,8 +36,9 @@ "reflect" "testing" - . "./testdata" - . "code.google.com/p/goprotobuf/proto" + . "github.com/golang/protobuf/proto" + proto3pb "github.com/golang/protobuf/proto/proto3_proto" + . "github.com/golang/protobuf/proto/testdata" ) type UnmarshalTextTest struct { @@ -156,8 +157,8 @@ // Number too large for int64 { - in: "count: 123456789012345678901", - err: "line 1.7: invalid int32: 123456789012345678901", + in: "count: 1 others { key: 123456789012345678901 }", + err: "line 1.23: invalid int64: 123456789012345678901", }, // Number too large for int32 @@ -294,8 +295,11 @@ // Missing required field { - in: ``, - err: `line 1.0: message testdata.MyMessage missing required field "count"`, + in: `name: "Pawel"`, + err: `proto: required field "testdata.MyMessage.count" not set`, + out: &MyMessage{ + Name: String("Pawel"), + }, }, // Repeated non-repeated field @@ -408,11 +412,24 @@ } else if err.Error() != test.err { t.Errorf("Test %d: Incorrect error.\nHave: %v\nWant: %v", i, err.Error(), test.err) + } else if _, ok := err.(*RequiredNotSetError); ok && test.out != nil && !reflect.DeepEqual(pb, test.out) { + t.Errorf("Test %d: Incorrect populated \nHave: %v\nWant: %v", + i, pb, test.out) } } } } +func TestUnmarshalTextCustomMessage(t *testing.T) { + msg := &textMessage{} + if err := UnmarshalText("custom", msg); err != nil { + t.Errorf("Unexpected error from custom unmarshal: %v", err) + } + if UnmarshalText("not custom", msg) == nil { + t.Errorf("Didn't get expected error from custom unmarshal") + } +} + // Regression test; this caused a panic. func TestRepeatedEnum(t *testing.T) { pb := new(RepeatedEnum) @@ -427,6 +444,48 @@ } } +func TestProto3TextParsing(t *testing.T) { + m := new(proto3pb.Message) + const in = `name: "Wallace" true_scotsman: true` + want := &proto3pb.Message{ + Name: "Wallace", + TrueScotsman: true, + } + if err := UnmarshalText(in, m); err != nil { + t.Fatal(err) + } + if !Equal(m, want) { + t.Errorf("\n got %v\nwant %v", m, want) + } +} + +func TestMapParsing(t *testing.T) { + m := new(MessageWithMap) + const in = `name_mapping: name_mapping:` + + `msg_mapping:,>` + // separating commas are okay + `msg_mapping>` + // no colon after "value" + `byte_mapping:` + want := &MessageWithMap{ + NameMapping: map[int32]string{ + 1: "Beatles", + 1234: "Feist", + }, + MsgMapping: map[int64]*FloatingPoint{ + -4: {F: Float64(2.0)}, + -2: {F: Float64(4.0)}, + }, + ByteMapping: map[bool][]byte{ + true: []byte("so be it"), + }, + } + if err := UnmarshalText(in, m); err != nil { + t.Fatal(err) + } + if !Equal(m, want) { + t.Errorf("\n got %v\nwant %v", m, want) + } +} + var benchInput string func init() { diff -Nru golang-goprotobuf-0.0~git20130901/proto/text_test.go golang-goprotobuf-0.0~git20150526/proto/text_test.go --- golang-goprotobuf-0.0~git20130901/proto/text_test.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/proto/text_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -39,11 +39,32 @@ "strings" "testing" - "code.google.com/p/goprotobuf/proto" + "github.com/golang/protobuf/proto" - pb "./testdata" + proto3pb "github.com/golang/protobuf/proto/proto3_proto" + pb "github.com/golang/protobuf/proto/testdata" ) +// textMessage implements the methods that allow it to marshal and unmarshal +// itself as text. +type textMessage struct { +} + +func (*textMessage) MarshalText() ([]byte, error) { + return []byte("custom"), nil +} + +func (*textMessage) UnmarshalText(bytes []byte) error { + if string(bytes) != "custom" { + return errors.New("expected 'custom'") + } + return nil +} + +func (*textMessage) Reset() {} +func (*textMessage) String() string { return "" } +func (*textMessage) ProtoMessage() {} + func newTestMessage() *pb.MyMessage { msg := &pb.MyMessage{ Count: proto.Int32(42), @@ -153,6 +174,16 @@ } } +func TestMarshalTextCustomMessage(t *testing.T) { + buf := new(bytes.Buffer) + if err := proto.MarshalText(buf, &textMessage{}); err != nil { + t.Fatalf("proto.MarshalText: %v", err) + } + s := buf.String() + if s != "custom" { + t.Errorf("Got %q, expected %q", s, "custom") + } +} func TestMarshalTextNil(t *testing.T) { want := "" tests := []proto.Message{nil, (*pb.MyMessage)(nil)} @@ -303,7 +334,7 @@ limit int } -var outOfSpace = errors.New("insufficient space") +var outOfSpace = errors.New("proto: insufficient space") func (w *limitedWriter) Write(p []byte) (n int, err error) { var avail = w.limit - w.b.Len() @@ -355,3 +386,56 @@ } } } + +func TestRepeatedNilText(t *testing.T) { + m := &pb.MessageList{ + Message: []*pb.MessageList_Message{ + nil, + &pb.MessageList_Message{ + Name: proto.String("Horse"), + }, + nil, + }, + } + want := `Message +Message { + name: "Horse" +} +Message +` + if s := proto.MarshalTextString(m); s != want { + t.Errorf(" got: %s\nwant: %s", s, want) + } +} + +func TestProto3Text(t *testing.T) { + tests := []struct { + m proto.Message + want string + }{ + // zero message + {&proto3pb.Message{}, ``}, + // zero message except for an empty byte slice + {&proto3pb.Message{Data: []byte{}}, ``}, + // trivial case + {&proto3pb.Message{Name: "Rob", HeightInCm: 175}, `name:"Rob" height_in_cm:175`}, + // empty map + {&pb.MessageWithMap{}, ``}, + // non-empty map; current map format is the same as a repeated struct + { + &pb.MessageWithMap{NameMapping: map[int32]string{1234: "Feist"}}, + `name_mapping:`, + }, + // map with nil value; not well-defined, but we shouldn't crash + { + &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{7: nil}}, + `msg_mapping:`, + }, + } + for _, test := range tests { + got := strings.TrimSpace(test.m.String()) + if got != test.want { + t.Errorf("\n got %s\nwant %s", got, test.want) + } + } +} diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/descriptor/descriptor.pb.go golang-goprotobuf-0.0~git20150526/protoc-gen-go/descriptor/descriptor.pb.go --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/descriptor/descriptor.pb.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/descriptor/descriptor.pb.go 2015-06-13 14:23:31.000000000 +0000 @@ -2,15 +2,39 @@ // source: google/protobuf/descriptor.proto // DO NOT EDIT! -package google_protobuf +/* +Package google_protobuf is a generated protocol buffer package. -import proto "code.google.com/p/goprotobuf/proto" -import json "encoding/json" +It is generated from these files: + google/protobuf/descriptor.proto + +It has these top-level messages: + FileDescriptorSet + FileDescriptorProto + DescriptorProto + FieldDescriptorProto + OneofDescriptorProto + EnumDescriptorProto + EnumValueDescriptorProto + ServiceDescriptorProto + MethodDescriptorProto + FileOptions + MessageOptions + FieldOptions + EnumOptions + EnumValueOptions + ServiceOptions + MethodOptions + UninterpretedOption + SourceCodeInfo +*/ +package descriptor + +import proto "github.com/golang/protobuf/proto" import math "math" -// Reference proto, json, and math imports to suppress error if they are not otherwise used. +// Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal -var _ = &json.SyntaxError{} var _ = math.Inf type FieldDescriptorProto_Type int32 @@ -92,9 +116,6 @@ func (x FieldDescriptorProto_Type) String() string { return proto.EnumName(FieldDescriptorProto_Type_name, int32(x)) } -func (x FieldDescriptorProto_Type) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *FieldDescriptorProto_Type) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(FieldDescriptorProto_Type_value, data, "FieldDescriptorProto_Type") if err != nil { @@ -132,9 +153,6 @@ func (x FieldDescriptorProto_Label) String() string { return proto.EnumName(FieldDescriptorProto_Label_name, int32(x)) } -func (x FieldDescriptorProto_Label) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *FieldDescriptorProto_Label) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(FieldDescriptorProto_Label_value, data, "FieldDescriptorProto_Label") if err != nil { @@ -173,9 +191,6 @@ func (x FileOptions_OptimizeMode) String() string { return proto.EnumName(FileOptions_OptimizeMode_name, int32(x)) } -func (x FileOptions_OptimizeMode) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *FileOptions_OptimizeMode) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(FileOptions_OptimizeMode_value, data, "FileOptions_OptimizeMode") if err != nil { @@ -213,9 +228,6 @@ func (x FieldOptions_CType) String() string { return proto.EnumName(FieldOptions_CType_name, int32(x)) } -func (x FieldOptions_CType) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *FieldOptions_CType) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(FieldOptions_CType_value, data, "FieldOptions_CType") if err != nil { @@ -261,11 +273,14 @@ Extension []*FieldDescriptorProto `protobuf:"bytes,7,rep,name=extension" json:"extension,omitempty"` Options *FileOptions `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"` // This field contains optional information about the original source code. - // You may safely remove this entire field whithout harming runtime + // You may safely remove this entire field without harming runtime // functionality of the descriptors -- the information is needed only by // development tools. - SourceCodeInfo *SourceCodeInfo `protobuf:"bytes,9,opt,name=source_code_info" json:"source_code_info,omitempty"` - XXX_unrecognized []byte `json:"-"` + SourceCodeInfo *SourceCodeInfo `protobuf:"bytes,9,opt,name=source_code_info" json:"source_code_info,omitempty"` + // The syntax of the proto file. + // The supported values are "proto2" and "proto3". + Syntax *string `protobuf:"bytes,12,opt,name=syntax" json:"syntax,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *FileDescriptorProto) Reset() { *m = FileDescriptorProto{} } @@ -349,6 +364,13 @@ return nil } +func (m *FileDescriptorProto) GetSyntax() string { + if m != nil && m.Syntax != nil { + return *m.Syntax + } + return "" +} + // Describes a message type. type DescriptorProto struct { Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` @@ -357,6 +379,7 @@ NestedType []*DescriptorProto `protobuf:"bytes,3,rep,name=nested_type" json:"nested_type,omitempty"` EnumType []*EnumDescriptorProto `protobuf:"bytes,4,rep,name=enum_type" json:"enum_type,omitempty"` ExtensionRange []*DescriptorProto_ExtensionRange `protobuf:"bytes,5,rep,name=extension_range" json:"extension_range,omitempty"` + OneofDecl []*OneofDescriptorProto `protobuf:"bytes,8,rep,name=oneof_decl" json:"oneof_decl,omitempty"` Options *MessageOptions `protobuf:"bytes,7,opt,name=options" json:"options,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -407,6 +430,13 @@ return nil } +func (m *DescriptorProto) GetOneofDecl() []*OneofDescriptorProto { + if m != nil { + return m.OneofDecl + } + return nil +} + func (m *DescriptorProto) GetOptions() *MessageOptions { if m != nil { return m.Options @@ -444,7 +474,7 @@ Number *int32 `protobuf:"varint,3,opt,name=number" json:"number,omitempty"` Label *FieldDescriptorProto_Label `protobuf:"varint,4,opt,name=label,enum=google.protobuf.FieldDescriptorProto_Label" json:"label,omitempty"` // If type_name is set, this need not be set. If both this and type_name - // are set, this must be either TYPE_ENUM or TYPE_MESSAGE. + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. Type *FieldDescriptorProto_Type `protobuf:"varint,5,opt,name=type,enum=google.protobuf.FieldDescriptorProto_Type" json:"type,omitempty"` // For message and enum types, this is the name of the type. If the name // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping @@ -460,7 +490,12 @@ // For strings, contains the default text contents (not escaped in any way). // For bytes, contains the C escaped value. All bytes >= 128 are escaped. // TODO(kenton): Base-64 encode? - DefaultValue *string `protobuf:"bytes,7,opt,name=default_value" json:"default_value,omitempty"` + DefaultValue *string `protobuf:"bytes,7,opt,name=default_value" json:"default_value,omitempty"` + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. Extensions of a oneof should + // not set this since the oneof to which they belong will be inferred based + // on the extension range containing the extension's field number. + OneofIndex *int32 `protobuf:"varint,9,opt,name=oneof_index" json:"oneof_index,omitempty"` Options *FieldOptions `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"` XXX_unrecognized []byte `json:"-"` } @@ -487,14 +522,14 @@ if m != nil && m.Label != nil { return *m.Label } - return 0 + return FieldDescriptorProto_LABEL_OPTIONAL } func (m *FieldDescriptorProto) GetType() FieldDescriptorProto_Type { if m != nil && m.Type != nil { return *m.Type } - return 0 + return FieldDescriptorProto_TYPE_DOUBLE } func (m *FieldDescriptorProto) GetTypeName() string { @@ -518,6 +553,13 @@ return "" } +func (m *FieldDescriptorProto) GetOneofIndex() int32 { + if m != nil && m.OneofIndex != nil { + return *m.OneofIndex + } + return 0 +} + func (m *FieldDescriptorProto) GetOptions() *FieldOptions { if m != nil { return m.Options @@ -525,6 +567,23 @@ return nil } +// Describes a oneof. +type OneofDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OneofDescriptorProto) Reset() { *m = OneofDescriptorProto{} } +func (m *OneofDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*OneofDescriptorProto) ProtoMessage() {} + +func (m *OneofDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + // Describes an enum type. type EnumDescriptorProto struct { Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` @@ -629,16 +688,23 @@ Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` // Input and output type names. These are resolved in the same way as // FieldDescriptorProto.type_name, but must refer to a message type. - InputType *string `protobuf:"bytes,2,opt,name=input_type" json:"input_type,omitempty"` - OutputType *string `protobuf:"bytes,3,opt,name=output_type" json:"output_type,omitempty"` - Options *MethodOptions `protobuf:"bytes,4,opt,name=options" json:"options,omitempty"` - XXX_unrecognized []byte `json:"-"` + InputType *string `protobuf:"bytes,2,opt,name=input_type" json:"input_type,omitempty"` + OutputType *string `protobuf:"bytes,3,opt,name=output_type" json:"output_type,omitempty"` + Options *MethodOptions `protobuf:"bytes,4,opt,name=options" json:"options,omitempty"` + // Identifies if client streams multiple client messages + ClientStreaming *bool `protobuf:"varint,5,opt,name=client_streaming,def=0" json:"client_streaming,omitempty"` + // Identifies if server streams multiple server messages + ServerStreaming *bool `protobuf:"varint,6,opt,name=server_streaming,def=0" json:"server_streaming,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *MethodDescriptorProto) Reset() { *m = MethodDescriptorProto{} } func (m *MethodDescriptorProto) String() string { return proto.CompactTextString(m) } func (*MethodDescriptorProto) ProtoMessage() {} +const Default_MethodDescriptorProto_ClientStreaming bool = false +const Default_MethodDescriptorProto_ServerStreaming bool = false + func (m *MethodDescriptorProto) GetName() string { if m != nil && m.Name != nil { return *m.Name @@ -667,6 +733,20 @@ return nil } +func (m *MethodDescriptorProto) GetClientStreaming() bool { + if m != nil && m.ClientStreaming != nil { + return *m.ClientStreaming + } + return Default_MethodDescriptorProto_ClientStreaming +} + +func (m *MethodDescriptorProto) GetServerStreaming() bool { + if m != nil && m.ServerStreaming != nil { + return *m.ServerStreaming + } + return Default_MethodDescriptorProto_ServerStreaming +} + type FileOptions struct { // Sets the Java package where classes generated from this .proto will be // placed. By default, the proto package is used, but this is often @@ -687,19 +767,35 @@ // top-level extensions defined in the file. JavaMultipleFiles *bool `protobuf:"varint,10,opt,name=java_multiple_files,def=0" json:"java_multiple_files,omitempty"` // If set true, then the Java code generator will generate equals() and - // hashCode() methods for all messages defined in the .proto file. This is - // purely a speed optimization, as the AbstractMessage base class includes - // reflection-based implementations of these methods. - JavaGenerateEqualsAndHash *bool `protobuf:"varint,20,opt,name=java_generate_equals_and_hash,def=0" json:"java_generate_equals_and_hash,omitempty"` - OptimizeFor *FileOptions_OptimizeMode `protobuf:"varint,9,opt,name=optimize_for,enum=google.protobuf.FileOptions_OptimizeMode,def=1" json:"optimize_for,omitempty"` + // hashCode() methods for all messages defined in the .proto file. + // - In the full runtime, this is purely a speed optimization, as the + // AbstractMessage base class includes reflection-based implementations of + // these methods. + // - In the lite runtime, setting this option changes the semantics of + // equals() and hashCode() to more closely match those of the full runtime; + // the generated methods compute their results based on field values rather + // than object identity. (Implementations should not assume that hashcodes + // will be consistent across runtimes or versions of the protocol compiler.) + JavaGenerateEqualsAndHash *bool `protobuf:"varint,20,opt,name=java_generate_equals_and_hash,def=0" json:"java_generate_equals_and_hash,omitempty"` + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + JavaStringCheckUtf8 *bool `protobuf:"varint,27,opt,name=java_string_check_utf8,def=0" json:"java_string_check_utf8,omitempty"` + OptimizeFor *FileOptions_OptimizeMode `protobuf:"varint,9,opt,name=optimize_for,enum=google.protobuf.FileOptions_OptimizeMode,def=1" json:"optimize_for,omitempty"` // Sets the Go package where structs generated from this .proto will be - // placed. There is no default. + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. GoPackage *string `protobuf:"bytes,11,opt,name=go_package" json:"go_package,omitempty"` // Should generic services be generated in each language? "Generic" services // are not specific to any particular RPC system. They are generated by the // main code generators in each language (without additional plugins). // Generic services were the only kind of service generation supported by - // early versions of proto2. + // early versions of google.protobuf. // // Generic services are now considered deprecated in favor of using plugins // that generate code specific to your particular RPC system. Therefore, @@ -708,6 +804,14 @@ CcGenericServices *bool `protobuf:"varint,16,opt,name=cc_generic_services,def=0" json:"cc_generic_services,omitempty"` JavaGenericServices *bool `protobuf:"varint,17,opt,name=java_generic_services,def=0" json:"java_generic_services,omitempty"` PyGenericServices *bool `protobuf:"varint,18,opt,name=py_generic_services,def=0" json:"py_generic_services,omitempty"` + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + Deprecated *bool `protobuf:"varint,23,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + CcEnableArenas *bool `protobuf:"varint,31,opt,name=cc_enable_arenas,def=0" json:"cc_enable_arenas,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` XXX_extensions map[int32]proto.Extension `json:"-"` @@ -734,10 +838,13 @@ const Default_FileOptions_JavaMultipleFiles bool = false const Default_FileOptions_JavaGenerateEqualsAndHash bool = false +const Default_FileOptions_JavaStringCheckUtf8 bool = false const Default_FileOptions_OptimizeFor FileOptions_OptimizeMode = FileOptions_SPEED const Default_FileOptions_CcGenericServices bool = false const Default_FileOptions_JavaGenericServices bool = false const Default_FileOptions_PyGenericServices bool = false +const Default_FileOptions_Deprecated bool = false +const Default_FileOptions_CcEnableArenas bool = false func (m *FileOptions) GetJavaPackage() string { if m != nil && m.JavaPackage != nil { @@ -767,6 +874,13 @@ return Default_FileOptions_JavaGenerateEqualsAndHash } +func (m *FileOptions) GetJavaStringCheckUtf8() bool { + if m != nil && m.JavaStringCheckUtf8 != nil { + return *m.JavaStringCheckUtf8 + } + return Default_FileOptions_JavaStringCheckUtf8 +} + func (m *FileOptions) GetOptimizeFor() FileOptions_OptimizeMode { if m != nil && m.OptimizeFor != nil { return *m.OptimizeFor @@ -802,6 +916,20 @@ return Default_FileOptions_PyGenericServices } +func (m *FileOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_FileOptions_Deprecated +} + +func (m *FileOptions) GetCcEnableArenas() bool { + if m != nil && m.CcEnableArenas != nil { + return *m.CcEnableArenas + } + return Default_FileOptions_CcEnableArenas +} + func (m *FileOptions) GetUninterpretedOption() []*UninterpretedOption { if m != nil { return m.UninterpretedOption @@ -833,6 +961,33 @@ // conflict with a field of the same name. This is meant to make migration // from proto1 easier; new code should avoid fields named "descriptor". NoStandardDescriptorAccessor *bool `protobuf:"varint,2,opt,name=no_standard_descriptor_accessor,def=0" json:"no_standard_descriptor_accessor,omitempty"` + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementions still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + MapEntry *bool `protobuf:"varint,7,opt,name=map_entry" json:"map_entry,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` XXX_extensions map[int32]proto.Extension `json:"-"` @@ -859,6 +1014,7 @@ const Default_MessageOptions_MessageSetWireFormat bool = false const Default_MessageOptions_NoStandardDescriptorAccessor bool = false +const Default_MessageOptions_Deprecated bool = false func (m *MessageOptions) GetMessageSetWireFormat() bool { if m != nil && m.MessageSetWireFormat != nil { @@ -874,6 +1030,20 @@ return Default_MessageOptions_NoStandardDescriptorAccessor } +func (m *MessageOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_MessageOptions_Deprecated +} + +func (m *MessageOptions) GetMapEntry() bool { + if m != nil && m.MapEntry != nil { + return *m.MapEntry + } + return false +} + func (m *MessageOptions) GetUninterpretedOption() []*UninterpretedOption { if m != nil { return m.UninterpretedOption @@ -926,19 +1096,6 @@ // for accessors, or it will be completely ignored; in the very least, this // is a formalization for deprecating fields. Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` - // EXPERIMENTAL. DO NOT USE. - // For "map" fields, the name of the field in the enclosed type that - // is the key for this map. For example, suppose we have: - // message Item { - // required string name = 1; - // required string value = 2; - // } - // message Config { - // repeated Item items = 1 [experimental_map_key="name"]; - // } - // In this situation, the map key for Item will be set to "name". - // TODO: Fully-implement this, then remove the "experimental_" prefix. - ExperimentalMapKey *string `protobuf:"bytes,9,opt,name=experimental_map_key" json:"experimental_map_key,omitempty"` // For Google-internal migration only. Do not use. Weak *bool `protobuf:"varint,10,opt,name=weak,def=0" json:"weak,omitempty"` // The parser stores options it doesn't recognize here. See above. @@ -998,13 +1155,6 @@ return Default_FieldOptions_Deprecated } -func (m *FieldOptions) GetExperimentalMapKey() string { - if m != nil && m.ExperimentalMapKey != nil { - return *m.ExperimentalMapKey - } - return "" -} - func (m *FieldOptions) GetWeak() bool { if m != nil && m.Weak != nil { return *m.Weak @@ -1020,9 +1170,14 @@ } type EnumOptions struct { - // Set this option to false to disallow mapping different tag names to a same + // Set this option to true to allow mapping different tag names to the same // value. - AllowAlias *bool `protobuf:"varint,2,opt,name=allow_alias,def=1" json:"allow_alias,omitempty"` + AllowAlias *bool `protobuf:"varint,2,opt,name=allow_alias" json:"allow_alias,omitempty"` + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` XXX_extensions map[int32]proto.Extension `json:"-"` @@ -1047,13 +1202,20 @@ return m.XXX_extensions } -const Default_EnumOptions_AllowAlias bool = true +const Default_EnumOptions_Deprecated bool = false func (m *EnumOptions) GetAllowAlias() bool { if m != nil && m.AllowAlias != nil { return *m.AllowAlias } - return Default_EnumOptions_AllowAlias + return false +} + +func (m *EnumOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_EnumOptions_Deprecated } func (m *EnumOptions) GetUninterpretedOption() []*UninterpretedOption { @@ -1064,6 +1226,11 @@ } type EnumValueOptions struct { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + Deprecated *bool `protobuf:"varint,1,opt,name=deprecated,def=0" json:"deprecated,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` XXX_extensions map[int32]proto.Extension `json:"-"` @@ -1088,6 +1255,15 @@ return m.XXX_extensions } +const Default_EnumValueOptions_Deprecated bool = false + +func (m *EnumValueOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_EnumValueOptions_Deprecated +} + func (m *EnumValueOptions) GetUninterpretedOption() []*UninterpretedOption { if m != nil { return m.UninterpretedOption @@ -1096,6 +1272,11 @@ } type ServiceOptions struct { + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + Deprecated *bool `protobuf:"varint,33,opt,name=deprecated,def=0" json:"deprecated,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` XXX_extensions map[int32]proto.Extension `json:"-"` @@ -1120,6 +1301,15 @@ return m.XXX_extensions } +const Default_ServiceOptions_Deprecated bool = false + +func (m *ServiceOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_ServiceOptions_Deprecated +} + func (m *ServiceOptions) GetUninterpretedOption() []*UninterpretedOption { if m != nil { return m.UninterpretedOption @@ -1128,6 +1318,11 @@ } type MethodOptions struct { + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + Deprecated *bool `protobuf:"varint,33,opt,name=deprecated,def=0" json:"deprecated,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` XXX_extensions map[int32]proto.Extension `json:"-"` @@ -1152,6 +1347,15 @@ return m.XXX_extensions } +const Default_MethodOptions_Deprecated bool = false + +func (m *MethodOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_MethodOptions_Deprecated +} + func (m *MethodOptions) GetUninterpretedOption() []*UninterpretedOption { if m != nil { return m.UninterpretedOption diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/descriptor/descriptor.pb.golden golang-goprotobuf-0.0~git20150526/protoc-gen-go/descriptor/descriptor.pb.golden --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/descriptor/descriptor.pb.golden 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/descriptor/descriptor.pb.golden 2015-06-13 14:23:31.000000000 +0000 @@ -4,7 +4,7 @@ package google_protobuf -import proto "code.google.com/p/goprotobuf/proto" +import proto "github.com/golang/protobuf/proto" import "math" // Reference proto and math imports to suppress error if they are not otherwise used. diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/descriptor/Makefile golang-goprotobuf-0.0~git20150526/protoc-gen-go/descriptor/Makefile --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/descriptor/Makefile 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/descriptor/Makefile 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ # Go support for Protocol Buffers - Google's data interchange format # # Copyright 2010 The Go Authors. All rights reserved. -# http://code.google.com/p/goprotobuf/ +# 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 @@ -29,13 +29,14 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# Not stored here, but descriptor.proto is in http://code.google.com/p/protobuf -# at protobuf-2.5.0/src/google/protobuf/descriptor.proto +# Not stored here, but descriptor.proto is in https://github.com/google/protobuf/ +# at src/google/protobuf/descriptor.proto regenerate: echo WARNING! THIS RULE IS PROBABLY NOT RIGHT FOR YOUR INSTALLATION - cd $(HOME)/src/protobuf-2.5.0/src && \ + cd $(HOME)/src/protobuf/src && \ protoc --go_out=. ./google/protobuf/descriptor.proto && \ - cp ./google/protobuf/descriptor.pb.go $(GOPATH)/src/code.google.com/p/goprotobuf/protoc-gen-go/descriptor/descriptor.pb.go + sed -i 's,^package google_protobuf,package descriptor,' google/protobuf/descriptor.pb.go && \ + cp ./google/protobuf/descriptor.pb.go $(GOPATH)/src/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go restore: cp descriptor.pb.golden descriptor.pb.go diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/doc.go golang-goprotobuf-0.0~git20150526/protoc-gen-go/doc.go --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/doc.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/doc.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -45,7 +45,7 @@ the library. See the README and documentation for protocol buffers to learn more: - http://code.google.com/p/protobuf/ + https://developers.google.com/protocol-buffers/ */ package documentation diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/generator/generator.go golang-goprotobuf-0.0~git20150526/protoc-gen-go/generator/generator.go --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/generator/generator.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/generator/generator.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -50,9 +50,10 @@ "unicode" "unicode/utf8" - "code.google.com/p/goprotobuf/proto" - descriptor "code.google.com/p/goprotobuf/protoc-gen-go/descriptor" - plugin "code.google.com/p/goprotobuf/protoc-gen-go/plugin" + "github.com/golang/protobuf/proto" + + "github.com/golang/protobuf/protoc-gen-go/descriptor" + plugin "github.com/golang/protobuf/protoc-gen-go/plugin" ) // A Plugin provides functionality to add to the output during Go code generation, @@ -95,6 +96,12 @@ func (c *common) File() *descriptor.FileDescriptorProto { return c.file } +func fileIsProto3(file *descriptor.FileDescriptorProto) bool { + return file.GetSyntax() == "proto3" +} + +func (c *common) proto3() bool { return fileIsProto3(c.file) } + // Descriptor represents a protocol buffer message. type Descriptor struct { common @@ -134,6 +141,7 @@ *descriptor.EnumDescriptorProto parent *Descriptor // The containing message, if any. typename []string // Cached typename vector. + index int // The index into the container, whether the file or a message. path string // The SourceCodeInfo path as comma-separated integers. } @@ -159,13 +167,12 @@ // Everything but the last element of the full type name, CamelCased. // The values of type Foo.Bar are call Foo_value1... not Foo_Bar_value1... . func (e *EnumDescriptor) prefix() string { - typeName := e.TypeName() - ccPrefix := CamelCaseSlice(typeName[0:len(typeName)-1]) + "_" if e.parent == nil { // If the enum is not part of a message, the prefix is just the type name. - ccPrefix = CamelCase(*e.Name) + "_" + return CamelCase(*e.Name) + "_" } - return ccPrefix + typeName := e.TypeName() + return CamelCaseSlice(typeName[0:len(typeName)-1]) + "_" } // The integer value of the named constant in this enumerated type. @@ -239,6 +246,10 @@ // as a map from the exported object to its symbols. // This is used for supporting public imports. exported map[Object][]symbol + + index int // The index of this file in the list of files to generate code for + + proto3 bool // whether to generate proto3 code for this file } // PackageName is the package name we'll use in the generated code to refer to this file. @@ -309,6 +320,7 @@ } } for _, get := range ms.getters { + if get.typeName != "" { g.RecordTypeUse(get.typeName) } @@ -364,16 +376,24 @@ g.P("func (m *", ms.sym, ") ", get.name, "() ", typ, " { return ", val, " }") } + } -type enumSymbol string +type enumSymbol struct { + name string + proto3 bool // Whether this came from a proto3 file. +} func (es enumSymbol) GenerateAlias(g *Generator, pkg string) { - s := string(es) + s := es.name g.P("type ", s, " ", pkg, ".", s) g.P("var ", s, "_name = ", pkg, ".", s, "_name") g.P("var ", s, "_value = ", pkg, ".", s, "_value") - g.P("func New", s, "(x ", s, ") *", s, " { e := ", s, "(x); return &e }") + g.P("func (x ", s, ") String() string { return (", pkg, ".", s, ")(x).String() }") + if !es.proto3 { + g.P("func (x ", s, ") Enum() *", s, "{ return (*", s, ")((", pkg, ".", s, ")(x).Enum()) }") + g.P("func (x *", s, ") UnmarshalJSON(data []byte) error { return (*", pkg, ".", s, ")(x).UnmarshalJSON(data) }") + } } type constOrVarSymbol struct { @@ -469,18 +489,36 @@ } g.ImportMap = make(map[string]string) + pluginList := "none" // Default list of plugin names to enable (empty means all). for k, v := range g.Param { switch k { case "import_prefix": g.ImportPrefix = v case "import_path": g.PackageImportPath = v + case "plugins": + pluginList = v default: if len(k) > 0 && k[0] == 'M' { g.ImportMap[k[1:]] = v } } } + + if pluginList != "" { + // Amend the set of plugins. + enabled := make(map[string]bool) + for _, name := range strings.Split(pluginList, "+") { + enabled[name] = true + } + var nplugins []Plugin + for _, p := range plugins { + if enabled[p.Name()] { + nplugins = append(nplugins, p) + } + } + plugins = nplugins + } } // DefaultPackageName returns the package name printed for the object. @@ -618,7 +656,6 @@ // Register the support package names. They might collide with the // name of a package we import. g.Pkg = map[string]string{ - "json": RegisterUniquePackageName("json", nil), "math": RegisterUniquePackageName("math", nil), "proto": RegisterUniquePackageName("proto", nil), } @@ -661,6 +698,7 @@ ext: exts, imp: imps, exported: make(map[Object][]symbol), + proto3: fileIsProto3(f), } extractComments(fd) g.allFiles[i] = fd @@ -673,6 +711,7 @@ for _, file := range g.allFiles { if fileName == file.GetName() { g.genFiles[i] = file + file.index = i continue FindFiles } } @@ -763,6 +802,7 @@ common: common{file}, EnumDescriptorProto: desc, parent: parent, + index: index, } if parent == nil { ed.path = fmt.Sprintf("%d,%d", enumPath, index) @@ -994,6 +1034,10 @@ g.generateEnum(enum) } for _, desc := range g.file.desc { + // Don't generate virtual messages for maps. + if desc.GetOptions().GetMapEntry() { + continue + } g.generateMessage(desc) } for _, ext := range g.file.ext { @@ -1028,10 +1072,44 @@ // Generate the header, including package definition func (g *Generator) generateHeader() { g.P("// Code generated by protoc-gen-go.") - g.P("// source: ", *g.file.Name) + g.P("// source: ", g.file.Name) g.P("// DO NOT EDIT!") g.P() - g.P("package ", g.file.PackageName()) + + name := g.file.PackageName() + + if g.file.index == 0 { + // Generate package docs for the first file in the package. + g.P("/*") + g.P("Package ", name, " is a generated protocol buffer package.") + g.P() + if loc, ok := g.file.comments[strconv.Itoa(packagePath)]; ok { + // not using g.PrintComments because this is a /* */ comment block. + text := strings.TrimSuffix(loc.GetLeadingComments(), "\n") + for _, line := range strings.Split(text, "\n") { + line = strings.TrimPrefix(line, " ") + // ensure we don't escape from the block comment + line = strings.Replace(line, "*/", "* /", -1) + g.P(line) + } + g.P() + } + g.P("It is generated from these files:") + for _, f := range g.genFiles { + g.P("\t", f.Name) + } + g.P() + g.P("It has these top-level messages:") + for _, msg := range g.file.desc { + if msg.parent != nil { + continue + } + g.P("\t", CamelCaseSlice(msg.TypeName())) + } + g.P("*/") + } + + g.P("package ", name) g.P() } @@ -1071,11 +1149,11 @@ // We almost always need a proto import. Rather than computing when we // do, which is tricky when there's a plugin, just import it and // reference it later. The same argument applies to the math package, - // for handling bit patterns for floating-point numbers, and to the - // json package, for symbolic names of enum values for JSON marshaling. - g.P("import " + g.Pkg["proto"] + " " + strconv.Quote(g.ImportPrefix+"code.google.com/p/goprotobuf/proto")) - g.P("import " + g.Pkg["json"] + ` "encoding/json"`) - g.P("import " + g.Pkg["math"] + ` "math"`) + // for handling bit patterns for floating-point numbers. + g.P("import " + g.Pkg["proto"] + " " + strconv.Quote(g.ImportPrefix+"github.com/golang/protobuf/proto")) + if !g.file.proto3 { + g.P("import " + g.Pkg["math"] + ` "math"`) + } for i, s := range g.file.Dependency { fd := g.fileByName(s) // Do not import our own package. @@ -1083,26 +1161,25 @@ continue } filename := goFileName(s) + // By default, import path is the dirname of the Go filename. + importPath := path.Dir(filename) if substitution, ok := g.ImportMap[s]; ok { - filename = substitution - } - filename = g.ImportPrefix + filename - if strings.HasSuffix(filename, ".go") { - filename = filename[0 : len(filename)-3] + importPath = substitution } + importPath = g.ImportPrefix + importPath // Skip weak imports. if g.weak(int32(i)) { - g.P("// skipping weak import ", fd.PackageName(), " ", strconv.Quote(filename)) + g.P("// skipping weak import ", fd.PackageName(), " ", strconv.Quote(importPath)) continue } if _, ok := g.usedPackages[fd.PackageName()]; ok { - g.P("import ", fd.PackageName(), " ", strconv.Quote(filename)) + g.P("import ", fd.PackageName(), " ", strconv.Quote(importPath)) } else { // TODO: Re-enable this when we are more feature-complete. // For instance, some protos use foreign field extensions, which we don't support. // Until then, this is just annoying spam. //log.Printf("protoc-gen-go: discarding unused import from %v: %v", *g.file.Name, s) - g.P("// discarding unused import ", fd.PackageName(), " ", strconv.Quote(filename)) + g.P("// discarding unused import ", fd.PackageName(), " ", strconv.Quote(importPath)) } } g.P() @@ -1111,10 +1188,11 @@ p.GenerateImports(g.file) g.P() } - g.P("// Reference proto, json, and math imports to suppress error if they are not otherwise used.") + g.P("// Reference imports to suppress errors if they are not otherwise used.") g.P("var _ = ", g.Pkg["proto"], ".Marshal") - g.P("var _ = &", g.Pkg["json"], ".SyntaxError{}") - g.P("var _ = ", g.Pkg["math"], ".Inf") + if !g.file.proto3 { + g.P("var _ = ", g.Pkg["math"], ".Inf") + } g.P() } @@ -1154,7 +1232,7 @@ g.PrintComments(enum.path) g.P("type ", ccTypeName, " int32") - g.file.addExport(enum, enumSymbol(ccTypeName)) + g.file.addExport(enum, enumSymbol{ccTypeName, enum.proto3()}) g.P("const (") g.In() for i, e := range enum.Value { @@ -1187,13 +1265,15 @@ g.Out() g.P("}") - g.P("func (x ", ccTypeName, ") Enum() *", ccTypeName, " {") - g.In() - g.P("p := new(", ccTypeName, ")") - g.P("*p = x") - g.P("return p") - g.Out() - g.P("}") + if !enum.proto3() { + g.P("func (x ", ccTypeName, ") Enum() *", ccTypeName, " {") + g.In() + g.P("p := new(", ccTypeName, ")") + g.P("*p = x") + g.P("return p") + g.Out() + g.P("}") + } g.P("func (x ", ccTypeName, ") String() string {") g.In() @@ -1201,24 +1281,20 @@ g.Out() g.P("}") - g.P("func (x ", ccTypeName, ") MarshalJSON() ([]byte, error) {") - g.In() - g.P("return json.Marshal(x.String())") - g.Out() - g.P("}") - - g.P("func (x *", ccTypeName, ") UnmarshalJSON(data []byte) error {") - g.In() - g.P("value, err := ", g.Pkg["proto"], ".UnmarshalJSONEnum(", ccTypeName, `_value, data, "`, ccTypeName, `")`) - g.P("if err != nil {") - g.In() - g.P("return err") - g.Out() - g.P("}") - g.P("*x = ", ccTypeName, "(value)") - g.P("return nil") - g.Out() - g.P("}") + if !enum.proto3() { + g.P("func (x *", ccTypeName, ") UnmarshalJSON(data []byte) error {") + g.In() + g.P("value, err := ", g.Pkg["proto"], ".UnmarshalJSONEnum(", ccTypeName, `_value, data, "`, ccTypeName, `")`) + g.P("if err != nil {") + g.In() + g.P("return err") + g.Out() + g.P("}") + g.P("*x = ", ccTypeName, "(value)") + g.P("return nil") + g.Out() + g.P("}") + } g.P() } @@ -1232,10 +1308,11 @@ // packed whether the encoding is "packed" (optional; repeated primitives only) // name= the original declared name // enum= the name of the enum type if it is an enum-typed field. +// proto3 if this field is in a proto3 message // def= string representation of the default value, if any. // The default value must be in a representation that can be used at run-time // to generate the default value. Thus bools become 0 and 1, for instance. -func (g *Generator) goTag(field *descriptor.FieldDescriptorProto, wiretype string) string { +func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptorProto, wiretype string) string { optrepreq := "" switch { case isOptional(field): @@ -1245,8 +1322,10 @@ case isRepeated(field): optrepreq = "rep" } - defaultValue := field.GetDefaultValue() - if defaultValue != "" { + var defaultValue string + if dv := field.DefaultValue; dv != nil { // set means an explicit default + defaultValue = *dv + // Some types need tweaking. switch *field.Type { case descriptor.FieldDescriptorProto_TYPE_BOOL: if defaultValue == "true" { @@ -1312,6 +1391,13 @@ } else { name = ",name=" + name } + if message.proto3() { + // We only need the extra tag for []byte fields; + // no need to add noise for the others. + if *field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES { + name += ",proto3" + } + } return strconv.Quote(fmt.Sprintf("%s,%d,%s%s%s%s%s", wiretype, field.GetNumber(), @@ -1397,6 +1483,8 @@ } if isRepeated(field) { typ = "[]" + typ + } else if message != nil && message.proto3() { + return } else if needsStar(*field.Type) { typ = "*" + typ } @@ -1437,6 +1525,7 @@ } fieldNames := make(map[*descriptor.FieldDescriptorProto]string) fieldGetterNames := make(map[*descriptor.FieldDescriptorProto]string) + mapFieldTypes := make(map[*descriptor.FieldDescriptorProto]string) g.PrintComments(message.path) g.P("type ", ccTypeName, " struct {") @@ -1453,7 +1542,38 @@ usedNames[fieldName] = true typename, wiretype := g.GoType(message, field) jsonName := *field.Name - tag := fmt.Sprintf("protobuf:%s json:%q", g.goTag(field, wiretype), jsonName+",omitempty") + tag := fmt.Sprintf("protobuf:%s json:%q", g.goTag(message, field, wiretype), jsonName+",omitempty") + + if *field.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE { + desc := g.ObjectNamed(field.GetTypeName()) + if d, ok := desc.(*Descriptor); ok && d.GetOptions().GetMapEntry() { + // Figure out the Go types and tags for the key and value types. + keyField, valField := d.Field[0], d.Field[1] + keyType, keyWire := g.GoType(d, keyField) + valType, valWire := g.GoType(d, valField) + keyTag, valTag := g.goTag(d, keyField, keyWire), g.goTag(d, valField, valWire) + + // We don't use stars, except for message-typed values. + // Message and enum types are the only two possibly foreign types used in maps, + // so record their use. They are not permitted as map keys. + keyType = strings.TrimPrefix(keyType, "*") + switch *valField.Type { + case descriptor.FieldDescriptorProto_TYPE_ENUM: + valType = strings.TrimPrefix(valType, "*") + g.RecordTypeUse(valField.GetTypeName()) + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + g.RecordTypeUse(valField.GetTypeName()) + default: + valType = strings.TrimPrefix(valType, "*") + } + + typename = fmt.Sprintf("map[%s]%s", keyType, valType) + mapFieldTypes[field] = typename // record for the getter generation + + tag += fmt.Sprintf(" protobuf_key:%s protobuf_val:%s", keyTag, valTag) + } + } + fieldNames[field] = fieldName fieldGetterNames[field] = fieldGetterName g.P(fieldName, "\t", typename, "\t`", tag, "`") @@ -1462,7 +1582,9 @@ if len(message.ExtensionRange) > 0 { g.P("XXX_extensions\t\tmap[int32]", g.Pkg["proto"], ".Extension `json:\"-\"`") } - g.P("XXX_unrecognized\t[]byte `json:\"-\"`") + if !message.proto3() { + g.P("XXX_unrecognized\t[]byte `json:\"-\"`") + } g.Out() g.P("}") @@ -1489,6 +1611,16 @@ g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSet(buf, m.ExtensionMap())") g.Out() g.P("}") + g.P("func (m *", ccTypeName, ") MarshalJSON() ([]byte, error) {") + g.In() + g.P("return ", g.Pkg["proto"], ".MarshalMessageSetJSON(m.XXX_extensions)") + g.Out() + g.P("}") + g.P("func (m *", ccTypeName, ") UnmarshalJSON(buf []byte) error {") + g.In() + g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSetJSON(buf, m.XXX_extensions)") + g.Out() + g.P("}") g.P("// ensure ", ccTypeName, " satisfies proto.Marshaler and proto.Unmarshaler") g.P("var _ ", g.Pkg["proto"], ".Marshaler = (*", ccTypeName, ")(nil)") g.P("var _ ", g.Pkg["proto"], ".Unmarshaler = (*", ccTypeName, ")(nil)") @@ -1581,6 +1713,9 @@ for _, field := range message.Field { fname := fieldNames[field] typename, _ := g.GoType(message, field) + if t, ok := mapFieldTypes[field]; ok { + typename = t + } mname := "Get" + fieldGetterNames[field] star := "" if needsStar(*field.Type) && typename[0] == '*' { @@ -1588,6 +1723,11 @@ star = "*" } + // In proto3, only generate getters for message fields. + if message.proto3() && *field.Type != descriptor.FieldDescriptorProto_TYPE_MESSAGE { + continue + } + // Only export getter symbols for basic types, // and for messages and enums in the same package. // Groups are not exported. @@ -1664,6 +1804,27 @@ g.P("return false") case descriptor.FieldDescriptorProto_TYPE_STRING: g.P(`return ""`) + case descriptor.FieldDescriptorProto_TYPE_ENUM: + // The default default for an enum is the first value in the enum, + // not zero. + obj := g.ObjectNamed(field.GetTypeName()) + var enum *EnumDescriptor + if id, ok := obj.(*ImportedDescriptor); ok { + // The enum type has been publicly imported. + enum, _ = id.o.(*EnumDescriptor) + } else { + enum, _ = obj.(*EnumDescriptor) + } + if enum == nil { + log.Printf("don't know how to generate getter for %s", field.GetName()) + continue + } + if len(enum.Value) == 0 { + g.P("return 0 // empty enum") + } else { + first := enum.Value[0].GetName() + g.P("return ", g.DefaultPackageName(obj)+enum.prefix()+first) + } default: g.P("return 0") } @@ -1674,7 +1835,8 @@ } if !message.group { - g.file.addExport(message, &messageSymbol{ccTypeName, hasExtensions, isMessageSet, getters}) + ms := &messageSymbol{sym: ccTypeName, hasExtensions: hasExtensions, isMessageSet: isMessageSet, getters: getters} + g.file.addExport(message, ms) } for _, ext := range message.ext { @@ -1686,10 +1848,11 @@ func (g *Generator) generateExtension(ext *ExtensionDescriptor) { ccTypeName := ext.DescName() - extendedType := "*" + g.TypeName(g.ObjectNamed(*ext.Extendee)) + extDesc := g.ObjectNamed(*ext.Extendee).(*Descriptor) + extendedType := "*" + g.TypeName(extDesc) field := ext.FieldDescriptorProto fieldType, wireType := g.GoType(ext.parent, field) - tag := g.goTag(field, wireType) + tag := g.goTag(extDesc, field, wireType) g.RecordTypeUse(*ext.Extendee) if n := ext.FieldDescriptorProto.TypeName; n != nil { // foreign extension type @@ -1701,8 +1864,10 @@ // Special case for proto2 message sets: If this extension is extending // proto2_bridge.MessageSet, and its final name component is "message_set_extension", // then drop that last component. + mset := false if extendedType == "*proto2_bridge.MessageSet" && typeName[len(typeName)-1] == "message_set_extension" { typeName = typeName[:len(typeName)-1] + mset = true } // For text formatting, the package must be exactly what the .proto file declares, @@ -1724,6 +1889,15 @@ g.P("}") g.P() + if mset { + // Generate a bit more code to register with message_set.go. + g.P("func init() { ") + g.In() + g.P(g.Pkg["proto"], ".RegisterMessageSetType((", fieldType, ")(nil), ", field.Number, ", \"", extName, "\")") + g.Out() + g.P("}") + } + g.file.addExport(ext, constOrVarSymbol{ccTypeName, "var", ""}) } @@ -1885,6 +2059,7 @@ // See descriptor.proto for more information about this. const ( // tag numbers in FileDescriptorProto + packagePath = 2 // package messagePath = 4 // message_type enumPath = 5 // enum_type // tag numbers in DescriptorProto diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/generator/Makefile golang-goprotobuf-0.0~git20150526/protoc-gen-go/generator/Makefile --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/generator/Makefile 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/generator/Makefile 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ # Go support for Protocol Buffers - Google's data interchange format # # Copyright 2010 The Go Authors. All rights reserved. -# http://code.google.com/p/goprotobuf/ +# 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 @@ -31,7 +31,7 @@ include $(GOROOT)/src/Make.inc -TARG=code.google.com/p/goprotobuf/compiler/generator +TARG=github.com/golang/protobuf/compiler/generator GOFILES=\ generator.go\ diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/generator/name_test.go golang-goprotobuf-0.0~git20150526/protoc-gen-go/generator/name_test.go --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/generator/name_test.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/generator/name_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2013 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/internal/grpc/grpc.go golang-goprotobuf-0.0~git20150526/protoc-gen-go/internal/grpc/grpc.go --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/internal/grpc/grpc.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/internal/grpc/grpc.go 2015-06-13 14:23:31.000000000 +0000 @@ -0,0 +1,436 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2015 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 grpc outputs gRPC service descriptions in Go code. +// It runs as a plugin for the Go protocol buffer compiler plugin. +// It is linked in to protoc-gen-go. +package grpc + +import ( + "fmt" + "path" + "strconv" + "strings" + + pb "github.com/golang/protobuf/protoc-gen-go/descriptor" + "github.com/golang/protobuf/protoc-gen-go/generator" +) + +// Paths for packages used by code generated in this file, +// relative to the import_prefix of the generator.Generator. +const ( + contextPkgPath = "golang.org/x/net/context" + grpcPkgPath = "google.golang.org/grpc" +) + +func init() { + generator.RegisterPlugin(new(grpc)) +} + +// grpc is an implementation of the Go protocol buffer compiler's +// plugin architecture. It generates bindings for gRPC support. +type grpc struct { + gen *generator.Generator +} + +// Name returns the name of this plugin, "grpc". +func (g *grpc) Name() string { + return "grpc" +} + +// The names for packages imported in the generated code. +// They may vary from the final path component of the import path +// if the name is used by other packages. +var ( + contextPkg string + grpcPkg string +) + +// Init initializes the plugin. +func (g *grpc) Init(gen *generator.Generator) { + g.gen = gen + contextPkg = generator.RegisterUniquePackageName("context", nil) + grpcPkg = generator.RegisterUniquePackageName("grpc", nil) +} + +// Given a type name defined in a .proto, return its object. +// Also record that we're using it, to guarantee the associated import. +func (g *grpc) objectNamed(name string) generator.Object { + g.gen.RecordTypeUse(name) + return g.gen.ObjectNamed(name) +} + +// Given a type name defined in a .proto, return its name as we will print it. +func (g *grpc) typeName(str string) string { + return g.gen.TypeName(g.objectNamed(str)) +} + +// P forwards to g.gen.P. +func (g *grpc) P(args ...interface{}) { g.gen.P(args...) } + +// Generate generates code for the services in the given file. +func (g *grpc) Generate(file *generator.FileDescriptor) { + for i, service := range file.FileDescriptorProto.Service { + g.generateService(file, service, i) + } +} + +// GenerateImports generates the import declaration for this file. +func (g *grpc) GenerateImports(file *generator.FileDescriptor) { + if len(file.FileDescriptorProto.Service) == 0 { + return + } + g.P("import (") + g.P(contextPkg, " ", strconv.Quote(path.Join(g.gen.ImportPrefix, contextPkgPath))) + g.P(grpcPkg, " ", strconv.Quote(path.Join(g.gen.ImportPrefix, grpcPkgPath))) + g.P(")") + g.P() + g.P("// Reference imports to suppress errors if they are not otherwise used.") + g.P("var _ ", contextPkg, ".Context") + g.P("var _ ", grpcPkg, ".ClientConn") + g.P() +} + +// reservedClientName records whether a client name is reserved on the client side. +var reservedClientName = map[string]bool{ +// TODO: do we need any in gRPC? +} + +func unexport(s string) string { return strings.ToLower(s[:1]) + s[1:] } + +// generateService generates all the code for the named service. +func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.ServiceDescriptorProto, index int) { + path := fmt.Sprintf("6,%d", index) // 6 means service. + + origServName := service.GetName() + fullServName := file.GetPackage() + "." + origServName + servName := generator.CamelCase(origServName) + + g.P() + g.P("// Client API for ", servName, " service") + g.P() + + // Client interface. + g.P("type ", servName, "Client interface {") + for i, method := range service.Method { + g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service. + g.P(g.generateClientSignature(servName, method)) + } + g.P("}") + g.P() + + // Client structure. + g.P("type ", unexport(servName), "Client struct {") + g.P("cc *", grpcPkg, ".ClientConn") + g.P("}") + g.P() + + // NewClient factory. + g.P("func New", servName, "Client (cc *", grpcPkg, ".ClientConn) ", servName, "Client {") + g.P("return &", unexport(servName), "Client{cc}") + g.P("}") + g.P() + + var methodIndex, streamIndex int + serviceDescVar := "_" + servName + "_serviceDesc" + // Client method implementations. + for _, method := range service.Method { + var descExpr string + if !method.GetServerStreaming() && !method.GetClientStreaming() { + // Unary RPC method + descExpr = fmt.Sprintf("&%s.Methods[%d]", serviceDescVar, methodIndex) + methodIndex++ + } else { + // Streaming RPC method + descExpr = fmt.Sprintf("&%s.Streams[%d]", serviceDescVar, streamIndex) + streamIndex++ + } + g.generateClientMethod(servName, fullServName, serviceDescVar, method, descExpr) + } + + g.P("// Server API for ", servName, " service") + g.P() + + // Server interface. + serverType := servName + "Server" + g.P("type ", serverType, " interface {") + for i, method := range service.Method { + g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service. + g.P(g.generateServerSignature(servName, method)) + } + g.P("}") + g.P() + + // Server registration. + g.P("func Register", servName, "Server(s *", grpcPkg, ".Server, srv ", serverType, ") {") + g.P("s.RegisterService(&", serviceDescVar, `, srv)`) + g.P("}") + g.P() + + // Server handler implementations. + var handlerNames []string + for _, method := range service.Method { + hname := g.generateServerMethod(servName, method) + handlerNames = append(handlerNames, hname) + } + + // Service descriptor. + g.P("var ", serviceDescVar, " = ", grpcPkg, ".ServiceDesc {") + g.P("ServiceName: ", strconv.Quote(fullServName), ",") + g.P("HandlerType: (*", serverType, ")(nil),") + g.P("Methods: []", grpcPkg, ".MethodDesc{") + for i, method := range service.Method { + if method.GetServerStreaming() || method.GetClientStreaming() { + continue + } + g.P("{") + g.P("MethodName: ", strconv.Quote(method.GetName()), ",") + g.P("Handler: ", handlerNames[i], ",") + g.P("},") + } + g.P("},") + g.P("Streams: []", grpcPkg, ".StreamDesc{") + for i, method := range service.Method { + if !method.GetServerStreaming() && !method.GetClientStreaming() { + continue + } + g.P("{") + g.P("StreamName: ", strconv.Quote(method.GetName()), ",") + g.P("Handler: ", handlerNames[i], ",") + if method.GetServerStreaming() { + g.P("ServerStreams: true,") + } + if method.GetClientStreaming() { + g.P("ClientStreams: true,") + } + g.P("},") + } + g.P("},") + g.P("}") + g.P() +} + +// generateClientSignature returns the client-side signature for a method. +func (g *grpc) generateClientSignature(servName string, method *pb.MethodDescriptorProto) string { + origMethName := method.GetName() + methName := generator.CamelCase(origMethName) + if reservedClientName[methName] { + methName += "_" + } + reqArg := ", in *" + g.typeName(method.GetInputType()) + if method.GetClientStreaming() { + reqArg = "" + } + respName := "*" + g.typeName(method.GetOutputType()) + if method.GetServerStreaming() || method.GetClientStreaming() { + respName = servName + "_" + generator.CamelCase(origMethName) + "Client" + } + return fmt.Sprintf("%s(ctx %s.Context%s, opts ...%s.CallOption) (%s, error)", methName, contextPkg, reqArg, grpcPkg, respName) +} + +func (g *grpc) generateClientMethod(servName, fullServName, serviceDescVar string, method *pb.MethodDescriptorProto, descExpr string) { + sname := fmt.Sprintf("/%s/%s", fullServName, method.GetName()) + methName := generator.CamelCase(method.GetName()) + inType := g.typeName(method.GetInputType()) + outType := g.typeName(method.GetOutputType()) + + g.P("func (c *", unexport(servName), "Client) ", g.generateClientSignature(servName, method), "{") + if !method.GetServerStreaming() && !method.GetClientStreaming() { + g.P("out := new(", outType, ")") + // TODO: Pass descExpr to Invoke. + g.P("err := ", grpcPkg, `.Invoke(ctx, "`, sname, `", in, out, c.cc, opts...)`) + g.P("if err != nil { return nil, err }") + g.P("return out, nil") + g.P("}") + g.P() + return + } + streamType := unexport(servName) + methName + "Client" + g.P("stream, err := ", grpcPkg, ".NewClientStream(ctx, ", descExpr, `, c.cc, "`, sname, `", opts...)`) + g.P("if err != nil { return nil, err }") + g.P("x := &", streamType, "{stream}") + if !method.GetClientStreaming() { + g.P("if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }") + g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }") + } + g.P("return x, nil") + g.P("}") + g.P() + + genSend := method.GetClientStreaming() + genRecv := method.GetServerStreaming() + genCloseAndRecv := !method.GetServerStreaming() + + // Stream auxiliary types and methods. + g.P("type ", servName, "_", methName, "Client interface {") + if genSend { + g.P("Send(*", inType, ") error") + } + if genRecv { + g.P("Recv() (*", outType, ", error)") + } + if genCloseAndRecv { + g.P("CloseAndRecv() (*", outType, ", error)") + } + g.P(grpcPkg, ".ClientStream") + g.P("}") + g.P() + + g.P("type ", streamType, " struct {") + g.P(grpcPkg, ".ClientStream") + g.P("}") + g.P() + + if genSend { + g.P("func (x *", streamType, ") Send(m *", inType, ") error {") + g.P("return x.ClientStream.SendMsg(m)") + g.P("}") + g.P() + } + if genRecv { + g.P("func (x *", streamType, ") Recv() (*", outType, ", error) {") + g.P("m := new(", outType, ")") + g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") + g.P("return m, nil") + g.P("}") + g.P() + } + if genCloseAndRecv { + g.P("func (x *", streamType, ") CloseAndRecv() (*", outType, ", error) {") + g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }") + g.P("m := new(", outType, ")") + g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") + g.P("return m, nil") + g.P("}") + g.P() + } +} + +// generateServerSignature returns the server-side signature for a method. +func (g *grpc) generateServerSignature(servName string, method *pb.MethodDescriptorProto) string { + origMethName := method.GetName() + methName := generator.CamelCase(origMethName) + if reservedClientName[methName] { + methName += "_" + } + + var reqArgs []string + ret := "error" + if !method.GetServerStreaming() && !method.GetClientStreaming() { + reqArgs = append(reqArgs, contextPkg+".Context") + ret = "(*" + g.typeName(method.GetOutputType()) + ", error)" + } + if !method.GetClientStreaming() { + reqArgs = append(reqArgs, "*"+g.typeName(method.GetInputType())) + } + if method.GetServerStreaming() || method.GetClientStreaming() { + reqArgs = append(reqArgs, servName+"_"+generator.CamelCase(origMethName)+"Server") + } + + return methName + "(" + strings.Join(reqArgs, ", ") + ") " + ret +} + +func (g *grpc) generateServerMethod(servName string, method *pb.MethodDescriptorProto) string { + methName := generator.CamelCase(method.GetName()) + hname := fmt.Sprintf("_%s_%s_Handler", servName, methName) + inType := g.typeName(method.GetInputType()) + outType := g.typeName(method.GetOutputType()) + + if !method.GetServerStreaming() && !method.GetClientStreaming() { + g.P("func ", hname, "(srv interface{}, ctx ", contextPkg, ".Context, codec ", grpcPkg, ".Codec, buf []byte) (interface{}, error) {") + g.P("in := new(", inType, ")") + g.P("if err := codec.Unmarshal(buf, in); err != nil { return nil, err }") + g.P("out, err := srv.(", servName, "Server).", methName, "(ctx, in)") + g.P("if err != nil { return nil, err }") + g.P("return out, nil") + g.P("}") + g.P() + return hname + } + streamType := unexport(servName) + methName + "Server" + g.P("func ", hname, "(srv interface{}, stream ", grpcPkg, ".ServerStream) error {") + if !method.GetClientStreaming() { + g.P("m := new(", inType, ")") + g.P("if err := stream.RecvMsg(m); err != nil { return err }") + g.P("return srv.(", servName, "Server).", methName, "(m, &", streamType, "{stream})") + } else { + g.P("return srv.(", servName, "Server).", methName, "(&", streamType, "{stream})") + } + g.P("}") + g.P() + + genSend := method.GetServerStreaming() + genSendAndClose := !method.GetServerStreaming() + genRecv := method.GetClientStreaming() + + // Stream auxiliary types and methods. + g.P("type ", servName, "_", methName, "Server interface {") + if genSend { + g.P("Send(*", outType, ") error") + } + if genSendAndClose { + g.P("SendAndClose(*", outType, ") error") + } + if genRecv { + g.P("Recv() (*", inType, ", error)") + } + g.P(grpcPkg, ".ServerStream") + g.P("}") + g.P() + + g.P("type ", streamType, " struct {") + g.P(grpcPkg, ".ServerStream") + g.P("}") + g.P() + + if genSend { + g.P("func (x *", streamType, ") Send(m *", outType, ") error {") + g.P("return x.ServerStream.SendMsg(m)") + g.P("}") + g.P() + } + if genSendAndClose { + g.P("func (x *", streamType, ") SendAndClose(m *", outType, ") error {") + g.P("return x.ServerStream.SendMsg(m)") + g.P("}") + g.P() + } + if genRecv { + g.P("func (x *", streamType, ") Recv() (*", inType, ", error) {") + g.P("m := new(", inType, ")") + g.P("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }") + g.P("return m, nil") + g.P("}") + g.P() + } + + return hname +} diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/link_grpc.go golang-goprotobuf-0.0~git20150526/protoc-gen-go/link_grpc.go --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/link_grpc.go 1970-01-01 00:00:00.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/link_grpc.go 2015-06-13 14:23:31.000000000 +0000 @@ -0,0 +1,34 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2015 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 main + +import _ "github.com/golang/protobuf/protoc-gen-go/internal/grpc" diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/main.go golang-goprotobuf-0.0~git20150526/protoc-gen-go/main.go --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/main.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/main.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -29,22 +29,31 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/* - A plugin for the Google protocol buffer compiler to generate Go code. - - This plugin takes no options and the protocol buffer file syntax does - not yet define any options for Go, so program does no option evaluation. - That may change. -*/ - +// protoc-gen-go is a plugin for the Google protocol buffer compiler to generate +// Go code. Run it by building this program and putting it in your path with +// the name +// protoc-gen-go +// That word 'go' at the end becomes part of the option string set for the +// protocol compiler, so once the protocol compiler (protoc) is installed +// you can run +// protoc --go_out=output_directory input_directory/file.proto +// to generate Go bindings for the protocol defined by file.proto. +// With that input, the output will be written to +// output_directory/file.pb.go +// +// The generated code is documented in the package comment for +// the library. +// +// See the README and documentation for protocol buffers to learn more: +// https://developers.google.com/protocol-buffers/ package main import ( "io/ioutil" "os" - "code.google.com/p/goprotobuf/proto" - "code.google.com/p/goprotobuf/protoc-gen-go/generator" + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/protoc-gen-go/generator" ) func main() { diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/Makefile golang-goprotobuf-0.0~git20150526/protoc-gen-go/Makefile --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/Makefile 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/Makefile 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ # Go support for Protocol Buffers - Google's data interchange format # # Copyright 2010 The Go Authors. All rights reserved. -# http://code.google.com/p/goprotobuf/ +# 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 diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/plugin/Makefile golang-goprotobuf-0.0~git20150526/protoc-gen-go/plugin/Makefile --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/plugin/Makefile 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/plugin/Makefile 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ # Go support for Protocol Buffers - Google's data interchange format # # Copyright 2010 The Go Authors. All rights reserved. -# http://code.google.com/p/goprotobuf/ +# 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 @@ -29,15 +29,15 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# Not stored here, but plugin.proto is in http://code.google.com/p/protobuf -# at protobuf-2.5.0/src/google/protobuf/compiler/plugin.proto +# Not stored here, but plugin.proto is in https://github.com/google/protobuf/ +# at src/google/protobuf/compiler/plugin.proto # Also we need to fix an import. regenerate: echo WARNING! THIS RULE IS PROBABLY NOT RIGHT FOR YOUR INSTALLATION - cd $(HOME)/src/protobuf-2.5.0/src && \ - protoc --go_out=. ./google/protobuf/compiler/plugin.proto && \ - cat ./google/protobuf/compiler/plugin.pb.go | \ - sed '/^import/s;google/protobuf/descriptor.pb;code.google.com/p/goprotobuf/protoc-gen-go/descriptor;' > $(GOPATH)/src/code.google.com/p/goprotobuf/protoc-gen-go/plugin/plugin.pb.go + cd $(HOME)/src/protobuf/src && \ + protoc --go_out=Mgoogle/protobuf/descriptor.proto=github.com/golang/protobuf/protoc-gen-go/descriptor:. \ + ./google/protobuf/compiler/plugin.proto && \ + cat ./google/protobuf/compiler/plugin.pb.go > $(GOPATH)/src/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.go restore: cp plugin.pb.golden plugin.pb.go diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/plugin/plugin.pb.go golang-goprotobuf-0.0~git20150526/protoc-gen-go/plugin/plugin.pb.go --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/plugin/plugin.pb.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/plugin/plugin.pb.go 2015-06-13 14:23:31.000000000 +0000 @@ -2,16 +2,24 @@ // source: google/protobuf/compiler/plugin.proto // DO NOT EDIT! +/* +Package google_protobuf_compiler is a generated protocol buffer package. + +It is generated from these files: + google/protobuf/compiler/plugin.proto + +It has these top-level messages: + CodeGeneratorRequest + CodeGeneratorResponse +*/ package google_protobuf_compiler -import proto "code.google.com/p/goprotobuf/proto" -import json "encoding/json" +import proto "github.com/golang/protobuf/proto" import math "math" -import google_protobuf "code.google.com/p/goprotobuf/protoc-gen-go/descriptor" +import google_protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor" -// Reference proto, json, and math imports to suppress error if they are not otherwise used. +// Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal -var _ = &json.SyntaxError{} var _ = math.Inf // An encoded CodeGeneratorRequest is written to the plugin's stdin. diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/plugin/plugin.pb.golden golang-goprotobuf-0.0~git20150526/protoc-gen-go/plugin/plugin.pb.golden --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/plugin/plugin.pb.golden 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/plugin/plugin.pb.golden 2015-06-13 14:23:31.000000000 +0000 @@ -4,9 +4,9 @@ package google_protobuf_compiler -import proto "code.google.com/p/goprotobuf/proto" +import proto "github.com/golang/protobuf/proto" import "math" -import google_protobuf "code.google.com/p/goprotobuf/protoc-gen-go/descriptor" +import google_protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor" // Reference proto and math imports to suppress error if they are not otherwise used. var _ = proto.GetString diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/extension_base.proto golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/extension_base.proto --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/extension_base.proto 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/extension_base.proto 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -29,6 +29,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +syntax = "proto2"; + package extension_base; message BaseMessage { diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/extension_extra.proto golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/extension_extra.proto --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/extension_extra.proto 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/extension_extra.proto 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2011 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/extension_test.go golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/extension_test.go --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/extension_test.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/extension_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -40,7 +40,7 @@ "regexp" "testing" - "code.google.com/p/goprotobuf/proto" + "github.com/golang/protobuf/proto" base "extension_base.pb" user "extension_user.pb" ) diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/extension_user.proto golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/extension_user.proto --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/extension_user.proto 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/extension_user.proto 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -29,6 +29,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +syntax = "proto2"; + import "extension_base.proto"; import "extension_extra.proto"; @@ -66,7 +68,7 @@ // Extend inside the scope of another type, using a message. message LoginMessage { extend extension_base.BaseMessage { - required UserMessage user_message = 16; + optional UserMessage user_message = 16; } } diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/golden_test.go golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/golden_test.go --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/golden_test.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/golden_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2012 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/grpc.proto golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/grpc.proto --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/grpc.proto 1970-01-01 00:00:00.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/grpc.proto 2015-06-13 14:23:31.000000000 +0000 @@ -0,0 +1,59 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2015 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. + +syntax = "proto3"; + +package grpc.testing; + +message SimpleRequest { +} + +message SimpleResponse { +} + +message StreamMsg { +} + +message StreamMsg2 { +} + +service Test { + rpc UnaryCall(SimpleRequest) returns (SimpleResponse); + + // This RPC streams from the server only. + rpc Downstream(SimpleRequest) returns (stream StreamMsg); + + // This RPC streams from the client. + rpc Upstream(stream StreamMsg) returns (SimpleResponse); + + // This one streams in both directions. + rpc Bidi(stream StreamMsg) returns (stream StreamMsg2); +} diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/imp2.proto golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/imp2.proto --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/imp2.proto 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/imp2.proto 2015-06-13 14:23:31.000000000 +0000 @@ -1,6 +1,7 @@ +// Go support for Protocol Buffers - Google's data interchange format // // Copyright 2011 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -28,6 +29,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +syntax = "proto2"; + package imp; message PubliclyImportedMessage { diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/imp3.proto golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/imp3.proto --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/imp3.proto 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/imp3.proto 2015-06-13 14:23:31.000000000 +0000 @@ -1,6 +1,7 @@ +// Go support for Protocol Buffers - Google's data interchange format // // Copyright 2012 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -28,6 +29,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +syntax = "proto2"; + package imp; message ForeignImportedMessage { diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/imp.pb.go.golden golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/imp.pb.go.golden --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/imp.pb.go.golden 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/imp.pb.go.golden 2015-06-13 14:23:31.000000000 +0000 @@ -4,7 +4,7 @@ package imp -import proto "code.google.com/p/goprotobuf/proto" +import proto "github.com/golang/protobuf/proto" import "math" import "os" import imp1 "imp2.pb" diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/imp.proto golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/imp.proto --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/imp.proto 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/imp.proto 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -29,6 +29,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +syntax = "proto2"; + package imp; import "imp2.proto"; diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/main_test.go golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/main_test.go --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/main_test.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/main_test.go 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -36,11 +36,11 @@ import ( "testing" - "./multi" - "./my_test" + multipb "./multi" + mytestpb "./my_test" ) func TestLink(t *testing.T) { - _ = &multi.Multi1{} - _ = &my_test.Request{} + _ = &multipb.Multi1{} + _ = &mytestpb.Request{} } diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/Makefile golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/Makefile --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/Makefile 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/Makefile 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ # Go support for Protocol Buffers - Google's data interchange format # # Copyright 2010 The Go Authors. All rights reserved. -# http://code.google.com/p/goprotobuf/ +# 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 diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/multi/multi1.proto golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/multi/multi1.proto --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/multi/multi1.proto 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/multi/multi1.proto 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -29,10 +29,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +syntax = "proto2"; + import "multi/multi2.proto"; import "multi/multi3.proto"; -package multi; +package multitest; message Multi1 { required Multi2 multi2 = 1; diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/multi/multi2.proto golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/multi/multi2.proto --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/multi/multi2.proto 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/multi/multi2.proto 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -29,7 +29,9 @@ // (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 multi; +syntax = "proto2"; + +package multitest; message Multi2 { required int32 required_value = 1; diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/multi/multi3.proto golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/multi/multi3.proto --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/multi/multi3.proto 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/multi/multi3.proto 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -29,7 +29,9 @@ // (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 multi; +syntax = "proto2"; + +package multitest; message Multi3 { enum HatType { diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/my_test/test.pb.go golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/my_test/test.pb.go --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/my_test/test.pb.go 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/my_test/test.pb.go 2015-06-13 14:23:31.000000000 +0000 @@ -2,17 +2,31 @@ // source: my_test/test.proto // DO NOT EDIT! +/* +Package my_test is a generated protocol buffer package. + +This package holds interesting messages. + +It is generated from these files: + my_test/test.proto + +It has these top-level messages: + Request + Reply + OtherBase + ReplyExtensions + OtherReplyExtensions + OldReply +*/ package my_test -import proto "code.google.com/p/goprotobuf/proto" -import json "encoding/json" +import proto "github.com/golang/protobuf/proto" import math "math" -// discarding unused import multi2 "multi/multi1.pb" +// discarding unused import multitest2 "multi" -// Reference proto, json, and math imports to suppress error if they are not otherwise used. +// Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal -var _ = &json.SyntaxError{} var _ = math.Inf type HatType int32 @@ -40,9 +54,6 @@ func (x HatType) String() string { return proto.EnumName(HatType_name, int32(x)) } -func (x HatType) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *HatType) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(HatType_value, data, "HatType") if err != nil { @@ -80,9 +91,6 @@ func (x Days) String() string { return proto.EnumName(Days_name, int32(x)) } -func (x Days) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *Days) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(Days_value, data, "Days") if err != nil { @@ -119,9 +127,6 @@ func (x Request_Color) String() string { return proto.EnumName(Request_Color_name, int32(x)) } -func (x Request_Color) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *Request_Color) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(Request_Color_value, data, "Request_Color") if err != nil { @@ -155,9 +160,6 @@ func (x Reply_Entry_Game) String() string { return proto.EnumName(Reply_Entry_Game_name, int32(x)) } -func (x Reply_Entry_Game) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *Reply_Entry_Game) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(Reply_Entry_Game_value, data, "Reply_Entry_Game") if err != nil { @@ -174,10 +176,14 @@ Hue *Request_Color `protobuf:"varint,3,opt,name=hue,enum=my.test.Request_Color" json:"hue,omitempty"` Hat *HatType `protobuf:"varint,4,opt,name=hat,enum=my.test.HatType,def=1" json:"hat,omitempty"` // optional imp.ImportedMessage.Owner owner = 6; - Deadline *float32 `protobuf:"fixed32,7,opt,name=deadline,def=inf" json:"deadline,omitempty"` - Somegroup *Request_SomeGroup `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"` - Reset_ *int32 `protobuf:"varint,12,opt,name=reset" json:"reset,omitempty"` - XXX_unrecognized []byte `json:"-"` + Deadline *float32 `protobuf:"fixed32,7,opt,name=deadline,def=inf" json:"deadline,omitempty"` + Somegroup *Request_SomeGroup `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"` + // This is a map field. It will generate map[int32]string. + NameMapping map[int32]string `protobuf:"bytes,14,rep,name=name_mapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // This is a map field whose value type is a message. + MsgMapping map[int64]*Reply `protobuf:"bytes,15,rep,name=msg_mapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Reset_ *int32 `protobuf:"varint,12,opt,name=reset" json:"reset,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *Request) Reset() { *m = Request{} } @@ -199,7 +205,7 @@ if m != nil && m.Hue != nil { return *m.Hue } - return 0 + return Request_RED } func (m *Request) GetHat() HatType { @@ -223,6 +229,20 @@ return nil } +func (m *Request) GetNameMapping() map[int32]string { + if m != nil { + return m.NameMapping + } + return nil +} + +func (m *Request) GetMsgMapping() map[int64]*Reply { + if m != nil { + return m.MsgMapping + } + return nil +} + func (m *Request) GetReset_() int32 { if m != nil && m.Reset_ != nil { return *m.Reset_ @@ -319,6 +339,37 @@ return 0 } +type OtherBase struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OtherBase) Reset() { *m = OtherBase{} } +func (m *OtherBase) String() string { return proto.CompactTextString(m) } +func (*OtherBase) ProtoMessage() {} + +var extRange_OtherBase = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*OtherBase) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_OtherBase +} +func (m *OtherBase) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +func (m *OtherBase) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + type ReplyExtensions struct { XXX_unrecognized []byte `json:"-"` } @@ -335,6 +386,38 @@ Tag: "fixed64,101,opt,name=time", } +var E_ReplyExtensions_Carrot = &proto.ExtensionDesc{ + ExtendedType: (*Reply)(nil), + ExtensionType: (*ReplyExtensions)(nil), + Field: 105, + Name: "my.test.ReplyExtensions.carrot", + Tag: "bytes,105,opt,name=carrot", +} + +var E_ReplyExtensions_Donut = &proto.ExtensionDesc{ + ExtendedType: (*OtherBase)(nil), + ExtensionType: (*ReplyExtensions)(nil), + Field: 101, + Name: "my.test.ReplyExtensions.donut", + Tag: "bytes,101,opt,name=donut", +} + +type OtherReplyExtensions struct { + Key *int32 `protobuf:"varint,1,opt,name=key" json:"key,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OtherReplyExtensions) Reset() { *m = OtherReplyExtensions{} } +func (m *OtherReplyExtensions) String() string { return proto.CompactTextString(m) } +func (*OtherReplyExtensions) ProtoMessage() {} + +func (m *OtherReplyExtensions) GetKey() int32 { + if m != nil && m.Key != nil { + return *m.Key + } + return 0 +} + type OldReply struct { XXX_extensions map[int32]proto.Extension `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -350,6 +433,12 @@ func (m *OldReply) Unmarshal(buf []byte) error { return proto.UnmarshalMessageSet(buf, m.ExtensionMap()) } +func (m *OldReply) MarshalJSON() ([]byte, error) { + return proto.MarshalMessageSetJSON(m.XXX_extensions) +} +func (m *OldReply) UnmarshalJSON(buf []byte) error { + return proto.UnmarshalMessageSetJSON(buf, m.XXX_extensions) +} // ensure OldReply satisfies proto.Marshaler and proto.Unmarshaler var _ proto.Marshaler = (*OldReply)(nil) @@ -377,11 +466,22 @@ Tag: "bytes,103,opt,name=tag", } +var E_Donut = &proto.ExtensionDesc{ + ExtendedType: (*Reply)(nil), + ExtensionType: (*OtherReplyExtensions)(nil), + Field: 106, + Name: "my.test.donut", + Tag: "bytes,106,opt,name=donut", +} + func init() { proto.RegisterEnum("my.test.HatType", HatType_name, HatType_value) proto.RegisterEnum("my.test.Days", Days_name, Days_value) proto.RegisterEnum("my.test.Request_Color", Request_Color_name, Request_Color_value) proto.RegisterEnum("my.test.Reply_Entry_Game", Reply_Entry_Game_name, Reply_Entry_Game_value) proto.RegisterExtension(E_ReplyExtensions_Time) + proto.RegisterExtension(E_ReplyExtensions_Carrot) + proto.RegisterExtension(E_ReplyExtensions_Donut) proto.RegisterExtension(E_Tag) + proto.RegisterExtension(E_Donut) } diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/my_test/test.pb.go.golden golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/my_test/test.pb.go.golden --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/my_test/test.pb.go.golden 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/my_test/test.pb.go.golden 2015-06-13 14:23:31.000000000 +0000 @@ -2,17 +2,31 @@ // source: my_test/test.proto // DO NOT EDIT! +/* +Package my_test is a generated protocol buffer package. + +This package holds interesting messages. + +It is generated from these files: + my_test/test.proto + +It has these top-level messages: + Request + Reply + OtherBase + ReplyExtensions + OtherReplyExtensions + OldReply +*/ package my_test -import proto "code.google.com/p/goprotobuf/proto" -import json "encoding/json" +import proto "github.com/golang/protobuf/proto" import math "math" -// discarding unused import multi2 "multi/multi1.pb" +// discarding unused import multitest2 "multi" -// Reference proto, json, and math imports to suppress error if they are not otherwise used. +// Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal -var _ = &json.SyntaxError{} var _ = math.Inf type HatType int32 @@ -40,9 +54,6 @@ func (x HatType) String() string { return proto.EnumName(HatType_name, int32(x)) } -func (x HatType) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *HatType) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(HatType_value, data, "HatType") if err != nil { @@ -80,9 +91,6 @@ func (x Days) String() string { return proto.EnumName(Days_name, int32(x)) } -func (x Days) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *Days) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(Days_value, data, "Days") if err != nil { @@ -119,9 +127,6 @@ func (x Request_Color) String() string { return proto.EnumName(Request_Color_name, int32(x)) } -func (x Request_Color) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *Request_Color) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(Request_Color_value, data, "Request_Color") if err != nil { @@ -155,9 +160,6 @@ func (x Reply_Entry_Game) String() string { return proto.EnumName(Reply_Entry_Game_name, int32(x)) } -func (x Reply_Entry_Game) MarshalJSON() ([]byte, error) { - return json.Marshal(x.String()) -} func (x *Reply_Entry_Game) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(Reply_Entry_Game_value, data, "Reply_Entry_Game") if err != nil { @@ -174,10 +176,14 @@ Hue *Request_Color `protobuf:"varint,3,opt,name=hue,enum=my.test.Request_Color" json:"hue,omitempty"` Hat *HatType `protobuf:"varint,4,opt,name=hat,enum=my.test.HatType,def=1" json:"hat,omitempty"` // optional imp.ImportedMessage.Owner owner = 6; - Deadline *float32 `protobuf:"fixed32,7,opt,name=deadline,def=inf" json:"deadline,omitempty"` - Somegroup *Request_SomeGroup `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"` - Reset_ *int32 `protobuf:"varint,12,opt,name=reset" json:"reset,omitempty"` - XXX_unrecognized []byte `json:"-"` + Deadline *float32 `protobuf:"fixed32,7,opt,name=deadline,def=inf" json:"deadline,omitempty"` + Somegroup *Request_SomeGroup `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"` + // This is a map field. It will generate map[int32]string. + NameMapping map[int32]string `protobuf:"bytes,14,rep,name=name_mapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // This is a map field whose value type is a message. + MsgMapping map[int64]*Reply `protobuf:"bytes,15,rep,name=msg_mapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Reset_ *int32 `protobuf:"varint,12,opt,name=reset" json:"reset,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *Request) Reset() { *m = Request{} } @@ -199,7 +205,7 @@ if m != nil && m.Hue != nil { return *m.Hue } - return 0 + return Request_RED } func (m *Request) GetHat() HatType { @@ -223,6 +229,20 @@ return nil } +func (m *Request) GetNameMapping() map[int32]string { + if m != nil { + return m.NameMapping + } + return nil +} + +func (m *Request) GetMsgMapping() map[int64]*Reply { + if m != nil { + return m.MsgMapping + } + return nil +} + func (m *Request) GetReset_() int32 { if m != nil && m.Reset_ != nil { return *m.Reset_ @@ -319,6 +339,37 @@ return 0 } +type OtherBase struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OtherBase) Reset() { *m = OtherBase{} } +func (m *OtherBase) String() string { return proto.CompactTextString(m) } +func (*OtherBase) ProtoMessage() {} + +var extRange_OtherBase = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*OtherBase) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_OtherBase +} +func (m *OtherBase) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +func (m *OtherBase) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + type ReplyExtensions struct { XXX_unrecognized []byte `json:"-"` } @@ -335,6 +386,38 @@ Tag: "fixed64,101,opt,name=time", } +var E_ReplyExtensions_Carrot = &proto.ExtensionDesc{ + ExtendedType: (*Reply)(nil), + ExtensionType: (*ReplyExtensions)(nil), + Field: 105, + Name: "my.test.ReplyExtensions.carrot", + Tag: "bytes,105,opt,name=carrot", +} + +var E_ReplyExtensions_Donut = &proto.ExtensionDesc{ + ExtendedType: (*OtherBase)(nil), + ExtensionType: (*ReplyExtensions)(nil), + Field: 101, + Name: "my.test.ReplyExtensions.donut", + Tag: "bytes,101,opt,name=donut", +} + +type OtherReplyExtensions struct { + Key *int32 `protobuf:"varint,1,opt,name=key" json:"key,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OtherReplyExtensions) Reset() { *m = OtherReplyExtensions{} } +func (m *OtherReplyExtensions) String() string { return proto.CompactTextString(m) } +func (*OtherReplyExtensions) ProtoMessage() {} + +func (m *OtherReplyExtensions) GetKey() int32 { + if m != nil && m.Key != nil { + return *m.Key + } + return 0 +} + type OldReply struct { XXX_extensions map[int32]proto.Extension `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -350,6 +433,12 @@ func (m *OldReply) Unmarshal(buf []byte) error { return proto.UnmarshalMessageSet(buf, m.ExtensionMap()) } +func (m *OldReply) MarshalJSON() ([]byte, error) { + return proto.MarshalMessageSetJSON(m.XXX_extensions) +} +func (m *OldReply) UnmarshalJSON(buf []byte) error { + return proto.UnmarshalMessageSetJSON(buf, m.XXX_extensions) +} // ensure OldReply satisfies proto.Marshaler and proto.Unmarshaler var _ proto.Marshaler = (*OldReply)(nil) @@ -377,11 +466,22 @@ Tag: "bytes,103,opt,name=tag", } +var E_Donut = &proto.ExtensionDesc{ + ExtendedType: (*Reply)(nil), + ExtensionType: (*OtherReplyExtensions)(nil), + Field: 106, + Name: "my.test.donut", + Tag: "bytes,106,opt,name=donut", +} + func init() { proto.RegisterEnum("my.test.HatType", HatType_name, HatType_value) proto.RegisterEnum("my.test.Days", Days_name, Days_value) proto.RegisterEnum("my.test.Request_Color", Request_Color_name, Request_Color_value) proto.RegisterEnum("my.test.Reply_Entry_Game", Reply_Entry_Game_name, Reply_Entry_Game_value) proto.RegisterExtension(E_ReplyExtensions_Time) + proto.RegisterExtension(E_ReplyExtensions_Carrot) + proto.RegisterExtension(E_ReplyExtensions_Donut) proto.RegisterExtension(E_Tag) + proto.RegisterExtension(E_Donut) } diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/my_test/test.proto golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/my_test/test.proto --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/my_test/test.proto 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/my_test/test.proto 2015-06-13 14:23:31.000000000 +0000 @@ -1,7 +1,7 @@ // Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. -// http://code.google.com/p/goprotobuf/ +// 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 @@ -29,6 +29,9 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +syntax = "proto2"; + +// This package holds interesting messages. package my.test; // dotted package name //import "imp.proto"; @@ -58,7 +61,7 @@ } repeated int64 key = 1; // optional imp.ImportedMessage imported_message = 2; - optional Color hue = 3; + optional Color hue = 3; // no default optional HatType hat = 4 [default=FEDORA]; // optional imp.ImportedMessage.Owner owner = 6; optional float deadline = 7 [default=inf]; @@ -72,6 +75,11 @@ // optional imp.PubliclyImportedEnum pub_enum = 13 [default=HAIR]; + // This is a map field. It will generate map[int32]string. + map name_mapping = 14; + // This is a map field whose value type is a message. + map msg_mapping = 15; + optional int32 reset = 12; } @@ -90,15 +98,30 @@ extensions 100 to max; } +message OtherBase { + optional string name = 1; + extensions 100 to max; +} + message ReplyExtensions { extend Reply { optional double time = 101; + optional ReplyExtensions carrot = 105; + } + extend OtherBase { + optional ReplyExtensions donut = 101; } } +message OtherReplyExtensions { + optional int32 key = 1; +} + // top-level extension extend Reply { optional string tag = 103; + optional OtherReplyExtensions donut = 106; +// optional imp.ImportedMessage elephant = 107; // extend with message from another file. } message OldReply { diff -Nru golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/proto3.proto golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/proto3.proto --- golang-goprotobuf-0.0~git20130901/protoc-gen-go/testdata/proto3.proto 1970-01-01 00:00:00.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/protoc-gen-go/testdata/proto3.proto 2015-06-13 14:23:31.000000000 +0000 @@ -0,0 +1,52 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2014 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. + +syntax = "proto3"; + +package proto3; + +message Request { + enum Flavour { + SWEET = 0; + SOUR = 1; + UMAMI = 2; + GOPHERLICIOUS = 3; + } + string name = 1; // "optional" may be omitted + repeated int64 key = 2; + optional Flavour taste = 3; + Book book = 4; +} + +message Book { + string title = 1; + bytes raw_data = 2; +} diff -Nru golang-goprotobuf-0.0~git20130901/README golang-goprotobuf-0.0~git20150526/README --- golang-goprotobuf-0.0~git20130901/README 2013-08-19 07:11:31.000000000 +0000 +++ golang-goprotobuf-0.0~git20150526/README 2015-06-13 14:23:31.000000000 +0000 @@ -1,19 +1,21 @@ Go support for Protocol Buffers - Google's data interchange format Copyright 2010 The Go Authors. -http://code.google.com/p/goprotobuf/ +https://github.com/golang/protobuf + +This package and the code it generates requires at least Go 1.2. This software implements Go bindings for protocol buffers. For information about protocol buffers themselves, see - http://code.google.com/apis/protocolbuffers/ + https://developers.google.com/protocol-buffers/ To use this software, you must first install the standard C++ implementation of protocol buffers from - http://code.google.com/p/protobuf/ + https://developers.google.com/protocol-buffers/ And of course you must also install the Go compiler and tools from - http://code.google.com/p/go/ + https://golang.org/ See - http://golang.org/doc/install.html + https://golang.org/doc/install for details or, if you are using gccgo, follow the instructions at - http://golang.org/doc/gccgo_install.html + https://golang.org/doc/install/gccgo This software has two parts: a 'protocol compiler plugin' that generates Go source files that, once compiled, can access and manage @@ -31,7 +33,7 @@ The simplest way is to run go get. # Grab the code from the repository and install the proto package. - go get -u code.google.com/p/goprotobuf/{proto,protoc-gen-go} + go get -u github.com/golang/protobuf/{proto,protoc-gen-go} The compiler plugin, protoc-gen-go, will be installed in $GOBIN, defaulting to $GOPATH/bin. It must be in your $PATH for the protocol @@ -49,14 +51,6 @@ The generated files will be suffixed .pb.go. See the Test code below for an example using such a file. -This repository uses the same code review mechanism as Go, so -if you wish to submit changes add the equivalent of these two lines -to $GOROOT/src/pkg/code.google.com/p/goprotobuf/.hg/hgrc - - [extensions] - codereview = $GOROOT/lib/codereview/codereview.py - -*where $GOROOT is the expanded text, such as /usr/foo/go*. The package comment for the proto library contains text describing the interface provided in Go for protocol buffers. Here is an edited @@ -118,20 +112,6 @@ } } -To build a package from test.proto and some other Go files, write a -Makefile like this: - - include $(GOROOT)/src/Make.$(GOARCH) - - TARG=path/to/example - GOFILES=\ - test.pb.go\ - other.go - - include $(GOROOT)/src/Make.pkg - include $(GOROOT)/src/pkg/code.google.com/p/goprotobuf/Make.protobuf - - To create and play with a Test object from the example package, package main @@ -139,7 +119,7 @@ import ( "log" - "code.google.com/p/goprotobuf/proto" + "github.com/golang/protobuf/proto" "path/to/example" )