|
|
@@ -36,13 +36,7 @@ package proto
|
|
|
*/
|
|
|
|
|
|
import (
|
|
|
- "bytes"
|
|
|
- "encoding/json"
|
|
|
"errors"
|
|
|
- "fmt"
|
|
|
- "reflect"
|
|
|
- "sort"
|
|
|
- "sync"
|
|
|
)
|
|
|
|
|
|
// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
|
|
|
@@ -145,46 +139,9 @@ func skipVarint(buf []byte) []byte {
|
|
|
return buf[i+1:]
|
|
|
}
|
|
|
|
|
|
-// MarshalMessageSet encodes the extension map represented by m in the message set wire format.
|
|
|
-// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
|
|
|
-func MarshalMessageSet(exts interface{}) ([]byte, error) {
|
|
|
- return marshalMessageSet(exts, false)
|
|
|
-}
|
|
|
-
|
|
|
-// marshaMessageSet implements above function, with the opt to turn on / off deterministic during Marshal.
|
|
|
-func marshalMessageSet(exts interface{}, deterministic bool) ([]byte, error) {
|
|
|
- switch exts := exts.(type) {
|
|
|
- case *XXX_InternalExtensions:
|
|
|
- var u marshalInfo
|
|
|
- siz := u.sizeMessageSet(exts)
|
|
|
- b := make([]byte, 0, siz)
|
|
|
- return u.appendMessageSet(b, exts, deterministic)
|
|
|
-
|
|
|
- case map[int32]Extension:
|
|
|
- // This is an old-style extension map.
|
|
|
- // Wrap it in a new-style XXX_InternalExtensions.
|
|
|
- ie := XXX_InternalExtensions{
|
|
|
- p: &struct {
|
|
|
- mu sync.Mutex
|
|
|
- extensionMap map[int32]Extension
|
|
|
- }{
|
|
|
- extensionMap: exts,
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- var u marshalInfo
|
|
|
- siz := u.sizeMessageSet(&ie)
|
|
|
- b := make([]byte, 0, siz)
|
|
|
- return u.appendMessageSet(b, &ie, deterministic)
|
|
|
-
|
|
|
- default:
|
|
|
- return nil, errors.New("proto: not an extension map")
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
|
|
|
+// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
|
|
|
// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
|
|
|
-func UnmarshalMessageSet(buf []byte, exts interface{}) error {
|
|
|
+func unmarshalMessageSet(buf []byte, exts interface{}) error {
|
|
|
var m map[int32]Extension
|
|
|
switch exts := exts.(type) {
|
|
|
case *XXX_InternalExtensions:
|
|
|
@@ -222,93 +179,3 @@ func UnmarshalMessageSet(buf []byte, exts interface{}) error {
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
-
|
|
|
-// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
|
|
|
-// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
|
|
-func MarshalMessageSetJSON(exts interface{}) ([]byte, error) {
|
|
|
- var m map[int32]Extension
|
|
|
- switch exts := exts.(type) {
|
|
|
- case *XXX_InternalExtensions:
|
|
|
- var mu sync.Locker
|
|
|
- m, mu = exts.extensionsRead()
|
|
|
- if m != nil {
|
|
|
- // Keep the extensions map locked until we're done marshaling to prevent
|
|
|
- // races between marshaling and unmarshaling the lazily-{en,de}coded
|
|
|
- // values.
|
|
|
- mu.Lock()
|
|
|
- defer mu.Unlock()
|
|
|
- }
|
|
|
- case map[int32]Extension:
|
|
|
- m = exts
|
|
|
- default:
|
|
|
- return nil, errors.New("proto: not an extension map")
|
|
|
- }
|
|
|
- var b bytes.Buffer
|
|
|
- b.WriteByte('{')
|
|
|
-
|
|
|
- // Process the map in key order for deterministic output.
|
|
|
- ids := make([]int32, 0, len(m))
|
|
|
- for id := range m {
|
|
|
- ids = append(ids, id)
|
|
|
- }
|
|
|
- sort.Sort(int32Slice(ids)) // int32Slice defined in text.go
|
|
|
-
|
|
|
- for i, id := range ids {
|
|
|
- ext := m[id]
|
|
|
- msd, ok := messageSetMap[id]
|
|
|
- if !ok {
|
|
|
- // Unknown type; we can't render it, so skip it.
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- if i > 0 && b.Len() > 1 {
|
|
|
- b.WriteByte(',')
|
|
|
- }
|
|
|
-
|
|
|
- fmt.Fprintf(&b, `"[%s]":`, msd.name)
|
|
|
-
|
|
|
- x := ext.value
|
|
|
- if x == nil {
|
|
|
- x = reflect.New(msd.t.Elem()).Interface()
|
|
|
- if err := Unmarshal(ext.enc, x.(Message)); err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- }
|
|
|
- d, err := json.Marshal(x)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- b.Write(d)
|
|
|
- }
|
|
|
- b.WriteByte('}')
|
|
|
- return b.Bytes(), nil
|
|
|
-}
|
|
|
-
|
|
|
-// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
|
|
|
-// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
|
|
-func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error {
|
|
|
- // Common-case fast path.
|
|
|
- if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
- // This is fairly tricky, and it's not clear that it is needed.
|
|
|
- return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented")
|
|
|
-}
|
|
|
-
|
|
|
-// A global registry of types that can be used in a MessageSet.
|
|
|
-
|
|
|
-var messageSetMap = make(map[int32]messageSetDesc)
|
|
|
-
|
|
|
-type messageSetDesc struct {
|
|
|
- t reflect.Type // pointer to struct
|
|
|
- name string
|
|
|
-}
|
|
|
-
|
|
|
-// RegisterMessageSetType is called from the generated code.
|
|
|
-func RegisterMessageSetType(m Message, fieldNum int32, name string) {
|
|
|
- messageSetMap[fieldNum] = messageSetDesc{
|
|
|
- t: reflect.TypeOf(m),
|
|
|
- name: name,
|
|
|
- }
|
|
|
-}
|