Unverified Commit 1b6519e4 authored by Robert Edmonds's avatar Robert Edmonds Committed by GitHub

Merge pull request #466 from protobuf-c/options

protoc-c: add custom options support
parents 53004955 5ae0762b
...@@ -42,7 +42,8 @@ lib_LTLIBRARIES += \ ...@@ -42,7 +42,8 @@ lib_LTLIBRARIES += \
protobuf-c/libprotobuf-c.la protobuf-c/libprotobuf-c.la
nobase_include_HEADERS += \ nobase_include_HEADERS += \
protobuf-c/protobuf-c.h protobuf-c/protobuf-c.h \
protobuf-c/protobuf-c.proto
protobuf_c_libprotobuf_c_la_SOURCES = \ protobuf_c_libprotobuf_c_la_SOURCES = \
protobuf-c/protobuf-c.c \ protobuf-c/protobuf-c.c \
...@@ -99,6 +100,8 @@ protoc_c_protoc_gen_c_SOURCES = \ ...@@ -99,6 +100,8 @@ protoc_c_protoc_gen_c_SOURCES = \
protoc-c/c_service.h \ protoc-c/c_service.h \
protoc-c/c_string_field.cc \ protoc-c/c_string_field.cc \
protoc-c/c_string_field.h \ protoc-c/c_string_field.h \
protobuf-c/protobuf-c.pb.cc \
protobuf-c/protobuf-c.pb.h \
protoc-c/main.cc protoc-c/main.cc
protoc_c_protoc_gen_c_CXXFLAGS = \ protoc_c_protoc_gen_c_CXXFLAGS = \
$(AM_CXXFLAGS) \ $(AM_CXXFLAGS) \
...@@ -107,6 +110,12 @@ protoc_c_protoc_gen_c_LDADD = \ ...@@ -107,6 +110,12 @@ protoc_c_protoc_gen_c_LDADD = \
$(protobuf_LIBS) \ $(protobuf_LIBS) \
-lprotoc -lprotoc
protobuf-c/protobuf-c.pb.cc protobuf-c/protobuf-c.pb.h: @PROTOC@ $(top_srcdir)/protobuf-c/protobuf-c.proto
$(AM_V_GEN)@PROTOC@ -I$(top_srcdir) --cpp_out=$(top_builddir) $(top_srcdir)/protobuf-c/protobuf-c.proto
BUILT_SOURCES += \
protobuf-c/protobuf-c.pb.cc \
protobuf-c/protobuf-c.pb.h
# #
# protoc-c compat link # protoc-c compat link
# #
...@@ -155,7 +164,8 @@ noinst_PROGRAMS += \ ...@@ -155,7 +164,8 @@ noinst_PROGRAMS += \
t_generated_code2_cxx_generate_packed_data_SOURCES = \ t_generated_code2_cxx_generate_packed_data_SOURCES = \
t/generated-code2/cxx-generate-packed-data.cc \ t/generated-code2/cxx-generate-packed-data.cc \
t/test-full.pb.cc t/test-full.pb.cc \
protobuf-c/protobuf-c.pb.cc
$(t_generated_code2_cxx_generate_packed_data_OBJECTS): t/test-full.pb.h $(t_generated_code2_cxx_generate_packed_data_OBJECTS): t/test-full.pb.h
t_generated_code2_cxx_generate_packed_data_CXXFLAGS = \ t_generated_code2_cxx_generate_packed_data_CXXFLAGS = \
$(AM_CXXFLAGS) \ $(AM_CXXFLAGS) \
...@@ -216,6 +226,23 @@ t_version_version_SOURCES = \ ...@@ -216,6 +226,23 @@ t_version_version_SOURCES = \
t_version_version_LDADD = \ t_version_version_LDADD = \
protobuf-c/libprotobuf-c.la protobuf-c/libprotobuf-c.la
# Issue #204
check_PROGRAMS += \
t/issue204/issue204
TESTS += \
t/issue204/issue204
t_issue204_issue204_SOURCES = \
t/issue204/issue204.c \
t/issue204/issue204.pb-c.c
t_issue204_issue204_LDADD = \
protobuf-c/libprotobuf-c.la
t/issue204/issue204.pb-c.c t/issue204/issue204.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/issue204/issue204.proto
$(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/issue204/issue204.proto
BUILT_SOURCES += \
t/issue204/issue204.pb-c.c t/issue204/issue204.pb-c.h
EXTRA_DIST += \
t/issue204/issue204.proto
# Issue #220 # Issue #220
check_PROGRAMS += \ check_PROGRAMS += \
t/issue220/issue220 t/issue220/issue220
......
...@@ -91,8 +91,11 @@ IF(BUILD_PROTOC) ...@@ -91,8 +91,11 @@ IF(BUILD_PROTOC)
SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON) SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_CXX_EXTENSIONS OFF) SET(CMAKE_CXX_EXTENSIONS OFF)
ADD_CUSTOM_COMMAND(OUTPUT protobuf-c/protobuf-c.pb.cc protobuf-c/protobuf-c.pb.h
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --cpp_out ${CMAKE_BINARY_DIR} -I${MAIN_DIR} ${MAIN_DIR}/protobuf-c/protobuf-c.proto)
FILE(GLOB PROTOC_GEN_C_SRC ${MAIN_DIR}/protoc-c/*.h ${MAIN_DIR}/protoc-c/*.cc ) FILE(GLOB PROTOC_GEN_C_SRC ${MAIN_DIR}/protoc-c/*.h ${MAIN_DIR}/protoc-c/*.cc )
ADD_EXECUTABLE(protoc-gen-c ${PROTOC_GEN_C_SRC}) ADD_EXECUTABLE(protoc-gen-c ${PROTOC_GEN_C_SRC} protobuf-c/protobuf-c.pb.cc protobuf-c/protobuf-c.pb.h)
TARGET_LINK_LIBRARIES(protoc-gen-c ${PROTOBUF_PROTOC_LIBRARY} ${PROTOBUF_LIBRARY}) TARGET_LINK_LIBRARIES(protoc-gen-c ${PROTOBUF_PROTOC_LIBRARY} ${PROTOBUF_LIBRARY})
...@@ -132,7 +135,7 @@ ADD_CUSTOM_COMMAND(OUTPUT t/test-full.pb.cc t/test-full.pb.h ...@@ -132,7 +135,7 @@ ADD_CUSTOM_COMMAND(OUTPUT t/test-full.pb.cc t/test-full.pb.h
GENERATE_TEST_SOURCES(${TEST_DIR}/test-full.proto t/test-full.pb-c.c t/test-full.pb-c.h) GENERATE_TEST_SOURCES(${TEST_DIR}/test-full.proto t/test-full.pb-c.c t/test-full.pb-c.h)
ADD_EXECUTABLE(cxx-generate-packed-data ${TEST_DIR}/generated-code2/cxx-generate-packed-data.cc t/test-full.pb.h t/test-full.pb.cc) ADD_EXECUTABLE(cxx-generate-packed-data ${TEST_DIR}/generated-code2/cxx-generate-packed-data.cc t/test-full.pb.h t/test-full.pb.cc protobuf-c/protobuf-c.pb.cc protobuf-c/protobuf-c.pb.h)
TARGET_LINK_LIBRARIES(cxx-generate-packed-data ${PROTOBUF_LIBRARY}) TARGET_LINK_LIBRARIES(cxx-generate-packed-data ${PROTOBUF_LIBRARY})
IF (MSVC AND BUILD_SHARED_LIBS) IF (MSVC AND BUILD_SHARED_LIBS)
TARGET_COMPILE_DEFINITIONS(cxx-generate-packed-data PRIVATE -DPROTOBUF_USE_DLLS) TARGET_COMPILE_DEFINITIONS(cxx-generate-packed-data PRIVATE -DPROTOBUF_USE_DLLS)
...@@ -182,7 +185,7 @@ INSTALL(TARGETS protoc-gen-c RUNTIME DESTINATION bin) ...@@ -182,7 +185,7 @@ INSTALL(TARGETS protoc-gen-c RUNTIME DESTINATION bin)
ENDIF() # BUILD_PROTOC ENDIF() # BUILD_PROTOC
INSTALL(TARGETS protobuf-c LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin) INSTALL(TARGETS protobuf-c LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin)
INSTALL(FILES ${MAIN_DIR}/protobuf-c/protobuf-c.h DESTINATION include/protobuf-c) INSTALL(FILES ${MAIN_DIR}/protobuf-c/protobuf-c.h ${MAIN_DIR}/protobuf-c/protobuf-c.proto DESTINATION include/protobuf-c)
INSTALL(FILES ${MAIN_DIR}/protobuf-c/protobuf-c.h DESTINATION include) INSTALL(FILES ${MAIN_DIR}/protobuf-c/protobuf-c.h DESTINATION include)
INSTALL(FILES ${CMAKE_BINARY_DIR}/protobuf-c.pdb DESTINATION lib OPTIONAL) INSTALL(FILES ${CMAKE_BINARY_DIR}/protobuf-c.pdb DESTINATION lib OPTIONAL)
......
/*
* Copyright (c) 2021, 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.
*/
syntax = "proto2";
import "google/protobuf/descriptor.proto";
// We never need to generate protobuf-c.pb-c.{c,h}, the options are used
// only by protoc-gen-c, never by the protobuf-c runtime itself
option (pb_c_file).no_generate = true;
message ProtobufCFileOptions {
// Suppresses pb-c.{c,h} file output completely.
optional bool no_generate = 1 [default = false];
// Generate helper pack/unpack functions?
// For backwards compatibility, if this field is not explicitly set,
// only top-level message pack/unpack functions will be generated
optional bool gen_pack_helpers = 2 [default = true];
// Generate helper init message functions?
optional bool gen_init_helpers = 3 [default = true];
// Use const char * instead of char * for string fields
optional bool const_strings = 4 [default = false];
// For oneof fields, set ProtobufCFieldDescriptor name field to the
// name of the containing oneof, instead of the field name
optional bool use_oneof_field_name = 5 [default = false];
// Overrides the package name, if present
optional string c_package = 6;
}
extend google.protobuf.FileOptions {
optional ProtobufCFileOptions pb_c_file = 1019;
}
message ProtobufCMessageOptions {
// Overrides the parent setting only if present
optional bool gen_pack_helpers = 1 [default = false];
// Overrides the parent setting only if present
optional bool gen_init_helpers = 2 [default = true];
// Reserved base message field name
optional string base_field_name = 3 [default = "base"];
}
extend google.protobuf.MessageOptions {
optional ProtobufCMessageOptions pb_c_msg = 1019;
}
message ProtobufCFieldOptions {
// Treat string as bytes in generated code
optional bool string_as_bytes = 1 [default = false];
}
extend google.protobuf.FieldOptions {
optional ProtobufCFieldOptions pb_c_field = 1019;
}
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
#include <protoc-c/c_helpers.h> #include <protoc-c/c_helpers.h>
#include <google/protobuf/io/printer.h> #include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h> #include <google/protobuf/wire_format.h>
#include <google/protobuf/descriptor.pb.h> #include <protobuf-c/protobuf-c.pb.h>
namespace google { namespace google {
namespace protobuf { namespace protobuf {
...@@ -114,7 +114,7 @@ void BytesFieldGenerator::GenerateStructMembers(io::Printer* printer) const ...@@ -114,7 +114,7 @@ void BytesFieldGenerator::GenerateStructMembers(io::Printer* printer) const
void BytesFieldGenerator::GenerateDefaultValueDeclarations(io::Printer* printer) const void BytesFieldGenerator::GenerateDefaultValueDeclarations(io::Printer* printer) const
{ {
std::map<std::string, std::string> vars; std::map<std::string, std::string> vars;
vars["default_value_data"] = FullNameToLower(descriptor_->full_name()) vars["default_value_data"] = FullNameToLower(descriptor_->full_name(), descriptor_->file())
+ "__default_value_data"; + "__default_value_data";
printer->Print(vars, "extern uint8_t $default_value_data$[];\n"); printer->Print(vars, "extern uint8_t $default_value_data$[];\n");
} }
...@@ -122,7 +122,7 @@ void BytesFieldGenerator::GenerateDefaultValueDeclarations(io::Printer* printer) ...@@ -122,7 +122,7 @@ void BytesFieldGenerator::GenerateDefaultValueDeclarations(io::Printer* printer)
void BytesFieldGenerator::GenerateDefaultValueImplementations(io::Printer* printer) const void BytesFieldGenerator::GenerateDefaultValueImplementations(io::Printer* printer) const
{ {
std::map<std::string, std::string> vars; std::map<std::string, std::string> vars;
vars["default_value_data"] = FullNameToLower(descriptor_->full_name()) vars["default_value_data"] = FullNameToLower(descriptor_->full_name(), descriptor_->file())
+ "__default_value_data"; + "__default_value_data";
vars["escaped"] = CEscape(descriptor_->default_value_string()); vars["escaped"] = CEscape(descriptor_->default_value_string());
printer->Print(vars, "uint8_t $default_value_data$[] = \"$escaped$\";\n"); printer->Print(vars, "uint8_t $default_value_data$[] = \"$escaped$\";\n");
...@@ -132,7 +132,7 @@ std::string BytesFieldGenerator::GetDefaultValue(void) const ...@@ -132,7 +132,7 @@ std::string BytesFieldGenerator::GetDefaultValue(void) const
return "{ " return "{ "
+ SimpleItoa(descriptor_->default_value_string().size()) + SimpleItoa(descriptor_->default_value_string().size())
+ ", " + ", "
+ FullNameToLower(descriptor_->full_name()) + FullNameToLower(descriptor_->full_name(), descriptor_->file())
+ "__default_value_data }"; + "__default_value_data }";
} }
void BytesFieldGenerator::GenerateStaticInit(io::Printer* printer) const void BytesFieldGenerator::GenerateStaticInit(io::Printer* printer) const
......
...@@ -82,9 +82,9 @@ EnumGenerator::~EnumGenerator() {} ...@@ -82,9 +82,9 @@ EnumGenerator::~EnumGenerator() {}
void EnumGenerator::GenerateDefinition(io::Printer* printer) { void EnumGenerator::GenerateDefinition(io::Printer* printer) {
std::map<std::string, std::string> vars; std::map<std::string, std::string> vars;
vars["classname"] = FullNameToC(descriptor_->full_name()); vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["shortname"] = descriptor_->name(); vars["shortname"] = descriptor_->name();
vars["uc_name"] = FullNameToUpper(descriptor_->full_name()); vars["uc_name"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file());
SourceLocation sourceLoc; SourceLocation sourceLoc;
descriptor_->GetSourceLocation(&sourceLoc); descriptor_->GetSourceLocation(&sourceLoc);
...@@ -98,7 +98,7 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) { ...@@ -98,7 +98,7 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
vars["opt_comma"] = ","; vars["opt_comma"] = ",";
vars["prefix"] = FullNameToUpper(descriptor_->full_name()) + "__"; vars["prefix"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file()) + "__";
for (int i = 0; i < descriptor_->value_count(); i++) { for (int i = 0; i < descriptor_->value_count(); i++) {
vars["name"] = descriptor_->value(i)->name(); vars["name"] = descriptor_->value(i)->name();
vars["number"] = SimpleItoa(descriptor_->value(i)->number()); vars["number"] = SimpleItoa(descriptor_->value(i)->number());
...@@ -132,8 +132,8 @@ void EnumGenerator::GenerateDescriptorDeclarations(io::Printer* printer) { ...@@ -132,8 +132,8 @@ void EnumGenerator::GenerateDescriptorDeclarations(io::Printer* printer) {
} else { } else {
vars["dllexport"] = dllexport_decl_ + " "; vars["dllexport"] = dllexport_decl_ + " ";
} }
vars["classname"] = FullNameToC(descriptor_->full_name()); vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name()); vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
printer->Print(vars, printer->Print(vars,
"extern $dllexport$const ProtobufCEnumDescriptor $lcclassname$__descriptor;\n"); "extern $dllexport$const ProtobufCEnumDescriptor $lcclassname$__descriptor;\n");
...@@ -154,7 +154,7 @@ void EnumGenerator::GenerateValueInitializer(io::Printer *printer, int index) ...@@ -154,7 +154,7 @@ void EnumGenerator::GenerateValueInitializer(io::Printer *printer, int index)
descriptor_->file()->options().optimize_for() == descriptor_->file()->options().optimize_for() ==
FileOptions_OptimizeMode_CODE_SIZE; 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()) + "__" + vd->name(); vars["c_enum_value_name"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file()) + "__" + 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");
...@@ -184,8 +184,8 @@ static int compare_value_indices_by_name(const void *a, const void *b) ...@@ -184,8 +184,8 @@ static int compare_value_indices_by_name(const void *a, const void *b)
void EnumGenerator::GenerateEnumDescriptor(io::Printer* printer) { void EnumGenerator::GenerateEnumDescriptor(io::Printer* printer) {
std::map<std::string, std::string> vars; std::map<std::string, std::string> vars;
vars["fullname"] = descriptor_->full_name(); vars["fullname"] = descriptor_->full_name();
vars["lcclassname"] = FullNameToLower(descriptor_->full_name()); vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars["cname"] = FullNameToC(descriptor_->full_name()); vars["cname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["shortname"] = descriptor_->name(); vars["shortname"] = descriptor_->name();
vars["packagename"] = descriptor_->file()->package(); vars["packagename"] = descriptor_->file()->package();
vars["value_count"] = SimpleItoa(descriptor_->value_count()); vars["value_count"] = SimpleItoa(descriptor_->value_count());
......
...@@ -78,9 +78,9 @@ void SetEnumVariables(const FieldDescriptor* descriptor, ...@@ -78,9 +78,9 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
std::map<std::string, std::string>* variables) { std::map<std::string, std::string>* variables) {
(*variables)["name"] = FieldName(descriptor); (*variables)["name"] = FieldName(descriptor);
(*variables)["type"] = FullNameToC(descriptor->enum_type()->full_name()); (*variables)["type"] = FullNameToC(descriptor->enum_type()->full_name(), descriptor->enum_type()->file());
const EnumValueDescriptor* default_value = descriptor->default_value_enum(); const EnumValueDescriptor* default_value = descriptor->default_value_enum();
(*variables)["default"] = FullNameToUpper(default_value->type()->full_name()) (*variables)["default"] = FullNameToUpper(default_value->type()->full_name(), default_value->type()->file())
+ "__" + default_value->name(); + "__" + default_value->name();
(*variables)["deprecated"] = FieldDeprecated(descriptor); (*variables)["deprecated"] = FieldDeprecated(descriptor);
} }
...@@ -138,7 +138,7 @@ void EnumFieldGenerator::GenerateStaticInit(io::Printer* printer) const ...@@ -138,7 +138,7 @@ void EnumFieldGenerator::GenerateStaticInit(io::Printer* printer) const
void EnumFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const void EnumFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{ {
std::string addr = "&" + FullNameToLower(descriptor_->enum_type()->full_name()) + "__descriptor"; std::string addr = "&" + FullNameToLower(descriptor_->enum_type()->full_name(), descriptor_->enum_type()->file()) + "__descriptor";
GenerateDescriptorInitializerGeneric(printer, true, "ENUM", addr); GenerateDescriptorInitializerGeneric(printer, true, "ENUM", addr);
} }
......
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
#include <protoc-c/c_enum_field.h> #include <protoc-c/c_enum_field.h>
#include <protoc-c/c_message_field.h> #include <protoc-c/c_message_field.h>
#include <protoc-c/c_helpers.h> #include <protoc-c/c_helpers.h>
#include <google/protobuf/descriptor.pb.h> #include <protobuf-c/protobuf-c.pb.h>
#include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/printer.h> #include <google/protobuf/io/printer.h>
...@@ -107,15 +107,19 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer, ...@@ -107,15 +107,19 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
const std::string &descriptor_addr) const const std::string &descriptor_addr) const
{ {
std::map<std::string, std::string> variables; std::map<std::string, std::string> variables;
const OneofDescriptor *oneof = descriptor_->containing_oneof();
const ProtobufCFileOptions opt = descriptor_->file()->options().GetExtension(pb_c_file);
variables["TYPE"] = type_macro; variables["TYPE"] = type_macro;
variables["classname"] = FullNameToC(FieldScope(descriptor_)->full_name()); variables["classname"] = FullNameToC(FieldScope(descriptor_)->full_name(), FieldScope(descriptor_)->file());
variables["name"] = FieldName(descriptor_); variables["name"] = FieldName(descriptor_);
variables["proto_name"] = descriptor_->name(); if (opt.use_oneof_field_name())
variables["proto_name"] = oneof->name();
else
variables["proto_name"] = descriptor_->name();
variables["descriptor_addr"] = descriptor_addr; variables["descriptor_addr"] = descriptor_addr;
variables["value"] = SimpleItoa(descriptor_->number()); variables["value"] = SimpleItoa(descriptor_->number());
const OneofDescriptor *oneof = descriptor_->containing_oneof();
if (oneof != NULL) if (oneof != NULL)
variables["oneofname"] = FullNameToLower(oneof->name()); variables["oneofname"] = CamelToLower(oneof->name());
if (FieldSyntax(descriptor_) == 3 && if (FieldSyntax(descriptor_) == 3 &&
descriptor_->label() == FieldDescriptor::LABEL_OPTIONAL) { descriptor_->label() == FieldDescriptor::LABEL_OPTIONAL) {
...@@ -127,7 +131,7 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer, ...@@ -127,7 +131,7 @@ void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
if (descriptor_->has_default_value()) { if (descriptor_->has_default_value()) {
variables["default_value"] = std::string("&") variables["default_value"] = std::string("&")
+ FullNameToLower(descriptor_->full_name()) + FullNameToLower(descriptor_->full_name(), descriptor_->file())
+ "__default_value"; + "__default_value";
} else if (FieldSyntax(descriptor_) == 3 && } else if (FieldSyntax(descriptor_) == 3 &&
descriptor_->type() == FieldDescriptor::TYPE_STRING) { descriptor_->type() == FieldDescriptor::TYPE_STRING) {
...@@ -203,11 +207,15 @@ FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) ...@@ -203,11 +207,15 @@ FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
} }
FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) { FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) {
const ProtobufCFieldOptions opt = field->options().GetExtension(pb_c_field);
switch (field->type()) { switch (field->type()) {
case FieldDescriptor::TYPE_MESSAGE: case FieldDescriptor::TYPE_MESSAGE:
return new MessageFieldGenerator(field); return new MessageFieldGenerator(field);
case FieldDescriptor::TYPE_STRING: case FieldDescriptor::TYPE_STRING:
return new StringFieldGenerator(field); if (opt.string_as_bytes())
return new BytesFieldGenerator(field);
else
return new StringFieldGenerator(field);
case FieldDescriptor::TYPE_BYTES: case FieldDescriptor::TYPE_BYTES:
return new BytesFieldGenerator(field); return new BytesFieldGenerator(field);
case FieldDescriptor::TYPE_ENUM: case FieldDescriptor::TYPE_ENUM:
......
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
#include <protoc-c/c_helpers.h> #include <protoc-c/c_helpers.h>
#include <protoc-c/c_message.h> #include <protoc-c/c_message.h>
#include <google/protobuf/io/printer.h> #include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.pb.h> #include <protobuf-c/protobuf-c.pb.h>
#include "protobuf-c.h" #include "protobuf-c.h"
...@@ -110,8 +110,6 @@ FileGenerator::FileGenerator(const FileDescriptor* file, ...@@ -110,8 +110,6 @@ FileGenerator::FileGenerator(const FileDescriptor* file,
extension_generators_[i].reset( extension_generators_[i].reset(
new ExtensionGenerator(file->extension(i), dllexport_decl)); new ExtensionGenerator(file->extension(i), dllexport_decl));
} }
SplitStringUsing(file_->package(), ".", &package_parts_);
} }
FileGenerator::~FileGenerator() {} FileGenerator::~FileGenerator() {}
...@@ -157,9 +155,13 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { ...@@ -157,9 +155,13 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
"protoc_version", SimpleItoa(PROTOBUF_C_VERSION_NUMBER)); "protoc_version", SimpleItoa(PROTOBUF_C_VERSION_NUMBER));
for (int i = 0; i < file_->dependency_count(); i++) { for (int i = 0; i < file_->dependency_count(); i++) {
printer->Print( const ProtobufCFileOptions opt =
"#include \"$dependency$.pb-c.h\"\n", file_->dependency(i)->options().GetExtension(pb_c_file);
"dependency", StripProto(file_->dependency(i)->name())); if (!opt.no_generate()) {
printer->Print(
"#include \"$dependency$.pb-c.h\"\n",
"dependency", StripProto(file_->dependency(i)->name()));
}
} }
printer->Print("\n"); printer->Print("\n");
...@@ -187,7 +189,13 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { ...@@ -187,7 +189,13 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
} }
for (int i = 0; i < file_->message_type_count(); i++) { for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->GenerateHelperFunctionDeclarations(printer, false); const ProtobufCFileOptions opt = file_->options().GetExtension(pb_c_file);
message_generators_[i]->GenerateHelperFunctionDeclarations(
printer,
opt.has_gen_pack_helpers(),
opt.gen_pack_helpers(),
opt.gen_init_helpers());
} }
printer->Print("/* --- per-message closures --- */\n\n"); printer->Print("/* --- per-message closures --- */\n\n");
...@@ -238,34 +246,18 @@ void FileGenerator::GenerateSource(io::Printer* printer) { ...@@ -238,34 +246,18 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
"filename", file_->name(), "filename", file_->name(),
"basename", StripProto(file_->name())); "basename", StripProto(file_->name()));
#if 0 const ProtobufCFileOptions opt = file_->options().GetExtension(pb_c_file);
// For each dependency, write a prototype for that dependency's
// BuildDescriptors() function. We don't expose these in the header because
// they are internal implementation details, and since this is generated code
// we don't have the usual risks involved with declaring external functions
// within a .cc file.
for (int i = 0; i < file_->dependency_count(); i++) {
const FileDescriptor* dependency = file_->dependency(i);
// Open the dependency's namespace.
vector<string> dependency_package_parts;
SplitStringUsing(dependency->package(), ".", &dependency_package_parts);
// Declare its BuildDescriptors() function.
printer->Print(
"void $function$();",
"function", GlobalBuildDescriptorsName(dependency->name()));
// Close the namespace.
for (int i = 0; i < dependency_package_parts.size(); i++) {
printer->Print(" }");
}
printer->Print("\n");
}
#endif
for (int i = 0; i < file_->message_type_count(); i++) { for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->GenerateHelperFunctionDefinitions(printer, false); message_generators_[i]->GenerateHelperFunctionDefinitions(
printer,
opt.has_gen_pack_helpers(),
opt.gen_pack_helpers(),
opt.gen_init_helpers());
} }
for (int i = 0; i < file_->message_type_count(); i++) { for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->GenerateMessageDescriptor(printer); message_generators_[i]->GenerateMessageDescriptor(printer,
opt.gen_init_helpers());
} }
for (int i = 0; i < file_->enum_type_count(); i++) { for (int i = 0; i < file_->enum_type_count(); i++) {
enum_generators_[i]->GenerateEnumDescriptor(printer); enum_generators_[i]->GenerateEnumDescriptor(printer);
......
...@@ -104,9 +104,6 @@ class FileGenerator { ...@@ -104,9 +104,6 @@ class FileGenerator {
std::unique_ptr<std::unique_ptr<ServiceGenerator>[]> service_generators_; std::unique_ptr<std::unique_ptr<ServiceGenerator>[]> service_generators_;
std::unique_ptr<std::unique_ptr<ExtensionGenerator>[]> extension_generators_; std::unique_ptr<std::unique_ptr<ExtensionGenerator>[]> extension_generators_;
// E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}.
std::vector<std::string> package_parts_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
}; };
......
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
#include <protoc-c/c_helpers.h> #include <protoc-c/c_helpers.h>
#include <google/protobuf/io/printer.h> #include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor.pb.h> #include <protobuf-c/protobuf-c.pb.h>
namespace google { namespace google {
namespace protobuf { namespace protobuf {
...@@ -106,6 +106,9 @@ bool CGenerator::Generate(const FileDescriptor* file, ...@@ -106,6 +106,9 @@ bool CGenerator::Generate(const FileDescriptor* file,
const std::string& parameter, const std::string& parameter,
OutputDirectory* output_directory, OutputDirectory* output_directory,
std::string* error) const { std::string* error) const {
if (file->options().GetExtension(pb_c_file).no_generate())
return true;
std::vector<std::pair<std::string, std::string> > options; std::vector<std::pair<std::string, std::string> > options;
ParseOptions(parameter, &options); ParseOptions(parameter, &options);
......
...@@ -177,9 +177,23 @@ std::string ToCamel(const std::string &name) { ...@@ -177,9 +177,23 @@ std::string ToCamel(const std::string &name) {
return rv; return rv;
} }
std::string FullNameToLower(const std::string &full_name) { std::string OverrideFullName(const std::string &full_name,
const FileDescriptor *file) {
const ProtobufCFileOptions opt = file->options().GetExtension(pb_c_file);
if (!opt.has_c_package())
return full_name;
std::string new_name = opt.c_package();
if (file->package().empty())
new_name += ".";
return new_name + full_name.substr(file->package().length());
}
std::string FullNameToLower(const std::string &full_name,
const FileDescriptor *file) {
std::vector<std::string> pieces; std::vector<std::string> pieces;
SplitStringUsing(full_name, ".", &pieces); SplitStringUsing(OverrideFullName(full_name, file), ".", &pieces);
std::string rv = ""; std::string rv = "";
for (unsigned i = 0; i < pieces.size(); i++) { for (unsigned i = 0; i < pieces.size(); i++) {
if (pieces[i] == "") continue; if (pieces[i] == "") continue;
...@@ -188,9 +202,10 @@ std::string FullNameToLower(const std::string &full_name) { ...@@ -188,9 +202,10 @@ std::string FullNameToLower(const std::string &full_name) {
} }
return rv; return rv;
} }
std::string FullNameToUpper(const std::string &full_name) { std::string FullNameToUpper(const std::string &full_name,
const FileDescriptor *file) {
std::vector<std::string> pieces; std::vector<std::string> pieces;
SplitStringUsing(full_name, ".", &pieces); SplitStringUsing(OverrideFullName(full_name, file), ".", &pieces);
std::string rv = ""; std::string rv = "";
for (unsigned i = 0; i < pieces.size(); i++) { for (unsigned i = 0; i < pieces.size(); i++) {
if (pieces[i] == "") continue; if (pieces[i] == "") continue;
...@@ -199,9 +214,10 @@ std::string FullNameToUpper(const std::string &full_name) { ...@@ -199,9 +214,10 @@ std::string FullNameToUpper(const std::string &full_name) {
} }
return rv; return rv;
} }
std::string FullNameToC(const std::string &full_name) { std::string FullNameToC(const std::string &full_name,
const FileDescriptor *file) {
std::vector<std::string> pieces; std::vector<std::string> pieces;
SplitStringUsing(full_name, ".", &pieces); SplitStringUsing(OverrideFullName(full_name, file), ".", &pieces);
std::string rv = ""; std::string rv = "";
for (unsigned i = 0; i < pieces.size(); i++) { for (unsigned i = 0; i < pieces.size(); i++) {
if (pieces[i] == "") continue; if (pieces[i] == "") continue;
...@@ -278,37 +294,6 @@ std::set<std::string> MakeKeywordsMap() { ...@@ -278,37 +294,6 @@ std::set<std::string> MakeKeywordsMap() {
std::set<std::string> kKeywords = MakeKeywordsMap(); std::set<std::string> kKeywords = MakeKeywordsMap();
std::string ClassName(const Descriptor* descriptor, bool qualified) {
// Find "outer", the descriptor of the top-level message in which
// "descriptor" is embedded.
const Descriptor* outer = descriptor;
while (outer->containing_type() != NULL) outer = outer->containing_type();
const std::string& outer_name = outer->full_name();
std::string inner_name = descriptor->full_name().substr(outer_name.size());
if (qualified) {
return "::" + DotsToColons(outer_name) + DotsToUnderscores(inner_name);
} else {
return outer->name() + DotsToUnderscores(inner_name);
}
}
std::string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) {
if (enum_descriptor->containing_type() == NULL) {
if (qualified) {
return DotsToColons(enum_descriptor->full_name());
} else {
return enum_descriptor->name();
}
} else {
std::string result = ClassName(enum_descriptor->containing_type(), qualified);
result += '_';
result += enum_descriptor->name();
return result;
}
}
std::string FieldName(const FieldDescriptor* field) { std::string FieldName(const FieldDescriptor* field) {
std::string result = ToLower(field->name()); std::string result = ToLower(field->name());
if (kKeywords.count(result) > 0) { if (kKeywords.count(result) > 0) {
......
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
#include <vector> #include <vector>
#include <sstream> #include <sstream>
#include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h> #include <protobuf-c/protobuf-c.pb.h>
#include <google/protobuf/io/printer.h> #include <google/protobuf/io/printer.h>
namespace google { namespace google {
...@@ -75,17 +75,6 @@ namespace protobuf { ...@@ -75,17 +75,6 @@ namespace protobuf {
namespace compiler { namespace compiler {
namespace c { namespace c {
// Returns the non-nested type name for the given type. If "qualified" is
// true, prefix the type with the full namespace. For example, if you had:
// package foo.bar;
// message Baz { message Qux {} }
// Then the qualified ClassName for Qux would be:
// Foo__Bar__Baz_Qux
// While the non-qualified version would be:
// Baz_Qux
std::string ClassName(const Descriptor* descriptor, bool qualified);
std::string ClassName(const EnumDescriptor* enum_descriptor, bool qualified);
// --- Borrowed from stubs. --- // --- Borrowed from stubs. ---
template <typename T> std::string SimpleItoa(T n) { template <typename T> std::string SimpleItoa(T n) {
std::stringstream stream; std::stringstream stream;
...@@ -132,11 +121,11 @@ std::string ToLower(const std::string &class_name); ...@@ -132,11 +121,11 @@ std::string ToLower(const std::string &class_name);
std::string ToUpper(const std::string &class_name); std::string ToUpper(const std::string &class_name);
// full_name() to lowercase with underscores // full_name() to lowercase with underscores
std::string FullNameToLower(const std::string &full_name); std::string FullNameToLower(const std::string &full_name, const FileDescriptor *file);
std::string FullNameToUpper(const std::string &full_name); std::string FullNameToUpper(const std::string &full_name, const 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); std::string FullNameToC(const std::string &class_name, const FileDescriptor *file);
// Splits, indents, formats, and prints comment lines // Splits, indents, formats, and prints comment lines
void PrintComment (io::Printer* printer, std::string comment); void PrintComment (io::Printer* printer, std::string comment);
......
This diff is collapsed.
...@@ -111,14 +111,20 @@ class MessageGenerator { ...@@ -111,14 +111,20 @@ class MessageGenerator {
void GenerateStructStaticInitMacro(io::Printer* printer); void GenerateStructStaticInitMacro(io::Printer* printer);
// Generate standard helper functions declarations for this message. // Generate standard helper functions declarations for this message.
void GenerateHelperFunctionDeclarations(io::Printer* printer, bool is_submessage); void GenerateHelperFunctionDeclarations(io::Printer* printer,
bool is_pack_deep,
bool gen_pack,
bool gen_init);
// Source file stuff. // Source file stuff.
// Generate code that initializes the global variable storing the message's // Generate code that initializes the global variable storing the message's
// descriptor. // descriptor.
void GenerateMessageDescriptor(io::Printer* printer); void GenerateMessageDescriptor(io::Printer* printer, bool gen_init);
void GenerateHelperFunctionDefinitions(io::Printer* printer, bool is_submessage); void GenerateHelperFunctionDefinitions(io::Printer* printer,
bool is_pack_deep,
bool gen_pack,
bool gen_init);
private: private:
......
...@@ -85,7 +85,7 @@ void MessageFieldGenerator::GenerateStructMembers(io::Printer* printer) const ...@@ -85,7 +85,7 @@ void MessageFieldGenerator::GenerateStructMembers(io::Printer* printer) const
{ {
std::map<std::string, std::string> vars; std::map<std::string, std::string> vars;
vars["name"] = FieldName(descriptor_); vars["name"] = FieldName(descriptor_);
vars["type"] = FullNameToC(descriptor_->message_type()->full_name()); vars["type"] = FullNameToC(descriptor_->message_type()->full_name(), descriptor_->message_type()->file());
vars["deprecated"] = FieldDeprecated(descriptor_); vars["deprecated"] = FieldDeprecated(descriptor_);
switch (descriptor_->label()) { switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED: case FieldDescriptor::LABEL_REQUIRED:
...@@ -119,7 +119,7 @@ void MessageFieldGenerator::GenerateStaticInit(io::Printer* printer) const ...@@ -119,7 +119,7 @@ void MessageFieldGenerator::GenerateStaticInit(io::Printer* printer) const
} }
void MessageFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const void MessageFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{ {
std::string addr = "&" + FullNameToLower(descriptor_->message_type()->full_name()) + "__descriptor"; std::string addr = "&" + FullNameToLower(descriptor_->message_type()->full_name(), descriptor_->message_type()->file()) + "__descriptor";
GenerateDescriptorInitializerGeneric(printer, false, "MESSAGE", addr); GenerateDescriptorInitializerGeneric(printer, false, "MESSAGE", addr);
} }
......
...@@ -74,9 +74,9 @@ ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor, ...@@ -74,9 +74,9 @@ ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor,
: descriptor_(descriptor) { : descriptor_(descriptor) {
vars_["name"] = descriptor_->name(); vars_["name"] = descriptor_->name();
vars_["fullname"] = descriptor_->full_name(); vars_["fullname"] = descriptor_->full_name();
vars_["cname"] = FullNameToC(descriptor_->full_name()); vars_["cname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars_["lcfullname"] = FullNameToLower(descriptor_->full_name()); vars_["lcfullname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars_["ucfullname"] = FullNameToUpper(descriptor_->full_name()); vars_["ucfullname"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file());
vars_["lcfullpadd"] = ConvertToSpaces(vars_["lcfullname"]); vars_["lcfullpadd"] = ConvertToSpaces(vars_["lcfullname"]);
vars_["package"] = descriptor_->file()->package(); vars_["package"] = descriptor_->file()->package();
if (dllexport_decl.empty()) { if (dllexport_decl.empty()) {
...@@ -107,8 +107,8 @@ void ServiceGenerator::GenerateVfuncs(io::Printer* printer) ...@@ -107,8 +107,8 @@ void ServiceGenerator::GenerateVfuncs(io::Printer* printer)
std::string lcname = CamelToLower(method->name()); std::string lcname = CamelToLower(method->name());
vars_["method"] = lcname; vars_["method"] = lcname;
vars_["metpad"] = ConvertToSpaces(lcname); vars_["metpad"] = ConvertToSpaces(lcname);
vars_["input_typename"] = FullNameToC(method->input_type()->full_name()); vars_["input_typename"] = FullNameToC(method->input_type()->full_name(), method->input_type()->file());
vars_["output_typename"] = FullNameToC(method->output_type()->full_name()); vars_["output_typename"] = FullNameToC(method->output_type()->full_name(), method->output_type()->file());
printer->Print(vars_, printer->Print(vars_,
" void (*$method$)($cname$_Service *service,\n" " void (*$method$)($cname$_Service *service,\n"
" $metpad$ const $input_typename$ *input,\n" " $metpad$ const $input_typename$ *input,\n"
...@@ -145,11 +145,11 @@ void ServiceGenerator::GenerateCallersDeclarations(io::Printer* printer) ...@@ -145,11 +145,11 @@ void ServiceGenerator::GenerateCallersDeclarations(io::Printer* printer)
for (int i = 0; i < descriptor_->method_count(); i++) { for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor *method = descriptor_->method(i); const MethodDescriptor *method = descriptor_->method(i);
std::string lcname = CamelToLower(method->name()); std::string lcname = CamelToLower(method->name());
std::string lcfullname = FullNameToLower(descriptor_->full_name()); std::string lcfullname = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars_["method"] = lcname; vars_["method"] = lcname;
vars_["metpad"] = ConvertToSpaces(lcname); vars_["metpad"] = ConvertToSpaces(lcname);
vars_["input_typename"] = FullNameToC(method->input_type()->full_name()); vars_["input_typename"] = FullNameToC(method->input_type()->full_name(), method->input_type()->file());
vars_["output_typename"] = FullNameToC(method->output_type()->full_name()); vars_["output_typename"] = FullNameToC(method->output_type()->full_name(), method->output_type()->file());
vars_["padddddddddddddddddd"] = ConvertToSpaces(lcfullname + "__" + lcname); vars_["padddddddddddddddddd"] = ConvertToSpaces(lcfullname + "__" + lcname);
printer->Print(vars_, printer->Print(vars_,
"void $lcfullname$__$method$(ProtobufCService *service,\n" "void $lcfullname$__$method$(ProtobufCService *service,\n"
...@@ -208,8 +208,8 @@ void ServiceGenerator::GenerateServiceDescriptor(io::Printer* printer) ...@@ -208,8 +208,8 @@ void ServiceGenerator::GenerateServiceDescriptor(io::Printer* printer)
for (int i = 0; i < n_methods; i++) { for (int i = 0; i < n_methods; i++) {
const MethodDescriptor *method = descriptor_->method(i); const MethodDescriptor *method = descriptor_->method(i);
vars_["method"] = method->name(); vars_["method"] = method->name();
vars_["input_descriptor"] = "&" + FullNameToLower(method->input_type()->full_name()) + "__descriptor"; vars_["input_descriptor"] = "&" + FullNameToLower(method->input_type()->full_name(), method->input_type()->file()) + "__descriptor";
vars_["output_descriptor"] = "&" + FullNameToLower(method->output_type()->full_name()) + "__descriptor"; vars_["output_descriptor"] = "&" + FullNameToLower(method->output_type()->full_name(), method->output_type()->file()) + "__descriptor";
if (optimize_code_size) { if (optimize_code_size) {
printer->Print(vars_, printer->Print(vars_,
" { NULL, $input_descriptor$, $output_descriptor$ }, /* CODE_SIZE */\n"); " { NULL, $input_descriptor$, $output_descriptor$ }, /* CODE_SIZE */\n");
...@@ -267,11 +267,11 @@ void ServiceGenerator::GenerateCallersImplementations(io::Printer* printer) ...@@ -267,11 +267,11 @@ void ServiceGenerator::GenerateCallersImplementations(io::Printer* printer)
for (int i = 0; i < descriptor_->method_count(); i++) { for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor *method = descriptor_->method(i); const MethodDescriptor *method = descriptor_->method(i);
std::string lcname = CamelToLower(method->name()); std::string lcname = CamelToLower(method->name());
std::string lcfullname = FullNameToLower(descriptor_->full_name()); std::string lcfullname = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars_["method"] = lcname; vars_["method"] = lcname;
vars_["metpad"] = ConvertToSpaces(lcname); vars_["metpad"] = ConvertToSpaces(lcname);
vars_["input_typename"] = FullNameToC(method->input_type()->full_name()); vars_["input_typename"] = FullNameToC(method->input_type()->full_name(), method->input_type()->file());
vars_["output_typename"] = FullNameToC(method->output_type()->full_name()); vars_["output_typename"] = FullNameToC(method->output_type()->full_name(), method->output_type()->file());
vars_["padddddddddddddddddd"] = ConvertToSpaces(lcfullname + "__" + lcname); vars_["padddddddddddddddddd"] = ConvertToSpaces(lcfullname + "__" + lcname);
vars_["index"] = SimpleItoa(i); vars_["index"] = SimpleItoa(i);
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
#include <protoc-c/c_helpers.h> #include <protoc-c/c_helpers.h>
#include <google/protobuf/io/printer.h> #include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h> #include <google/protobuf/wire_format.h>
#include <google/protobuf/descriptor.pb.h> #include <protobuf-c/protobuf-c.pb.h>
namespace google { namespace google {
namespace protobuf { namespace protobuf {
...@@ -76,7 +76,7 @@ using internal::WireFormat; ...@@ -76,7 +76,7 @@ using internal::WireFormat;
void SetStringVariables(const FieldDescriptor* descriptor, void SetStringVariables(const FieldDescriptor* descriptor,
std::map<std::string, std::string>* variables) { std::map<std::string, std::string>* variables) {
(*variables)["name"] = FieldName(descriptor); (*variables)["name"] = FieldName(descriptor);
(*variables)["default"] = FullNameToLower(descriptor->full_name()) (*variables)["default"] = FullNameToLower(descriptor->full_name(), descriptor->file())
+ "__default_value"; + "__default_value";
(*variables)["deprecated"] = FieldDeprecated(descriptor); (*variables)["deprecated"] = FieldDeprecated(descriptor);
} }
...@@ -93,13 +93,19 @@ StringFieldGenerator::~StringFieldGenerator() {} ...@@ -93,13 +93,19 @@ StringFieldGenerator::~StringFieldGenerator() {}
void StringFieldGenerator::GenerateStructMembers(io::Printer* printer) const void StringFieldGenerator::GenerateStructMembers(io::Printer* printer) const
{ {
const ProtobufCFileOptions opt = descriptor_->file()->options().GetExtension(pb_c_file);
switch (descriptor_->label()) { switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED: case FieldDescriptor::LABEL_REQUIRED:
case FieldDescriptor::LABEL_OPTIONAL: case FieldDescriptor::LABEL_OPTIONAL:
if (opt.const_strings())
printer->Print(variables_, "const ");
printer->Print(variables_, "char *$name$$deprecated$;\n"); printer->Print(variables_, "char *$name$$deprecated$;\n");
break; break;
case FieldDescriptor::LABEL_REPEATED: case FieldDescriptor::LABEL_REPEATED:
printer->Print(variables_, "size_t n_$name$$deprecated$;\n"); printer->Print(variables_, "size_t n_$name$$deprecated$;\n");
if (opt.const_strings())
printer->Print(variables_, "const ");
printer->Print(variables_, "char **$name$$deprecated$;\n"); printer->Print(variables_, "char **$name$$deprecated$;\n");
break; break;
} }
...@@ -123,10 +129,13 @@ std::string StringFieldGenerator::GetDefaultValue(void) const ...@@ -123,10 +129,13 @@ std::string StringFieldGenerator::GetDefaultValue(void) const
void StringFieldGenerator::GenerateStaticInit(io::Printer* printer) const void StringFieldGenerator::GenerateStaticInit(io::Printer* printer) const
{ {
std::map<std::string, std::string> vars; std::map<std::string, std::string> vars;
const ProtobufCFileOptions opt = descriptor_->file()->options().GetExtension(pb_c_file);
if (descriptor_->has_default_value()) { if (descriptor_->has_default_value()) {
vars["default"] = GetDefaultValue(); vars["default"] = GetDefaultValue();
} else if (FieldSyntax(descriptor_) == 2) { } else if (FieldSyntax(descriptor_) == 2) {
vars["default"] = "NULL"; vars["default"] = "NULL";
} else if (opt.const_strings()) {
vars["default"] = "(const char *)protobuf_c_empty_string";
} else { } else {
vars["default"] = "(char *)protobuf_c_empty_string"; vars["default"] = "(char *)protobuf_c_empty_string";
} }
......
...@@ -56,7 +56,7 @@ TEST_ENUM_TYPE_NAME enum_random[] = { ...@@ -56,7 +56,7 @@ TEST_ENUM_TYPE_NAME enum_random[] = {
T(0), T(2097152), T(268435455), T(127), T(16383), T(16384) }; T(0), T(2097152), T(268435455), T(127), T(16383), T(16384) };
#undef T #undef T
char *repeated_strings_0[] = { (char*)"onestring" }; const char *repeated_strings_0[] = { "onestring" };
char *repeated_strings_1[] = { (char*)"two", (char*)"string" }; const char *repeated_strings_1[] = { "two", "string" };
char *repeated_strings_2[] = { (char*)"many", (char*)"tiny", (char*)"little", (char*)"strings", (char*)"should", (char*)"be", (char*)"handled" }; const char *repeated_strings_2[] = { "many", "tiny", "little", "strings", "should", "be", "handled" };
char *repeated_strings_3[] = { (char*)"one very long strings XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }; const char *repeated_strings_3[] = { "one very long strings XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" };
...@@ -432,6 +432,39 @@ static void test_required_SubMess (void) ...@@ -432,6 +432,39 @@ static void test_required_SubMess (void)
#undef DO_TEST #undef DO_TEST
} }
static size_t foo__test_mess_optional__get_packed_size
(const Foo__TestMessOptional *message)
{
assert(message->base.descriptor == &foo__test_mess_optional__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
static size_t foo__test_mess_optional__pack
(const Foo__TestMessOptional *message,
uint8_t *out)
{
assert(message->base.descriptor == &foo__test_mess_optional__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
static Foo__TestMessOptional *
foo__test_mess_optional__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data)
{
return (Foo__TestMessOptional *)
protobuf_c_message_unpack (&foo__test_mess_optional__descriptor,
allocator, len, data);
}
static void foo__test_mess_optional__free_unpacked
(Foo__TestMessOptional *message,
ProtobufCAllocator *allocator)
{
if(!message)
return;
assert(message->base.descriptor == &foo__test_mess_optional__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
/* === Optional type fields === */ /* === Optional type fields === */
static void test_empty_optional (void) static void test_empty_optional (void)
{ {
...@@ -1241,7 +1274,7 @@ static void test_repeated_string (void) ...@@ -1241,7 +1274,7 @@ static void test_repeated_string (void)
{ {
#define DO_TEST(static_array, example_packed_data) \ #define DO_TEST(static_array, example_packed_data) \
DO_TEST_REPEATED(test_string, (char **), \ DO_TEST_REPEATED(test_string, (const char **), \
static_array, example_packed_data, \ static_array, example_packed_data, \
STRING_EQUALS) STRING_EQUALS)
...@@ -2076,8 +2109,8 @@ test_message_check(void) ...@@ -2076,8 +2109,8 @@ test_message_check(void)
Foo__TestMessageCheck__SubMessage sm = FOO__TEST_MESSAGE_CHECK__SUB_MESSAGE__INIT; Foo__TestMessageCheck__SubMessage sm = FOO__TEST_MESSAGE_CHECK__SUB_MESSAGE__INIT;
Foo__TestMessageCheck__SubMessage sm2 = FOO__TEST_MESSAGE_CHECK__SUB_MESSAGE__INIT; Foo__TestMessageCheck__SubMessage sm2 = FOO__TEST_MESSAGE_CHECK__SUB_MESSAGE__INIT;
Foo__TestMessageCheck m = FOO__TEST_MESSAGE_CHECK__INIT; Foo__TestMessageCheck m = FOO__TEST_MESSAGE_CHECK__INIT;
char *null = NULL; const char *null = NULL;
char *str = ""; const char *str = "";
Foo__TestMessageCheck__SubMessage *sm_p; Foo__TestMessageCheck__SubMessage *sm_p;
ProtobufCBinaryData bd; ProtobufCBinaryData bd;
......
#include <stdlib.h>
#include "t/issue251/issue251.pb-c.h"
int main(void)
{
TwoOneofs msg = TWO_ONEOFS__INIT;
const ProtobufCFieldDescriptor *field;
unsigned off1, off2, off_name;
field = protobuf_c_message_descriptor_get_field_by_name(
msg.base.descriptor,
"first_oneof");
assert (field);
off_name = field->offset;
field = protobuf_c_message_descriptor_get_field(
msg.base.descriptor,
10);
assert (field);
off1 = field->offset;
field = protobuf_c_message_descriptor_get_field(
msg.base.descriptor,
11);
assert (field);
off2 = field->offset;
assert (off_name == off1);
assert (off1 == off2);
field = protobuf_c_message_descriptor_get_field_by_name(
msg.base.descriptor,
"second_oneof");
assert (field);
off_name = field->offset;
field = protobuf_c_message_descriptor_get_field(
msg.base.descriptor,
20);
assert (field);
off1 = field->offset;
field = protobuf_c_message_descriptor_get_field(
msg.base.descriptor,
21);
assert (field);
off2 = field->offset;
assert (off_name == off1);
assert (off1 == off2);
return EXIT_SUCCESS;
}
import "protobuf-c/protobuf-c.proto";
option (pb_c_file).use_oneof_field_name = true;
message two_oneofs {
oneof first_oneof {
bool a = 10;
bool b = 11;
}
oneof second_oneof {
bool c = 20;
bool d = 21;
}
}
package foo; package foo;
import "protobuf-c/protobuf-c.proto";
option (pb_c_file).const_strings = true;
message SubMess { message SubMess {
required int32 test = 4; required int32 test = 4;
...@@ -11,6 +15,8 @@ message SubMess { ...@@ -11,6 +15,8 @@ message SubMess {
repeated int32 rep = 4; repeated int32 rep = 4;
optional bytes bytes1 = 2 [default = "a \0 char"]; optional bytes bytes1 = 2 [default = "a \0 char"];
optional string str1 = 3 [default = "hello world\n"]; optional string str1 = 3 [default = "hello world\n"];
optional string str2 = 5 [default = "hello\0world\n",
(pb_c_field).string_as_bytes = true];
} }
optional SubSubMess sub1 = 9; optional SubSubMess sub1 = 9;
optional SubSubMess sub2 = 10; optional SubSubMess sub2 = 10;
...@@ -115,6 +121,8 @@ message TestMessPacked { ...@@ -115,6 +121,8 @@ message TestMessPacked {
} }
message TestMessOptional { message TestMessOptional {
option (pb_c_msg).gen_pack_helpers = false;
option (pb_c_msg).gen_init_helpers = false;
optional int32 test_int32 = 1; optional int32 test_int32 = 1;
optional sint32 test_sint32 = 2; optional sint32 test_sint32 = 2;
optional sfixed32 test_sfixed32 = 3; optional sfixed32 test_sfixed32 = 3;
......
package foo; package foo;
import "protobuf-c/protobuf-c.proto";
option (pb_c_file).c_package = "foo";
message Person { message Person {
required string name = 1; required string name = 1;
required int32 id = 2; required int32 id = 2;
......
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