The protobuf code generator comes with support for customizing the generated C++ code, for instance to create extra helper methods or define custom types to make it easier to use the generated classes.
Customization is managed by using protobuf options on messages, fields or other protobuf elements. The options are either specified directly in the proto file or by using a cpp.conf file in the module. The config file has several sections and each config key refers to a specific protobuf element (message, field, etc.). Using a config file is recommended when the proto file will be used externally and should not contain implementation details (such as scope services), otherwise the options can be set directly in the proto file as this is easier.
The config value is a semi-colon separated list of option names/values, ie.
<name1>: <value1>; <name2>: <value2> ...It can also span multiple lines and the last element may end in a semi-colon:
option_name = <name1>: <value1>;
<name2>: <value2>;
If you want to set a default option for a specific element type (e.g. Message or Field) then create an entry with the element name prefixed with an underscore. e.g.
_Package = my_option: my_value _Message = my_option: my_value _Field = my_option: my_value _Enum = my_option: my_value _EnumValue = my_option: my_value _Service = my_option: my_value _Command = my_option: my_value _Request = my_option: my_value _Event = my_option: my_value
Controls which helper methods are generated for a given field, available values are:
Determines the storage datatype used in the C++ code, by default it will pick a type suitable for the intended use, e.g. a scope service gets OpString and ByteBuffer.
For byte fields choose from:
For string fields choose from:
Other types such as int32, etc. does not support this option yet.
Overrides the external datatype (not storage datatype). This is the type used when passing data to setters or when returned from getters. This can be useful to map integers to existing enums or other compatible types.
This option either directly defines the C++ type to use or specifies the name of a type which is defined in a cpp.conf file. See the section below called 'Custom types' for more details.
Determines whether it should create OpMessage classes for this message. If unset it uses the options defined in the package. Use either true or false.
The prefix to use for the OpMessage classe, the default is "Op". This can also be set in the package.
The suffix to use for the OpMessage classes, the default is "Message". This can also be set in the package.
Additional defines to place around the generated code This is a comma separated list of defines, whitespace around each entry will be stripped.
For instance:
cpp_defines=API_XYZ, SELFTESTWill result in C++ code like this:
#if defined(API_XYZ) && defined(SELFTEST)
Controls how the generated OpMessage is allocated/created. Can contain one of:
Overrides the generated c++ name for the selected item. Currently only support for enums and enum values.
Determines whether it should create OpMessage classes for the top-level messages. Default is not to create them. Use either true or false. This can also be set per message.
Determines if the generated OpMessage classes are placed in an outer class or not. The outer class only act as a namespace to ensture unique class names. Use either true or false.
The prefix to use for the OpMessage classes, the default is "Op". This can also be set per message.
The suffix to use for the OpMessage classes, the default is "Message". This can also be set per message.
Name of the C++ class to use for the message set wrapper, e.g. OpHardcoreMessages If this is not specified the generator will pick a unique name that avoids any conflicts with other classes. The name uses the following syntax:
<prefix><base>_MessageSetWhere prefix is taken from cpp_prefix and base is the module name plus the name of the proto file converted to camel-case.
The prefix to use for all generated class names in this package. Defaults to Op.
Additional defines to place around the generated code. This is a comma separated list of defines, whitespace around each entry will be stripped. For instance:
cpp_defines=API_XYZ, SELFTESTWill result in C++ code like this:
#if defined(API_XYZ) && defined(SELFTEST)
Base name for the service files, use to determine include files e.g. scope_http_logger will result in an include of modules/scope/src/generated/g_scope_http_logger.h and for the non-generated header file: modules/scope/src/scope_http_logger.h. See also cpp_hfile.
Similar to cpp_file but specifies the full path to the include file of the non-generated header file only. e.g. modules/scope/src/scope_resource_manager.h. Overrides cpp_file
Name of feature that the service requires to be compiled. The name is used in an #ifdef in the generated code This option is required.
Controls whether the service is required for the entire scope module to work. Normally if a service fails to be initialized it will skip the service (except when out of memory). If this is set to true then it will exit if the service fails to initialize.
Whether the service should be instantied or not. If set to false then the service is not part of the active service list. This is mostly useful for generating the code for messages in a .proto file and accessing them from C++ code manually.
Define extra parameters for the constructor. The exact value of this option is placed in the call to Construct(). It is possible to define shared member variables using Manager.shared_fields and then pass them with this option. e.g. using "shared_id_list" will result in a call like:
service->Construct(shared_id_list);
Additional defines to place around the generated code This is a comma separated list of defines, whitespace around each entry will be stripped. For instance:
cpp_defines=API_XYZ, SELFTEST; cpp_feature=FEATURE_FOOWill result in C++ code like this:
#if defined(FEATURE_FOO) && defined(API_XYZ) && defined(SELFTEST)
Determines if a service should generate files or not. The default value is true which enables file generation. For instance to disable generation do:
cpp_generate=false;
Create a block for the service you want to override options by adding the block [<service-name>.options] and then reference the item you want to override as config entries, e.g. MyMessage.field1 would access the global message MyMessage and the field field1 and override options for it.