예제 #1
0
        protected override void GenerateClassReferenceField(messageType message, fieldType field)
        {
            var fieldType = FieldType(field);

            if (field.modifier == modifierType.repeated)
            {
                IncludeWriter.WriteLine(
                    @"        void add{1}({2}& item);
        void remove{1}({2}& item);
        std::vector<{2}*> {0}List();
        {2}& get{1}(int index);
        int {0}Count() const;
"
                    , field.name, field.name.Capitalize(), fieldType);

                CppWriter.WriteLine(
                    @"        void Abstract{4}::add{1}({3}& item)
        {{
            assert((""Can't modify an already built object!"", !isBuilt()));
            if (m_root != item.getRoot())
                throw std::runtime_error(""All objects should share the same root"");
            m_header.add_{2}()->CopyFrom(item.getLocalMessageDescriptor());
        }}

        void Abstract{4}::remove{1}({3}& item)
        {{
            assert((""Can't modify an already built object!"", !isBuilt()));
            auto vals = m_header.mutable_{2}();
            auto newEnd = std::remove_if(vals->begin(), vals->end(), [this, &item](const LocalMessageDescriptor& check) 
            {{ 
                return getRoot()->decode(check) == &item; 
            }});
            vals->DeleteSubrange(newEnd - vals->begin(), vals->end() - newEnd);
        }}

        std::vector<{3}*> Abstract{4}::{0}List()
        {{
            auto count = {0}Count();
            auto list = std::vector<{3}*>();
            list.reserve(count);
            for (auto i = 0; i < count; ++i)
            {{
                list.push_back(&get{1}(i));
            }}
            return list;
        }}

        {3}& Abstract{4}::get{1}(int index)
        {{
            return *dynamic_cast<{3}*>(getRoot()->decode(m_header.{2}(index)));
        }}

        int Abstract{4}::{0}Count() const
        {{
            return m_header.{2}_size();
        }}
"
                    , field.name, field.name.Capitalize(), field.name.ToLowerInvariant(), fieldType, message.name);
                return;
            }

            if (field.modifier == modifierType.optional)
            {
                IncludeWriter.WriteLine(
                    @"        bool has{0}() const {{ return m_header.has_{1}(); }}
        void clear{0}() {{ m_header.clear_{1}(); }}
"
                    , field.name.Capitalize(), field.name.ToLowerInvariant());
            }

            IncludeWriter.WriteLine(
                @"        void set{1}({2}& value);
        {2}* {0}();
"
                , field.name, field.name.Capitalize(), fieldType);

            CppWriter.WriteLine(
                @"        void Abstract{4}::set{1}({3}& value)
        {{
            if (m_root != value.getRoot())
                throw std::runtime_error(""All objects should share the same root"");
            m_header.clear_{2}();
            m_header.mutable_{2}()->CopyFrom(value.getLocalMessageDescriptor());
            // TODO see if that works // m_header.set_allocated_{2}(value.getLocalMessageDescriptor());
        }}

        {3}* Abstract{4}::{0}()
        {{
            return dynamic_cast<{3}*>(getRoot()->decode(m_header.{2}()));
        }}
"
                , field.name, field.name.Capitalize(), field.name.ToLowerInvariant(), fieldType, message.name);
        }
예제 #2
0
        protected override void GenerateClassNestedField(messageType message, fieldType field)
        {
            var fieldType = FieldType(field);

            if (field.modifier == modifierType.repeated)
            {
                IncludeWriter.WriteLine(
                    @"        {2}& add{1}();
        std::vector<{2}*> {0}List();
        {2}& get{1}(int index);
        int {0}Count() const;
"
                    , field.name, field.name.Capitalize(), fieldType);

                CppWriter.WriteLine(
                    @"        {3}& Abstract{4}::add{1}()
        {{
            assert((""Can't modify an already built object!"", !isBuilt()));
            auto index = m_{0}List.size();
            auto {0} = std::make_unique<{3}>();
            {0}->setFieldId({5});
            {0}->setIndex(index);
            {0}->setParent(this);
            m_{0}List.set(index, std::move({0}));
            return *m_{0}List.get(index);
        }}

        std::vector<{3}*> Abstract{4}::{0}List()
        {{
            auto count = {0}Count();
            auto list = std::vector<{3}*>();
            list.reserve(count);
            for (auto i = 0; i < count; ++i)
            {{
                list.push_back(&get{1}(i));
            }}
            return list;
        }}

        {3}& Abstract{4}::get{1}(int index)
        {{
            if (!m_{0}List.get(index))
            {{
                auto {0} = {3}::ParseFrom(contentStream(), m_header.{2}(index));
                {0}->setFieldId({5});
                {0}->setIndex(index);
                {0}->setParent(this);
                m_{0}List.set(index, std::move({0}));
            }}
            return *m_{0}List.get(index);
        }}

        int Abstract{4}::{0}Count() const
        {{
            return !isBuilt() ? m_{0}List.size() : m_header.{2}_size();
        }}"
                    , field.name, field.name.Capitalize(), field.name.ToLowerInvariant(), fieldType, message.name, field.id);
                return;
            }

            if (field.modifier == modifierType.optional)
            {
                IncludeWriter.WriteLine(
                    @"        {2}& add{1}(); // adds the optional {1}
        {2}* {0}();
        bool has{1}() const;
        void clear{1}();
        
"
                    , field.name, field.name.Capitalize(), fieldType);

                CppWriter.WriteLine(
                    @"        {3}& Abstract{4}::add{1}()
        {{
            if (m_{0} == nullptr)
            {{
                if (isBuilt() && has{1}())
                {{
                    {0}(); // decode from body
                }}
                else
                {{
                    assert((""Can't modify an already built object!"", !isBuilt()));
                    m_{0} = std::make_unique<{6}::{3}>();
                    m_{0}->setFieldId({5});
                    m_{0}->setParent(this);
                }}
            }}
            return *m_{0};
        }}

        {3}* Abstract{4}::{0}()
        {{
            if (isBuilt() && has{1}() && m_{0} == nullptr)
            {{
                m_{0} = {3}::ParseFrom(contentStream(), m_header.{2}());
                m_{0}->setFieldId({5});
                m_{0}->setParent(this);
            }}
            return m_{0}.get();
        }}

        bool Abstract{4}::has{1}() const
        {{
            return (isBuilt() && m_header.has_{2}()) || (!isBuilt() && m_{0} != nullptr);
        }}

        void Abstract{4}::clear{1}()
        {{
            assert((""Can't modify an already built object!"", !isBuilt()));
            m_{0}.reset();
        }}
"
                    , field.name, field.name.Capitalize(), field.name.ToLowerInvariant(), fieldType, message.name, field.id, Namespace);
                return;
            }

            IncludeWriter.WriteLine(@"        {1}& {0}();", field.name, fieldType);
            CppWriter.WriteLine(
                @"        {2}& Abstract{3}::{0}()
        {{
            if (m_{0} == nullptr)
            {{
                if (isBuilt())
                {{
                    m_{0} = {2}::ParseFrom(contentStream(), m_header.{1}());
                }}
                else
                {{
                    m_{0} = std::make_unique<{2}>();
                }}
                m_{0}->setFieldId({4});
                m_{0}->setParent(this);
            }}
            return *m_{0};
        }}
"
                , field.name, field.name.ToLowerInvariant(), fieldType, message.name, field.id);
        }
예제 #3
0
        protected override void GenerateClassSimpleField(messageType message, fieldType field)
        {
            var fieldTypeForList = FieldType(field);
            var fieldType        = fieldTypeForList;

            if (field.type == typeType.@string)
            {
                fieldType = "const " + fieldType + "&";
            }
            // In C++, a repeated enum is stored as a RepeatedField<int>
            var underlyingType = field.type == typeType.@enum ?
                                 "int" :
                                 fieldTypeForList;

            if (field.modifier == modifierType.repeated)
            {
                IncludeWriter.WriteLine(
                    @"        void add{1}({2} item);
        void remove{1}({2} item);
        std::vector<{3}> {0}List();
        {2} get{1}(int index);
        int {0}Count() const;
"
                    , field.name, field.name.Capitalize(), fieldType, fieldTypeForList);

                CppWriter.WriteLine(
                    @"        void Abstract{4}::add{1}({3} item)
        {{
            assert((""Can't modify an already built object!"", !isBuilt()));
            m_header.add_{2}(item);
        }}

        void Abstract{4}::remove{1}({3} item)
        {{
            assert((""Can't modify an already built object!"", !isBuilt()));
            auto vals = m_header.mutable_{2}();
            auto newEnd = std::remove_if(vals->begin(), vals->end(), [&item]({6} check) {{ return check != item; }});
            vals->Truncate(newEnd - vals->begin());
        }}

        std::vector<{5}> Abstract{4}::{0}List()
        {{
            auto count = {0}Count();
            auto list = std::vector<{3}>();
            list.reserve(count);
            for (auto i = 0; i < count; ++i)
            {{
                list.push_back(get{1}(i));
            }}
            return list;
        }}

        {3} Abstract{4}::get{1}(int index)
        {{
            return m_header.{2}(index);
        }}

        int Abstract{4}::{0}Count() const
        {{
            return m_header.{2}_size();
        }}
"
                    , field.name, field.name.Capitalize(), field.name.ToLowerInvariant(), fieldType, message.name, fieldTypeForList, underlyingType);
                return;
            }

            if (field.modifier == modifierType.optional)
            {
                IncludeWriter.WriteLine(
                    @"        bool has{0}() const {{ return m_header.has_{1}(); }}        
        void clear{0}() {{ m_header.clear_{1}(); }}
"
                    , field.name.Capitalize(), field.name.ToLowerInvariant());
            }

            IncludeWriter.WriteLine(
                @"        {3} {0}() const {{ return m_header.{2}(); }}
        void set{1}({3} value) {{ m_header.set_{2}(value); }}
"
                , field.name, field.name.Capitalize(), field.name.ToLowerInvariant(), fieldType);
        }
예제 #4
0
        protected override void GenerateClassFields(messageType message)
        {
            if (!message.IsRoot)
            {
                IncludeWriter.WriteLine(
                    @"    private: 
        ProtoOrBuilder* m_root;
        ProtoOrBuilder* m_parent;
        int m_fieldId = -1; // field's ID as defined in the protozbuf.xml file (=> the .proto file)
        int m_index = -1; // instance's index in the parent's list

    public: 
        ProtoOrBuilder* getParent() { return m_parent; }
        void setParent(ProtoOrBuilder* parent);

        int fieldId() const { return m_fieldId; }
        void setFieldId(int fieldId) { m_fieldId = fieldId; }
        int index() const { return m_index; }
        void setIndex(int index) { m_index = index; }
");

                CppWriter.WriteLine(
                    @"        void Abstract{0}::setParent(ProtoOrBuilder* parent)
        {{
            m_parent = parent;
            m_root = parent->getRoot();
        }}", message.name);
            }
            else
            {
                IncludeWriter.WriteLine(
                    @"    protected: 
        std::shared_ptr<std::iostream> m_contentStream;");
            }

            IncludeWriter.WriteLine(
                @"    protected: 
        {0}Header m_header;
        long m_positionInContent;

    public:
        int positionInContent() const {{ return m_positionInContent; }}
        void setPositionInContent(int positionInContent) {{ m_positionInContent = positionInContent; }}

    protected: "
                , message.name);

            var allFields = message.field.OrderBy(_ => _.id);

            var messageFields = from fld in allFields
                                where fld.messageType != null && fld.type != typeType.referenceMessage
                                select fld;

            foreach (var field in messageFields)
            {
                var fieldtype = FieldType(field);
                switch (field.modifier)
                {
                case modifierType.repeated:
                    IncludeWriter.WriteLine(
                        @"        {2}::ArrayList<{0}> m_{1}List;", fieldtype, field.name, ResourceNamespace);
                    break;

                default:
                    IncludeWriter.WriteLine(
                        @"        std::unique_ptr<{0}> m_{1};", fieldtype, field.name);
                    break;
                }
            }
        }
예제 #5
0
        protected override void EndAbstractClass(messageType message)
        {
            IncludeWriter.WriteLine(
                @"    };
");
        }
예제 #6
0
        internal override void GenerateToStringFormatters()
        {
            IncludeWriter.WriteLine(
                @"    class BaseFormat
    {
    public:
        int m_indentation;
        int getIndentation() const { return m_indentation; }
        void setIndentation(int indentation) { m_indentation = indentation; }

        std::string getTabulations() const { return std::string(m_indentation, '\t'); }

        void formatHeader(std::ostringstream& builder, const std::string& title)
        {
            builder << getTabulations() << title << std::endl;
            builder << getTabulations() << ""{"" << std::endl;
            m_indentation++;
        }

        void formatFooter(std::ostringstream& builder)
        {
            m_indentation--;
            builder << getTabulations() << ""}"" << std::endl;
        }
    
        template<typename T>
        void formatField(std::ostringstream& builder, const std::string& name, T&& obj, bool has = true)
        {
            if (!has) return;
            builder << getTabulations() << name << "": "";
            if (has)
                builder << obj;
            else
                builder << ""not set"";
            builder << std::endl;
        }

        void formatProtoField(std::ostringstream& builder, const std::string& name, ProtoOrBuilder& obj, bool has = true)
        {
            if (!has) return;
            formatHeader(builder, name);
            builder << (has ? obj.toString(*this) : getTabulations() + ""null"") << std::endl;
            formatFooter(builder);
        }

        void formatProtoField(std::ostringstream& builder, const std::string& name, ProtoOrBuilder* obj, bool has = true)
        {
            if (!has || obj == nullptr) return;
            formatProtoField(builder, name, * obj, has && obj != nullptr);
        }
    
        template<typename T>
        void formatListField(std::ostringstream& builder, const std::string& name, const std::vector<T>& objs)
        {
            if (objs.empty()) return;

            builder << getTabulations() << name << "": "";
            std::copy(objs.begin(), objs.end(), std::ostream_iterator<T>(builder, "", ""));
            builder << std::endl;
        }

        template<typename T>
        void formatProtoField(std::ostringstream& builder, const std::string& name, const std::vector<T*>& objs)
        {
            if (objs.empty()) return;

            builder << getTabulations() << name << "": "" << std::endl;
            for (auto* obj : objs)
            {
                builder << obj->toString(*this);
            }
            builder << std::endl;
        }
    };
");
        }
예제 #7
0
        protected override void GenerateToString(messageType message)
        {
            IncludeWriter.WriteLine(
                @"        using ProtoOrBuilder::toString;
        std::string toString(BaseFormat& format) override;
");
            CppWriter.WriteLine(
                @"        std::string Abstract{0}::toString(BaseFormat& format)
        {{
            auto bd = std::ostringstream();
", message.name);

            CppWriter.WriteLine(
                @"            format.formatHeader(bd,""{0}"");
", message.name);

            var fields = message.field.OrderBy(_ => _.id);

            foreach (var field in fields)
            {
                switch (field.modifier)
                {
                case modifierType.repeated:
                    if (field.type == typeType.referenceMessage)
                    {
                        CppWriter.WriteLine(
                            @"            format.formatField(bd, ""{1}List"", {0}Count()); 
    ", field.name, field.name.Capitalize());
                    }
                    else if (field.type == typeType.nestedMessage)
                    {
                        CppWriter.WriteLine(
                            @"            format.formatProtoField(bd, ""{1}List"", {0}List()); 
    ", field.name, field.name.Capitalize());
                    }
                    else
                    {
                        CppWriter.WriteLine(
                            @"            format.formatListField(bd, ""{1}List"", {0}List());
    ", field.name, field.name.Capitalize());
                    }
                    break;

                case modifierType.optional:
                    if (field.type == typeType.referenceMessage || field.type == typeType.nestedMessage)
                    {
                        CppWriter.WriteLine(
                            @"            format.formatProtoField(bd, ""{1}"", {0}(), has{1}());
", field.name, field.name.Capitalize());
                    }
                    else
                    {
                        CppWriter.WriteLine(
                            @"            format.formatField(bd, ""{1}"", {0}(), has{1}());
    ", field.name, field.name.Capitalize());
                    }
                    break;

                default:
                    if (field.type == typeType.referenceMessage || field.type == typeType.nestedMessage)
                    {
                        CppWriter.WriteLine(
                            @"            format.formatProtoField(bd, ""{0}"", {0}());", field.name);
                    }
                    else
                    {
                        CppWriter.WriteLine(
                            @"            format.formatField(bd, ""{0}"", {0}());", field.name);
                    }
                    break;
                }
            }

            CppWriter.WriteLine(
                @"            format.formatFooter(bd);
            return bd.str();
        }
");
        }