// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
\page qt_add_protobuf.html
\ingroup cmake-commands-qtprotobuf

\title qt_add_protobuf
\target qt6_add_protobuf
\summary {Generates Qt-based C++ source code using a protobuf schema}
\preliminarycmakecommand
\cmakecommandsince 6.5

Usually \c qtprotobufgen would be invoked through CMake using the
\c qt_add_protobuf command.

\badcode
    qt_add_protobuf(<target>
        PROTO_FILES <file> ...
        [COPY_COMMENTS]
        [GENERATE_PACKAGE_SUBFOLDERS]
        [EXTRA_NAMESPACE <namespace>]
        [EXPORT_MACRO <infix>]
        [QML [QML_URI <uri>]]
        [PROTO_INCLUDES <path> ...]
        [OUTPUT_DIRECTORY <dir>]
        [OUTPUT_HEADERS <var>]
        [OUTPUT_TARGETS <var>]
    )
\endcode

The source files generated by \c qtprotobufgen are then added to the target.
If the target already exists, the files are \e added to the target source
list. If the target doesn't exist, it is created as a library which you must
link to.

\section1 Arguments
\list
    \include qtprotoccommon-options.qdocinc 0
    \li \c QML enables QProtobufMessage types in QML context by registering
        them as a QML module.
        Protobuf types can extend an existing QML module:
        \badcode
            qt_add_qml_module(targetname
                ...
            )

            qt_add_protobuf(targetname
                QML
                ...
            )
        \endcode

        If \c qt_add_protobuf is called with a non-existing target
        or the target is not a QML module, a new QML module will be created
        implicitly. In case of the new QML module creation, the
        \l {qt_add_qml_module} command is called inside the
        \c qt_add_protobuf command.
        \badcode
            qt_add_executable(targetname
                ...
            )

            qt_add_protobuf(targetname
                QML
                ...
            )
        \endcode
        Every QML module has to define a \c URI name. Other QML modules may
        use this name in \l{qtqml-syntax-imports.html}{import statements}
        to import the module into a user application. Use the \c QML_URI
        option to set the \c URI name. It has to be specified in dotted
        notation, e.g. \c {Qt.Protobuf.Package}.
        \badcode
            qt_add_executable(targetname
                ...
            )

            qt_add_protobuf(targetplugin
                QML
                QML_URI proto.uri.example
            )
        \endcode
        If \c QML_URI is omitted, then the protobuf package name will be used
        as the module \c URI.
        \note If \c QML_URI is passed to \c qt_add_protobuf command
        but \c target already exists, \c QML_URI argument will
        be ignored.
        \note If the \c QML_URI is skipped, all *.proto files specified
        in the \c qt_add_protobuf command should have the same \c protobuf
        package name, since it shall be used as a default \c URI for the
        resulting QML module.
        \note You should avoid creating several QML modules with the same
        \c QML_URI or proto package name, because it leads to import error
        in QML context.

    \include qtprotogen-options.qdocinc 0
    \include qtprotogen-cmake-options.qdocinc 0
\endlist

\sa{The qtprotobufgen Tool}

\section1 Resolving dependencies between protobuf targets

The \c qt_add_protobuf command doesn't consider the dependencies between
\c .proto files that are used to generate code for different targets.

The project may have two or more \c .proto files with dependencies:
\badcode
// test_messages.proto
syntax = "proto3";

package test.messages;

message MyMessage {
    int32 myField = 1;
}
\endcode

\badcode
// test_extensions.proto
syntax = "proto3";

import "test_messages.proto";

package test.extensions;

message MyExtension {
    test.messages.MyMessage baseMessage = 1;
    int32 extension = 2;
}

\endcode

The above \c .proto files can be used to generate the standalone libraries:
\badcode
qt_add_protobuf(test_messages
    PROTO_FILES
        test_messages.proto
)
...
qt_add_protobuf(test_extensions
    PROTO_FILES
        test_extensions.proto
)
...
\endcode

Since the \c test_extensions target depends on messages from the
\c test_messages target, users need to link to such targets manually in their
\c CMake scripts:
\badcode
target_link_libraries(test_extensions PUBLIC test_messages)
\endcode

\note Messages from \c test_messages target are used in header files that belong
to the \c test_extensions target, so targets that link to \c test_extensions
should have the \c test_messages target as a transitive dependency. It's
recommended to use the \c PUBLIC linking scope, to have the proper
\c INTERFACE_INCLUDE_DIRECTORIES and \c INTERFACE_LINK_LIBRARIES properties for
protobuf library targets.

\section1 Example

\include qt-add-protobuf-example.qdocinc 0
\include qt-add-protobuf-example.qdocinc 1
*/
