diff options
Diffstat (limited to 'src/google/protobuf/compiler/cpp')
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> |