The protobuf common.h header currently has a "using std::string;"
statement that pulls std::string into the google::protobuf namespace:
ce66f6047d/src/google/protobuf/stubs/common.h (L195)
I plan to delete that line soon. To keep protobuf-c working, this commit
updates the generator to fully qualify std::string.
Fixes#188.
Implements suggested fix from the issue:
The struct tag namespace is different from the type namespace. Use the
same symbol names (i.e. without leading underscores) in every namespace.
Upstream protobuf removed scoped_ptr.h, which provided the scoped_ptr
that we depended on, in commit 67952fab2c766ac5eacc15bb78e5af4039a3d398
(67952fab2c).
This commit converts uses of scoped_ptr type to idiomatic C++11
std::unique_ptr, similar to the changes in the protobuf commit.
This has been tested on protobuf 3.0.0 (the version currently in Debian)
as well as the latest protobuf 3.6.1 release.
The change in commit 712154b912de824741381c0bb26c2fbed54515a3 ("Bump
minimum required header version for proto3 syntax") uses functionality
only exposed by protobuf-3.x, breaking the build when compiling against
protobuf-2.x.
Since we still want to support building against protobuf-2.x, this
commit makes the proto3 syntax check in the file generator dependent on
building against protobuf-3.x.
The changes in #274 (proto3: make strings default to "" instead of NULL)
add a new symbol to the library and add an 'extern' declaration to the
protobuf-c header file.
Since the compiler may generate files that depend on that new
'protobuf_c_empty_string' declaration in protobuf-c.h, we need to bump
the min_header_version value that is written into generated header
files. But since the 'protobuf_c_empty_string' symbol can only be
referenced when generating proto3 syntax files, we only need to use the
stricter min_header_version value when processing a proto3 file.
The protobuf project removed "using namespace std" namespace pollution
from their stubs/common.h header file. This caused build failures for us
since we relied on their namespace pollution.
This commit updates protobuf-c to convert:
'map' → 'std::map'
'set' → 'std::set'
'back_insert_iterator' → 'std::back_insert_iterator'
The spec talks about "empty string" and other languages like C#
return a zero length string and not null.
This is useful because when moving from proto2's "required string"
to a proto3's plain string we will be guaranteed that we
never get a null pointer.
The tradeoff is adding a special case to the library but avoiding
a lot of null checks in the calling code.
The current code is already special casing "" in pack_string.
This commit fixes#251, which causes incorrect code to be generated when
there are multiple oneofs in the same message.
In #221, we added code to force int-sizing for oneof enums, but we only
set vars["opt_comma"] initially, before entering the loop over the
message's oneofs. This caused commas to be omitted when generating the
enums for subsequent oneofs after the first oneof.
This commit resets vars["opt_comma"] every time through the loop that
generates the enum declarations for the message's oneofs.
This commit fixes a problem identified in #251. When generating the
PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE directive at the end of the enum
values generated for a oneof, we inadvertently only included the
protobuf class name in the call to the directive. This breaks if there
is more than one oneof per protobuf class, which causes duplicate enum
names to be generated.
This issue is fixed by also appending the oneof's name to the protobuf
class name when generating the PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE
directive, which should cause unique enum names to be generated.
This changes the enum name that is generated, but these names are
implementation details since they are sentinel values that only exist to
force the compiler to size the enum type correctly.
(The test case for #220 is updated since that test relies on the
oneof implementation details in the code generator.)
This makes __free_unpacked() consistent with free(), and simplifies
callers by allowing them to indiscriminately free message objects
without regard to whether they have been allocated or not.
This is a first cut at adding proto3 support.
As far as I understand protobuf-c already has pretty much everything
needed once it is built using a new version of protobuf itself.
The only missing thing is that in proto3 all fields are optional and
having to manually set has_foo is inconvenient.
This patch special cases the proto3 syntax files so that structs for the
bytes, enum and primitive fields do not emit the has_ field.
It also adds PROTOBUF_C_LABEL_NONE to the label enum that is used for
proto3 fields. When a fields has this label, the quantifier is not
consulted and instead the field is packed/unpacked depending on
whether it has a value different from NULL/0.
From https://developers.google.com/protocol-buffers/docs/proto#optional:
If the default value is not specified for an optional element, a
type-specific default value is used instead: for strings, the default
value is the empty string. For bools, the default value is false. For
numeric types, the default value is zero. For enums, the default value
is the first value listed in the enum's type definition. This means care
must be taken when adding a value to the beginning of an enum value
list.
Prior to this change, protoc-c set the default enum value to 0, whether
or not 0 was the first value listed in the enum's type definition (or if
it even was listed at all).
Adds support for the LITE_RUNTIME optimization option to the protobuf-c
compiler. Enabling this option would generate lighter weight message,
enum, and service descriptors that contain NO strings. As a result,
calls to lookup descriptors via the *_get_{field,value,method}_by_name
API will return NULL.
Default compiler behavior (when optimize_for is not specified or is not
set to LITE_RUNTIME) is unchanged.
Certain protobuf comments could generate invalid C comments
and inadvertently close the comment block. This commit removes '/'
signs in such comments.
One example of a .proto file containing such comments is a commonly
included descriptor.proto from the protobuf library.
identifiers that begin with an underscore are reserved. instead, use a
double underscore in the *middle* of the identifier to indicate that
it's an "internal" identifier.
exact version coupling between the compiler and the public headers is
too strict because some existing projects (such as collectd,
riemann-c-client, and nmsg) directly embed .pb-c.h files generated by
protoc-c into their exported headers. this would cause unnecessary build
failures in downstream clients of these libraries if a newer version of
the protobuf-c headers is installed.
however, it's still desireable to be able to explicitly declare when
compatibility is broken between the headers and the compiler, so
introduce new variables that allow independently setting the minimum
header version required by the compiler and the minimum compiler version
required by the header.
this follows the protobuf C++ implementation a little bit more closely,
though we don't have an analogous facility for verifying that the header
and *library* are compatible. (this seems like overkill for a C project;
in practice the headers and the library will be from the same version,
especially in downstream distributors like debian where the -dev package
has an exact versioned dependency on the shared library package.)
this adds a version guard like the protobuf C++ implementation. it
ensures that protoc-c and <protobuf-c.h> are from the exact same version
of protobuf-c.
rename PROTOBUF_C_FIELD_FLAGS_PACKED to PROTOBUF_C_FIELD_FLAG_PACKED.
rename ProtobufCFieldFlagType to ProtobufCFieldFlag.
wrap some particular long lines.
update documentation.
for clarity, use a "uint32_t" instead of "unsigned" for the 'flags'
field in _ProtobufCFieldDescriptor.
there is some confusion with regard to the use of lower case letters in
enum values. take the following message definition:
message LowerCase {
enum CaseEnum {
UPPER = 1;
lower = 2;
}
optional CaseEnum value = 1 [default = lower];
}
this generates the following C enum:
typedef enum _LowerCase__CaseEnum {
LOWER_CASE__CASE_ENUM__UPPER = 1,
LOWER_CASE__CASE_ENUM__lower = 2
_PROTOBUF_C_FORCE_ENUM_TO_BE_INT_SIZE(LOWER_CASE__CASE_ENUM)
} LowerCase__CaseEnum;
note that the case of the enum value 'lower' was preserved in the C
symbol name as 'LOWER_CASE__CASE_ENUM__lower', but that the _INIT macro
references the same enum value with the (non-existent) C symbol name
'LOWER_CASE__CASE_ENUM__LOWER':
#define LOWER_CASE__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&lower_case__descriptor) \
, 0,LOWER_CASE__CASE_ENUM__LOWER }
additionally, the ProtobufCEnumValue array generated also refers to the
same enum value with the (non-existent) upper cased version:
const ProtobufCEnumValue lower_case__case_enum__enum_values_by_number[2] =
{
{ "UPPER", "LOWER_CASE__CASE_ENUM__UPPER", 1 },
{ "lower", "LOWER_CASE__CASE_ENUM__LOWER", 2 },
};
we should preserve the existing behavior of copying the case from the
enum values in the message definition and fix up the places where the
(non-existent) upper case version is used, rather than changing the enum
definition itself to match the case used in the _INIT macro and
enum_values_by_number array, because it's possible that there might be
existing working code that uses enum values with lower case letters that
would be affected by such a change.
incidentally, google's C++ protobuf implementation preserves case in
enum values. protoc --cpp_out generates the following enum declaration
for the message descriptor above:
enum LowerCase_CaseEnum {
LowerCase_CaseEnum_UPPER = 1,
LowerCase_CaseEnum_lower = 2
};