| // Copyright 2021 The Pigweed Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| // use this file except in compliance with the License. You may obtain a copy of |
| // the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| // License for the specific language governing permissions and limitations under |
| // the License. |
| |
| /** Tools for compiling and importing Javascript protos on the fly. */ |
| |
| import { Message } from 'google-protobuf'; |
| import { |
| DescriptorProto, |
| FileDescriptorSet, |
| } from 'google-protobuf/google/protobuf/descriptor_pb'; |
| |
| export type MessageCreator = new () => Message; |
| interface MessageMap { |
| [key: string | number]: MessageCreator; |
| } |
| interface MessageDescriptorMap { |
| [key: string | number]: DescriptorProto; |
| } |
| export interface ModuleMap { |
| [key: string | number]: any; |
| } |
| |
| /** |
| * A wrapper class of protocol buffer modules to provide convenience methods. |
| */ |
| export class ProtoCollection { |
| private readonly messages: MessageMap = {}; |
| private readonly messageDescriptors: MessageDescriptorMap = {}; |
| |
| constructor( |
| readonly fileDescriptorSet: FileDescriptorSet, |
| modules: ModuleMap, |
| ) { |
| this.mapMessages(fileDescriptorSet, modules); |
| } |
| |
| /** |
| * Creates a map between message identifier "{packageName}.{messageName}" |
| * and the Message class and also the associated DescriptorProto. |
| */ |
| private mapMessages(set: FileDescriptorSet, mods: ModuleMap): void { |
| for (const fileDescriptor of set.getFileList()) { |
| const mod = mods[fileDescriptor.getName()]; |
| for (const messageType of fileDescriptor.getMessageTypeList()) { |
| const fullName = |
| fileDescriptor.getPackage() + '.' + messageType.getName(); |
| const message = mod[messageType.getName()]; |
| this.messages[fullName] = message; |
| this.messageDescriptors[fullName] = messageType; |
| } |
| } |
| } |
| |
| /** |
| * Finds the Message class referenced by the identifier. |
| * |
| * @param identifier String identifier of the form |
| * "{packageName}.{messageName}" i.e: "pw.rpc.test.NewMessage". |
| */ |
| getMessageCreator(identifier: string): MessageCreator | undefined { |
| return this.messages[identifier]; |
| } |
| |
| /** |
| * Finds the DescriptorProto referenced by the identifier. |
| * |
| * @param identifier String identifier of the form |
| * "{packageName}.{messageName}" i.e: "pw.rpc.test.NewMessage". |
| */ |
| getDescriptorProto(identifier: string): DescriptorProto | undefined { |
| return this.messageDescriptors[identifier]; |
| } |
| } |