summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2025-10-09 06:22:47 -0500
committerJeff Carr <[email protected]>2025-10-09 06:44:05 -0500
commit1f282c7160e3776d6b532427e6c00ad82897a815 (patch)
tree88b06dee70427650ea608a02b752a4342ca46c11
parentb7ebd1bc4104df39062ddf264cf439fcdcac3881 (diff)
read and verify the version
-rw-r--r--findFilename.go65
-rw-r--r--load.go35
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
}
diff --git a/load.go b/load.go
index 93bd19a..dba0bf1 100644
--- a/load.go
+++ b/load.go
@@ -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 {