aboutsummaryrefslogtreecommitdiff
path: root/src/google/protobuf/compiler/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/compiler/cpp')
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc12
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum.h6
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_extension.cc10
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_extension.h4
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_field.h6
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.cc46
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.h20
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_generator.cc53
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_generator.h12
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.cc359
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.h151
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_map_field.cc56
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.cc155
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.h6
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_options.h7
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_service.h4
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.inc8
17 files changed, 504 insertions, 411 deletions
diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
index 4c135649..a19ad595 100644
--- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -50,6 +50,7 @@
#include <google/protobuf/test_util2.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/stubs/map_util.h>
#include <google/protobuf/stubs/stl_util.h>
@@ -98,6 +99,13 @@ class MockGeneratorContext : public GeneratorContext {
&actual_contents, true))
<< physical_filename;
CleanStringLineEndings(&actual_contents, false);
+
+#ifdef WRITE_FILES // Define to debug mismatched files.
+ GOOGLE_CHECK_OK(
+ File::SetContents("/tmp/1.cc", *expected_contents, true));
+ GOOGLE_CHECK_OK(File::SetContents("/tmp/2.cc", actual_contents, true));
+#endif
+
EXPECT_EQ(*expected_contents, actual_contents)
<< physical_filename
<< " needs to be regenerated. Please run "
@@ -119,8 +127,8 @@ class MockGeneratorContext : public GeneratorContext {
std::map<string, string*> files_;
};
-const char kDescriptorParameter[] = "dllexport_decl=LIBPROTOBUF_EXPORT";
-const char kPluginParameter[] = "dllexport_decl=LIBPROTOC_EXPORT";
+const char kDescriptorParameter[] = "dllexport_decl=PROTOBUF_EXPORT";
+const char kPluginParameter[] = "dllexport_decl=PROTOC_EXPORT";
const char kNormalParameter[] = "";
const char* test_protos[][2] = {
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.h b/src/google/protobuf/compiler/cpp/cpp_enum.h
index 55e6b835..6b9700ae 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.h
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.h
@@ -58,7 +58,7 @@ class EnumGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
EnumGenerator(const EnumDescriptor* descriptor,
- const std::map<string, string>& vars, const Options& options);
+ const std::map<std::string, std::string>& vars, const Options& options);
~EnumGenerator();
// Generate header code defining the enum. This code should be placed
@@ -85,12 +85,12 @@ class EnumGenerator {
private:
const EnumDescriptor* descriptor_;
- const string classname_;
+ const std::string classname_;
const Options& options_;
// whether to generate the *_ARRAYSIZE constant.
const bool generate_array_size_;
- std::map<string, string> variables_;
+ std::map<std::string, std::string> variables_;
friend class FileGenerator;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc
index 25bcc333..f866eb6e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_extension.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc
@@ -137,6 +137,16 @@ void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) const {
}
void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
+ // If we are building for lite with implicit weak fields, we want to skip over
+ // any custom options (i.e. extensions of messages from descriptor.proto).
+ // This prevents the creation of any unnecessary linker references to the
+ // descriptor messages.
+ if (options_.lite_implicit_weak_fields &&
+ descriptor_->containing_type()->file()->name() ==
+ "net/proto2/proto/descriptor.proto") {
+ return;
+ }
+
Formatter format(printer, variables_);
string default_str;
// If this is a class member, it needs to be declared in its class scope.
diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.h b/src/google/protobuf/compiler/cpp/cpp_extension.h
index c316f5da..72413f6b 100644
--- a/src/google/protobuf/compiler/cpp/cpp_extension.h
+++ b/src/google/protobuf/compiler/cpp/cpp_extension.h
@@ -75,10 +75,10 @@ class ExtensionGenerator {
private:
const FieldDescriptor* descriptor_;
- string type_traits_;
+ std::string type_traits_;
Options options_;
- std::map<string, string> variables_;
+ std::map<std::string, std::string> variables_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
};
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h
index 4561b33e..43a3e367 100644
--- a/src/google/protobuf/compiler/cpp/cpp_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_field.h
@@ -61,11 +61,11 @@ namespace cpp {
// ['name', 'index', 'number', 'classname', 'declared_type', 'tag_size',
// 'deprecation'].
void SetCommonFieldVariables(const FieldDescriptor* descriptor,
- std::map<string, string>* variables,
+ std::map<std::string, std::string>* variables,
const Options& options);
void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor,
- std::map<string, string>* variables);
+ std::map<std::string, std::string>* variables);
class FieldGenerator {
public:
@@ -203,7 +203,7 @@ class FieldGenerator {
protected:
const FieldDescriptor* descriptor_;
const Options& options_;
- std::map<string, string> variables_;
+ std::map<std::string, std::string> variables_;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 414da2f8..1e80715d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -256,6 +256,8 @@ void FileGenerator::GenerateProtoHeader(io::Printer* printer,
GenerateHeader(printer);
+ IncludeFile("net/proto2/public/port_undef.inc", printer);
+
GenerateBottomHeaderGuard(printer, filename_identifier);
}
@@ -425,20 +427,6 @@ void FileGenerator::GenerateSourceIncludes(io::Printer* printer) {
}
}
- // TODO(gerbens) Remove this when all code in google is using the same
- // proto library. This is a temporary hack to force build errors if
- // the proto library is compiled with GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
- // and is also linking internal proto2. This is to prevent regressions while
- // we work cleaning up the code base. After this is completed and we have
- // one proto lib all code uses this should be removed.
- if (options_.opensource_runtime) {
- format(
- "// This is a temporary google only hack\n"
- "#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS\n"
- "#include \"third_party/protobuf/version.h\"\n"
- "#endif\n");
- }
-
format("// @@protoc_insertion_point(includes)\n");
IncludeFile("net/proto2/public/port_def.inc", printer);
}
@@ -702,6 +690,8 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
format(
"\n"
"// @@protoc_insertion_point(global_scope)\n");
+
+ IncludeFile("net/proto2/public/port_undef.inc", printer);
}
void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
@@ -751,7 +741,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
format(
"\n"
"const $uint32$ $tablename$::offsets[] "
- "$GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
+ "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
format.Indent();
std::vector<std::pair<size_t, size_t> > pairs;
pairs.reserve(message_generators_.size());
@@ -762,7 +752,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
format(
"};\n"
"static const ::$proto_ns$::internal::MigrationSchema schemas[] "
- "$GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
+ "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
format.Indent();
{
int offset = 0;
@@ -958,7 +948,7 @@ void FileGenerator::GenerateTables(io::Printer* printer) {
format(
"PROTOBUF_CONSTEXPR_VAR ::$proto_ns$::internal::ParseTableField\n"
" const $tablename$::entries[] "
- "$GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
+ "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
format.Indent();
std::vector<size_t> entries;
@@ -981,7 +971,7 @@ void FileGenerator::GenerateTables(io::Printer* printer) {
"PROTOBUF_CONSTEXPR_VAR "
"::$proto_ns$::internal::AuxillaryParseTableField\n"
" const $tablename$::aux[] "
- "$GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
+ "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
format.Indent();
std::vector<size_t> aux_entries;
@@ -1001,7 +991,7 @@ void FileGenerator::GenerateTables(io::Printer* printer) {
"};\n"
"PROTOBUF_CONSTEXPR_VAR ::$proto_ns$::internal::ParseTable const\n"
" $tablename$::schema[] "
- "$GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
+ "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n");
format.Indent();
size_t offset = 0;
@@ -1199,25 +1189,25 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
}
if (options_.opensource_runtime) {
- DoIncludeFile("net/proto2/public/stubs/common.h", false, printer);
-
// Verify the protobuf library header version is compatible with the protoc
// version before going any further.
+ IncludeFile("net/proto2/public/port_def.inc", printer);
format(
- "#if GOOGLE_PROTOBUF_VERSION < $1$\n"
+ "#if PROTOBUF_VERSION < $1$\n"
"#error This file was generated by a newer version of protoc which is\n"
"#error incompatible with your Protocol Buffer headers. Please update\n"
"#error your headers.\n"
"#endif\n"
- "#if $2$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n"
+ "#if $2$ < PROTOBUF_MIN_PROTOC_VERSION\n"
"#error This file was generated by an older version of protoc which "
"is\n"
"#error incompatible with your Protocol Buffer headers. Please\n"
"#error regenerate this file with a newer version of protoc.\n"
"#endif\n"
"\n",
- GOOGLE_PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC, // 1
- GOOGLE_PROTOBUF_VERSION); // 2
+ PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC, // 1
+ PROTOBUF_VERSION); // 2
+ IncludeFile("net/proto2/public/port_undef.inc", printer);
}
// OK, it's now safe to #include other files.
@@ -1341,11 +1331,11 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations(
// These tables describe how to serialize and parse messages. Used
// for table driven code.
" static const ::$proto_ns$::internal::ParseTableField entries[]\n"
- " $GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);\n"
+ " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n"
" static const ::$proto_ns$::internal::AuxillaryParseTableField aux[]\n"
- " $GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);\n"
+ " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n"
" static const ::$proto_ns$::internal::ParseTable schema[$1$]\n"
- " $GOOGLE_PROTOBUF$_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold);\n"
+ " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n"
" static const ::$proto_ns$::internal::FieldMetadata field_metadata[];\n"
" static const ::$proto_ns$::internal::SerializationTable "
"serialization_table[];\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h
index 9dfdf50f..315cf139 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.h
+++ b/src/google/protobuf/compiler/cpp/cpp_file.h
@@ -76,10 +76,10 @@ class FileGenerator {
// info_path, if non-empty, should be the path (relative to printer's
// output) to the metadata file describing this proto header.
- void GenerateProtoHeader(io::Printer* printer, const string& info_path);
+ void GenerateProtoHeader(io::Printer* printer, const std::string& info_path);
// info_path, if non-empty, should be the path (relative to printer's
// output) to the metadata file describing this PB header.
- void GeneratePBHeader(io::Printer* printer, const string& info_path);
+ void GeneratePBHeader(io::Printer* printer, const std::string& info_path);
void GenerateSource(io::Printer* printer);
int NumMessages() const { return message_generators_.size(); }
@@ -91,16 +91,16 @@ class FileGenerator {
// Internal type used by GenerateForwardDeclarations (defined in file.cc).
class ForwardDeclarations;
- void IncludeFile(const string& google3_name, io::Printer* printer) {
+ void IncludeFile(const std::string& google3_name, io::Printer* printer) {
DoIncludeFile(google3_name, false, printer);
}
- void IncludeFileAndExport(const string& google3_name, io::Printer* printer) {
+ void IncludeFileAndExport(const std::string& google3_name, io::Printer* printer) {
DoIncludeFile(google3_name, true, printer);
}
- void DoIncludeFile(const string& google3_name, bool do_export,
+ void DoIncludeFile(const std::string& google3_name, bool do_export,
io::Printer* printer);
- string CreateHeaderInclude(const string& basename,
+ std::string CreateHeaderInclude(const std::string& basename,
const FileDescriptor* file);
void GenerateInternalForwardDeclarations(
const std::vector<const FieldDescriptor*>& fields, const Options& options,
@@ -117,9 +117,9 @@ class FileGenerator {
// Generates top or bottom of a header file.
void GenerateTopHeaderGuard(io::Printer* printer,
- const string& filename_identifier);
+ const std::string& filename_identifier);
void GenerateBottomHeaderGuard(io::Printer* printer,
- const string& filename_identifier);
+ const std::string& filename_identifier);
// Generates #include directives.
void GenerateLibraryIncludes(io::Printer* printer);
@@ -127,7 +127,7 @@ class FileGenerator {
// Generate a pragma to pull in metadata using the given info_path (if
// non-empty). info_path should be relative to printer's output.
- void GenerateMetadataPragma(io::Printer* printer, const string& info_path);
+ void GenerateMetadataPragma(io::Printer* printer, const std::string& info_path);
// Generates a couple of different pieces before definitions:
void GenerateGlobalStateFunctionDeclarations(io::Printer* printer);
@@ -182,7 +182,7 @@ class FileGenerator {
MessageSCCAnalyzer scc_analyzer_;
- std::map<string, string> variables_;
+ std::map<std::string, std::string> variables_;
// Contains the post-order walk of all the messages (and child messages) in
// this file. If you need a pre-order walk just reverse iterate.
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc
index 79f773ee..0e7e4dfd 100644
--- a/src/google/protobuf/compiler/cpp/cpp_generator.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -182,32 +182,41 @@ bool CppGenerator::Generate(const FileDescriptor* file,
// Generate cc file(s).
if (UsingImplicitWeakFields(file, file_options)) {
- {
- // This is the global .cc file, containing enum/services/tables/reflection
+ if (file->name() == "net/proto2/proto/descriptor.proto") {
+ // If we are building with implicit weak fields then we do not want to
+ // produce any symbols for descriptor.proto, so we just create an empty
+ // pb.cc file.
std::unique_ptr<io::ZeroCopyOutputStream> output(
generator_context->Open(basename + ".pb.cc"));
- io::Printer printer(output.get(), '$');
- file_generator.GenerateGlobalSource(&printer);
- }
+ } else {
+ {
+ // This is the global .cc file, containing
+ // enum/services/tables/reflection
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(basename + ".pb.cc"));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateGlobalSource(&printer);
+ }
- int num_cc_files = file_generator.NumMessages();
+ int num_cc_files = file_generator.NumMessages();
- // If we're using implicit weak fields then we allow the user to optionally
- // specify how many files to generate, not counting the global pb.cc file.
- // If we have more files than messages, then some files will be generated as
- // empty placeholders.
- if (file_options.num_cc_files > 0) {
- GOOGLE_CHECK_LE(file_generator.NumMessages(), file_options.num_cc_files)
- << "There must be at least as many numbered .cc files as messages.";
- num_cc_files = file_options.num_cc_files;
- }
- for (int i = 0; i < num_cc_files; i++) {
- // TODO(gerbens) Agree on naming scheme.
- std::unique_ptr<io::ZeroCopyOutputStream> output(generator_context->Open(
- basename + ".out/" + SimpleItoa(i) + ".cc"));
- io::Printer printer(output.get(), '$');
- if (i < file_generator.NumMessages()) {
- file_generator.GenerateSourceForMessage(i, &printer);
+ // If we're using implicit weak fields then we allow the user to
+ // optionally specify how many files to generate, not counting the global
+ // pb.cc file. If we have more files than messages, then some files will
+ // be generated as empty placeholders.
+ if (file_options.num_cc_files > 0) {
+ GOOGLE_CHECK_LE(file_generator.NumMessages(), file_options.num_cc_files)
+ << "There must be at least as many numbered .cc files as messages.";
+ num_cc_files = file_options.num_cc_files;
+ }
+ for (int i = 0; i < num_cc_files; i++) {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(basename + ".out/" +
+ SimpleItoa(i) + ".cc"));
+ io::Printer printer(output.get(), '$');
+ if (i < file_generator.NumMessages()) {
+ file_generator.GenerateSourceForMessage(i, &printer);
+ }
}
}
} else {
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.h b/src/google/protobuf/compiler/cpp/cpp_generator.h
index 06d3c36f..30363e73 100644
--- a/src/google/protobuf/compiler/cpp/cpp_generator.h
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.h
@@ -40,6 +40,8 @@
#include <string>
#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/port_def.inc>
+
namespace google {
namespace protobuf {
namespace compiler {
@@ -49,12 +51,12 @@ namespace cpp {
// header. If you create your own protocol compiler binary and you want
// it to support C++ output, you can do so by registering an instance of this
// CodeGenerator with the CommandLineInterface in your main() function.
-class LIBPROTOC_EXPORT CppGenerator : public CodeGenerator {
+class PROTOC_EXPORT CppGenerator : public CodeGenerator {
public:
CppGenerator();
~CppGenerator();
- enum class LIBPROTOC_EXPORT Runtime {
+ enum class Runtime {
kGoogle3, // Use the internal google3 runtime.
kOpensource, // Use the open-source runtime.
@@ -70,9 +72,9 @@ class LIBPROTOC_EXPORT CppGenerator : public CodeGenerator {
// implements CodeGenerator ----------------------------------------
bool Generate(const FileDescriptor* file,
- const string& parameter,
+ const std::string& parameter,
GeneratorContext* generator_context,
- string* error) const;
+ std::string* error) const;
private:
Runtime runtime_ = Runtime::kOpensource;
@@ -84,4 +86,6 @@ class LIBPROTOC_EXPORT CppGenerator : public CodeGenerator {
} // namespace protobuf
} // namespace google
+#include <google/protobuf/port_undef.inc>
+
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index bc0a9264..472c55f4 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -53,6 +53,8 @@
#include <google/protobuf/stubs/hash.h>
+#include <google/protobuf/port_def.inc>
+
namespace google {
namespace protobuf {
namespace compiler {
@@ -487,10 +489,9 @@ string DefaultValue(const Options& options, const FieldDescriptor* field) {
case FieldDescriptor::CPPTYPE_UINT32:
return SimpleItoa(field->default_value_uint32()) + "u";
case FieldDescriptor::CPPTYPE_INT64:
- return Int64ToString(MacroPrefix(options), field->default_value_int64());
+ return Int64ToString("PROTOBUF", field->default_value_int64());
case FieldDescriptor::CPPTYPE_UINT64:
- return UInt64ToString(MacroPrefix(options),
- field->default_value_uint64());
+ return UInt64ToString("PROTOBUF", field->default_value_uint64());
case FieldDescriptor::CPPTYPE_DOUBLE: {
double value = field->default_value_double();
if (value == std::numeric_limits<double>::infinity()) {
@@ -1058,7 +1059,7 @@ void ListAllTypesForServices(const FileDescriptor* fd,
bool GetBootstrapBasename(const Options& options, const string& basename,
string* bootstrap_basename) {
- if (options.opensource_runtime) {
+ if (options.opensource_runtime || options.lite_implicit_weak_fields) {
return false;
}
@@ -1169,6 +1170,193 @@ bool ShouldRepeat(const FieldDescriptor* descriptor,
wiretype != internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
}
+void GenerateLengthDelim(
+ const FieldDescriptor* field, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer,
+ const Formatter& format) {
+ format(
+ "ptr = Varint::Parse32Inline(ptr, &size);\n"
+ "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n");
+ if (!IsProto1(field->file(), options) && field->is_packable()) {
+ if (!HasPreservingUnknownEnumSemantics(field->file()) &&
+ field->type() == FieldDescriptor::TYPE_ENUM) {
+ format(
+ "ctx->extra_parse_data().SetEnumValidator($1$_IsValid, "
+ "msg->mutable_unknown_fields(), $2$);\n"
+ "parser_till_end = "
+ "::$proto_ns$::internal::PackedValidEnumParser$3$;\n"
+ "object = msg->mutable_$4$();\n",
+ QualifiedClassName(field->enum_type()), field->number(),
+ UseUnknownFieldSet(field->file(), options) ? "" : "Lite",
+ FieldName(field));
+ } else {
+ format(
+ "parser_till_end = ::$proto_ns$::internal::Packed$1$Parser;\n"
+ "object = msg->mutable_$2$();\n",
+ DeclaredTypeMethodName(field->type()), FieldName(field));
+ }
+ format(
+ "if (size > end - ptr) goto len_delim_till_end;\n"
+ "auto newend = ptr + size;\n"
+ "if (size) ptr = parser_till_end(ptr, newend, object, ctx);\n"
+ "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr == newend);\n");
+ } else {
+ auto field_type = field->type();
+ if (IsProto1(field->file(), options)) {
+ if (field->is_packable()) {
+ // Sigh ... packed fields endup as a string in proto1
+ field_type = FieldDescriptor::TYPE_BYTES;
+ }
+ if (field_type == FieldDescriptor::TYPE_STRING) {
+ // In proto1 strings are treated as bytes
+ field_type = FieldDescriptor::TYPE_BYTES;
+ }
+ }
+ string utf8 = "";
+ switch (field_type) {
+ case FieldDescriptor::TYPE_STRING:
+ utf8 = GetUtf8Suffix(field, options);
+ if (!utf8.empty()) {
+ string name = "nullptr";
+ if (HasDescriptorMethods(field->file(), options)) {
+ name = "\"" + field->full_name() + "\"";
+ }
+ format("ctx->extra_parse_data().SetFieldName($1$);\n", name);
+ }
+ PROTOBUF_FALLTHROUGH_INTENDED;
+ case FieldDescriptor::TYPE_BYTES: {
+ if (field->options().ctype() == FieldOptions::STRING ||
+ (IsProto1(field->file(), options) &&
+ field->options().ctype() == FieldOptions::STRING_PIECE)) {
+ format(
+ "parser_till_end = ::$proto_ns$::internal::StringParser$1$;\n"
+ "$string$* str = msg->$2$_$3$();\n"
+ "str->clear();\n",
+ utf8,
+ field->is_repeated() && !field->is_map() &&
+ !field->is_packable()
+ ? "add"
+ : "mutable",
+ FieldName(field));
+ if (utf8.empty()) {
+ // special case if there is no utf8 verification.
+ format(
+ "object = str;\n"
+ "if (size > end - ptr) goto len_delim_till_end;\n"
+ "str->append(ptr, size);\n"
+ "ptr += size;\n");
+ return;
+ }
+ } else if (field->options().ctype() == FieldOptions::CORD) {
+ string cord_parser = "CordParser" + utf8;
+ format(
+ "parser_till_end = ::$proto_ns$::internal::$1$;\n"
+ "auto* str = msg->$2$_$3$();\n"
+ "str->Clear();\n",
+ cord_parser,
+ field->is_repeated() && !field->is_map() ? "add" : "mutable",
+ FieldName(field));
+ } else if (field->options().ctype() == FieldOptions::STRING_PIECE) {
+ format(
+ "parser_till_end = "
+ "::$proto_ns$::internal::StringPieceParser$1$;\n"
+ "::$proto_ns$::internal::StringPieceField* str = "
+ "msg->$2$_$3$();\n"
+ "str->Clear();\n",
+ utf8,
+ field->is_repeated() && !field->is_map() ? "add" : "mutable",
+ FieldName(field));
+ }
+ format(
+ "object = str;\n"
+ "if (size > end - ptr) goto len_delim_till_end;\n"
+ "auto newend = ptr + size;\n"
+ "if (size) ptr = parser_till_end(ptr, newend, object, ctx);\n");
+ if (!utf8.empty()) {
+ // If utf8 verification is on this can fail.
+ format("$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr == newend);\n");
+ }
+ break;
+ }
+ case FieldDescriptor::TYPE_MESSAGE: {
+ GOOGLE_CHECK(field->message_type());
+ if (!IsProto1(field->file(), options) && field->is_map()) {
+ const FieldDescriptor* val =
+ field->message_type()->FindFieldByName("value");
+ GOOGLE_CHECK(val);
+ if (HasFieldPresence(field->file()) &&
+ val->type() == FieldDescriptor::TYPE_ENUM) {
+ format(
+ "ctx->extra_parse_data().field_number = $1$;\n"
+ "ctx->extra_parse_data().unknown_fields = "
+ "&msg->_internal_metadata_;\n",
+ field->number());
+ }
+ format(
+ "parser_till_end = ::$proto_ns$::internal::SlowMapEntryParser;\n"
+ "auto parse_map = $1$::_ParseMap;\n"
+ "ctx->extra_parse_data().payload.clear();\n"
+ "ctx->extra_parse_data().parse_map = parse_map;\n"
+ "object = &msg->$2$_;\n"
+ "if (size > end - ptr) goto len_delim_till_end;\n"
+ "auto newend = ptr + size;\n"
+ "GOOGLE_PROTOBUF_PARSER_ASSERT(parse_map(ptr, newend, "
+ "object, ctx));\n"
+ "ptr = newend;\n",
+ QualifiedClassName(field->message_type()), FieldName(field));
+ break;
+ }
+ if (IsImplicitWeakField(field, options, scc_analyzer)) {
+ if (!field->is_repeated()) {
+ format("object = HasBitSetters::mutable_$1$(msg);\n",
+ FieldName(field));
+ } else {
+ format(
+ "object = "
+ "CastToBase(&msg->$1$_)->AddWeak(reinterpret_cast<const "
+ "::google::protobuf::MessageLite*>(&$2$::_$3$_default_instance_));\n",
+ FieldName(field), Namespace(field->message_type()),
+ ClassName(field->message_type()));
+ }
+ format(
+ "parser_till_end = static_cast<::$proto_ns$::MessageLite*>("
+ "object)->_ParseFunc();\n");
+ } else if (IsWeak(field, options)) {
+ if (IsProto1(field->file(), options)) {
+ format("object = msg->internal_mutable_$1$();\n",
+ FieldName(field));
+ } else {
+ format(
+ "object = msg->_weak_field_map_.MutableMessage($1$, "
+ "_$classname$_default_instance_.$2$_);\n",
+ field->number(), FieldName(field));
+ }
+ format(
+ "parser_till_end = static_cast<::$proto_ns$::MessageLite*>("
+ "object)->_ParseFunc();\n");
+ } else {
+ format(
+ "parser_till_end = $1$::_InternalParse;\n"
+ "object = msg->$2$_$3$();\n",
+ QualifiedClassName(field->message_type()),
+ field->is_repeated() ? "add" : "mutable", FieldName(field));
+ }
+ format(
+ "if (size > end - ptr) goto len_delim_till_end;\n"
+ "auto newend = ptr + size;\n"
+ "bool ok = ctx->ParseExactRange({parser_till_end, object},\n"
+ " ptr, newend);\n"
+ "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ok);\n"
+ "ptr = newend;\n");
+ break;
+ }
+ default:
+ GOOGLE_LOG(FATAL) << "Illegal combination for length delimited wiretype "
+ << " filed type is " << field->type();
+ }
+ }
+}
+
void GenerateCaseBody(internal::WireFormatLite::WireType wiretype,
const FieldDescriptor* field, const Options& options,
MessageSCCAnalyzer* scc_analyzer,
@@ -1185,10 +1373,11 @@ void GenerateCaseBody(internal::WireFormatLite::WireType wiretype,
format(
"$uint64$ val;\n"
"ptr = Varint::Parse64(ptr, &val);\n"
- "if (!ptr) goto error;\n");
+ "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n");
string type = PrimitiveTypeName(options, field->cpp_type());
- if (field->type() == FieldDescriptor::TYPE_SINT32 ||
- field->type() == FieldDescriptor::TYPE_SINT64) {
+ if ((field->type() == FieldDescriptor::TYPE_SINT32 ||
+ field->type() == FieldDescriptor::TYPE_SINT64) &&
+ !IsProto1(field->file(), options)) {
int size = EstimateAlignmentSize(field) * 8;
format(
"$1$ value = "
@@ -1232,149 +1421,17 @@ void GenerateCaseBody(internal::WireFormatLite::WireType wiretype,
break;
}
case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
- format(
- "ptr = Varint::Parse32Inline(ptr, &size);\n"
- "if (!ptr) goto error;\n");
- if (!IsProto1(field->file(), options) && field->is_packable()) {
- if (!HasPreservingUnknownEnumSemantics(field->file()) &&
- field->type() == FieldDescriptor::TYPE_ENUM) {
- format(
- "ctx->extra_parse_data().SetEnumValidator($1$_IsValid, "
- "msg->mutable_unknown_fields(), $2$);\n"
- "parser_till_end = "
- "::$proto_ns$::internal::PackedValidEnumParser$3$;\n"
- "object = msg->mutable_$4$();\n",
- QualifiedClassName(field->enum_type()), field->number(),
- UseUnknownFieldSet(field->file(), options) ? "" : "Lite",
- FieldName(field));
- } else {
- format(
- "parser_till_end = ::$proto_ns$::internal::Packed$1$Parser;\n"
- "object = msg->mutable_$2$();\n",
- DeclaredTypeMethodName(field->type()), FieldName(field));
- }
- } else {
- auto field_type = field->type();
- if (IsProto1(field->file(), options)) {
- if (field->is_packable()) {
- // Sigh ... packed fields endup as a string in proto1
- field_type = FieldDescriptor::TYPE_BYTES;
- }
- if (field_type == FieldDescriptor::TYPE_STRING) {
- // In proto1 strings are treated as bytes
- field_type = FieldDescriptor::TYPE_BYTES;
- }
- }
- string utf8 = "";
- switch (field_type) {
- case FieldDescriptor::TYPE_STRING:
- utf8 = GetUtf8Suffix(field, options);
- if (!utf8.empty()) {
- string name = "nullptr";
- if (HasDescriptorMethods(field->file(), options)) {
- name = field->full_name();
- }
- format("ctx->extra_parse_data().SetFieldName(\"$1$\");\n", name);
- }
- [[clang::fallthrough]];
- case FieldDescriptor::TYPE_BYTES: {
- if (field->options().ctype() == FieldOptions::STRING ||
- (IsProto1(field->file(), options) &&
- field->options().ctype() == FieldOptions::STRING_PIECE)) {
- format(
- "parser_till_end = ::$proto_ns$::internal::StringParser$1$;\n"
- "$string$* str = msg->$2$_$3$();\n"
- "str->clear();\n",
- utf8,
- field->is_repeated() && !field->is_map() &&
- !field->is_packable()
- ? "add"
- : "mutable",
- FieldName(field));
- } else if (field->options().ctype() == FieldOptions::CORD) {
- string cord_parser = "CordParser" + utf8;
- format(
- "parser_till_end = ::$proto_ns$::internal::$1$;\n"
- "auto* str = msg->$2$_$3$();\n"
- "str->Clear();\n",
- cord_parser,
- field->is_repeated() && !field->is_map() ? "add" : "mutable",
- FieldName(field));
- } else if (field->options().ctype() == FieldOptions::STRING_PIECE) {
- format(
- "parser_till_end = "
- "::$proto_ns$::internal::StringPieceParser$1$;\n"
- "::$proto_ns$::internal::StringPieceField* str = "
- "msg->$2$_$3$();\n"
- "str->Clear();\n",
- utf8,
- field->is_repeated() && !field->is_map() ? "add" : "mutable",
- FieldName(field));
- }
- format("object = str;\n");
- break;
- }
- case FieldDescriptor::TYPE_MESSAGE: {
- GOOGLE_CHECK(field->message_type());
- if (IsImplicitWeakField(field, options, scc_analyzer)) {
- if (!field->is_repeated()) {
- format("object = HasBitSetters::mutable_$1$(msg);\n",
- FieldName(field));
- } else {
- format(
- "object = "
- "CastToBase(&msg->$1$_)->AddWeak(reinterpret_cast<const "
- "::google::protobuf::MessageLite*>(&$2$::_$3$_default_instance_));\n",
- FieldName(field), Namespace(field->message_type()),
- ClassName(field->message_type()));
- }
- format(
- "parser_till_end = static_cast<::$proto_ns$::MessageLite*>("
- "object)->_ParseFunc();\n");
- break;
- } else if (IsWeak(field, options)) {
- if (IsProto1(field->file(), options)) {
- format("object = msg->internal_mutable_$1$();\n",
- FieldName(field));
- } else {
- format(
- "object = msg->_weak_field_map_.MutableMessage($1$, "
- "_$classname$_default_instance_.$2$_);\n",
- field->number(), FieldName(field));
- }
- format(
- "parser_till_end = static_cast<::$proto_ns$::MessageLite*>("
- "object)->_ParseFunc();\n");
- break;
- }
- format(
- "parser_till_end = $1$::_InternalParse;\n"
- "object = msg->$2$_$3$();\n",
- QualifiedClassName(field->message_type()),
- field->is_repeated() && !field->is_map() ? "add" : "mutable",
- FieldName(field));
- break;
- }
- default:
- GOOGLE_LOG(FATAL) << "Illegal combination for length delimited wiretype "
- << " filed type is " << field->type();
- }
- }
- format(
- "if (size > end - ptr) goto len_delim_till_end;\n"
- "auto newend = ptr + size;\n"
- "if (!ctx->ParseExactRange({parser_till_end, object}, ptr, newend)) "
- "goto error;\n"
- "ptr = newend;\n");
+ GenerateLengthDelim(field, options, scc_analyzer, format);
break;
}
case WireFormatLite::WIRETYPE_START_GROUP: {
format(
"parser_till_end = $1$::_InternalParse;\n"
"object = msg->$2$_$3$();\n"
- "if (!ctx->PrepareGroup(tag, &depth)) goto error;\n"
+ "bool ok = ctx->PrepareGroup(tag, &depth);\n"
+ "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ok);\n"
"ptr = parser_till_end(ptr, end, object, ctx);\n"
- "if (!ptr) goto error;\n"
+ "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n"
"if (ctx->GroupContinues(depth)) goto group_continues;\n",
QualifiedClassName(field->message_type()),
field->is_repeated() ? "add" : "mutable", FieldName(field));
@@ -1413,8 +1470,8 @@ void GenerateCaseBody(internal::WireFormatLite::WireType wiretype,
uint64 mask = (1ull << (cnt * 8)) - 1;
format.Outdent();
format(
- "} while((*reinterpret_cast<const $uint64$*>(ptr) & $1$) == $2$ && "
- "(ptr += $3$));\n",
+ "} while ((::$proto_ns$::io::UnalignedLoad<$uint64$>(ptr) & $1$) == "
+ "$2$ && (ptr += $3$));\n",
mask, y, cnt);
}
format("break;\n");
@@ -1491,9 +1548,8 @@ void GenerateParserLoop(const Descriptor* descriptor, const Options& options,
" while (ptr < end) {\n"
" $uint32$ tag;\n"
" ptr = Varint::Parse32Inline(ptr, &tag);\n"
- " if (!ptr) goto error;\n"
- " switch (tag >> 3) {\n"
- " case 0: goto error;\n");
+ " $GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n"
+ " switch (tag >> 3) {\n");
format.Indent();
format.Indent();
@@ -1526,8 +1582,9 @@ void GenerateParserLoop(const Descriptor* descriptor, const Options& options,
format(
"default: {\n"
"handle_unusual: (void)&&handle_unusual;\n"
- " if ((tag & 7) == 4) {\n"
- " if (!ctx->ValidEndGroup(tag)) goto error;\n"
+ " if ((tag & 7) == 4 || tag == 0) {\n"
+ " bool ok = ctx->ValidEndGroup(tag);\n"
+ " $GOOGLE_PROTOBUF$_PARSER_ASSERT(ok);\n"
" return ptr;\n"
" }\n");
if (IsMapEntryMessage(descriptor)) {
@@ -1579,8 +1636,6 @@ void GenerateParserLoop(const Descriptor* descriptor, const Options& options,
" } // switch\n"
" } // while\n"
" return ptr;\n"
- "error:\n"
- " return nullptr;\n"
"len_delim_till_end: (void)&&len_delim_till_end;\n"
" return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},\n"
" {parser_till_end, object}, size);\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
index c01329fa..b8431aed 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -55,19 +55,16 @@ namespace protobuf {
namespace compiler {
namespace cpp {
-inline string ProtobufNamespace(const Options& options) {
+inline std::string ProtobufNamespace(const Options& options) {
return options.opensource_runtime ? "google::protobuf" : "proto2";
}
-inline string MacroPrefix(const Options& options) {
+inline std::string MacroPrefix(const Options& options) {
return options.opensource_runtime ? "GOOGLE_PROTOBUF" : "GOOGLE_PROTOBUF";
}
-inline string DeprecatedAttribute(const Options& options, bool deprecated) {
- if (!deprecated) {
- return "";
- }
- return MacroPrefix(options) + "_DEPRECATED ";
+inline std::string DeprecatedAttribute(const Options& options, bool deprecated) {
+ return deprecated ? "PROTOBUF_DEPRECATED " : "";
}
// Commonly-used separator comments. Thick is a line of '=', thin is a line
@@ -79,35 +76,35 @@ inline bool IsProto1(const FileDescriptor* file, const Options& options) {
return false;
}
-void SetCommonVars(const Options& options, std::map<string, string>* variables);
+void SetCommonVars(const Options& options, std::map<std::string, std::string>* variables);
-bool GetBootstrapBasename(const Options& options, const string& basename,
- string* bootstrap_basename);
+bool GetBootstrapBasename(const Options& options, const std::string& basename,
+ std::string* bootstrap_basename);
bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context,
- bool bootstrap_flag, string* basename);
+ bool bootstrap_flag, std::string* basename);
bool IsBootstrapProto(const Options& options, const FileDescriptor* file);
// Name space of the proto file. This namespace is such that the string
// "<namespace>::some_name" is the correct fully qualified namespace.
// This means if the package is empty the namespace is "", and otherwise
// the namespace is "::foo::bar::...::baz" without trailing semi-colons.
-string Namespace(const string& package);
-inline string Namespace(const FileDescriptor* d) {
+std::string Namespace(const std::string& package);
+inline std::string Namespace(const FileDescriptor* d) {
return Namespace(d->package());
}
-string Namespace(const Descriptor* d);
-string Namespace(const FieldDescriptor* d);
-string Namespace(const EnumDescriptor* d);
+std::string Namespace(const Descriptor* d);
+std::string Namespace(const FieldDescriptor* d);
+std::string Namespace(const EnumDescriptor* d);
// Returns true if it's safe to reset "field" to zero.
bool CanInitializeByZeroing(const FieldDescriptor* field);
-string ClassName(const Descriptor* descriptor);
-string ClassName(const EnumDescriptor* enum_descriptor);
+std::string ClassName(const Descriptor* descriptor);
+std::string ClassName(const EnumDescriptor* enum_descriptor);
-string QualifiedClassName(const Descriptor* d);
-string QualifiedClassName(const EnumDescriptor* d);
+std::string QualifiedClassName(const Descriptor* d);
+std::string QualifiedClassName(const EnumDescriptor* d);
// DEPRECATED just use ClassName or QualifiedClassName, a boolean is very
// unreadable at the callsite.
@@ -119,33 +116,33 @@ string QualifiedClassName(const EnumDescriptor* d);
// ::foo::bar::Baz_Qux
// While the non-qualified version would be:
// Baz_Qux
-inline string ClassName(const Descriptor* descriptor, bool qualified) {
+inline std::string ClassName(const Descriptor* descriptor, bool qualified) {
return qualified ? QualifiedClassName(descriptor) : ClassName(descriptor);
}
-inline string ClassName(const EnumDescriptor* descriptor, bool qualified) {
+inline std::string ClassName(const EnumDescriptor* descriptor, bool qualified) {
return qualified ? QualifiedClassName(descriptor) : ClassName(descriptor);
}
// Fully qualified name of the default_instance of this message.
-string DefaultInstanceName(const Descriptor* descriptor);
+std::string DefaultInstanceName(const Descriptor* descriptor);
// Returns the name of a no-op function that we can call to introduce a linker
// dependency on the given message type. This is used to implement implicit weak
// fields.
-string ReferenceFunctionName(const Descriptor* descriptor);
+std::string ReferenceFunctionName(const Descriptor* descriptor);
// Name of the base class: google::protobuf::Message or google::protobuf::MessageLite.
-string SuperClassName(const Descriptor* descriptor, const Options& options);
+std::string SuperClassName(const Descriptor* descriptor, const Options& options);
// 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
// should be using lowercase-with-underscores style for proto field names
// anyway, so normally this just returns field->name().
-string FieldName(const FieldDescriptor* field);
+std::string FieldName(const FieldDescriptor* field);
// Get the sanitized name that should be used for the given enum in C++ code.
-string EnumValueName(const EnumValueDescriptor* enum_value);
+std::string EnumValueName(const EnumValueDescriptor* enum_value);
// Returns an estimate of the compiler's alignment for the field. This
// can't guarantee to be correct because the generated code could be compiled on
@@ -155,7 +152,7 @@ int EstimateAlignmentSize(const FieldDescriptor* field);
// Get the unqualified name that should be used for a field's field
// number constant.
-string FieldConstantName(const FieldDescriptor *field);
+std::string FieldConstantName(const FieldDescriptor *field);
// Returns the scope where the field was defined (for extensions, this is
// different from the message type to which the field applies).
@@ -166,51 +163,51 @@ inline const Descriptor* FieldScope(const FieldDescriptor* field) {
// Returns the fully-qualified type name field->message_type(). Usually this
// is just ClassName(field->message_type(), true);
-string FieldMessageTypeName(const FieldDescriptor* field);
+std::string FieldMessageTypeName(const FieldDescriptor* field);
// Strips ".proto" or ".protodevel" from the end of a filename.
-LIBPROTOC_EXPORT string StripProto(const string& filename);
+PROTOC_EXPORT std::string StripProto(const std::string& filename);
// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
const char* PrimitiveTypeName(FieldDescriptor::CppType type);
-string PrimitiveTypeName(const Options& options, FieldDescriptor::CppType type);
+std::string PrimitiveTypeName(const Options& options, FieldDescriptor::CppType type);
// Get the declared type name in CamelCase format, as is used e.g. for the
// methods of WireFormat. For example, TYPE_INT32 becomes "Int32".
const char* DeclaredTypeMethodName(FieldDescriptor::Type type);
// Return the code that evaluates to the number when compiled.
-string Int32ToString(int number);
+std::string Int32ToString(int number);
// Return the code that evaluates to the number when compiled.
-string Int64ToString(const Options& options, int64 number);
+std::string Int64ToString(const Options& options, int64 number);
// Get code that evaluates to the field's default value.
-string DefaultValue(const Options& options, const FieldDescriptor* field);
+std::string DefaultValue(const Options& options, const FieldDescriptor* field);
// Compatibility function for callers outside proto2.
-string DefaultValue(const FieldDescriptor* field);
+std::string DefaultValue(const FieldDescriptor* field);
// Convert a file name into a valid identifier.
-string FilenameIdentifier(const string& filename);
+std::string FilenameIdentifier(const std::string& filename);
// For each .proto file generates a unique name. To prevent collisions of
// symbols in the global namespace
-string UniqueName(const string& name, const string& filename,
+std::string UniqueName(const std::string& name, const std::string& filename,
const Options& options);
-inline string UniqueName(const string& name, const FileDescriptor* d,
+inline std::string UniqueName(const std::string& name, const FileDescriptor* d,
const Options& options) {
return UniqueName(name, d->name(), options);
}
-inline string UniqueName(const string& name, const Descriptor* d,
+inline std::string UniqueName(const std::string& name, const Descriptor* d,
const Options& options) {
return UniqueName(name, d->file(), options);
}
-inline string UniqueName(const string& name, const EnumDescriptor* d,
+inline std::string UniqueName(const std::string& name, const EnumDescriptor* d,
const Options& options) {
return UniqueName(name, d->file(), options);
}
-inline string UniqueName(const string& name, const ServiceDescriptor* d,
+inline std::string UniqueName(const std::string& name, const ServiceDescriptor* d,
const Options& options) {
return UniqueName(name, d->file(), options);
}
@@ -222,32 +219,32 @@ inline Options InternalRuntimeOptions() {
options.opensource_runtime = false;
return options;
}
-inline string UniqueName(const string& name, const string& filename) {
+inline std::string UniqueName(const std::string& name, const std::string& filename) {
return UniqueName(name, filename, InternalRuntimeOptions());
}
-inline string UniqueName(const string& name, const FileDescriptor* d) {
+inline std::string UniqueName(const std::string& name, const FileDescriptor* d) {
return UniqueName(name, d->name(), InternalRuntimeOptions());
}
-inline string UniqueName(const string& name, const Descriptor* d) {
+inline std::string UniqueName(const std::string& name, const Descriptor* d) {
return UniqueName(name, d->file(), InternalRuntimeOptions());
}
-inline string UniqueName(const string& name, const EnumDescriptor* d) {
+inline std::string UniqueName(const std::string& name, const EnumDescriptor* d) {
return UniqueName(name, d->file(), InternalRuntimeOptions());
}
-inline string UniqueName(const string& name, const ServiceDescriptor* d) {
+inline std::string UniqueName(const std::string& name, const ServiceDescriptor* d) {
return UniqueName(name, d->file(), InternalRuntimeOptions());
}
// Return the qualified C++ name for a file level symbol.
-string QualifiedFileLevelSymbol(const string& package, const string& name);
+std::string QualifiedFileLevelSymbol(const std::string& package, const std::string& name);
// Escape C++ trigraphs by escaping question marks to \?
-string EscapeTrigraphs(const string& to_escape);
+std::string EscapeTrigraphs(const std::string& to_escape);
// Escaped function name to eliminate naming conflict.
-string SafeFunctionName(const Descriptor* descriptor,
+std::string SafeFunctionName(const Descriptor* descriptor,
const FieldDescriptor* field,
- const string& prefix);
+ const std::string& prefix);
// Returns true if generated messages have public unknown fields accessors
inline bool PublicUnknownFieldsAccessors(const Descriptor* message) {
@@ -355,6 +352,8 @@ inline bool HasFastArraySerialization(const FileDescriptor* file,
inline bool IsProto2MessageSet(const Descriptor* descriptor,
const Options& options) {
return !options.opensource_runtime &&
+ !options.enforce_lite &&
+ !options.lite_implicit_weak_fields &&
descriptor->options().message_set_wire_format() &&
descriptor->full_name() == "google.protobuf.bridge.MessageSet";
}
@@ -362,6 +361,8 @@ inline bool IsProto2MessageSet(const Descriptor* descriptor,
inline bool IsProto2MessageSetFile(const FileDescriptor* file,
const Options& options) {
return !options.opensource_runtime &&
+ !options.enforce_lite &&
+ !options.lite_implicit_weak_fields &&
file->name() == "net/proto2/bridge/proto/message_set.proto";
}
@@ -372,7 +373,7 @@ inline bool IsMapEntryMessage(const Descriptor* descriptor) {
// Returns true if the field's CPPTYPE is string or message.
bool IsStringOrMessage(const FieldDescriptor* field);
-string UnderscoresToCamelCase(const string& input, bool cap_next_letter);
+std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter);
inline bool HasFieldPresence(const FileDescriptor* file) {
return file->syntax() != FileDescriptor::SYNTAX_PROTO3;
@@ -401,11 +402,11 @@ inline bool IsCrossFileMessage(const FieldDescriptor* field) {
field->message_type()->file() != field->file();
}
-inline string MessageCreateFunction(const Descriptor* d) {
+inline std::string MessageCreateFunction(const Descriptor* d) {
return SupportsArenas(d) ? "CreateMessage" : "Create";
}
-inline string MakeDefaultName(const FieldDescriptor* field) {
+inline std::string MakeDefaultName(const FieldDescriptor* field) {
return "_i_give_permission_to_break_this_code_default_" + FieldName(field) +
"_";
}
@@ -455,7 +456,7 @@ struct MessageAnalysis {
// quadratic performance, if we do this per message we would get O(V*(V+E)).
// Logically this is just only used in message.cc, but in the header for
// FileGenerator to help share it.
-class LIBPROTOC_EXPORT MessageSCCAnalyzer {
+class PROTOC_EXPORT MessageSCCAnalyzer {
public:
explicit MessageSCCAnalyzer(const Options& options) : options_(options) {}
@@ -528,18 +529,18 @@ bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
// "__declspec(export) void fun();"
//
// which is convenient to prevent double, leading or trailing spaces.
-class LIBPROTOC_EXPORT Formatter {
+class PROTOC_EXPORT Formatter {
public:
explicit Formatter(io::Printer* printer) : printer_(printer) {}
- Formatter(io::Printer* printer, const std::map<string, string>& vars)
+ Formatter(io::Printer* printer, const std::map<std::string, std::string>& vars)
: printer_(printer), vars_(vars) {}
template <typename T>
- void Set(const string& key, const T& value) {
+ void Set(const std::string& key, const T& value) {
vars_[key] = ToString(value);
}
- void AddMap(const std::map<string, string>& vars) {
+ void AddMap(const std::map<std::string, std::string>& vars) {
for (const auto& keyval : vars) vars_[keyval.first] = keyval.second;
}
@@ -552,7 +553,7 @@ class LIBPROTOC_EXPORT Formatter {
void Outdent() const { printer_->Outdent(); }
io::Printer* printer() const { return printer_; }
- class LIBPROTOC_EXPORT SaveState {
+ class PROTOC_EXPORT SaveState {
public:
explicit SaveState(Formatter* format)
: format_(format), vars_(format->vars_) {}
@@ -560,28 +561,28 @@ class LIBPROTOC_EXPORT Formatter {
private:
Formatter* format_;
- std::map<string, string> vars_;
+ std::map<std::string, std::string> vars_;
};
private:
io::Printer* printer_;
- std::map<string, string> vars_;
+ std::map<std::string, std::string> vars_;
// Convenience overloads to accept different types as arguments.
- static string ToString(const string& s) { return s; }
+ static std::string ToString(const std::string& s) { return s; }
template <typename I, typename = typename std::enable_if<
std::is_integral<I>::value>::type>
- static string ToString(I x) {
+ static std::string ToString(I x) {
return SimpleItoa(x);
}
- static string ToString(strings::Hex x) { return StrCat(x); }
- static string ToString(const FieldDescriptor* d) { return Payload(d); }
- static string ToString(const Descriptor* d) { return Payload(d); }
- static string ToString(const EnumDescriptor* d) { return Payload(d); }
- static string ToString(const EnumValueDescriptor* d) { return Payload(d); }
+ static std::string ToString(strings::Hex x) { return StrCat(x); }
+ static std::string ToString(const FieldDescriptor* d) { return Payload(d); }
+ static std::string ToString(const Descriptor* d) { return Payload(d); }
+ static std::string ToString(const EnumDescriptor* d) { return Payload(d); }
+ static std::string ToString(const EnumValueDescriptor* d) { return Payload(d); }
template <typename Descriptor>
- static string Payload(const Descriptor* descriptor) {
+ static std::string Payload(const Descriptor* descriptor) {
std::vector<int> path;
descriptor->GetLocationPath(&path);
GeneratedCodeInfo::Annotation annotation;
@@ -593,18 +594,18 @@ class LIBPROTOC_EXPORT Formatter {
}
};
-class LIBPROTOC_EXPORT NamespaceOpener {
+class PROTOC_EXPORT NamespaceOpener {
public:
explicit NamespaceOpener(const Formatter& format)
: printer_(format.printer()) {}
- NamespaceOpener(const string& name, const Formatter& format)
+ NamespaceOpener(const std::string& name, const Formatter& format)
: NamespaceOpener(format) {
ChangeTo(name);
}
~NamespaceOpener() { ChangeTo(""); }
- void ChangeTo(const string& name) {
- std::vector<string> new_stack_ =
+ void ChangeTo(const std::string& name) {
+ std::vector<std::string> new_stack_ =
Split(name, "::", true);
int len = std::min(name_stack_.size(), new_stack_.size());
int common_idx = 0;
@@ -623,10 +624,10 @@ class LIBPROTOC_EXPORT NamespaceOpener {
private:
io::Printer* printer_;
- std::vector<string> name_stack_;
+ std::vector<std::string> name_stack_;
};
-string GetUtf8Suffix(const FieldDescriptor* field, const Options& options);
+std::string GetUtf8Suffix(const FieldDescriptor* field, const Options& options);
void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
const Options& options, bool for_parse,
const char* parameters,
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
index 4ab407d2..3114bbf7 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
@@ -177,54 +177,49 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
descriptor_->message_type()->FindFieldByName("key");
const FieldDescriptor* value_field =
descriptor_->message_type()->FindFieldByName("value");
- bool using_entry = false;
string key;
string value;
+ format(
+ "$map_classname$::Parser< ::$proto_ns$::internal::MapField$lite$<\n"
+ " $map_classname$,\n"
+ " $key_cpp$, $val_cpp$,\n"
+ " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
+ " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
+ " $default_enum_value$ >,\n"
+ " ::$proto_ns$::Map< $key_cpp$, $val_cpp$ > >"
+ " parser(&$name$_);\n");
if (IsProto3Field(descriptor_) ||
value_field->type() != FieldDescriptor::TYPE_ENUM) {
format(
- "$map_classname$::Parser< ::$proto_ns$::internal::MapField$lite$<\n"
- " $map_classname$,\n"
- " $key_cpp$, $val_cpp$,\n"
- " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
- " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
- " $default_enum_value$ >,\n"
- " ::$proto_ns$::Map< $key_cpp$, $val_cpp$ > >"
- " parser(&$name$_);\n"
"DO_(::$proto_ns$::internal::WireFormatLite::ReadMessageNoVirtual(\n"
" input, &parser));\n");
key = "parser.key()";
value = "parser.value()";
} else {
- using_entry = true;
key = "entry->key()";
value = "entry->value()";
- format("::std::unique_ptr<$map_classname$> entry($name$_.NewEntry());\n");
+ format("auto entry = parser.NewEntry();\n");
format(
- "{\n"
- " ::std::string data;\n"
- " DO_(::$proto_ns$::internal::WireFormatLite::ReadString(input, "
+ "::std::string data;\n"
+ "DO_(::$proto_ns$::internal::WireFormatLite::ReadString(input, "
"&data));\n"
- " DO_(entry->ParseFromString(data));\n"
- " if ($val_cpp$_IsValid(*entry->mutable_value())) {\n"
- " (*mutable_$name$())[entry->key()] =\n"
- " static_cast< $val_cpp$ >(*entry->mutable_value());\n"
- " } else {\n");
+ "DO_(entry->ParseFromString(data));\n"
+ "if ($val_cpp$_IsValid(*entry->mutable_value())) {\n"
+ " (*mutable_$name$())[entry->key()] =\n"
+ " static_cast< $val_cpp$ >(*entry->mutable_value());\n"
+ "} else {\n");
if (HasDescriptorMethods(descriptor_->file(), options_)) {
format(
- " mutable_unknown_fields()"
+ " mutable_unknown_fields()"
"->AddLengthDelimited($number$, data);\n");
} else {
format(
- " unknown_fields_stream.WriteVarint32($tag$u);\n"
- " unknown_fields_stream.WriteVarint32(\n"
- " static_cast< ::google::protobuf::uint32>(data.size()));\n"
- " unknown_fields_stream.WriteString(data);\n");
+ " unknown_fields_stream.WriteVarint32($tag$u);\n"
+ " unknown_fields_stream.WriteVarint32(\n"
+ " static_cast< ::google::protobuf::uint32>(data.size()));\n"
+ " unknown_fields_stream.WriteString(data);\n");
}
-
- format(
- " }\n"
- "}\n");
+ format("}\n");
}
if (key_field->type() == FieldDescriptor::TYPE_STRING) {
@@ -242,11 +237,6 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
.data(),
format);
}
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (using_entry && SupportsArenas(descriptor_)) {
- format("if (entry->GetArena() != NULL) entry.release();\n");
- }
}
static void GenerateSerializationLoop(const Formatter& format,
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index e219d784..4af54032 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -554,7 +554,7 @@ void ColdChunkSkipper::OnStartChunk(int chunk, int cached_has_bit_index,
}
// Emit has_bit check for each has_bit_dword index.
- format("if ($GOOGLE_PROTOBUF$_PREDICT_FALSE(");
+ format("if (PROTOBUF_PREDICT_FALSE(");
int first_word = HasbitWord(chunk, 0);
while (chunk < limit_chunk_) {
uint32 mask = 0;
@@ -940,8 +940,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
" $default_enum_value$ > {\n"
"public:\n"
"#if $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
- " static const char* _InternalParse(const char* begin, const char* "
- "end, void* object, ::$proto_ns$::internal::ParseContext* ctx);\n"
+ "static bool _ParseMap(const char* begin, const "
+ "char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);\n"
"#endif // $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
" typedef ::$proto_ns$::internal::MapEntry$lite$<$classname$, \n"
" $key_cpp$, $val_cpp$,\n"
@@ -1514,23 +1514,17 @@ bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset,
// If we don't have field presence, then _has_bits_ does not exist.
format("-1,\n");
} else {
- format(
- "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET(\n"
- " $classtype$, _has_bits_),\n");
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n");
}
if (descriptor_->oneof_decl_count() > 0) {
- format(
- "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET(\n"
- " $classtype$, _oneof_case_),\n");
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_),\n");
} else {
format("-1, // no _oneof_case_\n");
}
if (descriptor_->extension_range_count() > 0) {
- format(
- "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
- "_extensions_),\n");
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _extensions_),\n");
} else {
format("-1, // no _extensions_\n");
}
@@ -1538,8 +1532,7 @@ bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset,
// TODO(ckennelly): Consolidate this with the calculation for
// AuxillaryParseTableField.
format(
- "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET(\n"
- " $classtype$, _internal_metadata_),\n"
+ "PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n"
"&$package_ns$::_$classname$_default_instance_,\n");
if (UseUnknownFieldSet(descriptor_->file(), options_)) {
@@ -1650,10 +1643,10 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
Formatter::SaveState saver(&format);
format.AddMap(vars);
format(
- "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET("
+ "{PROTOBUF_FIELD_OFFSET("
"::$proto_ns$::internal::MapEntryHelper<$classtype$::"
"SuperType>, $field_name$_), $tag$,"
- "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET("
+ "PROTOBUF_FIELD_OFFSET("
"::$proto_ns$::internal::MapEntryHelper<$classtype$::"
"SuperType>, _has_bits_) * 8 + $hasbit$, $type$, "
"$ptr$},\n");
@@ -1661,8 +1654,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
return 2;
}
format(
- "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
- "_cached_size_), 0, 0, 0, NULL},\n");
+ "{PROTOBUF_FIELD_OFFSET($classtype$, _cached_size_), 0, 0, 0, NULL},\n");
std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
sorted_extensions.push_back(descriptor_->extension_range(i));
@@ -1677,8 +1669,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
const Descriptor::ExtensionRange* range =
sorted_extensions[extension_idx];
format(
- "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
- "_extensions_), "
+ "{PROTOBUF_FIELD_OFFSET($classtype$, _extensions_), "
"$1$, $2$, ::$proto_ns$::internal::FieldMetadata::kSpecial, "
"reinterpret_cast<const "
"void*>(::$proto_ns$::internal::ExtensionSerializer)},\n",
@@ -1703,8 +1694,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
if (IsMapEntryMessage(field->message_type())) {
format(
- "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($"
- "classtype$, $field_name$_), $1$, $2$, "
+ "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), $1$, $2$, "
"::$proto_ns$::internal::FieldMetadata::kSpecial, "
"reinterpret_cast<const void*>(static_cast< "
"::$proto_ns$::internal::SpecialSerializer>("
@@ -1745,7 +1735,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
if (field->options().weak()) {
// TODO(gerbens) merge weak fields into ranges
format(
- "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET("
+ "{PROTOBUF_FIELD_OFFSET("
"$classtype$, _weak_field_map_), $1$, $1$, "
"::$proto_ns$::internal::FieldMetadata::kSpecial, "
"reinterpret_cast<const "
@@ -1755,24 +1745,21 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
format.Set("oneofoffset",
sizeof(uint32) * field->containing_oneof()->index());
format(
- "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
- "$field_name$_), "
- "$1$, $GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
- "_oneof_case_) + $oneofoffset$, $2$, $3$},\n",
+ "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), $1$,"
+ " PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_) + "
+ "$oneofoffset$, $2$, $3$},\n",
tag, type, ptr);
} else if (HasFieldPresence(descriptor_->file()) &&
has_bit_indices_[field->index()] != -1) {
format.Set("hasbitsoffset", has_bit_indices_[field->index()]);
format(
- "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
- "$field_name$_), "
- "$1$, $GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
- "_has_bits_) * 8 + $hasbitsoffset$, $2$, $3$},\n",
+ "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), "
+ "$1$, PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_) * 8 + "
+ "$hasbitsoffset$, $2$, $3$},\n",
tag, type, ptr);
} else {
format(
- "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
- "$field_name$_), "
+ "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), "
"$1$, ~0u, $2$, $3$},\n",
tag, type, ptr);
}
@@ -1783,8 +1770,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
? "UnknownFieldSetSerializer"
: "UnknownFieldSerializerLite";
format(
- "{$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
- "_internal_metadata_), 0, ~0u, "
+ "{PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_), 0, ~0u, "
"::$proto_ns$::internal::FieldMetadata::kSpecial, reinterpret_cast<const "
"void*>(::$proto_ns$::internal::$1$)},\n",
serializer);
@@ -1876,12 +1862,62 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
"}\n"
"\n");
}
- // TODO(gerbens) make maps parse :(
format(
"#if $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n"
- "const char* $classname$::_InternalParse(const char* begin, const "
- "char* end, void* object, ::$proto_ns$::internal::ParseContext* ctx) { "
- "return end; }\n"
+ "bool $classname$::_ParseMap(const char* begin, const "
+ "char* end, void* object, ::google::protobuf::internal::ParseContext* ctx) {\n"
+ " using MF = ::$proto_ns$::internal::MapField$1$<\n"
+ " $classname$, EntryKeyType, EntryValueType,\n"
+ " kEntryKeyFieldType, kEntryValueFieldType,\n"
+ " kEntryDefaultEnumValue>;\n"
+ " auto mf = static_cast<MF*>(object);\n"
+ " Parser<MF, ::$proto_ns$::Map<EntryKeyType, EntryValueType>> "
+ "parser(mf);\n"
+ "#define DO_(x) if (!(x)) return false\n",
+ HasDescriptorMethods(descriptor_->file(), options_) ? "" : "Lite");
+ const FieldDescriptor* key = descriptor_->FindFieldByName("key");
+ const FieldDescriptor* val = descriptor_->FindFieldByName("value");
+ GOOGLE_CHECK(val);
+ string key_string;
+ string value_string;
+ if (HasFieldPresence(descriptor_->file()) &&
+ val->type() == FieldDescriptor::TYPE_ENUM) {
+ format(
+ " DO_(parser.ParseMapEnumValidation(\n"
+ " begin, end, ctx->extra_parse_data().field_number,\n"
+ " static_cast<::google::protobuf::internal::InternalMetadataWithArena$1$*>("
+ "ctx->extra_parse_data().unknown_fields), $2$_IsValid));\n",
+ HasDescriptorMethods(descriptor_->file(), options_) ? "" : "Lite",
+ QualifiedClassName(val->enum_type()));
+ key_string = "parser.entry_key()";
+ value_string = "parser.entry_value()";
+ } else {
+ format(" DO_(parser.ParseMap(begin, end));\n");
+ key_string = "parser.key()";
+ value_string = "parser.value()";
+ }
+ format.Indent();
+ if (key->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ key, options_, true,
+ StrCat(key_string, ".data(), static_cast<int>(", key_string,
+ ".length()),\n")
+ .data(),
+ format);
+ }
+ if (val->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ val, options_, true,
+ StrCat(value_string, ".data(), static_cast<int>(", value_string,
+ ".length()),\n")
+ .data(),
+ format);
+ }
+ format.Outdent();
+ format(
+ "#undef DO_\n"
+ " return true;\n"
+ "}\n"
"#endif // $GOOGLE_PROTOBUF$_ENABLE_EXPERIMENTAL_PARSER\n");
format("\n");
return;
@@ -2138,8 +2174,7 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) {
format(
"{\n"
- " $GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET(\n"
- " $classtype$, $name$_),\n"
+ " PROTOBUF_FIELD_OFFSET($classtype$, $name$_),\n"
" static_cast<$uint32$>($presence$),\n"
" $nwtype$, $pwtype$, $ptype$, $tag_size$\n"
"},\n");
@@ -2236,33 +2271,23 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
Formatter format(printer, variables_);
if (HasFieldPresence(descriptor_->file()) || IsMapEntryMessage(descriptor_)) {
- format(
- "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
- "_has_bits_),\n");
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n");
} else {
format("~0u, // no _has_bits_\n");
}
- format(
- "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
- "_internal_metadata_),\n");
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n");
if (descriptor_->extension_range_count() > 0) {
- format(
- "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, "
- "_extensions_),\n");
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _extensions_),\n");
} else {
format("~0u, // no _extensions_\n");
}
if (descriptor_->oneof_decl_count() > 0) {
- format(
- "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET("
- "$classtype$, _oneof_case_[0]),\n");
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_[0]),\n");
} else {
format("~0u, // no _oneof_case_\n");
}
if (num_weak_fields_ > 0) {
- format(
- "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$,"
- " _weak_field_map_),\n");
+ format("PROTOBUF_FIELD_OFFSET($classtype$, _weak_field_map_),\n");
} else {
format("~0u, // no _weak_field_map_\n");
}
@@ -2275,9 +2300,7 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
format("offsetof($classtype$DefaultTypeInternal, $1$_)",
FieldName(field));
} else {
- format(
- "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, $1$_)",
- FieldName(field));
+ format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_)", FieldName(field));
}
uint32 tag = field_generators_.get(field).CalculateFieldTag();
@@ -2289,9 +2312,7 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
}
for (auto oneof : OneOfRange(descriptor_)) {
- format(
- "$GOOGLE_PROTOBUF$_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, $1$_),\n",
- oneof->name());
+ format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_),\n", oneof->name());
}
if (IsMapEntryMessage(descriptor_)) {
@@ -2687,7 +2708,7 @@ void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) {
Formatter format(printer, variables_);
format(
"template<> "
- "$GOOGLE_PROTOBUF$_ATTRIBUTE_NOINLINE "
+ "PROTOBUF_NOINLINE "
"$classtype$* Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n"
" return Arena::$1$Internal< $classtype$ >(arena);\n"
"}\n",
@@ -3334,8 +3355,9 @@ void MessageGenerator::GenerateMergeFromCodedStream(io::Printer* printer) {
"const char* $classname$::_InternalParse(const char* begin, const "
"char* end, void* object,\n"
" ::$proto_ns$::internal::ParseContext* ctx) {\n"
+ " auto msg = static_cast<$classname$*>(object);\n"
" return ::$proto_ns$::internal::ParseMessageSet(begin, end, "
- "static_cast<$classname$*>(object), ctx);\n"
+ "msg, &msg->_extensions_, &msg->_internal_metadata_, ctx);\n"
"}\n"
"const char* $classname$::InternalParseMessageSetItem(const char* "
"begin, const char* end, void* object,\n"
@@ -3396,7 +3418,7 @@ void MessageGenerator::GenerateMergeFromCodedStream(io::Printer* printer) {
format(
"#define DO_(EXPRESSION) if "
- "(!$GOOGLE_PROTOBUF$_PREDICT_TRUE(EXPRESSION)) goto failure\n"
+ "(!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure\n"
" $uint32$ tag;\n");
if (!UseUnknownFieldSet(descriptor_->file(), options_)) {
@@ -3801,11 +3823,12 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray(
" target = _extensions_."
"InternalSerializeMessageSetWithCachedSizesToArray(\n"
" deterministic, target);\n");
+ GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
std::map<string, string> vars;
SetUnknkownFieldsVariable(descriptor_, options_, &vars);
format.AddMap(vars);
format(
- " target = ::$proto_ns$::internal::\n"
+ " target = ::$proto_ns$::internal::WireFormat::\n"
" SerializeUnknownMessageSetItemsToArray(\n"
" $unknown_fields$, target);\n");
format(
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h
index 170a70cd..6bef8d56 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -63,7 +63,7 @@ class MessageGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
MessageGenerator(const Descriptor* descriptor,
- const std::map<string, string>& vars,
+ const std::map<std::string, std::string>& vars,
int index_in_file_messages, const Options& options,
MessageSCCAnalyzer* scc_analyzer);
~MessageGenerator();
@@ -194,7 +194,7 @@ class MessageGenerator {
const Descriptor* descriptor_;
int index_in_file_messages_;
- string classname_;
+ std::string classname_;
Options options_;
FieldGeneratorMap field_generators_;
// optimized_order_ is the order we layout the message's fields in the
@@ -216,7 +216,7 @@ class MessageGenerator {
MessageSCCAnalyzer* scc_analyzer_;
- std::map<string, string> variables_;
+ std::map<std::string, std::string> variables_;
friend class FileGenerator;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h
index 6a364deb..84c18622 100644
--- a/src/google/protobuf/compiler/cpp/cpp_options.h
+++ b/src/google/protobuf/compiler/cpp/cpp_options.h
@@ -35,7 +35,6 @@
#include <string>
-#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace compiler {
@@ -45,7 +44,7 @@ namespace cpp {
// Generator options (see generator.cc for a description of each):
struct Options {
- string dllexport_decl;
+ std::string dllexport_decl;
bool safe_boundary_check = false;
bool proto_h = false;
bool transitive_pb_h = true;
@@ -58,8 +57,8 @@ struct Options {
bool opensource_runtime = false;
bool opensource_include_paths = false;
int num_cc_files = 0;
- string annotation_pragma_name;
- string annotation_guard_name;
+ std::string annotation_pragma_name;
+ std::string annotation_guard_name;
const AccessInfoMap* access_info_map = nullptr;
};
diff --git a/src/google/protobuf/compiler/cpp/cpp_service.h b/src/google/protobuf/compiler/cpp/cpp_service.h
index 3acbe637..2952e413 100644
--- a/src/google/protobuf/compiler/cpp/cpp_service.h
+++ b/src/google/protobuf/compiler/cpp/cpp_service.h
@@ -57,7 +57,7 @@ class ServiceGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit ServiceGenerator(const ServiceDescriptor* descriptor,
- const std::map<string, string>& vars,
+ const std::map<std::string, std::string>& vars,
const Options& options);
~ServiceGenerator();
@@ -109,7 +109,7 @@ class ServiceGenerator {
void GenerateStubMethods(io::Printer* printer);
const ServiceDescriptor* descriptor_;
- std::map<string, string> vars_;
+ std::map<std::string, std::string> vars_;
int index_in_metadata_;
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.inc b/src/google/protobuf/compiler/cpp/cpp_unittest.inc
index 0604731f..898b1fbb 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.inc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.inc
@@ -78,6 +78,8 @@
#include <google/protobuf/stubs/casts.h>
#include <google/protobuf/stubs/stl_util.h>
+#include <google/protobuf/port_def.inc>
+
namespace google {
namespace protobuf {
namespace compiler {
@@ -203,7 +205,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, ExtremeSmallIntegerDefault) {
const UNITTEST::TestExtremeDefaultValues& extreme_default =
UNITTEST::TestExtremeDefaultValues::default_instance();
EXPECT_EQ(~0x7fffffff, kint32min);
- EXPECT_EQ(GOOGLE_LONGLONG(~0x7fffffffffffffff), kint64min);
+ EXPECT_EQ(PROTOBUF_LONGLONG(~0x7fffffffffffffff), kint64min);
EXPECT_EQ(kint32min, extreme_default.really_small_int32());
EXPECT_EQ(kint64min, extreme_default.really_small_int64());
}
@@ -656,7 +658,7 @@ TEST(GENERATED_MESSAGE_TEST_NAME, CopyAssignmentOperator) {
TestUtil::ExpectAllFieldsSet(message2);
}
-#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || GOOGLE_PROTOBUF_RTTI
+#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || PROTOBUF_RTTI
TEST(GENERATED_MESSAGE_TEST_NAME, UpcastCopyFrom) {
// Test the CopyFrom method that takes in the generic const Message&
// parameter.
@@ -2267,3 +2269,5 @@ TEST(DESCRIPTOR_INIT_TEST_NAME, Initialized) {
} // namespace compiler
} // namespace protobuf
} // namespace google
+
+#include <google/protobuf/port_undef.inc>