diff options
author | appilon <apilon@hashicorp.com> | 2019-02-27 16:43:31 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-27 16:43:31 -0500 |
commit | 844b5a68d8af4791755b8f0ad293cc99f5959183 (patch) | |
tree | 255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/golang/protobuf/proto/equal.go | |
parent | 303b299eeb6b06e939e35905e4b34cb410dd9dc3 (diff) | |
parent | 15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (diff) | |
download | terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.gz terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.zst terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.zip |
Merge pull request #27 from terraform-providers/go-modules-2019-02-22
[MODULES] Switch to Go Modules
Diffstat (limited to 'vendor/github.com/golang/protobuf/proto/equal.go')
-rw-r--r-- | vendor/github.com/golang/protobuf/proto/equal.go | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/vendor/github.com/golang/protobuf/proto/equal.go b/vendor/github.com/golang/protobuf/proto/equal.go new file mode 100644 index 0000000..d4db5a1 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/equal.go | |||
@@ -0,0 +1,300 @@ | |||
1 | // Go support for Protocol Buffers - Google's data interchange format | ||
2 | // | ||
3 | // Copyright 2011 The Go Authors. All rights reserved. | ||
4 | // https://github.com/golang/protobuf | ||
5 | // | ||
6 | // Redistribution and use in source and binary forms, with or without | ||
7 | // modification, are permitted provided that the following conditions are | ||
8 | // met: | ||
9 | // | ||
10 | // * Redistributions of source code must retain the above copyright | ||
11 | // notice, this list of conditions and the following disclaimer. | ||
12 | // * Redistributions in binary form must reproduce the above | ||
13 | // copyright notice, this list of conditions and the following disclaimer | ||
14 | // in the documentation and/or other materials provided with the | ||
15 | // distribution. | ||
16 | // * Neither the name of Google Inc. nor the names of its | ||
17 | // contributors may be used to endorse or promote products derived from | ||
18 | // this software without specific prior written permission. | ||
19 | // | ||
20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | |||
32 | // Protocol buffer comparison. | ||
33 | |||
34 | package proto | ||
35 | |||
36 | import ( | ||
37 | "bytes" | ||
38 | "log" | ||
39 | "reflect" | ||
40 | "strings" | ||
41 | ) | ||
42 | |||
43 | /* | ||
44 | Equal returns true iff protocol buffers a and b are equal. | ||
45 | The arguments must both be pointers to protocol buffer structs. | ||
46 | |||
47 | Equality is defined in this way: | ||
48 | - Two messages are equal iff they are the same type, | ||
49 | corresponding fields are equal, unknown field sets | ||
50 | are equal, and extensions sets are equal. | ||
51 | - Two set scalar fields are equal iff their values are equal. | ||
52 | If the fields are of a floating-point type, remember that | ||
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 == {}). | ||
56 | - Two repeated fields are equal iff their lengths are the same, | ||
57 | and their corresponding elements are equal. Note a "bytes" field, | ||
58 | although represented by []byte, is not a repeated field and the | ||
59 | rule for the scalar fields described above applies. | ||
60 | - Two unset fields are equal. | ||
61 | - Two unknown field sets are equal if their current | ||
62 | encoded state is equal. | ||
63 | - Two extension sets are equal iff they have corresponding | ||
64 | elements that are pairwise equal. | ||
65 | - Two map fields are equal iff their lengths are the same, | ||
66 | and they contain the same set of elements. Zero-length map | ||
67 | fields are equal. | ||
68 | - Every other combination of things are not equal. | ||
69 | |||
70 | The return value is undefined if a and b are not protocol buffers. | ||
71 | */ | ||
72 | func Equal(a, b Message) bool { | ||
73 | if a == nil || b == nil { | ||
74 | return a == b | ||
75 | } | ||
76 | v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b) | ||
77 | if v1.Type() != v2.Type() { | ||
78 | return false | ||
79 | } | ||
80 | if v1.Kind() == reflect.Ptr { | ||
81 | if v1.IsNil() { | ||
82 | return v2.IsNil() | ||
83 | } | ||
84 | if v2.IsNil() { | ||
85 | return false | ||
86 | } | ||
87 | v1, v2 = v1.Elem(), v2.Elem() | ||
88 | } | ||
89 | if v1.Kind() != reflect.Struct { | ||
90 | return false | ||
91 | } | ||
92 | return equalStruct(v1, v2) | ||
93 | } | ||
94 | |||
95 | // v1 and v2 are known to have the same type. | ||
96 | func equalStruct(v1, v2 reflect.Value) bool { | ||
97 | sprop := GetProperties(v1.Type()) | ||
98 | for i := 0; i < v1.NumField(); i++ { | ||
99 | f := v1.Type().Field(i) | ||
100 | if strings.HasPrefix(f.Name, "XXX_") { | ||
101 | continue | ||
102 | } | ||
103 | f1, f2 := v1.Field(i), v2.Field(i) | ||
104 | if f.Type.Kind() == reflect.Ptr { | ||
105 | if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 { | ||
106 | // both unset | ||
107 | continue | ||
108 | } else if n1 != n2 { | ||
109 | // set/unset mismatch | ||
110 | return false | ||
111 | } | ||
112 | f1, f2 = f1.Elem(), f2.Elem() | ||
113 | } | ||
114 | if !equalAny(f1, f2, sprop.Prop[i]) { | ||
115 | return false | ||
116 | } | ||
117 | } | ||
118 | |||
119 | if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() { | ||
120 | em2 := v2.FieldByName("XXX_InternalExtensions") | ||
121 | if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) { | ||
122 | return false | ||
123 | } | ||
124 | } | ||
125 | |||
126 | if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { | ||
127 | em2 := v2.FieldByName("XXX_extensions") | ||
128 | if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { | ||
129 | return false | ||
130 | } | ||
131 | } | ||
132 | |||
133 | uf := v1.FieldByName("XXX_unrecognized") | ||
134 | if !uf.IsValid() { | ||
135 | return true | ||
136 | } | ||
137 | |||
138 | u1 := uf.Bytes() | ||
139 | u2 := v2.FieldByName("XXX_unrecognized").Bytes() | ||
140 | return bytes.Equal(u1, u2) | ||
141 | } | ||
142 | |||
143 | // v1 and v2 are known to have the same type. | ||
144 | // prop may be nil. | ||
145 | func equalAny(v1, v2 reflect.Value, prop *Properties) bool { | ||
146 | if v1.Type() == protoMessageType { | ||
147 | m1, _ := v1.Interface().(Message) | ||
148 | m2, _ := v2.Interface().(Message) | ||
149 | return Equal(m1, m2) | ||
150 | } | ||
151 | switch v1.Kind() { | ||
152 | case reflect.Bool: | ||
153 | return v1.Bool() == v2.Bool() | ||
154 | case reflect.Float32, reflect.Float64: | ||
155 | return v1.Float() == v2.Float() | ||
156 | case reflect.Int32, reflect.Int64: | ||
157 | return v1.Int() == v2.Int() | ||
158 | case reflect.Interface: | ||
159 | // Probably a oneof field; compare the inner values. | ||
160 | n1, n2 := v1.IsNil(), v2.IsNil() | ||
161 | if n1 || n2 { | ||
162 | return n1 == n2 | ||
163 | } | ||
164 | e1, e2 := v1.Elem(), v2.Elem() | ||
165 | if e1.Type() != e2.Type() { | ||
166 | return false | ||
167 | } | ||
168 | return equalAny(e1, e2, nil) | ||
169 | case reflect.Map: | ||
170 | if v1.Len() != v2.Len() { | ||
171 | return false | ||
172 | } | ||
173 | for _, key := range v1.MapKeys() { | ||
174 | val2 := v2.MapIndex(key) | ||
175 | if !val2.IsValid() { | ||
176 | // This key was not found in the second map. | ||
177 | return false | ||
178 | } | ||
179 | if !equalAny(v1.MapIndex(key), val2, nil) { | ||
180 | return false | ||
181 | } | ||
182 | } | ||
183 | return true | ||
184 | case reflect.Ptr: | ||
185 | // Maps may have nil values in them, so check for nil. | ||
186 | if v1.IsNil() && v2.IsNil() { | ||
187 | return true | ||
188 | } | ||
189 | if v1.IsNil() != v2.IsNil() { | ||
190 | return false | ||
191 | } | ||
192 | return equalAny(v1.Elem(), v2.Elem(), prop) | ||
193 | case reflect.Slice: | ||
194 | if v1.Type().Elem().Kind() == reflect.Uint8 { | ||
195 | // short circuit: []byte | ||
196 | |||
197 | // Edge case: if this is in a proto3 message, a zero length | ||
198 | // bytes field is considered the zero value. | ||
199 | if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { | ||
200 | return true | ||
201 | } | ||
202 | if v1.IsNil() != v2.IsNil() { | ||
203 | return false | ||
204 | } | ||
205 | return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte)) | ||
206 | } | ||
207 | |||
208 | if v1.Len() != v2.Len() { | ||
209 | return false | ||
210 | } | ||
211 | for i := 0; i < v1.Len(); i++ { | ||
212 | if !equalAny(v1.Index(i), v2.Index(i), prop) { | ||
213 | return false | ||
214 | } | ||
215 | } | ||
216 | return true | ||
217 | case reflect.String: | ||
218 | return v1.Interface().(string) == v2.Interface().(string) | ||
219 | case reflect.Struct: | ||
220 | return equalStruct(v1, v2) | ||
221 | case reflect.Uint32, reflect.Uint64: | ||
222 | return v1.Uint() == v2.Uint() | ||
223 | } | ||
224 | |||
225 | // unknown type, so not a protocol buffer | ||
226 | log.Printf("proto: don't know how to compare %v", v1) | ||
227 | return false | ||
228 | } | ||
229 | |||
230 | // base is the struct type that the extensions are based on. | ||
231 | // x1 and x2 are InternalExtensions. | ||
232 | func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool { | ||
233 | em1, _ := x1.extensionsRead() | ||
234 | em2, _ := x2.extensionsRead() | ||
235 | return equalExtMap(base, em1, em2) | ||
236 | } | ||
237 | |||
238 | func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool { | ||
239 | if len(em1) != len(em2) { | ||
240 | return false | ||
241 | } | ||
242 | |||
243 | for extNum, e1 := range em1 { | ||
244 | e2, ok := em2[extNum] | ||
245 | if !ok { | ||
246 | return false | ||
247 | } | ||
248 | |||
249 | m1, m2 := e1.value, e2.value | ||
250 | |||
251 | if m1 == nil && m2 == nil { | ||
252 | // Both have only encoded form. | ||
253 | if bytes.Equal(e1.enc, e2.enc) { | ||
254 | continue | ||
255 | } | ||
256 | // The bytes are different, but the extensions might still be | ||
257 | // equal. We need to decode them to compare. | ||
258 | } | ||
259 | |||
260 | if m1 != nil && m2 != nil { | ||
261 | // Both are unencoded. | ||
262 | if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { | ||
263 | return false | ||
264 | } | ||
265 | continue | ||
266 | } | ||
267 | |||
268 | // At least one is encoded. To do a semantically correct comparison | ||
269 | // we need to unmarshal them first. | ||
270 | var desc *ExtensionDesc | ||
271 | if m := extensionMaps[base]; m != nil { | ||
272 | desc = m[extNum] | ||
273 | } | ||
274 | if desc == nil { | ||
275 | // If both have only encoded form and the bytes are the same, | ||
276 | // it is handled above. We get here when the bytes are different. | ||
277 | // We don't know how to decode it, so just compare them as byte | ||
278 | // slices. | ||
279 | log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) | ||
280 | return false | ||
281 | } | ||
282 | var err error | ||
283 | if m1 == nil { | ||
284 | m1, err = decodeExtension(e1.enc, desc) | ||
285 | } | ||
286 | if m2 == nil && err == nil { | ||
287 | m2, err = decodeExtension(e2.enc, desc) | ||
288 | } | ||
289 | if err != nil { | ||
290 | // The encoded form is invalid. | ||
291 | log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) | ||
292 | return false | ||
293 | } | ||
294 | if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { | ||
295 | return false | ||
296 | } | ||
297 | } | ||
298 | |||
299 | return true | ||
300 | } | ||