diff options
author | Alex Pilon <apilon@hashicorp.com> | 2019-02-22 18:24:37 -0500 |
---|---|---|
committer | Alex Pilon <apilon@hashicorp.com> | 2019-02-22 18:24:37 -0500 |
commit | 15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (patch) | |
tree | 255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/golang/protobuf/proto/message_set.go | |
parent | 07971ca38143c5faf951d152fba370ddcbe26ad5 (diff) | |
download | terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.gz terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.zst terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.zip |
deps: github.com/hashicorp/terraform@sdk-v0.11-with-go-modules
Updated via: go get github.com/hashicorp/terraform@sdk-v0.11-with-go-modules and go mod tidy
Diffstat (limited to 'vendor/github.com/golang/protobuf/proto/message_set.go')
-rw-r--r-- | vendor/github.com/golang/protobuf/proto/message_set.go | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/vendor/github.com/golang/protobuf/proto/message_set.go b/vendor/github.com/golang/protobuf/proto/message_set.go new file mode 100644 index 0000000..3b6ca41 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/message_set.go | |||
@@ -0,0 +1,314 @@ | |||
1 | // Go support for Protocol Buffers - Google's data interchange format | ||
2 | // | ||
3 | // Copyright 2010 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 | package proto | ||
33 | |||
34 | /* | ||
35 | * Support for message sets. | ||
36 | */ | ||
37 | |||
38 | import ( | ||
39 | "bytes" | ||
40 | "encoding/json" | ||
41 | "errors" | ||
42 | "fmt" | ||
43 | "reflect" | ||
44 | "sort" | ||
45 | "sync" | ||
46 | ) | ||
47 | |||
48 | // errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. | ||
49 | // A message type ID is required for storing a protocol buffer in a message set. | ||
50 | var errNoMessageTypeID = errors.New("proto does not have a message type ID") | ||
51 | |||
52 | // The first two types (_MessageSet_Item and messageSet) | ||
53 | // model what the protocol compiler produces for the following protocol message: | ||
54 | // message MessageSet { | ||
55 | // repeated group Item = 1 { | ||
56 | // required int32 type_id = 2; | ||
57 | // required string message = 3; | ||
58 | // }; | ||
59 | // } | ||
60 | // That is the MessageSet wire format. We can't use a proto to generate these | ||
61 | // because that would introduce a circular dependency between it and this package. | ||
62 | |||
63 | type _MessageSet_Item struct { | ||
64 | TypeId *int32 `protobuf:"varint,2,req,name=type_id"` | ||
65 | Message []byte `protobuf:"bytes,3,req,name=message"` | ||
66 | } | ||
67 | |||
68 | type messageSet struct { | ||
69 | Item []*_MessageSet_Item `protobuf:"group,1,rep"` | ||
70 | XXX_unrecognized []byte | ||
71 | // TODO: caching? | ||
72 | } | ||
73 | |||
74 | // Make sure messageSet is a Message. | ||
75 | var _ Message = (*messageSet)(nil) | ||
76 | |||
77 | // messageTypeIder is an interface satisfied by a protocol buffer type | ||
78 | // that may be stored in a MessageSet. | ||
79 | type messageTypeIder interface { | ||
80 | MessageTypeId() int32 | ||
81 | } | ||
82 | |||
83 | func (ms *messageSet) find(pb Message) *_MessageSet_Item { | ||
84 | mti, ok := pb.(messageTypeIder) | ||
85 | if !ok { | ||
86 | return nil | ||
87 | } | ||
88 | id := mti.MessageTypeId() | ||
89 | for _, item := range ms.Item { | ||
90 | if *item.TypeId == id { | ||
91 | return item | ||
92 | } | ||
93 | } | ||
94 | return nil | ||
95 | } | ||
96 | |||
97 | func (ms *messageSet) Has(pb Message) bool { | ||
98 | return ms.find(pb) != nil | ||
99 | } | ||
100 | |||
101 | func (ms *messageSet) Unmarshal(pb Message) error { | ||
102 | if item := ms.find(pb); item != nil { | ||
103 | return Unmarshal(item.Message, pb) | ||
104 | } | ||
105 | if _, ok := pb.(messageTypeIder); !ok { | ||
106 | return errNoMessageTypeID | ||
107 | } | ||
108 | return nil // TODO: return error instead? | ||
109 | } | ||
110 | |||
111 | func (ms *messageSet) Marshal(pb Message) error { | ||
112 | msg, err := Marshal(pb) | ||
113 | if err != nil { | ||
114 | return err | ||
115 | } | ||
116 | if item := ms.find(pb); item != nil { | ||
117 | // reuse existing item | ||
118 | item.Message = msg | ||
119 | return nil | ||
120 | } | ||
121 | |||
122 | mti, ok := pb.(messageTypeIder) | ||
123 | if !ok { | ||
124 | return errNoMessageTypeID | ||
125 | } | ||
126 | |||
127 | mtid := mti.MessageTypeId() | ||
128 | ms.Item = append(ms.Item, &_MessageSet_Item{ | ||
129 | TypeId: &mtid, | ||
130 | Message: msg, | ||
131 | }) | ||
132 | return nil | ||
133 | } | ||
134 | |||
135 | func (ms *messageSet) Reset() { *ms = messageSet{} } | ||
136 | func (ms *messageSet) String() string { return CompactTextString(ms) } | ||
137 | func (*messageSet) ProtoMessage() {} | ||
138 | |||
139 | // Support for the message_set_wire_format message option. | ||
140 | |||
141 | func skipVarint(buf []byte) []byte { | ||
142 | i := 0 | ||
143 | for ; buf[i]&0x80 != 0; i++ { | ||
144 | } | ||
145 | return buf[i+1:] | ||
146 | } | ||
147 | |||
148 | // MarshalMessageSet encodes the extension map represented by m in the message set wire format. | ||
149 | // It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option. | ||
150 | func MarshalMessageSet(exts interface{}) ([]byte, error) { | ||
151 | return marshalMessageSet(exts, false) | ||
152 | } | ||
153 | |||
154 | // marshaMessageSet implements above function, with the opt to turn on / off deterministic during Marshal. | ||
155 | func marshalMessageSet(exts interface{}, deterministic bool) ([]byte, error) { | ||
156 | switch exts := exts.(type) { | ||
157 | case *XXX_InternalExtensions: | ||
158 | var u marshalInfo | ||
159 | siz := u.sizeMessageSet(exts) | ||
160 | b := make([]byte, 0, siz) | ||
161 | return u.appendMessageSet(b, exts, deterministic) | ||
162 | |||
163 | case map[int32]Extension: | ||
164 | // This is an old-style extension map. | ||
165 | // Wrap it in a new-style XXX_InternalExtensions. | ||
166 | ie := XXX_InternalExtensions{ | ||
167 | p: &struct { | ||
168 | mu sync.Mutex | ||
169 | extensionMap map[int32]Extension | ||
170 | }{ | ||
171 | extensionMap: exts, | ||
172 | }, | ||
173 | } | ||
174 | |||
175 | var u marshalInfo | ||
176 | siz := u.sizeMessageSet(&ie) | ||
177 | b := make([]byte, 0, siz) | ||
178 | return u.appendMessageSet(b, &ie, deterministic) | ||
179 | |||
180 | default: | ||
181 | return nil, errors.New("proto: not an extension map") | ||
182 | } | ||
183 | } | ||
184 | |||
185 | // UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. | ||
186 | // It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option. | ||
187 | func UnmarshalMessageSet(buf []byte, exts interface{}) error { | ||
188 | var m map[int32]Extension | ||
189 | switch exts := exts.(type) { | ||
190 | case *XXX_InternalExtensions: | ||
191 | m = exts.extensionsWrite() | ||
192 | case map[int32]Extension: | ||
193 | m = exts | ||
194 | default: | ||
195 | return errors.New("proto: not an extension map") | ||
196 | } | ||
197 | |||
198 | ms := new(messageSet) | ||
199 | if err := Unmarshal(buf, ms); err != nil { | ||
200 | return err | ||
201 | } | ||
202 | for _, item := range ms.Item { | ||
203 | id := *item.TypeId | ||
204 | msg := item.Message | ||
205 | |||
206 | // Restore wire type and field number varint, plus length varint. | ||
207 | // Be careful to preserve duplicate items. | ||
208 | b := EncodeVarint(uint64(id)<<3 | WireBytes) | ||
209 | if ext, ok := m[id]; ok { | ||
210 | // Existing data; rip off the tag and length varint | ||
211 | // so we join the new data correctly. | ||
212 | // We can assume that ext.enc is set because we are unmarshaling. | ||
213 | o := ext.enc[len(b):] // skip wire type and field number | ||
214 | _, n := DecodeVarint(o) // calculate length of length varint | ||
215 | o = o[n:] // skip length varint | ||
216 | msg = append(o, msg...) // join old data and new data | ||
217 | } | ||
218 | b = append(b, EncodeVarint(uint64(len(msg)))...) | ||
219 | b = append(b, msg...) | ||
220 | |||
221 | m[id] = Extension{enc: b} | ||
222 | } | ||
223 | return nil | ||
224 | } | ||
225 | |||
226 | // MarshalMessageSetJSON encodes the extension map represented by m in JSON format. | ||
227 | // It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option. | ||
228 | func MarshalMessageSetJSON(exts interface{}) ([]byte, error) { | ||
229 | var m map[int32]Extension | ||
230 | switch exts := exts.(type) { | ||
231 | case *XXX_InternalExtensions: | ||
232 | var mu sync.Locker | ||
233 | m, mu = exts.extensionsRead() | ||
234 | if m != nil { | ||
235 | // Keep the extensions map locked until we're done marshaling to prevent | ||
236 | // races between marshaling and unmarshaling the lazily-{en,de}coded | ||
237 | // values. | ||
238 | mu.Lock() | ||
239 | defer mu.Unlock() | ||
240 | } | ||
241 | case map[int32]Extension: | ||
242 | m = exts | ||
243 | default: | ||
244 | return nil, errors.New("proto: not an extension map") | ||
245 | } | ||
246 | var b bytes.Buffer | ||
247 | b.WriteByte('{') | ||
248 | |||
249 | // Process the map in key order for deterministic output. | ||
250 | ids := make([]int32, 0, len(m)) | ||
251 | for id := range m { | ||
252 | ids = append(ids, id) | ||
253 | } | ||
254 | sort.Sort(int32Slice(ids)) // int32Slice defined in text.go | ||
255 | |||
256 | for i, id := range ids { | ||
257 | ext := m[id] | ||
258 | msd, ok := messageSetMap[id] | ||
259 | if !ok { | ||
260 | // Unknown type; we can't render it, so skip it. | ||
261 | continue | ||
262 | } | ||
263 | |||
264 | if i > 0 && b.Len() > 1 { | ||
265 | b.WriteByte(',') | ||
266 | } | ||
267 | |||
268 | fmt.Fprintf(&b, `"[%s]":`, msd.name) | ||
269 | |||
270 | x := ext.value | ||
271 | if x == nil { | ||
272 | x = reflect.New(msd.t.Elem()).Interface() | ||
273 | if err := Unmarshal(ext.enc, x.(Message)); err != nil { | ||
274 | return nil, err | ||
275 | } | ||
276 | } | ||
277 | d, err := json.Marshal(x) | ||
278 | if err != nil { | ||
279 | return nil, err | ||
280 | } | ||
281 | b.Write(d) | ||
282 | } | ||
283 | b.WriteByte('}') | ||
284 | return b.Bytes(), nil | ||
285 | } | ||
286 | |||
287 | // UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format. | ||
288 | // It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option. | ||
289 | func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error { | ||
290 | // Common-case fast path. | ||
291 | if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) { | ||
292 | return nil | ||
293 | } | ||
294 | |||
295 | // This is fairly tricky, and it's not clear that it is needed. | ||
296 | return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented") | ||
297 | } | ||
298 | |||
299 | // A global registry of types that can be used in a MessageSet. | ||
300 | |||
301 | var messageSetMap = make(map[int32]messageSetDesc) | ||
302 | |||
303 | type messageSetDesc struct { | ||
304 | t reflect.Type // pointer to struct | ||
305 | name string | ||
306 | } | ||
307 | |||
308 | // RegisterMessageSetType is called from the generated code. | ||
309 | func RegisterMessageSetType(m Message, fieldNum int32, name string) { | ||
310 | messageSetMap[fieldNum] = messageSetDesc{ | ||
311 | t: reflect.TypeOf(m), | ||
312 | name: name, | ||
313 | } | ||
314 | } | ||