samedi 23 novembre 2019

Extracing tags from deeply nested protobuf structs in Go using reflection

I am trying to extract some tags from some deeply nested structs. The structs were generated from a protobuf message and contain a json tag.

I have pointer to a struct that may contain a struct with fields whose tags that I may want. I can iterate using the type to get the fields of a struct but when I encounter a field that is pointer how do I get its value and then recurse?

// Struct has hierarchy like this 
a := &somepb.UpdateRequest{
        Updates: []*somepb.UpdateRequest_Foo{
            &somepb.UpdateRequest_Foo{
                Id: 1,
                Foo: &somepb.FooInfo{
                    Metadata: &somepb.Metadata{
                        Name:        "Foo",
                        Description: "Bar",
                    },
                    Some:    "s",
                    Things:  "o",
                    Are:     "m",
                    Broken:  "e",
                    Here:    "p",
                },
            },
        },
 } 

// ParseStruct parses struct tags of given object
func ParseStruct(obj interface{}, tag string) {
    r := reflect.ValueOf(obj)
    if r.Kind() == reflect.Ptr {
        obj = r.Elem().Interface()
    }
    rv := reflect.TypeOf(obj)
    for i := 0; i < rv.NumField(); i++ {
        f := rv.Field(i)
        // This is to avoid getting tags for Metadata itself (from the struct above)
        // which is *Metadata, I want the tags for Name and Description
        // inside *Metadata instead
        if f.Type.Kind() == reflect.Ptr {
            value := f.Tag.Get(tag)
            if len(value) == 0 {
                continue
            }
            fmt.Println(value)
        }
    }
} 




Aucun commentaire:

Enregistrer un commentaire