• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2018 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15export interface HasKind { kind: string; }
16
17export class Registry<T> {
18  private key: (t: T) => string;
19  protected registry: Map<string, T>;
20
21  static kindRegistry<T extends HasKind>(): Registry<T> {
22    return new Registry<T>((t) => t.kind);
23  }
24
25  constructor(key: (t: T) => string) {
26    this.registry = new Map<string, T>();
27    this.key = key;
28  }
29
30  register(registrant: T) {
31    const kind = this.key(registrant);
32    if (this.registry.has(kind)) {
33      throw new Error(`Registrant ${kind} already exists in the registry`);
34    }
35    this.registry.set(kind, registrant);
36  }
37
38  has(kind: string): boolean {
39    return this.registry.has(kind);
40  }
41
42  get(kind: string): T {
43    const registrant = this.registry.get(kind);
44    if (registrant === undefined) {
45      throw new Error(`${kind} has not been registered.`);
46    }
47    return registrant;
48  }
49
50  // Support iteration: for (const foo of fooRegistry.values()) { ... }
51  * values() {
52    yield* this.registry.values();
53  }
54
55  unregisterAllForTesting(): void {
56    this.registry.clear();
57  }
58}
59