/**
* MessageRegistry.ets
*
* 消息类型注册表(可选功能)
*
* ⚠️ 重要说明:
* - 普通使用场景不需要注册,可直接使用 Person.create().toBinary()
* - 只有以下场景需要注册:
* 1. 使用 google.protobuf.Any 类型
* 2. 需要根据类型名动态创建消息
* 3. JSON 与其他格式间的转换(某些情况)
*
* 设计理念:
* - 注册是完全可选的
* - 不注册不影响基本功能
* - 只在特殊场景下才需要
*
* Version: 1.0.0
* ArkTS 2025 兼容
*/
import { Message, MessageConstructor } from './Message'
/**
* 消息类型注册表(可选功能)
*
* 提供消息类型的动态查找和创建功能
*
* 使用场景示例:
*
* 场景 1: 使用 google.protobuf.Any
* ```typescript
* import { MessageRegistry } from './protobuf-core'
* import { Person } from './pb/Person'
*
* // 注册消息类型
* MessageRegistry.register(Person)
*
* // 使用 Any 类型
* const anyMsg = new Google_Protobuf_Any()
* anyMsg.pack(person)
* const unpacked = anyMsg.unpack<Person>() // 需要从 typeUrl 查找类型
* ```
*
* 场景 2: 动态消息创建
* ```typescript
* // 注册所有消息类型
* MessageRegistry.registerAll([Person, Address, Employee])
*
* // 根据类型名动态创建
* const typeName = 'test.Person'
* const message = MessageRegistry.create(typeName, { name: 'Alice' })
* ```
*
* ❌ 不需要注册的场景:
* ```typescript
* // 普通使用场景
* const person = Person.create({ name: 'Alice' })
* const binary = person.toBinary()
* const decoded = Person.fromBinary(binary)
* // 这些都不需要注册!
* ```
*/
export class MessageRegistry {
/**
* 消息类型映射表
*
* key: 消息类型名称(如 "google.protobuf.Timestamp")
* value: 消息构造器
*/
private static readonly types = new Map<string, MessageConstructor<Message>>()
/**
* 注册消息类型
*
* ⚠️ 可选:只在需要动态查找或 Any 类型时才调用
*
* @param ctor 消息构造器
*
* 使用示例:
* ```typescript
* MessageRegistry.register(Person)
* ```
*/
static register<T extends Message>(ctor: MessageConstructor<T>): void {
MessageRegistry.types.set(ctor.typeName, ctor as MessageConstructor<Message>)
}
/**
* 批量注册消息类型
*
* 用于生成的索引文件中的 registerAllMessages() 函数
*
* @param ctors 消息构造器数组
*
* 使用示例:
* ```typescript
* MessageRegistry.registerAll([Person, Address, Employee])
* ```
*/
static registerAll(ctors: MessageConstructor<Message>[]): void {
ctors.forEach(ctor => MessageRegistry.register(ctor))
}
/**
* 获取消息构造器
*
* @param typeName 消息类型名称
* @returns 消息构造器,如果未注册则返回 undefined
*
* 使用示例:
* ```typescript
* const ctor = MessageRegistry.get('test.Person')
* if (ctor !== undefined) {
* const msg = ctor.create({ name: 'Alice' })
* }
* ```
*/
static get(typeName: string): MessageConstructor<Message> | undefined {
return MessageRegistry.types.get(typeName)
}
/**
* 检查类型是否已注册
*
* @param typeName 消息类型名称
* @returns true 如果已注册
*
* 使用示例:
* ```typescript
* if (MessageRegistry.has('test.Person')) {
* console.log('Person type is registered')
* }
* ```
*/
static has(typeName: string): boolean {
return MessageRegistry.types.has(typeName)
}
/**
* 根据类型名动态创建消息
*
* ⚠️ 注意:需要预先调用 register() 注册类型
*
* @param typeName 消息类型名称
* @param init 初始化数据(可选)
* @returns 创建的消息对象,如果类型未注册则返回 null
*
* 使用示例:
* ```typescript
* MessageRegistry.register(Person)
* const person = MessageRegistry.create('test.Person', { name: 'Alice' })
* if (person !== null) {
* console.log(person.toJson())
* }
* ```
*/
static create(typeName: string, init?: Object): Message | null {
const ctor = MessageRegistry.get(typeName)
if (ctor === undefined) {
console.warn(`Message type "${typeName}" not registered. Call MessageRegistry.register() first.`)
return null
}
return ctor.create(init as Partial<Message>)
}
/**
* 从二进制创建消息
*
* ⚠️ 注意:需要预先调用 register() 注册类型
*
* @param typeName 消息类型名称
* @param data 二进制数据
* @returns 创建的消息对象,如果类型未注册则返回 null
*
* 使用示例:
* ```typescript
* MessageRegistry.register(Person)
* const binary = new Uint8Array([...])
* const person = MessageRegistry.fromBinary('test.Person', binary)
* ```
*/
static fromBinary(typeName: string, data: Uint8Array): Message | null {
const ctor = MessageRegistry.get(typeName)
if (ctor === undefined) {
console.warn(`Message type "${typeName}" not registered.`)
return null
}
return ctor.fromBinary(data)
}
/**
* 从 JSON 创建消息
*
* ⚠️ 注意:需要预先调用 register() 注册类型
*
* @param typeName 消息类型名称
* @param json JSON 对象
* @returns 创建的消息对象,如果类型未注册则返回 null
*
* 使用示例:
* ```typescript
* MessageRegistry.register(Person)
* const json = { name: 'Alice', age: 30 }
* const person = MessageRegistry.fromJson('test.Person', json)
* ```
*/
static fromJson(typeName: string, json: Record<string, Object>): Message | null {
const ctor = MessageRegistry.get(typeName)
if (ctor === undefined) {
console.warn(`Message type "${typeName}" not registered.`)
return null
}
return ctor.fromJson(json)
}
/**
* 获取所有已注册的类型名称
*
* @returns 类型名称数组
*
* 使用示例:
* ```typescript
* const types = MessageRegistry.getRegisteredTypes()
* console.log('Registered types:', types)
* ```
*/
static getRegisteredTypes(): string[] {
return Array.from(MessageRegistry.types.keys())
}
/**
* 清空注册表
*
* ⚠️ 警告:此操作会清空所有已注册的类型
*
* 使用示例:
* ```typescript
* MessageRegistry.clear()
* ```
*/
static clear(): void {
MessageRegistry.types.clear()
}
/**
* 获取注册表大小
*
* @returns 已注册类型的数量
*
* 使用示例:
* ```typescript
* const count = MessageRegistry.size()
* console.log(`${count} types registered`)
* ```
*/
static size(): number {
return MessageRegistry.types.size
}
}