@@ -50,7 +50,9 @@ Equality is defined in this way:
50
50
are equal, and extensions sets are equal.
51
51
- Two set scalar fields are equal iff their values are equal.
52
52
If the fields are of a floating-point type, remember that
53
- NaN != x for all x, including NaN.
53
+ NaN != x for all x, including NaN. If the message is defined
54
+ in a proto3 .proto file, fields are not "set"; specifically,
55
+ zero length proto3 "bytes" fields are equal (nil == {}).
54
56
- Two repeated fields are equal iff their lengths are the same,
55
57
and their corresponding elements are equal (a "bytes" field,
56
58
although represented by []byte, is not a repeated field)
@@ -88,6 +90,7 @@ func Equal(a, b Message) bool {
88
90
89
91
// v1 and v2 are known to have the same type.
90
92
func equalStruct (v1 , v2 reflect.Value ) bool {
93
+ sprop := GetProperties (v1 .Type ())
91
94
for i := 0 ; i < v1 .NumField (); i ++ {
92
95
f := v1 .Type ().Field (i )
93
96
if strings .HasPrefix (f .Name , "XXX_" ) {
@@ -113,7 +116,7 @@ func equalStruct(v1, v2 reflect.Value) bool {
113
116
}
114
117
f1 , f2 = f1 .Elem (), f2 .Elem ()
115
118
}
116
- if ! equalAny (f1 , f2 ) {
119
+ if ! equalAny (f1 , f2 , sprop . Prop [ i ] ) {
117
120
return false
118
121
}
119
122
}
@@ -140,7 +143,8 @@ func equalStruct(v1, v2 reflect.Value) bool {
140
143
}
141
144
142
145
// v1 and v2 are known to have the same type.
143
- func equalAny (v1 , v2 reflect.Value ) bool {
146
+ // prop may be nil.
147
+ func equalAny (v1 , v2 reflect.Value , prop * Properties ) bool {
144
148
if v1 .Type () == protoMessageType {
145
149
m1 , _ := v1 .Interface ().(Message )
146
150
m2 , _ := v2 .Interface ().(Message )
@@ -163,7 +167,7 @@ func equalAny(v1, v2 reflect.Value) bool {
163
167
if e1 .Type () != e2 .Type () {
164
168
return false
165
169
}
166
- return equalAny (e1 , e2 )
170
+ return equalAny (e1 , e2 , nil )
167
171
case reflect .Map :
168
172
if v1 .Len () != v2 .Len () {
169
173
return false
@@ -174,16 +178,22 @@ func equalAny(v1, v2 reflect.Value) bool {
174
178
// This key was not found in the second map.
175
179
return false
176
180
}
177
- if ! equalAny (v1 .MapIndex (key ), val2 ) {
181
+ if ! equalAny (v1 .MapIndex (key ), val2 , nil ) {
178
182
return false
179
183
}
180
184
}
181
185
return true
182
186
case reflect .Ptr :
183
- return equalAny (v1 .Elem (), v2 .Elem ())
187
+ return equalAny (v1 .Elem (), v2 .Elem (), prop )
184
188
case reflect .Slice :
185
189
if v1 .Type ().Elem ().Kind () == reflect .Uint8 {
186
190
// short circuit: []byte
191
+
192
+ // Edge case: if this is in a proto3 message, a zero length
193
+ // bytes field is considered the zero value.
194
+ if prop != nil && prop .proto3 && v1 .Len () == 0 && v2 .Len () == 0 {
195
+ return true
196
+ }
187
197
if v1 .IsNil () != v2 .IsNil () {
188
198
return false
189
199
}
@@ -194,7 +204,7 @@ func equalAny(v1, v2 reflect.Value) bool {
194
204
return false
195
205
}
196
206
for i := 0 ; i < v1 .Len (); i ++ {
197
- if ! equalAny (v1 .Index (i ), v2 .Index (i )) {
207
+ if ! equalAny (v1 .Index (i ), v2 .Index (i ), prop ) {
198
208
return false
199
209
}
200
210
}
@@ -229,7 +239,7 @@ func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool {
229
239
230
240
if m1 != nil && m2 != nil {
231
241
// Both are unencoded.
232
- if ! equalAny (reflect .ValueOf (m1 ), reflect .ValueOf (m2 )) {
242
+ if ! equalAny (reflect .ValueOf (m1 ), reflect .ValueOf (m2 ), nil ) {
233
243
return false
234
244
}
235
245
continue
@@ -257,7 +267,7 @@ func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool {
257
267
log .Printf ("proto: badly encoded extension %d of %v: %v" , extNum , base , err )
258
268
return false
259
269
}
260
- if ! equalAny (reflect .ValueOf (m1 ), reflect .ValueOf (m2 )) {
270
+ if ! equalAny (reflect .ValueOf (m1 ), reflect .ValueOf (m2 ), nil ) {
261
271
return false
262
272
}
263
273
}
0 commit comments