func init() { if err := proto.SetExtension(realNumber, pb.E_Name, &realNumberName); err != nil { panic(err) } if err := proto.SetExtension(realNumber, pb.E_Complex_RealExtension, complexNumber); err != nil { panic(err) } }
func newTestMessage() *pb.MyMessage { msg := &pb.MyMessage{ Count: proto.Int32(42), Name: proto.String("Dave"), Quote: proto.String(`"I didn't want to go."`), Pet: []string{"bunny", "kitty", "horsey"}, Inner: &pb.InnerMessage{ Host: proto.String("footrest.syd"), Port: proto.Int32(7001), Connected: proto.Bool(true), }, Others: []*pb.OtherMessage{ { Key: proto.Int64(0xdeadbeef), Value: []byte{1, 65, 7, 12}, }, { Weight: proto.Float32(6.022), Inner: &pb.InnerMessage{ Host: proto.String("lesha.mtv"), Port: proto.Int32(8002), }, }, }, Bikeshed: pb.MyMessage_BLUE.Enum(), Somegroup: &pb.MyMessage_SomeGroup{ GroupField: proto.Int32(8), }, // One normally wouldn't do this. // This is an undeclared tag 13, as a varint (wire type 0) with value 4. XXX_unrecognized: []byte{13<<3 | 0, 4}, } ext := &pb.Ext{ Data: proto.String("Big gobs for big rats"), } if err := proto.SetExtension(msg, pb.E_Ext_More, ext); err != nil { panic(err) } greetings := []string{"adg", "easy", "cow"} if err := proto.SetExtension(msg, pb.E_Greeting, greetings); err != nil { panic(err) } // Add an unknown extension. We marshal a pb.Ext, and fake the ID. b, err := proto.Marshal(&pb.Ext{Data: proto.String("3G skiing")}) if err != nil { panic(err) } b = append(proto.EncodeVarint(201<<3|proto.WireBytes), b...) proto.SetRawExtension(msg, 201, b) // Extensions can be plain fields, too, so let's test that. b = append(proto.EncodeVarint(202<<3|proto.WireVarint), 19) proto.SetRawExtension(msg, 202, b) return msg }
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. }
func newClientAuthHSChan(conn *ricochetConn) (err error) { ch := new(authHSChan) ch.conn = conn ch.chanID, err = conn.allocateNextChanID() if err != nil { return } ch.clientCookie = make([]byte, authHiddenServiceCookieSize) if _, err = rand.Read(ch.clientCookie); err != nil { return err } openChan := &packet.OpenChannel{ ChannelIdentifier: proto.Int32((int32)(ch.chanID)), ChannelType: proto.String(authHiddenServiceChannelType), } if err = proto.SetExtension(openChan, packet.E_ClientCookie, ch.clientCookie); err != nil { return } ctrlPkt := &packet.ControlPacket{OpenChannel: openChan} rawPkt, err := proto.Marshal(ctrlPkt) if err != nil { return err } err = conn.sendPacket(controlChanID, rawPkt) conn.Lock() defer conn.Unlock() conn.chanMap[ch.chanID] = ch conn.getControlChan().authChan = (int)(ch.chanID) return }
func newClientContactReqChan(conn *ricochetConn, reqData *ContactRequest) (err error) { ch := new(contactReqChan) ch.conn = conn ch.chanID, err = conn.allocateNextChanID() if err != nil { return } req := &packet.ContactRequest{ Nickname: proto.String(reqData.MyNickname), MessageText: proto.String(reqData.Message), } openChan := &packet.OpenChannel{ ChannelIdentifier: proto.Int32((int32)(ch.chanID)), ChannelType: proto.String(contactReqChannelType), } if err = proto.SetExtension(openChan, packet.E_ContactRequest, req); err != nil { return } ctrlPkt := &packet.ControlPacket{OpenChannel: openChan} rawPkt, err := proto.Marshal(ctrlPkt) if err != nil { return err } err = ch.conn.sendPacket(controlChanID, rawPkt) conn.Lock() defer conn.Unlock() conn.chanMap[ch.chanID] = ch conn.getControlChan().contactReqChan = (int)(ch.chanID) return }
func TestMarshalRace(t *testing.T) { // unregistered extension desc := &proto.ExtensionDesc{ ExtendedType: (*pb.MyMessage)(nil), ExtensionType: (*bool)(nil), Field: 101010100, Name: "emptyextension", Tag: "varint,0,opt", } m := &pb.MyMessage{Count: proto.Int32(4)} if err := proto.SetExtension(m, desc, proto.Bool(true)); err != nil { t.Errorf("proto.SetExtension(m, desc, true): got error %q, want nil", err) } var g errgroup.Group for n := 3; n > 0; n-- { g.Go(func() error { _, err := proto.Marshal(m) return err }) } if err := g.Wait(); err != nil { t.Fatal(err) } }
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 init() { ext := &pb.Ext{ Data: proto.String("extension"), } if err := proto.SetExtension(cloneTestMessage, pb.E_Ext_More, ext); err != nil { panic("SetExtension: " + err.Error()) } }
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 TestExtensionDescsWithMissingExtensions(t *testing.T) { msg := &pb.MyMessage{Count: proto.Int32(0)} extdesc1 := pb.E_Ext_More if descs, err := proto.ExtensionDescs(msg); len(descs) != 0 || err != nil { t.Errorf("proto.ExtensionDescs: got %d descs, error %v; want 0, nil", len(descs), err) } ext1 := &pb.Ext{} if err := proto.SetExtension(msg, extdesc1, ext1); err != nil { t.Fatalf("Could not set ext1: %s", err) } extdesc2 := &proto.ExtensionDesc{ ExtendedType: (*pb.MyMessage)(nil), ExtensionType: (*bool)(nil), Field: 123456789, Name: "a.b", Tag: "varint,123456789,opt", } ext2 := proto.Bool(false) if err := proto.SetExtension(msg, extdesc2, ext2); err != nil { t.Fatalf("Could not set ext2: %s", err) } b, err := proto.Marshal(msg) if err != nil { t.Fatalf("Could not marshal msg: %v", err) } if err := proto.Unmarshal(b, msg); err != nil { t.Fatalf("Could not unmarshal into msg: %v", err) } descs, err := proto.ExtensionDescs(msg) if err != nil { t.Fatalf("proto.ExtensionDescs: got error %v", err) } sortExtDescs(descs) wantDescs := []*proto.ExtensionDesc{extdesc1, &proto.ExtensionDesc{Field: extdesc2.Field}} if !reflect.DeepEqual(descs, wantDescs) { t.Errorf("proto.ExtensionDescs(msg) sorted extension ids: got %+v, want %+v", descs, wantDescs) } }
// OpenAuthenticationChannel constructs a message which will reuqest to open a channel for // authentication on the given channelID, with the given cookie func (mb *MessageBuilder) OpenAuthenticationChannel(channelID int32, clientCookie [16]byte) ([]byte, error) { oc := &Protocol_Data_Control.OpenChannel{ ChannelIdentifier: proto.Int32(channelID), ChannelType: proto.String("im.ricochet.auth.hidden-service"), } err := proto.SetExtension(oc, Protocol_Data_AuthHiddenService.E_ClientCookie, clientCookie[:]) utils.CheckError(err) pc := &Protocol_Data_Control.Packet{ OpenChannel: oc, } return proto.Marshal(pc) }
// ConfirmAuthChannel constructs a message to acknowledge a previous open channel operation. func (mb *MessageBuilder) ConfirmAuthChannel(channelID int32, serverCookie [16]byte) ([]byte, error) { cr := &Protocol_Data_Control.ChannelResult{ ChannelIdentifier: proto.Int32(channelID), Opened: proto.Bool(true), } err := proto.SetExtension(cr, Protocol_Data_AuthHiddenService.E_ServerCookie, serverCookie[:]) utils.CheckError(err) pc := &Protocol_Data_Control.Packet{ ChannelResult: cr, } return proto.Marshal(pc) }
func (ch *contactReqChan) onOpenChannel() error { log := ch.conn.endpoint.log ch.state = chanStateOpen // Stop the timer since the peer took sufficient action. ch.conn.authTimer.Stop() log.Printf("server: ContactRequest from: '%v' (%s)", ch.conn.hostname, ch.reqData) // Check to see if we should mark the contact request as accepted, // rejected or pending. accept, err := ch.conn.endpoint.onContactRequest(ch.conn, ch.reqData) if err != nil { return err } resp := &packet.ContactRequestResponse{} if accept { resp.Status = packet.ContactRequestResponse_Accepted.Enum() } else { resp.Status = packet.ContactRequestResponse_Pending.Enum() } chanResult := &packet.ChannelResult{ ChannelIdentifier: proto.Int32((int32)(ch.chanID)), Opened: proto.Bool(true), } if err := proto.SetExtension(chanResult, packet.E_Response, resp); err != nil { return err } ctrlPkt := &packet.ControlPacket{ChannelResult: chanResult} rawPkt, err := proto.Marshal(ctrlPkt) if err != nil { return err } err = ch.conn.sendPacket(controlChanID, rawPkt) if !accept { return err } // We immediately accepted the Contact Request. ch.conn.endpoint.onConnectionEstablished(ch.conn) return ch.conn.sendChanClose(ch.chanID) }
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]) } }
// ReplyToContactRequestOnResponse constructs a message to acknowledge contact request func (mb *MessageBuilder) ReplyToContactRequestOnResponse(channelID int32, status string) ([]byte, error) { cr := &Protocol_Data_Control.ChannelResult{ ChannelIdentifier: proto.Int32(channelID), Opened: proto.Bool(true), } statusNum := Protocol_Data_ContactRequest.Response_Status_value[status] responseStatus := Protocol_Data_ContactRequest.Response_Status(statusNum) contactRequest := &Protocol_Data_ContactRequest.Response{ Status: &responseStatus, } err := proto.SetExtension(cr, Protocol_Data_ContactRequest.E_Response, contactRequest) utils.CheckError(err) pc := &Protocol_Data_Control.Packet{ ChannelResult: cr, } return proto.Marshal(pc) }
// OpenContactRequestChannel contructs a message which will reuqest to open a channel for // a contact request on the given channelID, with the given nick and message. func (mb *MessageBuilder) OpenContactRequestChannel(channelID int32, nick string, message string) ([]byte, error) { // Construct a Contact Request Channel oc := &Protocol_Data_Control.OpenChannel{ ChannelIdentifier: proto.Int32(channelID), ChannelType: proto.String("im.ricochet.contact.request"), } contactRequest := &Protocol_Data_ContactRequest.ContactRequest{ Nickname: proto.String(nick), MessageText: proto.String(message), } err := proto.SetExtension(oc, Protocol_Data_ContactRequest.E_ContactRequest, contactRequest) utils.CheckError(err) pc := &Protocol_Data_Control.Packet{ OpenChannel: oc, } return proto.Marshal(pc) }
func (ch *authHSChan) onOpenChannel() error { ch.state = chanStateOpen ch.serverCookie = make([]byte, authHiddenServiceCookieSize) if _, err := rand.Read(ch.serverCookie); err != nil { return err } chanResult := &packet.ChannelResult{ ChannelIdentifier: proto.Int32((int32)(ch.chanID)), Opened: proto.Bool(true), } if err := proto.SetExtension(chanResult, packet.E_ServerCookie, ch.serverCookie); err != nil { return err } ctrlPkt := &packet.ControlPacket{ChannelResult: chanResult} rawPkt, err := proto.Marshal(ctrlPkt) if err != nil { return err } return ch.conn.sendPacket(controlChanID, rawPkt) }
func TestClearAllExtensions(t *testing.T) { // unregistered extension desc := &proto.ExtensionDesc{ ExtendedType: (*pb.MyMessage)(nil), ExtensionType: (*bool)(nil), Field: 101010100, Name: "emptyextension", Tag: "varint,0,opt", } m := &pb.MyMessage{} if proto.HasExtension(m, desc) { t.Errorf("proto.HasExtension(%s): got true, want false", proto.MarshalTextString(m)) } if err := proto.SetExtension(m, desc, proto.Bool(true)); err != nil { t.Errorf("proto.SetExtension(m, desc, true): got error %q, want nil", err) } if !proto.HasExtension(m, desc) { t.Errorf("proto.HasExtension(%s): got false, want true", proto.MarshalTextString(m)) } proto.ClearAllExtensions(m) if proto.HasExtension(m, desc) { t.Errorf("proto.HasExtension(%s): got true, want false", proto.MarshalTextString(m)) } }
func TestMarshalUnmarshalRepeatedExtension(t *testing.T) { // Add a repeated extension to the result. tests := []struct { name string ext []*pb.ComplexExtension }{ { "two fields", []*pb.ComplexExtension{ {First: proto.Int32(7)}, {Second: proto.Int32(11)}, }, }, { "repeated field", []*pb.ComplexExtension{ {Third: []int32{1000}}, {Third: []int32{2000}}, }, }, { "two fields and repeated field", []*pb.ComplexExtension{ {Third: []int32{1000}}, {First: proto.Int32(9)}, {Second: proto.Int32(21)}, {Third: []int32{2000}}, }, }, } for _, test := range tests { // Marshal message with a repeated extension. msg1 := new(pb.OtherMessage) err := proto.SetExtension(msg1, pb.E_RComplex, test.ext) if err != nil { t.Fatalf("[%s] Error setting extension: %v", test.name, err) } b, err := proto.Marshal(msg1) if err != nil { t.Fatalf("[%s] Error marshaling message: %v", test.name, err) } // Unmarshal and read the merged proto. msg2 := new(pb.OtherMessage) err = proto.Unmarshal(b, msg2) if err != nil { t.Fatalf("[%s] Error unmarshaling message: %v", test.name, err) } e, err := proto.GetExtension(msg2, pb.E_RComplex) if err != nil { t.Fatalf("[%s] Error getting extension: %v", test.name, err) } ext := e.([]*pb.ComplexExtension) if ext == nil { t.Fatalf("[%s] Invalid extension", test.name) } if !reflect.DeepEqual(ext, test.ext) { t.Errorf("[%s] Wrong value for ComplexExtension: got: %v want: %v\n", test.name, ext, test.ext) } } }
func TestUnmarshalRepeatingNonRepeatedExtension(t *testing.T) { // We may see multiple instances of the same extension in the wire // format. For example, the proto compiler may encode custom options in // this way. Here, we verify that we merge the extensions together. tests := []struct { name string ext []*pb.ComplexExtension }{ { "two fields", []*pb.ComplexExtension{ {First: proto.Int32(7)}, {Second: proto.Int32(11)}, }, }, { "repeated field", []*pb.ComplexExtension{ {Third: []int32{1000}}, {Third: []int32{2000}}, }, }, { "two fields and repeated field", []*pb.ComplexExtension{ {Third: []int32{1000}}, {First: proto.Int32(9)}, {Second: proto.Int32(21)}, {Third: []int32{2000}}, }, }, } for _, test := range tests { var buf bytes.Buffer var want pb.ComplexExtension // Generate a serialized representation of a repeated extension // by catenating bytes together. for i, e := range test.ext { // Merge to create the wanted proto. proto.Merge(&want, e) // serialize the message msg := new(pb.OtherMessage) err := proto.SetExtension(msg, pb.E_Complex, e) if err != nil { t.Fatalf("[%s] Error setting extension %d: %v", test.name, i, err) } b, err := proto.Marshal(msg) if err != nil { t.Fatalf("[%s] Error marshaling message %d: %v", test.name, i, err) } buf.Write(b) } // Unmarshal and read the merged proto. msg2 := new(pb.OtherMessage) err := proto.Unmarshal(buf.Bytes(), msg2) if err != nil { t.Fatalf("[%s] Error unmarshaling message: %v", test.name, err) } e, err := proto.GetExtension(msg2, pb.E_Complex) if err != nil { t.Fatalf("[%s] Error getting extension: %v", test.name, err) } ext := e.(*pb.ComplexExtension) if ext == nil { t.Fatalf("[%s] Invalid extension", test.name) } if !reflect.DeepEqual(*ext, want) { t.Errorf("[%s] Wrong value for ComplexExtension: got: %s want: %s\n", test.name, ext, want) } } }
func main() { vars := []proto.Message{ &pb.M0{F: proto.Int32(0)}, &pb.M0{F: proto.Int32(-1000000), XXX_unrecognized: []byte{0, 1, 2}}, &pb.M1{F: proto.Int64(0)}, &pb.M1{F: proto.Int64(100)}, &pb.M1{F: proto.Int64(123123123123123123)}, &pb.M1{F: proto.Int64(-100)}, &pb.M1{F: proto.Int64(-123123123123123123)}, &pb.M2{}, &pb.M2{F: proto.Uint32(123123)}, &pb.M3{}, &pb.M3{F: proto.Uint64(123123123123123123)}, &pb.M4{F: proto.Int32(123123)}, &pb.M5{F: proto.Int64(123123)}, &pb.M5{F: proto.Int64(-123123)}, &pb.M6{XXX_unrecognized: []byte{0, 1, 2}}, &pb.M6{F: proto.Uint32(123123), XXX_unrecognized: []byte{0, 1, 2}}, &pb.M7{F: proto.Uint64(123123123123)}, &pb.M8{F: proto.Int32(-123123)}, &pb.M9{F: proto.Int64(-123123123123)}, &pb.M10{F: proto.Float64(123123.123123)}, &pb.M11{F: proto.Float32(123123.123123)}, &pb.M12{F: proto.Bool(true)}, &pb.M13{}, &pb.M13{F: proto.String("")}, &pb.M13{F: proto.String("foo")}, &pb.M13{F: proto.String("&pb.M6{F: proto.Uint32(123123), XXX_unrecognized: []byte{0,1,2}},")}, &pb.M13{F: proto.String("\x00\x01\x02")}, &pb.M14{}, &pb.M14{F: []byte{0, 1, 2}}, &pb.M14{F: []byte("&pb.M6{F: proto.Uint32(123123), XXX_unrecognized: []byte{0,1,2}},")}, &pb.M15{F0: proto.Int32(123)}, &pb.M15{F0: proto.Int32(123), F1: proto.String("foo"), F2: []byte{1, 2, 3}, F4: proto.Bool(false)}, &pb.M16{}, &pb.M16{F: pb.Corpus_UNIVERSAL.Enum()}, &pb.M16{F: pb.Corpus_PRODUCTS.Enum()}, &pb.M17{F: &pb.M15{F0: proto.Int32(123)}}, &pb.M17{F: &pb.M15{F0: proto.Int32(123), F1: proto.String("foo"), F2: []byte{1, 2, 3}, F4: proto.Bool(false)}}, func() proto.Message { v := &pb.M18{F0: proto.String("foo")} proto.SetExtension(v, pb.E_F1, 42) return v }(), &pb.M19{}, &pb.M19{F: []int32{0, -123, 500, 123123123}}, &pb.M20{F: []string{"", "foo", "\x00\x01\x02"}}, &pb.M21{F: []*pb.M15{&pb.M15{F0: proto.Int32(123)}, &pb.M15{F0: proto.Int32(123), F1: proto.String("foo"), F2: []byte{1, 2, 3}, F4: proto.Bool(false)}}}, &pb.M22{F: []*pb.M2{&pb.M2{}}}, &pb.M22{F: []*pb.M2{&pb.M2{}, &pb.M2{F: proto.Uint32(123123)}}}, &pb.M23{}, &pb.M23{F: map[int32]string{42: "", 11: "foo", 123123123: "\x00\x01\x02"}}, &pb.M24{F: map[string]*pb.M2{"": &pb.M2{}, "foo": &pb.M2{}, "\x00\x01\x02": &pb.M2{F: proto.Uint32(123123)}}}, &pb.M25{}, &pb.M25{F0: proto.String("")}, &pb.M25{F0: proto.String("foo")}, &pb.M25{F1: &pb.M2{}}, &pb.M25{F1: &pb.M2{F: proto.Uint32(123123)}}, &pb.M25{F2: pb.Corpus_UNIVERSAL.Enum()}, } for i, v := range vars { if false { data, err := proto.Marshal(v) if err != nil { panic(err) } f, err := os.Create(fmt.Sprintf("/tmp/proto/%v", i)) if err != nil { panic(err) } f.Write(data) f.Close() } else { f, err := os.Create(fmt.Sprintf("/tmp/proto/%v", i)) if err != nil { panic(err) } fmt.Printf("%v: %+v\n", i, v) err = proto.MarshalText(f, v) if err != nil { panic(err) } f.Close() } } }
func makeGolden() []golden { nested := &pb.Nested{Bunny: "Monty"} nb, err := proto.Marshal(nested) if err != nil { panic(err) } m1 := &pb.Message{ Name: "David", ResultCount: 47, Anything: &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(nested), Value: nb}, } m2 := &pb.Message{ Name: "David", ResultCount: 47, Anything: &anypb.Any{TypeUrl: "http://[::1]/type.googleapis.com/" + proto.MessageName(nested), Value: nb}, } m3 := &pb.Message{ Name: "David", ResultCount: 47, Anything: &anypb.Any{TypeUrl: `type.googleapis.com/"/` + proto.MessageName(nested), Value: nb}, } m4 := &pb.Message{ Name: "David", ResultCount: 47, Anything: &anypb.Any{TypeUrl: "type.googleapis.com/a/path/" + proto.MessageName(nested), Value: nb}, } m5 := &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(nested), Value: nb} any1 := &testpb.MyMessage{Count: proto.Int32(47), Name: proto.String("David")} proto.SetExtension(any1, testpb.E_Ext_More, &testpb.Ext{Data: proto.String("foo")}) proto.SetExtension(any1, testpb.E_Ext_Text, proto.String("bar")) any1b, err := proto.Marshal(any1) if err != nil { panic(err) } any2 := &testpb.MyMessage{Count: proto.Int32(42), Bikeshed: testpb.MyMessage_GREEN.Enum(), RepBytes: [][]byte{[]byte("roboto")}} proto.SetExtension(any2, testpb.E_Ext_More, &testpb.Ext{Data: proto.String("baz")}) any2b, err := proto.Marshal(any2) if err != nil { panic(err) } m6 := &pb.Message{ Name: "David", ResultCount: 47, Anything: &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(any1), Value: any1b}, ManyThings: []*anypb.Any{ &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(any2), Value: any2b}, &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(any1), Value: any1b}, }, } const ( m1Golden = ` name: "David" result_count: 47 anything: < [type.googleapis.com/proto3_proto.Nested]: < bunny: "Monty" > > ` m2Golden = ` name: "David" result_count: 47 anything: < ["http://[::1]/type.googleapis.com/proto3_proto.Nested"]: < bunny: "Monty" > > ` m3Golden = ` name: "David" result_count: 47 anything: < ["type.googleapis.com/\"/proto3_proto.Nested"]: < bunny: "Monty" > > ` m4Golden = ` name: "David" result_count: 47 anything: < [type.googleapis.com/a/path/proto3_proto.Nested]: < bunny: "Monty" > > ` m5Golden = ` [type.googleapis.com/proto3_proto.Nested]: < bunny: "Monty" > ` m6Golden = ` name: "David" result_count: 47 anything: < [type.googleapis.com/testdata.MyMessage]: < count: 47 name: "David" [testdata.Ext.more]: < data: "foo" > [testdata.Ext.text]: "bar" > > many_things: < [type.googleapis.com/testdata.MyMessage]: < count: 42 bikeshed: GREEN rep_bytes: "roboto" [testdata.Ext.more]: < data: "baz" > > > many_things: < [type.googleapis.com/testdata.MyMessage]: < count: 47 name: "David" [testdata.Ext.more]: < data: "foo" > [testdata.Ext.text]: "bar" > > ` ) return []golden{ {m1, strings.TrimSpace(m1Golden) + "\n", strings.TrimSpace(compact(m1Golden)) + " "}, {m2, strings.TrimSpace(m2Golden) + "\n", strings.TrimSpace(compact(m2Golden)) + " "}, {m3, strings.TrimSpace(m3Golden) + "\n", strings.TrimSpace(compact(m3Golden)) + " "}, {m4, strings.TrimSpace(m4Golden) + "\n", strings.TrimSpace(compact(m4Golden)) + " "}, {m5, strings.TrimSpace(m5Golden) + "\n", strings.TrimSpace(compact(m5Golden)) + " "}, {m6, strings.TrimSpace(m6Golden) + "\n", strings.TrimSpace(compact(m6Golden)) + " "}, } }
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) } } }