33 GoTag |
33 GoTag |
34 ) |
34 ) |
35 |
35 |
36 // Unmarshal deserializes the default string s according to the given kind k. |
36 // Unmarshal deserializes the default string s according to the given kind k. |
37 // When k is an enum, a list of enum value descriptors must be provided. |
37 // When k is an enum, a list of enum value descriptors must be provided. |
38 func Unmarshal(s string, k pref.Kind, evs pref.EnumValueDescriptors, f Format) (pref.Value, pref.EnumValueDescriptor, error) { |
38 func Unmarshal(s string, k protoreflect.Kind, evs protoreflect.EnumValueDescriptors, f Format) (protoreflect.Value, protoreflect.EnumValueDescriptor, error) { |
39 switch k { |
39 switch k { |
40 case pref.BoolKind: |
40 case protoreflect.BoolKind: |
41 if f == GoTag { |
41 if f == GoTag { |
42 switch s { |
42 switch s { |
43 case "1": |
43 case "1": |
44 return pref.ValueOfBool(true), nil, nil |
44 return protoreflect.ValueOfBool(true), nil, nil |
45 case "0": |
45 case "0": |
46 return pref.ValueOfBool(false), nil, nil |
46 return protoreflect.ValueOfBool(false), nil, nil |
47 } |
47 } |
48 } else { |
48 } else { |
49 switch s { |
49 switch s { |
50 case "true": |
50 case "true": |
51 return pref.ValueOfBool(true), nil, nil |
51 return protoreflect.ValueOfBool(true), nil, nil |
52 case "false": |
52 case "false": |
53 return pref.ValueOfBool(false), nil, nil |
53 return protoreflect.ValueOfBool(false), nil, nil |
54 } |
54 } |
55 } |
55 } |
56 case pref.EnumKind: |
56 case protoreflect.EnumKind: |
57 if f == GoTag { |
57 if f == GoTag { |
58 // Go tags use the numeric form of the enum value. |
58 // Go tags use the numeric form of the enum value. |
59 if n, err := strconv.ParseInt(s, 10, 32); err == nil { |
59 if n, err := strconv.ParseInt(s, 10, 32); err == nil { |
60 if ev := evs.ByNumber(pref.EnumNumber(n)); ev != nil { |
60 if ev := evs.ByNumber(protoreflect.EnumNumber(n)); ev != nil { |
61 return pref.ValueOfEnum(ev.Number()), ev, nil |
61 return protoreflect.ValueOfEnum(ev.Number()), ev, nil |
62 } |
62 } |
63 } |
63 } |
64 } else { |
64 } else { |
65 // Descriptor default_value use the enum identifier. |
65 // Descriptor default_value use the enum identifier. |
66 ev := evs.ByName(pref.Name(s)) |
66 ev := evs.ByName(protoreflect.Name(s)) |
67 if ev != nil { |
67 if ev != nil { |
68 return pref.ValueOfEnum(ev.Number()), ev, nil |
68 return protoreflect.ValueOfEnum(ev.Number()), ev, nil |
69 } |
69 } |
70 } |
70 } |
71 case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind: |
71 case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: |
72 if v, err := strconv.ParseInt(s, 10, 32); err == nil { |
72 if v, err := strconv.ParseInt(s, 10, 32); err == nil { |
73 return pref.ValueOfInt32(int32(v)), nil, nil |
73 return protoreflect.ValueOfInt32(int32(v)), nil, nil |
74 } |
74 } |
75 case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: |
75 case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: |
76 if v, err := strconv.ParseInt(s, 10, 64); err == nil { |
76 if v, err := strconv.ParseInt(s, 10, 64); err == nil { |
77 return pref.ValueOfInt64(int64(v)), nil, nil |
77 return protoreflect.ValueOfInt64(int64(v)), nil, nil |
78 } |
78 } |
79 case pref.Uint32Kind, pref.Fixed32Kind: |
79 case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: |
80 if v, err := strconv.ParseUint(s, 10, 32); err == nil { |
80 if v, err := strconv.ParseUint(s, 10, 32); err == nil { |
81 return pref.ValueOfUint32(uint32(v)), nil, nil |
81 return protoreflect.ValueOfUint32(uint32(v)), nil, nil |
82 } |
82 } |
83 case pref.Uint64Kind, pref.Fixed64Kind: |
83 case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: |
84 if v, err := strconv.ParseUint(s, 10, 64); err == nil { |
84 if v, err := strconv.ParseUint(s, 10, 64); err == nil { |
85 return pref.ValueOfUint64(uint64(v)), nil, nil |
85 return protoreflect.ValueOfUint64(uint64(v)), nil, nil |
86 } |
86 } |
87 case pref.FloatKind, pref.DoubleKind: |
87 case protoreflect.FloatKind, protoreflect.DoubleKind: |
88 var v float64 |
88 var v float64 |
89 var err error |
89 var err error |
90 switch s { |
90 switch s { |
91 case "-inf": |
91 case "-inf": |
92 v = math.Inf(-1) |
92 v = math.Inf(-1) |
96 v = math.NaN() |
96 v = math.NaN() |
97 default: |
97 default: |
98 v, err = strconv.ParseFloat(s, 64) |
98 v, err = strconv.ParseFloat(s, 64) |
99 } |
99 } |
100 if err == nil { |
100 if err == nil { |
101 if k == pref.FloatKind { |
101 if k == protoreflect.FloatKind { |
102 return pref.ValueOfFloat32(float32(v)), nil, nil |
102 return protoreflect.ValueOfFloat32(float32(v)), nil, nil |
103 } else { |
103 } else { |
104 return pref.ValueOfFloat64(float64(v)), nil, nil |
104 return protoreflect.ValueOfFloat64(float64(v)), nil, nil |
105 } |
105 } |
106 } |
106 } |
107 case pref.StringKind: |
107 case protoreflect.StringKind: |
108 // String values are already unescaped and can be used as is. |
108 // String values are already unescaped and can be used as is. |
109 return pref.ValueOfString(s), nil, nil |
109 return protoreflect.ValueOfString(s), nil, nil |
110 case pref.BytesKind: |
110 case protoreflect.BytesKind: |
111 if b, ok := unmarshalBytes(s); ok { |
111 if b, ok := unmarshalBytes(s); ok { |
112 return pref.ValueOfBytes(b), nil, nil |
112 return protoreflect.ValueOfBytes(b), nil, nil |
113 } |
113 } |
114 } |
114 } |
115 return pref.Value{}, nil, errors.New("could not parse value for %v: %q", k, s) |
115 return protoreflect.Value{}, nil, errors.New("could not parse value for %v: %q", k, s) |
116 } |
116 } |
117 |
117 |
118 // Marshal serializes v as the default string according to the given kind k. |
118 // Marshal serializes v as the default string according to the given kind k. |
119 // When specifying the Descriptor format for an enum kind, the associated |
119 // When specifying the Descriptor format for an enum kind, the associated |
120 // enum value descriptor must be provided. |
120 // enum value descriptor must be provided. |
121 func Marshal(v pref.Value, ev pref.EnumValueDescriptor, k pref.Kind, f Format) (string, error) { |
121 func Marshal(v protoreflect.Value, ev protoreflect.EnumValueDescriptor, k protoreflect.Kind, f Format) (string, error) { |
122 switch k { |
122 switch k { |
123 case pref.BoolKind: |
123 case protoreflect.BoolKind: |
124 if f == GoTag { |
124 if f == GoTag { |
125 if v.Bool() { |
125 if v.Bool() { |
126 return "1", nil |
126 return "1", nil |
127 } else { |
127 } else { |
128 return "0", nil |
128 return "0", nil |
132 return "true", nil |
132 return "true", nil |
133 } else { |
133 } else { |
134 return "false", nil |
134 return "false", nil |
135 } |
135 } |
136 } |
136 } |
137 case pref.EnumKind: |
137 case protoreflect.EnumKind: |
138 if f == GoTag { |
138 if f == GoTag { |
139 return strconv.FormatInt(int64(v.Enum()), 10), nil |
139 return strconv.FormatInt(int64(v.Enum()), 10), nil |
140 } else { |
140 } else { |
141 return string(ev.Name()), nil |
141 return string(ev.Name()), nil |
142 } |
142 } |
143 case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind, pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: |
143 case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: |
144 return strconv.FormatInt(v.Int(), 10), nil |
144 return strconv.FormatInt(v.Int(), 10), nil |
145 case pref.Uint32Kind, pref.Fixed32Kind, pref.Uint64Kind, pref.Fixed64Kind: |
145 case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind: |
146 return strconv.FormatUint(v.Uint(), 10), nil |
146 return strconv.FormatUint(v.Uint(), 10), nil |
147 case pref.FloatKind, pref.DoubleKind: |
147 case protoreflect.FloatKind, protoreflect.DoubleKind: |
148 f := v.Float() |
148 f := v.Float() |
149 switch { |
149 switch { |
150 case math.IsInf(f, -1): |
150 case math.IsInf(f, -1): |
151 return "-inf", nil |
151 return "-inf", nil |
152 case math.IsInf(f, +1): |
152 case math.IsInf(f, +1): |
153 return "inf", nil |
153 return "inf", nil |
154 case math.IsNaN(f): |
154 case math.IsNaN(f): |
155 return "nan", nil |
155 return "nan", nil |
156 default: |
156 default: |
157 if k == pref.FloatKind { |
157 if k == protoreflect.FloatKind { |
158 return strconv.FormatFloat(f, 'g', -1, 32), nil |
158 return strconv.FormatFloat(f, 'g', -1, 32), nil |
159 } else { |
159 } else { |
160 return strconv.FormatFloat(f, 'g', -1, 64), nil |
160 return strconv.FormatFloat(f, 'g', -1, 64), nil |
161 } |
161 } |
162 } |
162 } |
163 case pref.StringKind: |
163 case protoreflect.StringKind: |
164 // String values are serialized as is without any escaping. |
164 // String values are serialized as is without any escaping. |
165 return v.String(), nil |
165 return v.String(), nil |
166 case pref.BytesKind: |
166 case protoreflect.BytesKind: |
167 if s, ok := marshalBytes(v.Bytes()); ok { |
167 if s, ok := marshalBytes(v.Bytes()); ok { |
168 return s, nil |
168 return s, nil |
169 } |
169 } |
170 } |
170 } |
171 return "", errors.New("could not format value for %v: %v", k, v) |
171 return "", errors.New("could not format value for %v: %v", k, v) |