diff options
| author | Jeff Carr <[email protected]> | 2025-10-09 06:22:47 -0500 |
|---|---|---|
| committer | Jeff Carr <[email protected]> | 2025-10-09 06:44:05 -0500 |
| commit | 1f282c7160e3776d6b532427e6c00ad82897a815 (patch) | |
| tree | 88b06dee70427650ea608a02b752a4342ca46c11 | |
| parent | b7ebd1bc4104df39062ddf264cf439fcdcac3881 (diff) | |
read and verify the version
| -rw-r--r-- | findFilename.go | 65 | ||||
| -rw-r--r-- | load.go | 35 |
2 files changed, 79 insertions, 21 deletions
diff --git a/findFilename.go b/findFilename.go index 85ccbf4..5e81974 100644 --- a/findFilename.go +++ b/findFilename.go @@ -14,6 +14,39 @@ var ErrProtoVarNotString error = errors.New("name exists but is not a string") // Gemini AI can help author some pretty good protobuf code. // I never remember the syntax for 'reflect' on these things. +// sets "Filename" if it exists in the protobuf +func SetFilename(pb proto.Message, filename string) (bool, error) { + msg := pb.ProtoReflect() // This is the entry point to the reflection API. + + descriptor := msg.Descriptor() // Get the message's descriptor, which contains metadata about its fields. + + fieldName := protoreflect.Name("Filename") + fieldDescriptor := descriptor.Fields().ByName(fieldName) + + if fieldDescriptor == nil { + fieldName = protoreflect.Name("filename") + fieldDescriptor = descriptor.Fields().ByName(fieldName) + } + + if fieldDescriptor == nil { + return false, fmt.Errorf("fieldDescriptor == nil") + } + + if fieldDescriptor.Kind() != protoreflect.StringKind { + // The field exists but is not a string, so we can't return it as one. + return false, fmt.Errorf("The field exists but is not a string") + } + + valueToSet := protoreflect.ValueOfString(filename) + + // 6. If the field exists and is a string, get its value. + // The value is returned as a protoreflect.Value. + msg.Set(fieldDescriptor, valueToSet) + + // 7. Convert the protoreflect.Value to a native Go string. + return true, nil +} + // this will try both "filename" and "Filename" func GetFilename(pb proto.Message) (string, error) { // 1. Get the protoreflect.Message interface from the message. @@ -56,35 +89,35 @@ func GetFilename(pb proto.Message) (string, error) { return value.String(), nil } -// sets "Filename" if it exists in the protobuf -func SetFilename(pb proto.Message, filename string) (bool, error) { - msg := pb.ProtoReflect() // This is the entry point to the reflection API. +// this will try both "filename" and "Filename" +func GetString(pb proto.Message, varname string) (string, error) { + // 1. Get the protoreflect.Message interface from the message. + // This is the entry point to the reflection API. + msg := pb.ProtoReflect() - descriptor := msg.Descriptor() // Get the message's descriptor, which contains metadata about its fields. + // 2. Get the message's descriptor, which contains metadata about its fields. + descriptor := msg.Descriptor() - fieldName := protoreflect.Name("Filename") + // 3. Find the specific field descriptor by its protobuf name ("Filename"). + // Note: The field name must match the name in the .proto file. + fieldName := protoreflect.Name(varname) fieldDescriptor := descriptor.Fields().ByName(fieldName) + // 4. Check if the field was found. If not, return false. if fieldDescriptor == nil { - fieldName = protoreflect.Name("filename") - fieldDescriptor = descriptor.Fields().ByName(fieldName) - } - - if fieldDescriptor == nil { - return false, fmt.Errorf("fieldDescriptor == nil") + return "", ErrProtoNoVarName } + // 5. (Optional but recommended) Verify the field is a string type. if fieldDescriptor.Kind() != protoreflect.StringKind { // The field exists but is not a string, so we can't return it as one. - return false, fmt.Errorf("The field exists but is not a string") + return "", ErrProtoVarNotString } - valueToSet := protoreflect.ValueOfString(filename) - // 6. If the field exists and is a string, get its value. // The value is returned as a protoreflect.Value. - msg.Set(fieldDescriptor, valueToSet) + value := msg.Get(fieldDescriptor) // 7. Convert the protoreflect.Value to a native Go string. - return true, nil + return value.String(), nil } @@ -73,19 +73,44 @@ func ConfigLoad(pb proto.Message, argname string, protoname string) error { func Load(pb proto.Message) error { fullname, err := GetFilename(pb) if err != nil { - log.Info("filename =", fullname, err) + log.Info("'Filename' is not in: =", fullname, err) return err } + ver, err := GetString(pb, "version") + if err != nil { + log.Info("'Version' is not in: =", fullname, err) + return err + } + var worked bool if strings.HasSuffix(fullname, ".text") { - return loadTEXT(pb, fullname) + if err := loadTEXT(pb, fullname); err != nil { + return err + } + worked = true } if strings.HasSuffix(fullname, ".json") { - return loadJSON(pb, fullname) + if err := loadJSON(pb, fullname); err != nil { + return err + } + worked = true } if strings.HasSuffix(fullname, ".pb") { - return loadPB(pb, fullname) + if err := loadPB(pb, fullname); err != nil { + return err + } + worked = true } - return log.Errorf("unknown filetype %s", fullname) + if !worked { + return log.Errorf("unknown filetype %s", fullname) + } + newver, _ := GetString(pb, "version") + if ver != newver { + log.Printf("VERSION '%s' != '%s'\n", ver, newver) + log.Info("Your protobuf file is old and can not be loaded") + log.Info("You must delete or convert the file", fullname) + panic("protobuf version mismatch") + } + return nil } func LoadFile(pb proto.Message, fullname string) error { |
