|  | // Copyright 2024 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | package proto_test | 
|  |  | 
|  | import ( | 
|  | "bytes" | 
|  | "testing" | 
|  |  | 
|  | testhybridpb "google.golang.org/protobuf/internal/testprotos/testeditions/testeditions_hybrid" | 
|  | "google.golang.org/protobuf/proto" | 
|  | ) | 
|  |  | 
|  | func TestOneofOrDefault(t *testing.T) { | 
|  | for _, tt := range []struct { | 
|  | desc  string | 
|  | input func() *testhybridpb.TestAllTypes | 
|  | }{ | 
|  | { | 
|  | desc: "struct literal with nil nested message", | 
|  | input: func() *testhybridpb.TestAllTypes { | 
|  | return &testhybridpb.TestAllTypes{ | 
|  | OneofField: &testhybridpb.TestAllTypes_OneofNestedMessage{ | 
|  | OneofNestedMessage: nil, | 
|  | }, | 
|  | } | 
|  | }, | 
|  | }, | 
|  |  | 
|  | { | 
|  | desc: "struct literal with non-nil nested message", | 
|  | input: func() *testhybridpb.TestAllTypes { | 
|  | return &testhybridpb.TestAllTypes{ | 
|  | OneofField: &testhybridpb.TestAllTypes_OneofNestedMessage{ | 
|  | OneofNestedMessage: &testhybridpb.TestAllTypes_NestedMessage{}, | 
|  | }, | 
|  | } | 
|  | }, | 
|  | }, | 
|  |  | 
|  | { | 
|  | desc: "opaque setter with ValueOrDefault", | 
|  | input: func() *testhybridpb.TestAllTypes { | 
|  | msg := &testhybridpb.TestAllTypes{} | 
|  | msg.ClearOneofString() | 
|  | var val *testhybridpb.TestAllTypes_NestedMessage | 
|  | msg.SetOneofNestedMessage(proto.ValueOrDefault(val)) | 
|  | return msg | 
|  | }, | 
|  | }, | 
|  |  | 
|  | { | 
|  | desc: "opaque builder with ValueOrDefault", | 
|  | input: func() *testhybridpb.TestAllTypes { | 
|  | var val *testhybridpb.TestAllTypes_NestedMessage | 
|  | return testhybridpb.TestAllTypes_builder{ | 
|  | OneofNestedMessage: proto.ValueOrDefault(val), | 
|  | }.Build() | 
|  | }, | 
|  | }, | 
|  | } { | 
|  | t.Run(tt.desc, func(t *testing.T) { | 
|  | msg := tt.input() | 
|  | b, err := proto.Marshal(msg) | 
|  | if err != nil { | 
|  | t.Fatal(err) | 
|  | } | 
|  | want := []byte{130, 7, 0} | 
|  | if !bytes.Equal(b, want) { | 
|  | t.Fatalf("Marshal: got %x, want %x", b, want) | 
|  | } | 
|  | if !msg.HasOneofField() { | 
|  | t.Fatalf("HasOneofField was false, want true") | 
|  | } | 
|  | if got, want := msg.WhichOneofField(), testhybridpb.TestAllTypes_OneofNestedMessage_case; got != want { | 
|  | t.Fatalf("WhichOneofField: got %v, want %v", got, want) | 
|  | } | 
|  | if !msg.HasOneofNestedMessage() { | 
|  | t.Fatalf("HasOneofNestedMessage was false, want true") | 
|  | } | 
|  | if msg.HasOneofString() { | 
|  | t.Fatalf("HasOneofString was true, want false") | 
|  | } | 
|  | }) | 
|  | } | 
|  | } | 
|  |  | 
|  | func TestOneofOrDefaultBytes(t *testing.T) { | 
|  | for _, tt := range []struct { | 
|  | desc     string | 
|  | input    func() *testhybridpb.TestAllTypes | 
|  | wantWire []byte | 
|  | }{ | 
|  | { | 
|  | desc: "struct literal with nil bytes", | 
|  | input: func() *testhybridpb.TestAllTypes { | 
|  | return &testhybridpb.TestAllTypes{ | 
|  | OneofField: &testhybridpb.TestAllTypes_OneofBytes{ | 
|  | OneofBytes: nil, | 
|  | }, | 
|  | } | 
|  | }, | 
|  | }, | 
|  |  | 
|  | { | 
|  | desc: "struct literal with non-nil bytes", | 
|  | input: func() *testhybridpb.TestAllTypes { | 
|  | return &testhybridpb.TestAllTypes{ | 
|  | OneofField: &testhybridpb.TestAllTypes_OneofBytes{ | 
|  | OneofBytes: []byte{}, | 
|  | }, | 
|  | } | 
|  | }, | 
|  | }, | 
|  |  | 
|  | { | 
|  | desc: "opaque setter with ValueOrDefaultBytes", | 
|  | input: func() *testhybridpb.TestAllTypes { | 
|  | msg := &testhybridpb.TestAllTypes{} | 
|  | msg.ClearOneofString() | 
|  | var val []byte | 
|  | msg.SetOneofBytes(proto.ValueOrDefaultBytes(val)) | 
|  | return msg | 
|  | }, | 
|  | }, | 
|  |  | 
|  | { | 
|  | desc: "opaque setter", | 
|  | input: func() *testhybridpb.TestAllTypes { | 
|  | msg := &testhybridpb.TestAllTypes{} | 
|  | msg.ClearOneofString() | 
|  | var val []byte | 
|  | msg.SetOneofBytes(val) | 
|  | return msg | 
|  | }, | 
|  | }, | 
|  |  | 
|  | { | 
|  | desc: "opaque builder with ValueOrDefaultBytes", | 
|  | input: func() *testhybridpb.TestAllTypes { | 
|  | var val []byte | 
|  | return testhybridpb.TestAllTypes_builder{ | 
|  | OneofBytes: proto.ValueOrDefaultBytes(val), | 
|  | }.Build() | 
|  | }, | 
|  | }, | 
|  | } { | 
|  | t.Run(tt.desc, func(t *testing.T) { | 
|  | msg := tt.input() | 
|  | b, err := proto.Marshal(msg) | 
|  | if err != nil { | 
|  | t.Fatal(err) | 
|  | } | 
|  | want := []byte{146, 7, 0} | 
|  | if !bytes.Equal(b, want) { | 
|  | t.Fatalf("Marshal: got %x, want %x", b, want) | 
|  | } | 
|  | if !msg.HasOneofField() { | 
|  | t.Fatalf("HasOneofField was false, want true") | 
|  | } | 
|  | if got, want := msg.WhichOneofField(), testhybridpb.TestAllTypes_OneofBytes_case; got != want { | 
|  | t.Fatalf("WhichOneofField: got %v, want %v", got, want) | 
|  | } | 
|  | if !msg.HasOneofBytes() { | 
|  | t.Fatalf("HasOneofBytes was false, want true") | 
|  | } | 
|  | if msg.HasOneofString() { | 
|  | t.Fatalf("HasOneofString was true, want false") | 
|  | } | 
|  | }) | 
|  | } | 
|  | } |