xref: /aosp_15_r20/external/golang-protobuf/encoding/prototext/other_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 Willemsenpackage prototext_test
6*1c12ee1eSDan Willemsen
7*1c12ee1eSDan Willemsenimport (
8*1c12ee1eSDan Willemsen	"testing"
9*1c12ee1eSDan Willemsen
10*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/encoding/prototext"
11*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/proto"
12*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/reflect/protoregistry"
13*1c12ee1eSDan Willemsen
14*1c12ee1eSDan Willemsen	pb2 "google.golang.org/protobuf/internal/testprotos/textpb2"
15*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/types/known/anypb"
16*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/types/known/durationpb"
17*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/types/known/emptypb"
18*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/types/known/structpb"
19*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/types/known/timestamppb"
20*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/types/known/wrapperspb"
21*1c12ee1eSDan Willemsen)
22*1c12ee1eSDan Willemsen
23*1c12ee1eSDan Willemsenfunc TestRoundTrip(t *testing.T) {
24*1c12ee1eSDan Willemsen	tests := []struct {
25*1c12ee1eSDan Willemsen		desc     string
26*1c12ee1eSDan Willemsen		resolver *protoregistry.Types
27*1c12ee1eSDan Willemsen		message  proto.Message
28*1c12ee1eSDan Willemsen	}{{
29*1c12ee1eSDan Willemsen		desc: "well-known type fields set to empty messages",
30*1c12ee1eSDan Willemsen		message: &pb2.KnownTypes{
31*1c12ee1eSDan Willemsen			OptBool:      &wrapperspb.BoolValue{},
32*1c12ee1eSDan Willemsen			OptInt32:     &wrapperspb.Int32Value{},
33*1c12ee1eSDan Willemsen			OptInt64:     &wrapperspb.Int64Value{},
34*1c12ee1eSDan Willemsen			OptUint32:    &wrapperspb.UInt32Value{},
35*1c12ee1eSDan Willemsen			OptUint64:    &wrapperspb.UInt64Value{},
36*1c12ee1eSDan Willemsen			OptFloat:     &wrapperspb.FloatValue{},
37*1c12ee1eSDan Willemsen			OptDouble:    &wrapperspb.DoubleValue{},
38*1c12ee1eSDan Willemsen			OptString:    &wrapperspb.StringValue{},
39*1c12ee1eSDan Willemsen			OptBytes:     &wrapperspb.BytesValue{},
40*1c12ee1eSDan Willemsen			OptDuration:  &durationpb.Duration{},
41*1c12ee1eSDan Willemsen			OptTimestamp: &timestamppb.Timestamp{},
42*1c12ee1eSDan Willemsen			OptStruct:    &structpb.Struct{},
43*1c12ee1eSDan Willemsen			OptList:      &structpb.ListValue{},
44*1c12ee1eSDan Willemsen			OptValue:     &structpb.Value{},
45*1c12ee1eSDan Willemsen			OptEmpty:     &emptypb.Empty{},
46*1c12ee1eSDan Willemsen			OptAny:       &anypb.Any{},
47*1c12ee1eSDan Willemsen		},
48*1c12ee1eSDan Willemsen	}, {
49*1c12ee1eSDan Willemsen		desc: "well-known type scalar fields",
50*1c12ee1eSDan Willemsen		message: &pb2.KnownTypes{
51*1c12ee1eSDan Willemsen			OptBool: &wrapperspb.BoolValue{
52*1c12ee1eSDan Willemsen				Value: true,
53*1c12ee1eSDan Willemsen			},
54*1c12ee1eSDan Willemsen			OptInt32: &wrapperspb.Int32Value{
55*1c12ee1eSDan Willemsen				Value: -42,
56*1c12ee1eSDan Willemsen			},
57*1c12ee1eSDan Willemsen			OptInt64: &wrapperspb.Int64Value{
58*1c12ee1eSDan Willemsen				Value: -42,
59*1c12ee1eSDan Willemsen			},
60*1c12ee1eSDan Willemsen			OptUint32: &wrapperspb.UInt32Value{
61*1c12ee1eSDan Willemsen				Value: 0xff,
62*1c12ee1eSDan Willemsen			},
63*1c12ee1eSDan Willemsen			OptUint64: &wrapperspb.UInt64Value{
64*1c12ee1eSDan Willemsen				Value: 0xffff,
65*1c12ee1eSDan Willemsen			},
66*1c12ee1eSDan Willemsen			OptFloat: &wrapperspb.FloatValue{
67*1c12ee1eSDan Willemsen				Value: 1.234,
68*1c12ee1eSDan Willemsen			},
69*1c12ee1eSDan Willemsen			OptDouble: &wrapperspb.DoubleValue{
70*1c12ee1eSDan Willemsen				Value: 1.23e308,
71*1c12ee1eSDan Willemsen			},
72*1c12ee1eSDan Willemsen			OptString: &wrapperspb.StringValue{
73*1c12ee1eSDan Willemsen				Value: "谷歌",
74*1c12ee1eSDan Willemsen			},
75*1c12ee1eSDan Willemsen			OptBytes: &wrapperspb.BytesValue{
76*1c12ee1eSDan Willemsen				Value: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
77*1c12ee1eSDan Willemsen			},
78*1c12ee1eSDan Willemsen		},
79*1c12ee1eSDan Willemsen	}, {
80*1c12ee1eSDan Willemsen		desc: "well-known type time-related fields",
81*1c12ee1eSDan Willemsen		message: &pb2.KnownTypes{
82*1c12ee1eSDan Willemsen			OptDuration: &durationpb.Duration{
83*1c12ee1eSDan Willemsen				Seconds: -3600,
84*1c12ee1eSDan Willemsen				Nanos:   -123,
85*1c12ee1eSDan Willemsen			},
86*1c12ee1eSDan Willemsen			OptTimestamp: &timestamppb.Timestamp{
87*1c12ee1eSDan Willemsen				Seconds: 1257894000,
88*1c12ee1eSDan Willemsen				Nanos:   123,
89*1c12ee1eSDan Willemsen			},
90*1c12ee1eSDan Willemsen		},
91*1c12ee1eSDan Willemsen	}, {
92*1c12ee1eSDan Willemsen		desc: "Struct field and different Value types",
93*1c12ee1eSDan Willemsen		message: &pb2.KnownTypes{
94*1c12ee1eSDan Willemsen			OptStruct: &structpb.Struct{
95*1c12ee1eSDan Willemsen				Fields: map[string]*structpb.Value{
96*1c12ee1eSDan Willemsen					"bool": &structpb.Value{
97*1c12ee1eSDan Willemsen						Kind: &structpb.Value_BoolValue{
98*1c12ee1eSDan Willemsen							BoolValue: true,
99*1c12ee1eSDan Willemsen						},
100*1c12ee1eSDan Willemsen					},
101*1c12ee1eSDan Willemsen					"double": &structpb.Value{
102*1c12ee1eSDan Willemsen						Kind: &structpb.Value_NumberValue{
103*1c12ee1eSDan Willemsen							NumberValue: 3.1415,
104*1c12ee1eSDan Willemsen						},
105*1c12ee1eSDan Willemsen					},
106*1c12ee1eSDan Willemsen					"null": &structpb.Value{
107*1c12ee1eSDan Willemsen						Kind: &structpb.Value_NullValue{
108*1c12ee1eSDan Willemsen							NullValue: structpb.NullValue_NULL_VALUE,
109*1c12ee1eSDan Willemsen						},
110*1c12ee1eSDan Willemsen					},
111*1c12ee1eSDan Willemsen					"string": &structpb.Value{
112*1c12ee1eSDan Willemsen						Kind: &structpb.Value_StringValue{
113*1c12ee1eSDan Willemsen							StringValue: "string",
114*1c12ee1eSDan Willemsen						},
115*1c12ee1eSDan Willemsen					},
116*1c12ee1eSDan Willemsen					"struct": &structpb.Value{
117*1c12ee1eSDan Willemsen						Kind: &structpb.Value_StructValue{
118*1c12ee1eSDan Willemsen							StructValue: &structpb.Struct{
119*1c12ee1eSDan Willemsen								Fields: map[string]*structpb.Value{
120*1c12ee1eSDan Willemsen									"bool": &structpb.Value{
121*1c12ee1eSDan Willemsen										Kind: &structpb.Value_BoolValue{
122*1c12ee1eSDan Willemsen											BoolValue: false,
123*1c12ee1eSDan Willemsen										},
124*1c12ee1eSDan Willemsen									},
125*1c12ee1eSDan Willemsen								},
126*1c12ee1eSDan Willemsen							},
127*1c12ee1eSDan Willemsen						},
128*1c12ee1eSDan Willemsen					},
129*1c12ee1eSDan Willemsen					"list": &structpb.Value{
130*1c12ee1eSDan Willemsen						Kind: &structpb.Value_ListValue{
131*1c12ee1eSDan Willemsen							ListValue: &structpb.ListValue{
132*1c12ee1eSDan Willemsen								Values: []*structpb.Value{
133*1c12ee1eSDan Willemsen									{
134*1c12ee1eSDan Willemsen										Kind: &structpb.Value_BoolValue{
135*1c12ee1eSDan Willemsen											BoolValue: false,
136*1c12ee1eSDan Willemsen										},
137*1c12ee1eSDan Willemsen									},
138*1c12ee1eSDan Willemsen									{
139*1c12ee1eSDan Willemsen										Kind: &structpb.Value_StringValue{
140*1c12ee1eSDan Willemsen											StringValue: "hello",
141*1c12ee1eSDan Willemsen										},
142*1c12ee1eSDan Willemsen									},
143*1c12ee1eSDan Willemsen								},
144*1c12ee1eSDan Willemsen							},
145*1c12ee1eSDan Willemsen						},
146*1c12ee1eSDan Willemsen					},
147*1c12ee1eSDan Willemsen				},
148*1c12ee1eSDan Willemsen			},
149*1c12ee1eSDan Willemsen		},
150*1c12ee1eSDan Willemsen	}, {
151*1c12ee1eSDan Willemsen		desc:     "Any field without registered type",
152*1c12ee1eSDan Willemsen		resolver: new(protoregistry.Types),
153*1c12ee1eSDan Willemsen		message: func() proto.Message {
154*1c12ee1eSDan Willemsen			m := &pb2.Nested{
155*1c12ee1eSDan Willemsen				OptString: proto.String("embedded inside Any"),
156*1c12ee1eSDan Willemsen				OptNested: &pb2.Nested{
157*1c12ee1eSDan Willemsen					OptString: proto.String("inception"),
158*1c12ee1eSDan Willemsen				},
159*1c12ee1eSDan Willemsen			}
160*1c12ee1eSDan Willemsen			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
161*1c12ee1eSDan Willemsen			if err != nil {
162*1c12ee1eSDan Willemsen				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
163*1c12ee1eSDan Willemsen			}
164*1c12ee1eSDan Willemsen			return &pb2.KnownTypes{
165*1c12ee1eSDan Willemsen				OptAny: &anypb.Any{
166*1c12ee1eSDan Willemsen					TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
167*1c12ee1eSDan Willemsen					Value:   b,
168*1c12ee1eSDan Willemsen				},
169*1c12ee1eSDan Willemsen			}
170*1c12ee1eSDan Willemsen		}(),
171*1c12ee1eSDan Willemsen	}, {
172*1c12ee1eSDan Willemsen		desc: "Any field with registered type",
173*1c12ee1eSDan Willemsen		message: func() *pb2.KnownTypes {
174*1c12ee1eSDan Willemsen			m := &pb2.Nested{
175*1c12ee1eSDan Willemsen				OptString: proto.String("embedded inside Any"),
176*1c12ee1eSDan Willemsen				OptNested: &pb2.Nested{
177*1c12ee1eSDan Willemsen					OptString: proto.String("inception"),
178*1c12ee1eSDan Willemsen				},
179*1c12ee1eSDan Willemsen			}
180*1c12ee1eSDan Willemsen			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
181*1c12ee1eSDan Willemsen			if err != nil {
182*1c12ee1eSDan Willemsen				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
183*1c12ee1eSDan Willemsen			}
184*1c12ee1eSDan Willemsen			return &pb2.KnownTypes{
185*1c12ee1eSDan Willemsen				OptAny: &anypb.Any{
186*1c12ee1eSDan Willemsen					TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
187*1c12ee1eSDan Willemsen					Value:   b,
188*1c12ee1eSDan Willemsen				},
189*1c12ee1eSDan Willemsen			}
190*1c12ee1eSDan Willemsen		}(),
191*1c12ee1eSDan Willemsen	}, {
192*1c12ee1eSDan Willemsen		desc: "Any field containing Any message",
193*1c12ee1eSDan Willemsen		message: func() *pb2.KnownTypes {
194*1c12ee1eSDan Willemsen			m1 := &pb2.Nested{
195*1c12ee1eSDan Willemsen				OptString: proto.String("message inside Any of another Any field"),
196*1c12ee1eSDan Willemsen			}
197*1c12ee1eSDan Willemsen			b1, err := proto.MarshalOptions{Deterministic: true}.Marshal(m1)
198*1c12ee1eSDan Willemsen			if err != nil {
199*1c12ee1eSDan Willemsen				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
200*1c12ee1eSDan Willemsen			}
201*1c12ee1eSDan Willemsen			m2 := &anypb.Any{
202*1c12ee1eSDan Willemsen				TypeUrl: "pb2.Nested",
203*1c12ee1eSDan Willemsen				Value:   b1,
204*1c12ee1eSDan Willemsen			}
205*1c12ee1eSDan Willemsen			b2, err := proto.MarshalOptions{Deterministic: true}.Marshal(m2)
206*1c12ee1eSDan Willemsen			if err != nil {
207*1c12ee1eSDan Willemsen				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
208*1c12ee1eSDan Willemsen			}
209*1c12ee1eSDan Willemsen			return &pb2.KnownTypes{
210*1c12ee1eSDan Willemsen				OptAny: &anypb.Any{
211*1c12ee1eSDan Willemsen					TypeUrl: "google.protobuf.Any",
212*1c12ee1eSDan Willemsen					Value:   b2,
213*1c12ee1eSDan Willemsen				},
214*1c12ee1eSDan Willemsen			}
215*1c12ee1eSDan Willemsen		}(),
216*1c12ee1eSDan Willemsen	}}
217*1c12ee1eSDan Willemsen
218*1c12ee1eSDan Willemsen	for _, tt := range tests {
219*1c12ee1eSDan Willemsen		tt := tt
220*1c12ee1eSDan Willemsen		t.Run(tt.desc, func(t *testing.T) {
221*1c12ee1eSDan Willemsen			t.Parallel()
222*1c12ee1eSDan Willemsen			b, err := prototext.MarshalOptions{Resolver: tt.resolver}.Marshal(tt.message)
223*1c12ee1eSDan Willemsen			if err != nil {
224*1c12ee1eSDan Willemsen				t.Errorf("Marshal() returned error: %v\n\n", err)
225*1c12ee1eSDan Willemsen			}
226*1c12ee1eSDan Willemsen
227*1c12ee1eSDan Willemsen			gotMessage := new(pb2.KnownTypes)
228*1c12ee1eSDan Willemsen			err = prototext.UnmarshalOptions{Resolver: tt.resolver}.Unmarshal(b, gotMessage)
229*1c12ee1eSDan Willemsen			if err != nil {
230*1c12ee1eSDan Willemsen				t.Errorf("Unmarshal() returned error: %v\n\n", err)
231*1c12ee1eSDan Willemsen			}
232*1c12ee1eSDan Willemsen
233*1c12ee1eSDan Willemsen			if !proto.Equal(gotMessage, tt.message) {
234*1c12ee1eSDan Willemsen				t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", gotMessage, tt.message)
235*1c12ee1eSDan Willemsen			}
236*1c12ee1eSDan Willemsen		})
237*1c12ee1eSDan Willemsen	}
238*1c12ee1eSDan Willemsen}
239