RegisterExtension registers a per-tenant overrides extension. The extension e must be a non-nil pointer to the extension struct (pointer receivers are required). Panics if: - e is nil or not a pointer - Key() is empty or already registered - Key() conflicts with any built-in Overrides or LegacyOverr
(e T)
| 58 | // |
| 59 | // Returns a typed getter that retrieves the extension value from an Overrides. |
| 60 | func RegisterExtension[T Extension](e T) func(*Overrides) T { |
| 61 | // Check for nil / typed-nil before any method call so callers get a clear |
| 62 | // panic message instead of a nil-dereference inside Key() or LegacyKeys(). |
| 63 | typ := reflect.TypeOf(e) |
| 64 | if typ == nil || typ.Kind() != reflect.Ptr { |
| 65 | panic("overrides: RegisterExtension requires a non-nil pointer to the extension struct") |
| 66 | } |
| 67 | if reflect.ValueOf(e).IsNil() { |
| 68 | panic("overrides: RegisterExtension requires a non-nil pointer to the extension struct") |
| 69 | } |
| 70 | |
| 71 | key := e.Key() |
| 72 | if key == "" { |
| 73 | panic("overrides: extension Key() cannot be empty") |
| 74 | } |
| 75 | legacyKeys := e.LegacyKeys() |
| 76 | |
| 77 | extensionRegistry.Lock() |
| 78 | defer extensionRegistry.Unlock() |
| 79 | |
| 80 | validateExtensionKey(key) |
| 81 | validateExtensionLegacyKeys(key, legacyKeys) |
| 82 | |
| 83 | extensionRegistry.entries[key] = ®istryEntry{ |
| 84 | key: key, |
| 85 | legacyKeys: legacyKeys, |
| 86 | elemType: typ.Elem(), |
| 87 | } |
| 88 | for _, lk := range legacyKeys { |
| 89 | extensionRegistry.allLegacyKeys[lk] = struct{}{} |
| 90 | } |
| 91 | |
| 92 | return func(o *Overrides) T { |
| 93 | if o == nil || o.Extensions == nil { |
| 94 | var zero T |
| 95 | return zero |
| 96 | } |
| 97 | v, _ := o.Extensions[key].(T) |
| 98 | return v |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | // validateExtensionKey checks that key does not conflict with any reserved name. |
| 103 | // Must be called with extensionRegistry.Lock held. |