44 "fmt"
55 "net/url"
66 "reflect"
7+ "strconv"
78 "strings"
89 "time"
910
@@ -98,6 +99,12 @@ func fieldByProtoName(m reflect.Value, name string) reflect.Value {
9899
99100func populateRepeatedField (f reflect.Value , values []string ) error {
100101 elemType := f .Type ().Elem ()
102+
103+ // is the destination field a slice of an enumeration type?
104+ if enumValMap := proto .EnumValueMap (elemType .String ()); enumValMap != nil {
105+ return populateFieldEnumRepeated (f , values , enumValMap )
106+ }
107+
101108 conv , ok := convFromType [elemType .Kind ()]
102109 if ! ok {
103110 return fmt .Errorf ("unsupported field type %s" , elemType )
@@ -137,6 +144,11 @@ func populateField(f reflect.Value, value string) error {
137144 }
138145 }
139146
147+ // is the destination field an enumeration type?
148+ if enumValMap := proto .EnumValueMap (f .Type ().String ()); enumValMap != nil {
149+ return populateFieldEnum (f , value , enumValMap )
150+ }
151+
140152 conv , ok := convFromType [f .Kind ()]
141153 if ! ok {
142154 return fmt .Errorf ("unsupported field type %T" , f )
@@ -149,6 +161,47 @@ func populateField(f reflect.Value, value string) error {
149161 return nil
150162}
151163
164+ func convertEnum (value string , t reflect.Type , enumValMap map [string ]int32 ) (reflect.Value , error ) {
165+ // see if it's an enumeration string
166+ if enumVal , ok := enumValMap [value ]; ok {
167+ return reflect .ValueOf (enumVal ).Convert (t ), nil
168+ }
169+
170+ // check for an integer that matches an enumeration value
171+ eVal , err := strconv .Atoi (value )
172+ if err != nil {
173+ return reflect.Value {}, fmt .Errorf ("%s is not a valid %s" , value , t )
174+ }
175+ for _ , v := range enumValMap {
176+ if v == int32 (eVal ) {
177+ return reflect .ValueOf (eVal ).Convert (t ), nil
178+ }
179+ }
180+ return reflect.Value {}, fmt .Errorf ("%s is not a valid %s" , value , t )
181+ }
182+
183+ func populateFieldEnum (f reflect.Value , value string , enumValMap map [string ]int32 ) error {
184+ cval , err := convertEnum (value , f .Type (), enumValMap )
185+ if err != nil {
186+ return err
187+ }
188+ f .Set (cval )
189+ return nil
190+ }
191+
192+ func populateFieldEnumRepeated (f reflect.Value , values []string , enumValMap map [string ]int32 ) error {
193+ elemType := f .Type ().Elem ()
194+ f .Set (reflect .MakeSlice (f .Type (), len (values ), len (values )).Convert (f .Type ()))
195+ for i , v := range values {
196+ result , err := convertEnum (v , elemType , enumValMap )
197+ if err != nil {
198+ return err
199+ }
200+ f .Index (i ).Set (result )
201+ }
202+ return nil
203+ }
204+
152205var (
153206 convFromType = map [reflect.Kind ]reflect.Value {
154207 reflect .String : reflect .ValueOf (String ),
0 commit comments