@@ -441,6 +441,7 @@ func configGroup() *cobra.Command {
441
441
// which we use to determine if a config is an enum config
442
442
// Keep map of (enum) config names to translated enum name and values
443
443
// We'll build up the values lookup map in a later stage
444
+ // TODO: maybe cleanup into a proper type
444
445
enumLookupMap := make (map [string ]struct {
445
446
name string
446
447
values map [string ]string
@@ -592,6 +593,62 @@ func configGroup() *cobra.Command {
592
593
defaultValue .Set (mt .Descriptor ().Fields ().ByName (protoreflect .Name (protoFieldNames [i ])), protoreflect .ValueOf (orig .Value ))
593
594
}
594
595
newF .Value = defaultValue
596
+ // TODO: Should probably extract this/enum handling logic out for better code org...
597
+ // Handle overrides using the following logic:
598
+ // 1. Flatten out all overrides
599
+ // 2. Scan rules to check if any are identical to a previous one, note
600
+ // 3. Merge overrides with the same rules "upwards"
601
+ // 4. Write into overall overrides
602
+ overrides := make ([]* feature.Override , 0 )
603
+ ruleFirsts := make (map [string ]* feature.Override ) // Map of rulestrings to pointers of the first override that has them
604
+ for i , cn := range configNames {
605
+ orig := compiledMap [cn ]
606
+ enumLookup , isEnum := enumLookupMap [cn ]
607
+ for _ , origOverride := range orig .Overrides {
608
+ var origValProto protoreflect.Value
609
+ if isEnum {
610
+ if origVal , ok := origOverride .Value .(string ); ok {
611
+ enumDescriptor := mt .Descriptor ().Enums ().ByName (protoreflect .Name (enumLookup .name ))
612
+ if enumDescriptor == nil {
613
+ return errors .Errorf ("missing enum descriptor for %s" , enumLookup .name )
614
+ }
615
+ valueDescriptor := enumDescriptor .Values ().ByName (protoreflect .Name (enumLookup .values [origVal ]))
616
+ if valueDescriptor == nil {
617
+ return errors .Errorf ("missing enum value for %s" , enumLookup .values [origVal ])
618
+ }
619
+ origValProto = protoreflect .ValueOf (valueDescriptor .Number ())
620
+ } else {
621
+ return errors .New ("unexpected non-string original value" )
622
+ }
623
+ } else {
624
+ origValProto = protoreflect .ValueOf (origOverride .Value )
625
+ }
626
+ protoField := mt .Descriptor ().Fields ().ByName (protoreflect .Name (protoFieldNames [i ]))
627
+ // Check if an earlier override had this rule, if so merge into it
628
+ ruleFirst , ruleSeen := ruleFirsts [origOverride .Rule ]
629
+ if ruleSeen {
630
+ if value , ok := ruleFirst .Value .(protoreflect.Message ); ok {
631
+ value .Set (protoField , origValProto )
632
+ } else {
633
+ return errors .Errorf ("unexpected type while merging overrides %T" , ruleFirst .Value )
634
+ }
635
+ } else {
636
+ value := mt .New ()
637
+ value .Set (protoField , origValProto )
638
+ override := & feature.Override {
639
+ Rule : origOverride .Rule ,
640
+ RuleASTV3 : origOverride .RuleASTV3 ,
641
+ Value : value ,
642
+ }
643
+ overrides = append (overrides , override )
644
+ if _ , ok := ruleFirsts [origOverride .Rule ]; ! ok {
645
+ ruleFirsts [origOverride .Rule ] = override
646
+ }
647
+ ruleFirsts [override .Rule ] = override
648
+ }
649
+ }
650
+ }
651
+ newF .Overrides = overrides
595
652
sf , err := r .Parse (ctx , ns , outName , registry )
596
653
if err != nil {
597
654
return errors .Wrap (err , "parse generated config" )
0 commit comments