xref: /aosp_15_r20/external/golang-protobuf/proto/methods_test.go (revision 1c12ee1efe575feb122dbf939ff15148a3b3e8f2)
1*1c12ee1eSDan Willemsen// Copyright 2019 The Go Authors. All rights reserved.
2*1c12ee1eSDan Willemsen// Use of this source code is governed by a BSD-style
3*1c12ee1eSDan Willemsen// license that can be found in the LICENSE file.
4*1c12ee1eSDan Willemsen
5*1c12ee1eSDan Willemsen// The protoreflect tag disables fast-path methods, including legacy ones.
6*1c12ee1eSDan Willemsen//go:build !protoreflect
7*1c12ee1eSDan Willemsen// +build !protoreflect
8*1c12ee1eSDan Willemsen
9*1c12ee1eSDan Willemsenpackage proto_test
10*1c12ee1eSDan Willemsen
11*1c12ee1eSDan Willemsenimport (
12*1c12ee1eSDan Willemsen	"bytes"
13*1c12ee1eSDan Willemsen	"errors"
14*1c12ee1eSDan Willemsen	"fmt"
15*1c12ee1eSDan Willemsen	"testing"
16*1c12ee1eSDan Willemsen
17*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/impl"
18*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/proto"
19*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/runtime/protoiface"
20*1c12ee1eSDan Willemsen
21*1c12ee1eSDan Willemsen	legacypb "google.golang.org/protobuf/internal/testprotos/legacy"
22*1c12ee1eSDan Willemsen)
23*1c12ee1eSDan Willemsen
24*1c12ee1eSDan Willemsentype selfMarshaler struct {
25*1c12ee1eSDan Willemsen	bytes []byte
26*1c12ee1eSDan Willemsen	err   error
27*1c12ee1eSDan Willemsen}
28*1c12ee1eSDan Willemsen
29*1c12ee1eSDan Willemsenfunc (m selfMarshaler) Reset()        {}
30*1c12ee1eSDan Willemsenfunc (m selfMarshaler) ProtoMessage() {}
31*1c12ee1eSDan Willemsen
32*1c12ee1eSDan Willemsenfunc (m selfMarshaler) String() string {
33*1c12ee1eSDan Willemsen	return fmt.Sprintf("selfMarshaler{bytes:%v, err:%v}", m.bytes, m.err)
34*1c12ee1eSDan Willemsen}
35*1c12ee1eSDan Willemsen
36*1c12ee1eSDan Willemsenfunc (m selfMarshaler) Marshal() ([]byte, error) {
37*1c12ee1eSDan Willemsen	return m.bytes, m.err
38*1c12ee1eSDan Willemsen}
39*1c12ee1eSDan Willemsen
40*1c12ee1eSDan Willemsenfunc (m *selfMarshaler) Unmarshal(b []byte) error {
41*1c12ee1eSDan Willemsen	m.bytes = b
42*1c12ee1eSDan Willemsen	return m.err
43*1c12ee1eSDan Willemsen}
44*1c12ee1eSDan Willemsen
45*1c12ee1eSDan Willemsenfunc TestLegacyMarshalMethod(t *testing.T) {
46*1c12ee1eSDan Willemsen	for _, test := range []selfMarshaler{
47*1c12ee1eSDan Willemsen		{bytes: []byte("marshal")},
48*1c12ee1eSDan Willemsen		{bytes: []byte("marshal"), err: errors.New("some error")},
49*1c12ee1eSDan Willemsen	} {
50*1c12ee1eSDan Willemsen		m := impl.Export{}.MessageOf(test).Interface()
51*1c12ee1eSDan Willemsen		b, err := proto.Marshal(m)
52*1c12ee1eSDan Willemsen		if err != test.err || !bytes.Equal(b, test.bytes) {
53*1c12ee1eSDan Willemsen			t.Errorf("proto.Marshal(%v) = %v, %v; want %v, %v", test, b, err, test.bytes, test.err)
54*1c12ee1eSDan Willemsen		}
55*1c12ee1eSDan Willemsen		if gotSize, wantSize := proto.Size(m), len(test.bytes); gotSize != wantSize {
56*1c12ee1eSDan Willemsen			t.Fatalf("proto.Size(%v) = %v, want %v", test, gotSize, wantSize)
57*1c12ee1eSDan Willemsen		}
58*1c12ee1eSDan Willemsen
59*1c12ee1eSDan Willemsen		prefix := []byte("prefix")
60*1c12ee1eSDan Willemsen		want := append(prefix, test.bytes...)
61*1c12ee1eSDan Willemsen		b, err = proto.MarshalOptions{}.MarshalAppend(prefix, m)
62*1c12ee1eSDan Willemsen		if err != test.err || !bytes.Equal(b, want) {
63*1c12ee1eSDan Willemsen			t.Errorf("MarshalAppend(%v, %v) = %v, %v; want %v, %v", prefix, test, b, err, test.bytes, test.err)
64*1c12ee1eSDan Willemsen		}
65*1c12ee1eSDan Willemsen
66*1c12ee1eSDan Willemsen		b, err = proto.MarshalOptions{
67*1c12ee1eSDan Willemsen			Deterministic: true,
68*1c12ee1eSDan Willemsen		}.MarshalAppend(nil, m)
69*1c12ee1eSDan Willemsen		if err != test.err || !bytes.Equal(b, test.bytes) {
70*1c12ee1eSDan Willemsen			t.Errorf("MarshalOptions{Deterministic:true}.MarshalAppend(nil, %v) = %v, %v; want %v, %v", test, b, err, test.bytes, test.err)
71*1c12ee1eSDan Willemsen		}
72*1c12ee1eSDan Willemsen	}
73*1c12ee1eSDan Willemsen}
74*1c12ee1eSDan Willemsen
75*1c12ee1eSDan Willemsenfunc TestLegacyUnmarshalMethod(t *testing.T) {
76*1c12ee1eSDan Willemsen	sm := &selfMarshaler{}
77*1c12ee1eSDan Willemsen	m := impl.Export{}.MessageOf(sm).Interface()
78*1c12ee1eSDan Willemsen	want := []byte("unmarshal")
79*1c12ee1eSDan Willemsen	if err := proto.Unmarshal(want, m); err != nil {
80*1c12ee1eSDan Willemsen		t.Fatalf("proto.Unmarshal(selfMarshaler{}) = %v, want nil", err)
81*1c12ee1eSDan Willemsen	}
82*1c12ee1eSDan Willemsen	if !bytes.Equal(sm.bytes, want) {
83*1c12ee1eSDan Willemsen		t.Fatalf("proto.Unmarshal(selfMarshaler{}): Marshal method not called")
84*1c12ee1eSDan Willemsen	}
85*1c12ee1eSDan Willemsen}
86*1c12ee1eSDan Willemsen
87*1c12ee1eSDan Willemsentype descPanicSelfMarshaler struct{}
88*1c12ee1eSDan Willemsen
89*1c12ee1eSDan Willemsenconst descPanicSelfMarshalerBytes = "bytes"
90*1c12ee1eSDan Willemsen
91*1c12ee1eSDan Willemsenfunc (m *descPanicSelfMarshaler) Reset()                      {}
92*1c12ee1eSDan Willemsenfunc (m *descPanicSelfMarshaler) ProtoMessage()               {}
93*1c12ee1eSDan Willemsenfunc (m *descPanicSelfMarshaler) Descriptor() ([]byte, []int) { panic("Descriptor method panics") }
94*1c12ee1eSDan Willemsenfunc (m *descPanicSelfMarshaler) String() string              { return "descPanicSelfMarshaler{}" }
95*1c12ee1eSDan Willemsenfunc (m *descPanicSelfMarshaler) Marshal() ([]byte, error) {
96*1c12ee1eSDan Willemsen	return []byte(descPanicSelfMarshalerBytes), nil
97*1c12ee1eSDan Willemsen}
98*1c12ee1eSDan Willemsen
99*1c12ee1eSDan Willemsenfunc TestSelfMarshalerDescriptorPanics(t *testing.T) {
100*1c12ee1eSDan Willemsen	m := &descPanicSelfMarshaler{}
101*1c12ee1eSDan Willemsen	got, err := proto.Marshal(impl.Export{}.MessageOf(m).Interface())
102*1c12ee1eSDan Willemsen	want := []byte(descPanicSelfMarshalerBytes)
103*1c12ee1eSDan Willemsen	if err != nil || !bytes.Equal(got, want) {
104*1c12ee1eSDan Willemsen		t.Fatalf("proto.Marshal(%v) = %v, %v; want %v, nil", m, got, err, want)
105*1c12ee1eSDan Willemsen	}
106*1c12ee1eSDan Willemsen}
107*1c12ee1eSDan Willemsen
108*1c12ee1eSDan Willemsentype descSelfMarshaler struct {
109*1c12ee1eSDan Willemsen	someField int // some non-generated field
110*1c12ee1eSDan Willemsen}
111*1c12ee1eSDan Willemsen
112*1c12ee1eSDan Willemsenconst descSelfMarshalerBytes = "bytes"
113*1c12ee1eSDan Willemsen
114*1c12ee1eSDan Willemsenfunc (m *descSelfMarshaler) Reset()        {}
115*1c12ee1eSDan Willemsenfunc (m *descSelfMarshaler) ProtoMessage() {}
116*1c12ee1eSDan Willemsenfunc (m *descSelfMarshaler) Descriptor() ([]byte, []int) {
117*1c12ee1eSDan Willemsen	return ((*legacypb.Legacy)(nil)).GetF1().Descriptor()
118*1c12ee1eSDan Willemsen}
119*1c12ee1eSDan Willemsenfunc (m *descSelfMarshaler) String() string {
120*1c12ee1eSDan Willemsen	return "descSelfMarshaler{}"
121*1c12ee1eSDan Willemsen}
122*1c12ee1eSDan Willemsenfunc (m *descSelfMarshaler) Marshal() ([]byte, error) {
123*1c12ee1eSDan Willemsen	return []byte(descSelfMarshalerBytes), nil
124*1c12ee1eSDan Willemsen}
125*1c12ee1eSDan Willemsen
126*1c12ee1eSDan Willemsenfunc TestSelfMarshalerWithDescriptor(t *testing.T) {
127*1c12ee1eSDan Willemsen	m := &descSelfMarshaler{}
128*1c12ee1eSDan Willemsen	got, err := proto.Marshal(impl.Export{}.MessageOf(m).Interface())
129*1c12ee1eSDan Willemsen	want := []byte(descSelfMarshalerBytes)
130*1c12ee1eSDan Willemsen	if err != nil || !bytes.Equal(got, want) {
131*1c12ee1eSDan Willemsen		t.Fatalf("proto.Marshal(%v) = %v, %v; want %v, nil", m, got, err, want)
132*1c12ee1eSDan Willemsen	}
133*1c12ee1eSDan Willemsen}
134*1c12ee1eSDan Willemsen
135*1c12ee1eSDan Willemsenfunc TestDecodeFastCheckInitialized(t *testing.T) {
136*1c12ee1eSDan Willemsen	for _, test := range testValidMessages {
137*1c12ee1eSDan Willemsen		if !test.checkFastInit {
138*1c12ee1eSDan Willemsen			continue
139*1c12ee1eSDan Willemsen		}
140*1c12ee1eSDan Willemsen		for _, message := range test.decodeTo {
141*1c12ee1eSDan Willemsen			t.Run(fmt.Sprintf("%s (%T)", test.desc, message), func(t *testing.T) {
142*1c12ee1eSDan Willemsen				m := message.ProtoReflect().New()
143*1c12ee1eSDan Willemsen				opts := proto.UnmarshalOptions{
144*1c12ee1eSDan Willemsen					AllowPartial: true,
145*1c12ee1eSDan Willemsen				}
146*1c12ee1eSDan Willemsen				out, err := opts.UnmarshalState(protoiface.UnmarshalInput{
147*1c12ee1eSDan Willemsen					Buf:     test.wire,
148*1c12ee1eSDan Willemsen					Message: m,
149*1c12ee1eSDan Willemsen				})
150*1c12ee1eSDan Willemsen				if err != nil {
151*1c12ee1eSDan Willemsen					t.Fatalf("Unmarshal error: %v", err)
152*1c12ee1eSDan Willemsen				}
153*1c12ee1eSDan Willemsen				if got, want := (out.Flags&protoiface.UnmarshalInitialized != 0), !test.partial; got != want {
154*1c12ee1eSDan Willemsen					t.Errorf("out.Initialized = %v, want %v", got, want)
155*1c12ee1eSDan Willemsen				}
156*1c12ee1eSDan Willemsen			})
157*1c12ee1eSDan Willemsen		}
158*1c12ee1eSDan Willemsen	}
159*1c12ee1eSDan Willemsen}
160*1c12ee1eSDan Willemsen
161*1c12ee1eSDan Willemsentype selfMerger struct {
162*1c12ee1eSDan Willemsen	src protoiface.MessageV1
163*1c12ee1eSDan Willemsen}
164*1c12ee1eSDan Willemsen
165*1c12ee1eSDan Willemsenfunc (*selfMerger) Reset()         {}
166*1c12ee1eSDan Willemsenfunc (*selfMerger) ProtoMessage()  {}
167*1c12ee1eSDan Willemsenfunc (*selfMerger) String() string { return "selfMerger{}" }
168*1c12ee1eSDan Willemsenfunc (m *selfMerger) Merge(src protoiface.MessageV1) {
169*1c12ee1eSDan Willemsen	m.src = src
170*1c12ee1eSDan Willemsen}
171*1c12ee1eSDan Willemsen
172*1c12ee1eSDan Willemsenfunc TestLegacyMergeMethod(t *testing.T) {
173*1c12ee1eSDan Willemsen	src := &selfMerger{}
174*1c12ee1eSDan Willemsen	dst := &selfMerger{}
175*1c12ee1eSDan Willemsen	proto.Merge(
176*1c12ee1eSDan Willemsen		impl.Export{}.MessageOf(dst).Interface(),
177*1c12ee1eSDan Willemsen		impl.Export{}.MessageOf(src).Interface(),
178*1c12ee1eSDan Willemsen	)
179*1c12ee1eSDan Willemsen	if got, want := dst.src, src; got != want {
180*1c12ee1eSDan Willemsen		t.Errorf("Merge(dst, src): want dst.src = src, got %v", got)
181*1c12ee1eSDan Willemsen	}
182*1c12ee1eSDan Willemsen	if got := src.src; got != nil {
183*1c12ee1eSDan Willemsen		t.Errorf("Merge(dst, src): want src.src = nil, got %v", got)
184*1c12ee1eSDan Willemsen	}
185*1c12ee1eSDan Willemsen}
186