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

/*!
    \keyword Protobuf
    \page qtprotobuf-index.html
    \title Qt Protobuf
    \ingroup frameworks-technologies

    The Qt Protobuf \l {The qtprotobufgen Tool}{generator plugin} generates
    Qt-based classes from \c{.proto} files. You can use the classes to
    serialize and deserialize their associated protobuf messages.

    \section1 Overview

    \section2 What are protocol buffers?
    Protocol buffers are a language-neutral, platform-neutral, and extensible
    mechanism for serializing structured data, which is compact and easy
    to use:
    \list
        \li A user defines the structure of data in \c{.proto} files.
        \li Proto compiler is invoked at build time on \c{.proto} files to
            generate code in various programming languages.
    \endlist
    The provided format is suitable for network traffic or long-term data
    storage.

    \section2 Which problems do protocol buffers solve?
    Protocol buffers provide a serialization format for packets of typed and
    structured data that are up to a few megabytes in size. Moreover, it can
    be extended with new information without invalidating existing data or
    requiring code to be updated. For more information, see
    \l {https://protobuf.dev/}{Protocol Buffers Overview}.

    \section2 What are the benefits of using Qt Protobuf?
    You can use a Protocol buffers mechanism in any Qt-based project:
    \list
        \li No need to call a protocol buffer compiler explicitly.
        \li No need to integrate generated code into project tree manually.
        \li Convenient serialization and deserialization API.
        \li Integrated properties mechanism for generated protobuf messages.
        \li Integrated gRPC-client support (see \l {Qt GRPC}{QtGrpc module}).
        \li Integrated QML-types support for generated protobuf messages.
            See \l{Qt Protobuf QML types}
        \li Enabled using Qt Core and Qt GUI types as a part of *.proto schema.
            See \l {Protobuf Qt Core types module} and
            \l {Protobuf Qt GUI types module}.
    \endlist

    \section2 Incoming features
    \list
        \li Enabling gRPC-server support.
    \endlist

    \section1 Using the Module
    Google protocol buffers provide a generator called \c protoc that
    supports extensions. \l {The qtprotobufgen Tool} is an extension
    for \c protoc and requires that you install \c protoc on your host system.
    For more information about the installation, see
    \l {https://grpc.io/docs/protoc-installation/}{Protoc Installation}.

    Example of installation for Linux, using \e {apt}:
    \badcode
    apt install -y protobuf-compiler
    protoc --version  # Ensure compiler version is 3+
    \endcode
    For more information about component API usage, see \e {CMake API}.

    \section2 QML API
    The QML types of the module are available through the QML and QML_URI
    options in the \l{qt_add_protobuf} macro.
    The import name is equal to the \c.proto package name or defined by
    QML_URI option in the \l{qt_add_protobuf} macro.
    To use the types, add the following import statement to your .qml file:
    \code
        import my.proto.package.uri
    \endcode

    \section2 C++ API

    \include {module-use.qdocinc} {using the c++ api}

    \section3 Building with CMake

    \include {module-use.qdocinc} {building with cmake} {Protobuf}

    \section1 Articles and Guides
    \list
        \li \l {CMake Commands in Qt6 Protobuf}
        \li \l {Protobuf Qt Core types module} {Protobuf Qt Core types}
        \li \l {Protobuf Qt GUI types module} {Protobuf Qt GUI types}
        \li \l {Qt Protobuf Well-Known Types C++ Classes} {Qt Protobuf Well-Known types}
    \endlist

    \section1 References
    \list
        \li \l {Qt Protobuf C++ Classes}{Qt Protobuf C++ Classes}
        \li \l {Qt Protobuf QML types}
    \endlist

    \section1 Examples
    \list
        \li \l {Qt Protobuf Examples}
    \endlist
*/

/*!
    \module QtProtobuf
    \modulestate Technical Preview
    \title Qt Protobuf C++ Classes
    \qtcmakepackage Protobuf
    \since 6.5
    \brief Provides protocol buffers support in Qt.
*/

/*!
    \group qtprotobuf-examples
    \keyword Qt Protobuf Examples
    \title Qt Protobuf Examples
    \brief A collection describes existing QML-types support for \l {Qt Protobuf}

    These examples demonstrate how to generate code using the protobuf schema
    and use it in your projects.
*/

/*!
    \group QtProtobuf
    \keyword Qt Protobuf QML types
    \title Qt Protobuf QML types
    \brief A collection of examples for \l {Qt Protobuf}

    With the \l{The qtprotobufgen Tool}{generator plugin}, you can register
    protobuf messages in the QML. To register the type, use the
    \c QML and \c QML_URI generation keys. See API details in
    \l{qt_add_protobuf}{qt_add_protobuf} command and
    API usage example \l{QML extended protobuf example}{QML extended protobuf}.

    Registered protobuf messages are available in the QML,
    like built-in \l{Q_GADGET} types. The registration is done via the QML
    module.

    \section2 Protobuf message duplicates
    You should avoid declaration of protobuf message duplicates in your
    \c *.proto files or do it wisely. In case your
    application uses several identical protobuf message names declared inside
    different protobuf packages, they can contradict each other in
    auto-generated code.
    In example below, 2 different proto packages \c qtprotobufnamespace and
    \c qtprotobufnamespace1.nested use the same proto message
    \c NestedFieldMessage.
    The file \c nested.proto:
    \badcode
        syntax = "proto3";

        package qtprotobufnamespace;
        import "externalpackage.proto";

        message NestedFieldMessage {
            sint32 testFieldInt = 1;
        }
    \endcode
    The file \c nestedspace1.proto:
    \badcode
        syntax = "proto3";

        package qtprotobufnamespace1.nested;

        message NestedFieldMessage {
            message NestedMessage {
                sint32 field = 1;
            }
            NestedMessage nested = 1;
        }
    \endcode
    In case there is no possibility to avoid name duplicates among
    packages, then put duplicated messages in different QML modules
    and use a <Qualifier> for each QML module import,
    see \l{Module (Namespace) Imports}.
    Below the example how to add protobuf packages into different
    QML modules:
    \badcode
        # qtprotobufnamespace QML module
        qt_add_protobuf(nestedtypes_qtprotobuf_qml
            PROTO_FILES
                nested.proto
            QML
            QML_URI
                qtprotobufnamespace
            OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/qt_protobuf_gen1"
        )

        ....................................

        # qtprotobufnamespace1.nested QML module
        qt_add_protobuf(nestedspace_qml
            PROTO_FILES
                nestedspace1.proto
            QML
            QML_URI
                qtprotobufnamespace1.nested
            OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/qt_protobuf_gen2"
        )
    \endcode
    The <Qualifier> usage example:
    \badcode
        import qtprotobufnamespace as NestedFieldMessages
        import qtprotobufnamespace1.nested as FieldMessages_Nested1

        .....................................
        .....................................
        .....................................

        property NestedFieldMessages.nestedFieldMessage fieldMsg1;
        property FieldMessages_Nested1.nestedFieldMessage fieldMsg2;
    \endcode
    \note The usage of duplicates will trigger a warning at compilation time.

    \section2 QML keywords handling
    Pay attention to the keywords that are reserved in QML or
    JavaScript context, but not reserved in *.proto context.
    Fields with names that are reserved by QML
    will be silently extended by \c _proto suffix by the
    \l {The qtprotobufgen Tool}{generator plugin}.
    For example, \c id, \c property, and \c import are reserved keywords.
    They will be replaced by \c id_proto, \c property_proto,
    \c import_proto:
    \badcode
        message MessageUpperCaseReserved {
            sint32 Import = 1;
            sint32 Property = 2;
            sint32 Id = 3;
        }
    \endcode
    Generated code output:
    \code
        Q_PROPERTY(QtProtobuf::sint32 import_proto READ import_proto ...)
        Q_PROPERTY(QtProtobuf::sint32 property_proto READ property_proto ...)
        Q_PROPERTY(QtProtobuf::sint32 id_proto READ id_proto ...)
    \endcode
    Also, enum values cannot begin with a lower case letter.
    The \l {The qtprotobufgen Tool}{generator plugin} will capitalize
    the first letter in code output. See the \c *.proto example below:
    \badcode
        enum LowerCaseEnum {
            enumValue0 = 0;
            enumValue1 = 1;
            enumValue2 = 2;
        }
    \endcode
    Generated code output:
    \code
        enum LowerCaseEnum {
            EnumValue0 = 0,
            EnumValue1 = 1,
            EnumValue2 = 2,
        };
        Q_ENUM(LowerCaseEnum)
    \endcode
    Also, enum fields cannot begin with an underscore symbol.
    Such fields will be generated as is, but will be undefined in
    the QML, unless the QML engine will allow registering
    them in the future. See the \c *.proto example below:
    \badcode
        enum UnderScoreEnum {
            _enumUnderscoreValue0 = 0;
            _EnumUnderscoreValue1 = 1;
        }
    \endcode
    Generated output:
    \code
        enum UnderScoreEnum {
            _enumUnderscoreValue0 = 0,
            _EnumUnderscoreValue1 = 1,
        };
        Q_ENUM(UnderScoreEnum)
    \endcode
    For more information about the QML properties syntax, check
    \l {Defining Property Attributes}.
*/
