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 {FileDescriptorSet} from 'google-protobuf/google/protobuf/descriptor_pb'; 19 20export type MessageCreator = new () => Message; 21class MessageMap extends Map<string, MessageCreator> {} 22export class ModuleMap extends Map<string, any> {} 23 24/** 25 * A wrapper class of protocol buffer modules to provide convenience methods. 26 */ 27export class ProtoCollection { 28 private messages: MessageMap; 29 30 constructor( 31 readonly fileDescriptorSet: FileDescriptorSet, 32 modules: ModuleMap 33 ) { 34 this.messages = this.mapMessages(fileDescriptorSet, modules); 35 } 36 37 /** 38 * Creates a map between message identifier "{packageName}.{messageName}" 39 * and the Message class. 40 */ 41 private mapMessages(set: FileDescriptorSet, mods: ModuleMap): MessageMap { 42 const messages = new MessageMap(); 43 for (const fileDescriptor of set.getFileList()) { 44 const mod = mods.get(fileDescriptor.getName()!)!; 45 for (const messageType of fileDescriptor.getMessageTypeList()) { 46 const fullName = 47 fileDescriptor.getPackage()! + '.' + messageType.getName(); 48 const message = mod[messageType.getName()!]; 49 messages.set(fullName, message); 50 } 51 } 52 return messages; 53 } 54 55 /** 56 * Finds the Message class referenced by the identifier. 57 * 58 * @param identifier String identifier of the form 59 * "{packageName}.{messageName}" i.e: "pw.rpc.test.NewMessage". 60 */ 61 getMessageCreator(identifier: string): MessageCreator | undefined { 62 return this.messages.get(identifier); 63 } 64} 65