Repository.mk                                      |    2 
 codemaker/Executable_rustmaker.mk                  |   33 
 codemaker/Module_codemaker.mk                      |    1 
 codemaker/source/rustmaker/cpp_include_manager.cxx |  174 +
 codemaker/source/rustmaker/cpp_include_manager.hxx |   86 
 codemaker/source/rustmaker/cpproduce.cxx           | 2739 +++++++++++++++++++++
 codemaker/source/rustmaker/cpproduce.hxx           |  225 +
 codemaker/source/rustmaker/rustfile.cxx            |  664 +++++
 codemaker/source/rustmaker/rustfile.hxx            |  112 
 codemaker/source/rustmaker/rustmaker.cxx           |   64 
 codemaker/source/rustmaker/rustoptions.cxx         |  196 +
 codemaker/source/rustmaker/rustoptions.hxx         |   27 
 codemaker/source/rustmaker/rustproduce.cxx         | 1234 +++++++++
 codemaker/source/rustmaker/rustproduce.hxx         |   92 
 codemaker/source/rustmaker/type_analyzer.cxx       |  188 +
 codemaker/source/rustmaker/type_analyzer.hxx       |   94 
 codemaker/source/rustmaker/unoproduce.cxx          |  376 ++
 codemaker/source/rustmaker/unoproduce.hxx          |  109 
 config_host.mk.in                                  |    1 
 configure.ac                                       |   14 
 20 files changed, 6431 insertions(+)

New commits:
commit d9f05dc007e3db909fa842a301f666ce421159ac
Author:     Mohamed Ali <mohmedali1462...@gmail.com>
AuthorDate: Sun Jul 20 20:05:28 2025 +0300
Commit:     Stephan Bergmann <stephan.bergm...@collabora.com>
CommitDate: Thu Sep 11 21:38:59 2025 +0200

    Rust Bindings: Add rustmaker (Rust codemaker)
    
    The rustmaker provides comprehensive support for converting UNO type 
definitions into idiomatic Rust code with proper memory safety and type system 
integration.
    
    Also adds the RustFile, RustOptions, and RustProducer classes to handle
    Rust code generation, file management, and command line option parsing
    for various UNO type kinds such as enums, structs, and interfaces.
    
    Change-Id: Iaf87af13352c55e81c1745ef7a8f591c3e61e0a4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188088
    Reviewed-by: Stephan Bergmann <stephan.bergm...@collabora.com>
    Tested-by: Jenkins

diff --git a/Repository.mk b/Repository.mk
index 0cb81f699ba4..25f8e9213085 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -97,6 +97,7 @@ $(eval $(call 
gb_Helper_register_executables_for_install,SDK,sdk, \
        javamaker \
        netmaker \
        pythonmaker \
+       $(if $(ENABLE_RUST_UNO),rustmaker) \
     $(call gb_CondExeSp2bv,sp2bv) \
        $(if $(filter ODK,$(BUILD_TYPE)),unoapploader) \
        unoidl-read \
@@ -458,6 +459,7 @@ $(eval $(call 
gb_Helper_register_libraries_for_install,OOOLIBS,ooo, \
        passwordcontainer \
        pcr \
        pdffilter \
+       $(if $(ENABLE_RUST_UNO),rust_uno-cpp) \
        $(call gb_Helper_optional,SCRIPTING,protocolhandler) \
        sax \
        sb \
diff --git a/codemaker/Executable_rustmaker.mk 
b/codemaker/Executable_rustmaker.mk
new file mode 100644
index 000000000000..1fb006b23e83
--- /dev/null
+++ b/codemaker/Executable_rustmaker.mk
@@ -0,0 +1,33 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Executable_Executable,rustmaker))
+
+$(eval $(call gb_Executable_use_libraries,rustmaker,\
+    salhelper \
+    sal \
+    unoidl \
+))
+
+$(eval $(call gb_Executable_use_static_libraries,rustmaker,\
+    codemaker \
+))
+
+$(eval $(call gb_Executable_add_exception_objects,rustmaker,\
+    codemaker/source/rustmaker/rustmaker \
+    codemaker/source/rustmaker/rustoptions \
+    codemaker/source/rustmaker/rustproduce \
+    codemaker/source/rustmaker/rustfile \
+    codemaker/source/rustmaker/cpproduce \
+    codemaker/source/rustmaker/unoproduce \
+    codemaker/source/rustmaker/type_analyzer \
+    codemaker/source/rustmaker/cpp_include_manager \
+))
+
+# vim:set noet sw=4 ts=4:
diff --git a/codemaker/Module_codemaker.mk b/codemaker/Module_codemaker.mk
index 36f44f231195..495400366539 100644
--- a/codemaker/Module_codemaker.mk
+++ b/codemaker/Module_codemaker.mk
@@ -19,6 +19,7 @@ $(eval $(call gb_Module_add_targets,codemaker,\
     Executable_cppumaker \
     Executable_netmaker \
     Executable_pythonmaker \
+    $(if $(ENABLE_RUST_UNO),Executable_rustmaker) \
 ))
 endif
 
diff --git a/codemaker/source/rustmaker/cpp_include_manager.cxx 
b/codemaker/source/rustmaker/cpp_include_manager.cxx
new file mode 100644
index 000000000000..bbf4b98bb777
--- /dev/null
+++ b/codemaker/source/rustmaker/cpp_include_manager.cxx
@@ -0,0 +1,174 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "cpp_include_manager.hxx"
+#include "rustfile.hxx"
+#include <filesystem>
+#include <algorithm>
+#include <sal/log.hxx>
+
+CppIncludeManager::CppIncludeManager(const TypeAnalyzer::TypeInfo& typeInfo)
+    : m_typeInfo(typeInfo)
+{
+}
+
+void CppIncludeManager::dumpIncludes(CppFile& file, std::string_view 
interfaceName)
+{
+    // Write file header comment
+    file.beginLine()
+        .append("// Auto-generated C++ bridge functions for ")
+        .append(interfaceName)
+        .endLine()
+        .beginLine()
+        .append("// Generated by rustmaker with dynamic includes")
+        .endLine()
+        .endLine();
+
+    // Write pragma once directive to prevent multiple inclusions (only for 
header files)
+    if (file.getExtension() == ".hxx")
+    {
+        file.beginLine().append("#pragma once").endLine().endLine();
+    }
+
+    // Write standard includes
+    writeStandardIncludes(file);
+
+    // Write UNO-specific includes based on type analysis
+    writeUnoIncludes(file);
+
+    // Write interface-specific includes
+    writeInterfaceIncludes(file, interfaceName);
+
+    file.endLine();
+}
+
+void CppIncludeManager::dumpNamespaces(CppFile& file)
+{
+    // Generate specific namespace using declarations for only what we need
+    for (const auto& ns : m_typeInfo.namespaces)
+    {
+        file.beginLine().append("using namespace 
").append(ns).append(";").endLine();
+    }
+    file.endLine();
+}
+
+void CppIncludeManager::writeStandardIncludes(CppFile& file)
+{
+    // Always needed for UNO operations
+    if (m_typeInfo.needsUnoInterface)
+    {
+        file.beginLine().append("#include 
<com/sun/star/uno/XInterface.hpp>").endLine();
+        file.beginLine().append("#include 
<com/sun/star/uno/Reference.hxx>").endLine();
+        file.beginLine().append("#include 
<com/sun/star/uno/Exception.hpp>").endLine();
+        file.beginLine().append("#include <sal/log.hxx>").endLine(); // For 
SAL_WARN macro
+    }
+
+    // Basic type includes
+    if (m_typeInfo.needsSalTypes)
+    {
+        file.beginLine().append("#include <sal/types.h>").endLine();
+    }
+
+    if (m_typeInfo.needsRtlUstring)
+    {
+        file.beginLine().append("#include <rtl/ustring.hxx>").endLine();
+    }
+}
+
+void CppIncludeManager::writeUnoIncludes(CppFile& file)
+{
+    // Core UNO types - implemented: Any
+    if (m_typeInfo.needsAny)
+    {
+        file.beginLine().append("#include 
<com/sun/star/uno/Any.hxx>").endLine();
+        file.beginLine().append("#include <uno/data.h>").endLine();
+        file.beginLine().append("#include <cppu/unotype.hxx>").endLine();
+    }
+
+    if (m_typeInfo.needsSequence)
+    {
+        file.beginLine().append("#include 
<com/sun/star/uno/Sequence.hxx>").endLine();
+        file.beginLine().append("#include <uno/sequence2.h>").endLine();
+        file.beginLine().append("#include 
<typelib/typedescription.h>").endLine();
+    }
+
+    if (m_typeInfo.needsPropertyValue)
+    {
+        // TODO: implement PropertyValue handling
+        file.beginLine().append("// TODO: Add PropertyValue 
includes").endLine();
+        file.beginLine().append("#include 
<com/sun/star/beans/PropertyValue.hpp>").endLine();
+    }
+}
+
+void CppIncludeManager::writeInterfaceIncludes(CppFile& file, std::string_view 
interfaceName)
+{
+    // Include the interface being processed
+    OString selfInclude = "<" + OString(interfaceName).replaceAll("."_ostr, 
"/"_ostr) + ".hpp>";
+    file.beginLine().append("#include ").append(selfInclude).endLine();
+
+    // Include headers for all interface types found in the analysis
+    for (const auto& interfaceType : m_typeInfo.interfaceTypes)
+    {
+        // Don't include ourselves twice
+        if (interfaceType != interfaceName)
+        {
+            OString includeFile = "<" + interfaceType.replaceAll("."_ostr, 
"/"_ostr) + ".hpp>";
+            file.beginLine().append("#include ").append(includeFile).endLine();
+        }
+    }
+}
+
+OString CppIncludeManager::calculateRelativeIncludePath(const CppFile& file,
+                                                        const OString& 
targetType,
+                                                        const std::string& 
extension)
+{
+    namespace fs = std::filesystem;
+
+    // Get the current file's directory
+    fs::path currentFilePath = file.getPath();
+    fs::path currentDir = currentFilePath.parent_path();
+
+    // Convert target type name to path (dots to slashes)
+    std::string targetTypeStr = std::string(targetType);
+    std::replace(targetTypeStr.begin(), targetTypeStr.end(), '.', '/');
+
+    // Find the base directory (cpp)
+    fs::path baseDir = currentDir;
+    while (baseDir.has_parent_path() && baseDir.filename() != "cpp")
+    {
+        baseDir = baseDir.parent_path();
+    }
+
+    // Create target file path
+    fs::path target = (baseDir / (targetTypeStr + 
extension)).lexically_normal();
+
+    // If they're in the same directory, just use the filename
+    if (target.parent_path() == currentDir)
+    {
+        std::string result = target.filename().string();
+        return OString("\"" + result + "\"");
+    }
+
+    // Otherwise calculate relative path from current directory to target file
+    fs::path rel;
+    try
+    {
+        rel = fs::relative(target, currentDir);
+    }
+    catch (const std::exception&)
+    {
+        // Fallback: use the path relative to base directory
+        rel = fs::relative(target, baseDir);
+    }
+
+    std::string result = rel.generic_string();
+    return OString("\"" + result + "\"");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/codemaker/source/rustmaker/cpp_include_manager.hxx 
b/codemaker/source/rustmaker/cpp_include_manager.hxx
new file mode 100644
index 000000000000..ea9a190b1680
--- /dev/null
+++ b/codemaker/source/rustmaker/cpp_include_manager.hxx
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include "type_analyzer.hxx"
+#include <rtl/string.hxx>
+
+// Forward declaration
+class CppFile;
+
+/**
+ * Manages dynamic generation of C++ includes and namespace declarations
+ * based on type analysis results.
+ */
+class CppIncludeManager
+{
+public:
+    /**
+     * Constructor that takes type analysis results.
+     *
+     * @param typeInfo The type analysis results from TypeAnalyzer.
+     */
+    explicit CppIncludeManager(const TypeAnalyzer::TypeInfo& typeInfo);
+
+    /**
+     * Writes the necessary #include directives to the C++ file.
+     *
+     * @param file The CppFile to write to.
+     * @param interfaceName The name of the interface being processed (for 
self-include).
+     */
+    void dumpIncludes(CppFile& file, std::string_view interfaceName);
+
+    /**
+     * Writes the necessary using namespace declarations to the C++ file.
+     *
+     * @param file The CppFile to write to.
+     */
+    void dumpNamespaces(CppFile& file);
+
+private:
+    const TypeAnalyzer::TypeInfo& m_typeInfo;
+
+    /**
+     * Writes standard system includes that are always needed.
+     *
+     * @param file The CppFile to write to.
+     */
+    void writeStandardIncludes(CppFile& file);
+
+    /**
+     * Writes UNO-specific includes based on type analysis.
+     *
+     * @param file The CppFile to write to.
+     */
+    void writeUnoIncludes(CppFile& file);
+
+    /**
+     * Writes interface-specific includes.
+     *
+     * @param file The CppFile to write to.
+     * @param interfaceName The name of the interface being processed.
+     */
+    void writeInterfaceIncludes(CppFile& file, std::string_view interfaceName);
+
+    /**
+     * Calculates relative include paths like cppumaker does.
+     * This generates the proper relative path from the current file being 
generated
+     * to the target dependency file.
+     *
+     * @param file The current file being generated (provides context for 
relative path)
+     * @param targetType The UNO type name (e.g., 
"com.sun.star.beans.Property")
+     * @param extension The file extension to use (e.g., ".hxx", ".hpp")
+     * @return Properly formatted include statement with quotes
+     */
+    static OString calculateRelativeIncludePath(const CppFile& file, const 
OString& targetType,
+                                                const std::string& extension);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/codemaker/source/rustmaker/cpproduce.cxx 
b/codemaker/source/rustmaker/cpproduce.cxx
new file mode 100644
index 000000000000..cf8af02c0950
--- /dev/null
+++ b/codemaker/source/rustmaker/cpproduce.cxx
@@ -0,0 +1,2739 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "cpproduce.hxx"
+#include <rtl/string.hxx>
+#include "rustfile.hxx"
+#include "type_analyzer.hxx"
+#include "cpp_include_manager.hxx"
+#include <codemaker/typemanager.hxx>
+#include <codemaker/unotype.hxx>
+#include <sal/log.hxx>
+#include <sal/types.h>
+#include <iostream>
+#include <filesystem>
+#include <string_view>
+#include <algorithm>
+
+CppProducer::CppProducer(const OString& outputDir, bool verbose, bool dryRun,
+                         const rtl::Reference<TypeManager>& typeManager)
+    : m_outputDir(outputDir)
+    , m_verbose(verbose)
+    , m_dryRun(dryRun)
+    , m_typeManager(typeManager)
+    , m_combinedSourceFile()
+    , m_combinedHeaderFile()
+{
+}
+
+void CppProducer::initializeCombinedFile()
+{
+    if (m_dryRun)
+        return;
+
+    // Create the combined source file (.cxx)
+    m_combinedSourceFile = std::make_unique<CppFile>(m_outputDir, 
"rust_uno_bindings", ".cxx");
+    std::filesystem::path sourceFilePath = m_combinedSourceFile->getPath();
+    if (std::filesystem::exists(sourceFilePath))
+    {
+        std::filesystem::remove(sourceFilePath);
+    }
+    m_combinedSourceFile->openFile();
+
+    // Include the header file
+    m_combinedSourceFile->beginLine().append("#include 
\"rust_uno_bindings.hxx\"").endLine();
+    m_combinedSourceFile->beginLine().append("").endLine();
+
+    // Create the combined header file (.hxx)
+    m_combinedHeaderFile = std::make_unique<CppFile>(m_outputDir, 
"rust_uno_bindings", ".hxx");
+    std::filesystem::path headerFilePath = m_combinedHeaderFile->getPath();
+    if (std::filesystem::exists(headerFilePath))
+    {
+        std::filesystem::remove(headerFilePath);
+    }
+    m_combinedHeaderFile->openFile();
+
+    // Add header guard
+    m_combinedHeaderFile->beginLine().append("#pragma once").endLine();
+    m_combinedHeaderFile->beginLine().append("").endLine();
+
+    // Add only sal/types.h which definitely exists
+    m_combinedHeaderFile->beginLine().append("#include 
<sal/types.h>").endLine();
+    m_combinedHeaderFile->beginLine().append("").endLine();
+}
+
+void CppProducer::finalizeCombinedFile()
+{
+    if (m_combinedSourceFile)
+    {
+        m_combinedSourceFile->closeFile();
+        m_combinedSourceFile.reset();
+    }
+
+    if (m_combinedHeaderFile)
+    {
+        m_combinedHeaderFile->closeFile();
+        m_combinedHeaderFile.reset();
+    }
+}
+
+void CppProducer::produceEnum(std::string_view name,
+                              const rtl::Reference<unoidl::EnumTypeEntity>& 
entity)
+{
+    if (m_verbose)
+        std::cout << "[cpp-opaque-enum] " << name << " -> enum bridge 
functions" << '
';
+
+    generateEnumBridge(name, entity);
+}
+
+void CppProducer::produceStruct(std::string_view name,
+                                const 
rtl::Reference<unoidl::PlainStructTypeEntity>& entity)
+{
+    if (m_verbose)
+        std::cout << "[cpp-opaque-struct] " << name
+                  << " -> constructor/destructor + getter/setter functions" << 
'
';
+
+    generateStructWrapper(name, entity);
+    // generateStructBridge(name, entity);
+}
+
+void CppProducer::produceInterface(std::string_view name,
+                                   const 
rtl::Reference<unoidl::InterfaceTypeEntity>& entity)
+{
+    if (m_verbose)
+        std::cout << "[cpp-opaque-interface] " << name
+                  << " -> opaque handle + method wrapper functions" << '
';
+
+    generateInterfaceHeader(name, entity);
+    generateInterfaceSource(name, entity);
+}
+
+void CppProducer::produceService(
+    std::string_view name, const 
rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>& entity)
+{
+    if (m_verbose)
+        std::cout << "[cpp-opaque-service] " << name << " -> service creation 
bridge functions"
+                  << '
';
+
+    generateServiceHeader(name, entity);
+    generateServiceSource(name, entity);
+}
+
+void CppProducer::generateEnumBridge(std::string_view name,
+                                     const 
rtl::Reference<unoidl::EnumTypeEntity>& entity)
+{
+    generateEnumHeader(name, entity);
+    generateEnumSource(name, entity);
+}
+
+void CppProducer::generateStructWrapper(std::string_view name,
+                                        const 
rtl::Reference<unoidl::PlainStructTypeEntity>& entity)
+{
+    generateStructHeader(name, entity);
+    generateStructSource(name, entity);
+}
+
+void CppProducer::generateStructBridge(std::string_view name,
+                                       const 
rtl::Reference<unoidl::PlainStructTypeEntity>&)
+{
+    CppFile file(m_outputDir, name);
+
+    if (m_dryRun)
+        return;
+
+    file.openFile();
+
+    file.beginLine().append("extern \"C\"").endLine().beginBlock();
+
+    // Simple opaque struct bridge functions (like old FFI approach)
+    OString className = getInterfaceClassName(name);
+    OString functionPrefix = getCFunctionPrefix(name);
+
+    file.beginLine()
+        .append("// Opaque struct creation")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT void* ")
+        .append(functionPrefix)
+        .append("_create()")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("return new ")
+        .append(className)
+        .append("();")
+        .endLine()
+        .endBlock();
+
+    file.beginLine().append("").endLine();
+    file.endBlock().append(" // extern \"C\"");
+
+    file.closeFile();
+}
+
+void CppProducer::generateCBridgeIncludes(CppFile& file, std::string_view name,
+                                          const 
rtl::Reference<unoidl::InterfaceTypeEntity>& entity)
+{
+    // Use existing infrastructure for includes
+    TypeAnalyzer analyzer(m_typeManager);
+    TypeAnalyzer::TypeInfo typeInfo = analyzer.analyzeInterface(entity);
+    CppIncludeManager includeManager(typeInfo);
+
+    includeManager.dumpIncludes(file, name);
+}
+
+void CppProducer::generateCBridgeTypeDefinitions(CppFile& file, const OString& 
handleTypeName)
+{
+    // Opaque handle typedef for type safety
+    file.beginLine()
+        .append("// Opaque handle for type-safe C FFI")
+        .endLine()
+        .beginLine()
+        .append("typedef void* ")
+        .append(handleTypeName)
+        .append(";")
+        .endLine()
+        .beginLine()
+        .append("")
+        .endLine();
+}
+
+void CppProducer::generateCBridgeConstructors(CppFile& file, const OString& 
className,
+                                              const OString& functionPrefix,
+                                              const OString& handleTypeName)
+{
+    // Opaque constructor function - creates interface instance from existing 
Reference
+    file.beginLine()
+        .append("// Opaque constructor - creates interface wrapper from UNO 
Reference")
+        .endLine()
+        .beginLine()
+        .append(handleTypeName)
+        .append(" ")
+        .append(functionPrefix)
+        .append("_create_from_reference(void* xInterface)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("if (!xInterface) return nullptr;")
+        .endLine()
+        .beginLine()
+        .append("")
+        .endLine()
+        .beginLine()
+        .append("// Cast void* back to Reference<")
+        .append(className)
+        .append(">")
+        .endLine()
+        .beginLine()
+        .append("Reference<")
+        .append(className)
+        .append(">* pRef = static_cast<Reference<")
+        .append(className)
+        .append(">*>(xInterface);")
+        .endLine()
+        .beginLine()
+        .append("if (!pRef->is()) return nullptr;")
+        .endLine()
+        .beginLine()
+        .append("")
+        .endLine()
+        .beginLine()
+        .append("// Create wrapper with interface reference")
+        .endLine()
+        .beginLine()
+        .append("return new ")
+        .append(className)
+        .append("Wrapper(*pRef);")
+        .endLine()
+        .endBlock()
+        .beginLine()
+        .append("")
+        .endLine()
+        .beginLine()
+        .append("// Opaque service creation - attempts to create UNO service")
+        .endLine()
+        .beginLine()
+        .append("// Note: This is a simplified approach - real service 
creation")
+        .endLine()
+        .beginLine()
+        .append("// would need ComponentContext and service name resolution")
+        .endLine()
+        .beginLine()
+        .append(handleTypeName)
+        .append(" ")
+        .append(functionPrefix)
+        .append("_create_service(void* xContext, const char* serviceName)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("if (!xContext || !serviceName) return nullptr;")
+        .endLine()
+        .beginLine()
+        .append("")
+        .endLine()
+        .beginLine()
+        .append("try")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("// Cast context")
+        .endLine()
+        .beginLine()
+        .append("Reference<XComponentContext>* pContext =")
+        .endLine()
+        .extraIndent()
+        .beginLine()
+        .append("static_cast<Reference<XComponentContext>*>(xContext);")
+        .endLine()
+        .beginLine()
+        .append("")
+        .endLine()
+        .beginLine()
+        .append("// Create service")
+        .endLine()
+        .beginLine()
+        .append("OUString svcName = OUString::createFromAscii(serviceName);")
+        .endLine()
+        .beginLine()
+        .append("Reference<")
+        .append(className)
+        .append("> xService(")
+        .endLine()
+        .extraIndent()
+        .beginLine()
+        .append("pContext->getServiceManager()->createInstanceWithContext(")
+        .endLine()
+        .extraIndent()
+        .beginLine()
+        .append("svcName, *pContext), UNO_QUERY);")
+        .endLine()
+        .beginLine()
+        .append("")
+        .endLine()
+        .beginLine()
+        .append("if (!xService.is()) return nullptr;")
+        .endLine()
+        .beginLine()
+        .append("")
+        .endLine()
+        .beginLine()
+        .append("// Return wrapper")
+        .endLine()
+        .beginLine()
+        .append("return new ")
+        .append(className)
+        .append("Wrapper(xService);")
+        .endLine()
+        .endBlock()
+        .beginLine()
+        .append("catch (const Exception& ex)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("// TODO: Log exception details")
+        .endLine()
+        .beginLine()
+        .append("SAL_WARN(\"rustmaker\", \"UNO exception in interface 
method\");")
+        .endLine()
+        .beginLine()
+        .append("return nullptr;")
+        .endLine()
+        .endBlock()
+        .endBlock();
+}
+
+void CppProducer::generateCBridgeDestructor(CppFile& file, const OString& 
className,
+                                            const OString& functionPrefix,
+                                            const OString& handleTypeName)
+{
+    // Opaque destructor function - destroys interface instance
+    file.beginLine()
+        .append("")
+        .endLine()
+        .beginLine()
+        .append("// Opaque destructor - destroys interface wrapper")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT void ")
+        .append(functionPrefix)
+        .append("_destroy(")
+        .append(handleTypeName)
+        .append(" handle)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("if (handle)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("delete static_cast<")
+        .append(className)
+        .append("Wrapper*>(handle);")
+        .endLine()
+        .endBlock();
+}
+
+void CppProducer::generateCBridgeValidation(CppFile& file, const OString& 
className,
+                                            const OString& functionPrefix,
+                                            const OString& handleTypeName)
+{
+    // Opaque validity check function
+    file.beginLine()
+        .append("")
+        .endLine()
+        .beginLine()
+        .append("// Opaque validity check - tests if interface is valid")
+        .endLine()
+        .beginLine()
+        .append("bool ")
+        .append(functionPrefix)
+        .append("_is_valid(")
+        .append(handleTypeName)
+        .append(" handle)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("if (!handle) return false;")
+        .endLine()
+        .beginLine()
+        .append("return static_cast<")
+        .append(className)
+        .append("Wrapper*>(handle)->isValid();")
+        .endLine()
+        .endBlock();
+}
+
+void CppProducer::generateCBridgeMethods(CppFile& file, const OString& 
className,
+                                         const OString& functionPrefix,
+                                         const OString& handleTypeName,
+                                         const 
rtl::Reference<unoidl::InterfaceTypeEntity>& entity)
+{
+    // Opaque method bridge functions - each method gets unique extern "C" 
function
+    for (const auto& method : entity->getDirectMethods())
+    {
+        file.beginLine()
+            .append("")
+            .endLine()
+            .beginLine()
+            .append("// Opaque method bridge for ")
+            .append(method.name)
+            .endLine()
+            .beginLine()
+            .append(getMethodReturnType(method.returnType))
+            .append(" ")
+            .append(functionPrefix)
+            .append("_")
+            .append(method.name)
+            .append("(")
+            .append(handleTypeName)
+            .append(" handle");
+
+        // Use proper types instead of void* for parameters
+        for (const auto& param : method.parameters)
+        {
+            file.append(", ").append(getCppTypeName(param.type)).append(" 
").append(param.name);
+        }
+
+        file.append(")")
+            .endLine()
+            .beginBlock()
+            .beginLine()
+            .append("if (!handle) return ")
+            .append(getMethodDefaultReturn(method.returnType))
+            .append(";")
+            .endLine()
+            .beginLine()
+            .append("")
+            .endLine()
+            .beginLine()
+            .append("auto* wrapper = static_cast<")
+            .append(className)
+            .append("Wrapper*>(handle);")
+            .endLine()
+            .beginLine()
+            .append("return wrapper->")
+            .append(method.name)
+            .append("(");
+
+        // Pass through all opaque parameters
+        bool first = true;
+        for (const auto& param : method.parameters)
+        {
+            if (!first)
+                file.append(", ");
+            first = false;
+            file.append(param.name);
+        }
+
+        file.append(");").endLine().endBlock();
+    }
+}
+
+void CppProducer::generateCBridge(std::string_view name,
+                                  const 
rtl::Reference<unoidl::InterfaceTypeEntity>& entity)
+{
+    CppFile file(m_outputDir, name);
+
+    if (m_dryRun)
+        return;
+
+    file.openFile();
+
+    // Generate file setup and includes
+    generateCBridgeIncludes(file, name, entity);
+
+    // Generate type definitions
+    OString className = getInterfaceClassName(name);
+    OString functionPrefix = getCFunctionPrefix(name);
+    OString handleTypeName = functionPrefix + "Handle";
+
+    generateCBridgeTypeDefinitions(file, handleTypeName);
+
+    file.beginLine().append("extern \"C\"").endLine().beginBlock();
+
+    // Generate constructor functions
+    generateCBridgeConstructors(file, className, functionPrefix, 
handleTypeName);
+
+    // Generate destructor function
+    generateCBridgeDestructor(file, className, functionPrefix, handleTypeName);
+
+    // Generate validation function
+    generateCBridgeValidation(file, className, functionPrefix, handleTypeName);
+
+    // Generate method bridge functions
+    generateCBridgeMethods(file, className, functionPrefix, handleTypeName, 
entity);
+
+    file.beginLine().append("").endLine();
+    file.endBlock().append(" // extern \"C\"");
+
+    file.closeFile();
+}
+
+void CppProducer::generateStructHeader(std::string_view name,
+                                       const 
rtl::Reference<unoidl::PlainStructTypeEntity>& entity)
+{
+    if (m_dryRun || !m_combinedHeaderFile)
+        return;
+
+    // Use combined file instead of individual file
+    CppFile& file = *m_combinedHeaderFile;
+    file.openFileAppend();
+
+    // Generate includes following the pattern used in generateStructSource
+    file.beginLine().append("#include <sal/types.h>").endLine();
+    file.beginLine().append("#include 
<com/sun/star/uno/Reference.hxx>").endLine();
+    file.beginLine().append("#include <com/sun/star/uno/Any.hxx>").endLine();
+    // Include the struct definition
+    std::string headerName(name);
+    std::replace(headerName.begin(), headerName.end(), '.', '/');
+    file.beginLine().append("#include 
<").append(headerName).append(".hpp>").endLine();
+    file.beginLine().append("").endLine();
+    file.beginLine().append("using namespace com::sun::star::uno;").endLine();
+
+    file.beginLine().append("extern \"C\"").endLine().beginBlock();
+    // Add struct-specific namespace
+    std::string cppNamespace(name);
+    size_t lastDot = cppNamespace.rfind('.');
+    if (lastDot != std::string::npos)
+    {
+        cppNamespace = cppNamespace.substr(0, lastDot);
+        // Convert dots to double colons for C++ namespace syntax
+        size_t pos = 0;
+        while ((pos = cppNamespace.find('.', pos)) != std::string::npos)
+        {
+            cppNamespace.replace(pos, 1, "::");
+            pos += 2;
+        }
+    }
+
+    // Simple opaque struct bridge functions
+    OString functionPrefix = getCFunctionPrefix(name);
+    OString handleTypeName = functionPrefix + "Handle";
+    file.beginLine()
+        .append("// Opaque handle for type-safe C FFI")
+        .endLine()
+        .beginLine()
+        .append("typedef void* ")
+        .append(handleTypeName)
+        .append(";")
+        .endLine()
+        .beginLine()
+        .append("")
+        .endLine();
+
+    file.beginLine()
+        .append("// Opaque struct creation")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT ")
+        .append(handleTypeName)
+        .append(" ")
+        .append(functionPrefix)
+        .append("_constructor();")
+        .endLine();
+
+    file.beginLine()
+        .append("// Opaque handle destruction")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT void ")
+        .append(functionPrefix)
+        .append("_destroy(")
+        .append(handleTypeName)
+        .append(" handle);")
+        .endLine();
+
+    file.beginLine()
+        .append("// Struct from_ptr type casting")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT ")
+        .append(handleTypeName)
+        .append(" ")
+        .append(functionPrefix)
+        .append("_from_ptr(void* ptr);")
+        .endLine();
+
+    file.beginLine()
+        .append("")
+        .endLine()
+        .beginLine()
+        .append("// Getters/setters for direct struct members")
+        .endLine();
+
+    // Opaque member access functions - each member gets getter/setter
+    for (const auto& member : entity->getDirectMembers())
+    {
+        file.beginLine()
+            .append("// Opaque getter for ")
+            .append(member.name)
+            .append(" (type: ")
+            .append(member.type)
+            .append(")")
+            .endLine()
+            .beginLine()
+            .append("SAL_DLLPUBLIC_EXPORT void* ")
+            .append(functionPrefix)
+            .append("_get_")
+            .append(member.name)
+            .append("(")
+            .append(handleTypeName)
+            .append(" handle);")
+            .endLine();
+
+        file.beginLine()
+            .append("// Opaque setter for ")
+            .append(member.name)
+            .append(" (type: ")
+            .append(member.type)
+            .append(")")
+            .endLine()
+            .beginLine()
+            .append("SAL_DLLPUBLIC_EXPORT void ")
+            .append(functionPrefix)
+            .append("_set_")
+            .append(member.name)
+            .append("(")
+            .append(handleTypeName)
+            .append(" handle, void* value);")
+            .endLine();
+    }
+    file.endBlock().append("// extern \"C\"").endLine();
+    file.closeFile();
+}
+
+// Unified include generation function to eliminate duplication
+void CppProducer::generateCommonIncludes(CppFile& file, std::string_view name, 
bool needsLogging,
+                                         bool needsUnoTypes)
+{
+    // Always include sal/types.h
+    file.beginLine().append("#include <sal/types.h>").endLine();
+
+    // Include logging if needed
+    if (needsLogging)
+    {
+        file.beginLine().append("#include <sal/log.hxx>").endLine();
+    }
+
+    // Include UNO types if needed
+    if (needsUnoTypes)
+    {
+        file.beginLine().append("#include 
<com/sun/star/uno/Reference.hxx>").endLine();
+        file.beginLine().append("#include 
<com/sun/star/uno/Any.hxx>").endLine();
+    }
+
+    // Include the type-specific header
+    std::string headerName(name);
+    std::replace(headerName.begin(), headerName.end(), '.', '/');
+    file.beginLine().append("#include 
<").append(headerName).append(".hpp>").endLine();
+    file.beginLine().append("").endLine();
+}
+
+void CppProducer::generateStructSourceIncludes(CppFile& file, std::string_view 
name)
+{
+    generateCommonIncludes(file, name, false, true);
+}
+
+void CppProducer::generateEnumIncludes(CppFile& file, std::string_view name)
+{
+    generateCommonIncludes(file, name, false, false);
+}
+
+void CppProducer::generateEnumSourceIncludes(CppFile& file, std::string_view 
name)
+{
+    generateCommonIncludes(file, name, true, false);
+}
+
+void CppProducer::generateEnumHeader(std::string_view name,
+                                     const 
rtl::Reference<unoidl::EnumTypeEntity>&)
+{
+    if (m_dryRun || !m_combinedHeaderFile)
+        return;
+
+    // Use combined file instead of individual file
+    CppFile& file = *m_combinedHeaderFile;
+    file.openFileAppend();
+
+    // Add separator comment for this enum
+    file.beginLine().append("").endLine();
+    file.beginLine().append("// === ").append(name).append(" ===").endLine();
+
+    // Generate includes in combined file
+    generateEnumIncludes(file, name);
+
+    // Generate extern "C" declarations
+    file.beginLine().append("extern \"C\"").endLine().beginBlock();
+
+    // Opaque enum conversion functions - treat enums as opaque values
+    OString enumName = 
convertUnoTypeToCpp(OUString::createFromAscii(std::string(name)));
+    OString functionPrefix = getCFunctionPrefix(name); // Use consistent 
double-underscore naming
+    file.beginLine()
+        .append("    SAL_DLLPUBLIC_EXPORT ")
+        .append(enumName)
+        .append(" ")
+        .append(functionPrefix)
+        .append("_from_i32(sal_Int32 value);")
+        .endLine();
+
+    file.beginLine()
+        .append("    SAL_DLLPUBLIC_EXPORT sal_Int32 ")
+        .append(functionPrefix)
+        .append("_to_i32(")
+        .append(enumName)
+        .append(" value);")
+        .endLine();
+
+    file.beginLine().append("}").endLine();
+
+    file.closeFile();
+}
+
+void CppProducer::generateEnumSource(std::string_view name,
+                                     const 
rtl::Reference<unoidl::EnumTypeEntity>&)
+{
+    if (m_dryRun || !m_combinedSourceFile)
+        return;
+
+    // Use combined file instead of individual file
+    CppFile& file = *m_combinedSourceFile;
+    file.openFileAppend();
+
+    // Add separator comment for this enum
+    file.beginLine().append("").endLine();
+    file.beginLine().append("// === ").append(name).append(" ===").endLine();
+
+    // Generate includes for source file
+    generateEnumSourceIncludes(file, name);
+
+    // Generate extern "C" implementations
+    file.beginLine().append("extern \"C\"").endLine().beginBlock();
+
+    // Opaque enum conversion functions implementations
+    OString enumName = 
convertUnoTypeToCpp(OUString::createFromAscii(std::string(name)));
+    OString functionPrefix = getCFunctionPrefix(name); // Use consistent 
double-underscore naming
+
+    // from_i32 implementation
+    file.beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT ")
+        .append(enumName)
+        .append(" ")
+        .append(functionPrefix)
+        .append("_from_i32(sal_Int32 value)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("return static_cast<")
+        .append(enumName)
+        .append(">(value);")
+        .endLine()
+        .endBlock();
+
+    // to_i32 implementation
+    file.beginLine()
+        .append("")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT sal_Int32 ")
+        .append(functionPrefix)
+        .append("_to_i32(")
+        .append(enumName)
+        .append(" value)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("return static_cast<sal_Int32>(value);")
+        .endLine()
+        .endBlock();
+
+    file.beginLine().append("}").endLine();
+
+    file.closeFile();
+}
+
+// Unified namespace generation function to eliminate duplication
+void CppProducer::generateSourceNamespaces(CppFile& file, std::string_view 
name)
+{
+    file.beginLine().append("using namespace com::sun::star::uno;").endLine();
+
+    // Add type-specific namespace
+    std::string cppNamespace(name);
+    size_t lastDot = cppNamespace.rfind('.');
+    if (lastDot != std::string::npos)
+    {
+        cppNamespace = cppNamespace.substr(0, lastDot);
+        // Convert dots to double colons for C++ namespace syntax
+        size_t pos = 0;
+        while ((pos = cppNamespace.find('.', pos)) != std::string::npos)
+        {
+            cppNamespace.replace(pos, 1, "::");
+            pos += 2;
+        }
+        file.beginLine().append("using namespace 
").append(cppNamespace).append(";").endLine();
+    }
+    file.beginLine().append("").endLine();
+}
+
+void CppProducer::generateStructSourceNamespaces(CppFile& file, 
std::string_view name)
+{
+    generateSourceNamespaces(file, name);
+}
+
+void CppProducer::generateStructSourceBasicFunctions(CppFile& file, const 
OString& functionPrefix,
+                                                     const OString& 
handleTypeName,
+                                                     const std::string& 
className)
+{
+    // Generate struct creation function
+    file.beginLine()
+        .append("// Opaque struct creation")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT ")
+        .append(handleTypeName)
+        .append(" ")
+        .append(functionPrefix)
+        .append("_constructor()")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("return new ")
+        .append(className)
+        .append("();")
+        .endLine()
+        .endBlock()
+        .beginLine()
+        .append("")
+        .endLine();
+
+    // Generate struct destroy function
+    file.beginLine()
+        .append("// Opaque handle destruction")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT void ")
+        .append(functionPrefix)
+        .append("_destroy(")
+        .append(handleTypeName)
+        .append(" handle)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("delete static_cast<")
+        .append(className)
+        .append("*>(handle);")
+        .endLine()
+        .endBlock()
+        .beginLine()
+        .append("")
+        .endLine();
+
+    // Generate from_ptr function for struct type casting
+    file.beginLine()
+        .append("// Struct from_ptr type casting")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT ")
+        .append(handleTypeName)
+        .append(" ")
+        .append(functionPrefix)
+        .append("_from_ptr(void* ptr)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("if (ptr == nullptr) return nullptr;")
+        .endLine()
+        .beginLine()
+        .append("// For structs, we assume the pointer is already the correct 
type")
+        .endLine()
+        .beginLine()
+        .append("// Create a copy of the struct")
+        .endLine()
+        .beginLine()
+        .append("")
+        .append(className)
+        .append("* source = static_cast<")
+        .append(className)
+        .append("*>(ptr);")
+        .endLine()
+        .beginLine()
+        .append("return new ")
+        .append(className)
+        .append("(*source);")
+        .endLine()
+        .endBlock()
+        .beginLine()
+        .append("")
+        .endLine();
+}
+
+void CppProducer::generateStructSourceBaseMembers(
+    CppFile& file, const OString& functionPrefix, const OString& 
handleTypeName,
+    const std::string& className, const 
rtl::Reference<unoidl::PlainStructTypeEntity>& entity)
+{
+    // Generate getters/setters for base type members (if struct has a base)
+    if (!entity->getDirectBase().isEmpty())
+    {
+        file.beginLine()
+            .append("// Getters/setters for base type members (")
+            .append(entity->getDirectBase())
+            .append(")")
+            .endLine();
+
+        // Get base type entity to access its members
+        rtl::Reference<unoidl::Entity> baseEntity;
+        codemaker::UnoType::Sort baseSort
+            = m_typeManager->getSort(entity->getDirectBase(), &baseEntity);
+
+        if (baseSort == codemaker::UnoType::Sort::PlainStruct)
+        {
+            rtl::Reference<unoidl::PlainStructTypeEntity> baseStruct(
+                static_cast<unoidl::PlainStructTypeEntity*>(baseEntity.get()));
+
+            for (const auto& baseMember : baseStruct->getDirectMembers())
+            {
+                generateStructMemberAccessors(file, functionPrefix, 
handleTypeName, className,
+                                              baseMember);
+            }
+        }
+    }
+}
+
+void CppProducer::generateStructSourceDirectMembers(
+    CppFile& file, const OString& functionPrefix, const OString& 
handleTypeName,
+    const std::string& className, const 
rtl::Reference<unoidl::PlainStructTypeEntity>& entity)
+{
+    // Generate getters/setters for direct struct members
+    file.beginLine().append("// Getters/setters for direct struct 
members").endLine();
+
+    for (const auto& member : entity->getDirectMembers())
+    {
+        generateStructMemberAccessors(file, functionPrefix, handleTypeName, 
className, member);
+    }
+}
+
+void CppProducer::generateStructMemberAccessors(CppFile& file, const OString& 
functionPrefix,
+                                                const OString& handleTypeName,
+                                                const std::string& className,
+                                                const 
unoidl::PlainStructTypeEntity::Member& member)
+{
+    // Generate getter implementation
+    file.beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT void* ")
+        .append(functionPrefix)
+        .append("_get_")
+        .append(member.name)
+        .append("(")
+        .append(handleTypeName)
+        .append(" handle)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append(className)
+        .append("* obj = static_cast<")
+        .append(className)
+        .append("*>(handle);")
+        .endLine()
+        .beginLine()
+        .append("return &(obj->")
+        .append(member.name)
+        .append(");")
+        .endLine()
+        .endBlock();
+
+    // Generate setter implementation
+    file.beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT void ")
+        .append(functionPrefix)
+        .append("_set_")
+        .append(member.name)
+        .append("(")
+        .append(handleTypeName)
+        .append(" handle, void* value)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append(className)
+        .append("* obj = static_cast<")
+        .append(className)
+        .append("*>(handle);")
+        .endLine()
+        .beginLine()
+        .append("obj->")
+        .append(member.name);
+
+    // Check if this is a UNO interface type by checking the UNO type string
+    OUString unoType = member.type;
+    SAL_INFO("codemaker", "Struct member " << member.name << " UNO type: " << 
unoType);
+
+    // UNO interface types start with "com.sun.star" and end with an interface 
name (typically starting with "X")
+    // Examples: "com.sun.star.uno.XInterface", "com.sun.star.text.XText"
+    bool isInterfaceType = (unoType.startsWith("com.sun.star.") && 
(unoType.lastIndexOf('.') != -1)
+                            && (unoType.copy(unoType.lastIndexOf('.') + 
1).startsWith("X")));
+
+    if (isInterfaceType)
+    {
+        SAL_INFO("codemaker", "Detected UNO interface type, using pointer 
assignment");
+        // For interface types, assign the pointer directly without 
dereferencing
+        // The C++ struct expects Reference<Interface>, but we assign the raw 
interface pointer
+        file.append(" = reinterpret_cast<")
+            .append(convertUnoTypeToCpp(unoType))
+            .append("*>(value);");
+    }
+    else
+    {
+        SAL_INFO("codemaker", "Non-interface type, using dereferenced 
assignment");
+        // For non-interface types, dereference the pointer as before
+        file.append(" = *reinterpret_cast<const ")
+            .append(convertUnoTypeToCpp(unoType))
+            .append("*>(value);");
+    }
+    file.endLine().endBlock().beginLine().append("").endLine();
+}
+
+void CppProducer::generateStructSource(std::string_view name,
+                                       const 
rtl::Reference<unoidl::PlainStructTypeEntity>& entity)
+{
+    if (m_dryRun || !m_combinedSourceFile)
+        return;
+
+    // Use combined file instead of individual file
+    CppFile& file = *m_combinedSourceFile;
+    file.openFileAppend();
+
+    // Add separator comment for this struct
+    file.beginLine().append("").endLine();
+    file.beginLine().append("// === ").append(name).append(" ===").endLine();
+
+    // Start isolated block for this struct to avoid namespace conflicts
+    file.beginLine().append("namespace");
+    file.beginBlock();
+
+    // Generate includes
+    generateStructSourceIncludes(file, name);
+
+    // Generate namespaces (now in isolated scope)
+    generateStructSourceNamespaces(file, name);
+
+    OString functionPrefix = getCFunctionPrefix(name);
+    OString handleTypeName = functionPrefix + "Handle";
+    // Use fully qualified C++ type name to avoid namespace ambiguity
+    OString className = 
convertUnoTypeToCpp(OUString::createFromAscii(std::string(name)));
+
+    file.beginLine().append("extern \"C\"").endLine().beginBlock();
+
+    // Generate basic functions (creation/destruction)
+    generateStructSourceBasicFunctions(file, functionPrefix, handleTypeName, 
className.getStr());
+
+    // Generate accessors for base type members
+    generateStructSourceBaseMembers(file, functionPrefix, handleTypeName, 
className.getStr(),
+                                    entity);
+
+    // Generate accessors for direct members
+    generateStructSourceDirectMembers(file, functionPrefix, handleTypeName, 
className.getStr(),
+                                      entity);
+
+    file.endBlock().append(" // extern \"C\"").endLine();
+
+    // End isolated block for this struct
+    file.endBlock().append(" // End isolated block for 
").append(name).endLine();
+
+    file.closeFile();
+}
+
+// Helper functions
+std::string_view CppProducer::splitName(std::string_view name)
+{
+    size_t split = name.find_last_of(".::");
+    if (split != std::string_view::npos)
+        return name.substr(split + 1);
+    else
+        return name;
+}
+
+OString CppProducer::getInterfaceClassName(std::string_view unoName)
+{
+    return OString(splitName(unoName));
+}
+
+OString CppProducer::getCFunctionPrefix(std::string_view unoName)
+{
+    // Convert com.sun.star.lang.XMain to com__sun__star__lang__XMain for 
function names
+    OString temp(unoName);
+    return temp.replaceAll(".", "__");
+}
+
+OString CppProducer::getMethodReturnType(std::u16string_view returnType) const
+{
+    // Use the sophisticated type mapping from the old FFI producer
+    return getCppTypeName(returnType);
+}
+
+OString CppProducer::getMethodDefaultReturn(std::u16string_view returnType) 
const
+{
+    // First resolve any typedefs to their underlying types
+    OUString resolvedType = resolveTypedef(returnType);
+
+    // Handle void vs non-void return types properly
+    if (resolvedType == u"void")
+        return ""; // void methods don't return anything
+
+    // Return appropriate default values for different types
+    if (resolvedType == u"double")
+        return "0.0";
+    else if (resolvedType == u"float")
+        return "0.0f";
+    else if (resolvedType == u"sal_Int32" || resolvedType == u"long" || 
resolvedType == u"sal_Int16"
+             || resolvedType == u"short" || resolvedType == u"sal_Int8" || 
resolvedType == u"byte"
+             || resolvedType == u"sal_uInt8" || resolvedType == u"sal_uInt16"
+             || resolvedType == u"sal_uInt32" || resolvedType == u"sal_Int64"
+             || resolvedType == u"sal_uInt64" || resolvedType == u"sal_Unicode"
+             || resolvedType == u"unsigned short" || resolvedType == 
u"unsigned long"
+             || resolvedType == u"unsigned hyper" || resolvedType == u"hyper")
+        return "0";
+    else if (resolvedType == u"sal_Bool" || resolvedType == u"boolean")
+        return "false";
+    else
+    {
+        // Check if it's an enum type
+        if (isUnoType(resolvedType) && isUnoEnum(resolvedType))
+        {
+            // Return default enum value (first enum value, typically 0)
+            OString returnTypeStr = u2b(resolvedType);
+            size_t lastDot = returnTypeStr.lastIndexOf('.');
+            std::string_view enumName = (lastDot != std::string_view::npos)
+                                            ? returnTypeStr.subView(lastDot + 
1)
+                                            : returnTypeStr;
+            return "static_cast<"_ostr + enumName + "_>(0)"_ostr;
+        }
+        // Check if it's a struct type
+        else if (isUnoType(resolvedType) && isUnoStruct(resolvedType))
+        {
+            // Return empty struct for struct types
+            return OString("{}"); // Empty struct literal
+        }
+        else
+        {
+            return "nullptr"; // For pointer/interface/any types
+        }
+    }
+}
+
+OString CppProducer::convertUnoTypeToCpp(std::u16string_view unoType) const
+{
+    std::string result(unoType.begin(), unoType.end());
+
+    // Handle sequences: []type -> Sequence<type>
+    int sequenceDepth = 0;
+    while (result.starts_with("[]"))
+    {
+        result = result.substr(2);
+        sequenceDepth++;
+    }
+
+    // Check if the inner type is an interface and wrap with Reference<> if 
needed for sequences
+    bool needsReferenceWrapper = false;
+    if (sequenceDepth > 0 && result.find(".") != std::string::npos)
+    {
+        // For UNO types with namespaces, check if it's an interface (before 
namespace conversion)
+        rtl::Reference<unoidl::Entity> entity;
+        OUString unoTypeName = OUString::createFromAscii(result);
+        codemaker::UnoType::Sort sort = m_typeManager->getSort(unoTypeName, 
&entity);
+
+        if (sort == codemaker::UnoType::Sort::Interface)
+        {
+            needsReferenceWrapper = true;
+        }
+    }
+
+    // Handle template arguments recursively (before namespace conversion)
+    result = convertTemplateArguments(result);
+
+    // Convert dots to double colons for C++ namespace syntax
+    size_t pos = 0;
+    while ((pos = result.find('.', pos)) != std::string::npos)
+    {
+        result.replace(pos, 1, "::");
+        pos += 2;
+    }
+
+    // Handle primitive types (only for non-template contexts)
+    if (result.find('<') == std::string::npos)
+    {
+        if (result == "boolean")
+            result = "sal_Bool";
+        else if (result == "byte")
+            result = "sal_Int8";
+        else if (result == "short")
+            result = "sal_Int16";
+        else if (result == "unsigned short")
+            result = "sal_uInt16";
+        else if (result == "long")
+            result = "sal_Int32";
+        else if (result == "unsigned long")
+            result = "sal_uInt32";
+        else if (result == "hyper")
+            result = "sal_Int64";
+        else if (result == "unsigned hyper")
+            result = "sal_uInt64";
+        else if (result == "float")
+            result = "float";
+        else if (result == "double")
+            result = "double";
+        else if (result == "char")
+            result = "sal_Unicode";
+        else if (result == "string")
+            result = "OUString";
+        else if (result == "type")
+            result = "Type";
+        else if (result == "any")
+            result = "Any";
+        // else: keep as-is for UNO types like com::sun::star::...
+    }
+
+    // Apply Reference<> wrapper if needed
+    if (needsReferenceWrapper)
+    {
+        result = "Reference<" + result + ">";
+    }
+
+    // Wrap with Sequence<> for each nesting level
+    for (int i = 0; i < sequenceDepth; i++)
+    {
+        result = "Sequence<" + result + ">";
+    }
+
+    return OString(result.c_str());
+}
+
+std::string CppProducer::convertTemplateArguments(const std::string& unoType) 
const
+{
+    std::string result = unoType;
+
+    // Find template arguments within < >
+    size_t start = result.find('<');
+    if (start == std::string::npos)
+        return result; // No template arguments
+
+    size_t end = result.rfind('>');
+    if (end == std::string::npos || end <= start)
+        return result; // Malformed template
+
+    // Extract and process template arguments
+    std::string prefix = result.substr(0, start + 1);
+    std::string suffix = result.substr(end);
+    std::string args = result.substr(start + 1, end - start - 1);
+
+    // Split arguments by comma (simple split for now)
+    std::string processedArgs = "";
+    size_t argStart = 0;
+    size_t comma = 0;
+
+    while (true)
+    {
+        comma = args.find(',', argStart);
+        std::string arg;
+        if (comma == std::string::npos)
+        {
+            arg = args.substr(argStart);
+        }
+        else
+        {
+            arg = args.substr(argStart, comma - argStart);
+        }
+
+        // Trim whitespace
+        arg.erase(0, arg.find_first_not_of("   "));
+        arg.erase(arg.find_last_not_of("       ") + 1);
+
+        // Recursively process nested template arguments first
+        arg = convertTemplateArguments(arg);
+
+        // Handle sequence types first: []type -> Sequence<type>
+        if (arg.starts_with("[]"))
+        {
+            std::string innerType = arg.substr(2);
+            arg = "Sequence<" + innerType + ">";
+        }
+
+        // Convert basic types
+        if (arg == "string")
+            arg = "OUString";
+        else if (arg == "boolean")
+            arg = "sal_Bool";
+        else if (arg == "byte")
+            arg = "sal_Int8";
+        else if (arg == "short")
+            arg = "sal_Int16";
+        else if (arg == "long")
+            arg = "sal_Int32";
+        else if (arg == "hyper")
+            arg = "sal_Int64";
+        else if (arg == "float")
+            arg = "float";
+        else if (arg == "double")
+            arg = "double";
+        else if (arg == "char")
+            arg = "sal_Unicode";
+        else if (arg == "type")
+            arg = "Type";
+        else if (arg == "any")
+            arg = "Any";
+        // For complex types, convert dots to ::
+        else if (arg.find('.') != std::string::npos)
+        {
+            size_t pos = 0;
+            while ((pos = arg.find('.', pos)) != std::string::npos)
+            {
+                arg.replace(pos, 1, "::");
+                pos += 2;
+            }
+        }
+
+        if (!processedArgs.empty())
+            processedArgs += ",";
+        processedArgs += arg;
+
+        if (comma == std::string::npos)
+            break;
+        argStart = comma + 1;
+    }
+
+    return prefix + processedArgs + suffix;
+}
+
+void CppProducer::generateInterfaceHeader(std::string_view name,
+                                          const 
rtl::Reference<unoidl::InterfaceTypeEntity>& entity)
+{
+    if (m_dryRun || !m_combinedHeaderFile)
+        return;
+
+    // Use combined file instead of individual file
+    CppFile& file = *m_combinedHeaderFile;
+    file.openFileAppend();
+
+    // Add separator comment for this interface
+    file.beginLine().append("").endLine();
+    file.beginLine().append("// === ").append(name).append(" ===").endLine();
+
+    file.beginLine().append("extern \"C\"").endLine().beginBlock();
+
+    // Generate opaque handle typedef
+    OString functionPrefix = getCFunctionPrefix(name);
+    OString handleTypeName = functionPrefix + "Handle";
+
+    file.beginLine()
+        .append("// Opaque handle for type-safe C FFI")
+        .endLine()
+        .beginLine()
+        .append("typedef void* ")
+        .append(handleTypeName)
+        .append(";")
+        .endLine()
+        .beginLine()
+        .append("")
+        .endLine();
+
+    // Generate create/destroy functions
+    file.beginLine()
+        .append("// Interface lifecycle")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT ")
+        .append(handleTypeName)
+        .append(" ")
+        .append(functionPrefix)
+        .append("_constructor();")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT void ")
+        .append(functionPrefix)
+        .append("_destructor(")
+        .append(handleTypeName)
+        .append(" handle);")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT ")
+        .append(handleTypeName)
+        .append(" ")
+        .append(functionPrefix)
+        .append("_from_ptr(void* ptr);")
+        .endLine();
+
+    file.beginLine().append("").endLine();
+
+    // Generate method wrappers for all methods
+    file.beginLine().append("// Method wrappers").endLine();
+
+    // TODO: Add interface inheritance support in the future
+    // For now, only process direct methods from this interface
+
+    // Process only this interface's direct methods (no inheritance)
+    for (const auto& method : entity->getDirectMethods())
+    {
+        // Generate method signature
+        file.beginLine();
+
+        // Return type - use void* for all non-void returns (keep it simple)
+        OString returnType = getMethodReturnType(method.returnType);
+        if (returnType == "void")
+        {
+            file.append("SAL_DLLPUBLIC_EXPORT void ");
+        }
+        else
+        {
+            file.append("SAL_DLLPUBLIC_EXPORT void* ");
+        }
+
+        // Function name: com__sun__star__lang__XMain__methodName
+        file.append(functionPrefix)
+            .append("_")
+            .append(method.name)
+            .append("(")
+            .append(handleTypeName)
+            .append(" handle");
+
+        // Add parameters
+        for (const auto& param : method.parameters)
+        {
+            file.append(", void* ").append(param.name);
+        }
+
+        file.append(");");
+        file.endLine();
+    }
+
+    file.endBlock().beginLine().append("// extern \"C\"").endLine();
+
+    file.closeFile();
+}
+
+void CppProducer::generateInterfaceSourceIncludes(CppFile& file, 
std::string_view name)
+{
+    generateCommonIncludes(file, name, true, true);
+}
+
+void CppProducer::generateInterfaceSourceNamespaces(CppFile& file, 
std::string_view name)
+{
+    generateSourceNamespaces(file, name);
+}
+
+void CppProducer::generateInterfaceSourceBasicFunctions(CppFile& file,
+                                                        const OString& 
functionPrefix,
+                                                        const OString& 
className,
+                                                        const OString& 
handleTypeName)
+{
+    // Interface creation
+    file.beginLine()
+        .append("// Interface creation - creates empty Reference (to be 
populated by Rust)")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT ")
+        .append(handleTypeName)
+        .append(" ")
+        .append(functionPrefix)
+        .append("_constructor()")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("//Debug: Interface constructor called for ")
+        .append(className)
+        .endLine()
+        .beginLine()
+        .append("SAL_WARN(\"rustmaker\", \"Debug: Creating interface ")
+        .append(className)
+        .append("\");")
+        .endLine()
+        .beginLine()
+        .append("// Create empty Reference - actual interface will be set from 
Rust side")
+        .endLine()
+        .beginLine()
+        .append("auto res = new Reference<")
+        .append(className)
+        .append(">();")
+        .endLine()
+        .beginLine()
+        .append("")
+        .endLine()
+        .beginLine()
+        .append("if (!res)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("SAL_WARN(\"rust_uno_ffi\", \"Failed to allocate Reference<")
+        .append(className)
+        .append("> wrapper\");")
+        .endLine()
+        .beginLine()
+        .append("return nullptr;")
+        .endLine()
+        .endBlock()
+        .beginLine()
+        .append("")
+        .endLine()
+        .beginLine()
+        .append(
+            "// Note: Empty Reference is expected here - is() will be false 
until set from Rust")
+        .endLine()
+        .beginLine()
+        .append("SAL_INFO(\"rust_uno_ffi\", \"✅ Successfully created empty 
Reference<")
+        .append(className)
+        .append("> wrapper\");")
+        .endLine()
+        .beginLine()
+        .append("return res;")
+        .endLine()
+        .endBlock();
+
+    file.beginLine().append("").endLine();
+
+    // Interface destruction
+    file.beginLine()
+        .append("// Interface destruction")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT void ")
+        .append(functionPrefix)
+        .append("_destructor(")
+        .append(handleTypeName)
+        .append(" handle)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("delete static_cast<Reference<")
+        .append(className)
+        .append(">*>(handle);")
+        .endLine()
+        .endBlock();
+    file.beginLine().append("").endLine();
+
+    // Interface casting from void* to typed Reference using UNO_QUERY
+    file.beginLine()
+        .append("// Interface casting - casts void* to typed Reference using 
UNO_QUERY")
+        .endLine()
+        .beginLine()
+        .append("SAL_DLLPUBLIC_EXPORT ")
+        .append(handleTypeName)
+        .append(" ")
+        .append(functionPrefix)
+        .append("_from_ptr(void* ptr)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("if (ptr == nullptr) return nullptr;")
+        .endLine()
+        .beginLine()
+        .append("try")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("// Convert XInterface* to ")
+        .append(className)
+        .append(" via UNO_QUERY")
+        .endLine()
+        .beginLine()
+        .append("Reference<XInterface>* interfacePtr = 
static_cast<Reference<XInterface>*>(ptr);")
+        .endLine()
+        .beginLine()
+        .append("Reference<")
+        .append(className)
+        .append("> queryResult(interfacePtr->get(), UNO_QUERY);")
+        .endLine()
+        .beginLine()
+        .append("if (!queryResult.is()) return nullptr;")
+        .endLine()
+        .beginLine()
+        .append("Reference<")
+        .append(className)
+        .append(">* refPtr = new Reference<")
+        .append(className)
+        .append(">(queryResult);")
+        .endLine()
+        .beginLine()
+        .append("if (refPtr && refPtr->is())")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("SAL_INFO(\"rust_uno_ffi\", \"Successfully created Reference<")
+        .append(className)
+        .append("> in from_ptr\");")
+        .endLine()
+        .beginLine()
+        .append("return refPtr;")
+        .endBlock()
+        .beginLine()
+        .append("SAL_WARN(\"rust_uno_ffi\", \"Reference is invalid in from_ptr 
for ")
+        .append(className)
+        .append("\");")
+        .endLine()
+        .beginLine()
+        .append("delete refPtr;")
+        .endLine()
+        .beginLine()
+        .append("return nullptr;")
+        .endLine()
+        .endBlock()
+        .beginLine()
+        .append("catch (const Exception& e)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("SAL_WARN(\"rustmaker\", \"UNO exception in ")
+        .append(functionPrefix)
+        .append("_from_ptr: \" << e.Message);")
+        .endLine()
+        .beginLine()
+        .append("return nullptr;")
+        .endLine()
+        .beginLine()
+        .append("}")
+        .endLine()
+        .endBlock();
+
+    file.beginLine().append("").endLine();
+}
+
+void CppProducer::generateInterfaceSourceMethodImplementations(
+    CppFile& file, const OString& functionPrefix, const OString& className,
+    const OString& handleTypeName, const 
rtl::Reference<unoidl::InterfaceTypeEntity>& entity)
+{
+    // Generate method implementations
+    file.beginLine().append("// Method implementations").endLine();
+
+    // TODO: Add interface inheritance support in the future
+    // For now, only process direct methods from this interface (no 
inheritance)
+
+    // Process only this interface's direct methods
+    for (const auto& method : entity->getDirectMethods())
+    {
+        generateSingleInterfaceMethod(file, functionPrefix, className, 
handleTypeName, method);
+    }
+}
+
+void CppProducer::generateSingleInterfaceMethod(CppFile& file, const OString& 
functionPrefix,
+                                                const OString& className,
+                                                const OString& handleTypeName,
+                                                const 
unoidl::InterfaceTypeEntity::Method& method)
+{
+    file.beginLine();
+
+    // Use void* for all non-void returns (keep it simple)
+    OString returnType = getMethodReturnType(method.returnType);
+    if (returnType == "void")
+    {
+        file.append("SAL_DLLPUBLIC_EXPORT void ");
+    }
+    else
+    {
+        file.append("SAL_DLLPUBLIC_EXPORT void* ");
+    }
+
+    file.append(functionPrefix)
+        .append("_")
+        .append(method.name)
+        .append("(")
+        .append(handleTypeName)
+        .append(" handle");
+
+    // Add parameters
+    for (const auto& param : method.parameters)
+    {
+        file.append(", void* ").append(param.name);
+    }
+
+    file.append(")").endLine().beginBlock();
+
+    // Implementation body
+    file.beginLine()
+        .append("//Debug: Method ")
+        .append(method.name)
+        .append(" called")
+        .endLine()
+        .beginLine()
+        .append("SAL_WARN(\"rustmaker\", \"Debug: Method ")
+        .append(className)
+        .append("::")
+        .append(method.name)
+        .append(" called\");")
+        .endLine()
+        .beginLine()
+        .append("Reference<")
+        .append(className)
+        .append(">* ref = static_cast<Reference<")
+        .append(className)
+        .append(">*>(handle);")
+        .endLine()
+        .beginLine()
+        .append("//Debug: Checking reference validity")
+        .endLine()
+        .beginLine()
+        .append("if (!ref) { SAL_WARN(\"rustmaker\", \"Debug: ref is null\"); 
")
+        .append(method.returnType == u"void" ? "return;" : "return nullptr;")
+        .append(" }")
+        .endLine()
+        .beginLine()
+        .append("if (!ref->is()) { SAL_WARN(\"rustmaker\", \"Debug: ref->is() 
is false\"); ")
+        .append(method.returnType == u"void" ? "return;" : "return nullptr;")
+        .append(" }")
+        .endLine();
+
+    // Generate try-catch block for UNO exceptions
+    file.beginLine().append("try").endLine().beginBlock();
+
+    // Generate actual UNO method call
+    generateActualMethodCall(file, method);
+
+    // Note: Return value conversion is now handled inside 
generateActualMethodCall()
+
+    // Exception handling
+    file.endBlock()
+        .beginLine()
+        .append("catch (const Exception& ex)")
+        .endLine()
+        .beginBlock()
+        .beginLine()
+        .append("SAL_WARN(\"rustmaker\", \"UNO exception in ")
+        .append(className)
+        .append("_")
+        .append(method.name)
+        .append(": \" << ex.Message);")
+        .endLine();
+
+    // Return appropriate error value based on return type
+    if (method.returnType == u"void")
+    {
+        file.beginLine().append("return; // void method - no return on 
exception").endLine();
+    }
+    else
+    {
+        file.beginLine().append("return nullptr; // error return for non-void 
method").endLine();
+    }
+
+    file.endBlock().endBlock();
+
+    file.beginLine().append("").endLine();
+}
+
+void CppProducer::generateInterfaceSource(std::string_view name,
+                                          const 
rtl::Reference<unoidl::InterfaceTypeEntity>& entity)
+{
+    if (m_dryRun || !m_combinedSourceFile)
+        return;
+
+    // Use combined file instead of individual file
+    CppFile& file = *m_combinedSourceFile;
+    file.openFileAppend();
+
+    // Add separator comment for this interface
+    file.beginLine().append("").endLine();
+    file.beginLine().append("// === ").append(name).append(" ===").endLine();
+
+    // Generate includes
+    generateInterfaceSourceIncludes(file, name);
+
+    // Add namespaces
+    generateInterfaceSourceNamespaces(file, name);
+
+    file.beginLine().append("extern \"C\"").endLine().beginBlock();
+
+    // Generate implementation
+    OString functionPrefix = getCFunctionPrefix(name);
+    OString handleTypeName = functionPrefix + "Handle";
+    // Use fully qualified C++ type name to avoid namespace ambiguity
+    OString className = 
convertUnoTypeToCpp(OUString::createFromAscii(std::string(name)));
+
+    // Generate basic functions (creation/destruction)
+    generateInterfaceSourceBasicFunctions(file, functionPrefix, className, 
handleTypeName);
+
+    // Generate method implementations
+    generateInterfaceSourceMethodImplementations(file, functionPrefix, 
className, handleTypeName,
+                                                 entity);
+
+    file.endBlock().append(" // extern \"C\"");
+    file.beginLine().append("").endLine();
+
+    file.closeFile();
+}
+
+void CppProducer::generateActualMethodCall(CppFile& file,
+                                           const 
unoidl::InterfaceTypeEntity::Method& method)
+{
+    // Generate actual UNO method call based on method signature
+    file.beginLine()
+        .append("//Debug: About to call UNO method ")
+        .append(method.name)
+        .endLine()
+        .beginLine()
+        .append("SAL_WARN(\"rustmaker\", \"Debug: Calling UNO method ")
+        .append(method.name)
+        .append(" with ")
+        
.append(OString::number(static_cast<sal_Int32>(method.parameters.size())))
+        .append(" parameters\");")
+        .endLine();
+
+    if (method.returnType != u"void")
+    {
+        // Method with return value
+        file.beginLine()
+            .append("// Call actual UNO method with return value")
+            .endLine()
+            .beginLine();
+
+        file.append("auto result = (*ref)->").append(method.name).append("(");
+    }
+    else
+    {
+        // Void method
+        file.beginLine().append("// Call actual UNO method (void 
return)").endLine().beginLine();
+
+        file.append("(*ref)->").append(method.name).append("(");
+    }
+
+    // Add parameters with proper type conversion
+    bool first = true;
+    for (const auto& param : method.parameters)
+    {
+        if (!first)
+            file.append(", ");
+        first = false;
+
+        // Convert void* parameters to proper UNO types based on parameter type
+        std::u16string_view paramType = param.type;
+
+        // Determine if parameter is input-only (needs const) or output/inout 
(needs non-const reference)
+        bool isInputOnly
+            = (param.direction == 
unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN);
+
+        if (paramType == u"string")
+        {
+            if (isInputOnly)
+            {
+                // Input parameter: convert rtl_uString* to OUString object
+                
file.append("OUString(static_cast<rtl_uString*>(").append(param.name).append("))");
+            }
+            else
+            {
+                // Output parameter: needs OUString reference for binding
+                
file.append("*reinterpret_cast<OUString*>(").append(param.name).append(")");
+            }
+        }
+        else if (paramType == u"any")
+        {
+            if (isInputOnly)
+                file.append("*reinterpret_cast<const 
Any*>(").append(param.name).append(")");
+            else
+                
file.append("*reinterpret_cast<Any*>(").append(param.name).append(")");
+        }
+        else if (paramType == u"boolean")
+        {
+            if (isInputOnly)
+                file.append("*reinterpret_cast<const 
sal_Bool*>(").append(param.name).append(")");
+            else
+                
file.append("*reinterpret_cast<sal_Bool*>(").append(param.name).append(")");
+        }
+        else if (paramType == u"byte")
+        {
+            if (isInputOnly)
+                file.append("*reinterpret_cast<const 
sal_Int8*>(").append(param.name).append(")");
+            else
+                
file.append("*reinterpret_cast<sal_Int8*>(").append(param.name).append(")");
+        }
+        else if (paramType == u"short")
+        {
+            if (isInputOnly)
+                file.append("*reinterpret_cast<const 
sal_Int16*>(").append(param.name).append(")");
+            else
+                
file.append("*reinterpret_cast<sal_Int16*>(").append(param.name).append(")");
+        }
+        else if (paramType == u"long")
+        {
+            if (isInputOnly)
+                file.append("*reinterpret_cast<const 
sal_Int32*>(").append(param.name).append(")");
+            else
+                
file.append("*reinterpret_cast<sal_Int32*>(").append(param.name).append(")");
+        }
+        else if (paramType == u"hyper")
+        {
+            if (isInputOnly)
+                file.append("*reinterpret_cast<const 
sal_Int64*>(").append(param.name).append(")");
+            else
+                
file.append("*reinterpret_cast<sal_Int64*>(").append(param.name).append(")");
+        }
+        else if (paramType == u"float")
+        {
+            if (isInputOnly)
+                file.append("*reinterpret_cast<const 
float*>(").append(param.name).append(")");
+            else
+                
file.append("*reinterpret_cast<float*>(").append(param.name).append(")");
+        }
+        else if (paramType == u"double")
+        {
+            if (isInputOnly)
+                file.append("*reinterpret_cast<const 
double*>(").append(param.name).append(")");
+            else
+                
file.append("*reinterpret_cast<double*>(").append(param.name).append(")");
+        }
+        else if (paramType == u"type")
+        {
+            if (isInputOnly)
+                file.append("*reinterpret_cast<const 
Type*>(").append(param.name).append(")");
+            else
+                
file.append("*reinterpret_cast<Type*>(").append(param.name).append(")");
+        }
+        else if (paramType.starts_with(u"[]"))
+        {
+            // Sequence type - convert with null pointer safety
+            OString cppTypeName = convertUnoTypeToCpp(paramType);
+
+            if (isInputOnly)
+            {
+                // Input parameter - can use temporary empty sequence
+                file.append("(")
+                    .append(param.name)
+                    .append(" ? *reinterpret_cast<const ")
+                    .append(cppTypeName)
+                    .append("*>(")
+                    .append(param.name)
+                    .append(") : ")
+                    .append(cppTypeName)
+                    .append("())");
+            }
+            else
+            {
+                // Output/InOut parameter - needs reference, must dereference 
non-null pointer
+                file.append("*reinterpret_cast<")
+                    .append(cppTypeName)
+                    .append("*>(")
+                    .append(param.name)
+                    .append(")");
+            }
+        }
+        else
+        {
+            // For interfaces and other complex types
+            // Check if it's an interface type that needs Reference<> wrapper
+            rtl::Reference<unoidl::Entity> entity;
+            codemaker::UnoType::Sort sort = 
m_typeManager->getSort(OUString(paramType), &entity);
+
+            if (sort == codemaker::UnoType::Sort::Interface)
+            {
+                // Interface parameters: void* from Rust points to 
Reference<ActualType>*
+                // We need to dereference and cast via UNO_QUERY to the 
expected interface type
+                OString cppTypeName = convertUnoTypeToCpp(paramType);
+                if (isInputOnly)
+                {
+                    // For input interface parameters, we assume the Rust code 
passes Reference<SomeInterface>*
+                    // We dereference it and cast via UNO_QUERY to the 
expected interface type
+                    file.append("Reference<")
+                        .append(cppTypeName)
+                        .append(">(static_cast<Reference<XInterface>*>(")
+                        .append(param.name)
+                        .append(")->get(), UNO_QUERY)");
+                }
+                else
+                    file.append("*reinterpret_cast<Reference<")
+                        .append(cppTypeName)
+                        .append(">*>(")
+                        .append(param.name)
+                        .append(")");
+            }
+            else
+            {
+                // For structs and other complex types, assume proper type cast
+                OString cppTypeName = convertUnoTypeToCpp(paramType);
+                if (isInputOnly)
+                {
+                    file.append("(")
+                        .append(param.name)
+                        .append(" == nullptr ? ")
+                        .append(cppTypeName)
+                        .append("() : *reinterpret_cast<const ")
+                        .append(cppTypeName)
+                        .append("*>(")
+                        .append(param.name)
+                        .append("))");
+                }
+                else
+                {
+                    file.append("*reinterpret_cast<")
+                        .append(cppTypeName)
+                        .append("*>(")
+                        .append(param.name)
+                        .append(")");
+                }
+            }
+        }
+    }
+
+    file.append(");").endLine();
+
+    // Handle return value conversion for non-void methods
+    if (method.returnType != u"void")
+    {
+        file.beginLine().append("// Convert result to opaque void* 
return").endLine();
+
+        std::u16string_view returnType = method.returnType;
+
+        if (returnType == u"string")
+        {
+            file.beginLine().append("return new OUString(result);").endLine();
+        }
+        else if (returnType == u"any")
+        {
+            file.beginLine().append("return new Any(result);").endLine();
+        }
+        else if (returnType == u"boolean")
+        {
+            file.beginLine().append("return new sal_Bool(result);").endLine();
+        }
+        else if (returnType == u"byte")
+        {
+            file.beginLine().append("return new sal_Int8(result);").endLine();
+        }
+        else if (returnType == u"short")
+        {
+            file.beginLine().append("return new sal_Int16(result);").endLine();
+        }
+        else if (returnType == u"long")
+        {
+            file.beginLine().append("return new sal_Int32(result);").endLine();
+        }
+        else if (returnType == u"hyper")
+        {
+            file.beginLine().append("return new sal_Int64(result);").endLine();
+        }
+        else if (returnType == u"float")
+        {
+            file.beginLine().append("return new float(result);").endLine();
+        }
+        else if (returnType == u"double")
+        {
+            file.beginLine().append("return new double(result);").endLine();
+        }
+        else if (returnType == u"type")
+        {
+            file.beginLine().append("return new Type(result);").endLine();
+        }
+        else if (returnType.starts_with(u"[]"))
+        {
+            // Sequence return type
+            file.beginLine()
+                .append("return new ")
+                .append(convertUnoTypeToCpp(returnType))
+                .append("(result);")
+                .endLine();
+        }
+        else
+        {
+            // For interfaces and other complex types, create appropriate 
wrapper
+            // Check if it's an interface type
+            rtl::Reference<unoidl::Entity> entity;
+            codemaker::UnoType::Sort sort = 
m_typeManager->getSort(OUString(returnType), &entity);
+
+            if (sort == codemaker::UnoType::Sort::Interface)
+            {
+                // Add debug output for interface return values
+                file.beginLine()
+                    .append("SAL_WARN(\"rustmaker\", \"Debug: UNO method ")
+                    .append(method.name)
+                    .append(
+                        " completed, result.is() = \" << (result.is() ? 
\"true\" : \"false\"));")
+                    .endLine()
+                    .beginLine()
+                    .append("SAL_INFO(\"rust_uno_ffi\", \"Creating new 
Reference<")
+                    .append(convertUnoTypeToCpp(returnType))
+                    .append("> wrapper for method ")
+                    .append(method.name)
+                    .append("\");")
+                    .endLine()
+                    .beginLine()
+                    .append("auto res = new Reference<")
+                    .append(convertUnoTypeToCpp(returnType))
+                    .append(">(result);")
+                    .endLine()
+                    .beginLine()
+                    .append("")
+                    .endLine()
+                    .beginLine()
+                    .append("if (!res)")
+                    .endLine()
+                    .beginBlock()
+                    .beginLine()
+                    .append("SAL_WARN(\"rust_uno_ffi\", \"Failed to create 
Reference wrapper for ")
+                    .append(convertUnoTypeToCpp(returnType))
+                    .append(" in method ")
+                    .append(method.name)
+                    .append("\");")
+                    .endLine()
+                    .beginLine()
+                    .append("return nullptr;")
+                    .endLine()
+                    .endBlock()
+                    .beginLine()
+                    .append("")
+                    .endLine()
+                    .beginLine()
+                    .append("if (!res->is())")
+                    .endLine()
+                    .beginBlock()
+                    .beginLine()
+                    .append("SAL_WARN(\"rust_uno_ffi\", \"Reference wrapper is 
invalid (is() = "
+                            "false) for ")
+                    .append(convertUnoTypeToCpp(returnType))
+                    .append(" in method ")
+                    .append(method.name)
+                    .append("\");")
+                    .endLine()
+                    .beginLine()
+                    .append("delete res;")
+                    .endLine()
+                    .beginLine()
+                    .append("return nullptr;")
+                    .endLine()
+                    .endBlock()
+                    .beginLine()
+                    .append("")
+                    .endLine()
+                    .beginLine()
+                    .append("SAL_INFO(\"rust_uno_ffi\", \"✅ Successfully 
created valid Reference "
+                            "wrapper for ")
+                    .append(convertUnoTypeToCpp(returnType))
+                    .append(" in method ")
+                    .append(method.name)
+                    .append("\");")
+                    .endLine()
+                    .beginLine()
+                    .append("return res;")
+                    .endLine();
+            }
+            else
+            {
+                // For structs and other types
+                file.beginLine()
+                    .append("return new ")
+                    .append(convertUnoTypeToCpp(returnType))
+                    .append("(result);")
+                    .endLine();
+            }
+        }
+    }
+}
+
+void CppProducer::generateReturnValueConversion(CppFile& file,
+                                                const 
unoidl::InterfaceTypeEntity::Method& method)
+{
+    file.beginLine().append("// Convert result to opaque void* 
return").endLine();
+
+    std::u16string_view returnType = method.returnType;
+
+    if (returnType == u"string")
+    {
+        file.beginLine().append("return new OUString(result);").endLine();
+    }
+    else if (returnType == u"any")
+    {
+        file.beginLine().append("return new Any(result);").endLine();
+    }
+    else if (returnType == u"boolean")
+    {
+        file.beginLine().append("return new sal_Bool(result);").endLine();
+    }
+    else if (returnType == u"byte")
+    {
+        file.beginLine().append("return new sal_Int8(result);").endLine();
+    }
+    else if (returnType == u"short")
+    {
+        file.beginLine().append("return new sal_Int16(result);").endLine();
+    }
+    else if (returnType == u"long")
+    {
+        file.beginLine().append("return new sal_Int32(result);").endLine();
+    }
+    else if (returnType == u"hyper")
+    {
+        file.beginLine().append("return new sal_Int64(result);").endLine();
+    }
+    else if (returnType == u"float")
+    {
+        file.beginLine().append("return new float(result);").endLine();
+    }
+    else if (returnType == u"double")
+    {
+        file.beginLine().append("return new double(result);").endLine();
+    }
+    else if (returnType == u"type")
+    {
+        file.beginLine().append("return new Type(result);").endLine();
+    }
+    else if (returnType.starts_with(u"[]"))
+    {
+        // Sequence return type - return void* to new sequence
+        file.beginLine()
+            .append("return new ")
+            .append(convertUnoTypeToCpp(returnType))
+            .append("(result);")
+            .endLine();
+    }
+    else
+    {
+        // For interfaces - return Reference<> to avoid instantiating abstract 
types
+        rtl::Reference<unoidl::Entity> entity;
+        codemaker::UnoType::Sort sort = 
m_typeManager->getSort(OUString(returnType), &entity);
+
+        if (sort == codemaker::UnoType::Sort::Interface)
+        {
+            // Interface return type - return new Reference<Interface>(result)
+            file.beginLine()
+                .append("SAL_INFO(\"rust_uno_ffi\", \"Creating Reference 
wrapper for return type ")
+                .append(convertUnoTypeToCpp(returnType))
+                .append("\");")
+                .endLine()
+                .beginLine()
+                .append("auto res = new Reference<")
+                .append(convertUnoTypeToCpp(returnType))
+                .append(">(result);")
+                .endLine()
+                .beginLine()
+                .append("")
+                .endLine()
+                .beginLine()
+                .append("if (!res)")
+                .endLine()
+                .beginBlock()
+                .beginLine()
+                .append("SAL_WARN(\"rust_uno_ffi\", \"Failed to create 
Reference wrapper for ")
+                .append(convertUnoTypeToCpp(returnType))
+                .append("\");")
+                .endLine()
+                .beginLine()
+                .append("return nullptr;")
+                .endLine()
+                .endBlock()
+                .beginLine()
+                .append("")
+                .endLine()
+                .beginLine()
+                .append("if (!res->is())")
+                .endLine()
+                .beginBlock()
+                .beginLine()
+                .append(
+                    "SAL_WARN(\"rust_uno_ffi\", \"Reference wrapper is invalid 
(is() = false) for ")
+                .append(convertUnoTypeToCpp(returnType))
+                .append("\");")
+                .endLine()
+                .beginLine()
+                .append("delete res;")
+                .endLine()
+                .beginLine()
+                .append("return nullptr;")
+                .endLine()
+                .endBlock()
+                .beginLine()
+                .append("")
+                .endLine()
+                .beginLine()
+                .append("SAL_INFO(\"rust_uno_ffi\", \"✅ Successfully created 
valid Reference "
+                        "wrapper for ")
+                .append(convertUnoTypeToCpp(returnType))
+                .append("\");")
+                .endLine()
+                .beginLine()
+                .append("return res;")
+                .endLine();
+        }
+        else
+        {
+            // For structs, enums and other types - return void* to new object
+            file.beginLine()
+                .append("return new ")
+                .append(convertUnoTypeToCpp(returnType))
+                .append("(result);")
+                .endLine();
+        }
+    }
+}
+
+// Type mapping functions (from old FFI producer)
+
+OUString CppProducer::resolveTypedef(std::u16string_view unoType) const
+{
+    // Recursively resolve typedefs to their underlying types
+    rtl::Reference<unoidl::Entity> entity;
+    rtl::Reference<unoidl::MapCursor> cursor;
+    codemaker::UnoType::Sort sort = m_typeManager->getSort(OUString(unoType), 
&entity, &cursor);
+
+    if (sort == codemaker::UnoType::Sort::Typedef)
+    {
+        rtl::Reference<unoidl::TypedefEntity> typedefEntity(
+            static_cast<unoidl::TypedefEntity*>(entity.get()));
+        if (typedefEntity.is())
+        {
+            // Recursively resolve in case of nested typedefs
+            OUString resolvedType = typedefEntity->getType();
+            return resolveTypedef(resolvedType);
+        }
+    }
+
+    // If not a typedef or resolution failed, return the original type
+    return OUString(unoType);
+}
+
+OString CppProducer::mapUnoPrimitiveToSal(std::u16string_view unoType) const
+{
+    // Common primitive type mappings from UNO to SAL types
+    if (unoType == u"boolean")
+        return "sal_Bool"_ostr;
+    else if (unoType == u"byte")
+        return "sal_Int8"_ostr;
+    else if (unoType == u"short")
+        return "sal_Int16"_ostr;
+    else if (unoType == u"unsigned short")
+        return "sal_uInt16"_ostr;
+    else if (unoType == u"long")
+        return "sal_Int32"_ostr;
+    else if (unoType == u"unsigned long")
+        return "sal_uInt32"_ostr;
+    else if (unoType == u"hyper")
+        return "sal_Int64"_ostr;
+    else if (unoType == u"unsigned hyper")
+        return "sal_uInt64"_ostr;
+    else if (unoType == u"float")
+        return "float"_ostr;
+    else if (unoType == u"double")
+        return "double"_ostr;
+    else
+        return OString(); // Not a primitive type
+}
+
+OString CppProducer::getCppTypeName(std::u16string_view unoType) const
+{
+    // First, resolve any typedefs to their underlying types
+    OUString resolvedType = resolveTypedef(unoType);
+
+    // Map UNO types to C++ types for extern "C" functions
+    if (resolvedType == u"void")
+        return "void"_ostr;
+    else if (resolvedType == u"string")
+        return "rtl_uString*"_ostr;
+    else if (resolvedType == u"any" || resolvedType == u"com.sun.star.uno.Any")
+        return "uno_Any*"_ostr;
+
+    // Try primitive type mapping
+    OString primitiveType = mapUnoPrimitiveToSal(resolvedType);
+    if (!primitiveType.isEmpty())
+        return primitiveType;
+
+    // Handle complex types
+    if (resolvedType.startsWith(u"[]"))
+        return "uno_Sequence*"_ostr;
+    else if (isUnoStruct(resolvedType))
+    {
+        // For structs, return the FFI struct name with underscore (value 
type, not pointer)
+        OString type = u2b(resolvedType);
+        size_t lastDot = type.lastIndexOf('.');
+        if (lastDot != std::string_view::npos)
+            return OString::Concat(type.subView(lastDot + 1)) + "_";
+        else
+            return type + "_";
+    }
+    else if (isUnoEnum(resolvedType))
+    {
+        // For enums, return the enum name with underscore to match generated 
FFI enums
+        OString type = u2b(resolvedType);
+        size_t lastDot = type.lastIndexOf('.');
+        if (lastDot != std::string_view::npos)
+            return OString::Concat(type.subView(lastDot + 1)) + "_";
+        else
+            return type + "_";
+    }
+    else if (isUnoConstantGroup(resolvedType))
+    {
+        // For constant groups, return the FFI name with underscore
+        OString type = u2b(resolvedType);
+        size_t lastDot = type.lastIndexOf('.');
+        if (lastDot != std::string_view::npos)
+            return OString::Concat(type.subView(lastDot + 1)) + "_";
+        else
+            return type + "_";
+    }
+    else if (isUnoType(resolvedType))
+    {
+        // For interfaces and other types, return XInterface* pointer
+        return "XInterface*"_ostr;
+    }
+    else
+        return "void*"_ostr; // Default to void* for unknown types
+}
+
+OString CppProducer::getRustFFITypeName(std::u16string_view unoType) const
+{
+    // Map UNO types to Rust FFI types
+    if (unoType == u"string")
+        return "*mut rtl_uString"_ostr;
+    else if (unoType == u"boolean")
+        return "u8"_ostr; // sal_Bool is typedef'd to u8 (unsigned char)
+    else if (unoType == u"byte")
+        return "i8"_ostr;
+    else if (unoType == u"short")
+        return "i16"_ostr;
+    else if (unoType == u"unsigned short")
+        return "u16"_ostr;
+    else if (unoType == u"long")
+        return "i32"_ostr;
+    else if (unoType == u"unsigned long")
+        return "u32"_ostr;
+    else if (unoType == u"hyper")
+        return "i64"_ostr;
+    else if (unoType == u"unsigned hyper")
+        return "u64"_ostr;
+    else if (unoType == u"float")
+        return "f32"_ostr;
+    else if (unoType == u"double")
+        return "f64"_ostr;
+    else if (unoType == u"void")
+        return "()"_ostr;
+    else if (unoType == u"any" || unoType == u"com.sun.star.uno.Any")
+        return "*mut uno_Any"_ostr; // UNO Any type
+    else if (isUnoStruct(unoType))
+    {
+        // For structs, return just the struct name with underscore since we 
import it
+        OString type = u2b(unoType);
+        size_t lastDot = type.lastIndexOf('.');
+        if (lastDot != std::string_view::npos)
+            return OString::Concat(type.subView(lastDot + 1)) + "_";
+        else
+            return type + "_";
+    }
+    else if (isUnoEnum(unoType))
+    {
+        // For enums, return just the enum name since we import it
+        OString type = u2b(unoType);
+        size_t lastDot = type.lastIndexOf('.');
+        if (lastDot != std::string_view::npos)
+            return OString(type.subView(lastDot + 1));
+        else
+            return type;
+    }
+    else if (isUnoConstantGroup(unoType))
+    {
+        // For constant groups, return the constant group name with underscore 
to match C++ side
+        OString type = u2b(unoType);
+        size_t lastDot = type.lastIndexOf('.');
+        if (lastDot != std::string_view::npos)
+            return OString::Concat(type.subView(lastDot + 1)) + "_";
+        else
+            return type + "_";
+    }
+    else if (isUnoType(unoType))
+    {
+        // For interfaces, return *mut XInterface pointer
+        return "*mut XInterface"_ostr;
+    }
+    else
+        return "*mut std::ffi::c_void"_ostr; // Default for unknown types
+}
+
+OString CppProducer::convertBasicType(const OString& typeName) const
+{
+    OString result = typeName;
+
+    // Convert UNO primitive types to C++ types
+    if (result == "long")
+        result = "sal_Int32";
+    else if (result == "short")
+        result = "sal_Int16";
+    else if (result == "byte")
+        result = "sal_Int8";
+    else if (result == "boolean")
+        result = "sal_Bool";
+    else if (result == "double")
+        result = "double";
+    else if (result == "float")
+        result = "float";
+    else if (result == "string")
+        result = "OUString";
+    else if (result == "any")
+        result = "Any";
+    else if (result.indexOf('.') != -1)
+    {
+        // For UNO types with namespace, convert dots to double colons
+        result = result.replaceAll(".", "::");
+    }
+
+    return result;
+}
+
+// Type classification helper methods
+
+bool CppProducer::isUnoType(std::u16string_view typeName) const
+{
+    // Check if this is a valid UNO type using TypeManager
+    rtl::Reference<unoidl::Entity> entity;
+    rtl::Reference<unoidl::MapCursor> cursor;
+
+    codemaker::UnoType::Sort sort = m_typeManager->getSort(OUString(typeName), 
&entity, &cursor);
+
+    // Return true for any valid UNO type (not just interfaces/structs/enums)
+    return sort != codemaker::UnoType::Sort::Void && sort != 
codemaker::UnoType::Sort::Boolean
+           && sort != codemaker::UnoType::Sort::Byte && sort != 
codemaker::UnoType::Sort::Short
+           && sort != codemaker::UnoType::Sort::UnsignedShort
+           && sort != codemaker::UnoType::Sort::Long
+           && sort != codemaker::UnoType::Sort::UnsignedLong
-e 
... etc. - the rest is truncated

Reply via email to