细算下来,接触protobuf也有5、6年了,从最开始的简单了解使用,到后来的自己翻译了相关的使用文档,最近两年因为工作方向调整,protobuf就不怎么使用了。

最近在学习Solidity,使用过程中发现protobuf的支持语言中并没有Solidity,所以决定自己实现一个Solidity的插件,一方面可以熟悉Solidity,另一方面也可以加深对protobuf的了解。

Protobuf提供了C++、C#、Dart、Go、Jave、Kotlin、Python的API供开发者实现自己的插件。

最近两年一直从事的都是Go开发,但C++作为入行时接触的第一门语言,所以最后决定还是使用C++来开发这个插件。C++的API介绍,详见这里

以下是一个简单的示例:

#include <iostream>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/descriptor.h>

class SolidityGenerator : public google::protobuf::compiler::CodeGenerator
{
public:
    bool Generate(const google::protobuf::FileDescriptor *file, const std::string &parameter,
                  google::protobuf::compiler::GeneratorContext *context, std::string *error) const
    {
        // show all messages got from protoc
        for (int i = 0; i < file->message_type_count(); ++i)
        {
            const google::protobuf::Descriptor *message = file->message_type(i);
            std::cerr << message->name() << std::endl;

            // show fields in message
            for (int j = 0; j < message->field_count(); ++j)
            {
                const google::protobuf::FieldDescriptor *field = message->field(j);
                std::cerr << "field type: " << field->type_name() << std::endl;
                std::cerr << "field name: " << field->name() << std::endl;
                std::cerr << "field nuber: " << field->number() << std::endl;
            }
        }

        return true;
    }
};

int main(int argc, char *argv[])
{
    SolidityGenerator generator;
    return google::protobuf::compiler::PluginMain(argc, argv, &generator);
}

上面的示例代码只是简单的遍历message的所有字段:包括字段的类型、名称以及序号。

为啥不用std::cout输出呢?因为插件的std::coutstd::cin被protoc占用了。


孟斯特

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意