...
1 package aipreflect
2
3 import (
4 "fmt"
5 "strings"
6
7 "go.einride.tech/aip/resourcename"
8 "google.golang.org/genproto/googleapis/api/annotations"
9 "google.golang.org/protobuf/proto"
10 "google.golang.org/protobuf/reflect/protopath"
11 "google.golang.org/protobuf/reflect/protorange"
12 "google.golang.org/protobuf/reflect/protoreflect"
13 "google.golang.org/protobuf/reflect/protoregistry"
14 )
15
16
17 func ValidateResourceReferences(message proto.Message) error {
18 return protorange.Range(message.ProtoReflect(), func(values protopath.Values) error {
19 curr := values.Index(-1)
20 var field protoreflect.FieldDescriptor
21 var fieldValue string
22 switch curr.Step.Kind() {
23 case protopath.FieldAccessStep:
24 field = curr.Step.FieldDescriptor()
25 if field.Kind() != protoreflect.StringKind {
26 return nil
27 }
28 if field.Cardinality() == protoreflect.Repeated {
29 return nil
30 }
31 fieldValue = curr.Value.String()
32 case protopath.ListIndexStep:
33 prev := values.Index(-2)
34 field = prev.Step.FieldDescriptor()
35 if field.Kind() != protoreflect.StringKind {
36 return nil
37 }
38 fieldValue = curr.Value.String()
39 default:
40 return nil
41 }
42 resourceReferenceAnnotation := proto.GetExtension(
43 field.Options(), annotations.E_ResourceReference,
44 ).(*annotations.ResourceReference)
45 if resourceReferenceAnnotation == nil {
46 return nil
47 }
48 var errValidate error
49 RangeResourceDescriptorsInPackage(
50 protoregistry.GlobalFiles,
51 field.ParentFile().Package(),
52 func(resource *annotations.ResourceDescriptor) bool {
53 if resource.GetType() != resourceReferenceAnnotation.GetType() {
54 return true
55 }
56 for _, pattern := range resource.GetPattern() {
57 if resourcename.Match(pattern, fieldValue) {
58 return false
59 }
60 }
61 errValidate = fmt.Errorf(
62 "value '%s' of field %s is not a valid resource reference for %s",
63 fieldValue,
64
65 strings.TrimLeft(strings.TrimLeftFunc(values.Path.String(), func(r rune) bool {
66 return r != ')'
67 }), ")."),
68 resourceReferenceAnnotation.GetType(),
69 )
70 return false
71 },
72 )
73 return errValidate
74 })
75 }
76
View as plain text