xref: /aosp_15_r20/external/pigweed/pw_protobuf_compiler/ts/proto_collection.ts (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1// Copyright 2021 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7//     https://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, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15/** Tools for compiling and importing Javascript protos on the fly. */
16
17import { Message } from 'google-protobuf';
18import {
19  DescriptorProto,
20  FileDescriptorSet,
21} from 'google-protobuf/google/protobuf/descriptor_pb';
22
23export type MessageCreator = new () => Message;
24interface MessageMap {
25  [key: string | number]: MessageCreator;
26}
27interface MessageDescriptorMap {
28  [key: string | number]: DescriptorProto;
29}
30export interface ModuleMap {
31  [key: string | number]: any;
32}
33
34/**
35 * A wrapper class of protocol buffer modules to provide convenience methods.
36 */
37export class ProtoCollection {
38  private readonly messages: MessageMap = {};
39  private readonly messageDescriptors: MessageDescriptorMap = {};
40
41  constructor(
42    readonly fileDescriptorSet: FileDescriptorSet,
43    modules: ModuleMap,
44  ) {
45    this.mapMessages(fileDescriptorSet, modules);
46  }
47
48  /**
49   * Creates a map between message identifier "{packageName}.{messageName}"
50   * and the Message class and also the associated DescriptorProto.
51   */
52  private mapMessages(set: FileDescriptorSet, mods: ModuleMap): void {
53    for (const fileDescriptor of set.getFileList()) {
54      const mod = mods[fileDescriptor.getName()];
55      for (const messageType of fileDescriptor.getMessageTypeList()) {
56        const fullName =
57          fileDescriptor.getPackage() + '.' + messageType.getName();
58        const message = mod[messageType.getName()];
59        this.messages[fullName] = message;
60        this.messageDescriptors[fullName] = messageType;
61      }
62    }
63  }
64
65  /**
66   * Finds the Message class referenced by the identifier.
67   *
68   *  @param identifier String identifier of the form
69   *  "{packageName}.{messageName}" i.e: "pw.rpc.test.NewMessage".
70   */
71  getMessageCreator(identifier: string): MessageCreator | undefined {
72    return this.messages[identifier];
73  }
74
75  /**
76   * Finds the DescriptorProto referenced by the identifier.
77   *
78   *  @param identifier String identifier of the form
79   *  "{packageName}.{messageName}" i.e: "pw.rpc.test.NewMessage".
80   */
81  getDescriptorProto(identifier: string): DescriptorProto | undefined {
82    return this.messageDescriptors[identifier];
83  }
84}
85