143 for ; buf[i]&0x80 != 0; i++ { |
137 for ; buf[i]&0x80 != 0; i++ { |
144 } |
138 } |
145 return buf[i+1:] |
139 return buf[i+1:] |
146 } |
140 } |
147 |
141 |
148 // MarshalMessageSet encodes the extension map represented by m in the message set wire format. |
142 // unmarshalMessageSet decodes the extension map encoded in buf 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. |
143 // 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 { |
144 func unmarshalMessageSet(buf []byte, exts interface{}) error { |
188 var m map[int32]Extension |
145 var m map[int32]Extension |
189 switch exts := exts.(type) { |
146 switch exts := exts.(type) { |
190 case *XXX_InternalExtensions: |
147 case *XXX_InternalExtensions: |
191 m = exts.extensionsWrite() |
148 m = exts.extensionsWrite() |
192 case map[int32]Extension: |
149 case map[int32]Extension: |
220 |
177 |
221 m[id] = Extension{enc: b} |
178 m[id] = Extension{enc: b} |
222 } |
179 } |
223 return nil |
180 return nil |
224 } |
181 } |
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 } |
|