1// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package proto_test
6
7import (
8	"testing"
9
10	"google.golang.org/protobuf/internal/flags"
11	"google.golang.org/protobuf/internal/protobuild"
12	"google.golang.org/protobuf/proto"
13	"google.golang.org/protobuf/testing/protopack"
14
15	testpb "google.golang.org/protobuf/internal/testprotos/test"
16	weakpb "google.golang.org/protobuf/internal/testprotos/test/weak1"
17)
18
19func init() {
20	if flags.ProtoLegacy {
21		testValidMessages = append(testValidMessages, testWeakValidMessages...)
22		testInvalidMessages = append(testInvalidMessages, testWeakInvalidMessages...)
23		testMerges = append(testMerges, testWeakMerges...)
24	}
25}
26
27var testWeakValidMessages = []testProto{
28	{
29		desc: "weak message",
30		decodeTo: []proto.Message{
31			func() proto.Message {
32				if !flags.ProtoLegacy {
33					return nil
34				}
35				m := &testpb.TestWeak{}
36				m.SetWeakMessage1(&weakpb.WeakImportMessage1{
37					A: proto.Int32(1000),
38				})
39				m.ProtoReflect().SetUnknown(protopack.Message{
40					protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
41						protopack.Tag{1, protopack.VarintType}, protopack.Varint(2000),
42					}),
43				}.Marshal())
44				return m
45			}(),
46		},
47		wire: protopack.Message{
48			protopack.Tag{1, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
49				protopack.Tag{1, protopack.VarintType}, protopack.Varint(1000),
50			}),
51			protopack.Tag{2, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
52				protopack.Tag{1, protopack.VarintType}, protopack.Varint(2000),
53			}),
54		}.Marshal(),
55	},
56}
57
58var testWeakInvalidMessages = []testProto{
59	{
60		desc:     "invalid field number 0 in weak message",
61		decodeTo: []proto.Message{(*testpb.TestWeak)(nil)},
62		wire: protopack.Message{
63			protopack.Tag{1, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{
64				protopack.Tag{0, protopack.VarintType}, protopack.Varint(1000),
65			}),
66		}.Marshal(),
67	},
68}
69
70var testWeakMerges = []testMerge{
71	{
72		desc: "clone weak message",
73		src: protobuild.Message{
74			"weak_message1": protobuild.Message{
75				"a": 1,
76			},
77		},
78		types: []proto.Message{&testpb.TestWeak{}},
79	}, {
80		desc: "merge weak message",
81		dst: protobuild.Message{
82			"weak_message1": protobuild.Message{
83				"a": 1,
84			},
85		},
86		src: protobuild.Message{
87			"weak_message1": protobuild.Message{
88				"a": 2,
89			},
90		},
91		want: protobuild.Message{
92			"weak_message1": protobuild.Message{
93				"a": 2,
94			},
95		},
96		types: []proto.Message{&testpb.TestWeak{}},
97	},
98}
99
100func TestWeakNil(t *testing.T) {
101	if !flags.ProtoLegacy {
102		t.SkipNow()
103	}
104
105	m := new(testpb.TestWeak)
106	if v, ok := m.GetWeakMessage1().(*weakpb.WeakImportMessage1); !ok || v != nil {
107		t.Errorf("m.GetWeakMessage1() = type %[1]T(%[1]v), want (*weakpb.WeakImportMessage1)", v)
108	}
109}
110
111func TestWeakMarshalNil(t *testing.T) {
112	if !flags.ProtoLegacy {
113		t.SkipNow()
114	}
115
116	m := new(testpb.TestWeak)
117	m.SetWeakMessage1(nil)
118	if b, err := proto.Marshal(m); err != nil || len(b) != 0 {
119		t.Errorf("Marshal(weak field set to nil) = [%x], %v; want [], nil", b, err)
120	}
121	m.SetWeakMessage1((*weakpb.WeakImportMessage1)(nil))
122	if b, err := proto.Marshal(m); err != nil || len(b) != 0 {
123		t.Errorf("Marshal(weak field set to typed nil) = [%x], %v; want [], nil", b, err)
124	}
125}
126