* Copyright (c) 2025 Huawei Technologies Co., Ltd.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { AbsolutePath } from '../../core';
import { CodeGenerator, UberSchema } from '../core';
import {
BaseComponentInstanceHTemplate,
ComponentJSIBinderHTemplate,
} from '../templates';
import { GlueCodeComponentDataV2 } from './AppBuildTimeGlueCodeGenerator';
export type LibraryData = {
libraryCppName: string;
uberSchema: UberSchema;
};
export class CppComponentCodeGenerator implements CodeGenerator<LibraryData> {
private glueCodeComponentsData: GlueCodeComponentDataV2[] = [];
constructor(
private onGetRNOHOutputPath: (filename: string) => AbsolutePath,
private codegenNoticeLines: string[]
) {}
getGlueCodeData() {
return this.glueCodeComponentsData;
}
generate({
libraryCppName,
uberSchema,
}: LibraryData): Map<AbsolutePath, string> {
const fileContentByPath = new Map<AbsolutePath, string>();
for (const [_filename, schema] of uberSchema
.getSpecSchemaByFilenameMap()
.entries()) {
if (schema.type === 'Component') {
Object.entries(schema.components).map(([componentName, shape]) => {
const componentJSIBinderHTemplate = new ComponentJSIBinderHTemplate(
componentName,
this.codegenNoticeLines
);
const componentInstanceSpecHTemplate =
new BaseComponentInstanceHTemplate(
componentName,
libraryCppName,
this.codegenNoticeLines
);
shape.props.forEach((prop) => {
componentJSIBinderHTemplate.addProp({
name: prop.name,
isObject: prop.typeAnnotation.type === 'ObjectTypeAnnotation',
});
});
shape.events.forEach((event) => {
componentJSIBinderHTemplate.addEvent({
type: event.bubblingType,
eventHandlerName: event.name,
});
});
shape.commands.forEach((command) => {
componentJSIBinderHTemplate.addCommand({
name: command.name,
});
componentInstanceSpecHTemplate.addCommand({
name: command.name,
args: command.typeAnnotation.params.map((param) => ({
name: param.name,
typeAnnotation: param.typeAnnotation,
})),
});
});
fileContentByPath.set(
this.onGetRNOHOutputPath(`${componentName}JSIBinder.h`),
componentJSIBinderHTemplate.build()
);
fileContentByPath.set(
this.onGetRNOHOutputPath(`Base${componentName}ComponentInstance.h`),
componentInstanceSpecHTemplate.build()
);
this.glueCodeComponentsData.push({
name: componentName,
libraryCppName,
});
});
}
}
return fileContentByPath;
}
}