Unverified Commit 25174818 authored by Robert Edmonds's avatar Robert Edmonds Committed by GitHub

Merge pull request #762 from protobuf-c/edmonds/google-protobuf-30-fixes

Chase compatibility issues with Google protobuf 30.0-rc1
parents 185beed2 9a6b35e1
...@@ -102,6 +102,7 @@ protoc_gen_c_protoc_gen_c_SOURCES = \ ...@@ -102,6 +102,7 @@ protoc_gen_c_protoc_gen_c_SOURCES = \
protoc-gen-c/c_service.h \ protoc-gen-c/c_service.h \
protoc-gen-c/c_string_field.cc \ protoc-gen-c/c_string_field.cc \
protoc-gen-c/c_string_field.h \ protoc-gen-c/c_string_field.h \
protoc-gen-c/compat.h \
protobuf-c/protobuf-c.pb.cc \ protobuf-c/protobuf-c.pb.cc \
protobuf-c/protobuf-c.pb.h \ protobuf-c/protobuf-c.pb.h \
protoc-gen-c/main.cc protoc-gen-c/main.cc
......
...@@ -142,7 +142,7 @@ struct ValueIndex ...@@ -142,7 +142,7 @@ struct ValueIndex
int value; int value;
unsigned index; unsigned index;
unsigned final_index; /* index in uniqified array of values */ unsigned final_index; /* index in uniqified array of values */
const char *name; compat::StringView name;
}; };
void EnumGenerator::GenerateValueInitializer(google::protobuf::io::Printer *printer, int index) void EnumGenerator::GenerateValueInitializer(google::protobuf::io::Printer *printer, int index)
{ {
...@@ -152,7 +152,7 @@ void EnumGenerator::GenerateValueInitializer(google::protobuf::io::Printer *prin ...@@ -152,7 +152,7 @@ void EnumGenerator::GenerateValueInitializer(google::protobuf::io::Printer *prin
descriptor_->file()->options().optimize_for() == descriptor_->file()->options().optimize_for() ==
google::protobuf::FileOptions_OptimizeMode_CODE_SIZE; google::protobuf::FileOptions_OptimizeMode_CODE_SIZE;
vars["enum_value_name"] = vd->name(); vars["enum_value_name"] = vd->name();
vars["c_enum_value_name"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file()) + "__" + vd->name(); vars["c_enum_value_name"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file()) + "__" + std::string(vd->name());
vars["value"] = SimpleItoa(vd->number()); vars["value"] = SimpleItoa(vd->number());
if (optimize_code_size) if (optimize_code_size)
printer->Print(vars, " { NULL, NULL, $value$ }, /* CODE_SIZE */\n"); printer->Print(vars, " { NULL, NULL, $value$ }, /* CODE_SIZE */\n");
...@@ -176,7 +176,7 @@ static int compare_value_indices_by_name(const void *a, const void *b) ...@@ -176,7 +176,7 @@ static int compare_value_indices_by_name(const void *a, const void *b)
{ {
const ValueIndex *vi_a = (const ValueIndex *) a; const ValueIndex *vi_a = (const ValueIndex *) a;
const ValueIndex *vi_b = (const ValueIndex *) b; const ValueIndex *vi_b = (const ValueIndex *) b;
return strcmp (vi_a->name, vi_b->name); return vi_a->name.compare(vi_b->name);
} }
void EnumGenerator::GenerateEnumDescriptor(google::protobuf::io::Printer* printer) { void EnumGenerator::GenerateEnumDescriptor(google::protobuf::io::Printer* printer) {
...@@ -194,18 +194,15 @@ void EnumGenerator::GenerateEnumDescriptor(google::protobuf::io::Printer* printe ...@@ -194,18 +194,15 @@ void EnumGenerator::GenerateEnumDescriptor(google::protobuf::io::Printer* printe
// Sort by name and value, dropping duplicate values if they appear later. // Sort by name and value, dropping duplicate values if they appear later.
// TODO: use a c++ paradigm for this! // TODO: use a c++ paradigm for this!
NameIndex *name_index = new NameIndex[descriptor_->value_count()]; std::vector<ValueIndex> value_index;
ValueIndex *value_index = new ValueIndex[descriptor_->value_count()];
for (int j = 0; j < descriptor_->value_count(); j++) { for (int j = 0; j < descriptor_->value_count(); j++) {
const google::protobuf::EnumValueDescriptor *vd = descriptor_->value(j); const google::protobuf::EnumValueDescriptor *vd = descriptor_->value(j);
name_index[j].index = j; value_index.push_back({ vd->number(), (unsigned)j, 0, vd->name() });
name_index[j].name = vd->name().c_str();
value_index[j].index = j;
value_index[j].value = vd->number();
value_index[j].name = vd->name().c_str();
} }
qsort(value_index, descriptor_->value_count(), qsort(&value_index[0],
sizeof(ValueIndex), compare_value_indices_by_value_then_index); value_index.size(),
sizeof(ValueIndex),
compare_value_indices_by_value_then_index);
// only record unique values // only record unique values
int n_unique_values; int n_unique_values;
...@@ -275,8 +272,10 @@ void EnumGenerator::GenerateEnumDescriptor(google::protobuf::io::Printer* printe ...@@ -275,8 +272,10 @@ void EnumGenerator::GenerateEnumDescriptor(google::protobuf::io::Printer* printe
vars["n_ranges"] = SimpleItoa(n_ranges); vars["n_ranges"] = SimpleItoa(n_ranges);
if (!optimize_code_size) { if (!optimize_code_size) {
qsort(value_index, descriptor_->value_count(), qsort(&value_index[0],
sizeof(ValueIndex), compare_value_indices_by_name); value_index.size(),
sizeof(ValueIndex),
compare_value_indices_by_name);
printer->Print(vars, printer->Print(vars,
"static const ProtobufCEnumValueIndex $lcclassname$__enum_values_by_name[$value_count$] =\n" "static const ProtobufCEnumValueIndex $lcclassname$__enum_values_by_name[$value_count$] =\n"
"{\n"); "{\n");
...@@ -319,9 +318,6 @@ void EnumGenerator::GenerateEnumDescriptor(google::protobuf::io::Printer* printe ...@@ -319,9 +318,6 @@ void EnumGenerator::GenerateEnumDescriptor(google::protobuf::io::Printer* printe
" NULL,NULL,NULL,NULL /* reserved[1234] */\n" " NULL,NULL,NULL,NULL /* reserved[1234] */\n"
"};\n"); "};\n");
} }
delete[] value_index;
delete[] name_index;
} }
} // namespace protobuf_c } // namespace protobuf_c
...@@ -78,7 +78,7 @@ void SetEnumVariables(const google::protobuf::FieldDescriptor* descriptor, ...@@ -78,7 +78,7 @@ void SetEnumVariables(const google::protobuf::FieldDescriptor* descriptor,
(*variables)["type"] = FullNameToC(descriptor->enum_type()->full_name(), descriptor->enum_type()->file()); (*variables)["type"] = FullNameToC(descriptor->enum_type()->full_name(), descriptor->enum_type()->file());
const google::protobuf::EnumValueDescriptor* default_value = descriptor->default_value_enum(); const google::protobuf::EnumValueDescriptor* default_value = descriptor->default_value_enum();
(*variables)["default"] = FullNameToUpper(default_value->type()->full_name(), default_value->type()->file()) (*variables)["default"] = FullNameToUpper(default_value->type()->full_name(), default_value->type()->file())
+ "__" + default_value->name(); + "__" + std::string(default_value->name());
(*variables)["deprecated"] = FieldDeprecated(descriptor); (*variables)["deprecated"] = FieldDeprecated(descriptor);
} }
......
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
#include "c_message_field.h" #include "c_message_field.h"
#include "c_primitive_field.h" #include "c_primitive_field.h"
#include "c_string_field.h" #include "c_string_field.h"
#include "compat.h"
namespace protobuf_c { namespace protobuf_c {
......
This diff is collapsed.
...@@ -73,6 +73,8 @@ ...@@ -73,6 +73,8 @@
#include <protobuf-c/protobuf-c.pb.h> #include <protobuf-c/protobuf-c.pb.h>
#include "compat.h"
namespace protobuf_c { namespace protobuf_c {
// --- Borrowed from stubs. --- // --- Borrowed from stubs. ---
...@@ -84,14 +86,12 @@ template <typename T> std::string SimpleItoa(T n) { ...@@ -84,14 +86,12 @@ template <typename T> std::string SimpleItoa(T n) {
std::string SimpleFtoa(float f); std::string SimpleFtoa(float f);
std::string SimpleDtoa(double f); std::string SimpleDtoa(double f);
void SplitStringUsing(const std::string &str, const char *delim, std::vector<std::string> *out); void SplitStringUsing(compat::StringView str, const char *delim, std::vector<std::string> *out);
std::string CEscape(const std::string& src); std::string CEscape(compat::StringView src);
std::string StringReplace(const std::string& s, const std::string& oldsub, const std::string& newsub, bool replace_all); inline bool HasSuffixString(compat::StringView str, compat::StringView suffix) { return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; }
inline bool HasSuffixString(const std::string& str, const std::string& suffix) { return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; } inline std::string StripSuffixString(compat::StringView str, compat::StringView suffix) { if (HasSuffixString(str, suffix)) { return std::string(str.substr(0, str.size() - suffix.size())); } else { return std::string(str); } }
inline std::string StripSuffixString(const std::string& str, const std::string& suffix) { if (HasSuffixString(str, suffix)) { return str.substr(0, str.size() - suffix.size()); } else { return str; } }
char* FastHexToBuffer(int i, char* buffer); char* FastHexToBuffer(int i, char* buffer);
// Get the (unqualified) name that should be used for this field in C code. // Get the (unqualified) name that should be used for this field in C code.
// The name is coerced to lower-case to emulate proto1 behavior. People // The name is coerced to lower-case to emulate proto1 behavior. People
// should be using lowercase-with-underscores style for proto field names // should be using lowercase-with-underscores style for proto field names
...@@ -110,31 +110,31 @@ inline const google::protobuf::Descriptor* FieldScope(const google::protobuf::Fi ...@@ -110,31 +110,31 @@ inline const google::protobuf::Descriptor* FieldScope(const google::protobuf::Fi
// convert a CamelCase class name into an all uppercase affair // convert a CamelCase class name into an all uppercase affair
// with underscores separating words, e.g. MyClass becomes MY_CLASS. // with underscores separating words, e.g. MyClass becomes MY_CLASS.
std::string CamelToUpper(const std::string &class_name); std::string CamelToUpper(compat::StringView class_name);
std::string CamelToLower(const std::string &class_name); std::string CamelToLower(compat::StringView class_name);
// lowercased, underscored name to camel case // lowercased, underscored name to camel case
std::string ToCamel(const std::string &name); std::string ToCamel(compat::StringView name);
// lowercase the string // lowercase the string
std::string ToLower(const std::string &class_name); std::string ToLower(compat::StringView class_name);
std::string ToUpper(const std::string &class_name); std::string ToUpper(compat::StringView class_name);
// full_name() to lowercase with underscores // full_name() to lowercase with underscores
std::string FullNameToLower(const std::string &full_name, const google::protobuf::FileDescriptor *file); std::string FullNameToLower(compat::StringView full_name, const google::protobuf::FileDescriptor *file);
std::string FullNameToUpper(const std::string &full_name, const google::protobuf::FileDescriptor *file); std::string FullNameToUpper(compat::StringView full_name, const google::protobuf::FileDescriptor *file);
// full_name() to c-typename (with underscores for packages, otherwise camel case) // full_name() to c-typename (with underscores for packages, otherwise camel case)
std::string FullNameToC(const std::string &class_name, const google::protobuf::FileDescriptor *file); std::string FullNameToC(compat::StringView class_name, const google::protobuf::FileDescriptor *file);
// Splits, indents, formats, and prints comment lines // Splits, indents, formats, and prints comment lines
void PrintComment(google::protobuf::io::Printer* printer, std::string comment); void PrintComment(google::protobuf::io::Printer* printer, std::string comment);
// make a string of spaces as long as input // make a string of spaces as long as input
std::string ConvertToSpaces(const std::string &input); std::string ConvertToSpaces(compat::StringView input);
// Strips ".proto" or ".protodevel" from the end of a filename. // Strips ".proto" or ".protodevel" from the end of a filename.
std::string StripProto(const std::string& filename); std::string StripProto(compat::StringView filename);
// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.). // Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
// Note: non-built-in type names will be qualified, meaning they will start // Note: non-built-in type names will be qualified, meaning they will start
...@@ -148,23 +148,19 @@ const char* PrimitiveTypeName(google::protobuf::FieldDescriptor::CppType type); ...@@ -148,23 +148,19 @@ const char* PrimitiveTypeName(google::protobuf::FieldDescriptor::CppType type);
const char* DeclaredTypeMethodName(google::protobuf::FieldDescriptor::Type type); const char* DeclaredTypeMethodName(google::protobuf::FieldDescriptor::Type type);
// Convert a file name into a valid identifier. // Convert a file name into a valid identifier.
std::string FilenameIdentifier(const std::string& filename); std::string FilenameIdentifier(compat::StringView filename);
// Return the name of the BuildDescriptors() function for a given file.
std::string GlobalBuildDescriptorsName(const std::string& filename);
// return 'required', 'optional', or 'repeated' // return 'required', 'optional', or 'repeated'
std::string GetLabelName(google::protobuf::FieldDescriptor::Label label); std::string GetLabelName(google::protobuf::FieldDescriptor::Label label);
// write IntRanges entries for a bunch of sorted values. // write IntRanges entries for a bunch of sorted values.
// returns the number of ranges there are to bsearch. // returns the number of ranges there are to bsearch.
unsigned WriteIntRanges(google::protobuf::io::Printer* printer, int n_values, const int *values, const std::string &name); unsigned WriteIntRanges(google::protobuf::io::Printer* printer, int n_values, const int *values, compat::StringView name);
struct NameIndex struct NameIndex
{ {
unsigned index; unsigned index;
const char *name; compat::StringView name;
}; };
int compare_name_indices_by_name(const void*, const void*); int compare_name_indices_by_name(const void*, const void*);
...@@ -186,16 +182,6 @@ inline int FieldSyntax(const google::protobuf::FieldDescriptor* field) { ...@@ -186,16 +182,6 @@ inline int FieldSyntax(const google::protobuf::FieldDescriptor* field) {
return 2; return 2;
} }
// Work around changes in protobuf >= 22.x without breaking compilation against
// older protobuf versions.
#if GOOGLE_PROTOBUF_VERSION >= 4022000
# define GOOGLE_ARRAYSIZE ABSL_ARRAYSIZE
# define GOOGLE_CHECK_EQ ABSL_CHECK_EQ
# define GOOGLE_CHECK_EQ ABSL_CHECK_EQ
# define GOOGLE_DCHECK_GE ABSL_DCHECK_GE
# define GOOGLE_LOG ABSL_LOG
#endif
} // namespace protobuf_c } // namespace protobuf_c
#endif // PROTOBUF_C_PROTOC_GEN_C_C_HELPERS_H__ #endif // PROTOBUF_C_PROTOC_GEN_C_C_HELPERS_H__
This diff is collapsed.
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
#include "c_helpers.h" #include "c_helpers.h"
#include "c_primitive_field.h" #include "c_primitive_field.h"
#include "compat.h"
namespace protobuf_c { namespace protobuf_c {
......
...@@ -184,19 +184,19 @@ void ServiceGenerator::GenerateInit(google::protobuf::io::Printer* printer) ...@@ -184,19 +184,19 @@ void ServiceGenerator::GenerateInit(google::protobuf::io::Printer* printer)
"}\n"); "}\n");
} }
struct MethodIndexAndName { unsigned i; const char *name; }; struct MethodIndexAndName { unsigned i; compat::StringView name; };
static int static int
compare_method_index_and_name_by_name (const void *a, const void *b) compare_method_index_and_name_by_name (const void *a, const void *b)
{ {
const MethodIndexAndName *ma = (const MethodIndexAndName *) a; const MethodIndexAndName *ma = (const MethodIndexAndName *) a;
const MethodIndexAndName *mb = (const MethodIndexAndName *) b; const MethodIndexAndName *mb = (const MethodIndexAndName *) b;
return strcmp (ma->name, mb->name); return ma->name.compare(mb->name);
} }
void ServiceGenerator::GenerateServiceDescriptor(google::protobuf::io::Printer* printer) void ServiceGenerator::GenerateServiceDescriptor(google::protobuf::io::Printer* printer)
{ {
int n_methods = descriptor_->method_count(); int n_methods = descriptor_->method_count();
MethodIndexAndName *mi_array = new MethodIndexAndName[n_methods]; std::vector<MethodIndexAndName> mi_array;
bool optimize_code_size = descriptor_->file()->options().has_optimize_for() && bool optimize_code_size = descriptor_->file()->options().has_optimize_for() &&
descriptor_->file()->options().optimize_for() == descriptor_->file()->options().optimize_for() ==
...@@ -205,7 +205,7 @@ void ServiceGenerator::GenerateServiceDescriptor(google::protobuf::io::Printer* ...@@ -205,7 +205,7 @@ void ServiceGenerator::GenerateServiceDescriptor(google::protobuf::io::Printer*
vars_["n_methods"] = SimpleItoa(n_methods); vars_["n_methods"] = SimpleItoa(n_methods);
printer->Print(vars_, "static const ProtobufCMethodDescriptor $lcfullname$__method_descriptors[$n_methods$] =\n" printer->Print(vars_, "static const ProtobufCMethodDescriptor $lcfullname$__method_descriptors[$n_methods$] =\n"
"{\n"); "{\n");
for (int i = 0; i < n_methods; i++) { for (unsigned i = 0; i < n_methods; i++) {
const google::protobuf::MethodDescriptor* method = descriptor_->method(i); const google::protobuf::MethodDescriptor* method = descriptor_->method(i);
vars_["method"] = method->name(); vars_["method"] = method->name();
vars_["input_descriptor"] = "&" + FullNameToLower(method->input_type()->full_name(), method->input_type()->file()) + "__descriptor"; vars_["input_descriptor"] = "&" + FullNameToLower(method->input_type()->full_name(), method->input_type()->file()) + "__descriptor";
...@@ -217,14 +217,15 @@ void ServiceGenerator::GenerateServiceDescriptor(google::protobuf::io::Printer* ...@@ -217,14 +217,15 @@ void ServiceGenerator::GenerateServiceDescriptor(google::protobuf::io::Printer*
printer->Print(vars_, printer->Print(vars_,
" { \"$method$\", $input_descriptor$, $output_descriptor$ },\n"); " { \"$method$\", $input_descriptor$, $output_descriptor$ },\n");
} }
mi_array[i].i = i; mi_array.push_back({i, method->name()});
mi_array[i].name = method->name().c_str();
} }
printer->Print(vars_, "};\n"); printer->Print(vars_, "};\n");
if (!optimize_code_size) { if (!optimize_code_size) {
qsort ((void*)mi_array, n_methods, sizeof (MethodIndexAndName), qsort(&mi_array[0],
compare_method_index_and_name_by_name); mi_array.size(),
sizeof(MethodIndexAndName),
compare_method_index_and_name_by_name);
printer->Print(vars_, "const unsigned $lcfullname$__method_indices_by_name[] = {\n"); printer->Print(vars_, "const unsigned $lcfullname$__method_indices_by_name[] = {\n");
for (int i = 0; i < n_methods; i++) { for (int i = 0; i < n_methods; i++) {
vars_["i"] = SimpleItoa(mi_array[i].i); vars_["i"] = SimpleItoa(mi_array[i].i);
...@@ -258,8 +259,6 @@ void ServiceGenerator::GenerateServiceDescriptor(google::protobuf::io::Printer* ...@@ -258,8 +259,6 @@ void ServiceGenerator::GenerateServiceDescriptor(google::protobuf::io::Printer*
" $lcfullname$__method_indices_by_name\n" " $lcfullname$__method_indices_by_name\n"
"};\n"); "};\n");
} }
delete[] mi_array;
} }
void ServiceGenerator::GenerateCallersImplementations(google::protobuf::io::Printer* printer) void ServiceGenerator::GenerateCallersImplementations(google::protobuf::io::Printer* printer)
......
// Copyright (c) 2008-2025, Dave Benson and the protobuf-c authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef PROTOBUF_C_PROTOC_GEN_C_COMPAT_H__
#define PROTOBUF_C_PROTOC_GEN_C_COMPAT_H__
#if GOOGLE_PROTOBUF_VERSION >= 4022000
# define GOOGLE_ARRAYSIZE ABSL_ARRAYSIZE
# define GOOGLE_CHECK_EQ ABSL_CHECK_EQ
# define GOOGLE_DCHECK_GE ABSL_DCHECK_GE
# define GOOGLE_LOG ABSL_LOG
#endif
#if GOOGLE_PROTOBUF_VERSION >= 6030000
# include <absl/strings/string_view.h>
#else
# include <string>
#endif
namespace protobuf_c {
namespace compat {
#if GOOGLE_PROTOBUF_VERSION >= 6030000
typedef absl::string_view StringView;
#else
typedef const std::string& StringView;
#endif
} // namespace compat
} // namespace protobuf_c
#endif // PROTOBUF_C_PROTOC_GEN_C_COMPAT_H__
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "c_generator.h" #include "c_generator.h"
#include "c_helpers.h" #include "c_helpers.h"
#include "compat.h"
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
protobuf_c::CGenerator c_generator; protobuf_c::CGenerator c_generator;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment